Skip to content

11. Communication

Summary

Honestly I feel like half of the time I am reading guides and other documentation.
Other half waiting for the compiler.
And third half debugging the code.

Math is hard.

Work Process

Calendar

Date To be done What was done
Thursday - 10h local meeting
Friday - FabLab normal work
- PCB fabrication so I can test stuff on the weekend
- PCB fabrication
Saturday - brake
Sunday - wifi test & debugging
Monday - ESP-NOW test
- figuring out BLE
Tuesday - FabLab normal work - Figured out BT Mesh
Wednesday - 12h Local
- 13h Regional
- 15h Global
- documenting

Introduction

Henk made an introduction based on Erwin 's slides.

Connection Types

  • Star Topology
    • everybody connects to only 1 center/main uC.
  • Ring topology
    • Connection in series
  • Bus Topology
    • 1 big data line that connect everyone

Protocols:

  • UART
    • Asynchronous (no clock)
    • TX = Transmit
    • RX = Receive
    • fixed speed
    • twisted wires for lower EMC
  • SPI
    • =Serial Peripheral Interface
    • MISO-MOSI communication (Main-Secondary)
    • synchronous (clock)
    • High data rate
  • I2C

    • Inter IC Communication
    • mostly fixed addresses
    • lots of (pre)communication to create connection between two devices
    • fixe bus levels with pull-up/down
  • TCP/IP

    • Transmission Control Protocol / Internet Protocol
    • OSI layers
      • 7 different layers
    • local / non-local addresses
    • Gateways
    • Different protocols can be used with it

WireShark: * Network Protocol Analyzer

Eye pattern Differential signalling

Group Part

Intro 1

Intro 2

My work

Reading Time !

Searching for the b2b connector (I would like to use an extension cable)

Schematics:

PCB

So I first created a PCB with two SW2812 LEDS and two buttons.

I run into an clearance issue.

Mill error

I manage to find a 0,5mm mill head so I could mill my board without modifying it.

So I made two at two different times. For the second one I made a mistake were I took it out before checking if the traces were ok or not. Fortunately I only lost 1 led position.

PCB

Wio-SX1262

LORA - Wireless

ESP NOW - Wireless

Following this tutorial I tried to do a connection between my two ESP32.

It should work as follow. When I click on the button, the other ESP RGB LED should light up with a random color.

ESP-NOW Communication
ESP-NOW Communication
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp-now-two-way-communication-esp32/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
//ESP-Now
#include <esp_now.h>
#include <WiFi.h>

//I2C
#include <Wire.h>

//RGB LED
#include <FastLED.h>

//LED SETUP
#define LED_PIN     D0 //or D9
#define NUM_LEDS    1
#define BRIGHTNESS  32
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100


CRGBPalette16 currentPalette;
TBlendType    currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

int R;
int G;
int B;

//Button
#define Button_PIN1 D6 //or D8
//#define Button_PIN2 D6 //or D8

//Screen
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 32  // OLED display height, in pixels
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);


// REPLACE WITH THE MAC Address of your receiver 
//uint8_t broadcastAddress[] = {0xE8, 0x06, 0x90, 0xA0, 0xFA, 0x88};
uint8_t broadcastAddress[] = {0xE8, 0x06, 0x90, 0xA1, 0x08, 0x80};
//uint8_t broadcastAddress[] = {0xE8, 0x06, 0x90, 0x9E, 0x87, 0xA8};

// Define variables to store readings to be sent
int OM_01; //Out Message 01

// Define variables to store incoming readings
int IM_01; //In Message 01

// Variable to store if sending data was successful
String success;

//Structure example to send data
//Must match the receiver structure
typedef struct struct_message {
    int M_01;
} struct_message;

// Create a struct_message called OUT_message to hold sensor readings
struct_message OUT_message;

// Create a struct_message to hold incoming sensor readings
struct_message IN_message;

//variable to store information about the peer
esp_now_peer_info_t peerInfo;

// Callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
if (status ==0){
    success = "Delivery Success";
}
else{
    success = "Delivery Fail";
}
}

// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&IN_message, incomingData, sizeof(IN_message));
Serial.print("Bytes received: ");
Serial.println(len);
IM_01 = IN_message.M_01;
}

void setup() {

pinMode(Button_PIN1, INPUT);

// Init Serial Monitor
Serial.begin(115200);

// Init OLED display
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
}

// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);

delay(100);

// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
}

// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Transmitted packet
esp_now_register_send_cb(OnDataSent);

// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;  
peerInfo.encrypt = false;

// Add peer        
if (esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
}
// Register for a callback function that will be called when data is received
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));

delay( 300 ); // power-up safety delay
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness(  BRIGHTNESS );

currentPalette = RainbowColors_p;
currentBlending = LINEARBLEND;
}

void loop() {

//Button Read
if (digitalRead(Button_PIN1) == HIGH){
    OM_01 = 2;
}
else{
    OM_01=0;
}

// Set values to send
OUT_message.M_01 = OM_01;


// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &OUT_message, sizeof(OUT_message));

if (result == ESP_OK) {
    Serial.println("Sent with success");
}
else {
    Serial.println("Error sending the data");
}
updateDisplay();
delay(1000);


//LED light up
if(IM_01 >= 1){

    R = random(0,255);
    G = random(0,255);
    B = random(0,255);

    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}
else{
    R = 0;
    G = 0;
    B = 0;
    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}
}


void updateDisplay(){
// Display Readings on OLED Display
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);

display.setCursor(0, 0);
display.println("INCOMING READINGS");
display.setCursor(0, 15);
display.display();

// Display Readings in Serial Monitor
Serial.println("INCOMING READINGS");
Serial.print("Temperature: ");

}

I think this code could be further optimized.

I2C - Wired

BlueTooth - Wireless

There is two major version of bluetooth: BlueTooth and BlueTooth Low Energy (BLE) BLE’s primary application is short distance transmission of small amounts of data. Xiao's Documentation. Unlike Bluetooth that is always on, BLE remains in sleep mode constantly except for when a connection is initiated.

Example Scanner from Arduino IDE:

BlueTooth Scan

I have no clue what I am looking at...
Name: No name (I guess)
Address: connection address
manufacturer data: same as ID ?
RSSI: how strong the signal is

Just read the doc and so this is the list: name, MAC address, manufacturer data and signal of the scanned Bluetooth device.

Point-to-Point

In P2P communication we have a server that gives data and a client that reads it. It is unidirectional.

I first tried to understand it and use it from Xiao's doc, but I had a hard time with it. Than it redirected me to another guide: ESP32 BLE Server and Client.

Bluetooth Server

With the two guides I started to understand things. And also that P2P is not good for my project.

Another guide

Mesh

Lets see if this guide will be good for me.

Library needed PainlessMesh and its dependencies.

So the guide says no use of delay().
What about fastled.delay() ?
Hope nothing will brake...

I also needed to readd this library

For now I am struggling to put my own data from loop() inside the data that needs to be sent over.

Seems like nobody tried to do BlueTooth Mesh in previous years.

Here is a guide that uses a mobile up to setup the MESH. I am trying to do it inside the code...
I do not want to use a phone to setup my MESH network.

Wait
WHAT ?!
Here it says the MESH is supported natively by ESP32-S3 ?!

Lets read new doc ...

Ah.
It is the same one as with the mobil phone setup.

Well.
For now I managed to get the message through (Serial.print). But not yet light up my LED.

I DID IT !!!

BlueTooth MESH - Broadcast
BlueTooth MESH - Broadcast
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp-mesh-esp32-esp8266-painlessmesh/

This is a simple example that uses the painlessMesh library: https://github.com/gmag11/painlessMesh/blob/master/examples/basic/basic.ino
*/

//BlueTooth MESH
#include "painlessMesh.h"

//JSON file creation & Reading
#include <Arduino_JSON.h>

//RGB LED
#include <FastLED.h>

//LED SETUP
#define LED_PIN     D0 //or D9
#define NUM_LEDS    1
#define BRIGHTNESS  32
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100


CRGBPalette16 currentPalette;
TBlendType    currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

int R;
int G;
int B;

//Button
#define Button_PIN1 D6 //or D8
#define Button_PIN2 D8
//#define Button_PIN2 D6 //or D8


//the name of the MESH network
#define   MESH_PREFIX     "whateverYouLike"

//password of the MESH network
#define   MESH_PASSWORD   "somethingSneaky"

// This refers to the the TCP port that you want the mesh server to run on. The default is 5555
#define   MESH_PORT       5555

//Number for this node
int nodeNumber = 1;

//String to send to other nodes with sensor readings
String final_message;

