Problemów może być sporo ja bym jednak zaczął od zmodyfikowania kodu odpowiedzialnego za komunikację zarówno po stronie PC jak i AVR. Wiem, że to brzmi mało pocieszająco ale gwarantuję, że efekt
końcowy będzie zadowalający. Po pierwsze zrób jakąś strukturę ramki, która ma "wyraźny" początek i koniec. Po to mamy do dyspozycji w tabeli ASCII znaki [STX] i [ETX], [EOT], [ACK], [NAK]. Transmisja szeregowa jest "stara jak świat" i nie bez powodu to wszystko wymyślono. Oczywiście nie ma obowiązku używania takich właśnie znaków ale chodzi o ideę.
W chwili obecnej Twój kod działa na zasadzie "szczęśliwego przypadku". Teoretycznie jak na linii pokażą się zakłócenia to wpadamy w pętlę
receive_text() i nigdy z niej nie wychodzimy... Być może nawet występują jakieś przepełnienia tablicy i "zwis" AVR. Zauważ, że wyjście z pętli masz tylko na określony znak -
brakuje obsługi przepełnienie bufora lub/i timeout.
Nie masz obsługi limitu długości ramki ani timeout'ów. Czyli praktycznie nigdy nie wiesz w jakim miejscu jesteś.
Aby to wszystko jakoś poukładać...
W AVR robisz globalny bufor ramki tablicę (array) o nazwie np.:
received;
Do tego dodajesz globalny wskaźnik (int) bieżącej pozycji w ramce
uartPos.
Odbieranie znaków niech następuje w przerwaniu lub jako nieblokujący kod w głównej pętli programu ( musi być wywoływany na tyle często by nadążył odbierać znaki przy ustalonej szybkości transmisji ).
Odbiór polega na sprawdzeniu czy w buforze portu szeregowego jest a jeśli jest to wstawieniu go do tablicy
received[uartPos] a następnie uartPos++ ;
Pod tym robisz warunek czy przypadkiem uartPos nie jest większy niż max rozmiar ramki. Jeśli jest to zerujesz uartPos = 0; ( w ten sposób masz pewność, że nie "wyskoczysz za tablicę").
Raz na jakiś czas uruchamiasz funkcję, która sprawdza dane w ramce i jeśli są niekompletne lub błędne to wysyłasz do PC znak np.: [NAK] i resetujesz wskaźnik pozycji.
Wtedy PC wie, że coś poszło nie tak i ma przerwać / ponowić transmisję.
Przykład takiej prostej transmisji znajdziesz w temacie:
https://www.elektroda.pl/rtvforum/topic3433799.html ( bez timeout'ów bo zastosowana tam logika ich nie wymaga ).
No i jeszcze kilka
ogólnych praktycznych porad ...
Aby upewnić się, że wszystko jest OK.
1. Przed rozpoczęciem zabawy upewnij się, że port szeregowy Ci działa - zewrzyj PINY 2 i 3 w gnieździe portu, uruchom terminal i zobacz czy dane "wracają".
2. Miałem styczność z portami na USB, które pozwoliły się zainicjować tylko 2, 3 razy a potem się wieszały - trzeba było ponownie wyjąć i włożyć do USB.
3. Napisz na AVR prosty program "echo" aby mieć pewność, że parametry transmisji są dobrze wyliczone dla zastosowanego kwarcu - niedawno miałem sytuację, ze 2 attiny z różnych serii uruchomione na wewnętrznym oscylatorze 1MHz "nie dogadały" się bo tak duże były różnice czasowe ( WTF ) - po podłączeniu kwarcu było OK.