Skip to content

11. Embedded Networking and Communications

Hero Shot

This week I learnt and worked on doing microcontrollers’ communication through the several networking protocols, wired(asynchronous, synchronous) and wireless.


Group assignment:

  • Send a message between two projects
  • Document your work to the group work page and reflect on your individual page what you learned

Individual assignment:

  • design, build and connect wired or wireless node(s) with network or bus addresses and a local input and/or output devices

Learning outcomes

  • Demonstrate workflows used in network design
  • Implement and interpret networking protocols and/or communication protocols

Group Assignment

This week’s group work page is here


What I’ve learnt this week

Network is communication tool where different location. It enable to parallel work in different area.

1.Network Type

  • Wired
    UART, USART, SERCOM, PIO, bit-bang

    • Asynchronous Serial
      Serial broadcast
      Hop-count
      Broad-hop

    • Synchronous Serial
      I2C, SPI

    • Asynchronous unclocked
      ATP(Authenticated Transfer Protocol)

  • Wireless

    • Radio
    • Antennas
    • Single-chip
    • Software radio
    • OpenWrt

2.Wired

USART:(Universal Synchronous & Asynchronous Receiver Transmitter)

SERCOM:(Serial Communication Module)
It is for arm processors and it’s flexible programmable communication processor.

PIO:(Programmed I/O)
It is programmable peripherals.

bit-bang:
implemental programs

(1) Asynchronous Serial

It is serial broadcasting and it needs 2 wires(TX,RX) to connect host and nodes.
Each node also connect both TX(Transmitter) and RX(Receiver) wire and has it’s original address. Therefore host can communicate data to certain node.

UART:(Universal Asynchronous Receiver Transmitter)
UART has a rule of data to send or receive.

Hop Count :
It doesn’t have original address and count the number of the routers and when it reachs last, give that number.

Broad Hop :
Broad hop is a combination of serial and hop count communication. Host broadcasts the message all at once.
Each node sends back by hop count style.

(2) Synchronous Serial

SDI / SDO / CS /SCK, PICO / POCI /…

It has two lines,SDA(Serial Data Line) and SCL(Serical Clock Line). Both line has pull up resistors.
SDA is communicated both ways among host and nodes.
SCL is came from host and has constant frequency. Input and Output must be synchronized to the clock.

SPI :(Serail Peripheral Interface) MISO / MOSI/SS ← (~~master/slave~~ → main/secondary) SDI / SDO / CS / SCK
(Serial data in/Serial data out/chip select/serial clok)
PICO/POC
(Perpherial in controller out/ peripheral out controller in)

I2C:(Inter-Integrated Circuit)

I2C
from Analog devices

The main sends clock data and decide the secondary’s original address. They can communicate each other by selecting each address.

The each bus line has pull up resistor and it keeps HIGH voltage until data sending sign started.

3.Wireless


Individual Assignment

This week, I checked 2 Protocols, Wifi(wireless) and I2C(synchronous wired) using several microcontrollers.

protocol TEST
WIFI LED light on / off
RGB LED light on / off
I2C 2 micro controller communication
3 micro controller communication

WIFI [Non wired]

First test was LED on/off by WIFI protocol.
Using the example code from Arduino IDE, the wifi address and password in Kamakura lab were entered. Port no.(written in the code) was also put in it. (Code is No.1)

Check

We should write WiFi library at first part of the code.

#include <WiFi.h>

After compiling, the address was showed at the Serial Monitor.
That address and port number that was written in the code were entered into the internet browser and this On / Off click page was appeared.
IP address:Port No 
 EX > IP address:123.456.789.071, Port No:80
      123.456.789.071:80

When I clicked the “here” at LED on, then LED was light up and clicked “here” at LED off, LED was off.

Summary

When I tried to test this code at home, I couldn’t connect to the network. Possible reason maybe as follows;
1. First I put the mesh network address -> Not connected
2. Changed the port ID from 80 -> Not Connected
3. Put the network ID and password from the router -> Not connected
4. Check if Xiao can see my house network -> Could see
5. Put back port ID to default one and connect -> Worked!

As first 1 to 3 and 4 and 5 are tested in different room, it seemed also the reason to enable to connect.

NOTICE
- Only 2.4GHZ is available for Xiao
- Not select the SSID with WPA3 only