//It is recommended to avoid using delay() in the mesh network code. 
//To maintain the mesh, some tasks need to be performed in the background. 
//Using delay() will stop these tasks from happening and can cause the mesh to lose stability/fall apart. 
//The following line creates a new Scheduler called userScheduler
Scheduler userScheduler; // to control your personal task

//Create a painlessMesh object called mesh to handle the mesh network
painlessMesh  mesh;

// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain

String Message(); // Prototype for sending message

//Create a task called taskSendMessage responsible for calling the sendMessage() function every X (the number) second as long as the program is running.
Task taskSendMessage( TASK_SECOND * 5 , TASK_FOREVER, &sendMessage );

int M1;

String Message() {
JSONVar jsonReadings;
jsonReadings["node"] = nodeNumber;
jsonReadings["M1"] = M1;
//Message() variable is then converted into a JSON string using the stringify() method and saved on the Message variable
final_message = JSON.stringify(jsonReadings);
return final_message;
}

//The sendMessage() function sends a message to all nodes in the message network (broadcast).
void sendMessage() {

String msg = Message();

//board chip ID
//msg += mesh.getNodeId();
//Replaced by nodeNumber

//To broadcast a message, simply use the sendBroadcast() method on the mesh object and pass as argument the message (msg) you want to send.
mesh.sendBroadcast(msg);

//Every time a new message is sent, the code changes the interval between messages (one to five seconds).
taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}


int M1_I;

//several callback functions are created that will be called when specific events happen on the mesh.
//The receivedCallback() function prints the message sender (from) and the content of the message (msg.c_str()).
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("Received from %u msg=%s\n", from, msg.c_str());
//The message comes in JSON format, so, we can access the variables as follows:
JSONVar myObject = JSON.parse(msg.c_str());
int node = myObject["node"];
M1_I = myObject["M1"];
Serial.print(M1_I);
}

//The newConnectionCallback() function runs whenever a new node joins the network. 
//This function simply prints the chip ID of the new node. 
//You can modify the function to do any other task.
void newConnectionCallback(uint32_t nodeId) {
    Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId);
}

//The changedConnectionCallback() function runs whenever a connection changes on the network (when a node joins or leaves the network).
void changedConnectionCallback() {
Serial.printf("Changed connections\n");
}

//The nodeTimeAdjustedCallback() function runs when the network adjusts the time, so that all nodes are synchronized. 
//It prints the offset.
void nodeTimeAdjustedCallback(int32_t offset) {
    Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset);
}



void setup() {

pinMode(Button_PIN1, INPUT);
pinMode(Button_PIN2, INPUT);

Serial.begin(115200);

FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness(  BRIGHTNESS );

currentPalette = RainbowColors_p;
currentBlending = LINEARBLEND;

//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
mesh.setDebugMsgTypes( ERROR | STARTUP );  // set before init() so that you can see startup messages

//Initialize the mesh with the details defined earlier.
mesh.init( MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT );
//Assign all the callback functions to their corresponding events.
mesh.onReceive(&receivedCallback);
mesh.onNewConnection(&newConnectionCallback);
mesh.onChangedConnections(&changedConnectionCallback);
mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);

//Finally, add the taskSendMessage function to the userScheduler. 
//The scheduler is responsible for handling and running the tasks at the right time.
userScheduler.addTask( taskSendMessage );

//Finally, enable the taskSendMessage, so that the program starts sending the messages to the mesh.
taskSendMessage.enable();
}

void loop() {

//Button Read
if (digitalRead(Button_PIN1) == HIGH){
    M1 = 2;
}
else{
    M1 = 0;
}

//Button Read + LED
if (digitalRead(Button_PIN2) == HIGH){
    R = random(0,255);
    G = random(0,255);
    B = random(0,255);

    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}
else{
    R = 0;
    G = 0;
    B = 0;
    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}

sendMessage();

//LED light up
if(M1_I >= 1){

    R = random(0,255);
    G = random(0,255);
    B = random(0,255);

    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}
else{
    R = 0;
    G = 0;
    B = 0;
    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}

//To keep the mesh running, add mesh.update() to the loop().
// it will run the user scheduler as well
mesh.update();
}

While reading the wiki I saw that you can specify the receiver (instead of just broadcasting). I should look into it later on.

