OK, I am a newbie, my first post, I will try to explain carefully. I haven't used C since my undergrad days, I am now in my 50s and fairly new to Arduino. I have been dabbling mostly in Java in the meantime, Be gentle please! I am fully aware that my understanding of C pointers and arrays has gone awry sometime over the last thirty + years, so I will explain what I think is going on, knowing it is flawed, in the hope that someone can put me right.
I am using an ESP8266 as a websocket server using the server from Links2004 here
I am using it to control WS8218 - type LEDs with a websocket client interface (html). When the server receives a websocket colour change event (as a hex string) I want it to store the value in a global variable, such that if the page reloads or a new browser connects, this value will be sent to the client to preserve the state of the controller and update the web page; it does this by sending the client the value when a new connection event happens on the websocket server (ie all this is being handled by web sockets.)
Now, I can make all this work no problem with Strings, but understand that such profligate waste of resources is frowned upon, so I am trying to do it at a lower level. Here goes with my code and what I think is happening:
uint8_t * colourString = (uint8_t*)"#000000";
size_t payloadLength = 7;
So colourString is a pointer, referencing the first element of a uint8_t type array. The string primitive (as I would call it, sorry) is a const char array? So both data types are one byte but chars are signed, is that right? (When are chars negative?) colourString, as a pointer, can't know the length of the aray, so I save that in a separate variable.
The method signature of webSocketEvent looks like this:
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {
and when an event bearing a hex string is received I do this:
if (payload[0] == '#') { // we get RGB data
if(!gSelected && gProgramMode){
//do nothing
}
else{ //any other situation
colourString = payload;
payloadLength = lenght;
And then decode the string to r,g,b and do all the biz, which works fine. 'payload' is also a uint8_t * pointer, so after the assignment, colourString takes the value of payload, thus now referencing the first element of the payload array, right? (or wrong?).
In the same method of our server we handle connection events:
case WStype_CONNECTED: { // if a new websocket connection is established
//Serial.println("Incoming connection, websocket server arduino");
IPAddress ip = webSocket.remoteIP(num);
Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
Serial.printf("colourString sending connected = %s\n", &colourString);
//webSocket.sendTXT(num, colourString); //if String
webSocket.sendTXT(num, colourString, payloadLength); //if not
}
break;
The webserver has the method
bool sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0);
where num is the id of the client.
And a snippet of my serial out:
15:27:22.981 -> [0] get Text: Websocket.js Connection opened: Sun Dec 29 2019 16:27:22 GMT+0800 (China Standard Time)
15:27:29.664 -> Incoming event
15:27:29.664 -> [0] get Text: #70000
15:27:32.555 -> Incoming event
15:27:32.555 -> [0] get Text: #72a00
15:27:40.408 -> handleFileRead: /
15:27:40.446 -> Sent file: /index.html
15:27:40.446 -> Incoming event
15:27:40.446 -> Disconnected
15:27:40.446 ->
15:27:40.484 -> handleFileRead: /main.css
15:27:40.484 -> Sent file: /main.css
15:27:40.625 -> handleFileRead: /WebSocket.js
15:27:40.662 -> Sent file: /WebSocket.js
15:27:40.771 -> Incoming event
15:27:40.771 -> [0] Connected from 192.168.4.2 url: /
15:27:40.771 -> colourString sending connected = ⸮⸮⸮?⸮⸮⸮?⸮⸮⸮?
So why is the colourString garbled here? The client, decodes it to 0,0,0. I have been trying to work this out for many days now. And barked up an entire forest of wrong trees in the process I think (const char * casts, UTF8 errors, etc etc!!) Also please, point out the flaws in my C-thinking
Many thanks in advance,
Joe