After testing the LED on/off test by Wifi, I tested the case of RGB LED.
Basically, I added several codes for RGB(LED pinmode setting, on/off command for each color) from the first one, and test it.(Code No.2)

Same as the first code, the IP address was displayed after compiling the code. The address and port number were put into the browser and then the screen below was appeared.

When each “here” could send the command for turning on and off.

Note

📌 Not solved yet…
Mixing color didn’t work well.
For example, when Red LED light was on, Blue LED light was switched on, the color wasn’t reflected properly(no color mixing).


I2C [Wired synchronous serial]

Next I tested I2C network.

Test No. Main Secondary1 Secondary2
1 Xiao C3 Xiao RP2040
2 Xiao C3 Xiao RP2040 Raspberry Pi Pico2

1. Connected XiaoC3 and XiaoRP2040

First, a circuit was created I2C communication with XiaoC3 as a Main and Xiao RP2040 as a secondary.

Next, the code for I2C communication was found from the internet and written and compiled on the Arduino for the main and the secondary respectively.
In this code, main side initiated the communication(Wire.begin()) and send 0.
The secondary side got the queue, send the string “hello” to the main side.
(Codes are 3-(1),(2))

Point

  • It must be include “#include Wire.h”(Wire library)
  • A unique address should be specified for secondary and written in the respective code of main and secondary as “#define”

Test

The communication test was succeeded.

2. Connected among XiaoC3, XiaoRP2040 and Raspberry Pi Pico

As a communication between 2 microcontrollers has been succeeded, a communication among 3 were tested as a next step.

Circuit was basically created same theory among 3 microcontrollers.

This time, secondary2’s code sent the string “world” to main too and the secondary2 part of code was added in main program too.

Test

The test was same procedure as the first one. However, it was hard time to be recognized a Raspberry Pi Pico.
So the circuit was changed back to 2 microcontrollers(XiaoC3 and Raspberry Pi Pico) and checked if they were worked.

The test of 2 microcontrollers were OK again, then back to 3 microcontrollers test. This time, the same port was taken up to several microcontrollers, it made impossible to establish a network.
-> Each port was set correct ports and test it.

This time, network was established successfully and communication was also began.

Research

I researched a lot about the how to connect the circuit and the codes. As I had rather hard time with establishing the network, I checked those information through internet. Instructors also gave a lot of advises as usual.

What I’ve learnt this week

This week, I’ve learnt a lot about the network and experimented in many ways by creating real circuits. Creating real circuits was really helpful to understanding the I2C structure, because making and putting the circuit was a bit complicating.