Ok. So from what I see I only need to change mesh.sendBroadcast( String &msg, bool includeSelf = false ) to mesh.sendSingle(uint32_t dest, String &msg)
Compiler did not give an error so it should work.

BlueTooth MESH - Single Send
BlueTooth MESH - Single Send
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp-mesh-esp32-esp8266-painlessmesh/

This is a simple example that uses the painlessMesh library: https://github.com/gmag11/painlessMesh/blob/master/examples/basic/basic.ino
*/

//BlueTooth MESH
#include "painlessMesh.h"

//JSON file creation & Reading
#include <Arduino_JSON.h>

//RGB LED
#include <FastLED.h>

//LED SETUP
#define LED_PIN     D0 //or D9
#define NUM_LEDS    1
#define BRIGHTNESS  32
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100


CRGBPalette16 currentPalette;
TBlendType    currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

int R;
int G;
int B;

//Button
#define Button_PIN1 D6 //or D8
#define Button_PIN2 D8
//#define Button_PIN2 D6 //or D8


//the name of the MESH network
#define   MESH_PREFIX     "whateverYouLike"

//password of the MESH network
#define   MESH_PASSWORD   "somethingSneaky"

// This refers to the the TCP port that you want the mesh server to run on. The default is 5555
#define   MESH_PORT       5555

//Number for this node
int nodeNumber = 1;

//Node ID to send a specific message 
int Node_ID = 1; 

//String to send to other nodes with sensor readings
String final_message;

//It is recommended to avoid using delay() in the mesh network code. 
//To maintain the mesh, some tasks need to be performed in the background. 
//Using delay() will stop these tasks from happening and can cause the mesh to lose stability/fall apart. 
//The following line creates a new Scheduler called userScheduler
Scheduler userScheduler; // to control your personal task

//Create a painlessMesh object called mesh to handle the mesh network
painlessMesh  mesh;

// User stub
void sendMessage() ; // Prototype so PlatformIO doesn't complain

String Message(); // Prototype for sending message

//Create a task called taskSendMessage responsible for calling the sendMessage() function every X (the number) second as long as the program is running.
Task taskSendMessage( TASK_SECOND * 5 , TASK_FOREVER, &sendMessage );

int M1;

String Message() {
JSONVar jsonReadings;
jsonReadings["node"] = nodeNumber;
jsonReadings["M1"] = M1;
//Message() variable is then converted into a JSON string using the stringify() method and saved on the Message variable
final_message = JSON.stringify(jsonReadings);
return final_message;
}

//The sendMessage() function sends a message to all nodes in the message network (broadcast).
void sendMessage() {

String msg = Message();

//board chip ID
//msg += mesh.getNodeId();
//Replaced by nodeNumber

//To broadcast a message, simply use the sendBroadcast() method on the mesh object and pass as argument the message (msg) you want to send.
//mesh.sendBroadcast(msg);


//Send to specific Node
mesh.sendSingle(Node_ID, msg);


//Every time a new message is sent, the code changes the interval between messages (one to five seconds).
taskSendMessage.setInterval( random( TASK_SECOND * 1, TASK_SECOND * 5 ));
}


int M1_I;

//several callback functions are created that will be called when specific events happen on the mesh.
//The receivedCallback() function prints the message sender (from) and the content of the message (msg.c_str()).
void receivedCallback( uint32_t from, String &msg ) {
Serial.printf("Received from %u msg=%s\n", from, msg.c_str());
//The message comes in JSON format, so, we can access the variables as follows:
JSONVar myObject = JSON.parse(msg.c_str());
int node = myObject["node"];
M1_I = myObject["M1"];
Serial.print(M1_I);
}

//The newConnectionCallback() function runs whenever a new node joins the network. 
//This function simply prints the chip ID of the new node. 
//You can modify the function to do any other task.
void newConnectionCallback(uint32_t nodeId) {
    Serial.printf("--> startHere: New Connection, nodeId = %u\n", nodeId);
}

//The changedConnectionCallback() function runs whenever a connection changes on the network (when a node joins or leaves the network).
void changedConnectionCallback() {
Serial.printf("Changed connections\n");
}

