Das Programm soll - irgendwann - einen Wechselrichter per RS485 - steuern.
serial_read(0x01030000000184ff);
Sendet eine bestimmte Zeichenfolge auf die der WR antworten muss.
Zur Zeit ist der Empfänger ein c#-Programm auf dem PC.
Die Zeichenfolge wird im Prinzip richtig gesendet. Nur ohne das delay werden die letzten beiden Zeichen mit '0' ausgegeben. D.h. Die Übertragung wird durch den auf den Sende-Befehl folgenden Befehl vorzeitig abgebrochen.
Eigentlich müsste doch das Setzen des TXCO-Bits abgewartet werden?
Der Code an sich ist eigentlich gar nicht mal so lang wenn man die
unnötigen Leerzeilen rauslöscht. Hab ich mal gemacht...
Wenn der Code nicht mehr auf eine Seite passt, der Zeilenzähler dreistellig wird und damit die Forensoftware die Formatierung nicht mehr sauber hin bekommt, fühlt sich das lang an.
Nur ohne das delay werden die letzten beiden Zeichen mit '0' ausgegeben.
siehst du die beiden "Nullwerte" auch so mit einem Oszi auf der Leitung?
was passiert, wenn du nochmal zusätzlich 2 Bytes ausgibst?
Zur Zeit ist der Empfänger ein c#-Programm auf dem PC.
kannst du da mal ein "übliches" Terminalprogramm" verwenden?
welche Hardware verwendest du? Es gibt mir zu denken, dass du RS485 schreibst. Da muss zum richtigen Zeitpunkt der Treiber von "Senden" auf "Empfangen" umgeschaltet werden...
Schon mal was von einer Schleife gehört? Oder wirst du nach Programmzeilen bezahlt?
Hat es einen Grund, warum das so äußerst merkwürdig machen willst?
Eine Halbduplex-Sendefunktion baut man anders. Außerdem löscht man das TXC0 Flag, indem man eine 1 reinschreibt! Klingt komisch, ist aber so! RTFM!
UCSR0A &=~ (1<<TXC0);
Damit wird TCX0 NICHT gelöscht! Eher so.
UCSR0A |= (1<<TXC0);
Ja, so!
Außerdem prüft man für das Senden meistens UDRE0, denn damit kann man lückenlos senden. Das ist ja der Witz des Sendepuffers. Nur beim letzten Byte prüft man TXC0, um dann den Tranceiver wieder auf Empfangen bzw. Tristate zu schalten. Siehe Anhang. Solche Daten übergibt man aber besser als Pointer auf ein Bytearray, nicht als 64 Bit Zahl.
welche Hardware verwendest du? Es gibt mir zu denken, dass du RS485
schreibst. Da muss zum richtigen Zeitpunkt der Treiber von "Senden" auf
"Empfangen" umgeschaltet werden...
M328-Nano + RS485-Adapter, ich mach heute abend mal ein Foto.
Mit PORTC &= ~(1<<2); wird von Senden auf Empfangen umgeschaltet.
//for (uint8_t i=14;i-=2;i<254)
Hatte ich zuerst probiert - ging aber nicht. Wenn das Ganze erst mal funktioniert werde ich das noch layouten - wobei die Auflösung der Schleife durchaus Sinn ergeben kann weil die Steuerung der Schleife wegfällt.
Danke für alle Hinweise - insbesondere TXC0-Flag. Ich werde das heute abend probieren und berichten.
M328-Nano + RS485-Adapter, ich mach heute abend mal ein Foto.
Wenn du kein Oszi hast, dann teste deine Software mal mit einer normalen RS232-Schnitte, da muss der Treiber nicht umgeschaltet werden und du siehst was der µC tatsächlich sendet.
Das Programm soll - irgendwann - einen Wechselrichter per RS485 -
steuern.
serial_read(0x01030000000184ff);
Sendet eine bestimmte Zeichenfolge auf die der WR antworten muss.
Ganz schlechter Stil. Eine Funktion sollte nur genau DAS machen, was der Name besagt! Bei dir solltest du senden und empfangen in getrennte Funktionen packen.
aber trotzdem richtig, denn der Wechselrichter soll ausgelesen werden. Die write-Funktion gibt es auch. Da soll in das Register des WR geschrieben werden.
aber trotzdem richtig, denn der Wechselrichter soll ausgelesen werden.
Die write-Funktion gibt es auch. Da soll in das Register des WR
geschrieben werden.
Dann nennt man es aber readRegister oder ähnlich. Und wieso braucht ein LESEfunktion einen 64 Bit Parameter? Dort gehört eher eine Registeradresse rein.
Vielen dank für die Hilfe. Fehler war tatsächlich txc0 1 statt 0 zum löschen. Ich hatte offenbar nur bis >cleared by writing< gelesen und mir den Rest falsch gedacht.
Nutze dein Steuersignal für den Tranceiver (PC2) als Trigger zur Messung mit dem Oszi (Kanal 1). Dann siehst du die Sendedaten vom Arduino zum Wechselrichter und dessen Antwort (Kanal 2). Damit kannst du eine systematische Fehlersuche starten.
Woran kann das liegen? Ist der Adapter unbrauchbar?
Senden M328-PC und M328-WR und PC-WR geht.
Wer sagt das? Wie hast du das gemessen?
Ich sende die Zeichenfolge (0x010300000001840a) an den Wechselrichter. Wenn der Wechselrichter "0x0103020005 + 2byte crc" antwortet, funktioniert die Kommunikation in beide Richtungen.
Die Oszi-Bilder 2+3 sehen erkennbar anders aus als Bild 1. Die dreieckigen Zacken können nicht als eindeutige digitale rs485-Signale ausgewertet werden - Hardwareproblem. Der Adapter ist in der Lage, Signale vom PC umzuformen - nicht jedoch Signale vom WR. Die sind vermutlich ein bisschen anders und daher in einem Grenzbereich, den der Adapter nicht auswerten kann.
Ich hab den Adapter gewechselt und sehe jetzt die richtige Antwort des WR - 01-03-02-00-05 zumindest auf dem Oszi (Bild 4/ mangels Kabel per Camera). Das Signal kommt jetzt richtig auf dem rx Pin an. Den Rest bekomm ich dann - wahrscheinlich - irgendwie hin.
Jedenfalls Danke für die wirklich hilfreiche Unterstützung.
Ich sende die Zeichenfolge (0x010300000001840a) an den Wechselrichter.
Wenn der Wechselrichter "0x0103020005 + 2byte crc" antwortet,
funktioniert die Kommunikation in beide Richtungen.
Die Oszi-Bilder 2+3 sehen erkennbar anders aus als Bild 1.
Mal in Ernst. Was soll das? Dein Oszi kann DIGITALE, SCHARFE Screenshots auf USB ausgeben. NUTZE DAS! Nicht diesen verwaschenen Mist mit dem Handy!
Die
dreieckigen Zacken können nicht als eindeutige digitale rs485-Signale
ausgewertet werden - Hardwareproblem.
Ja welches Signal sehen wird denn da wirklich? An welchem IC an welchem Pin wurde gemessen?
Der Adapter ist in der Lage,
Signale vom PC umzuformen - nicht jedoch Signale vom WR. Die sind
vermutlich ein bisschen anders und daher in einem Grenzbereich, den der
Adapter nicht auswerten kann.
Glaub ich nicht. Ist eher ein Schaltungsfehler deinerseits.