Codes

  1. LED Blink code(Wifi) I used this wifi example code to light on/off LED.

    /* 
    LED Blink code (Wifi)
     WiFi Web Server LED Blink
    
     A simple web server that lets you blink an LED via the web.
     This sketch will print the IP address of your WiFi Shield (once connected)
     to the Serial monitor. From there, you can open that address in a web browser
     to turn on and off the LED on pin 5.
    
     If the IP address of your shield is yourAddress:
     http://yourAddress/H turns the LED on
     http://yourAddress/L turns it off
    
     This example is written for a network using WPA2 encryption. For insecure
     WEP or WPA, change the Wifi.begin() call and use Wifi.setMinSecurity() accordingly.
    
     Circuit:
     * WiFi shield attached
     * LED attached to pin 5
    
     created for arduino 25 Nov 2012
     by Tom Igoe
    
    ported for sparkfun esp32
    31.01.2017 by Jan Hendrik Berlin
    
     */
    
    #include <WiFi.h>
    
    // ssid and passwd are put ssid and password of Kamakura lab
    const char *ssid = "ssid";
    const char *password = "passwd";
    
    NetworkServer server(71);
    
    void setup() {
      Serial.begin(115200);
      pinMode(5, OUTPUT);  // set the LED pin mode
    
      delay(10);
    
      // We start by connecting to a WiFi network
    
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);
    
      WiFi.begin(ssid, password);
    
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
    
      Serial.println("");
      Serial.println("WiFi connected.");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
    
      server.begin();
    }
    
    void loop() {
      NetworkClient client = server.accept();  // listen for incoming clients
    
      if (client) {                     // if you get a client,
        Serial.println("New Client.");  // print a message out the serial port
        String currentLine = "";        // make a String to hold incoming data from the client
        while (client.connected()) {    // loop while the client's connected
          if (client.available()) {     // if there's bytes to read from the client,
            char c = client.read();     // read a byte, then
            Serial.write(c);            // print it out the serial monitor
            if (c == '\n') {            // if the byte is a newline character
    
              // if the current line is blank, you got two newline characters in a row.
              // that's the end of the client HTTP request, so send a response:
              if (currentLine.length() == 0) {
                // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                // and a content-type so the client knows what's coming, then a blank line:
                client.println("HTTP/1.1 200 OK");
                client.println("Content-type:text/html");
                client.println();
    
                // the content of the HTTP response follows the header:
                client.print("Click <a href=\"/H\">here</a> to turn the LED on pin 5 on.<br>");
                client.print("Click <a href=\"/L\">here</a> to turn the LED on pin 5 off.<br>");
    
                // The HTTP response ends with another blank line:
                client.println();
                // break out of the while loop:
                break;
              } else {  // if you got a newline, then clear currentLine:
                currentLine = "";
              }
            } else if (c != '\r') {  // if you got anything else but a carriage return character,
              currentLine += c;      // add it to the end of the currentLine
            }
    
            // Check to see if the client request was "GET /H" or "GET /L":
            if (currentLine.endsWith("GET /H")) {
              digitalWrite(5, HIGH);  // GET /H turns the LED on
            }
            if (currentLine.endsWith("GET /L")) {
              digitalWrite(5, LOW);  // GET /L turns the LED off
            }
          }
        }
        // close the connection:
        client.stop();
        Serial.println("Client Disconnected.");
      }
    }
    

  2. RGB LED On/Off Code

    #include <WiFi.h>
    
    const char *ssid = "ssid";        // input ID
    const char *password = "passwd";  // input password
    
    /* Set LED color pin num */
    int pinRed = 2;
    int pinGrn = 3;
    int pinBlu = 4;
    
    NetworkServer server(71);
    
    void setup() {
      Serial.begin(115200);
    
      //pinMode(5, OUTPUT);  // set the LED pin mode
      pinMode(pinRed, OUTPUT);  // set the LED pin mode
      pinMode(pinGrn, OUTPUT);  // set the LED pin mode
      pinMode(pinBlu, OUTPUT);  // set the LED pin mode
    
      delay(10);
    
      // We start by connecting to a WiFi network
    
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);
    
      WiFi.begin(ssid, password);
    
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
    
      Serial.println("");
      Serial.println("WiFi connected.");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
    
      server.begin();
    }
    
    void loop() {
      NetworkClient client = server.accept();  // listen for incoming clients
    
      if (client) {                     // if you get a client,
        Serial.println("New Client.");  // print a message out the serial port
        String currentLine = "";        // make a String to hold incoming data from the client
        while (client.connected()) {    // loop while the client's connected
          if (client.available()) {     // if there's bytes to read from the client,
            char c = client.read();     // read a byte, then
            Serial.write(c);            // print it out the serial monitor
            if (c == '\n') {            // if the byte is a newline character
    
              // if the current line is blank, you got two newline characters in a row.
              // that's the end of the client HTTP request, so send a response:
              if (currentLine.length() == 0) {
                // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                // and a content-type so the client knows what's coming, then a blank line:
                client.println("HTTP/1.1 200 OK");
                client.println("Content-type:text/html");
                client.println();
    
                // the content of the HTTP response follows the header:
                client.print("Click <a href=\"/rH\">here</a> to turn the Red LED on pin on.<br>");
                client.print("Click <a href=\"/rL\">here</a> to turn the Red LED on pin off.<br>");
                client.print("Click <a href=\"/gH\">here</a> to turn the Green LED on pin on.<br>");
                client.print("Click <a href=\"/gL\">here</a> to turn the Green LED on pin off.<br>");
                client.print("Click <a href=\"/bH\">here</a> to turn the Blue LED on pin on.<br>");
                client.print("Click <a href=\"/bL\">here</a> to turn the Blue LED on pin off.<br>");
    
                // The HTTP response ends with another blank line:
                client.println();
                // break out of the while loop:
                break;
              } else {  // if you got a newline, then clear currentLine:
                currentLine = "";
              }
            } else if (c != '\r') {  // if you got anything else but a carriage return character,
              currentLine += c;      // add it to the end of the currentLine
            }
    
            // RED Check to see if the client request was "GET /H" or "GET /L":
            if (currentLine.endsWith("GET /rH")) {
              digitalWrite(pinRed, HIGH);  // GET /H turns the LED on
            }
            if (currentLine.endsWith("GET /rL")) {
              digitalWrite(pinRed, LOW);  // GET /L turns the LED off
            }
            // Green
             if (currentLine.endsWith("GET /gH")) {
              digitalWrite(pinGrn, HIGH);  // GET /H turns the LED on
            }
            if (currentLine.endsWith("GET /gL")) {
              digitalWrite(pinGrn, LOW);  // GET /L turns the LED off
            }
            //Blue
            if (currentLine.endsWith("GET /bH")) {
              digitalWrite(pinBlu, HIGH);  // GET /H turns the LED on
            }
            if (currentLine.endsWith("GET /bL")) {
              digitalWrite(pinBlu, LOW);  // GET /L turns the LED off
            }
         }
        }
        // close the connection:
        client.stop();
        Serial.println("Client Disconnected.");
      }
    }
    

  3. I2C Code
    (1) Main

   #include "Wire.h"

