11. Embedded Networking and Communications¶
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)
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.
Useful links¶
- I2C com
- I2C lecture for beginner
- XiaoC3 access point
- seeed XiaoC3
- Arduino docs
- I2C com
- Aruduino docs2
Codes¶
-
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."); } }
-
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."); } }
-
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");
}