At the moment, I'm using various operating systems and devices like the Raspberry pi to control lights and other stuff over websockets. I use websockets since they added the support on Chrome. I write a lot of Javascript stuff for fun. Websockets allow you to communicate with another server without the need of reloading a page. It's a lot better than Ajax. Once the connection is open with a web server data can travel both ways. No unnecessary headers to send. No unnecessary requests. You just send only the data you want, this in both directions. AND FAST, DAMN FAST.
For example I use Javascript's requestAnimationframe
to send RGB values (based on music frequency) to lamps connected to the network. requestAnimationframe
executes approximately at 60 Hz. But that's not the highest speed, I also created some "web controllers" to control servos and other stuff with touch and mouse events. In that case it probably touches transmission frequencies of 200-300 data packets (normally I use JSON- encoded strings) or more per second.
Websocket servers have also broadcast which allows you for example to control multiple RGB lamps based on the music you play from basically every modern device that has a browser. I don't use "normal" sockets because of the simple fact that there is no support for sockets in a standard web browser. So I would need to create a custom iOS app, custom Windows app, custom Android app. I said that we know that websockets are made for a fast multi-user / multi-device / bidirectional communication. And it should be really fast or it's useless.
Lately I have a lot of fun with electronics and MCUs, so I made even more lamps and stuff controlled from Arduinos, ATtinys and other microcontrollers. I'm new to C++ but since I write Javascript code since the previous century I just have to slightly modify old Javascript functions to run in the Arduino IDE.
But for sure I'm not ready to write a perfect library for an MCU, so I need to use what I find online.
Apparently there are not many people into websockets. I tested 2-3 Arduino websockets libraries and couldn't get them to work properly.
The last one I tested(Links2004) works but I can't send a 4 decimal string faster than 2 times per second or it crashes.
All I did was to add this code for testing:
void onWebsocketMessage(uint8_t * payload) {
analogWrite(13,atoi((const char *)payload));
}
Where payload
is the data received.
Problems that could slow down/crash everything:
- My code. Does
atoi
take too much to execute? - My code. Is the
(const char *)
cast filling memory? - The lib itself?
I know that the CPU memory or whatever else is not the problem because of this video:
https://www.youtube.com/watch?v=8ISbmQTbjDI
He gets realtime stats from the controller at 200-600 Hz.
While it's supercool and I could just install that "custom firmware" I prefer to stay in the Arduino IDE for now.
How to fix websockets on the ESP8266 device using Arduino IDE?
Or maybe can I extract only the websocket part from that firmware (CNLohr's Video)?
Suggest another lib?
I posted here because I use the Arduino IDE. And the ESP8266 has also been part of the Arduino world for a while. And maybe some not so popular Arduino-based websockets work also on the ESP8266.
Wouldn't it be nice to control your ws2812b strip with a web interface showing the preview like this?
http://jsfiddle.net/dgws3usa/5/
EDIT
links2004 @ github
- The network should be fine. It's a relatively expensive Cisco/Linksys N router at 20cm/8inch away from the ESP8266 module.
- Luckily the module I'm using is one of the modules listed in the Arduino IDE, the MOD-WIFI-ESP8266-DEV, but I have another one with fewer GPIOs.
- I just noticed now that I programmed it at 80 Mhz instead of 160 Mhz.
- The program I uploaded consists only of the basic websockets server example with in addition just the code posted above.
- If
atoi
is the problem/is slow, what are other ways to convert the received array to a string? - I use both the latest versions of the Arduino ESP8266 port and the arduinoWebSockets. At least I guess so. I followed the install instructions one day before I asked this question.
- By crash I mean, while moving the range slider, if updating in realtime with
addEventListener('input',function,false)
at some point (after 1 sec/ 3-4 messages send/received) it stops sending or receiving data. By the way, the video you posted seems to work properly with a lot more code. Also that guy updates in realtime withoninput
vs 'onchange', which would only update when the user releases the slider. - I think for now I can't use
Serial.setDebugOutput(true);
as I didn't get the serial communication working. I'm using a cheap CH340G to program the chip.
Japanese post.
I'm doing exatly the same thing but in a much simpler way. No web server, no ping pongs, no serial stuff, I don't use complex functions to elaborate the web server's data. Altough his example works.
He is doing, code-wise, a lot more than I do.
for(i=0; i<4; i++) { mask[i] = client.read(); } byte m_data[data_len]; char data_c[data_len]; Serial.print("Receive Data = "); for(i = 0; i1-0x30); break; case 3: data_b = ((data_c[0]-0x30)*100) + ((data_c1-0x30)*10) + (data_c2-0x30); break; } LED_PWM(data_b);
My full "test" code:
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <Hash.h>
ESP8266WiFiMulti WiFiMulti;
WebSocketsServer webSocket=WebSocketsServer(81);
void webSocketEvent(uint8_t num,WStype_t type,uint8_t * payload,size_t lenght) {
switch(type) {
case WStype_DISCONNECTED:
break;
case WStype_CONNECTED:
{
IPAddress ip=webSocket.remoteIP(num);
}
break;
case WStype_TEXT:
analogWrite(13,atoi((const char *)payload)); // MY CODE
webSocket.broadcastTXT(payload,lenght);
break;
case WStype_BIN:
hexdump(payload,lenght);
webSocket.sendBIN(num,payload,lenght);
break;
}
}
void setup() {
pinMode(13,OUTPUT); // MY CODE
for(uint8_t t=4;t>0;t--) {
delay(1000);
}
WiFiMulti.addAP("ssid","pass");
while(WiFiMulti.run()!=WL_CONNECTED) {
delay(100);
}
webSocket.begin();
webSocket.onEvent(webSocketEvent);
}
void loop() {
webSocket.loop();
}
I normally write Javascript code. Converting a string to a number or vice-versa is much simpler.
num=1; str=1+''; num=str*1;
So all this binary array is relatively new for me.Note that while I convert the binary array to an int now. In the future I need to convert that to a string which then will be parsed. Something like JSON. And so update more channels per message.
On the client side, like I said, I'm sending the data really fast. So if there is no buffer on the server side that could be a problem. Solving that is simple:
requestanimationframe
. Continuously check if the input changed. That allows you to send the data every 16-17ms. So 60 Hz. Not slower, Not faster. But again that should be the maximum pause between messages.
I said that I will reprogram it at 160 Mhz now and hope there are other ways to convert the received data faster and hope for updates relative to my code.
EDIT2
Right. The serial works. Reprogrammed the ESP8266 At 160 Mhz.
The error I get when when I set Serial.setDebugOutput(true);
is:
LmacRxBlk:1
If you need some other information just ask.
EDIT3
Sorry for the late response.
webSocket.broadcastTXT(payload,lenght);
Broadcasting seems to be the problem. I just have a few minutes so for now I can't do the describe debug stuff... But I will do as soon as I have a little more time.
EDIT4 for Aditya Tannu
Added
#include <NeoPixelBus.h>
#define pixelCount 16
NeoPixelBus strip = NeoPixelBus(pixelCount,13);
Inside the webSocketEvent function
case WStype_TEXT:
for(uint8_t i=0;i<pixelCount;i++){
strip.SetPixelColor(
i,
RgbColor(i==(atoi((const char *)payload)%pixelCount)?255:0,0,0)
// i need to put the above outside of the loop.
// it does not work if i do so
);
}
strip.Show();
break;
HTML JS
var ws,form;
function msg(a){
console.log(a);
}
window.onload=function() {
form=document.getElementById('form');// change
ws=new WebSocket('ws://IPNUMBER:PORT');// change
ws.onopen=function() {
ws.send('0');
};
ws.onmessage=msg;
form.addEventListener('input',function() {
ws.send(this.firstChild.value) // firstchild is the range
}, false);
}
vid, I use a logic level converter from 3.3v to 5v: pca9306.
EDIT 5 for Links2004
I think I should rework the examples. It looks like most users don't understand it well.
Nono. At some point you need to broadcast back the actual position anyway.
Sorry. I forgot to test the debug stuff again. But we know it's the broadcast. We just need to send back data only when there is not too much traffic.