Przesyłanie po UDP/RS232 wartości liczbowych.

Masz pomysł na funkcjonalność lub koncepcję na rozwój projektu. Opisz wszystko tutaj.
LakiLuck
Posty: 12
Rejestracja: czw mar 03, 2022 8:03 am

Odczyt udało mi się zrobić, tz. wgrałem do NodeMcu program razem z obsługą wyświetlacza po I2C żeby zobaczyć czy uda mi się odebrać dane z Rotex. Po wielu zabawach udało mi się połączyć o odczytać przesłaną paczkę właśnie w poniższej postaci:
0 ; 0 ; 0 ; 0 ; 38 ; 17 ; 22 ; 12 ; 0,0

Póki co utknąłem na przypisaniu wartości do konkretnych zmiennych. Robię to na podstawie programów jakie znalazłem w sieci, ale mam tylko taki, który jest w stanie wyciągnąć dane z ciągu zawartego pomiędzy <> czyli np. <0 ; 0 ; 0 ; 0 ; 38 ; 17 ; 22 ; 12 ; 0,0>, ale w moim przypadku otrzymuję dane bez nawiasów więc nie do końca działa to tak jakbym chciał, a przypuszczam, że chcąc zaciągnąć dane do supla będą potrzebne zmienne w czystej postaci, więc walczę dalej.
Poniżej obecny program:


// 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]
// Tr: Temperatura powrotu [°C]
// Ts: Temperatura zbiornika [°C]
// Tv: Temperatura zasilania [°C]
// V: natężenie przepływu (l / min)

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);
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){
// if (Serial.available()>0)
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);
}
LakiLuck
Posty: 12
Rejestracja: czw mar 03, 2022 8:03 am

Witam po dłuższej przerwie. Wstyd się przyznać, że trwało to aż rok czasu, ale każdy wie jak obecnie się żyje, masa innych zajęć i notoryczny brak wolnego czasu....
W końcu udało mi się ogarnąć temat odczytu danych z sterownika instalacji solarnej Rotex (po roku czasu!) + dołożyłem od siebie pomiar mocy. Dane odczytuję w ESP32 Wemos D1 mini.
Miałem nadzieję, że w tym czasie pojawi się od paru lat zapowiadany kanał pomiarowy ogólnego przeznaczenia, ale już się nie łudzę dlatego chciałbym podpiąć dane wg sugestii Klew-a.

