Skip to content

Networking and Communications

**Welcome to week 13 Assignment!

This week I learned about connecting and communication between two devices or PCBs.

There are 3 protocols for microcontrollers to communicate and connect with each other.

UART SPI IIC
Universal Asynchronous Receiver/Transmitter Serial Peripheral Interface Inter-Integrated Circuit
Reference Reference Reference
limited number of peripherals, devices must agree on speed of communication (baud rate) Cannot transmit into several peripherals at the same time 128 peripherals
Frame
Frame Frame
Start—Date—Parity—End SCK: Clock - MOSI: Primary-controller-out secondary-controller-in. - MISO: primary-controller-in secondary-controller- -out- SS:Detect Slave Address—Start Condition—Function (Read or write)—Stop condition

UART

TX and RX are abbreviations for Transmit and Receive, respectively

UART

Original image reference was taken from this site www.circuitbasics.com yet I recreated the image.

note: Parity bits are a simple form of error detecting code.

SPI

SCK: Clock
MOSI: primary-controller-out secondary-controller-in.
MISO: Primary-controller-in secondary-controller-out.
SS: Detect secondary controller

SPI

When connecting to several controllers (secondary, tertiary…), you need wiring with each one because you cannot send data at the same time.

SPI_multiple

image reference

IIC \ I2C

SCI: CLOCK
SDA: Data one line to all secondary-controllers
i2c2

i2c

Original image reference was taken from this site circuitbasics.com yet I recreated the image.

The other image was taken from wikipedia

Note: a pullup resistor must be used in this circuit.

Those three protocols connect through the following pinout on the Seeed XIAO Microcontrollers: pinout

My Circuit Design

In my assignment I will be using Seeed-Xiao-RP2040 using the I2C method.

circuit_sketch

circuit_design

In my Secondary controller I am using 2 led lights, one connector and 2 499 pull-up resistors.
In my Primary controller I am using a switch, one connector and 2 499 pull-up resistors.

secondary_master

After soldering all the parts and checking if the operation was successful I used a multimeter to check all pins and connections.

I wrote Secondary and Primary controllers code, compiled them in my microcontrollers and yet my network still wasn’t working, therefore I followed the following steps for Debugging

1- I checked again the connections with my multimeter and checked if I wrote my pinout correctly in the code.

2- I wrote a code for the Primary board individually to test it:

const int BUTTON_PIN = D6;
const int ledPin =  25;      // the number of the LED pin


void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  Serial.begin(9600);
}

void loop() {
  // Read button status
  int buttonStatus = digitalRead(BUTTON_PIN);
  Serial.println(buttonStatus);
  // }

  delay(50);
}

2- I wrote a code for the Secondary board individually to test it:

int ledPin = D9; // the pin that the LED is connected to

void setup() {
  pinMode(ledPin, OUTPUT); // initialize the LED pin as an output
}

void loop() {
  digitalWrite(ledPin, HIGH); // turn the LED on
  delay(1000); // wait for a second
  digitalWrite(ledPin, LOW); // turn the LED off
  delay(1000); // wait for a second
}

slave_test

Conclusion after Debugging

While using Xiao RP2040, always refer to your pinouts as D2,D3.. don’t use numbers only.

LED must be applied to the circuit with a specific direction that is shown on the led itself with an arrow (arrow point to GND), I applied my led the other direction.

I uploaded the following code in my Primary Board

// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

int sw_pin = 6;
int sw_value = 0;

#include <Wire.h>

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
  pinMode(sw_pin, INPUT_PULLUP);
  Serial.begin(115200);
}

void loop()
{

sw_value = digitalRead(sw_pin);
Serial.println(digitalRead(sw_pin));
delay(100);

if(sw_value == 0){

  Wire.beginTransmission(4); // transmit to device #4       // sends five bytes
  Wire.write(0);              // sends one byte  
  Wire.endTransmission();    // stop transmitting  

  delay(100);
}

}

I uploaded the following code in my Secondary Board

// Wire Peripheral Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI Peripheral device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

int led_pin_1 = 9;
int led_pin_2 = 8;
int x = 1; //variable to save the information from the master

#include <Wire.h>

void setup() {

  Wire.begin(5);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output

  pinMode(led_pin_1, OUTPUT);
  pinMode(led_pin_2, OUTPUT);
}

