Hallo und guten Tag zusammen,
ich hoffe Ihr könnt mir helfen, nachdem das in diversen Arduino Foren
nicht wirklich funktioniert hat.
Ich bin auf der Suche nach entweder jemandem, der ein Arduino Blue Pill
(STM32F103) und SN65HVD230 für CAN Bus mittels in der Arduino IDE
programmiert hat, oder ein (wenn möglich deutschsprachiges) Tutorial
dazu. Gefunden dazu hab ich ein Video eines nuschelnden Spaniers der
versucht englisch zu sprechen.. ;-)
ich bin auf der Suche nach Hilfe zur Selbsthilfe es soll mir keiner
einen Sketch schreiben. Wenn jemand etwas fertiges lauffähiges zu dem
Thema hat, was vernünftig kommentiert ist, würde mir das als Grundlage
auf der ich aufbauen kann weiterhelfen.
Mein Projekt ist die Steuerung einer analogen Modelleisenbahn. Teile der
Steuerung (wie zB die Steuerung des Schattenbahnhofes) habe ich fertig.
Ich möchte nur den Zustand von ein paar Variablen via CAN von einem
Arduino zum anderen schicken. ZB (Lichtschranke 1 = High)
Gruß
Kay
Bluepill leider nein. Bei AVR und Teensy 3/4 habe ich gute Erfahrungen
mit den ACAN-Bibliotheken von Pierre Molinaro gemacht. Wo hakt es denn?
LG, Sebastian
Es hakt überall :-)
Das ist ja das Problem. Die absoluten Basics des CAN sind mir so
halbwegs klar, aber in dem beispielsketch den ich bei Github gefunden
habe:
https://github.com/nopnop2002/Arduino-STM32-CAN/blob/master/stm32f103/stm32f103.ino
Komme ich keinen schritt weiter, da steige ich nicht durch. Das mag
auch am Englisch oder der für einen Laien nicht ausreichenden
kommentierung liegen.
Zu meinem Hintergrund ich programiere erst seit 2 Jahren, komme aber aus
der Elektronic... Wohl noch analog :-)
Zu meinen Programierkenntnissen:
Umgesetzt habe ich bis dato:
1. Steuerung des Schattenbahnhofes mit 5 Gleisen (Suche freies Gleis,
fahren des Zuges bis zum Haltepunkt, schalten der Weichen usw.
2. Geschwindigkeits mess und Regelung (mit LCD)
3. Totman box, die Verhindert das die Bahn tagelang im Keller unter
strom steht (mit LCD)
4. Schweisslicht
5. Gleisstatusanzeige mit LCD
und ein paar andere Kleinigkeiten
Alles als State Maschine mit Übergang also mit aktualState und
nextState.
Habe mir das alles selber bei gebracht, aber für den CAN Bus fehlen mir
wohl noch jede Menge Basics. Deshalb wäre ein Tutorial wie dieses:
https://www.fh-bielefeld.de/medienportal/video/13B1-Aufzugtuer-als-endlicher-Automat-in-C/36538450aeaa04af71bc17b2ae9617d0
(damit hab ich die State Maschine verstanden) nur halt für CAN äusserst
hilfreich. Alternativ würde auch ein sehr gut kommentierter Code reichen
der eine Variable übergibt. Denn könnte ich mir dann mittels try and
error erklären. Dafür ist der Code von Github aber zu komplex
Gruß
Kay
Kay L. schrieb:> Komme ich keinen schritt weiter, da steige ich nicht durch. Das mag> auch am Englisch oder der für einen Laien nicht ausreichenden> kommentierung liegen.
In dem Github-Code ist Treiber und Beispiel alles in einem Sourcefile
verwurstet. Das ist für das erste Verständnis auch maximal ungünstig.
Besser wäre eine abgekapselte Lib, die einfach nur den can_write,
can_read und die grundlegende CAN-Struktur mit Id, Len und Data[8] zur
Verfügung stellt.
Wichtig ist auch, dass man nicht unbedingt nur seine beiden
CAN-Teilnehmer vor sich liegen hat, dessen Code man selber erstellt hat.
Besser man hat ein CAN-Analyzer mit angeschlossen, dem man vertraut und
einem anzeigt, was gerade auf dem Bus vor sich geht.
So ein CAN-Analyzer kann etwas von Peak sein (evtl. etwas teuer für
Hobby), etwas von fischl.de oder auch einfach nur ein Logik-Analyzer von
Amazon für <10€. Der LA hat den Nachteil, dass er keine Live-View
bietet. Gibt auch noch weitere CAN-Werkzeuge für kleines Geld, einfach
mal stöbern.
Bleibe dran, es lohnt sich! CAN ist zwar schon uralt, aber eine schöne
Methode, damit sich verschiedene Teilnehmer Botschaften zuschieben
können, ohne an Bustimings gebunden zu sein.
Kay L. schrieb:> ich hoffe Ihr könnt mir helfen, nachdem das in diversen Arduino Foren> nicht wirklich funktioniert hat.> Ich bin auf der Suche nach entweder jemandem, der ein Arduino Blue Pill> (STM32F103) und SN65HVD230 für CAN Bus mittels in der Arduino IDE> programmiert hat, oder ein (wenn möglich deutschsprachiges) Tutorial> dazu.
Bei Deinem STM32F103 kannst Du entweder USB oder CAN verwendet, nicht
beides zusammen. Erstens liegen die Signale auf den gleichen Pins, und
zweitens verwenden beide Peripherieeinheiten das gleiche Dual-Port-RAM.
Erste Empfehlung: keinen F103 nehmen, sondern einen F302 oder F303. Die
haben das Problem nicht.
Zweite Empfehlung, wenn das Kind schon ganz tief im Brunnen steckt:
Schauen, ob Du für Dein konkretes Board einen Schaltplan bekommst. Wenn
da USB drauf ist, dann alles, was damit zu tut hat, runternehmen.
Überprüfen, ob PA11/PA12 tatsächlich mit der Stiftleiste verbunden sind.
In der Software alles, was mit USB zu tun hat, rauswerfen.
Dann könnte es gehen.
Es ist halt blöd, dass noch so altes Zeugs verkauft und verwendet wird.
Blöde Anfängerfalle.
fchk
Frank K. schrieb:> Kay L. schrieb:>> ich hoffe Ihr könnt mir helfen, nachdem das in diversen Arduino Foren>> nicht wirklich funktioniert hat.>> Ich bin auf der Suche nach entweder jemandem, der ein Arduino Blue Pill>> (STM32F103) und SN65HVD230 für CAN Bus mittels in der Arduino IDE>> programmiert hat, oder ein (wenn möglich deutschsprachiges) Tutorial>> dazu.>> Bei Deinem STM32F103 kannst Du entweder USB oder CAN verwendet, nicht> beides zusammen. Erstens liegen die Signale auf den gleichen Pins, und> zweitens verwenden beide Peripherieeinheiten das gleiche Dual-Port-RAM.>> Erste Empfehlung: keinen F103 nehmen, sondern einen F302 oder F303. Die> haben das Problem nicht.> Zweite Empfehlung, wenn das Kind schon ganz tief im Brunnen steckt:> Schauen, ob Du für Dein konkretes Board einen Schaltplan bekommst. Wenn> da USB drauf ist, dann alles, was damit zu tut hat, runternehmen.> Überprüfen, ob PA11/PA12 tatsächlich mit der Stiftleiste verbunden sind.> In der Software alles, was mit USB zu tun hat, rauswerfen.>> Dann könnte es gehen.>> Es ist halt blöd, dass noch so altes Zeugs verkauft und verwendet wird.> Blöde Anfängerfalle.>> fchk
Hallo Frank,
ich verstehe gerade deinen Post nicht, ich möchte USB gar nicht nutzen.
Selbst das programieren des Arduinos mache ich direkt, also über STLink
utility.
Gruß
Kay
Kay L. schrieb:> ich verstehe gerade deinen Post nicht, ich möchte USB gar nicht nutzen.
Ist auf Deinem Bluepill Board denn ein USB-Anschluss drauf? Auch wenn
der nicht benutzt wird. Wenn ja, dann wird der die gleichen Pins
(PA11/PA12) benutzen, die der CAN verwendet. Genau diese
Doppelbeschaltung kann zu Problemen führen.
Was mir noch einfallt: Ist das denn wirklich ein originaler Chip von ST?
Die STM32F103 sind mit die am häufigsten gecloneten Chips überhaupt - da
gibt es wesentlich mehr Kopien als Originale. Auch der Aufdruck ist of
gefälscht.
Die STM32F30x sind von der Clonerei noch nicht so betroffen, obwohl es
auch da Nachbauten gibt. Und die Nachbauten sind nicht immer überall 1:1
kompatibel.
fchk
Pieter schrieb:> moin,>> in Zusammenfassung: CAN ist einfacher als I2C!> Was verwirrend ist, sind die Filter und Masken. Meist braucht man die> aber gar nicht.> Was ist an dem code unklar?>>>https://github.com/nopnop2002/Arduino-STM32-CAN/blob/master/stm32f103/stm32f103.ino>> VG> Pieter
So ziemlich alles ;-) vor allem der ist ziemlich lang. Wir ist auch
nicht klar warum der verschiedene Bitraten zulässt, fehlermeldung für
eine falsche Bitrate auswirft usw.
Das dies für die saubere Programierung und den sauberen stabilen Betrieb
notwendig ist, ist mir natürlich klar, für den Einstieg aber nur maximal
verwirrend
Eine Sketch zB der Via CAN einfach nur den Zustand einer Variable mit
festgelegter Bitrate an einen anderen übermittelt, ohne hätte, sollte,
könnte, vielleicht wäre für mich der ideale Einstieg.
Da könnte ich dann sehen, ah es läuft, dann ändere ich den Zustand der
Variable die ich sende und sehe "ach da und in der Form wird der Zustand
übertragen" dann "ach da wird der Name in der Form der variablen
übertragen" ach da syncronisiere ich die Bitrate" usw usw.
Oder halt ein Video die CAN für Dummies erklärt ;-)
Ich muß auch nicht so tief gehen wenn es eine einfache Libery wie zB für
die Character LCD´s gibt wäre mir das noch lieber.
ich mache ja keine Raketentechnik nur eine Modelleisenbahn, da ist es
nicht schlimm wenn mal was schief läuft.
Gruß
Kay
Kay L. schrieb:> Eine Sketch zB der Via CAN einfach nur den Zustand einer Variable mit> festgelegter Bitrate an einen anderen übermittelt
Du musst ja auch nicht den kompletten Code verstehen. Wenn er
funktioniert - ich habe es nicht getestet - reicht der Teil ab Zeile
522.
Als erstes muss man natürlich den CAN mal einschalten:
1
voidsetup(){
2
Serial.begin(115200);
3
boolret=CANInit(CAN_500KBPS,2);// CAN_RX to PB8, CAN_TX to PB9
Thomas F. schrieb:> Kay L. schrieb:>> Eine Sketch zB der Via CAN einfach nur den Zustand einer Variable mit>> festgelegter Bitrate an einen anderen übermittelt>> Du musst ja auch nicht den kompletten Code verstehen. Wenn er> funktioniert - ich habe es nicht getestet - reicht der Teil ab Zeile> 522.> Als erstes muss man natürlich den CAN mal einschalten:>>
1
>voidsetup(){
2
>Serial.begin(115200);
3
>boolret=CANInit(CAN_500KBPS,2);// CAN_RX to PB8, CAN_TX to PB9
4
>if(!ret)while(true);
5
>}
6
>
>> Und dann ein einfaches Senden:>>
1
>voidloop(){
2
>CAN_msg_tCAN_TX_msg;
3
>
4
>CAN_TX_msg.data[0]=0x00;
5
>CAN_TX_msg.data[1]=0x01;
6
>CAN_TX_msg.data[2]=0x02;
7
>CAN_TX_msg.len=3;// Länge der Botschaft: 3 Bytes
8
>
9
>CAN_TX_msg.type=DATA_FRAME;
10
>CAN_TX_msg.id=0x123;
11
>
12
>CANSend(&CAN_TX_msg);
13
>
14
>Delay(1000);
15
>}
16
>
> Wie gesagt: ungetestet, aber in etwa so läufts.
Erstmal vielen lieben Dank!! ich suche schon seit Monaten in den Arduino
Foren....
Mal sehen ob ich das bis dato gelesene auch richtig Verstanden habe.
Auf der Empängerseite mus ich das auch so einfügen nur anstelle von TX
(Transiver) RX (Receiver) einsetzten?
Zum Sketch
1
CAN_msg_tCAN_TX_msg;
2
// Beutet für den STM ab hier startet eine CAN Message als Sender
3
4
CAN_TX_msg.data[0]=0x00;
5
// Bedeutet Datenbits 1 -3 aber was bedeutet "0x00"?
6
CAN_TX_msg.len=3;
7
// Länge der Botschaft: 3 Bytes (selbsterklärend)
8
CAN_TX_msg.type=DATA_FRAME;
9
// Hier weis ich nicht so genau was das ist?
10
CAN_TX_msg.id=0x123;
11
// Der "Name" der Botschaft, damit der Empfänger die für Ihn bestimme Botschaft auch findet. aber was ist 0x123 (sind die 0x123 usw ev nur Platzhalter?
12
CANSend(&CAN_TX_msg);
13
// "Sendebefehl das die Mitteilung jetzt gesendet wird
Ich hoffe das stimmt so halbwegs? und meine Fragen sind nicht komplett
doof
Gruß
Kay
// Bedeutet Datenbits 1 -3 aber was bedeutet "0x00"?
Dir ist der Ausdruck "0x00" unbekannt? Das sind jetzt aber absolute
Anfänger-Grundlagen: 0x steht für die Hex-Schreibweise einer Zahl. 0x00
ist einfach 0. 0x0A ist 10.
1
CAN_TX_msg.id=0x123;
2
// Der "Name" der Botschaft, damit der Empfänger die für Ihn bestimme Botschaft auch findet. aber was ist 0x123 (sind die 0x123 usw ev nur Platzhalter?
Siehe oben: Hexadezimale Schreibweise.
Ich fürchte du solltest dich erst noch mal mit den Grundlagen befassen.
Sorry da stand ich auf dem Schlauch.. Ich war schon bei Hexadezimal, nur
hatte ich die zweistellig vor Augen... Das 0x vorne als Bescheibung für
die Hexadezimalzahl hatte ich nicht mehr auf dem Schirm...
Frank K. schrieb:> Wenn ja, dann wird der die gleichen Pins> (PA11/PA12) benutzen, die der CAN verwendet. Genau diese> Doppelbeschaltung kann zu Problemen führen.
Was wird denn hier wieder für Käse-Information verbreitet?
Ein F103 kann das CAN Interface entweder auf PA11/PA12 oder
auf PB8/PB9 konfiguriert haben.
Einfach mal ins Datenblatt schauen oder CubeMX über sich
ergehen lassen .....
Frank K. schrieb:> Kay L. schrieb:>>> ich verstehe gerade deinen Post nicht, ich möchte USB gar nicht nutzen.>> Ist auf Deinem Bluepill Board denn ein USB-Anschluss drauf? Auch wenn> der nicht benutzt wird. Wenn ja, dann wird der die gleichen Pins> (PA11/PA12) benutzen, die der CAN verwendet. Genau diese> Doppelbeschaltung kann zu Problemen führen.>> Was mir noch einfallt: Ist das denn wirklich ein originaler Chip von ST?> Die STM32F103 sind mit die am häufigsten gecloneten Chips überhaupt - da> gibt es wesentlich mehr Kopien als Originale. Auch der Aufdruck ist of> gefälscht.>> Die STM32F30x sind von der Clonerei noch nicht so betroffen, obwohl es> auch da Nachbauten gibt. Und die Nachbauten sind nicht immer überall 1:1> kompatibel.>> fchk
Sorry hatte deine Post übersehen. Ja USB ist drauf, um den USB zur
Programierung zu nutzen muss man vorher mittels eines FTDI Adapters
einen Bootloader aufspielen. Da ich ja über STLink Programiere, spiele
ich keinen Bootloader auf und in der Arduino IDE nutze ich auch kein
USB. Eine doppelnutzung kann also nicht vorkommen.
Mir ist auch bewusst das die 103er oft gefaked werden. Ich hatte sogar
schon mal welche, da hab ich mich tot gesucht, warum die sich nicht
programieren lassen. Irgendwann bin ich dann mal darauf gekommen mir die
Chips genauer anzusehen und siehe da, kein ST Logo drauf.
Das ist der Arduino Blue Pill:
https://www.az-delivery.de/products/stm32f103c8t6
ich weiß jetzt auch nicht ob es einen anderen ST32 als "Arduino" gibt.
Ich hab mal die Scematics von dem teil angehangen. Ich hoffe, das ist
OK?
Kay L. schrieb:> Sorry hatte deine Post übersehen.
Meinen Beitrag hast du auch wohl auch übersehen.
Kay L. schrieb:> Ich hab mal die Scematics von dem teil angehangen.
Nein, du hast ihn angehängt. Oder sagst du auch du hast etwas
eingekaufen, du hast etwas aufgemalen, du hast etwas eingelöten?
erklehr behr schrieb:> Kay L. schrieb:>> Sorry hatte deine Post übersehen.>> Meinen Beitrag hast du auch wohl auch übersehen.>> Kay L. schrieb:>> Ich hab mal die Scematics von dem teil angehangen.>> Nein, du hast ihn angehängt. Oder sagst du auch du hast etwas> eingekaufen, du hast etwas aufgemalen, du hast etwas eingelöten?
Trägt dieser Post etwas zur Lösung meiner Fragestellung bei?
Kay L. schrieb:> Das ist der Arduino Blue Pill...> ich weiß jetzt auch nicht ob es einen anderen ST32 als "Arduino" gibt.
Es hat noch nie ein echtes "Arduino Blue Pill" Board gegeben. Das
LeafLabs Maple Mini Board kommt dem noch am nächsten, aber auch das war
nie ein originales Arduino Board. Beide Boards wurden nicht von Arduino
designt und die zugehörige Software kommt auch nicht von Arduino.
Wenn du etwas besseres mit ähnlichem Format haben willst, dann nimm ein
Nucleo32 Board von ST. Das kannst du auch mit der Arduino IDE
programmieren und die entsprechende Software
(https://github.com/stm32duino/Arduino_Core_STM32) kommt direkt vom
Chiphersteller ST.
vor das CANSend().
Kay L. schrieb:> Auf der Empängerseite mus ich das auch so einfügen nur anstelle von TX> (Transiver) RX (Receiver) einsetzten?
TX steht für Transmitter. Und nein, du solltest vor dem Aufruf von
CANReceive(&CAN_RX_msg) mit CANMsgAvail() prüfen, ob überhaupt eine
CAN-Nachricht empfangen wurde.
In der loop()-Routine des stm32f103.ino werden regelmäßig zwei
verschiedene CAN-Nachrichten gesendet, und dann werden auch alle
CAN-Nachrichten empfangen und ausgegeben. Nimm das doch als ersten
Versuch.
LG, Sebastian
> vor das CANSend().>> Kay L. schrieb:>> Auf der Empängerseite mus ich das auch so einfügen nur anstelle von TX>> (Transiver) RX (Receiver) einsetzten?>> TX steht für Transmitter. Und nein, du solltest vor dem Aufruf von> CANReceive(&CAN_RX_msg) mit CANMsgAvail() prüfen, ob überhaupt eine> CAN-Nachricht empfangen wurde.>> In der loop()-Routine des stm32f103.ino werden regelmäßig zwei> verschiedene CAN-Nachrichten gesendet, und dann werden auch alle> CAN-Nachrichten empfangen und ausgegeben. Nimm das doch als ersten> Versuch.>> LG, Sebastian
Vielen lieben Dank dafür, damit kann ich etwas anfangen.
Verstehe ich das richtig, das ich die info die ich übertragen will (zB
StatusLS1 = true)
in die canTX.msg umwandeln muß?
Hallo,
vielleicht habe den Sinn nicht verstanden, aber warum nimmst Du nicht
einfach eine fertige Can-Bus Platine mit Controller 2515?
Oder soll es eine persönliche Herausforderung sein, nicht den normalen
Weg über gute Programme wie schon erwähnt ACAN2515, MCP_Can usw.... zu
gehen?
Kay L. schrieb:> das ich die info die ich übertragen will (zB StatusLS1 = true)> in die canTX.msg umwandeln muß
Ja. Vielleicht besser nicht so umständlich, aber ja.
LG, Sebastian
Peter* schrieb:> Hallo,>> vielleicht habe den Sinn nicht verstanden, aber warum nimmst Du nicht> einfach eine fertige Can-Bus Platine mit Controller 2515?>> Oder soll es eine persönliche Herausforderung sein, nicht den normalen> Weg über gute Programme wie schon erwähnt ACAN2515, MCP_Can usw.... zu> gehen?
Hallo Peter,
Der STM32F1 stellt ja den CAN BUS zur verfügung, also warum den Umweg
über Umwandeln gehen? Der 2525 Wandelt ja das CAN in ein SPI Signal um.
Nun ja der "normale Weg" ist wohl eher das vorhandene CAN ohne Umwandler
zu nutzen. Nur weil es viele anders machen muß es ja nicht der normale
sein :-)
Die Herausforderung dabei ist meine Konstellation:
1. ich bin blutiger Anfänger
2. Den Blue Pill mit STM32F1 nutzen nicht viele (wie man auch hier im
Fred ja schon sieht ist der eher verpöhnt)
3. Den CAN Bus darauf noch entsprechend weniger.
Auch habe ich meine Baseboards für die Nutzung von CAN vorgesehen.
Zu guter letzt, ja mittlerweile ist es etwas persönliches zwischen mir
und dem CAN Bus :-)
Gruß
Kay
Sebastian schrieb:> Kay L. schrieb:>> das ich die info die ich übertragen will (zB StatusLS1 = true)>> in die canTX.msg umwandeln muß>> Ja. Vielleicht besser nicht so umständlich, aber ja.>> LG, Sebastian
Hallo Sebastian,
vielen lieben Dank! Jetzt weiß ich wo ich ansetzten muß!
Auch an alle anderen die etwas zur Lösung und damit das ich einen Ansatz
habe beigetragen haben
Gruß
Kay
Kay L. schrieb:> Auch an alle anderen die etwas zur Lösung und damit das ich einen Ansatz> habe beigetragen haben
Ein Oszilloskop und ein Logikanalysator könnten im weiteren Verlauf
hilfreich sein. Tip: Schließe einen SN65HVD230 am CAN-Bus an, versorge
ihn, und häng den Logikanalysator an seinen RX-Pin. So kannst du passiv
den Bus beobachten
LG, Sebastian
Sebastian schrieb:> Kay L. schrieb:>> Auch an alle anderen die etwas zur Lösung und damit das ich einen Ansatz>> habe beigetragen haben>> Ein Oszilloskop und ein Logikanalysator könnten im weiteren Verlauf> hilfreich sein. Tip: Schließe einen SN65HVD230 am CAN-Bus an, versorge> ihn, und häng den Logikanalysator an seinen RX-Pin. So kannst du passiv> den Bus beobachten>> LG, Sebastian
Ja mache ich Dankeschön.
Kay L. schrieb:> Den Blue Pill mit STM32F1 nutzen nicht viele
Nicht mehr. Vor 2000 war das ein sehr beliebtes Board, deswegen haben
viele Bastler damit Erfahrung.
Kay L. schrieb:> Vielen lieben Dank dafür, damit kann ich etwas anfangen.> Verstehe ich das richtig, das ich die info die ich übertragen will (zB> StatusLS1 = true)>> in die canTX.msg umwandeln muß?
canTX_msg ist ein struct.
Das struct beinhaltet unter anderem die Datenbytes der zu sendenden
Botschaft.
Eine CAN-Botschaft kann zwischen 0 und 8 Datenbytes enthalten.
Willst du lediglich ein Statusbit übertragen dann musst du min. 1
Datenbyte senden:
Hallo,
Kay L. schrieb:> Nun ja der "normale Weg" ist wohl eher das vorhandene CAN ohne Umwandler> zu nutzen. Nur weil es viele anders machen muß es ja nicht der normale> sein :-)
Über "normal" kann man sich streiten, aber es hängt doch meistens vom
dem Faktor der Anzahl ab, die es so nutzen!!
Der Can_Controller MCp2515 ist kein Umwandler er nutz SPI und übernimmt
die ganze Abwicklung des CanBus's und befreit den Prozessor von dieser
Aufgabe, der sonst gebunden ist!! und evtl. so zusätzlich Speicherplatz
belegt.
> 3. Den CAN Bus darauf noch entsprechend weniger.... dein handeln ist wohl so
unlogisch oder :-)
Habe noch vor wenigen Jahren im Automotiv_bereich den CAN_Restbus (500k)
mit dem BlusPill mit MCP2515 simuliert, selbst ein Arduino UNO reicht so
aus.
verpönt ist dumm, aber ist inzwischen zu teuer geworden 2Euro hat er
gekostet.
PI Pico W (6,99) mit ACAN
Hallo,
ACAN steht für ACAN2515 oder auch ACAN2517/18 (Can 2.0B und FD)
NiRen, CANdiy-Shield V2
Pico ist momentan der Günstigste (Reichelt) und auch unter Arduino
programmierbar.
Leider bekomme ich folgende Fehlermeldung:
C:\Users\Büro\privat\Eisenbahn\MCU_Program\Sketches\Testprogramme\CAN\CA
N1_0\CAN1_0.ino: In function 'void setup()':
CAN1_0:52:24: error: 'CAN_500KBPS' was not declared in this scope
CAN1_0:52:38: error: 'CANInit' was not declared in this scope
exit status 1
'CAN_500KBPS' was not declared in this scope
Er sieht CANinit usw anscheinend als undefinierte Variable....
Was hab ich vergessen?
Gruß
Kay
xxxxxx.h steht für den Namen deiner Header-Datei der Arduino
Lib die du verwendest bzw. verwenden willst.
Kay L. schrieb:> Er sieht CANinit usw anscheinend als undefinierte Variable....
Nein, er sieht CANinit als ihm unbekannte Funktion.
Die Datei stm32f103.cpp solle alles aus stm32f103.ino bis
einschliesslich Zeile 502 enthalten. Allerdings solle der Anfang danach
noch leicht abgeändert werden:
[code]
#include <Arduino.h>
#include "stm32f103.h"
[code]
Außerdem solltest du die Typdefinitionen, die schon in stm32f103.h sind,
in stm32f103.cpp am Anfang noch löschen (also die enums BITRATE,
CAN_FORMAT, CAN_FRAME und die struct CAN_msg_t).
Dann sollte dein Sketch übersetzen.
LG, Sebastian
Hallo Sebastian,
ok, dann hatte ich Frank s Post (09.02.2023 14:30) komplett falsch
verstanden. Ich dachte ich bräuchte nur den kleinen Teil...
Auf ein neues.
Vielen Dank für eure Mühe
Gruß
Kay
Kay L. schrieb:> ok, dann hatte ich Frank s Post (09.02.2023 14:30) komplett falsch> verstanden. Ich dachte ich bräuchte nur den kleinen Teil...Meinst du den Beitrag von Thomas? Thomas F. schrieb:> Du musst ja auch nicht den kompletten Code verstehen. Wenn er> funktioniert - ich habe es nicht getestet - reicht der Teil ab Zeile> 522.
Er meinte wohl dass du den Code ausserhalb von loop() nicht verstehen
musst, und dass es reicht den loop()-Teil für deine Zwecke anzupassen.
Er meinte damit aber nicht dass du den Code vor setup () und loop() gar
nicht brauchst.
Zumindest meine ich dass er das meinte.
Kay L. schrieb:> Auf ein neues.
Ich habe mir, angeregt durch deine Experimente, kurzfristig ein
Nucleo-F303K8-Board zugelegt. Alles was ich heute mittag geschrieben
habe hatte ich vorher mit
https://github.com/nopnop2002/Arduino-STM32-CAN/tree/master/stm32f303
nachvollzogen. Bei mir läuft der CAN-Empfang auf dem STM32F303K8T6. Ich
benutze allerdings einen TJA1050-Transceiver an PA11 und PA12 (die
beiden Pins sind hoffentlich 5V-tolerant):
Sebastian W. schrieb:> Meinst du den Beitrag von Thomas? Thomas F. schrieb:>> Du musst ja auch nicht den kompletten Code verstehen. Wenn er>> funktioniert - ich habe es nicht getestet - reicht der Teil ab Zeile>> 522.>> Er meinte wohl dass du den Code ausserhalb von loop() nicht verstehen> musst, und dass es reicht den loop()-Teil für deine Zwecke anzupassen.> Er meinte damit aber nicht dass du den Code vor setup () und loop() gar> nicht brauchst.>> Zumindest meine ich dass er das meinte.
Genau das habe ich gemeint. :-)
Natürlich muss man die benötigten Code-Teile vor Zeile 522 auch mit in
das Projekt übernehmen. Wie das geht hat ja Sebastian dankenswerter
Weise beschrieben.
Ab Zeile 522 kannst du dann mit deinen eigenen Code herumwerkeln.
Kay L. schrieb:> im sketch wir eine assert.h eingebunden.>> ich bin aber zu blöd die zu finden.
Kommentiere einfach mal die paar Zeilen welche "assert" enthalten aus.
Sollte problemlos auch ohne gehen.
Fuck!
Lese den Anhang, verstehe ihn, verinnerliche ihn und handle
danach. Kann man so blöd sein nicht zu verstehen wie dein
Posting die anderen sehen?
"Längerer Sourcecode" ist es wenn man dauernd scrollen muss um
alles zu sehen. Dein Sourcecode ist länger!
fuck schrieb:> Fuck!>> Lese den Anhang, verstehe ihn, verinnerliche ihn und handle> danach. Kann man so blöd sein nicht zu verstehen wie dein> Posting die anderen sehen?>> "Längerer Sourcecode" ist es wenn man dauernd scrollen muss um> alles zu sehen. Dein Sourcecode ist länger!
Hallo Fuck,
das ist eine Definitionsfrage ;-)
Danke für den Hinweis, werde mich in Zukunft daran halten. Wenn ich
nicht zu blöd bin....
Kay L. schrieb:> ich bekomme weiterhin die Fehlermeldung beim Kompelieren:> 'CAN1' was not declared in this scope
Für welches Board übersetzt du denn? Also was ist unter "Werkzeuge" als
"Board" und als "Board part number" eingestellt?
LG, Sebastian
Kay L. schrieb:> STM32F1 Boards (Arduino STM32)> generic STM32F103C und STM32F103C6> Die ich immer benutze.
Bei mir gibt es keine Übersetzungsfehler. Häng den aktuellen Stand der
Dateien mal an, dann kann ich schauen wo der Unterschied liegt.
LG, Sebastian
Hallo Sebastian,
sorry das ich dich hab warten lassen.
Anbei die h, die ccp und die ino Datei.
Die komplette Fehlermeldung hab ich in die Datei "fehler" kopiert
Gruß und Danke
Kay
Hast du dir mal den aller ersten Fehler durch gelesen und auch
verstanden
> stm32f103.cpp:15:3: error: conflicting declaration 'typedef struct CAN_msg_t
CAN_msg_t'
Es wird dir in der darauf folgenden Zeile verraten wo das typedef noch
deklariert wird. 🤷♂️
Hallo Jens,
ja hatte ich gesehen. Das ist selbstverständlich weg wenn ich das erste
typedef struct aus der Datei lösche. Die frage die ich mir stelle ist:
muss das struct in der .h oder der . ccp Datei sein?
Egal in welcher Datei ich das auskommentiere der "conflicting
declaration" Fehler ist weg, was aber bleibt ist der Hauptfehler "CAN1
was not declared in this scope"
Gruß
Kay
Kay L. schrieb:> muss das struct in der .h oder der . ccp Datei sein?
Du willst diesen Typ auch im Hauptprogramm zur Verfügung haben, damit du
CAN-Nachrichten überhaupt senden und empfangen kannst. Also in die
.h-Datei.
Kay L. schrieb:> was aber bleibt ist der Hauptfehler "CAN1> was not declared in this scope"
Das passiert auf meinem Rechner nicht, wenn ich für BluePill F103C6
(32K) oder Generic F103C6Tx übersetze. Welche Version der Arduino-IDE
und des STM32-Support für die Arduino-IDE hast du installiert? Bei mir
sind es Arduino 1.8.19 und darin STM32 2.4.0 ...
LG, Sebastian
Ok.
Der Fehler wird in der ersten Zeile erzeugt, welche irgend etwas CAN
spezifisches beinhaltet. Es hat also nichts explizit mit dem "CAN1" zu
tun sondern vermutlich mit grundsätzlichen.
Arbeitest du in der Arduino Umgebung oder nutzt du einen anderen Editor?
Weil es jetzt Sinn machen würde sich durch die "Arduino.h" zu hangeln
und zu schauen welchen Controller und damit welche Definitionen dazu
wirklich verlinkt werden.
Die ganzen CAN Registernamen welche in deinem Code auftauchen sind
jedenfalls nicht jene, wie sie in der STM HAL genutzt werden. Wobei der
Arduino STM32 Core eigentlich die HAL nutzt.
Hast du als "Controller" auch einen ausgewählt der CAN hat?
Sorry, wenn es da tiefer in den Arduino-Core bin ich wieder raus. Dein
Beispiel von weiter oben müsste ich mir mal anschauen, wo der die CAN
Definitionen her holt.
Sebastian W. schrieb:
> Das passiert auf meinem Rechner nicht, wenn ich für BluePill F103C6> (32K) oder Generic F103C6Tx übersetze. Welche Version der Arduino-IDE> und des STM32-Support für die Arduino-IDE hast du installiert? Bei mir> sind es Arduino 1.8.19 und darin STM32 2.4.0 ...
meine IDE ist auch 1.8.19. Meinst Du mit STM32 2.4.0 den
Boardverwalter? Da hab ich den STM32F1xx/GD32F1xx boards Version
2021.5.31
Jens R. schrieb:
> Arbeitest du in der Arduino Umgebung oder nutzt du einen anderen Editor?
ich arbeite in der Arduino IDE
Zusatz von meiner Seite, ich vermute fast ich hab irgend etwas nicht
installiert. ich habe die original Arduino-STM32-CAN in eine IDE auf
einem anderen Rechner kopiert. Exakt die selbe Fehlermeldung. Dort ist
wohl eine neuere IDE installiert 2.0.0
Kay L. schrieb:> Meinst Du mit STM32 2.4.0 den> Boardverwalter? Da hab ich den STM32F1xx/GD32F1xx boards Version> 2021.5.31
Ok, ich glaube ich verstehe jetzt warum bei dir die Übersetzung
fehlschlägt.
Ich muss allerdings vorausschicken, dass ich erst vor zwei Wochen
angefangen habe mich mit den STM32-Prozessoren und deren Programmierung
zu beschäftigen.
Es scheint so, dass es zwei Arduino-IDE-Erweiterungen für die
Programmierung der STM32-Prozessoren gibt.
Zum einen ist da (A)
https://github.com/rogerclarkmelbourne/Arduino_STM32. Diese Umgebung
kann über die Boardverwalter-URL
http://dan.drown.org/stm32duino/package_STM32duino_index.json der
Arduino-IDE hinzugefügt werden, und ergänzt den Boardverwalter dann um
"STM32F1xx/GD32F1xx boards by stm32duino" und um "STM32F4xx boards by
stm32duino".
Zum anderen gibt es (B)
https://github.com/stm32duino/Arduino_Core_STM32. Diese Umgebung kann
über die Boardverwalter-URL
https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
der Arduino-IDE hinzugefügt werden, und ergänzt den Boardverwalter dann
um "STM32 MCU based boards by STMicroelectronics".
Stefan hat die Geschichte dahinter unter
http://stefanfrings.de/stm32/stm32f1.html ein wenig erläutert.
Du hast (A) installiert. (A) unterstützt aber allem Anschein nach nicht
die Programmierung des CAN-Busses, und ist auch generell die ältere und
inzwischen weniger gepflegte Version. Ich habe (B) installiert. (B) wird
von ST Microelectronics selbst gepflegt, scheint umfassender und
aktueller zu sein, und enthält die für dein Projekt nötige Unterstützung
von CAN1.
Wie gesagt, ich bin diesbezüglich nicht der Experte, aber aus meiner
Perspektive solltest du überlegen, grundsätzlich auf (B) umzusteigen.
Dabei könnte es eventuell natürlich nötig werden, einige deiner älteren
Projekte entsprechend anzupassen. Vielleicht benutzt du auch in diesen
anderen Projekten aber auch Zusatzbibliotheken die (A) voraussetzen? Das
ist von hier aus schwierig zu beurteilen.
LG, Sebastian
Hallo Sebastian,
Top klasse! Wo kann ich "gefällt mir" drücken ;-)
Es funktioniert!!!! Da wäre ich nie drauf gekommen.
Jetzt kompeliert er alles einwandfrei. Da kann ich endlich versuchen ne
LED auf dem zweiten Board VIA CAN zum Leuchten zu bringen!
Vielen lieben Dank an dich und alle anderen die mir geholfen haben!
Das ich dann ggf alle Projekte anpassen ist ist nicht das Problem. Da
hätte ich sowieso früher oder später nochmal ran gemusst, da ich heute
vieles anders lösen würde als noch vor 2 Jahren!
LG
Kay
der nur funktionier, wenn ich von "Seriel.begin" bis "while (true);"
auskommentiere.
Dann Leuchtet LED 2 und LED1 lässt sich über den schalter ein und
ausmachen. Auch LED_BUILDIN leuchtet so wie es sein soll
Bleiben die Zeilen aktiv, leuchtet nur die LED_Buildin, die im void
setup angeschaltet wird, die anderen beiden nicht. alles was im Sketch
nach Seriel.begin kommt wird ignoriert
Kay L. schrieb:> aber leider schlechte Nachrichten....
Hast du denn den Tranceiver schon angeschlossen? Ansonsten kann es gut
sein, dass CANInit fehlschlägt, und dann führst du ja eine
Endlosschleife in setup() aus und loop() wird überhaupt nicht betreten.
Setze in stm32f103.cpp mal DEBUG auf 1, dann sollte während CANInit auf
Serial einiges an Informationen erscheinen.
Mir kommen auch die Bezeichner PB6, PA0, PA3 im Zusammenhang mit
pinMode, digitalWrite und digitalRead sehr komisch vor. An der Stelle
sollten eigentlich Bezeichner der Art D5 verwendet werden. Wie sieht
dein Aufbau genau aus? Wie sind die digitalen Ein- und Ausgänge
bezeichnet?
LG, Sebastian
Sebastian W. schrieb:> Hast du denn den Tranceiver schon angeschlossen? Ansonsten kann es gut> sein, dass CANInit fehlschlägt, und dann führst du ja eine> Endlosschleife in setup() aus und loop() wird überhaupt nicht betreten.
Ich hab das hier mal mit meinem STM32F303 nachvollzogen. CANInit()
funktioniert auch ohne angeschlossenen Transceiver. Da ist bei dir doch
irgendwo ziemlich grundsätzlich noch der Wurm drin.
LG, Sebastian
Sebastian W. schrieb:> Mir kommen auch die Bezeichner PB6, PA0, PA3 im Zusammenhang mit> pinMode, digitalWrite und digitalRead sehr komisch vor. An der Stelle> sollten eigentlich Bezeichner der Art D5 verwendet werden. Wie sieht> dein Aufbau genau aus? Wie sind die digitalen Ein- und Ausgänge> bezeichnet?
PB6, PA8, PA3 kommen aus dem STM Datenblatt:
https://www.alldatasheet.com/datasheet-pdf/pdf/201596/STMICROELECTRONICS/STM32F103C8T6.html
Ab Seite 18 in der Tabelle.
Ich hab ja auch schon mehrere Programme exakt so geschrieben nur beim
CAN hab ich diese Probleme.
ich habs mit und ohne Transiver versucht, ebenso mit einem anderen
Bluepill Board. Mit einem Logiganalyser habe ich RX dauerhaft High und
TX dauerhaft 0. (gemessen direkt am Arduino vor dem Transiver.
Das "Problem" hab ich auch mal unserem Entwicklungsleiter geschrieben
(er hat mich auf STM und CAN gebracht) vielleicht hat er eine Idee.
Dir trotzdem vielen Dank für die Mühe. Sobald sich irgendwas ergibt
melde ich mich
Gruß
Kay
Sebastian W. schrieb:> Sebastian W. schrieb:>> Hast du denn den Tranceiver schon angeschlossen? Ansonsten kann es gut>> sein, dass CANInit fehlschlägt, und dann führst du ja eine>> Endlosschleife in setup() aus und loop() wird überhaupt nicht betreten.>> Ich hab das hier mal mit meinem STM32F303 nachvollzogen. CANInit()> funktioniert auch ohne angeschlossenen Transceiver. Da ist bei dir doch> irgendwo ziemlich grundsätzlich noch der Wurm drin.
Mmh. Ohne Transceiver liefert bei meinem STM32F303 mit angeschlossenem
Logikanalysator an PA11 und PA12 CANInit() plötzlich "CAN1 initialize
fail!!" und false zurück. Ziehe ich den Logikanalysator ab erhalte ich
"CAN1 initialize ok" und true.
Eine der zwei möglichen Meldungen solltest du aber in jedem Fall
erhalten. Lösch auch mal die Zeile "if (!ret) while (true);". Dann
sollte nach der Medung "CAN1 initialize fail!!" zumindest trotzdem deine
loop()-Funktion mit Taster und LED betreten werden.
Kay L. schrieb:> ich habs mit und ohne Transiver versucht, ebenso mit einem anderen> Bluepill Board. Mit einem Logiganalyser habe ich RX dauerhaft High und> TX dauerhaft 0. (gemessen direkt am Arduino vor dem Transiver.
Mmh. CAN_RX ist ja ein Eingang und also ohne angeschlossenen Transceiver
undefiniert. Aber bei geht ohne angeschlossenen Transceiver CAN_TX nach
der Initialisierung auf dauerhaft High. CAN_TX ist bei dir PB9, und dort
ist der D-Pin des SN65HVD230 angeschlossen?
Es besteht ja auch immer noch die Möglichkeit, dass dein F103 kein
original STM32 ist. Bei den Nachbauten scheint ja oft gerade die
CAN-Unterstützung zu fehlen oder fehlerhaft zu sein ...
LG, Sebastian
Hallo Sebastian,
das es sich ggf nicht um STM32 original handelt hatte ich auch schon in
Betracht gezogen und hab mir die am Samstag abend genauer angesehen, das
ST Micro Logo ist drauf also kein Nachbau sondern, wenn, dann eine
Fälschung. Mir ist dabei aber eine andere Abweichung aufgefallen. Drauf
sein sollte der STM32F103C8xx verbaut ist aber STM32F103C6xx ob das der
Grund sein kann kann ich so erstmal nicht sagen, ich habe mir aber
zumindest bei AZ Delivery einen neuen Blue Pill mit C8 bestellt. Mal
sehen ob es damit funktioniert
Danke und Gruß
Kay
Kay L. schrieb:> Drauf sein sollte der STM32F103C8xx verbaut ist aber STM32F103C6xx
Dann würde ich versuchen den Sketch noch einmal zu übersetzen und
hochzuladen, und dabei vorher im Menü "Werkzeuge" unter "Board" "Generic
STM32F1 series" als "Board part number" anstatt "BluePill F103C8" besser
"BluePill F103C6 (32K)" auszuwählen.
LG, Sebastian
Soderle,
der C8 ist angekommen und getestet, selbes Ergebnis. Es liegt also nicht
an der Chip version.
lösche ich "if (!ret) while (true);" bleibt der Code ebenfalls stehen,
lösche ich " bool ret = CANInit(CAN_500KBPS, 0); " dabei ist egal ob
",0" oder ",2" läuft der Code weiter und die LED´s gehen wie gewünscht
an.
Ein anderer Gedanke kam mir, ich programmiere mit den ST LinkV2 und
nicht über die Arduino IDE, könnte das damit zusammen hängen?
Gruß
Kay
Kay L. schrieb:> lösche ich " bool ret = CANInit(CAN_500KBPS, 0); " dabei ist egal ob> ",0" oder ",2" läuft der Code weiter und die LED´s gehen wie gewünscht> an.
Dann schlägt die CANInit fehl. Höchstwahrscheinlich hier:
1
boolcan1=false;
2
CAN1->MCR&=~(0x1UL);// Require CAN1 to normal mode
3
// Wait for normal mode
4
// If the connection is not correct, it will not return to normal mode.
Das Datenblatt sagt dazu:
The request to enter Normal mode is issued by clearing the INRQ bit in
the CAN_MCR register (-> Zeile 2). The bxCAN enters Normal mode and is
ready to take part in bus activities when it has synchronized with the
data transfer on the CAN bus. This is done by waiting for the occurrence
of a sequence of 11 consecutive recessive bits (Bus Idle state). The
switch to Normal mode is confirmed by the hardware by clearing the INAK
bit in the CAN_MSR register.
Evtl. ist dein Bus nicht im Idle-State und der CAN-Controller verweigert
deshalb den Normal Mode? Hast du einen zweiten Teilnehmer am Bus der
auch funktioniert?
Hallo Kay,
ich empfehle die systematisch vorzugehen:
1. Setze in stm32f103.cpp mal DEBUG auf 1, dann sollte während CANInit
auf
Serial einiges an Informationen erscheinen.
2. Zeig mal ein Foto von deinem Testaufbau mit Anschluß des
Transceivers.
3. Mach auch noch ein Foto der STM32, möglichst mit Licht von der Seite
so dass man den Aufdruck gut erkennen kann.
Ich meine in der stm32f103.cpp auch noch einen Fehler entdeckt zu haben.
In
1
boolCANInit(BITRATEbitrate,intremap)
wird für
1
remap==0
folgende Zeile ausgeführt:
1
GPIOA->ODR|=0x1UL<<12;// PA12 Upll-up
PA12 ist aber der CAN_TX Ausgang, da macht ein Pull-up gar keinen Sinn.
Ich meine daher, dort müsste stattdessen folgendes hin:
1
GPIOA->ODR|=0x1UL<<11;// PA11 Pull-up
Dieses kleine Problem gilt nur für PA11, nicht für PB8, dort ist der
Code korrekt. Das Problem spielt auch gar keine Rolle mehr sobald ein
Transceiver angeschlossen ist, weil der seinen "R"-Ausgang treibt und
damit den Pegel an PA11 definiert.
LG, Sebastian
Soderle, ich glaube ich komme dem Übeltäter immer näher.
ich habe die Datei von Github komplett in meinen Sketch integriert, also
nicht als geteilete .h. und .cpp Datei.
Dabei bleibt der Code nicht stehen. Die LED´s mach was sie sollen.
Also muß ich beim "zerteilen" einen Bock eingebaut haben. Ich hab das
jetzt zig mal kontrolliert finde aber keinen.
Kann mal jemand schauen?
STM32_ino.txt ist die original Datei von Github. Die hab ich dann
zerlegt und wie oben beschrieben geändert:
stm32f103.cpp
und
stm32f103.h
Meine .ino Date:
CAN2_1.txt
Ich hab die Ino dateien nur als txt hier hochgeladen, damit die jeder
einsehen kann
LG Kay
Hallo Zusammen,
vielleicht kann jemand mir die Zeilen in der VOID_loop_CAN.txt
kommentieren,
damit ich verstehe, was in den einzelnen Zeilen geschieht
Dankeschön
Kay
Kay L. schrieb:> Also muß ich beim "zerteilen" einen Bock eingebaut haben. Ich hab das> jetzt zig mal kontrolliert finde aber keinen.> Kann mal jemand schauen?
In stm32f103.h ist ein Fehler. Die Deklaration von BITRATE muss so
lauten:
In dem Vorschlag von mir oben waren noch zusätzliche Bitraten enthalten,
sorry.
Ich habe auch noch eine erste Zeile #pragma once dazugefügt.
LG, Sebastian
Hallo Sebastian,
nun blockiert der Code nicht mehr. Top Danke. Und Du brauchst dich nicht
entschuldigen. Du hilfst mir sehr weiter. Fehlersuche bildet :-) Hab ich
wieder was gelernt.
Jetzt brauch ich nur noch kommentierungen was in welcher Zeile der VOID
LOOP passiert dann sollte ich der Sache langsam aber stetig auf den
Grund kommen.
Nochmals vielen leiben Dank!
LG
kay
Kay L. schrieb:> vielleicht kann jemand mir die Zeilen in der VOID_loop_CAN.txt> kommentieren, damit ich verstehe, was in den einzelnen Zeilen geschieht
Ich mach das mal mit CAN2_1.txt, weil VOID_loop_CAN.txt nicht
vollständig ist.
Zeile 13: counter zählt bei jedem Versand einer Nachricht hoch.
Zeile 14: Es werden später CAN-Nachrichten verschiedener Länge versandt.
In frameLength steht wie lang die nächste Nachricht sein soll.
Zeilen 41-52: CAN_TX_msg wird initial partiell befüllt.
Zeilen 54-56: Es wird alle interval Millisekunden etwas getan.
Zeilen 57-67: Der Rest der CAN_TX_msg wird befüllt. Wenn counter eine
gerade Zahl ist, wird das EXTENDED_FORMAT und die ID 0x32F103 gewählt,
sonst das STANDARD_FORMAT in die ID 0x103. Ausserdem wird bei
CAN_TX_msg.len 0 ein REMOTE_FRAME gesendet, ansonsten ein DATA_FRAME. Es
sollen hier halt einfach nur verschiedene Arten von CAN-Nachrichten mal
testweise erzeugt werden. Für die Details kuck bei
https://de.wikipedia.org/wiki/Controller_Area_Network.
Zeile 68: Die vorbereitete Nachricht wird an die Sende-Hardware zum
Senden übergeben.
Zeilen 69-71: Die Zähler werden erhöht.
Zeile 74: Es wird geprüft ob eine empfangene Nachricht bereitliegt.
Zeile 75: Die Nachricht wird aus Empfangshardware abgeholt.
Zeilen 77-108: Die empfangene Nachricht wird auf Serial ausgegeben.
HTH.
LG, Sebastian
Kay L. schrieb:> Fehlersuche bildet :-) Hab ich> wieder was gelernt.
Durch die zusätzlichen Einträge ist dein gewählter CAN_500KBPS Wert nach
hinten verschoben worden und hat den Wert 6 bekommen. CANInit holt sich
die target_bitrate unter diesem index aus dem SPEED-Array, und der hat
nur 6 Einträge. SPEED[6] liegt also hinter dem Array, und der Wert dort
im Speicher ist irgend etwas. ComputeCANTimings schlägt dann
wahrscheinlich fehl, gibt eine Fehlermeldung aus, und läuft in diese "if
(result) while(true)" Endlosschleife in stm32f103.cpp Zeile 340.
LG, Sebastian
Hallo Sebastian,
erstmal sorry das ich mich nicht gemeldet habe, aber ich musste mir
einen neuen Rechner zulegen und es war nicht ganz so einfach alles
wieder neu aufzusetzen.
ich habe noch ein paar Fragen:
Ich möchte zunächst nur den Zustand einer Variable übertragen.
Kann ich das so senden:
1
CAN_msg_tCAN_TX_msg;// CAN_TX_msg wird initial partiell befüllt. Daten die versendet werden sollen Begin Nachricht
2
CAN_msg_tCAN_RX_msg;
3
if(LEDAN==false)CAN_TX_msg.data[0]=0x00;
4
if(LEDAN==true)CAN_TX_msg.data[0]=0x01;
5
CAN_TX_msg.len=frameLength;// Daten die versendet werden sollen ende / Ende Nachricht
Mir ist die Empfangsseite nicht ganz klar da im Beispiel die Nachricht
mit der ID "0x32F103" versehen wird muss am Empfänger ja nach eben
dieser gefragt (bzw verglichen werden)
reicht eventuell:
1
if(CAN_RX_msg.id==0x32F103)
könnte ich da die Daten wieder in die Variable zurückwandeln?
zB
Kay L. schrieb:> Kann ich das so senden:
Im Prinzip ja. CAN_TX_msg.len, also die Länge des Datenbereichs der
CAN-Nachricht, ist bei dir immer genau 1 und sollte also auch mit 1
intialisiert werden. CAN_TX_msg.id, CAN_TX_msg.type und
CAN_TX_msg.format sollten auch noch gesetzt werden. Und
CAN_TX_msg.data[0] kann man auch weniger umständlich füllen :)
Kay L. schrieb:> könnte ich da die Daten wieder in die Variable zurückwandeln?
Im Prinzip ja. Auch das Auslesen von CAN_RX_msg.data[0] geht etwas
weniger umständlich. Ich würde auch wenigstens noch prüfen dass
CAN_RX_msg.len zumindest >=1 ist, aber dass sind eher schon Details
deines zu erstellenden Detailkonzepts von CAN-Nachrichten.
LG, Sebastian
Hallo zusammen,
vielen Dank an alle die mir bis hierhin geholfen haben.
ich habe es geschafft der Zustand der ersten Variablen zu übertragen.
Ich fühle mich wie Marconi :-)
Jetzt kann ich Schritt für Schritt weitermachen und verstehen, was
passiert, wenn man dies ändert.
Ich halte euch auf dem laufenden bzw komme bei Fragen nochmal auf euch
zu.
GLG
Kay
Hallo zusammen,
Soderle da ist doch noch eine allgemeine Frage zu CAN aufgetaucht.
Da nicht ständig gesendet werden muß (und auch soll) sondern nur wenn
eine Änderung des Zustandes eingetreten ist, reicht es wenn ich im
Sketch einmal sende?
z.B.:
1
if(next_state_Lichtschranke1!=akt_state_Lichtschranke1)// ---------------vergleich ob sich der Status der Lichtschranke1 geändert hat
2
{
3
// Hier dann senden der CAN nachricht
4
}
Sprich wird die Rückmeldung, ob die Nachricht angekommen ist über die
Hardware (Transiver) geregelt?
Gruß
Kay
Kay L. schrieb:> Da nicht ständig gesendet werden muß (und auch soll) sondern nur wenn> eine Änderung des Zustandes eingetreten ist
Bei CAN macht man es üblicherweise genau anders: Der Sender sendet
zyklisch, z.B alle 100ms, immer wieder seine aktuellen Daten.
Der oder die Empfänger lesen die Daten, entscheiden ob sich für sie
etwas geändert hat und ob deshalb etwas zu tun ist. Das hat den Vorteil
dass Empfänger die mal eine Nachricht verpasst haben dann beim nächsten
Sendezyklus die aktuellen Daten auch noch bekommen.
> Sprich wird die Rückmeldung, ob die Nachricht angekommen ist über die> Hardware (Transiver) geregelt?
Ein CAN-Empfänger sendet am Ende der gerade empfangenen Botschaft das
ACK-Bit an den Empfänger zurück. Der Empfänger weiß somit dass
mindestens ein Empfänger seine Botschaft "quittiert" hat.
Der Transceiver hat damit wenig zu tun, der leitet ja nur die Bits
weiter.
Thomas F. schrieb:> Kay L. schrieb:>> Da nicht ständig gesendet werden muß (und auch soll) sondern nur wenn>> eine Änderung des Zustandes eingetreten ist>> Bei CAN macht man es üblicherweise genau anders: Der Sender sendet> zyklisch, z.B alle 100ms, immer wieder seine aktuellen Daten.> Der oder die Empfänger lesen die Daten, entscheiden ob sich für sie> etwas geändert hat und ob deshalb etwas zu tun ist. Das hat den Vorteil> dass Empfänger die mal eine Nachricht verpasst haben dann beim nächsten> Sendezyklus die aktuellen Daten auch noch bekommen.>>
Erstmal danke, aber dann kann es doch passieren, das der Bus permanent
belegt ist, wenn ich zB 100 Nachrichten mit oberster Priorität alle
100ms sende. Oder nicht?
Kay L. schrieb:> Erstmal danke, aber dann kann es doch passieren, das der Bus permanent> belegt ist, wenn ich zB 100 Nachrichten mit oberster Priorität alle> 100ms sende. Oder nicht?
kann passieren, kommt natürlich auf die Bus-Geschwindigkeit an.
Der "Architekt" des Busses überlegt sich das im Vorfeld und prüft ob die
gewählte Baudrate das auch hergibt. Bei CAN heißt das dann "Bus-Last"
und winrd in Prozent-Auslastung angegeben.
Ein 500kBit Bus langweilt sich mit 100 Botschaften im 0,1s Zyklus zu
Tode.
Thomas F. schrieb:> Kay L. schrieb:>> Erstmal danke, aber dann kann es doch passieren, das der Bus permanent>> belegt ist, wenn ich zB 100 Nachrichten mit oberster Priorität alle>> 100ms sende. Oder nicht?>> kann passieren, kommt natürlich auf die Bus-Geschwindigkeit an.> Der "Architekt" des Busses überlegt sich das im Vorfeld und prüft ob die> gewählte Baudrate das auch hergibt. Bei CAN heißt das dann "Bus-Last"> und winrd in Prozent-Auslastung angegeben.>> Ein 500kBit Bus langweilt sich mit 100 Botschaften im 0,1s Zyklus zu> Tode.
OK Danke für den "Kernsatz" am Schluß ;-)
Beim CAN-Bus kann man ziemlich sicher sein dass eine Nachricht entweder
zugestellt wird oder sie nicht zustellbar ist. Der Fall "nicht
zustellbar" lässt sich evtl. auf Senderseite durch das Auslesen von
speziellen Registern erkennen.
Aber "ziemlich sicher" ist nicht "ganz sicher". Wenn du ganz sicher sein
möchtest, dann könnte z.B. der Empfänger nach Erhalt einer Nachricht
eine Quittung an den Sender zurücksenden.
Ich mach es bei meinem Haus- und Gartenbus so, dass ich jede
Statusänderung sofort melde, und dann noch jede Minute den vollen Status
versende. Ausnahme ist das Aufspielen neuer Software über den CAN-Bus,
dabei quittiere ich dem Sender jede einzelne Nachricht. Auch damit der
Sender nicht zu schnell wird, denn das Beschreiben des Flash dauert ein
wenig.
LG, Sebastian
hallo Zusammen,
ich steuere damit meine Modellbahnalage. Zur Zeit gehe ich von 4 Prios
aus:
1. Sensoren die belegte oder Einfahrt eines Zuges melden (um Kollisionen
zu vermeiden) also Fahrstreckenüberwachung
2. Manuelle steuerung der Fahrstrecken (Geschwindigkeitsregelung oder
Weichenschaltung sowie Daten für die Anzeigemodule
3. Sensoren in der Landschaft , Häuserbeleuchtung knopfdruckaktionen
usw.
Ich befürchte das bei ständigem senden von Prio 1 und Prio 2 Nachrichten
kein "Platz" mehr für Prio drei ist.
Kay L. schrieb:> Ich befürchte das bei ständigem senden von Prio 1 und Prio 2 Nachrichten> kein "Platz" mehr für Prio drei ist.
Nicht fürchten, ausrechnen. Wenn du den CAN-Bus mit 500kHz fährst,
passen pro Sekunde theoretisch 5000 Nachrichten a 100 Bit drauf. Die
Nachrichten mit numerisch kleineren Ids bekommen auf dem Bus Priorität
vor Nachrichten mit höheren Ids.
LG, Sebastian
Hallo Sebastian,
dann passt das wenn ich "nur" alle 500mS sende. Es ist nicht schlimm
wenn eine info um die Zeit verzögert ankommt.
Noch etwas, ich habe zwei Dinge gelesen:
1. In den Datenbits werden nur 8 Zustande (0-7) akzeptiert? also 8-F
wird ignoriert?
2. mit dem 11 Bit Identifier sind nur 2048 Nachrichten eindeutig zu
identifizieren? Müssten das nicht viel mehr sein?
Gruß
Kay
Kay L. schrieb:> 1. In den Datenbits werden nur 8 Zustande (0-7) akzeptiert? also 8-F> wird ignoriert?
Wo hast du denn das gelesen?
Ein Datenbit kennt nur 2 Zustände, 0 und 1.
Das Data-Segment einer CAN-Botschaft kann maximal 8 Daten-Bytes
innerhalb einer CAN-Botschaft transportieren. Ausnahme:CAN-FD, aber
lassen wir das vorerst.
> 2. mit dem 11 Bit Identifier sind nur 2048 Nachrichten eindeutig zu> identifizieren? Müssten das nicht viel mehr sein?
Warum, reicht doch? Die Kommunikation in modernen Autos kommt mit 11-Bit
Identifiern aus.
Kay L. schrieb:> In den Datenbits werden nur 8 Zustande (0-7) akzeptiert? also 8-F wird> ignoriert?
Nein, das stimmt nicht. Höchstwahrscheinlich hast du da etwas
missverstanden. Das Datenfeld besteht aus 0 bis 8 Bytes aus 8 Bits.
Jedes Datenbyte kann jeden Wert zwischen 0 und 255 annehmen. Das
Datenlängenfeld bestimmt die Anzahl der Datenbytes. Es ist zwar 4 Bit
lang, darf aber nur Werte zwischen 0 und 8 annehmen, 9-15 sind nicht
erlaubt.
Kay L. schrieb:> mit dem 11 Bit Identifier sind nur 2048 Nachrichten eindeutig zu> identifizieren? Müssten das nicht viel mehr sein?
Wenn man Nachrichten numerieren möchte, dann sollte so eine Nummer wohl
besser Teil der Datenbytes sein. Die Id wird meist für den Typ der Daten
verwendet, auch weil man per Hardware auf Ids filtern kann. Aber wenn du
lustig bist kannst du auch einen Teil der Id-Bits für Daten verwenden,
die CAN-Bus-Spezifikation selbst hindert dich nicht daran ...
LG, Sebastian
Hallo Zusammen,
ich habe nun ein wenig rumexperimentiert und steige so halbwegs durch.
bis jetzt übertrage ich nur zwei Zustände pro Datenbyte in etwa so:
Variable A = false dann CAN_TX_msg.data[0] = 0x00
Variable A = true dann CAN_TX_msg.data[0] = 0x01
Das klappt einwandfrei
Das bedeutet aber wiederum das ich nur 2 Variablen in data[0]übertragen
kann.
Wenn ich das richtig versteh können aber die eigentlich daten digits
(also die letzten beiden) 0 bis F annehmen (0x00 bis 0xFF) dann könnte
ich den Zustand (0 oder 1) von 4 verschiedenen Lichtschranken pro Ziffer
übertragen.
für die letzte Ziffer in etwa so:
LS1 - LS2 - LS3 - LS4
0 - 0 - 0 - 1
würde 1 als letzte Ziffer ergeben
LS1 - LS2 - LS3 - LS4
1 - 1 - 1 - 1
würde F als letzte Ziffer ergeben.
Ich bekomme nur gerade nicht wirklich hin die 4 Zustände in eine Hex
umzuwandeln, die ich übertragen kann.
Gruß
Kay
Kay L. schrieb:> Ich bekomme nur gerade nicht wirklich hin die 4 Zustände in eine Hex> umzuwandeln, die ich übertragen kann.
Du musst die vier Zustände in eine Zahl umwandeln. Hexadezimal oder
Dezimal sind nur Darstellungsformen von Zahlen, die aber mit der
Übertragung nichts zu tun haben.
Dazu muss man ein wenig Binärarithmetik veranstalten.
Also z.B zum Senden:
Du verwendest immer noch frameLength als Länge der gesendeten Daten? Und
der Code bastelt auch immer noch mit REMOTE_FRAME rum? Und warum
EXTENDED_FRAME und so hohe Id (0x32F103)? Da würde ich erst einmal alle
Überbleibsel der Testanwendung rausräumen die du (noch) nicht brauchst.
LG, Sebastian
Da ich mir nicht sicher war was ich davon ggf noch brauche hab ich es
noch nicht rausgeworfen. Das wollte ich machen nachdem die Übertragung
in Hex auch funktioniert.
EXTENDED_FRAME bedeutet doch nur das ich eine höhere ID Zahl habe. Ich
ändere das aber heute Abend ab. Auch die ID setze ich dann auf den
kleinsten Wert zum Test.
Ich melde mich dann wieder
Gruß
Kay
Kay L. schrieb:> Er erkennt also die ID 0x000001 nicht. Ich sehe aber gerade nicht, warum...
Ich auch nicht. Welche Id WIRD denn empfangen?
LG, Sebastian
Hallo Sebastian,
wie meinst du das ? Es gibt nur eine Nachricht und die hat die ID
0x000001 . Es sind auch nur die zwei Telnehmer am Bus. Ich kann auch
eine andere ID nehmen. Die Übertragung funktioniert immer nur wenn im
Empfänger die else Schleife drin ist.
Oder meinst Du wie die Daten vom Logiganalyser aussehen?
einen Screenshot findets Du im Anhang
Gruß
Kay
Kay L. schrieb:> Die Übertragung funktioniert immer nur wenn im Empfänger die else> Schleife drin ist.
Ich meine: Warum wird der else-Zweig betreten? Doch anscheinend weil im
Empfänger die Id nicht 0x000001 ist. Was ist sie denn? Gib die Id mal
auf die serielle Schnittstelle aus. Oder besser: Schreib dir eine
Prozedur die generell eine CAN_msg_t komplett auf die serielle
Schnittstelle ausgibt, und ruf die Prozedur direkt vor dem Senden und
direkt nach dem Empfang auf.
LG, Sebastian
PS: Du benutzt die Saleae-Software? Die hat einen Analysator für CAN ...
Ok Nun verstanden.
Da muß ich mal sehen ob das mit der seriellen Schnittstellenausgabe bei
mir überhaupt geht, da ich nicht mit der Arduino Software das Board
beschreibe sondern eine kompilierte Binärdatei exportiere und dann mit
ST - LinkV2 auf den STM32 programmiere.
Ich hab das noch nicht ausprobiert.
ja ich nutze Logic2 von saleae, wohl die Freewareversion. Bis Dato hab
ich noch keinen CAN Analysator gefunden.
Gruß
Kay
So CAN Analyser gefunden.
Screenshot anbei Ch1 ist TX am Sender. ist Async Serial die ID? dann ist
die 0xFF und nicht 0x000001 was das verhalten erklären würde. Ich aber
(noch) keinen blassen Schimmer habe warum die ID falsch ist.
Ausserdem zeigt er mir zweimal Error an.
ich muß jetzt leider weg. Ich werde morgen die funktionierenden Sketche
in die STMs einprogramieren und erneut messen. Mal sehen ob die Fehler
dann weg sind.
Und wieder mal, vielen Dank Sebastian.
Gruß
Kay
Kay L. schrieb:> Bis Dato hab> ich noch keinen CAN Analysator gefunden.
Siehe Bild.
Kay L. schrieb:> einen Screenshot findets Du im Anhang
Ich hab das mal händisch dekodiert. Das ist eine saubere STANDARD DATA
CAN-Nachricht mit id 0x0001, len 0x01 und data[0] 0x00. Die Prüfsumme
stimmt, und der Empfänger hat den korrekten Empfang mit ACK quittiert.
Kay L. schrieb:> Da muß ich mal sehen ob das mit der seriellen Schnittstellenausgabe bei> mir überhaupt geht.
Alternativ kuck es dir im Debugger an. Aber irgendeine Möglichkeit,
deine Software im laufenden Betrieb zu untersuchen, wirst du brauchen
...
LG, Sebastian
Kay L. schrieb:> creenshot anbei Ch1 ist TX am Sender. ist Async Serial die ID? dann ist> die 0xFF und nicht 0x000001 was das verhalten erklären würde.
Erstens hast du nicht die ganze CAN-Nachricht erwischt, die ersten zwei
Bits oder so fehlen.
Zweitens ist Async Serial der Analysator für eine serielle
Schnittstelle. Den solltest du mal deaktivieren oder entfernen, der
hilft hier nicht.
[[[ Wenn du Debug-Meldungen auf einen seriellen Port ausgibst, dann
kannst du an diesen Port auch noch den Logik-Analysator anschließen, und
die Ausgaben mit Async Serial als Text darstellen lassen. So sieht man
manchmal ganz gut die Programmreaktionen auf eingehende Nachrichten und
so. ]]]
Drittens musst du dem CAN-Analysator mitteilen, welchen Kanal er
dekodieren soll. Nimm am besten Empfänger-RX. Sender-RX ginge aber auch,
es geht nur darum dass der Analysator auch das ACK-Bit sieht.
LG, Sebastian
Sebastian W. schrieb:> Ich hab das mal händisch dekodiert. Das ist eine saubere STANDARD DATA> CAN-Nachricht mit id 0x0001, len 0x01 und data[0] 0x00. Die Prüfsumme> stimmt, und der Empfänger hat den korrekten Empfang mit ACK quittiert.
Dann ist ja alles wie es sein sollte. Trotzdem empängt der nur wenn ich
zu
die else funktion nach der if ID = 0x0001 einfüge. Da mus da doch
irgendwo ein Bock sein.
Blöde Frage; Spaces werden ignoriert? Nicht das ich etwas suche, was man
nicht sieht.
PS: zum "händisch dekodoert, hast du ev einen Link wo ich nachschauen
kann wie man das macht?
GRuß
Kay
PPS: Mit mir hast Du dir ja ganz schön einen ans Bein gebunden..... ;-)