- Symulator MaSzyna -
Symulator EU07 (i nie tylko) => Bieżące Symulatorowe => Wątek zaczęty przez: marcinn w 09 Maja 2021, 04:18:50
-
Witajcie.
Jestem po dosyć długiej diagnostyce problemów komunikacji z Maszyną.
Wydaje mi się, że synchronizowanie ramek nie działa. Tzn. działa, ale łapanie synchronizacji jest dziełem przypadku i zależy od kompilatora.
W momencie kiedy Maszyna gubi synchronizację, zaczyna czytać bajt po bajcie. Preambuła sprawdzana jest tak:
if (sc == 0xEF)
sync_cnt++;
Jednak zmienna "sc" zdefiniowana jest jako char, a char jest signed:
char sc = 0;
Skutkuje to (przynajmniej u mnie) pomijaniem bajtów "0xEF" i "zmęczeniem" synchronizacji ze względu na przekroczoną ilość prób.
Może ktoś będzie w stanie to potwierdzić. U siebie zmieniłem na unsigned char i widzę poprawę.
PS. Wrzucam na tę chwilę na forum, bo zgodnie z odp. PW od Milek7 najpierw trzeba dogadać komu (do którego forka i której gałęzi) podrzucać PR. Poza tym wydaje mi się, że kompilator VS (dla Windows) może dawać ten sam efekt, co czyniłoby błąd raczej krytycznym (dla korzystających z pulpitów).
-
Poza tym wydaje mi się, że kompilator VS (dla Windows) może dawać ten sam efekt, co czyniłoby błąd raczej krytycznym (dla korzystających z pulpitów).
Visual C domyslnie traktuje char jako signed (chyba ze dostanie inaczej w konfiguracji) wiec tak, zachowanie zapewne jest takie samo. Nie pamietam by ktos sie specjalnie skarzyl na problemy z synchronizacja, ale dalem na wszelki wypadek u siebie podmiane na unsigned.
-
Wpadłem na to grzebiąc w libie do Arduino. Zdarza mi się bowiem, że uruchomienie Maszyny resetuje mi uC (Mega 2560). Czytałem że jest to normalne po otwarciu portu szeregowego i bardziej dziwi mnie, że z rzadka to nie następuje.
Problem nie jest zauważalny, gdy po stronie Arduino transmisja określona jest tak:
uint8_t output[20] = {0xEF, 0xEF, 0xEF, 0xEF};
uint8_t input[52] = {0};
void setup() {
Serial.begin(19200, SERIAL_8N1);
while (!Serial);
}
void loop() {
Serial.readBytes((uint8_t *) &input, 52);
Serial.write((uint8_t *) &output, 20);
}
Ale problem można odtworzyć na wersji Maszyny z signed char, gdy w kodzie uC dodasz guarda:
uint8_t output[20] = {0xEF, 0xEF, 0xEF, 0xEF};
uint8_t input[52] = {0};
void setup() {
Serial.begin(19200, SERIAL_8N1);
while (!Serial);
}
void loop() {
if (Serial.available() >= 52) {
Serial.readBytes((uint8_t *) &input, 52);
}
if (Serial.availableForWrite() >= 20) {
Serial.write((uint8_t *) &output, 20);
}
}
Przy signed char Maszyna nie łapie synca:
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: tired of trying
uart: bad sync
uart: read byte: 0
uart: read byte: -17
uart: read byte: -17
uart: read byte: -17
uart: read byte: -17
uart: read byte: 4
uart: read byte: -128
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
uart: read byte: 0
Ale po zmianie na unsigned char - już tak:
uart: tx: EF EF EF EF 00 00 00 00 00 00 08 03 0C B0 00 DA 09 00 00 00 00 00 00 00 00 B4 5E 76 2F 1F 02 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
sm42-907 received command: [aidriverdisable]
New order for [passat]: JumpToNextOrder
[...]
uart: bad sync
uart: read byte: 0
uart: read byte: 239
uart: read byte: 239
uart: read byte: 239
uart: read byte: 239
uart: synced, skipping one packet..
uart: sync ok
Bez guarda readBytes() czeka na bufor wejściowy przez czas określany za pomocą Serial.setTimeout(), domyślnie 1s.
Zależy mi na tym, żeby blokować loop() czekając na dane.