Hallo, ich brauche etwas Unterstützung, Ich bin auf Home-Assistant zur Haussteuerung gestoßen und versuche, meine Sensor/Actor Module dort einzubinden. HASSIO sowie den MQTT-Broker (Mosqitto) habe ich in VMWARE (Host: win 7) zum laufen gebracht. Meine Sensor/Actor Systeme basieren auf Arduino-Controllerplatinen, die ich mittels ATMEL Studio in Ansi-C programmiere. C++ verwende ich nicht, da ich davon und allgemein von der OOP keine bzw. nicht viel Ahnung habe. Um mal schnell etwas zum Spielen zu bekommen habe ich ein ESB8266-Modul unter Verwendung der Arduino-Plattform und der PubSubClient-Library mit "Q&D Programmiermethode" testweise zum Spielen gebracht. Leider ist diese Lib nur unter C++ verwendbar und nicht unter ANSI-C. Einen Versuch, sie nach ANSI-C zu portieren habe ich gleich abgebrochen, die Lib ist riesengroß. Nach weiterer längerer Web-Suche stieß ich auf die MQTT-C Lib von Liam Bindle bei GITHUB, aber leider sind keine brauchbaren Anwendungs-Dokus oder gar brauchbare Beispiele zu finden. Es gelingt mir bis dato nicht, mein System mit dem MQTT Broker zu verbinden oder gar Daten hoch zu senden. Wäre supertoll, falls hier jemand Ahnung von dieser Library hätte und ggf. Beispiele / Links nennen könnte. Vielleicht gibt es auch eine besser dokumentierte ANSI-C Library? Danke in Voraus! Yogy
jemand schrieb: > https://mqtt.org/software/ > Eine davon vielleicht? Über diese Seite bin ich ja zu meinem MQTT-C von Liam Bindle gekommen. Diese Lib ist relativ "schmal" aber wohl für mich zu komplex im einsatz. Ich werde mir wohl hier eine andere Lib aussuchen müssen. VG Yogy
Vielleicht solltest du dich mal beschäftigen wie die ESP Firmware aufgebaut ist. Es gibt ein SDK, das beinhaltet FreeRTOS, LwIP und Treiber für WLAN und BT. Und einiges an Libraries. https://github.com/espressif/ESP8266_RTOS_SDK Das ist alles in C geschrieben. Darauf aufbauend gibt es das Arduino Core, dass einen ermöglich Arduino Sketche für den ESP zu erstellen. Verwenden viele muss man aber nicht. Es gibt hier auch eine MQTT Lib die direkt auf dem SDK aufbaut und kein Arduino Core braucht. https://github.com/espressif/esp-mqtt Die ist in C geschrieben.
Hallo zusammen, ich habe mir die anderen Libs angeschaut und eigentlich keine einzige gefunden habe, die auf meinem System, das ohne weitere Firmware oder Betriebssystem arbeitet, ohnen weiteres ohne größerer Arbeiten einsetzbar wäre. Ich habe mich dann weiter mit der Liam Bindle MQTT-C Lib beschäftigt und diese nun fast zu Spielen gebracht. Publish funzt. Ursache der Probleme war/ist das Zusammenspiel mit „meinen“ anderen SW-Routinen sowie meiner relativen Unkenntnis der Pointersystematic bei C. Schlußendlich scheitere ich an folgendem Problem: Ich nutze auch die Client-Subscriber Funktion. Kommt eine Antwort vom Broker, dann ruft die MQTT-C -Lib die empfangenen Daten ab mit dem Funktionsaufruf:
1 | ssize_t mqtt_unpack_response(struct mqtt_response* response, const U8 *buf, size_t bufsz) |
So weit. So gut. Die Implementierung der Funktion ist meine Aufgabe, sie muß dazu „meine“ Routine (socket-read aus der W5500 Lib) aufrufen. Nun scheitere ich daran, meine gelesenen Daten an den „buf“ zu übergeben. Meine Routine derzeit:
1 | ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void* buf, size_t bufsz, int flags) |
2 | {
|
3 | U8 recv_buff[1024]; |
4 | const void *const start = buf; //Ist die Speicheradresse des Buffer-Starts |
5 | ssize_t rv; |
6 | |
7 | rv = (getSn_RX_RSR(_MQTT_Client_sock_nr)); |
8 | |
9 | if (rv == 0) |
10 | {
|
11 | return 0; |
12 | }
|
13 | else
|
14 | {
|
15 | |
16 | W5500_socket_recv(_MQTT_Client_sock_nr, recv_buff, rv); //ganzen buffer aus W5500 lesen!!! |
17 | bufsz -= rv; |
18 | // Nun umkopieren, das nicht funktioniert
|
19 | for (U8 i=0;i<rv;i++) |
20 | {
|
21 | *(U8*)buf++ = recv_buff[i]; |
22 | }
|
23 | return buf - start; |
24 | }
|
25 | }
|
Der Problempunkt ist:
1 | *(U8*)buf++ = recv_buff[i]; |
Das gibt zwar keine Kompilerfehler, funktioniert aber nicht. IMHO wäre richtig
1 | *buf++ = recv_buff[i]; |
aber das gibt die Fehlermeldung: „invalid use of void expression.“ Der Versuch mit:
1 | buf[i] = recv_buff[i]; |
bringt den gleichen Fehler. Und ein
1 | (U8)buf[i] = recv_buff[i]; oder (U8*)buf[i] = recv_buff[i]; |
ebenso. Wo liegt mein Fehler??? Danke und VG Yogy
Pointerarithmetik benötigt eine definierte Größe des Datentyps auf den gezeigt wird, und void hat keine definierte Größe. Statt der for-Schleife würde ich memcpy(buf,recv_buff,rv); return rv; benutzen. Rätselhaft bleibt warum *(U8*)buf++ = recv_buff[i]; nicht auch Fehler generiert, *(U8*)buf++ wird ja als *(U8*)(buf++) ausgewertet und buf++ ist wiederum verbotene void*-Arithmetik ... LG, Sebastian
:
Bearbeitet durch User
Sebastian W. schrieb: > Rätselhaft bleibt warum *(U8*)buf++ = recv_buff[i]; nicht auch Fehler > generiert, *(U8*)buf++ wird ja als *(U8*)(buf++) ausgewertet und buf++ > ist wiederum verbotene void*-Arithmetik ... Pointer-Arithmetik auf void Pointern ist eine gcc Erweiterung.
Sebastian W. schrieb: > Pointerarithmetik benötigt eine definierte Größe des Datentyps auf den > gezeigt wird, und void hat keine definierte Größe. > > Statt der for-Schleife würde ich memcpy(buf,recv_buff,rv); return rv; > benutzen. > > Rätselhaft bleibt warum *(U8*)buf++ = recv_buff[i]; nicht auch Fehler > generiert, *(U8*)buf++ wird ja als *(U8*)(buf++) ausgewertet und buf++ > ist wiederum verbotene void*-Arithmetik ... > > LG, Sebastian Ja, danke, mit memcopy funktioniert es. Nur, warum es nicht mit der for-Schleife funktioniert ist mir immer noch schleierhaft. Übrigens kann ich nach memcopy den inhalt von buf korect auslesen mit:
1 | for (U8 i=0;i<rv;i++) |
2 | {
|
3 | PutcService( *(U8*)(buf+i)); |
4 | }
|
(PutcService gibt bei mir ein Zeichen seriell aus) Auf jeden Fall danke für den Tip. Viele Grüße, Yogy
Hanns-Jürgen M. schrieb: > Nur, warum es nicht mit der > for-Schleife funktioniert ist mir immer noch schleierhaft.
1 | *(U8*)buf++ |
entspricht
1 | *(U8*)(buf++) |
und das ist void-Pointer-Arithmetik. Besser vermeiden.
1 | *buf++ |
ist void-Pointer-Arithmetik und dazu noch void-Pointer-Dereferenzierung. Das ist in jedem Fall ein Fehler.
1 | buf[i] |
ist auch void-Pointer-Arithmetik und dazu noch void-Pointer-Dereferenzierung. Das ist auch in jedem Fall ein Fehler.
1 | (U8)buf[i] |
ist dasselbe, und dann castest du void noch in U8. Ich glaube das geht nicht, man kann nur void-Pointer in andere Pointer casten, aber nicht void selbst. Ausserdem, selbst wenn das ginge, ist das Resultat nach dem cast ein Wert und kein lvalue. Bei
1 | (U8*)buf[i] |
castest du void in einen U8-Pointer. Das ist noch falscher. Funktionieren müssten eigentlich
1 | *((U8*)buf)++ |
oder
1 | ((U8*)buf)[i] |
oder
1 | *((U8*)buf+i) |
LG, Sebastian
:
Bearbeitet durch User
Das Spiel funktioniert anderes herum... Du prüfst das Emfangsregister und übergibst dann die Daten an den MQTT Teil. Die Tücke beim w5500 ist das beim auslesen auch weitere Pakete im Buffer liegen können. Den Code verstehe ich nicht, da fehlen mir die Zusammenhänge. Es sei denn deine Library benutz Funktionspointer für den Ethernet Stack. Dann musst du dafür sorgen das die Daten so übergeben werden.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.