//The nodeTimeAdjustedCallback() function runs when the network adjusts the time, so that all nodes are synchronized. 
//It prints the offset.
void nodeTimeAdjustedCallback(int32_t offset) {
    Serial.printf("Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset);
}



void setup() {

pinMode(Button_PIN1, INPUT);
pinMode(Button_PIN2, INPUT);

Serial.begin(115200);

FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness(  BRIGHTNESS );

currentPalette = RainbowColors_p;
currentBlending = LINEARBLEND;

//mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on
mesh.setDebugMsgTypes( ERROR | STARTUP );  // set before init() so that you can see startup messages

//Initialize the mesh with the details defined earlier.
mesh.init( MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT );
//Assign all the callback functions to their corresponding events.
mesh.onReceive(&receivedCallback);
mesh.onNewConnection(&newConnectionCallback);
mesh.onChangedConnections(&changedConnectionCallback);
mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);

//Finally, add the taskSendMessage function to the userScheduler. 
//The scheduler is responsible for handling and running the tasks at the right time.
userScheduler.addTask( taskSendMessage );

//Finally, enable the taskSendMessage, so that the program starts sending the messages to the mesh.
taskSendMessage.enable();
}

void loop() {

//Button Read
if (digitalRead(Button_PIN1) == HIGH){
    M1 = 2;
}
else{
    M1 = 0;
}

//Button Read + LED
if (digitalRead(Button_PIN2) == HIGH){
    R = random(0,255);
    G = random(0,255);
    B = random(0,255);

    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}
else{
    R = 0;
    G = 0;
    B = 0;
    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}

sendMessage();

//LED light up
if(M1_I >= 1){

    R = random(0,255);
    G = random(0,255);
    B = random(0,255);

    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}
else{
    R = 0;
    G = 0;
    B = 0;
    for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    } 

    FastLED.show();
    FastLED.delay(1000 / UPDATES_PER_SECOND);
}

//To keep the mesh running, add mesh.update() to the loop().
// it will run the user scheduler as well
mesh.update();
}

Backdoor story:

SPI - Wired

WiFi

So I tried out the example code given in the arduino IDE.

WifiScan

As you can see it detects ALL the wifi spots from the building. Not just the WiFi but all emitters. There is less WiFi visible in no scan mode as they are in a mesh mode. So you connect once and you will (re)connect the nearest WiFi spot, when you move around.

Other stuff

Signal Intensity Module

WiFi

Than I started putting together a code.

I first tested if the RGBs work as intended with this guide.

Than as I already tested the WiFi scan code example, I just needed to create a conversion table of RSSI values to LED values. But what is the max value of an RSSI ?
It depends on the manufacturer. It is a relative index.

Lets go read the doc

  • RSSI stands for Received Signal Strength Indicator
  • rssi: The rssi parameter is a reference to an int32_t variable where the function stores the received signal strength indication (RSSI) of the network.

Found what I was looking for in 2nd doc

  • rssi -- threshold value in dbm between -100 to 10 Note that in some rare cases where signal strength is very strong, rssi values can be slightly positive.

For memo: lower the RSSI value the worst the connection is.

WiFi intensity drops with the following equation:

\[ \frac{1}{d^2} \]

I will also need the map function.

So I struggled a lot to get my first code version to work. I had issues with defining empty string values. I also had issue with my if function where it wasn't happy comparing char to string. And a lot more of red errors.

To convert char to string I have found the following function: toCharArray()

After doing several hours of trouble shooting the code finally work.
Kinda...

I thought that it worked as follow
Scan > found wifi > print wifi > continue scan
but in really
Scan All > magic print

So my idea of getting the RSSI out from it, while it is scanning, does not work...

F*xx...
I should have just read the doc which says that you can put the SSID into the wifi.scanNetworks()

Why can I connect to it but not just scan the RSSI ?!?!?!

RSSI Intensity to RGB - WiFi
RSSI Intensity to RGB
//Source:   https://randomnerdtutorials.com/guide-for-ws2812b-addressable-rgb-led-strip-with-arduino/
//          https://github.com/FastLED/FastLED/wiki/Pixel-reference
//          https://wiki.seeedstudio.com/xiao_esp32s3_wifi_usage/





// BlueTooth
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

//BlueTooth Setup
int scanTime = 5;  //In seconds
BLEScan *pBLEScan;

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
    Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
}
};


//LED
#include <FastLED.h>

//LED SETUP
#define LED_PIN     D9
#define NUM_LEDS    1
#define BRIGHTNESS  32
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100


CRGBPalette16 currentPalette;
TBlendType    currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

//Mapping
int R;
int G;
int B;

