Sungo SXL MQTT Anbindung
Inhaltsverzeichnis
Allgemeines
Nach einer kleinen Pause (5 Monate) versuche ich die SunGO SXL Anbindung aus dem Versuchstadium zu befreien und mal alles ordentlich zu machen. Die Hardware kommt in eine Gehäuse und die Software soll ihren ersten Stresztest bestehen.
Ausgangssituation
Abgesehen von der SunGo SXL Steuerung sind aktuelle noch ein RasPi 3B, ein CP2102 USBSER und Arduino NANO und 4 DS18B20 im Einsatz. Das Netzteil ist nur eine Übergangslösung. Am liebsten wuerde ich eine MiniUSV mit ins Gehaeuse packen. Mal schauen was es da von der Stange gibt. Auf dem RasPi laeuft derzeit nur eine Software die die Aufgabe hat die Daten des SunGo-Interfaces und die Temperaturen der 4 DS18B20 (Vor-/Ruecklauf-Heizkreis1 und Vor-/Ruecklauf-Fuszbodenheizung) einzulesen und per MQTT an den FHEM-Broker (MQTT-Server) zu liefern.
Software
Verdammt! Nach 5 Monaten raecht sich die fehlende Dokumentation.
Sungo_MQTT
Dieses Programm liest die Daten des Interfaces ueber die USB-Schnittstelle ein und uebergibt sie an die Console und den MQTT-Server.
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <stdbool.h>
6 #include <time.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10 #include <termios.h> // termios is the API that is in general recommended for serial I/O in Unix.
11 #include "MQTTClient.h"
12
13 // MQTT defines
14 #define ADDRESS "tcp://192.168.178.12:1883"
15 //#define ADDRESS "tcp://localhost:1883"
16 #define CLIENTID "SunGo"
17 //#define TOPIC "MQTTExamples"
18 //#define PAYLOAD "Hello World!"
19 #define QOS 0
20 #define TIMEOUT 10000L
21
22 // SERCOM defines
23 #define BAUDRATE B115200
24 #define MODEMDEVICE "/dev/ttyS1"
25 #define _POSIX_SOURCE 1 /* POSIX compliant source */
26 #define FALSE 0
27 #define TRUE 1
28
29
30 // SunGo defines
31 #define DUMMY 0
32 #define TEMPERATUR 1 // °C
33 #define STRAHLUNG 2 // W/m²
34 #define SPEICHER1 7 // kwh
35 #define DATUM 8
36 #define UHRZEIT 9
37 #define PROZENT 10 // %
38 #define FUNKTION1 11
39 #define FUNKTION2 12
40 #define SPEICHER2 15 // h
41 #define VOLUMENSTROM 19 // l/min
42
43
44 volatile int STOP=FALSE; // braucht man eigentlich nicht Man koennte z.B. um die Endlosschleife elegant zu verlassen durch einen Taster mit ISR die globale Variabe STOP auf true setzen
45 // solange das nicht realisiert ist laeuft die "main-Schleife" endlos.
46
47
48 // globale Variablen
49 char datum[11];
50 char uhrzeit[7];
51 char temperatur[25];
52 char prozent[7];
53 char strahlung[8];
54 char fehler[17];
55 char stunden[8];
56 char dummy[7];
57
58 // hexadezimale Darstellung in dezimale umstellen
59 unsigned int hextodec(char hex[10]){
60 unsigned int decimal=0;
61 unsigned int length=0;
62 unsigned int base = 1;
63 int i=0;
64
65 while(hex[i]!='\0'){
66 i++;
67 }
68 length=i;
69
70 //printf("hextodec %s\n\r",hex);
71 //printf("length %d\n\r",length);
72
73 for(i = length-1; i >= 0; i--){
74 //printf("i: %d\n\r",i);
75 if (i<0)i=0;
76 if(hex[i] >= '0' && hex[i] <= '9'){
77 decimal += ((unsigned char)hex[i] - 48) * base;
78 base *= 16;
79 }
80 else if(hex[i] >= 'A' && hex[i] <= 'F'){
81 decimal += ((unsigned char)hex[i] - 55) * base;
82 base *= 16;
83 }
84 else if(hex[i] >= 'a' && hex[i] <= 'f'){
85 decimal += ((unsigned char)hex[i] - 87) * base;
86 base *= 16;
87 }
88 }
89 //printf("decimal %d\n\r",decimal);
90 return decimal;
91 }
92
93 void delay(int number_of_seconds) // wird doch nicht gebraucht
94 {
95 // Converting time into milli_seconds
96 int milli_seconds = 1000 * number_of_seconds;
97
98 // Storing start time
99 clock_t start_time = clock();
100
101 // looping till required time is not achieved
102 while (clock() < start_time + milli_seconds)
103 ;
104 }
105
106 // allgemeine Funktion; die verschiedenen Typen werden ueber switch case angesprochen
107 void formatieren(unsigned char typ,unsigned char lowbyte,unsigned char highbyte){
108 char data[10]=""; // dient der Aufnahme des zu wandelnden Wertes gebildet aus highbyte und lowbyte
109 char tmp[3]=""; // hilfvariable
110 char formatted[25]="";
111 char dataStr[5]="";
112 unsigned int dataInteger;
113 float dataFloat;
114 unsigned int dataStunden, dataMinuten;
115
116 //memset(formatted,'\0',sizeof(formatted));
117 //memset(data,'\0',sizeof(data));
118 //memset(tmp,'\0',sizeof(tmp));
119
120 // aus den beiden Einzelwerten wird der "Gesamtwert in der "richtigen" Reihenfolge gebildet
121 sprintf(tmp,"%02X",highbyte);
122 strcpy(data,tmp);
123 sprintf(tmp,"%02X",lowbyte);
124 strcat(data,tmp);
125
126 //printf("Data: %s\n",data);
127
128 dataInteger=hextodec(data);
129
130 switch(typ) {
131 case DUMMY: if(TRUE){
132 strcpy(dummy,data);
133 }
134 else{
135 strcpy(dummy,"Error!");
136 }
137 break;
138 case DATUM: sprintf(dataStr,"%d",dataInteger);
139 strcpy(formatted,"00.00.2021");
140 if(strlen(dataStr)==3){
141 formatted[0]=dataStr[1];
142 formatted[1]=dataStr[2];
143 formatted[4]=dataStr[0];
144 strcpy(datum,formatted);
145 }
146 else if(strlen(dataStr)==4){
147 formatted[0]=dataStr[2];
148 formatted[1]=dataStr[3];
149 formatted[3]=dataStr[0];
150 formatted[4]=dataStr[1];
151 strcpy(datum,formatted);
152 }
153 else{
154 strcpy(datum,"Error!");
155 }
156 break;
157 case UHRZEIT: dataStunden=(unsigned int)dataInteger/60;
158 dataMinuten=dataInteger-(dataStunden*60);
159 if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen
160 sprintf(formatted,"%02d:%02d",dataStunden,dataMinuten);
161 strcpy(uhrzeit,formatted);
162 }
163 else{
164 strcpy(uhrzeit,"Error!");
165 }
166 break;
167 case TEMPERATUR: dataFloat=(float)dataInteger/10.0;
168 if(TRUE){
169 //sprintf(formatted,"%5.1f °C (%d) ",dataFloat,dataInteger);
170 sprintf(formatted,"%5.1f °C",dataFloat);
171 strcpy(temperatur,formatted);
172 }
173 else{
174 strcpy(temperatur,"Error!\0");
175 }
176 break;
177 case SPEICHER2: if(TRUE){
178 sprintf(formatted,"%dh",dataInteger);
179 strcpy(stunden,formatted);
180 }
181 else{
182 strcpy(stunden,"Error!");
183 }
184 break;
185 case PROZENT: if(TRUE){
186 sprintf(formatted,"%3d%%",dataInteger);
187 strcpy(prozent,formatted);
188 }
189 else{
190 strcpy(prozent,"Error!");
191 }
192 break;
193 case STRAHLUNG: if(TRUE){
194 sprintf(formatted,"%d W/m² ",dataInteger);
195 strcpy(strahlung,formatted);
196 }
197 else{
198 strcpy(strahlung,"Error!\0");
199 }
200 break;
201 default: printf("Type Error (unknown)\n"); break;
202 }
203
204 return;
205 }
206
207 int main(int argc, char **argv)
208 { int i; // Schleifenzaehler allgemein
209 unsigned int state=0, syncstate=0; // state 10,20,30 oder 31 entsprechend 0100, 0200, 0300, 0301
210 unsigned int dsIndex, dfIndex; // Zeiger auf Datensatz und Datenfeld
211 unsigned long zeitzaehler=0; // Ausgabe verlangsamen 500000 etwa 1 Minute
212
213 unsigned char buf[1];
214 unsigned char merker[6];
215 unsigned char datensatz[100];
216 unsigned char datenfeld[100];
217 unsigned char datenfelder[50][16];
218 bool printflag;
219
220 // MQTT Vorbereitung
221 MQTTClient client;
222 MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
223 MQTTClient_message pubmsg = MQTTClient_message_initializer;
224 MQTTClient_deliveryToken token;
225 int mqttrc; //
226 char topic[255]; // zur Aufnahme Werte unterhalb des basetopic
227 char *basetopic = "Haus/Heizung/Solaranlage/SunGo/";
228
229 // MQTT Cleint Struktur anlegen
230 if ((mqttrc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS){
231 printf("Failed to create mqttclient, return code %d\n", mqttrc);
232 exit(EXIT_FAILURE);
233 }
234
235 // SerCOM Vorbereitung
236 struct termios oldtio,newtio;
237 int fd; // FileDescriptor SerCOM
238 int res; // SerCOM Einlesekontrolle
239
240 // wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nimm diese sonst versuche default
241 if (argc > 1)
242 fd = open(argv[1], O_RDWR | O_NOCTTY );
243 else
244 fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
245 if (fd <0) {
246 perror(MODEMDEVICE);
247 exit(-1);
248 }
249
250 // sichere die aktuellen Einstellungen
251 tcgetattr(fd,&oldtio);
252
253 // baue die neuen Einstellungen zusammen
254 bzero(&newtio, sizeof(newtio));
255 newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
256 newtio.c_iflag = IGNPAR | IXON | IXOFF;
257 newtio.c_oflag = 0;
258 newtio.c_lflag = 0;
259 newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
260 newtio.c_cc[VMIN] = 1; /* blocking read until 1 chars received */
261
262 tcflush(fd, TCIFLUSH);
263 tcsetattr(fd,TCSANOW,&newtio);
264
265 setvbuf(stdout, (char *)NULL, _IONBF, 0);
266
267 // hier sind alle Vorbereitungen (SERCOM, MQTT) abgeschlossen jetzt koennen die Daten des Interfaces eingelesen, aufbereitet und per MQTT gesendet werden
268 // Die 4 verschiedenen denkbaren Pakete (DPA_1, DPA_2, DPB_1, DPB_2) beginnen alle mit AA 55 55 AA (DEZ: 170 85 85 170)
269 // wenn diese Folge erkannt wird bestimmen die beiden folgenden Bytes den Typ des Paketes
270 while (STOP==FALSE) { // Endlosschleife
271
272 res = read(fd,buf,1);
273
274 //sobald ein AA kommt beginne die Beobachtung
275 if ((buf[0]==170) && (syncstate==5)){
276 syncstate=0;
277 }
278 if ((buf[0]==170) && (syncstate==0)){ // wenn der syncstate 0 (gleich Anfang) und ein AA erkannt wird dann setze sysncstate=1
279 syncstate=1;
280 merker[0]=buf[0];
281 }
282 if ((buf[0]==85) && (syncstate==1)){ // wenn der syncstate 1 (AA bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=2
283 syncstate=2;
284 merker[1]=buf[0];
285 }
286 if ((buf[0]==85) && (syncstate==2)){ // wenn der syncstate 2 (AA 55 bereits erkannt) und ein 55 erkannt wird dann setze sysncstate=3
287 syncstate=3;
288 merker[2]=buf[0];
289 }
290 if ((buf[0]==170) && (syncstate==3)){ // wenn der syncstate 3 (AA 55 55 bereits erkannt) und ein AA erkannt wird dann setze sysncstate=4
291 syncstate=4;
292 merker[3]=buf[0];
293 state=0;
294 }
295 // wenn AA 55 55 AA erkannt wurde steht syncstate auf 4 , in merker[0-3] befindet sich die Syncfolge und state ist 0
296 // wenn das nachfolgende Byte entweder 01 02 oder 03 ist ist alles wie erwartet und kann weitergehen syncstate = 5
297 if (((buf[0]==1)||(buf[0]==2)||(buf[0]==3)) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==4)){
298 merker[4]=buf[0];
299 syncstate=5;
300 }
301 // ab hier werden die 4 Pakete unterschieden DPA_1 0200 (state 20), DPA_2 0100 (state 10), DPB_1 0301 (state 31) und DPB_2 0300 (state 30)
302
303 if ((buf[0]==0) && (merker[4]==1) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
304 state=10; // state 10 bereit fuer 0100 Daten fuer das LC-Display
305 printflag=FALSE;
306 for(i=0;i<5;i++)merker[i]=0;
307
308 }
309 if ((buf[0]==0) && (merker[4]==2) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
310 state=20; // state 20 bereit fuer 0200 hat keinen (?) Inhalt -> keine Auswertung
311 printflag=FALSE;
312 for(i=0;i<5;i++)merker[i]=0;
313
314 }
315 if ((buf[0]==0) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
316 state=30; // state 30 bereit fuer 0300 Datensatze
317 printflag=FALSE;
318 for(i=0;i<5;i++)merker[i]=0;
319 dsIndex=0;
320
321 }
322 if ((buf[0]==1) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
323 state=31; // state 31 bereit fuer 0301 Datenfaelder
324 printflag=FALSE;
325 for(i=0;i<5;i++)merker[i]=0;
326 dfIndex=0;
327
328 }
329
330
331 // state 10 und 20 werden nicht ausgewertet
332 if ((state==10) && printflag) {
333
334 }
335 else if ((state==20) && printflag) {
336
337 }
338 else if ((state==30) && printflag){
339
340 if(dsIndex<100)datensatz[dsIndex++]=buf[0];
341 }
342 else if ((state==31) && printflag) {
343
344 if(dfIndex<100)datenfeld[dfIndex++]=buf[0];
345 }
346 else{
347 //printf("syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]);
348 }
349
350 printflag=TRUE;
351
352 if (zeitzaehler==10000){
353 // es wird etwa 3 mal pro Minute eine Auswahl der Datensaetze ausgegeben
354 // Datum: 18.09.2021
355 // Message published, return code 0
356 // Uhrzeit: 12:17
357 // Message published, return code 0
358 // Kollektor: 58.6 °C
359 // Message published, return code 0
360 // Speicher unten: 49.2 °C
361 // Message published, return code 0
362 // Speicher oben: 52.1 °C
363 // Message published, return code 0
364 // Rücklaufanhebung T7: 52.0 °C
365 // Message published, return code 0
366 // Rücklaufanhebung T8: 28.1 °C
367 // Message published, return code 0
368 // Ausgang 1: 60%
369 // Message published, return code 0
370 // Ausgang 6: 100%
371 // Message published, return code 0
372 // Speicher 2: 15632h
373 // Message published, return code 0
374
375 conn_opts.keepAliveInterval = 20;
376 conn_opts.cleansession = 1;
377 // Baue MQTT Verbindung auf
378 if ((mqttrc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS){
379 printf("Failed to connect, return code %d\n", mqttrc);
380 exit(EXIT_FAILURE);
381 }
382 //Datum
383 formatieren(DATUM,datensatz[2],datensatz[3]);
384 printf("Datum: %s\n",datum);
385 strcpy(topic,basetopic);
386 strcat(topic,"Datum");
387 pubmsg.payload = datum;
388 pubmsg.payloadlen = (int)strlen(datum);
389 pubmsg.qos = QOS;
390 pubmsg.retained = 0;
391 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
392 printf("Failed to publish message, return code %d\n", mqttrc);
393 exit(EXIT_FAILURE);
394 }else{
395 printf("Message published, return code %d\n", mqttrc);
396 }
397 //Uhrzeit
398 formatieren(UHRZEIT,datensatz[4],datensatz[5]);
399 printf("Uhrzeit: %s\n",uhrzeit);
400 strcpy(topic,basetopic);
401 strcat(topic,"Uhrzeit");
402 pubmsg.payload = uhrzeit;
403 pubmsg.payloadlen = (int)strlen(uhrzeit);
404 pubmsg.qos = QOS;
405 pubmsg.retained = 0;
406 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
407 printf("Failed to publish message, return code %d\n", mqttrc);
408 exit(EXIT_FAILURE);
409 }else{
410 printf("Message published, return code %d\n", mqttrc);
411 }
412 //Kollektor
413 formatieren(TEMPERATUR,datensatz[6],datensatz[7]);
414 printf("Kollektor: %s\n",temperatur);
415 strcpy(topic,basetopic);
416 strcat(topic,"Kollektor/Temperatur");
417 pubmsg.payload = temperatur;
418 pubmsg.payloadlen = (int)strlen(temperatur);
419 pubmsg.qos = QOS;
420 pubmsg.retained = 0;
421 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
422 printf("Failed to publish message, return code %d\n", mqttrc);
423 exit(EXIT_FAILURE);
424 }else{
425 printf("Message published, return code %d\n", mqttrc);
426 }
427 //Speicher unten
428 formatieren(TEMPERATUR,datensatz[8],datensatz[9]);
429 printf("Speicher unten: %s\n",temperatur);
430 strcpy(topic,basetopic);
431 strcat(topic,"Speicher/unten/Temperatur");
432 pubmsg.payload = temperatur;
433 pubmsg.payloadlen = (int)strlen(temperatur);
434 pubmsg.qos = QOS;
435 pubmsg.retained = 0;
436 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
437 printf("Failed to publish message, return code %d\n", mqttrc);
438 exit(EXIT_FAILURE);
439 }else{
440 printf("Message published, return code %d\n", mqttrc);
441 }
442 //Speicher oben
443 formatieren(TEMPERATUR,datensatz[10],datensatz[11]);
444 printf("Speicher oben: %s\n",temperatur);
445 strcpy(topic,basetopic);
446 strcat(topic,"Speicher/oben/Temperatur");
447 pubmsg.payload = temperatur;
448 pubmsg.payloadlen = (int)strlen(temperatur);
449 pubmsg.qos = QOS;
450 pubmsg.retained = 0;
451 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
452 printf("Failed to publish message, return code %d\n", mqttrc);
453 exit(EXIT_FAILURE);
454 }else{
455 printf("Message published, return code %d\n", mqttrc);
456 }
457 //Rücklaufanhebung T7
458 formatieren(TEMPERATUR,datensatz[18],datensatz[19]);
459 printf("Rücklaufanhebung T7: %s\n",temperatur);
460 strcpy(topic,basetopic);
461 strcat(topic,"Rücklaufanhebung/T7/Temperatur");
462 pubmsg.payload = temperatur;
463 pubmsg.payloadlen = (int)strlen(temperatur);
464 pubmsg.qos = QOS;
465 pubmsg.retained = 0;
466 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
467 printf("Failed to publish message, return code %d\n", mqttrc);
468 exit(EXIT_FAILURE);
469 }else{
470 printf("Message published, return code %d\n", mqttrc);
471 }
472 //Rücklaufanhebung T8
473 formatieren(TEMPERATUR,datensatz[20],datensatz[21]);
474 printf("Rücklaufanhebung T8: %s\n",temperatur);
475 strcpy(topic,basetopic);
476 strcat(topic,"Rücklaufanhebung/T8/Temperatur");
477 pubmsg.payload = temperatur;
478 pubmsg.payloadlen = (int)strlen(temperatur);
479 pubmsg.qos = QOS;
480 pubmsg.retained = 0;
481 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
482 printf("Failed to publish message, return code %d\n", mqttrc);
483 exit(EXIT_FAILURE);
484 }else{
485 printf("Message published, return code %d\n", mqttrc);
486 }
487 //Ausgang 1
488 formatieren(PROZENT,datensatz[32],0);
489 printf("Ausgang 1: %s\n",prozent);
490 strcpy(topic,basetopic);
491 strcat(topic,"Ausgang/1/Prozent");
492 pubmsg.payload = prozent;
493 pubmsg.payloadlen = (int)strlen(prozent);
494 pubmsg.qos = QOS;
495 pubmsg.retained = 0;
496 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
497 printf("Failed to publish message, return code %d\n", mqttrc);
498 exit(EXIT_FAILURE);
499 }else{
500 printf("Message published, return code %d\n", mqttrc);
501 }
502 //Ausgang 6
503 formatieren(PROZENT,datensatz[37],0);
504 printf("Ausgang 6: %s\n",prozent);
505 strcpy(topic,basetopic);
506 strcat(topic,"Ausgang/6/Prozent");
507 pubmsg.payload = prozent;
508 pubmsg.payloadlen = (int)strlen(prozent);
509 pubmsg.qos = QOS;
510 pubmsg.retained = 0;
511 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
512 printf("Failed to publish message, return code %d\n", mqttrc);
513 exit(EXIT_FAILURE);
514 }else{
515 printf("Message published, return code %d\n", mqttrc);
516 }
517 // Speicherstunden
518 formatieren(SPEICHER2,datensatz[50],datensatz[51]);
519 printf("Speicher 2: %s\n",stunden);
520 strcpy(topic,basetopic);
521 strcat(topic,"Speicher/Stunden");
522 pubmsg.payload = stunden;
523 pubmsg.payloadlen = (int)strlen(stunden);
524 pubmsg.qos = QOS;
525 pubmsg.retained = 0;
526 if ((mqttrc = MQTTClient_publishMessage(client, topic, &pubmsg, &token)) != MQTTCLIENT_SUCCESS){
527 printf("Failed to publish message, return code %d\n", mqttrc);
528 exit(EXIT_FAILURE);
529 }else{
530 printf("Message published, return code %d\n", mqttrc);
531 }
532 /* printf("Waiting for up to %d seconds for publication of %s\n"
533 "on topic %s for client with ClientID: %s\n",
534 (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID);
535 rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
536 printf("Message with delivery token %d delivered\n", token);
537 */
538 if ((mqttrc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS){
539 printf("Failed to disconnect, return code %d\n", mqttrc);
540 }
541 zeitzaehler=0;
542 }
543 zeitzaehler++;
544 if (zeitzaehler%100000==0)printf("%d\n",zeitzaehler); // Lebenszeichen
545
546 }
547
548 close(fd); // schliesze serielle Schnittstelle
549
550 tcsetattr(fd,TCSANOW,&oldtio); // stelle die alte ComConfig wieder her
551
552 MQTTClient_destroy(&client); // beende die MQTT Kommunikation
553
554 return EXIT_SUCCESS;
555 }
Sungoauswertungcurses
Dieses Programm dient erst mal nur dem Einlesen und Interpretieren der Daten vom Interface. Sie werden nach der Aufbereitung geordnet und auf der Console mittels curses ausgegeben. In diesem Programm sind noch die alten Varianten der Konvertierungsfunktionen vorhanden. Dies ist zwar nicht elegant, aber es funktioniert.
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <termios.h> // termios is the API that is in general recommended for serial I/O in Unix.
9 #include <curses.h>
10
11 #define BAUDRATE B115200
12 #define MODEMDEVICE "/dev/ttyS1"
13 #define _POSIX_SOURCE 1 /* POSIX compliant source */
14 #define FALSE 0
15 #define TRUE 1
16
17 volatile int STOP=FALSE;
18
19 char datum[11];
20 char uhrzeit[7];
21 char temperatur[25];
22 char prozent[7];
23 char fehler[17];
24 char stunden[8];
25 char dummy[7];
26
27
28 unsigned int hextodec(char hex[10]){
29 unsigned int decimal=0;
30 unsigned int length=0;
31 unsigned int base = 1;
32 int i=0;
33
34 while(hex[i]!='\0'){
35 i++;
36 }
37 length=i;
38
39 //printf("hextodec %s\n\r",hex);
40 //printf("length %d\n\r",length);
41
42 for(i = length-1; i >= 0; i--){
43 //printf("i: %d\n\r",i);
44 if (i<0)i=0;
45 if(hex[i] >= '0' && hex[i] <= '9'){
46 decimal += ((unsigned char)hex[i] - 48) * base;
47 base *= 16;
48 }
49 else if(hex[i] >= 'A' && hex[i] <= 'F'){
50 decimal += ((unsigned char)hex[i] - 55) * base;
51 base *= 16;
52 }
53 else if(hex[i] >= 'a' && hex[i] <= 'f'){
54 decimal += ((unsigned char)hex[i] - 87) * base;
55 base *= 16;
56 }
57 }
58 //printf("decimal %d\n\r",decimal);
59 return decimal;
60 }
61
62
63 void datumformatieren(unsigned char lowbyte,unsigned char highbyte){
64 char data[10]="";
65 char tmp[3]="";
66 char datumStr_formatted[]="00.00.2021";
67 char datumStr[5]="";
68 unsigned int datumInt;
69 size_t l;
70
71 sprintf(tmp,"%X",highbyte);
72 strcpy(data,tmp);
73 //l=strlen(data);
74 //printf("data: %s (%d)\n\r",data,l);
75
76 sprintf(tmp,"%X",lowbyte);
77 strcat(data,tmp);
78 //l=strlen(data);
79 //printf("data: %s (%d)\n\r",data,l);
80
81 //strcpy(data,"0135");
82 //printf("data: %s\n\r",data);
83 datumInt=hextodec(data);
84 //printf("int: %d\n\r",datumInt);
85 sprintf(datumStr,"%d",datumInt);
86 if(strlen(datumStr)==3){
87 datumStr_formatted[0]=datumStr[1];
88 datumStr_formatted[1]=datumStr[2];
89 datumStr_formatted[4]=datumStr[0];
90 strcpy(datum,datumStr_formatted);
91 }
92 else if(strlen(datumStr)==4){
93 datumStr_formatted[0]=datumStr[2];
94 datumStr_formatted[1]=datumStr[3];
95 datumStr_formatted[3]=datumStr[0];
96 datumStr_formatted[4]=datumStr[1];
97 strcpy(datum,datumStr_formatted);
98 }
99 else{
100 strcpy(datum,"Error!");
101 }
102 return;
103 }
104
105
106 void uhrzeitformatieren(unsigned char lowbyte,unsigned char highbyte){
107 char data[10]="";
108 char tmp[3]="";
109 char uhrzeitStr_formatted[]="00:00";
110 unsigned int uhrzeitInt, stunden, minuten;
111 size_t l;
112
113 sprintf(tmp,"%02X",highbyte);
114 strcpy(data,tmp);
115 //l=strlen(data);
116 //printf("data: %s (%d)\n\r",data,l);
117
118 sprintf(tmp,"%02X",lowbyte);
119 strcat(data,tmp);
120 //l=strlen(data);
121 //printf("data: %s (%d)\n\r",data,l);
122
123 //strcpy(data,"1500");
124 //printf("data: %s\n\r",data);
125 uhrzeitInt=hextodec(data);
126 //printf("int: %d\n\r",uhrzeitInt);
127 stunden=(unsigned int)uhrzeitInt/60;
128 minuten=uhrzeitInt-(stunden*60);
129 if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen
130 sprintf(uhrzeitStr_formatted,"%02d:%02d",stunden,minuten);
131 strcpy(uhrzeit,uhrzeitStr_formatted);
132 }
133 else{
134 strcpy(uhrzeit,"Error!");
135 }
136 return;
137 }
138
139 void temperaturformatieren(unsigned char lowbyte,unsigned char highbyte){
140 char data[10]="";
141 char tmp[3]="";
142 char temperaturStr_formatted[20]="";
143 unsigned int temperaturInt;
144 float temperaturFloat;
145 size_t l;
146
147 memset(data,'\0',sizeof(data));
148 memset(tmp,'\0',sizeof(tmp));
149
150
151 sprintf(tmp,"%02X",highbyte);
152 strcpy(data,tmp);
153 //l=strlen(data);
154 //printf("data: %s (%d)\n\r",data,l);
155
156 sprintf(tmp,"%02X",lowbyte);
157 strcat(data,tmp);
158 //l=strlen(data);
159 //printf("data: %s (%d)\n\r",data,l);
160
161
162 //strcpy(data,"0500");
163 //printf("data: %s\n\r",data);
164 temperaturInt=hextodec(data);
165 //printf("int: %d\n\r",temperaturInt);
166 temperaturFloat=(float)temperaturInt/10.0;
167
168 if(TRUE){
169 memset(temperaturStr_formatted,'\0',sizeof(temperaturStr_formatted));
170 sprintf(temperaturStr_formatted,"%5.1f °C (%d) ",temperaturFloat,temperaturInt);
171 strcpy(temperatur,temperaturStr_formatted);
172 }
173 else{
174 strcpy(temperatur,"Error!\0");
175 }
176 return;
177 }
178
179
180 void prozentformatieren(unsigned char byte){
181 char data[10]="";
182 char tmp[3]="";
183 char prozentStr_formatted[]="000%";
184 unsigned int prozentInt;
185 size_t l;
186
187 sprintf(tmp,"%X",byte);
188 strcpy(data,tmp);
189 //l=strlen(data);
190 //printf("data: %s (%d)\n\r",data,l);
191
192
193 //strcpy(data,"1500");
194 //printf("data: %s\n\r",data);
195 prozentInt=hextodec(data);
196 //printf("int: %d\n\r",prozentInt);
197
198 if(TRUE){
199 sprintf(prozentStr_formatted,"%3d%%",prozentInt);
200 strcpy(prozent,prozentStr_formatted);
201 }
202 else{
203 strcpy(prozent,"Error!");
204 }
205 return;
206 }
207
208
209 void stundenformatieren(unsigned char lowbyte,unsigned char highbyte){
210 char data[10]="";
211 char tmp[3]="";
212 char stundenStr_formatted[]="000000h";
213 unsigned int stundenInt;
214
215 sprintf(tmp,"%X",highbyte);
216 strcpy(data,tmp);
217 //l=strlen(data);
218 //printf("data: %s (%d)\n\r",data,l);
219
220 sprintf(tmp,"%X",lowbyte);
221 strcat(data,tmp);
222 //l=strlen(data);
223 //printf("data: %s (%d)\n\r",data,l);
224
225 //strcpy(data,"1500");
226 //printf("data: %s\n\r",data);
227 stundenInt=hextodec(data);
228 //printf("int: %d\n\r",temperaturInt);
229
230 if(TRUE){
231 sprintf(stundenStr_formatted,"%dh",stundenInt);
232 strcpy(stunden,stundenStr_formatted);
233 }
234 else{
235 strcpy(stunden,"Error!");
236 }
237 return;
238 }
239
240 void fehlerformatieren(unsigned char byte1,unsigned char byte2,unsigned char byte3,unsigned char byte4,unsigned char byte5,unsigned char byte6,unsigned char byte7,unsigned char byte8){
241 char data[10]="";
242 char tmp[3]="";
243 char fehlerStr_formatted[9];
244 unsigned int fehlerInt;
245
246 fehlerInt=12345;
247
248 if(TRUE){
249 sprintf(fehlerStr_formatted,"%d",fehlerInt);
250 strcpy(fehler,fehlerStr_formatted);
251 }
252 else{
253 strcpy(fehler,"Error!");
254 }
255 return;
256 }
257
258
259 void dummyformatieren(unsigned char lowbyte,unsigned char highbyte){
260 char data[10]="";
261 char tmp[3]="";
262
263 sprintf(tmp,"%X",highbyte);
264 strcpy(data,tmp);
265 //l=strlen(data);
266 //printf("data: %s (%d)\n\r",data,l);
267
268 sprintf(tmp,"%X",lowbyte);
269 strcat(data,tmp);
270 //l=strlen(data);
271 //printf("data: %s (%d)\n\r",data,l);
272
273 if(TRUE){
274 strcpy(dummy,data);
275 }
276 else{
277 strcpy(dummy,"Error!");
278 }
279 return;
280 }
281
282 int main(int argc, char **argv)
283 {
284
285 struct termios oldtio,newtio;
286
287 int fd;
288 int c;
289 int res;
290 int i,k,l;
291 unsigned int x,y,z,t1,t2,t3,dsIndex, dfIndex, dfX, dfY, sort1,sort2, stelle, zeilenproblock;
292 unsigned int state=0, syncstate=0;
293
294 unsigned char buf[1];
295 unsigned char merker[6];
296 unsigned char datensatz[200];
297 unsigned char datenfeld[100];
298 unsigned char datenfelder[50][16];
299 char data[10]="";
300 char tmp[3]="";
301 bool printflag;
302
303 memset(temperatur, '\0', sizeof(temperatur));
304
305
306 // wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nim diese sonst veruche default
307 if (argc > 1)
308 fd = open(argv[1], O_RDWR | O_NOCTTY );
309 else
310 fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
311 if (fd <0) {
312 perror(MODEMDEVICE);
313 exit(-1);
314 }
315
316 // sichere die aktuellen Einstellungen
317 tcgetattr(fd,&oldtio);
318
319 // baue die neuen Einstellungen zusammen
320 bzero(&newtio, sizeof(newtio));
321 newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
322 newtio.c_iflag = IGNPAR | IXON | IXOFF;
323 newtio.c_oflag = 0;
324 newtio.c_lflag = 0;
325 newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
326 newtio.c_cc[VMIN] = 5; /* blocking read until 5 chars received */
327
328 tcflush(fd, TCIFLUSH);
329 tcsetattr(fd,TCSANOW,&newtio);
330
331 setvbuf(stdout, (char *)NULL, _IONBF, 0);
332
333 initscr();
334 getmaxyx(stdscr,x,y);
335 printf("X:%d/Y:%d\n",x,y);
336 while (STOP==FALSE) { /* loop for input */
337 res = read(fd,buf,1); /* returns after 5 chars have been input */
338 //printf("A: syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]);
339
340 //sobald ein AA kommt beginne die Beobachtung
341 if ((buf[0]==170) && (syncstate==5)){
342 syncstate=0;
343 }
344 if ((buf[0]==170) && (syncstate==0)){
345 syncstate=1;
346 merker[0]=buf[0];
347 }
348 if ((buf[0]==85) && (syncstate==1)){
349 syncstate=2;
350 merker[1]=buf[0];
351 }
352 if ((buf[0]==85) && (syncstate==2)){
353 syncstate=3;
354 merker[2]=buf[0];
355 }
356 if ((buf[0]==170) && (syncstate==3)){
357 syncstate=4;
358 merker[3]=buf[0];
359 state=0;
360 }
361 if (((buf[0]==1)||(buf[0]==2)||(buf[0]==3)) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==4)){
362 merker[4]=buf[0];
363 syncstate=5;
364 }
365
366
367 if ((buf[0]==0) && (merker[4]==1) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
368 state=10; // state 10 bereit fuer 0100
369 printflag=FALSE;
370 for(i=0;i<5;i++)merker[i]=0;
371 x=1;
372 y=8;
373 stelle=0;
374 }
375 if ((buf[0]==0) && (merker[4]==2) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
376 state=20; // state 10 bereit fuer 0100
377 printflag=FALSE;
378 for(i=0;i<5;i++)merker[i]=0;
379 x=2;
380 y=8;
381 stelle=0;
382 }
383 if ((buf[0]==0) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
384 state=30; // state 10 bereit fuer 0100
385 printflag=FALSE;
386 for(i=0;i<5;i++)merker[i]=0;
387 dsIndex=0;
388 x=3;
389 y=8;
390 stelle=0;
391 }
392 if ((buf[0]==1) && (merker[4]==3) && (merker[0]==170) && (merker[1]==85) && (merker[2]==85) && (merker[3]==170) && (syncstate==5)){
393 state=31; // state 10 bereit fuer 0100
394 printflag=FALSE;
395 for(i=0;i<5;i++)merker[i]=0;
396 dfIndex=0;
397 x=4;
398 y=8;
399 stelle=0;
400 }
401
402 zeilenproblock=3;
403
404 if ((state==10) && printflag) {
405 z=(x-1)*zeilenproblock+x;
406 mvprintw(z,1,"0100:");
407 mvaddch(z,y,buf[0]);
408 mvprintw(z+1,y,"%02X ",buf[0]);
409 mvprintw(z+2,y,"%d ",stelle);
410 y+=3;
411 stelle++;
412 }
413 else if ((state==20) && printflag) {
414 z=(x-1)*zeilenproblock+x;
415 mvprintw(z,1,"0200:");
416 mvaddch(z,y,buf[0]);
417 mvprintw(z+1,y,"%02X ",buf[0]);
418 mvprintw(z+2,y,"%d ",stelle);
419 y+=3;
420 stelle++;
421 }
422 else if ((state==30) && printflag){
423 z=(x-1)*zeilenproblock+x;
424 mvprintw(z,1,"0300:");
425 mvaddch(z,y,buf[0]);
426 mvprintw(z+1,y,"%02X ",buf[0]);
427 mvprintw(z+2,y,"%d ",stelle);
428 y+=3;
429 stelle++;
430 if(dsIndex<100)datensatz[dsIndex++]=buf[0];
431 }
432 else if ((state==31) && printflag) {
433 z=(x-1)*zeilenproblock+x;
434 mvprintw(z,1,"0301:");
435 mvaddch(z,y,buf[0]);
436 mvprintw(z+1,y,"%02X ",buf[0]);
437 mvprintw(z+2,y,"%d ",stelle);
438 y+=3;
439 stelle++;
440 if(dfIndex<100)datenfeld[dfIndex++]=buf[0];
441 }
442 else{
443 //printf("syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]);
444 }
445 //mvprintw(5,1,"Test");
446 printflag=TRUE;
447 refresh();
448 //printf("E: syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]);
449 //if (buf[0]=='z') STOP=TRUE;
450 //x max = 4
451 z=20;
452 t1=35;
453 t2=t1+30;
454 sort1=0;
455 mvprintw(z+sort1,1,"Datum: (2,3)");
456 datumformatieren(datensatz[2],datensatz[3]);
457 //printf("datum: %s",datum);
458 mvprintw(z+sort1,t1,datum);
459 mvprintw(z+sort1,t2,"%02X %02X",datensatz[2],datensatz[3]);
460 sort1++;
461 mvprintw(z+sort1,1,"Uhrzeit: (4,5)");
462 uhrzeitformatieren(datensatz[4],datensatz[5]);
463 //printf("uhrzeit: %s",uhrzeit);
464 mvprintw(z+sort1,t1,uhrzeit);
465 mvprintw(z+sort1,t2,"%02X %02X",datensatz[4],datensatz[5]);
466 sort1++;
467 mvprintw(z+sort1,1,"Kollektor: (6,7)");
468 temperaturformatieren(datensatz[6],datensatz[7]);
469 //printf("temperatur: %s",temperatur);
470 mvprintw(z+sort1,t1,"%s",temperatur);
471 mvprintw(z+sort1,t2,"%02X %02X",datensatz[6],datensatz[7]);
472 sort1++;
473 mvprintw(z+sort1,1,"Speicher unten: (8,9)");
474 temperaturformatieren(datensatz[8],datensatz[9]);
475 //printf("temperatur: %s",temperatur);
476 mvprintw(z+sort1,t1,"%s",temperatur);
477 mvprintw(z+sort1,t2,"%02X %02X",datensatz[8],datensatz[9]);
478 sort1++;
479 mvprintw(z+sort1,1,"Speicher oben: (10,11)");
480 temperaturformatieren(datensatz[10],datensatz[11]);
481 //printf("temperatur: %s",temperatur);
482 mvprintw(z+sort1,t1,"%s",temperatur);
483 mvprintw(z+sort1,t2,"%02X %02X",datensatz[10],datensatz[11]);
484 sort1++;
485 mvprintw(z+sort1,1,"Thermostat: (12,13)");
486 temperaturformatieren(datensatz[12],datensatz[13]);
487 //printf("temperatur: %s",temperatur);
488 mvprintw(z+sort1,t1,"%s",temperatur);
489 mvprintw(z+sort1,t2,"%02X %02X",datensatz[12],datensatz[13]);
490 sort1++;
491 mvprintw(z+sort1,1,"Poolschutz: (14,15)");
492 temperaturformatieren(datensatz[14],datensatz[15]);
493 //printf("temperatur: %s",temperatur);
494 mvprintw(z+sort1,t1,"%s",temperatur);
495 mvprintw(z+sort1,t2,"%02X %02X",datensatz[14],datensatz[15]);
496 sort1++;
497 mvprintw(z+sort1,1,"Ertrag: (16,17)");
498 temperaturformatieren(datensatz[16],datensatz[17]);
499 //printf("temperatur: %s",temperatur);
500 mvprintw(z+sort1,t1,"%s",temperatur);
501 mvprintw(z+sort1,t2,"%02X %02X",datensatz[16],datensatz[17]);
502 sort1++;
503 mvprintw(z+sort1,1,"Ruecklaufanhebung T7: (18,19)");
504 temperaturformatieren(datensatz[18],datensatz[19]);
505 //printf("temperatur: %s",temperatur);
506 mvprintw(z+sort1,t1,"%s",temperatur);
507 mvprintw(z+sort1,t2,"%02X %02X",datensatz[18],datensatz[19]);
508 sort1++;
509 mvprintw(z+sort1,1,"Ruecklaufanhebung T8: (20,21)");
510 temperaturformatieren(datensatz[20],datensatz[21]);
511 //printf("temperatur: %s",temperatur);
512 mvprintw(z+sort1,t1,"%s",temperatur);
513 mvprintw(z+sort1,t2,"%02X %02X",datensatz[20],datensatz[21]);
514 sort1++;
515 mvprintw(z+sort1,1,"T: (22,23)");
516 temperaturformatieren(datensatz[22],datensatz[23]);
517 //printf("temperatur: %s",temperatur);
518 mvprintw(z+sort1,t1,"%s",temperatur);
519 mvprintw(z+sort1,t2,"%02X %02X",datensatz[22],datensatz[23]);
520 sort1++;
521 mvprintw(z+sort1,1,"Dummy: (24,25)");
522 dummyformatieren(datensatz[24],datensatz[25]);
523 //printf("dummy: %s",dummy);
524 mvprintw(z+sort1,t1,dummy);
525 mvprintw(z+sort1,t2,"%02X %02X",datensatz[24],datensatz[25]);
526 sort1++;
527 mvprintw(z+sort1,1,"Strahlung: (26,27)");
528 temperaturformatieren(datensatz[26],datensatz[27]);
529 //printf("temperatur: %s",temperatur);
530 mvprintw(z+sort1,t1,temperatur);
531 mvprintw(z+sort1,t2,"%02X %02X",datensatz[26],datensatz[27]);
532 sort1++;
533 mvprintw(z+sort1,1,"Dummy: (28,29)");
534 dummyformatieren(datensatz[28],datensatz[29]);
535 //printf("dummy: %s",dummy);
536 mvprintw(z+sort1,t1,dummy);
537 mvprintw(z+sort1,t2,"%02X %02X",datensatz[28],datensatz[29]);
538 sort1++;
539 mvprintw(z+sort1,1,"Dummy: (30,31)");
540 temperaturformatieren(datensatz[30],datensatz[31]);
541 //printf("dummy: %s",dummy);
542 mvprintw(z+sort1,t1,dummy);
543 mvprintw(z+sort1,t2,"%02X %02X",datensatz[30],datensatz[31]);
544 sort1++;
545 mvprintw(z+sort1,1,"Ausgang 1: (32)");
546 prozentformatieren(datensatz[32]);
547 //printf("prozent: %s",prozent);
548 mvprintw(z+sort1,t1,prozent);
549 mvprintw(z+sort1,t2,"%02X",datensatz[32]);
550 sort1++;
551 mvprintw(z+sort1,1,"Ausgang 2: (33)");
552 prozentformatieren(datensatz[33]);
553 //printf("prozent: %s",prozent);
554 mvprintw(z+sort1,t1,prozent);
555 mvprintw(z+sort1,t2,"%02X",datensatz[33]);
556 sort1++;
557 mvprintw(z+sort1,1,"Ausgang 3: (34)");
558 prozentformatieren(datensatz[34]);
559 //printf("prozent: %s",prozent);
560 mvprintw(z+sort1,t1,prozent);
561 mvprintw(z+sort1,t2,"%02X",datensatz[34]);
562 sort1++;
563 mvprintw(z+sort1,1,"Ausgang 4: (35)");
564 prozentformatieren(datensatz[35]);
565 //printf("prozent: %s",prozent);
566 mvprintw(z+sort1,t1,prozent);
567 mvprintw(z+sort1,t2,"%02X",datensatz[35]);
568 sort1++;
569 mvprintw(z+sort1,1,"Ausgang 5: (36)");
570 prozentformatieren(datensatz[36]);
571 //printf("prozent: %s",prozent);
572 mvprintw(z+sort1,t1,prozent);
573 mvprintw(z+sort1,t2,"%02X",datensatz[36]);
574 sort1++;
575 mvprintw(z+sort1,1,"Ausgang 6: (37)");
576 prozentformatieren(datensatz[37]);
577 //printf("prozent: %s",prozent);
578 mvprintw(z+sort1,t1,prozent);
579 mvprintw(z+sort1,t2,"%02X",datensatz[37]);
580 sort1++;
581 mvprintw(z+sort1,1,"Fehler: (38-45)");
582 fehlerformatieren(datensatz[38],datensatz[39],datensatz[40],datensatz[41],datensatz[42],datensatz[43],datensatz[44],datensatz[45]);
583 //printf("fehler: %s",fehler);
584 mvprintw(z+sort1,t1,fehler);
585 mvprintw(z+sort1,t2,"%02X %02X %02X %02X %02X %02X %02X %02X",datensatz[38],datensatz[39],datensatz[40],datensatz[41],datensatz[42],datensatz[43],datensatz[44],datensatz[45]);
586 sort1++;
587 mvprintw(z+sort1,1,"Speicher 1: (46,47)");
588 temperaturformatieren(datensatz[46],datensatz[47]);
589 //printf("temperatur: %s",temperatur);
590 mvprintw(z+sort1,t1,temperatur);
591 mvprintw(z+sort1,t2,"%02X %02X",datensatz[46],datensatz[47]);
592 sort1++;
593 mvprintw(z+sort1,1,"Dummy: (48,49)");
594 dummyformatieren(datensatz[48],datensatz[49]);
595 //printf("dummy: %s",dummy);
596 mvprintw(z+sort1,t1,dummy);
597 mvprintw(z+sort1,t2,"%02X %02X",datensatz[48],datensatz[49]);
598 sort1++;
599 mvprintw(z+sort1,1,"Speicher 2: (50,51)");
600 stundenformatieren(datensatz[50],datensatz[51]);
601 //printf("stunden: %s",stunden);
602 mvprintw(z+sort1,t1,stunden);
603 mvprintw(z+sort1,t2,"%02X %02X",datensatz[50],datensatz[51]);
604 sort1++;
605 mvprintw(z+sort1,1,"Dummy: (52,53)");
606 dummyformatieren(datensatz[52],datensatz[53]);
607 //printf("dummy: %s",dummy);
608 mvprintw(z+sort1,t1,dummy);
609 mvprintw(z+sort1,t2,"%02X %02X",datensatz[52],datensatz[53]);
610 sort1++;
611 mvprintw(z+sort1,1,"Dummy: (54,55)");
612 dummyformatieren(datensatz[54],datensatz[55]);
613 //printf("dummy: %s",dummy);
614 mvprintw(z+sort1,t1,dummy);
615 mvprintw(z+sort1,t2,"%02X %02X",datensatz[54],datensatz[55]);
616 sort1++;
617 mvprintw(z+sort1,1,"Funktion 1 aktiv: (56,57)");
618 dummyformatieren(datensatz[56],datensatz[57]);
619 //printf("dummy: %s",dummy);
620 mvprintw(z+sort1,t1,dummy);
621 mvprintw(z+sort1,t2,"%02X %02X",datensatz[56],datensatz[57]);
622 sort1++;
623 mvprintw(z+sort1,1,"Funktion 2 aktiv: (58,59)");
624 dummyformatieren(datensatz[58],datensatz[59]);
625 //printf("dummy: %s",dummy);
626 mvprintw(z+sort1,t1,dummy);
627 mvprintw(z+sort1,t2,"%02X %02X",datensatz[58],datensatz[59]);
628 sort1++;
629 mvprintw(z+sort1,1,"Volumenstrom: (60,61)");
630 dummyformatieren(datensatz[60],datensatz[61]);
631 //printf("dummy: %s",dummy);
632 mvprintw(z+sort1,t1,dummy);
633 mvprintw(z+sort1,t2,"%02X %02X",datensatz[60],datensatz[61]);
634 sort1++;
635 mvprintw(z+sort1,1,"Dummy: (62,63)");
636 dummyformatieren(datensatz[62],datensatz[63]);
637 //printf("dummy: %s",dummy);
638 mvprintw(z+sort1,t1,dummy);
639 mvprintw(z+sort1,t2,"%02X %02X",datensatz[62],datensatz[63]);
640 sort1++;
641 mvprintw(z+sort1,1,"Dummy: (64,65)");
642 dummyformatieren(datensatz[64],datensatz[65]);
643 //printf("dummy: %s",dummy);
644 mvprintw(z+sort1,t1,dummy);
645 mvprintw(z+sort1,t2,"%02X %02X",datensatz[64],datensatz[65]);
646
647 t3=t2+20;
648 sort2=0;
649
650 i=0;
651 mvprintw(z+sort2,t3,"%02X ",datenfeld[i++]);
652 mvprintw(z+sort2,t3+3,"%02X ",datenfeld[i++]);
653 mvprintw(z+sort2,t3+6,"%02X ",datenfeld[i++]);
654 for(k=0;k<32;k++){
655 sprintf(tmp,"%X",datenfeld[i+(k*16)]);
656 strcpy(data,tmp);
657 sort2=hextodec(data)*2;
658 if (sort2>62) sort2=64;
659 for(l=0;l<16;l++){
660 mvprintw(z+sort2,t3+(l*3),"%02X ",datenfeld[i+(k*16)+l]);
661 if (datenfeld[i+(k*16)+l]!=0){ mvprintw(z+sort2+1,t3+(l*3),"%c ",datenfeld[i+(k*16)+l]); }
662 else { mvprintw(z+sort2+1,t3+(l*3)," "); }
663 }
664 }
665
666 }
667 endwin();
668
669 close(fd);
670
671 tcsetattr(fd,TCSANOW,&oldtio);
672
673 return EXIT_SUCCESS;
674 }
Sungoserialcapture
Diese Programm liest die Interfacedaten und schreibt die Daten ohne Auswertung zur weiteren Bearbeitung in ein Datei. Auch in diesem Programm sind noch die alten Varianten der Konvertierungsfunktionen vorhanden. Dies ist zwar nicht elegant, aber es funktioniert.
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <termios.h> // termios is the API that is in general recommended for serial I/O in Unix.
9 #include <curses.h>
10
11 #define BAUDRATE B115200
12 #define MODEMDEVICE "/dev/ttyS1"
13 #define _POSIX_SOURCE 1 /* POSIX compliant source */
14 #define FALSE 0
15 #define TRUE 1
16
17 volatile int STOP=FALSE;
18
19 char datum[11];
20 char uhrzeit[7];
21 char temperatur[8];
22 char prozent[7];
23 char fehler[17];
24 char stunden[8];
25 char dummy[7];
26
27 unsigned int hextodec(char hex[10]){
28 unsigned int decimal=0;
29 unsigned int length=0;
30 unsigned int base = 1;
31 int i=0;
32
33 while(hex[i]!='\0'){
34 i++;
35 }
36 length=i;
37
38 //printf("hextodec %s\n\r",hex);
39 //printf("length %d\n\r",length);
40
41 for(i = length-1; i >= 0; i--){
42 //printf("i: %d\n\r",i);
43 if (i<0)i=0;
44 if(hex[i] >= '0' && hex[i] <= '9'){
45 decimal += ((unsigned char)hex[i] - 48) * base;
46 base *= 16;
47 }
48 else if(hex[i] >= 'A' && hex[i] <= 'F'){
49 decimal += ((unsigned char)hex[i] - 55) * base;
50 base *= 16;
51 }
52 else if(hex[i] >= 'a' && hex[i] <= 'f'){
53 decimal += ((unsigned char)hex[i] - 87) * base;
54 base *= 16;
55 }
56 }
57 //printf("decimal %d\n\r",decimal);
58 return decimal;
59 }
60
61
62 void datumformatieren(unsigned char lowbyte,unsigned char highbyte){
63 char data[10]="";
64 char tmp[3]="";
65 char datumStr_formatted[]="00.00.2021";
66 char datumStr[5]="";
67 unsigned int datumInt;
68 size_t l;
69
70 sprintf(tmp,"%X",highbyte);
71 strcpy(data,tmp);
72 //l=strlen(data);
73 //printf("data: %s (%d)\n\r",data,l);
74
75 sprintf(tmp,"%X",lowbyte);
76 strcat(data,tmp);
77 //l=strlen(data);
78 //printf("data: %s (%d)\n\r",data,l);
79
80 //strcpy(data,"0135");
81 //printf("data: %s\n\r",data);
82 datumInt=hextodec(data);
83 //printf("int: %d\n\r",datumInt);
84 sprintf(datumStr,"%d",datumInt);
85 if(strlen(datumStr)==3){
86 datumStr_formatted[0]=datumStr[1];
87 datumStr_formatted[1]=datumStr[2];
88 datumStr_formatted[4]=datumStr[0];
89 strcpy(datum,datumStr_formatted);
90 }
91 else if(strlen(datumStr)==4){
92 datumStr_formatted[0]=datumStr[2];
93 datumStr_formatted[1]=datumStr[3];
94 datumStr_formatted[3]=datumStr[0];
95 datumStr_formatted[4]=datumStr[1];
96 strcpy(datum,datumStr_formatted);
97 }
98 else{
99 strcpy(datum,"Error!");
100 }
101 return;
102 }
103
104
105 void uhrzeitformatieren(unsigned char lowbyte,unsigned char highbyte){
106 char data[10]="";
107 char tmp[3]="";
108 char uhrzeitStr_formatted[]="00:00";
109 unsigned int uhrzeitInt, stunden, minuten;
110 size_t l;
111
112 sprintf(tmp,"%X",highbyte);
113 strcpy(data,tmp);
114 //l=strlen(data);
115 //printf("data: %s (%d)\n\r",data,l);
116
117 sprintf(tmp,"%X",lowbyte);
118 strcat(data,tmp);
119 //l=strlen(data);
120 //printf("data: %s (%d)\n\r",data,l);
121
122 //strcpy(data,"1500");
123 //printf("data: %s\n\r",data);
124 uhrzeitInt=hextodec(data);
125 //printf("int: %d\n\r",uhrzeitInt);
126 stunden=(unsigned int)uhrzeitInt/60;
127 minuten=uhrzeitInt-(stunden*60);
128 if(TRUE){ // hier koennte man die gueltig der stunden und minuten noch testen
129 sprintf(uhrzeitStr_formatted,"%d:%d",stunden,minuten);
130 strcpy(uhrzeit,uhrzeitStr_formatted);
131 }
132 else{
133 strcpy(uhrzeit,"Error!");
134 }
135 return;
136 }
137
138 void temperaturformatieren(unsigned char lowbyte,unsigned char highbyte){
139 char data[10]="";
140 char tmp[3]="";
141 char temperaturStr_formatted[]="000.0°C";
142 unsigned int temperaturInt;
143 float temperaturFloat;
144 size_t l;
145
146 sprintf(tmp,"%X",highbyte);
147 strcpy(data,tmp);
148 //l=strlen(data);
149 //printf("data: %s (%d)\n\r",data,l);
150
151 sprintf(tmp,"%X",lowbyte);
152 strcat(data,tmp);
153 //l=strlen(data);
154 //printf("data: %s (%d)\n\r",data,l);
155
156 //strcpy(data,"1500");
157 //printf("data: %s\n\r",data);
158 temperaturInt=hextodec(data);
159 //printf("int: %d\n\r",temperaturInt);
160 temperaturFloat=(float)temperaturInt/10.0;
161
162 if(TRUE){
163 sprintf(temperaturStr_formatted,"%.1f°C",temperaturFloat);
164 strcpy(temperatur,temperaturStr_formatted);
165 }
166 else{
167 strcpy(temperatur,"Error!");
168 }
169 return;
170 }
171
172
173 void prozentformatieren(unsigned char byte){
174 char data[10]="";
175 char tmp[3]="";
176 char prozentStr_formatted[]="000%";
177 unsigned int prozentInt;
178 size_t l;
179
180 sprintf(tmp,"%X",byte);
181 strcpy(data,tmp);
182 //l=strlen(data);
183 //printf("data: %s (%d)\n\r",data,l);
184
185
186 //strcpy(data,"1500");
187 //printf("data: %s\n\r",data);
188 prozentInt=hextodec(data);
189 //printf("int: %d\n\r",prozentInt);
190
191 if(TRUE){
192 sprintf(prozentStr_formatted,"%d%%",prozentInt);
193 strcpy(prozent,prozentStr_formatted);
194 }
195 else{
196 strcpy(prozent,"Error!");
197 }
198 return;
199 }
200
201
202 void stundenformatieren(unsigned char lowbyte,unsigned char highbyte){
203 char data[10]="";
204 char tmp[3]="";
205 char stundenStr_formatted[]="000000h";
206 unsigned int stundenInt;
207
208 sprintf(tmp,"%X",highbyte);
209 strcpy(data,tmp);
210 //l=strlen(data);
211 //printf("data: %s (%d)\n\r",data,l);
212
213 sprintf(tmp,"%X",lowbyte);
214 strcat(data,tmp);
215 //l=strlen(data);
216 //printf("data: %s (%d)\n\r",data,l);
217
218 //strcpy(data,"1500");
219 //printf("data: %s\n\r",data);
220 stundenInt=hextodec(data);
221 //printf("int: %d\n\r",temperaturInt);
222
223 if(TRUE){
224 sprintf(stundenStr_formatted,"%dh",stundenInt);
225 strcpy(stunden,stundenStr_formatted);
226 }
227 else{
228 strcpy(stunden,"Error!");
229 }
230 return;
231 }
232
233 void fehlerformatieren(unsigned char byte1,unsigned char byte2,unsigned char byte3,unsigned char byte4,unsigned char byte5,unsigned char byte6,unsigned char byte7,unsigned char byte8){
234 char data[10]="";
235 char tmp[3]="";
236 char fehlerStr_formatted[9];
237 unsigned int fehlerInt;
238
239 fehlerInt=12345;
240
241 if(TRUE){
242 sprintf(fehlerStr_formatted,"%d",fehlerInt);
243 strcpy(fehler,fehlerStr_formatted);
244 }
245 else{
246 strcpy(fehler,"Error!");
247 }
248 return;
249 }
250
251
252 void dummyformatieren(unsigned char lowbyte,unsigned char highbyte){
253 char data[10]="";
254 char tmp[3]="";
255
256 sprintf(tmp,"%X",highbyte);
257 strcpy(data,tmp);
258 //l=strlen(data);
259 //printf("data: %s (%d)\n\r",data,l);
260
261 sprintf(tmp,"%X",lowbyte);
262 strcat(data,tmp);
263 //l=strlen(data);
264 //printf("data: %s (%d)\n\r",data,l);
265
266 if(TRUE){
267 strcpy(dummy,data);
268 }
269 else{
270 strcpy(dummy,"Error!");
271 }
272 return;
273 }
274
275 int main(int argc, char **argv)
276 {
277 FILE *fp;
278 struct termios oldtio,newtio;
279
280 int fd;
281 int c;
282 int res;
283 int i,k,l;
284 unsigned int x,y,z,t1,t2,dsIndex, dfIndex, dfX, dfY, sort1,sort2, stelle, zeilenproblock;
285 unsigned int state=0, syncstate=0;
286
287 unsigned char buf[1];
288 unsigned char merker[6];
289 unsigned char datensatz[100];
290 unsigned char datenfeld[100];
291 unsigned char datenfelder[50][16];
292 char data[10]="";
293 char tmp[3]="";
294 bool printflag;
295
296 // wenn in Kommandozeile die Schnittstelle mitgegeben wird, dann nimm diese sonst veruche default
297 if (argc > 1)
298 fd = open(argv[1], O_RDWR | O_NOCTTY );
299 else
300 fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
301 if (fd <0) {
302 perror(MODEMDEVICE);
303 exit(-1);
304 }
305
306 // sichere die aktuellen Einstellungen
307 tcgetattr(fd,&oldtio);
308
309 // baue die neuen Einstellungen zusammen
310 bzero(&newtio, sizeof(newtio));
311 newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
312 newtio.c_iflag = IGNPAR | IXON | IXOFF;
313 newtio.c_oflag = 0;
314 newtio.c_lflag = 0;
315 newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
316 newtio.c_cc[VMIN] = 5; /* blocking read until 5 chars received */
317
318 tcflush(fd, TCIFLUSH);
319 tcsetattr(fd,TCSANOW,&newtio);
320
321 setvbuf(stdout, (char *)NULL, _IONBF, 0);
322
323 fp=fopen("sungocapture.bin","w");
324
325 if (fp == NULL)
326 return 0;
327
328 while (STOP==FALSE) { /* loop for input */
329 res = read(fd,buf,1); /* returns after 5 chars have been input */
330 //printf("A: syncstate: %d, state: %d, %X\n\r",syncstate,state,buf[0]);
331
332 fputc(res,fp);
333
334 }
335
336 fclose(fp);
337
338 close(fd);
339
340 tcsetattr(fd,TCSANOW,&oldtio);
341
342 return EXIT_SUCCESS;
343 }