Two ESP8266 on one Fastled webserver

Hello,

First of all, I'm not an expert. Sorry in advance if my questions are stupid or incomplete. Please be patient with me and tell me if I'm missing information (Had some bad experiences in the past).

I have set up two ESP8266 with a Fastled webserver by Evil Genius Labs. They work perfectly. The problem is that I want them to show the same colour modus. So right now I have to change them both independently. Is there a way I could make one of the two connect to the others webserver and get its information from that location. As far as I know, I could only make one ESP create its own WIFI network and let the second one connect to that as a client and make them communicate. But by doing so I would lose my access to the webserver.

Is there anyone that can point me in the right direction? Or tell me if this is possible at all.

Just open a second port between the two

Yes, Opening a Second Port between the two as said can be helpful for you.

Oke so it took me some time to open a second port and figure that all out (turned out to be quite simple). I'm quite new with wifi and the ESP8266. I got that working now. Now i need to figure out how to send the data over, I think I will manage that. Bare with me XD. I will keep you posted

An easy method is to look at the "websockets" examples.

I used this and have never looked back.

Thank you hiddenvision for your reply!

Oke, so I have a couple of hiccups. I am afraid this project is a bit beyond my knowledge but I wanna learn this one way or another so it doesn't matter how long this is gonna take me, I will get there! Here is a little status update, and some more in-depth info on the problem. All the help is welcome guys!

What I have achieved during this process so far:

  • I manage to build two lamps programmed by an ESP8266 chip which is hooked up to and USB to serial of an arduiono uno with the atmega chip removed (For wireing diagram: Flashing the ESP8266 with an Arduino UNO)
  • I set up a webserver with the ESP8266 FastLED webserver by Jason Coon
  • I am able to create a second port to which one of the two ESP8266 can connect to
  • I am also able to connect the second ESP8266 directly to the webserver instead of the second port

What I am not able to achieve:

  • Either Send the FastLED data of the current light status to the second ESP8266. I have tried to figure out how the FastLED.show() functions is actually executed in the hope I could find a way to obtain the data for this function and send it over. But I think I found out that this is not a realistic way of doing things
  • Or let the second ESP8266 connect to the other ESP and get the current settings of the webserver and use these to control its own LEDs.

The first option doest seem possible since there isn't anything (as far as I know) that would kinda work like "client.println(FastLED.show());" or "client.println(FastLED.getLEDdata);" and just send over the bits of data.

The second options seems a bit like an undoable option since there is a whole HTML webpage behind this that keeps track of the webpage settings. So I don't see a way in how I could rewrite the Arduino program to ask for the settings of the webserver.

Is there any other way I could tackle this problem? Or am I doing something horribly wrong?

Just post up your current code so I have something to start from.
I am out right now but will look once I get back in.

@hiddenvision

So the code on the Main ESP8266 is from the fastLED webserver from Github like I mentioned before. What I had thus far for the second ESP8266 is:

#include <SPI.h>
#include <ESP8266WiFi.h>
#include <FastLED.h>

char ssid[] = "****"; //  your network SSID (name)
char pass[] = "*****";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;
IPAddress server(192,168,0,188);  // numeric IP for Google (no DNS)

WiFiClient client;

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  Serial.printf("Connecting to %s\n", ssid);
  if (String(WiFi.SSID()) != String(ssid)) {
    WiFi.begin(ssid, pass);
  }
  delay(1000);
}

void loop() {
  static bool hasConnected = false;
  EVERY_N_SECONDS(1) {
    if (WiFi.status() != WL_CONNECTED) {
      hasConnected = false;
    }
    else if (!hasConnected) {
      hasConnected = true;
      Serial.print("Connected to WLAN! IP:");
      Serial.print(WiFi.localIP());
    }
  }
  
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }
  
  if (!client.connected()) {
    client.connect(server, 80);
  }
   
  if (client.connected()) {
    Serial.println("Connected!");
    client.stop();
    delay(1000);
  }
}

I somehow need to add the part where it asks for the fastled status when it’s connected. Please don’t mind the 1000ms delay when it’s connected, that was for testing. I can also change port 80 to 81, but i then need to add a script to the main ESP8266 with the webserver, that when it detects a connection to port 81 it will send the FastLED data.

I had a quick look for the server stuff you mentioned.
If you have the link it would save some time.

What you have done is correct’ish, now you just need to send/print some data like client.println(“hello”).
The server will then see that data you send. If I remember right.

In reality you may way to construct a proper GET header to request a page like you would normally. You then just configure the server to listen for requests for that page and bingo, send the reply.

I would still consider using websockets.
They allow you to openly send and receive data to and from either device.
That way either unit can update the other if needed.

Anyway, drop that link or the code up here so I can see what the other esp unit is doing.
It would then not be too hard to add either the client or server section of the WS library as needed.

I do not have an ESP connected right now but this may do something.
SEE LATER POST FOR UPDATED CODE

#include <SPI.h>
#include <ESP8266WiFi.h>
//#include <FastLED.h>

