V sériové lince se ztrácí odeslaná data
Napsal: 26 úno 2021, 10:22
Mám problém s odesíláním dat v "jednobajtovém" formátu do sériové linky.
Nějak se mi ztrácí data a nemůžu přijít na to, co se děje.
Konkrétní příklad:
Mám pole dat o délce 33 bajtů.
Skutečně uložené hodnoty v tom poli jsou následující:
Tyhle data potřebuju poslat do sériove linky jako jednotlivé bajty (bez převodu na text) - prostě jen 33 obyčejných bajtů, žádné oddělování, žádné ukončování.
Data posílám přes RS485. Přepínání mezi příjmem a vysíláním mám bez problému funkční.
Věnujte pozornost těm 10 hodnotám 0xFF v závěru pole (indexy 22 až 31).
Když napíšu tuto jednoduchou smyčku, program funguje podle očekávání.
Nejdřív odešle do linky hodnotu položky pole v textovém formátu (podle počtu cifer čísla je to 1 až 3 bajty) a ukončí se sekvencí CR+LF (0x0D, 0x0A).
Hned potom se odešle jednobajtová hodnota z požadované položky pole (to je to, co chci ve finále získat).
Výpis, ve kterém jsem ručně upravil řádkování a mezery, aby bylo zřetelné, kde jednotivé položky začínají a končí:
(výpis byl pořízený sériovým terminálem Hercules a čísla ve složených závorkách jsou v hexadecimálním tvaru)
Jak je vidět, všech 33 položek z pole se bez problému odešle.
Teď ale stačí, abych zakomentoval ten výpis v textovém formátu a najednou se 5 bajtů, které obsahují 0xFF ztratí.
Vždycky se ztratí jen těch 5 bajtů.
Nebude to žádné náhodné elektrické rušení.
Poslední bajt (0xCC) je už zase v pořádku.
Těch závěrečných 0xFF bajtů se odešle už jen 5 místo 10.
Stačí ale, abych oddělil jednotlivé datové bajty třeba mezerou (kód 0x20) a všechna data zase bez problémů projdou.
Ale to nechci. To bych posílal zbytečně dalších 33 prázdných bajtů navíc.
Zkoušel jsem prodlužovat pauzu mezi vysíláním jednotlivých položek, jestli se mi třeba nepřeplňuje přijímací buffer, ale nemá to žádný vliv.
Už fakt nemám žádný nápad, co s tím udělat.
Nějak se mi ztrácí data a nemůžu přijít na to, co se děje.
Konkrétní příklad:
Mám pole dat o délce 33 bajtů.
Skutečně uložené hodnoty v tom poli jsou následující:
Kód: Vybrat vše
vysilaci_pole[0] = 1; // = 0x01
vysilaci_pole[1] = 2; // = 0x02
vysilaci_pole[2] = 29; // = 0x1D
vysilaci_pole[3] = 130; // = 0x82
vysilaci_pole[4] = 96; // = 0x60
vysilaci_pole[5] = 55; // = 0x37
vysilaci_pole[6] = 240; // = 0xF0
vysilaci_pole[7] = 46; // = 0x2E
vysilaci_pole[8] = 35; // = 0x23
vysilaci_pole[9] = 125; // = 0x7D
vysilaci_pole[10] = 28; // = 0x1C
vysilaci_pole[11] = 13; // = 0x0D
vysilaci_pole[12] = 254; // = 0xFE
vysilaci_pole[13] = 23; // = 0x17
vysilaci_pole[14] = 27; // = 0x1B
vysilaci_pole[15] = 21; // = 0x15
vysilaci_pole[16] = 28; // = 0x1C
vysilaci_pole[17] = 213; // = 0xD5
vysilaci_pole[18] = 22; // = 0x16
vysilaci_pole[19] = 81; // = 0x51
vysilaci_pole[20] = 144; // = 0x90
vysilaci_pole[21] = 241; // = 0xF1
vysilaci_pole[22] = 255; // = 0xFF
vysilaci_pole[23] = 255; // = 0xFF
vysilaci_pole[24] = 255; // = 0xFF
vysilaci_pole[25] = 255; // = 0xFF
vysilaci_pole[26] = 255; // = 0xFF
vysilaci_pole[27] = 255; // = 0xFF
vysilaci_pole[28] = 255; // = 0xFF
vysilaci_pole[29] = 255; // = 0xFF
vysilaci_pole[30] = 255; // = 0xFF
vysilaci_pole[31] = 255; // = 0xFF
vysilaci_pole[32] = 204; // = 0xCC
Tyhle data potřebuju poslat do sériove linky jako jednotlivé bajty (bez převodu na text) - prostě jen 33 obyčejných bajtů, žádné oddělování, žádné ukončování.
Data posílám přes RS485. Přepínání mezi příjmem a vysíláním mám bez problému funkční.
Věnujte pozornost těm 10 hodnotám 0xFF v závěru pole (indexy 22 až 31).
Když napíšu tuto jednoduchou smyčku, program funguje podle očekávání.
Nejdřív odešle do linky hodnotu položky pole v textovém formátu (podle počtu cifer čísla je to 1 až 3 bajty) a ukončí se sekvencí CR+LF (0x0D, 0x0A).
Hned potom se odešle jednobajtová hodnota z požadované položky pole (to je to, co chci ve finále získat).
Kód: Vybrat vše
for (byte i = 0; i < pocet ; i ++)
{
Serial1.println(vysilaci_pole[i]); // výpis čísla v textovém formátu s ukončovací sekvencí CR+LF
Serial1.write(vysilaci_pole[i]); // výpis čísla v jednobajtovém formátu (jen jeden datový bajt)
delay(10);
}
Výpis, ve kterém jsem ručně upravil řádkování a mezery, aby bylo zřetelné, kde jednotivé položky začínají a končí:
(výpis byl pořízený sériovým terminálem Hercules a čísla ve složených závorkách jsou v hexadecimálním tvaru)
Kód: Vybrat vše
textové vyjádření bajt
{31}{0D}{0A} {01}
{32}{0D}{0A} {02}
{32}{39}{0D}{0A} {1D}
{31}{33}{30}{0D}{0A} {82}
{39}{36}{0D}{0A} {60}
{35}{35}{0D}{0A} {37}
{32}{34}{30}{0D}{0A} {F0}
{34}{36}{0D}{0A} {2E}
{33}{35}{0D}{0A} {23}
{31}{32}{35}{0D}{0A} {7D}
{32}{38}{0D}{0A} {1C}
{31}{33}{0D}{0A} {0D}
{32}{35}{34}{0D}{0A} {FE}
{32}{33}{0D}{0A} {17}
{32}{37}{0D}{0A} {1B}
{32}{31}{0D}{0A} {15}
{32}{38}{0D}{0A} {1C}
{32}{31}{33}{0D}{0A} {D5}
{32}{32}{0D}{0A} {16}
{38}{31}{0D}{0A} {51}
{31}{34}{34}{0D}{0A} {90}
{32}{34}{31}{0D}{0A} {F1}
{32}{35}{35}{0D}{0A} {FF}
{32}{35}{35}{0D}{0A} {FF}
{32}{35}{35}{0D}{0A} {FF}
{32}{35}{35}{0D}{0A} {FF}
{32}{35}{35}{0D}{0A} {FF}
{32}{35}{35}{0D}{0A} {FF}
{32}{35}{35}{0D}{0A} {FF}
{32}{35}{35}{0D}{0A} {FF}
{32}{35}{35}{0D}{0A} {FF}
{32}{35}{35}{0D}{0A} {FF}
{32}{30}{34}{0D}{0A} {CC}
Teď ale stačí, abych zakomentoval ten výpis v textovém formátu a najednou se 5 bajtů, které obsahují 0xFF ztratí.
Vždycky se ztratí jen těch 5 bajtů.
Nebude to žádné náhodné elektrické rušení.
Poslední bajt (0xCC) je už zase v pořádku.
Kód: Vybrat vše
for (byte i = 0; i < pocet ; i ++)
{
// Serial1.println(vysilaci_pole[i]); // výpis čísla v textovém formátu s ukončovací sekvencí CR+LF
Serial1.write(vysilaci_pole[i]); // výpis čísla v jednobajtovém formátu (jen jeden datový bajt)
delay(10);
}
Kód: Vybrat vše
{01}
{02}
{1D}
{82}
{60}
{37}
{F0}
{2E}
{23}
{7D}
{1C}
{0D}
{FE}
{17}
{1B}
{15}
{1C}
{D5}
{16}
{51}
{90}
{F1}
{FF}
{FF}
{FF}
{FF}
{FF}
{CC}
Stačí ale, abych oddělil jednotlivé datové bajty třeba mezerou (kód 0x20) a všechna data zase bez problémů projdou.
Ale to nechci. To bych posílal zbytečně dalších 33 prázdných bajtů navíc.
Kód: Vybrat vše
for (byte i = 0; i < pocet ; i ++)
{
Serial1.write(vysilaci_pole[i]); // výpis čísla v jednobajtovém formátu (jen jeden datový bajt)
Serial1.write(' '); // mezera mezi bajty
delay(10);
}
Kód: Vybrat vše
{01}{20}
{02}{20}
{1D}{20}
{82}{20}
{60}{20}
{37}{20}
{F0}{20}
{2E}{20}
{23}{20}
{7D}{20}
{1C}{20}
{0D}{20}
{FE}{20}
{17}{20}
{1B}{20}
{15}{20}
{1C}{20}
{D5}{20}
{16}{20}
{51}{20}
{90}{20}
{F1}{20}
{FF}{20}
{FF}{20}
{FF}{20}
{FF}{20}
{FF}{20}
{FF}{20}
{FF}{20}
{FF}{20}
{FF}{20}
{FF}{20}
{CC}{20}
Zkoušel jsem prodlužovat pauzu mezi vysíláním jednotlivých položek, jestli se mi třeba nepřeplňuje přijímací buffer, ale nemá to žádný vliv.
Už fakt nemám žádný nápad, co s tím udělat.