//define the address
#define SLAVE_ADDR 9
#define SLAVE_ADDR2 8

#define ANSWERSIZE 5


void setup() {
  // put your setup code here, to run once:
  Wire.begin();           // Start 
  Serial.begin(9600);

  Serial.println("I2C Master");

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(50);

  Serial.println("Write data to Slave");
/*
  Wire.beginTransmission(SLAVE_ADDR);   
  Wire.write(0);
  Wire.endTransmission();
  Serial.println("Receive Data");
  Wire.requestFrom(SLAVE_ADDR, ANSWERSIZE);
*/
  String resp = " ";
  transData(SLAVE_ADDR, resp);    // transmission to secondary1
  Serial.println(resp);

  transData(SLAVE_ADDR2, resp);   // transmission to secondary2
  Serial.println(resp);
}

void transData(int s_addr, String response){
  Wire.beginTransmission(s_addr);       // Start transmission
  Wire.write(0);                        // prepare the sending data
  Wire.endTransmission();               // End transmission

  Serial.print("Receive Data from");
  Serial.println(s_addr);
  Wire.requestFrom(s_addr, ANSWERSIZE);

  // String response = " ";
  response = " ";
  while(Wire.available()){
    char b = Wire.read();
      Serial.print(b);
    response += b;
  }
}

(2) Secondary1

#include "Wire.h"

//define the address
#define SLAVE_ADDR 9

#define ANSWERSIZE 5

String answer = "Hello";

void setup() {
  // put your setup code here, to run once:
  Wire.begin(SLAVE_ADDR);

  Wire.onRequest(requestEvent);

  Wire.onReceive(receiveEvent);

  Serial.begin(9600);
  Serial.println("I2C Slave Demonstration");

}

void receiveEvent(int howbyte){
  while(0 < Wire.available()){
    byte x = Wire.read();
  }

  Serial.println("Receive Event");
}

void requestEvent(){
  byte response[ANSWERSIZE];

  for(byte i=0;i<ANSWERSIZE; i++){
    response[i] = (byte)answer.charAt(i);
  }
    Wire.write(response, sizeof(response));
    Serial.println("Request Event");

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(50);

}

(3) Secondary2

#include "Wire.h"

//define the address
#define SLAVE_ADDR2 8

#define ANSWERSIZE 5

String answer = "World";

void setup() {
 //debug
  Serial.println("slave start");

  // put your setup code here, to run once:
  Wire.begin(SLAVE_ADDR2);

  Wire.onRequest(requestEvent);

  Wire.onReceive(receiveEvent);

  Serial.begin(9600);
  Serial.println("I2C Slave2 Demonstration");

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(50);

}

void receiveEvent(int howbyte){     // intをつけないとエラーが出る
//  Serial.println(howbyte);  // 何バイト受信したか

  while(0 < Wire.available()){
    byte x = Wire.read();
  }

  Serial.println("Receive Event");
}

void requestEvent(){
  byte response[ANSWERSIZE];

  for(byte i=0;i<ANSWERSIZE; i++){
    response[i] = (byte)answer.charAt(i);
  }

  Wire.write(response, sizeof(response));
  Serial.println("Request Event");

}