P1: prędkość obrotowa pompy P1 w % - wykorzystać kanał wilgotności (w %)
P2: pompa P2 włączona/wyłączona, 0 lub 1 - wykorzystać sensor binarny (widoczny stan on/off)
Tk: Temperatura kolektorów - kanał termometru
Tr: Temperatura w dolnej części zbiornika (tak naprawdę ta woda idzie do paneli - kanał termometru
Ts: Temperatura górnej części zbiornika - kanał termometru
Tv: Temperatury wody która wraca do zbiornika - kanał termometru
V: przepływ wody powracającej do zbiornika (l / min) V - nie ma kanału z jednostką (l/min) więc do kanału termometru
dT: różnica temperatur Tv-Tr - kanał termometru
P: moc chwilowa w kW - wykorzystać kanał licznika energii (sam pomiar mocy)?

Powiedzcie mi proszę jak się za to zabrać; co i gdzie zmienić żeby wykorzystać dane które mam? Widzę, że wiele osób dostosowuje różne kanały na swoje potrzeby, ale nie znalazłem nigdzie informacji jak się za to zabrać od początku.
mtcz
Posty: 29
Rejestracja: wt wrz 27, 2022 12:34 pm

Ja mam sterownik z firmy TECH. Odczytuję dane na wemos D1 mini przez RS232. Wysyłam ramki od razu w takiej samej postaci na serwer z linuxem. Tam w PHP dekoduję ramki i tworzę pliki tekstowe (na każdy kanał osobny plik). Z tych plików korzysta Supla Virtual Device, która jest zainstalowana na tym serwerze. Działa bez problemu. Jedyny problem to wymagany dodatkowy serwer, ale wystarczy najtańszy VPS.
Awatar użytkownika
klew
Posty: 8179
Rejestracja: czw cze 27, 2019 12:16 pm
Lokalizacja: Wrocław

LakiLuck pisze: wt maja 30, 2023 6:52 am P1: prędkość obrotowa pompy P1 w % - wykorzystać kanał wilgotności (w %)
P2: pompa P2 włączona/wyłączona, 0 lub 1 - wykorzystać sensor binarny (widoczny stan on/off)
Tk: Temperatura kolektorów - kanał termometru
Tr: Temperatura w dolnej części zbiornika (tak naprawdę ta woda idzie do paneli - kanał termometru
Ts: Temperatura górnej części zbiornika - kanał termometru
Tv: Temperatury wody która wraca do zbiornika - kanał termometru
V: przepływ wody powracającej do zbiornika (l / min) V - nie ma kanału z jednostką (l/min) więc do kanału termometru
dT: różnica temperatur Tv-Tr - kanał termometru
P: moc chwilowa w kW - wykorzystać kanał licznika energii (sam pomiar mocy)?

Powiedzcie mi proszę jak się za to zabrać; co i gdzie zmienić żeby wykorzystać dane które mam? Widzę, że wiele osób dostosowuje różne kanały na swoje potrzeby, ale nie znalazłem nigdzie informacji jak się za to zabrać od początku.
KPOP nadal jest "w trakcie", ale już myślę, że bliżej niż dalej ;)

Kanał wilgotności ma ten minus, że nie ma w apce jeszcze historii, ale będzie dodana.

Co do reszty: do termometrów użyj klasy Supla::Sensor::VirtualThermometer.
Tu jest jakis przykład jak tego użyć:
viewtopic.php?p=132418#p132418

Analogicznie do wilgotności jest VirtualHygrometer, do sensora on/off jest VirtualBinary.

Moc możesz wysyłać kanałem licznika energii, ale nie będziesz miał wtedy historii. Ja widzę dwie opcje: możesz użyć mocy i przeliczać ją na energię (moc * czas = energia) i wtedy będziesz miał podgląd pod chwilową moc oraz wyliczoną ilość energii zapisaną w historii, albo moc też wysyłać w kanale termometru...
Widzimy się na Supla Offline Party vol. 2 :!:
LakiLuck
Posty: 12
Rejestracja: czw mar 03, 2022 8:03 am

Chyba nie bardzo wiem o co chodzi z tymi klasami; czy to jest język Java? O ile w arduino jestem w stanie sobie poradzić, to java to kolejna rzecz do nauczenia się od zera, bo to dla mnie czarna magia. Trochę mnie to przeraża, bo zanim to ogarnę to minie kolejny rok, masakra :(.
Awatar użytkownika
klew
Posty: 8179
Rejestracja: czw cze 27, 2019 12:16 pm
Lokalizacja: Wrocław

LakiLuck pisze: wt maja 30, 2023 10:38 am Chyba nie bardzo wiem o co chodzi z tymi klasami; czy to jest język Java? O ile w arduino jestem w stanie sobie poradzić, to java to kolejna rzecz do nauczenia się od zera, bo to dla mnie czarna magia. Trochę mnie to przeraża, bo zanim to ogarnę to minie kolejny rok, masakra :(.
To C++.
W Arduino programuje się w C++, choć większość początkujących osób raczej używa czegoś w stylu uproszczonego C.

Są przykłady w bibiliotece. Spróbuj ich użyć. Nie trzeba rozumieć klas, aby uruchomić podstawowe rzeczy.
Widzimy się na Supla Offline Party vol. 2 :!:
LakiLuck
Posty: 12
Rejestracja: czw mar 03, 2022 8:03 am

Walczę kolejny dzień ...
Widzę już wszystkie kanały w Supli, ale odczytuję tylko kanały temperatury i wilgotności.
Co z sygnałami binarnymi, bo choć widzę te kanały to nie mam odczytu

Definiuję:

auto b1 = new Supla::Sensor::VirtualBinary(); //HA
auto h1 = new Supla::Sensor::VirtualHygroMeter; // P1;
auto b2 = new Supla::Sensor::VirtualBinary; //P2
auto t1 = new Supla::Sensor::VirtualThermometer;//Tk
auto t2 = new Supla::Sensor::VirtualThermometer;//Tr
auto t3 = new Supla::Sensor::VirtualThermometer;//Ts
auto t4 = new Supla::Sensor::VirtualThermometer;//Tv
auto t5 = new Supla::Sensor::VirtualThermometer;//dT
auto t6 = new Supla::Sensor::VirtualThermometer;//V
auto t7 = new Supla::Sensor::VirtualThermometer;//P

i w programie :

h1->setValue(P1);
t1->setValue(Tk);
t2->setValue(Tr);
t3->setValue(Ts);
t4->setValue(Tv);
t5->setValue(dT);
t6->setValue(V);
t7->setValue(Q);

HA i P2 to zmienne boolean, ale jak odczytać ich stan w supli? b1->setValue(HA); oraz b2>setValue(P2) nie są poprawne i zwraca błąd przy kompilacji.
Awatar użytkownika
klew
Posty: 8179
Rejestracja: czw cze 27, 2019 12:16 pm
Lokalizacja: Wrocław

LakiLuck pisze: pt cze 02, 2023 10:25 am auto b1 = new Supla::Sensor::VirtualBinary(); //HA
auto h1 = new Supla::Sensor::VirtualHygroMeter; // P1;


HA i P2 to zmienne boolean, ale jak odczytać ich stan w supli? b1->setValue(HA); oraz b2>setValue(P2) nie są poprawne i zwraca błąd przy kompilacji.
Klasa VirtualBinary nie ma metody "setValue". Tam jest tylko "set()", "clear()", "toggle()", zerknij tutaj:
https://github.com/SUPLA/supla-device/b ... nary.h#L36

Możesz jest ustawiać np tak:

Kod: Zaznacz cały

  if (HA) {
    b1->set();
  } else {
    b1->clear();
  }
Widzimy się na Supla Offline Party vol. 2 :!:
LakiLuck
Posty: 12
Rejestracja: czw mar 03, 2022 8:03 am

Klew,
bardzo Ci dziękuję, bo pomogłeś mi zrozumieć o co chodzi i dojść do rozwiązania. Trwa mi to strasznie długo, ale staram się nie pytać o wszystko, tylko doczytywać i sam próbować.
Została mi ostatnia rzecz, o którą chciałbym dopytać, a mianowicie pomiar mocy. Jak sam sugerowałeś można go podpiąć pod kanał temperatury i tak działa bez problemu, albo przeliczyć na energię w kWh i rejestrować w kanale licznika energii.
Podpiąłem się więc do kanału licznika energii:

auto e1 = new Supla::Sensor::ElectricityMeter;
....
e1->setFwdActEnergy(0,E); //E - energia w kWh

Widzę energię czynną pobraną, ale to jest chyba wartość sumaryczna całościowa.
Która zmienna jest w sulpli rejestrowana i pokazywana na wykresie? Czy supla sama sumuje moc chwilową?
Dodatkowe pytanie związane z tym kanałem...czy mając moc P [kW] i energię Q [kWh] jest możliwość pokazania obu wartości w tym samym kanale, tzn. żeby widzieć aktualną moc czynną i energię jak to jest np. w przypadku podpięcia PZEM 04?
LakiLuck
Posty: 12
Rejestracja: czw mar 03, 2022 8:03 am

e1->setPowerActive(0,Q);//moc czynna
e2->setFwdActEnergy(0,S); //energia czynna pobrana

Jak to scalić razem w jednym liczniku energii

new Supla::Sensor::ElectricityMeter
ODPOWIEDZ

Wróć do „Pomysły i koncepcje”