void loop()
{
  delay(100);
  if (x == 0){
    Serial.println("light ON");
    digitalWrite(led_pin_1, HIGH);
    digitalWrite(led_pin_2, HIGH);
    x=1;
    delay(100);
  } else {
    digitalWrite(led_pin_1, LOW);
    digitalWrite(led_pin_2, LOW);

  }
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

Note: These code I found on the Arduino page, I modefied them to suit the microcontroller I am using.

Resistance is 49.0 OHM, I realized I applied 500k OHM, so I re-soldered my resistance elements.

My boards were still not communicating; so now was time to consider the following sequence:

Circuits are correct >> Wiring on the boards are correct >> Code is correct because we used it on different boards

so now it was time to assume that the microcontroller Seeed xiao RP2040 doesn’t work well with this library, therefore we changes the microcontrollers into seeedunio xiao. and THAT WAS IT they communicated!! so lets just blame the chemistry here!

comunicate

Group Assignment

During Networking and Communications Week in Fab Academy, we embarked on a project to explore various methods of connecting two microcontrollers. Our objective was to establish a wireless communication link between microcontrollers and utilize it to control a LED lighting system. In this documentation, we will focus on our exploration of ESP-NOW, a communication protocol developed by Espressif Systems, and demonstrate how we successfully implemented it in our project.

ESP-NOW is a communication protocol specifically designed for low-power devices, developed by Espressif Systems, the creators of ESP32 microcontrollers. It allows direct communication between devices without the need for a Wi-Fi network or an access point. ESP-NOW operates in two modes: Station (STA) and Soft Access Point (AP).

Howe we implement:

1- Hardware Setup: We connected an ESP32 Dev Kit microcontroller to a push button and a LED. The push button was used as an input to trigger the LED lighting control. Additionally, we had another microcontroller, acting as the receiver, connected to an NeoPixel LED.

2- Configuring ESP-NOW: We set up one ESP32 module as a sender and the other as a receiver. The sender module was configured to send messages via ESP-NOW when the push button was pressed, while the receiver module was set up to receive and interpret these messages.

3- Establishing Communication: The sender module, in STA mode, established a direct connection with the receiver module, operating in AP mode. This allowed for peer-to-peer communication between the two microcontrollers.

4- LED Lighting Control: When the push button was pressed on the sender module, it sent a message via ESP-NOW to the receiver module. The receiver module interpreted the message and controlled the connected LED accordingly, resulting in the desired lighting effect.

The receiver PCB:

receiver

The remote PCB:

remotePCB

For the remote and receiver we need to figure out the mac number its like an identifier for each MCU using this code:

#include "WiFi.h"

                void setup(){
                  Serial.begin(115200);
                  WiFi.mode(WIFI_MODE_STA);
                  Serial.println(WiFi.macAddress());
                }

                void loop(){

                }

The remote code:

#include
                #include

                #define PIN_NEO_PIXEL  13  // Arduino pin that connects to NeoPixel
                #define NUM_PIXELS     3   // The number of LEDs (pixels) on NeoPixel

                Adafruit_NeoPixel NeoPixel(NUM_PIXELS, PIN_NEO_PIXEL, NEO_GRB + NEO_KHZ800);

                uint8_t remoteMac[] = {0xB8, 0xD6, 0x1A, 0x5C, 0x03, 0x88};

                void setup() {
                  Serial.begin(115200);
                  NeoPixel.begin();
                  NeoPixel.clear(); // Set all pixel colors to 'off'
                  NeoPixel.show();  // Update the NeoPixel strip

                  WiFi.mode(WIFI_STA);
                  WiFi.disconnect();

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

                  esp_now_peer_info_t peerInfo;
                  memset(&peerInfo, 0, sizeof(peerInfo));
                  memcpy(peerInfo.peer_addr, remoteMac, sizeof(remoteMac));
                  peerInfo.channel = 0;
                  peerInfo.encrypt = false;

                  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
                    Serial.println("Failed to add peer");
                    return;
                  }

                  esp_now_register_recv_cb(OnDataRecv);
                }

                void loop() {
                  // No need to add any code here
                }

                void OnDataRecv(const uint8_t* mac, const uint8_t* data, int len) {
                  if (len == 1) {
                    uint8_t receivedData = data[0];
                    handleReceivedData(receivedData);
                  }
                }

                void handleReceivedData(uint8_t data) {
                  if (data == 0) {
                    NeoPixel.clear();
                    NeoPixel.show();
                  } else if (data == 1) {
                    NeoPixel.setPixelColor(0, NeoPixel.Color(255, 0, 0));
                    NeoPixel.show();
                    delay(2000);
                    NeoPixel.clear();
                    NeoPixel.show();
                  } else if (data == 2) {
                    NeoPixel.setPixelColor(1, NeoPixel.Color(125, 125, 0));
                    NeoPixel.show();
                    delay(2000);
                    NeoPixel.clear();
                    NeoPixel.show();
                  } else if (data == 3) {
                    NeoPixel.setPixelColor(2, NeoPixel.Color(125, 80, 200));
                    NeoPixel.show();
                    delay(2000);
                    NeoPixel.clear();
                    NeoPixel.show();
                  }
                }

Conclusion : Through our exploration of ESP-NOW, we successfully established a wireless communication link between microcontrollers, enabling us to control a LED lighting system. ESP-NOW provided a straightforward and efficient method for peer-to-peer communication without relying on Wi-Fi infrastructure. This project showcases the versatility and potential of ESP-NOW for various applications requiring wireless microcontroller communication.

group_assignment

Files Download:

Primary_Board_circuit
Secondary_Board_circuit


Last update: July 4, 2023
Back to top