Skocz do zawartości
NeverGiveUp1995

ESP8266 Softserial - ucina odebrane dane?

Pomocna odpowiedź

Witam mam taki problem kod napisany w arduino z użyciem softserial który przepisuje mi dane do tablicy tylko tu jest problem że mi je obcina jak to rozwiązać jakieś przykłady? Próbowałem zwiekszyć buffor w softserial.h ale to nie pomogło 

to co mam odczytać 
0226FFF4169E502D169F4B23157C0050157D0208157E0033166E00001616002D1681F83015CD0000 
162010311621000115890001158B000016B6000016B0000516AE000015AB00001587000015880000 
159B000001F60000028E00000298000002990000024500000218AE85 

a to co odbiera 

0226FFF4169E502D169F4B23157C0050157D0208157E0033166E00001616002D1681F83015CD0000 
162010311621000115890001158B000016B6000016B00 

#include <SoftwareSerial.h>

const int PIN_RX = 2;
const int PIN_TX = 5;

SoftwareSerial PiecSerial(PIN_RX, PIN_TX);

uint16_t bajtOdebrany = 0;
uint16_t ramkaCO[120] = {};


void setup()
{
pinMode(PIN_RX, INPUT_PULLUP);
pinMode(PIN_TX, INPUT_PULLUP);

//uruchomienie hardeware serial
Serial.begin(9600);
while (!Serial)
delay(300);
Serial.println("Hardeware serial gotowy!");
delay(300);

//uruchomienie software serial
PiecSerial.begin(9600);
while (!PiecSerial)
delay(300);
Serial.println("Software serial gotowy!");
delay(300);
}


//funkcja tworzaca tablice wartosci odczytanych z PiecSerial
uint16_t* DoTablicy()
{
int i = 0;
while (PiecSerial.available ())
{
bajtOdebrany = PiecSerial.read();
ramkaCO[i] = bajtOdebrany;
i++;
delay(10);
}
return ramkaCO;
}

void loop() {


if (PiecSerial.available()) { // Flaga od programowego rs232
uint16_t* tablicaOdczyt = DoTablicy(); // Odczyt do tablicy

// Wyswietlanie ramki na rs232 sprzetowy
for (int i = 0; i < 119; i++)
{
Serial.print(ramkaCO[i], HEX);
}
Serial.println("----------");



// Czyszczenie tablicy z ramka
for (int i = 0; i < 119; i++)
{
ramkaCO[i] = 0;
}

}

}

 

Udostępnij ten post


Link to post
Share on other sites

Cześć,

zamień:

uint16_t ramkaCO[120] = {};

na

uint16_t ramkaCO[512] = {};

I w tej linii:

for (int i = 0; i < 119; i++)

zamień na

for (int i = 0; i < 512; i++)

Pozdrawiam

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Czy ja dobrze widzę

while (PiecSerial.available ())
{
bajtOdebrany = PiecSerial.read();
ramkaCO[i] = bajtOdebrany;
i++;
delay(10);
}

Odbierasz bajt, czekasz 10ms, odbierasz kolejny. Przy 9600 1 bajt trwa ok 10ms czyli przez delay 10ms, tracisz 10 znaków. Jakiś tam bufor masz, ale po 10 obiegach tej pętli , gdyby nie było bufora, tracisz ok 90 znaków, 100 obiegach 900 znaków. Bufor typowo ma 64 znaki, więc po 6 obiegach pętli zaczynasz tracić znaki. Dodatkowo, program jest blokowany przez

Serial.print(ramkaCO[i], HEX);
}
Serial.println("----------");

Policz teraz czy odbierasz mniej więcej wielkość bufora -  liczba obiegów pętli * 9 - czas nbadawania znaków na sprzetowym UART. Jak to się zgadza to wiesz gdzie masz błąd a nawet dwa.

Jaki był cel delay(10)? Co chciałeś osiągnąć?

Dlaczego nie używasz bufora nadawczego i nadawania w przerwaniach lub z wykorzystaniem DMA ? Teraz, nadając sprzętowym UART blokujesz program. To też wpływa na gubienie znaków a masz ESP, z dosyć dużą pamięcią RAM na bufory oraz z DMA.

Czemu służą delay(300) w tym fragmencie?

while (!PiecSerial)
delay(300);
Serial.println("Software serial gotowy!");
delay(300);

Masz jakąś premię od szefa za liczbę użytych delay?

 

Aby program działał lub działał lepiej powinieneś:

- wywalić delay i wszelkie konstrukcje while(zdarzenie),

- nie używać softwarowych UART, I2C, SPI (niezbyt szybki master I2C czy SPI może być),

- używać buforów nadawczych.

Edytowano przez InspektorGadzet

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

to może ktoś zapoda jakimś działajacym kodem odbierającym dane do tablicy ? bo ja juz tego za bardzo nie ogarniam

 

Edytowano przez NeverGiveUp1995

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
7 minut temu, NeverGiveUp1995 napisał:

to może ktoś zapoda jakimś działajacym kodem odbierającym dane do tablicy ?

Może zapoda. Ja nie, bo pomagać to i owszem, pomagam, ale roboty, jak większość forumowiczów, tym bardziej za darmo, nie robię

 

