Ich öffne mal für die serielle Kommunikation des Sunstar S03 eBike
Mittelmotor - Lenkerdisplay einen eigenen Thread.
Hab rausgefunden dass der Motor zwei Byte schickt, worauf das Display
mit einem Byte antwortet, welche Knöpfe gerade gedrückt sind.
Das zweite Byte des Motors scheint 0xff zu sein, davon sieht man also
nur das Startbit.
Davor dann halt das Statusbyte, dessen erste 4 Bit ich entschlüsseln
konnte.
Zu beachten dabei, dass die Bits in der Reihenfolge vertauscht werden
müssen.
Nun hab ich große Schierigkeiten, mit Arduino Nano, die zwei Bytes zu
empfangen, was neben dem fehlenden Stopbit wohl auch an der kruden
Baudrate von gemessenen 19375 Baud liegt.
Siehe Bild im Anahng.
1
00010011 13 mid no light
2
00100011 23 high no light
3
01000011 43 low no light
4
5
10010011 93 mid and light
6
10100011 a3 high and light
7
11000011 c3 low and light
8
9
1000 / (0,8 ms / 15,5 bit) = 19375 baud
Ich erziele mit dem einen Hardwareserial (dann halt leider kein
debugging mehr möglich) und 19200 baud ganz passable Ergebnisse:
https://youtu.be/DJE9R2gr2jQ
Vielleicht findet Ihr aber eine andere Erklärung als 19375 baud, 8 bit,
pairty, KEIN Stopbit
das Roland
Das R. schrieb:> KEIN Stopbit
Das Stop-Bit ist immer 1, darum siehst du es nicht ;)
Das R. schrieb:> eBike MittelmotorDas R. schrieb:> an der kruden Baudrate von gemessenen 19375 Baud
Es könnte LIN-Bus sein. Nominal 19200baud, aber Toleranz erlaubt.
Kannste googeln, bei der Firma Vector Informatik und bei der Firma
Softing gibt es viel nützliche Informationen dazu
mfg mf
minifloat schrieb:> Das R. schrieb:>> KEIN Stopbit>> Das Stop-Bit ist immer 1, darum siehst du es nicht ;)
Ja klar aber man sieht ja das Startbit des zweiten Bytes !!!
Und davor ist ein wechselndes Bit was perfekt zu der Parität passt.
Also kein Stop bit.
minifloat schrieb:> PS, vielleicht kein LIN, aber ähnlich. Das Low-Nibble scheint immer 0011> zu sein, womit sich ebenfalls die Baudrate vermessen lässt...
Nein kurz bevor der Motor auf störung geht, sind die linken vier bits
manchmal verschieden von 1100 :-/
Einzige Möglichkeit wäre noch 10 bit und es existiert kein zweites 0xff
byte, sondern dass ist nur die Pause zwischen dem Empfang des
Motorstatus-bytes und dem Rücksenden des Display bytes. Das klingt mir
aber total unplausibel
Ungerade Baudraten gibt es nicht. Wie soll den der Empfänger das Stopbit
erkennen.
Bei einer z.b. 8 Bit Übertragung werden einfach die Bits gezählt. Nach
den 8 Bit kommen 1-2 Bits die ein bestimmten Wert haben müssen damit das
"Paket" als richtig gilt.
Gruß
Pucki
Sorry, i see. Kann es sein, dass ein Frame immer 11Bit lang ist und es
ein Start- und ein Stop-Bit gibt, die beide immer 0 sind?
Mit dieser Konvention sind auch krumme Baudraten und eine Vermessung
derer möglich.
Das gesumms kann mit einer 16bit-SPI eingelesen und erzeugt werden,
wobei man einem Timer zum Vermessen der Master-Baudrate braucht.
mfg mf
Ohne Stopbit, mit Parity ginge überhaupt nur, wenn das letzte Bit (das
Paritybit) immmer high ist. Ansonten klappt es mit dem nächste Startbit
(high->low) nicht. Das ist dann aber doch ein Stopbit.
Baudrate 19.375 ist 19.200 mit nur 1% Abweichung, das passt schon.
Oliver
Alexander K. schrieb:> Ungerade Baudraten gibt es nicht.
Doch, das gibt es. Die Baudrate ist eine Konvention zwischen Sender und
Empfänger, damit der Empfänger zur jeweils richtigen Zeit auf die Bits
schaut.
mfg mf
Bitte schaut Euch das Bild an und denkt Euch eigene Vorschläge aus.
Entweder sind das zwei Byte mit dem zweiten als 0xff Oder der Motor
schickt eh immer nur ein einziges Byte. Dann gäbe es keine Folgebytes
auf die synchronisiert werden müsste !
Ich kann ja mit 19200 baud das erste Byte auslesen und auch das
gewünschte button-byte zurücksenden. Es können also auch 19200 baud
sein.
Hier als zweites Bild die gesammte bidirektionale Kommunikation über ein
kabel. (das mit den getexten bits is sicherlich falsch gestextet)
Zuerst das Byte vom Motor, dann entweder 0xff vom Motor oder Zeitspanne,
dann Antwort vom Display.
Naja, das Stoppbit ist schon da. Nur dass vorher noch ein 0-Bit ist.
Witzig. Hab ich zwar so noch nicht gesehen, aber schreckt mit einfachen
Mitteln einen großteil der Hobbyfreaks ab.
Also die eine Seite sendet 9-bit + Parity odd, wobei die 9bit schon
selber ihre Parity bilden, die andere sendet ganz normal 9 Bit
insgesamt, evenfalls parity odd.
der erste Empfänger ignoriert einfach die Framing errors und ist fertig.
Lass doch mal die Rückantwort genauso dekodieren, vielleicht ergibt das
auch immer gültige Frames für den Sender. Mir scheint, dass es da bei
der Rückantwort 3 low, 4 high, 3 low gibt. das passt perfekt.
Bei einer UART-mäßigen Übertragung gibt es immer ein Stopbit. Der
Empfänger erkennt den Start eines Wortes anhand der (bei deiner
Polarität) fallenden Flanke das Startbits. Damit dort eine Flanke ist,
muß vorher ein Stopbit (plus evtl Idle) die Leitung auf High gesetzt
haben. Ohne Stopbit keine Flanke, kein Startbit, keine Übertragung.
Überleg dir einfach, wie die Leitung aussehen würde, wenn nur konstant
Nullen ohne Stopbit übermittelt würden ...
Wieviele Datenbits zwischen Start- und Stopbit sind, ist ziemlich egal.
Allerdings: je mehr, desto genauer müssen die Takte der
Kommunikationspartner übereinstimmen - die Unterschiede summieren sich
für jedes Bit und irgendwann laufen die dann auseinander.
Das oberste Bild könnten z.B. zwei Wörter mit 5N1 sein. Oder auch ein
Wort mit mindestens 10 Bits (Nutzdaten plus Parity).
foobar schrieb:> Das oberste Bild könnten z.B. zwei Wörter mit 5N1 sein. Oder auch ein> Wort mit mindestens 10 Bits (Nutzdaten plus Parity).
Naja im Grunde kann es mir egal sein, was nach dem 9ten bit kommt. Das
9te bit scheint das Paritätsbit zu sein, wenn der atmega328p das
unterstützt hab ich fehlererkennung, wenn nicht dann nicht.
Und danach kommt eh keine Info mehr.
Mein Problem ist jetzt, nach so 0,6 ms das Antwortbyte zu senden. Und
das will ja so gar nicht klappen, siehe das video.
foobar schrieb:> Überleg dir einfach, wie die Leitung aussehen würde, wenn nur konstant> Nullen ohne Stopbit übermittelt würden ...
Das gibt es auch, mit dem Unterschied, dass das Startbit dann 1 ist, um
einen Frameanfang zu erkennen. Impliziert natürlich ein oder mehrere
Stopbits mit 0-Pegel.
mfg mf
Das R. schrieb:> Mein Problem ist jetzt, nach so 0,6 ms das Antwortbyte zu senden. Und> das will ja so gar nicht klappen, siehe das video.
Wieso? Kein RX Interrupt? Ohne fifo
A. S. schrieb:> Das R. schrieb:>> Mein Problem ist jetzt, nach so 0,6 ms das Antwortbyte zu senden. Und>> das will ja so gar nicht klappen, siehe das video.>> Wieso? Kein RX Interrupt? Ohne fifo
Nein selbst die serialEvent function kann anscheinend die loop() nicht
unterbrechen. Arduino ist halt nur für 0815 Andwendungen :-/
Wie man den FIFO ausschaltet weiß ich nicht, aber das bringt nichts:
#define SERIAL_RX_BUFFER_SIZE 2
#define SERIAL_TX_BUFFER_SIZE 1
Also wenn ich gleich zu Begin der serialEvent reine digitalWrite(..)
setzte, anstatt Serial.write(..), und so tatsächlich das Rücksendebyte
soweit simulieren kann dass der Motorcontroller nicht auf Störung geht,
dann erscheint dieses künstliche Byte tatsächlich direkt nach dem
empfangenen Statusbyte des Motorcontrolers.
Aber sobald ich in der loop() auch was tue, verschiebt sich das
künstliche Byte immer weiter nach hinten.
Anbei ein gif von dieser loop:
1
void loop()
2
{
3
for (int i=0; i<30; i++) digitalWrite(LED_BUILTIN, (millis()/500)%2);
4
}
Und hier der komplette Testcode:
1
//#define SERIAL_RX_BUFFER_SIZE 2
2
//#define SERIAL_TX_BUFFER_SIZE 1
3
4
#define BAUD_DISPLAY 19200
5
#define TX 1 // pin 1 is TX on Arduino Nano
6
uint8_t iAssist = 0;
7
8
void setup()
9
{
10
Serial.begin(BAUD_DISPLAY); // 19375
11
pinMode(LED_BUILTIN, OUTPUT);
12
}
13
14
void loop()
15
{
16
for (int i=0; i<30; i++) digitalWrite(LED_BUILTIN, (millis()/500)%2);
Mir gelingt es übrigens auch nicht, das auf TX künstlich gesendete Byte
nicht gleich wieder auf RX zu empfangen. Obwohl ich eigentlich das
UCSR0B Byte temporär lösche.
Ist halt doof dass die Entwickler beide Richtungen über das selbe Kabel
laufen lassen - obwohl eine Leitung offensichtlich ungenutzt blieb.
Das R. schrieb:> display_receive.gif> 3,74 MB
Der Staub auf deinem Display interessiert hier niemanden.
Achte bei hochgeladenen Photos bitte auf entsprechende Bildformate,
für Animationen also besser PNG-Screenshots als Basis.
A. S. schrieb:> Off Topic: Das DSO Shell, macht das die Gifs und die Auswertung> schon so> einfach direkt? Welchen Typ kann da jemand empfehlen?
Nee nee. Das sind einzelen Photos mit dem Smartphone "auf Stativ" die
anschließen mit Gimp als eigene Ebenen geöffnet wurden. Dann kann man
ganz einfach mit ".gif" als gif-animationen exportieren.
Die 20 Euro für das 9V DSO kann ich aber trotzdem empfehlen:
https://de.aliexpress.com/item/4001079570967.html
Wobei ich inzwischen auch welche mit wohl mehr features sehe:
https://de.aliexpress.com/item/4000435245024.html
Gibt bei youtube bestimmt "reviews"
Das R. schrieb:> Die 20 Euro für das 9V DSO kann ich aber trotzdem empfehlen:
Das heißt, die serielle Auswertung ist von dir per Auge reingepinnt?
Ein einfaches oszi, das solche Pegel direkt binär anzeigt, das wär was
für mich.
korrekt, ich hab mit "Courier" einen font gewählt der für jedes Zeichen
den selben Abstand hat und dann so lange mit der Fontgröße gespielt, bis
ich für EUCH ein schönes Bild gebastelt hatte. ja ja..
Das R. schrieb:> bis ich für EUCH ein schönes Bild gebastelt hatte
Whow, ... Ich dachte noch so, was für ein Twat, wenn er mit SO einem
geilen Equipment nicht weiter kommt ....
Und was für ein geiles Equipment, dass sogar ein Bit zuviel noch
decodiert...
;-)
Das R. schrieb:> Ich glaub ich werde> mit ...> meine eigene UART implementieren
Der Atmega328 hat einen "UART RX complete" Interrupt, eventuell könntest
du in diesem kurz warten (Ich weiß, macht man nicht) und dann Senden.
Besser wäre natürlich in dem einen Timer starten und in dem Timer
Interrupt dann zu Senden. Wie und ob das in Arduino geht hab ich keine
Ahnung, in C ist das aber ganz einfach.
Die Hardware zu nutzen dürfte aber wesentlich einfacher sein als das per
Bit Bang auszugeben.
A. S. schrieb:> Ein einfaches oszi, das solche Pegel direkt binär anzeigt, das wär was> für mich.
du suchst einen Logic Analyzer, ein ca.10€ Salea Nachbau wäre das,
braucht halt einen PC zur Anzeige.
K. S. schrieb:> Das R. schrieb:>> Ich glaub ich werde>> mit ...>> meine eigene UART implementieren>> Der Atmega328 hat einen "UART RX complete" Interrupt, eventuell könntest> du in diesem kurz warten (Ich weiß, macht man nicht) und dann Senden.> Besser wäre natürlich in dem einen Timer starten und in dem Timer> Interrupt dann zu Senden. Wie und ob das in Arduino geht hab ich keine> Ahnung, in C ist das aber ganz einfach.>> Die Hardware zu nutzen dürfte aber wesentlich einfacher sein als das per> Bit Bang auszugeben.
Hab mit einem pin-interrupt und einem timer-interrupt das ganze selber
gelöst und so die hardware uart zurück für den debug output:
https://youtu.be/9VCfnFRpVyc
K. S. schrieb:> du suchst einen Logic Analyzer, ein ca.10€ Salea Nachbau wäre das,> braucht halt einen PC zur Anzeige.
Nein, genau den nicht. Wenn es Probleme gibt, dann analoge, also dass
die Pegel so aussehen wie beim TO, und z.B die umschaltschwelle
"justiert" werden muss oder das Signal per variablem R in Reihe oder
parallel.
Und da muss ich mir dann immer extra ein Oszi holen und per Auge
decodieren.