char ssid[] = "****"; //  your network SSID (name)
char pass[] = "*****";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)

unsigned long lastlook = 0;
int status = WL_IDLE_STATUS;
IPAddress server(192,168,0,188);  // numeric IP for Google (no DNS)

//WiFiClient client; // no need for it to be global

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  Serial.printf("Connecting to %s\n", ssid);
  if (String(WiFi.SSID()) != String(ssid)) {
    WiFi.begin(ssid, pass);
  }
  delay(1000);
}

void loop() {
  static bool hasConnected = false;
  if ((lastlook + 1000) < millis()){return;}

  lastlook = millis();
  if (WiFi.status() != WL_CONNECTED) {hasConnected = false;}
  else {
    if (!hasConnected) {
      hasConnected = true;
      Serial.print("Connected to WLAN! IP:");
      Serial.print(WiFi.localIP());
    }
  }

  if (hasConnected) {
    WiFiClient client;
    client.setTimeout(1500);  
    if(client.connect(server, 80)) {
      Serial.println("Connected!");
      client.print("Hello...........\r\n");
      client.flush();
      while(client.connected()) {
        while (client.available()) {
          char c = client.read();
          Serial.write(c);
        }
      }
      Serial.println("\r\nDisconnected!");
    }
    client.flush(); client.stop();
  }
}

Well I had a play.
More just shuffling examples of stuff to look like something real.!
But still do not have an ESP connected so no realworld testing has been done.
It compiles, that's always a winner.

Actually I just connected one and it programs and runs in both modes.
See the #define ASCLIENT near the top

As a server you can browse to the IP.
As a client it will connect to a server (NOT ACTUALLY TESTED THAT BIT).

There is some extra libraries needed but nothing you cannot find I'm sure.
Shout if I am making it worse.!

SEE LATER POST FOR CODE

Golly, it must be a few months since I had to think ESP.
It has a bug or two but I just programmed up a second unit and it works.
The Code above was edited if you downloaded before this message.

Not sure if mDNS stuff will help find the server by name as I had to drop an entry on my router.
There will be other methods if not.
Ahh I read my stuff again and find a MDNS query function to search for mDNS enabled devices.
Not implemented it in this example but I am sure someone will if needed.

Still the Connection worked, that has to be a good sign.

Obviously there is no reconnection strategy or other such tweaks in play.
I would have to have a look at the library to refresh what was available and what needs to be written.

This is easier.

You can put your ssid and pass in a separate file called private.h (see example)

That way we can pass on the INO without needing to edit out sensitive data.

1: comment out the //#define ASCLIENT line
Program up a server device and browse to it (3 sliders)
http://espserver
or
http://192.168.0.188

If the ESP client connects then changing the SERVER sliders will PUSH the data to the CLIENT
You can view debug things in serial monitor

2: uncomment the #define ASCLIENT line
Edit the server_ip as required
Program up a client device and view in serial monitor.
you will see the 1 second requests
and should also see the pushed data when you adjust the sliders on the server web page.

This is in no way a solid solution, there is little error or connectivity checking,
but it should give you an idea on what is possible.

IF THE CLIENT DOES NOT CONNECT THEN CHANGE the C_websocket.begin to use the IP not the NAME
Sorry that is just how I left it, but a good test anyway to see if it can resolve the name.
It works in my environment so it may work in yours.!!