7 minut temu, NeverGiveUp1995 napisał:

bo ja juz tego za bardzo nie ogarniam

Czego konkretnie? Wskazałem błędy, trzeba je tylko wyeliminować.

Edytowano przez InspektorGadzet

Udostępnij ten post


Link to post
Share on other sites

to tak program zmieniłem tak jak poniżej a nadawanie z dma albo przerwaniach nie mam pojecia jak zrobić 

#include <SoftwareSerial.h>

const int PIN_RX = 2;
const int PIN_TX = 5;
const int PIN_RX_SP = 3;
const int PIN_TX_SP = 1;

SoftwareSerial PiecSerial(PIN_RX, PIN_TX);

uint16_t bajtOdebrany = 0;
uint16_t ramkaCO[120] = {};


void setup()
{
pinMode(PIN_RX, INPUT_PULLUP);
pinMode(PIN_TX, INPUT_PULLUP);
pinMode(PIN_RX_SP, INPUT_PULLUP);
pinMode(PIN_TX_SP, INPUT_PULLUP);

//uruchomienie hardeware serial
Serial.begin(9600);
while (!Serial)

Serial.println("Hardeware serial gotowy!");


//uruchomienie software serial
PiecSerial.begin(9600);
while (!PiecSerial)

Serial.println("Software serial gotowy!");

}


//funkcja tworzaca tablice wartosci odczytanych z PiecSerial
uint16_t* DoTablicy()
{
int i = 0;
while (Serial.available ())
{
bajtOdebrany = Serial.read();
ramkaCO[i] = bajtOdebrany;
i++;

}
return ramkaCO;
}

void loop() {


if (Serial.available()) { // Flaga od programowego rs232
uint16_t* tablicaOdczyt = DoTablicy(); // Odczyt do tablicy
}
// Wyswietlanie ramki na rs232 sprzetowy
for (int i = 0; i < 119; i++)
{
Serial.print(ramkaCO[i], HEX);
}
Serial.println("----------");



// Czyszczenie tablicy z ramka
for (int i = 0; i < 119; i++)
{
ramkaCO[i] = 0;
}



}

 

Udostępnij ten post


Link to post
Share on other sites
16 minut temu, NeverGiveUp1995 napisał:

to może ktoś zapoda jakimś działajacym kodem odbierającym dane do tablicy ? bo ja juz tego za bardzo nie ogarniam

Moim skromnym zdaniem Twój problem został rozwiązany przynajmniej w większej części. Spróbuj raz jeszcze uważnie wprowadzić zmiany i powinno działać jak powinno. @InspektorGadzet ma tu rację, jeśli coś może być obsługiwane sprzętowo to powinno być obsługiwane sprzętowo.

 

1 minutę temu, NeverGiveUp1995 napisał:

nadawanie z dma albo przerwaniach nie mam pojecia jak zrobić 

Nie pozostaje nic innego jak odesłać do literatury tudzież dydaktycznych opracowań tematycznych lub upraszać łaski @InspektorGadzet on to wszystko ma w małym palcu lewej stopy.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
27 minut temu, atMegaTona napisał:

@InspektorGadzet ma tu rację, jeśli coś może być obsługiwane sprzętowo to powinno być obsługiwane sprzętowo.

Tyle, że @NeverGiveUp1995, bez zastanowienia, wybrał płytkę, która ma tylko jednego UART'a. Zawsze jest jednak wyjście, na przykład SC16IS7xx ale taniej wybrać płytkę z wymaganymi peryferiami.

 

27 minut temu, atMegaTona napisał:

upraszać łaski @InspektorGadzet on to wszystko ma w małym palcu lewej stopy.

Jak bym tak każdemu bezinteresownie robił projekty, to:

- Nic innego bym nie robił.

- Umarłbym z głodu.

- Zanim bym umarł płaciłbym kary za niewywiązanie się ze swoich zobowiązań.

 

27 minut temu, atMegaTona napisał:

Nie pozostaje nic innego jak odesłać do literatury

Chciałem znaleźć gotowca i natrafiłem na stronie Nettigo na "mądrość ludową" przypominającą mi powiedzenie "Tam gdzie się kończy głupota cywilna, zaczyna się mądrość wojskowa":

"Z praktyki Nie używaj przerwań, jeśli potrafisz znaleźć inne rozwiązanie. Programy wykorzystujące przerwania trudniej diagnozować (debuggować) jeżeli coś działa nie tak jak się spodziewasz."

Widać, że autor tego tekstu ma kiepską praktykę. Właśnie wszystko co się da należy realizować na przerwaniach. To upraszcza kod dlatego mogę napisać, że na stronie Nettigo nie ma co szukać i nie polecam jej. Przypomniało mi się, że kody obsługi wyświetlaczy jakie tam znalazłem są ŻENUJĄCE. Nie nadają się nawet na demo, a z powyższą "mądrością" to nie spodziewam się, że coś wartościowego można na tej stronie znaleźć

 

Edytowano przez InspektorGadzet
  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Napisz odpowiedź...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.


×
×
  • Utwórz nowe...