//WiFi
#include "WiFi.h"
//WIFI SETUP 
const char* ssid = "Orange-DQmcb"; //WiFi name
const char* password = "REPLACE_WITH_YOUR_PASSWORD"; //WiFi password
float RSSI;
int n;




//Global Setup
void setup() {
Serial.begin(115200);

//WiFi Setup
if(false){
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);
}


//BlueTooth Setup
if(false){
    BLEDevice::init("");
    pBLEScan = BLEDevice::getScan();  //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true);  //active scan uses more power, but get results faster
    pBLEScan->setInterval(100);
    pBLEScan->setWindow(99);  // less or equal setInterval value
}


Serial.println("Setup done");


//LEDS
delay( 300 ); // power-up safety delay
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness(  BRIGHTNESS );

currentPalette = RainbowColors_p;
currentBlending = LINEARBLEND;
}


void loop(){
Serial.println(" ");
Serial.println(" ");
Serial.println("--- Start ---");

if (false){
n = WiFi.scanNetworks();
Serial.print(n);
Serial.println(" networks found");
}

if (false){
    Serial.println("Nr | SSID                             | RSSI | CH | Encryption");
    for (int i = 0; i < n; ++i) {
    // Print SSID and RSSI for each network found
    Serial.printf("%2d", i + 1);
    Serial.print(" | ");
    Serial.printf("%-32.32s", WiFi.SSID(i).c_str());
    Serial.print(" | ");
    Serial.printf("%4ld", WiFi.RSSI(i));
    Serial.print(" | ");
    Serial.printf("%2ld", WiFi.channel(i));
    Serial.print(" | ");
    switch (WiFi.encryptionType(i)) {
        case WIFI_AUTH_OPEN:            Serial.print("open"); break;
        case WIFI_AUTH_WEP:             Serial.print("WEP"); break;
        case WIFI_AUTH_WPA_PSK:         Serial.print("WPA"); break;
        case WIFI_AUTH_WPA2_PSK:        Serial.print("WPA2"); break;
        case WIFI_AUTH_WPA_WPA2_PSK:    Serial.print("WPA+WPA2"); break;
        case WIFI_AUTH_WPA2_ENTERPRISE: Serial.print("WPA2-EAP"); break;
        case WIFI_AUTH_WPA3_PSK:        Serial.print("WPA3"); break;
        case WIFI_AUTH_WPA2_WPA3_PSK:   Serial.print("WPA2+WPA3"); break;
        case WIFI_AUTH_WAPI_PSK:        Serial.print("WAPI"); break;
        default:                        Serial.print("unknown");
    }
    Serial.println();
    delay(10);
}}


delay(1000);

/**/
//WiFi.scanNetworks(false,false,false,2000,0,"Orange-DQmcb");
RSSI = WiFi.RSSI();
Serial.print("RSSI: ");
Serial.println(RSSI);


delay(1000);

R = map(RSSI, -100, 10, 0, 255); //Remaps the RSSI value to RGB value
G = map(RSSI, -100, 10, 255, 0); //Remaps the RSSI value to RGB value
B = 0;

Serial.println(" ");
Serial.print("R:");
Serial.println(R);
Serial.print("G:");
Serial.println(G);

for(int i = 0; i < NUM_LEDS; i++ ){
    leds[i].setRGB(R,G,B);  // Set Color HERE!!!
    }

FastLED.show();
FastLED.delay(1000 / UPDATES_PER_SECOND);

delay(1000);
}

Other Sources :
(generally distance measurement, almost the same as intensity)

BlueTooth

ESP-Now


Comparison Table

You can see it here.
You can contribute to it too. Any help is greatly accepted.


Learning Outcome

Creating a more complex PCB take too much time.
Compiling take a lot of time. Sometimes I wonder if me waiting to compile is more time than me working...
Communication is sometimes easy. But sometimes it can be really complicated... (Lost a whole day to debug an issue)

Peer-to-Peer Communication (ESP-NOW) is easier than Bluetooth and Point-to-Point (Server-Client).

But to be honest I have no clue what I learned.
I have discovered lots of things, but did I learn anything ?
No clue.

I just persevered.



Assignment Check

  • individual assignment:
    • design, build, and connect wired or wireless node(s) with network or bus addresses and local input &/or output device(s)
      • done
  • group assignment:
    • send a message between two projects