void setup_client() {
  C_webSocket.begin(WS_server_IP, WS_Port);
  //C_webSocket.begin(WS_server_NAME, WS_Port);

I have changed it now due to some other updates.

SEE LATER POST FOR UPDATES, but remember this one for how to use.

@Hiddenvision SHOUTOUT to you! You have been an amazing help so far. Thanks for your time. I didnt have been able to play around/ research the past days, but I will continue with the project today. I will send my code and use your feedback.

Again thanks a lot, I will get back to this today!

No Worries,
As long as it is helping you LEARN rather than just complete the project.

If you are going to develop much with the WiFi stuff then look into the http.update stuff.
It will save a load of moving things about and connecting wires and give you the ability to update the device remotely.

Also the onboard filesystem is handy for saving data like webpages or settings.
SPIFFS library.

But one step at a time, those are all can do's NOT must do's.

The two units are still ticking away here, bouncing data around.
I presume you saw the attachments.

This was todays version.
SEE PREVIOUS POSTS FOR FIRST USE INFO

Nothing much is changing just little tweaks and formatting.

For reference the round trip time for the returned packet was approx. 4 or 5 millis.
That was time taken in total to

C_send - S_receive - S_serial.print - S_send_reply - C_receive_reply.

private.h (288 Bytes)

FORUM_ESP_FastLed.ino (9.68 KB)

So I used your code and they communicate perfectly. I saw some things I haven’t used before like #ifndef but these things were pretty self-explanatory. So to make it more understandable what’s going on I split the code into two parts, the server and client. This made it better to follow.

As I understand, you programmed a part into the HTML script that sends the data, I am not an expert on HTML, but your script was pretty short. However, the webpage I’m using is quite a bit longer. I haven’t figured out how it functions yet.

Anyway, I think I understand what you are doing and I should be able to implement this into the code I’m using. At least for the server-side that is. I’m not so sure how I would edit the code for the client that is doest use its own websurfer anymore but instead uses the information of the server ESP.

I will just dump everything I am using right now in the attechment, except for the secrets.h file.

Anyway, I think I should be able to figure out how to make it all works now. If not, I will let you know. Thanks a lot

ESP webserver FORUM.zip (305 KB)

No worries on how you prefer the code.
I just did it like that as an easy way to keep it all in the one file.
Easier to edit common functions for me that way.
Also it was just yet another example of how to do something.

I took a look at the sketch you supplied.
I notice that the code already contains some stuff for websockets_server.

So you are actually 98% there.

Get your code using the websocket bits that exist and then just bolt in the websocket_clients stuff on top.
That way you can broardcast to any devices that are connected with setting updates or whatever.
You could use the MDNS stuff to find all devices if needed.

Just make sure you don't trigger a chain reaction where every device wants to constantly update the others!

The example I gave should have enough info for implementing something,
I will continue to play with it but I think the motor is almost started.

Also have a look at the McLighting code.

It fully uses Websockets_server already.

Although this link is not Arduino

I have seen somewhere mention that someone has Arduino has a version.
Ahh Arduino/libraries/ESP8266WiFiMesh at master · esp8266/Arduino · GitHub

Just another way to do the same sort of thing.

Re the example.
The HTML part is just the little page for the browser to work.
Simple 3 sliders, txt box and enough javascript to get the websocket connection going.

The fastled example uses a page(s) from SPIFFS, you will find in the data folder.
Focus on the .js files as they are the bulk of local code.
But don't bother with reading the bootstrap and jquery _min.js files.!!
I see that some are one liners,(no linefeeds)
you want to spend some time formatting those so they are easy to read and or edit.

Also the edit page is all squished(hard to edit), I have an unsquished version if needed.

There is no reason why all the devices cannot contain mostly the same code.
They can all have webserver and both websocket Servers and Clients for the background traffic.
When you browse to any device it could present a list of reachable units so you can select some or all to apply the settings you are changing. Then the unit that you are connected to can distribute the settings to the other devices as per the list.

Tried to compile your example, failed for some reason.
So I did download the original source but for some reason it fails to compile also.
Not looked too deep but it did not look like an easy to edit example.
I found the McLighting example far easier to dive in and adapt.

Anyway, just to further comment,
you do not need to use the websockets stuff for the web pages.
You can leave them as they are for now.

You just need to patch in the example I gave to your fastled code if you only have two modules.
Just get rid of all the webserver related stuff and it should not conflict with the current fastled code.
If I can get the FastLed example to compile then I will give it a go, just to know if I am talking rubbish or not.
HaHa.

Ok Well I manage to stop the error enough to compile.

So I looked closer at the code and had noticed that it has some bits for sending out the settings already.

void setup(){


  autoPlayTimeout = millis() + (autoplayDuration * 1000);  
  WS_setup();  
}

void sendInt(uint8_t value){ sendString(String(value));}
void sendString(String value){ webServer.send(200, "text/plain", value);}
void broadcastInt(String name, uint8_t value){
  String json = "{\"name\":\"" + name + "\",\"value\":" + String(value) + "}";
  //webSocketsServer.broadcastTXT(json);
  PassedData = json;
#ifdef ASCLIENT
#else
  if (WS_ClientNum != 99){
    if(PassedData == ""){PassedData = "NONE_#";}
    S_webSocket.sendTXT(WS_ClientNum, PassedData);      
  }      
#endif  
}

void broadcastString(String name, String value){
  String json = "{\"name\":\"" + name + "\",\"value\":\"" + String(value) + "\"}";
  PassedData = json;
  //webSocketsServer.broadcastTXT(json);
#ifdef ASCLIENT
#else
  if (WS_ClientNum != 99){
    if(PassedData == ""){PassedData = "NONE_#";}
    S_webSocket.sendTXT(WS_ClientNum, PassedData);      
  }      
#endif  

}

void loop() {
  // Add entropy to random number generator; we use a lot of it.
  random16_add_entropy(random(65535));

  //  dnsServer.processNextRequest();
  //  webSocketsServer.loop();
  WS_loop();
  webServer.handleClient();
  //  handleIrInput();

}

So I added in the passeddata= json; bit
Then I just edited the client/server example a little and included it to the fastled example.

Add the include line just above where your first function is or at least below any variable declarations it needs.

#include "FORUM_ESP_FastLed.h"

// scale the brightness of all pixels down
void dimAll(byte value){
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i].nscale8(value);
  }
}

Then add WS_setup(); as the last line of your current setup()
Then add WS_loop(); as the first line of your current loop()

At least that is a super fast way to try it out.

FORUM_ESP_FastLed.h (5.86 KB)