port szeregowy przypisanie odczytanych wartości do zmiennych - Wersja do druku +- Arduino Polska Forum (https://forum.arduinopolska.pl) +-- Dział: Korzystanie z Arduino (https://forum.arduinopolska.pl/dzial-korzystanie-z-arduino) +--- Dział: Piaskownica (https://forum.arduinopolska.pl/dzial-piaskownica) +--- Wątek: port szeregowy przypisanie odczytanych wartości do zmiennych (/watek-port-szeregowy-przypisanie-odczytanych-warto%C5%9Bci-do-zmiennych) Strony:
1
2
|
port szeregowy przypisanie odczytanych wartości do zmiennych - LakiLuck - 19-04-2022 [attachment=1220]Witam. Jestem początkujący w arduino i jest to moje pierwsze pytanie, bo niestety nie mogę sobie poradzić i utknąłem w martwym punkcie. Chcę odczytać zmienne, które są wysyłane z instalacji solarnej, aby móc je później przeliczyć i przesłać do supli. Problemem jest obróbka zmiennych. Instalacja solarna wysyła co 30s 9 wartości zmiennych oddzielonych od siebie znakiem ';' . zmienne różnego typu (book, integer, float) Napisałem prosty program, który odczytuje to, co wysyła sterownik solarów i wyświetlam to na LCD 2x16, ale nie wiem jak przepisać te wartości do konkretnych zmiennych. Znalazłem podobny przykład, ale w przypadku, gdy dane zawierają znak początkowy i końcowy transmisji, a u mnie nie ma znaku początkowego, jest jedynie znak końcowy, za każdym razem inny i nie do końca zrozumiały (zdjęcie w załączniku). Format danych z ROTEX: HA; BK; P1; P2; Tk; Tr; Ts,Tv; V HA: ręczny/automat (1/0) BK: Status styku blokującego palnik: wyłączony = 0; załączony = 1 P1: prędkość obrotowa pompy P1 w % (63%, 75%, 83% , 100% itd) P2: pompa P2 włączona/wyłączona, 0=wyłączona, 1=włączona Tk: Temperatura kolektorów [°C] - integer Tr: Temperatura powrotu [°C] -integer Ts: Temperatura zbiornika [°C] - integer Tv: Temperatura zasilania [°C] - integer V: natężenie przepływu (l / min) - float Poniższy program byłby idealny, gdyby nie to, że nie mam początkowego znaku, a końcowy jest za każdym razem inny const byte numChars = 32; char receivedChars[numChars]; char tempChars[numChars]; // temporary array for use when parsing variables to hold the parsed data char messageFromPC[numChars] = {0}; boolean HA = 0; boolean BK = 0; int P1 = 0; boolean P2 = 0; int Tk = 0; int Tr = 0; int Ts = 0; int Tv = 0; float V = 0.0; boolean newData = false; //============ void setup() { Serial.begin(9600); } //============ void loop() { recvWithStartEndMarkers(); if (newData == true) { strcpy(tempChars, receivedChars); // this temporary copy is necessary to protect the original data // because strtok() used in parseData() replaces the commas with \0 parseData(); showParsedData(); newData = false; } } //============ void recvWithStartEndMarkers() { static boolean recvInProgress = false; static byte ndx = 0; char startMarker = '<'; char endMarker = '>'; char rc; while (Serial.available() > 0 && newData == false){ rc = Serial.read (); if (recvInProgress == true) { if (rc != endMarker) { receivedChars[ndx] = rc; ndx++; if (ndx >= numChars) { ndx = numChars - 1; } } else { receivedChars[ndx] = '\0'; // terminate the string recvInProgress = false; ndx = 0; newData = true; } } else if (rc == startMarker) { recvInProgress = true; } } } //============ void parseData() { // split the data into its parts char * strtokIndx; // this is used by strtok() as an index strtokIndx = strtok(tempChars, ";"); // this continues where the previous call left off HA = atoi(strtokIndx); // convert this part to an integer strtokIndx = strtok(NULL, ";"); BK = atof(strtokIndx); // convert this part to a integer strtokIndx = strtok(NULL, ";"); P1 = atoi(strtokIndx); // convert this part to a integer strtokIndx = strtok(NULL, ";"); P2 = atoi(strtokIndx); // convert this part to a integer strtokIndx = strtok(NULL, ";"); Tk = atoi(strtokIndx); // convert this part to a integer strtokIndx = strtok(NULL, ";"); Tr = atoi(strtokIndx); // convert this part to a integer strtokIndx = strtok(NULL, ";"); Ts = atoi(strtokIndx); // convert this part to a integer strtokIndx = strtok(NULL, ";"); Tv = atoi(strtokIndx); // convert this part to a integer strtokIndx = strtok(NULL, ";"); V = atof(strtokIndx); // convert this part to a float } //============ void showParsedData() { Serial.println("Dane ROTEX: "); Serial.print("HA: "); Serial.println(HA); Serial.print("BK: "); Serial.println(BK); Serial.print("P1: "); Serial.println(P1); Serial.print("P2: "); Serial.println(P2); Serial.print("Tk: "); Serial.println(Tk); Serial.print("Tr: "); Serial.println(Tr); Serial.print("Ts: "); Serial.println(Ts); Serial.print("Tv: "); Serial.println(Tv); Serial.print("V: "); Serial.println(V); } pomóżcie proszę, bo sam sobie nie poradzę RE: port szeregowy przypisanie odczytanych wartości do zmiennych - Jarewa0606 - 19-04-2022 Ale masz ";" miedzy danymi to w czym problem?? RE: port szeregowy przypisanie odczytanych wartości do zmiennych - kaczakat - 19-04-2022 Na początek prześlij wszystko z portu UART na SERIAL. Są przykłady do Arduino, nawet wbudowane, przekopiowywanie znaków z UART na UART1 (lub softuart), znak odebrany -> znak wysłany. Potem to samo można zrobić ale już nie jako znaki lecz rzutując je na typ uint8_t, by zobaczyć liczby zamiast poszczególnych ASCII, bo Twoja analiza wysyłania takiego zestawu na LCD nie jest dobra, możesz pominąć znaki niedrukowane. A tak będziesz miał jasne czy jest jakiś znak kończący czy nie, najczęściej jest znak CR lub NL lub oba. Bo po co sobie utrudniać życie? Już po pierwszej części można odszyfrować oczami, czy pojawia się jeden ciąg znaków czy linie, jak są linie czy inne sekcje to już jest łatwiej. Znak rozpoczęcia nie jest w ogóle potrzebny, po prostu odbierasz cały ciąg znaków do znaku końca i potem od nowa. Jeśli nie ma znaków końca linii to trzeba się nauczyć mierzyć timeouty, tak by po czasie wyłapać kiedy jest transmisja a kiedy jest pauza odpowiednio długa by uznać, że poprzednia transmisja się zakończyła. Jest mnóstwo przykładów jak robić odbiór/przesył, parsowanie, serialEvent, są przykłady wbudowane, na Strig i tablicach char. Jak będziesz chciał po prostu usiąść i wymyślić to pewnie polegniesz, jak przeanalizujesz kilkadziesiąt podobnych programów to może dojdziesz do tego jak to robić. Tu jeden z przykładów: https://forum.arduinopolska.pl/watek-sterowanie-przeka%C5%BAnikiem-za-pomoc%C4%85-sms-arduino-uno-modu%C5%82-gsm RE: port szeregowy przypisanie odczytanych wartości do zmiennych - LakiLuck - 20-04-2022 Chyba niezbyt wyraźnie opisałem problem. Ja nic nie wysyłam, tylko odbieram dane przez port RS. Nie mam wpływu na to co dostaje, to jest ciąg który przychodzi co 30sek i jestem go w stanie tylko odebrać. Nie zależy mi na wyświetlaniu czegokolwiek na LCD. Wyświetlacz podłączyłem tylko po to, żeby podejrzeć co wysyła sterownik Rotex, jak wygląda ten ciąg. Na tej podstawie porównując z danymi wyświetlanymi w sterowniku Rotex byłem w stanie zobaczyć które zmienne dostaje. Nie potrafię tylko skutecznie wyciągnąć z tego ciągu zmiennych, żeby je dalej użyć w programie. Znalazłem program zamieszczony powyżej który adaptowałem do mojej sytuacji i byłoby wszystko dobrze, gdyby nie to, ze nie mam tego nieszczęsnego stałego znaku początkowego i końcowego (w powyższym przykładzie <....>) i nie wiem jak wyeliminować tylko uzależnienie od tych znaków. RE: port szeregowy przypisanie odczytanych wartości do zmiennych - kaczakat - 20-04-2022 A ja Ci napisałem jak masz się do tego zabrać, do opracowania metody musisz poznać ramkę, nie wysyłaj na LCD tylko UART. Na UART w monitorze możesz zobaczyć po kilku przesyłach coś takiego: 1213;1231231;231;23123412;31241;241241241;412412412;124124;2412;412412;4123 1213;1231231;231;23123412;31241;241241241;412412412;124124;2412;412412;4123 1213;1231231;231;23123412;31241;241241241;412412412;124124;2412;412412;4123 1213;1231231;231;23123412;31241;241241241;412412412;124124;2412;412412;4123 albo 1213;1231231;231;23123412;31241;241241241;412412412;124124;2412;412412;41231213;1231231;231;23123412;31241;241241241;412412412;124124;2412;412412;41231213;1231231;231;23123412;31241;241241241;412412412;124124;2412;412412;41231213;1231231;231;23123412;31241;241241241;412412412;124124;2412;412412;4123 To niewielka wiedza, ale bardzo tanio zdobyta. Jak będzie ta druga opcja to zostaje pomiar czasu (i tak warto to robić), znak który przyleci po przerwie np.>=2000ms jest pierwszym, a poprzedni był ostatnim. Nie zobaczysz tego na LCD. RE: port szeregowy przypisanie odczytanych wartości do zmiennych - Jarewa0606 - 20-04-2022 Ale ma przecież między danymi ";" wiec po co odczytywać cała ramkę jak z bufora można odczytać pojedynczo od znaku do znaku. Bo i tak to musi robić. Oczywiście mimo wszystko trzeba odczytać całą ramkę jw. bo na końcu może być niewidoczny znak dla twojego kodu. RE: port szeregowy przypisanie odczytanych wartości do zmiennych - kaczakat - 20-04-2022 Powinien odczytać całą ramkę i potem ją obrobić bo nie będzie wiedział jakie dane mu właśnie wleciały. Tych danych nie jest dużo, jeden bufor, potem kopia do drugiego na którym się pracuje i potem się przepisuje od ; do ; zamienia na liczbę i przypisuje do zmiennych liczbowych. Tu dwa sposoby jak to robić ze stringa, nie pamiętam czy sam to pisałem, czy gdzieś znalazłem, chodziło o porównanie czasu operacji różnymi metodami: Kod: //#include <String.h> A tu przykład z odbiorem i konwersją do tablicy floatów: Kod: //#include <String.h> Kod: //#include <String.h> RE: port szeregowy przypisanie odczytanych wartości do zmiennych - LakiLuck - 11-05-2023 Kupiłem konwerter UART-RS232, podłączyłem sterownik Rotex do laptopa i podejrzałem serial monitor. Otrzymałem dane w poniższej postaci: [attachment=1340] Nadal nie wiem, jak te dane ściągnąć do ESP8266 i przypisać je do poszczególnych zmiennych. Działanie każdego programu który 'umęczęczę' symuluję w Tinkercadzie, ale niż nie działa. Gdybym tylko miał chociaż znak na początku i końcu każdego ciągu byłbym w stanie skorzystać z programu, który przedstawiłem w pierwszym poście, ale niestety Pomoże ktoś? RE: port szeregowy przypisanie odczytanych wartości do zmiennych - kaczakat - 11-05-2023 Wszystkiego najlepszego w kolejnym roku zabawy z Arduino. Przecież masz znak specjalny, nie jest to ciąg znaków tylko ładne linie, więc masz przykład jak odebrać taką linię nawet w przykładach Arduino, serialEvent, a jak poszukasz w moich postach to wrzucałem tu na forum przykład na bazie serialEvent jak odebrać linię tekstu z parametrami oddzielonymi jakimiś znakami, np. ";" , przypisać je do zmiennych i użyć. RE: port szeregowy przypisanie odczytanych wartości do zmiennych - Irvin - 13-05-2023 Masz ładne linie tekstu. Jak program się uruchamia pierwszy raz nawiązując kontakt, to przylatują komunikaty z napisami w kilku liniach, jak linia zaczyna się od znaku innego niż '0' lub '1' to go wrzucasz w kosz. Potem lecą kolejne linie. Jeśli za każdym razem jest taka struktura komunikatu, to robisz to wg przykładów z posta #7. |