Hey Everyone
I am hoping that someone here with a bit more knowledge about the ESP8266 chips can help.
I have just published the PubSub MQTT library and everything works well and compiles fine no problems with Publishing messages but…
The Subscribe node if it is used it compiles and uploads but after a reset on the ESP the chip goes in to a boot loop throwing an Exception 3 (LoadStoreErrorCause = Processor internal physical address or data error during load or store)
Decoding stack results
0x402047cd: HardwareSerial::end() at C:\Users\User\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.3\cores\esp8266\HardwareSerial.cpp line 55
0x40203414: ESP8266WiFiSTAClass::begin(char const*, char const*, int, unsigned char const*, bool) at C:\Users\User\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.3\libraries\ESP8266WiFi\src\ESP8266WiFiSTA.cpp line 124
0x40204838: _GLOBAL__sub_I__ZN14HardwareSerialC2Ei() at C:\Users\User\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.3\cores\esp8266\HardwareSerial.cpp line 139
0x402026da: xod::xod_dev__esp8266_mcu__connect::evaluate(xod::xod_dev__esp8266_mcu__connect::ContextObject*) at C:\Users\User\Documents\Arduino\sketch_dec17b/sketch_dec17b.ino line 1407
0x40202e0f: xod::runTransaction() at C:\Users\User\Documents\Arduino\sketch_dec17b/sketch_dec17b.ino line 2126
0x40202e0f: xod::runTransaction() at C:\Users\User\Documents\Arduino\sketch_dec17b/sketch_dec17b.ino line 2126
0x40204994: Print::printNumber(unsigned long, unsigned char) at C:\Users\User\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.3\cores\esp8266\Print.cpp line 256
0x40202fa2: xod::runTransaction() at C:\Users\User\Documents\Arduino\sketch_dec17b/sketch_dec17b.ino line 2197
0x40205018: user_init() at C:\Users\User\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.3\cores\esp8266\core_esp8266_main.cpp line 216
I am trying to reuse as many of the builtin nodes for networking as i can to make it more versatile. Can anyone shed some light on this one please? (Maybe one of the devs that did the original networking nodes?)
I looked at the implementation and that’s suspicious:
{{#global}}
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
char* topicG;
char* payloadG;
int lengthG = 0;
bool MQTTConnected = false;
void callback(char* topic, byte* payload, unsigned int length) {
// You change the payloadG *pointer* in an unpredictable way, not copy
// data there
for (int i = 0; i < length; i++) {
payloadG = payloadG + ((char)payload[i]);
}
// you can store a pointer to a memory area with unknown life time. It can
// potentially be destroyed right after the callback
topicG = topic;
lengthG = length;
}
{{/global}}
Thanks I completely missed that you’re quite right.
I had to rewrite this call back because in the example code the data is used immediately to be pushed to the serial connection I cobbled that together from a couple of different examples.
I’m trying to just create a buffer for the data in global scope so that the other nodes can access it when they get processed if it relates to them , it is definitely not an ideal implementation as the callback can change the buffer during a cycle if the messages are coming into quickly.
The library does have an implementation for a stream object which would be the better alternative but I do not have a lot of experience using these do you think this would be the better way to go?
One possible approach would be streaming data byte-by-byte from MQTT nodes. But it would require a total rework, another library, etc.
Your approach is possible as well. I didn’t test it, but are you looking for something like this?
{{#global}}
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// We’ll keep own copy of the buffer
// https://github.com/knolleary/pubsubclient/blob/v2.7/src/PubSubClient.h#L26
// The buffer holds topic and the payload
uint8_t g_buffer[MQTT_MAX_PACKET_SIZE];
// Convenient pointers to the buffer
// The topic is always at the beginning
char* g_topic = g_buffer;
// This will vary
uint8_t* g_payload;
size_t g_payloadLength;
void callback(char* topic, byte* payload, unsigned int length) {
// Copy the new topic (including trailing \x00) to the head of the buffer
strcpy(g_buffer, topic);
// Payload goes right after the topic and \x00 symbol
g_payload = g_buffer + strlen(topic) + 1;
// Copy it there...
memcpy(g_payload, payload, length);
// ...keep the length for future use
g_payloadLength = length
}
{{/global}}