11. Make devices talk to each other¶
This week I learnt how to connect 2 different devices so they can communicate with each other through I2C communication protocols. I learnt how to make a Master device can connect to child devices using an I2C bus, and make it communicate in both directions.
Looking ahead, I would also like to eventually add Wifi and Bluetooth capability to my board and connect it to an online database. I would also make the I2C bus scalable so it can make full use of the maximum
Group assignment:
- Send a message between two projects
Individual assignment:
- Design, build and connect wired or wireless node(s) with network or bus addresses and a local input and/or output devices
Groupwork: Send a message between two projects¶
Our task for this week was to communicate between any 2 devices we already made. We communicated between Shoko and Maki’s project, using 2 wireless methods; . The commnication between the two projects was done by ESP-NOW as both are boards were XIAO ESP32s. You can find the group assignment on the below page. Link to Groupwork documentation
Individual work: Design build and connect wired network¶
Basics of Communication¶
Data transfer can occur via wired methods like USB and I2C, or wireless methods, like Wi-Fi and Bluetooth.
Below are some of the major methods;
- USB is a versatile, high-speed serial bus connecting a host to peripherals using different transfer types.
- I2C is a slower, short-distance, two-wire serial bus for connecting microcontrollers and peripheral ICs, using SDA for data and SCL for the clock signal.
- Wireless connections transmit data through radio waves, offering mobility but often at lower speeds and shorter ranges than wired alternatives.
This week, I decided to implement wired communication between different shelves of the spice rack. My plan was to have 1 master board, and separate child boards for each row. Rico recommended me to us I2C for this, but I couldn’t really understand why exactly, so I did some research into the different communication protocols and what sets I2C apart.
Protocols are methods, procedure (e.g., which device speaks first, at what point, etc), rules (amount of data per message, etc), etc for engagement
Wired Communication Protocols:
Setting realistic goals¶
After my learnings from last week, I started with scoping my main objectives for this week;
1. Learn how a Master device can and recognise different inputs from peripheral devices
2. Learn how a Master device can execute LED output on other child devices
Testing circuits¶
I decided to start with a simple button recognition circuit, and expand the features bit by bit
1. Read button status without I2C¶
Code
const int buttonPinRed = D0; // the number of the pushbutton pin const int buttonPinBlue = D2; // the number of the pushbutton pin // variables will change: int buttonStateRed = 0; // variable for reading the pushbutton status int buttonStateBlue = 0; // variable for reading the pushbutton status void setup() { // initialize the pushbutton pin as an input: Serial.begin(9600);// initialize serial communication at 115200 bits per second pinMode(buttonPinRed, INPUT_PULLUP); pinMode(buttonPinBlue, INPUT_PULLUP); } void loop() { // read the state of the pushbutton value: buttonStateRed = digitalRead(buttonPinRed); // check if the pushbutton is pressed. If it is, the buttonState is HIGH: if (buttonStateRed == HIGH) { // turn LED on: Serial.print("Red is on, "); } else { // turn LED off: Serial.print("Red is off, "); } // read the state of the pushbutton value: buttonStateBlue = digitalRead(buttonPinBlue); // check if the pushbutton is pressed. If it is, the buttonState is HIGH: if (buttonStateBlue == HIGH) { // turn LED on: Serial.println("Blue is on"); } else { // turn LED off: Serial.println("Blue is off"); } }2. Test I2C Communication¶
I breadboarded a 2nd I2C device to connect to my Master device (Xiao ESP32C3).
I used the Wire library example to first ensure that the I2C communication is working.
Master device
#include "Wire.h" #define I2C_DEV_ADDR 0x55 //Specifies the slave device address uint32_t i = 0; void setup() { Serial.begin(115200);//Initiate Serial communication Serial.setDebugOutput(true); Wire.begin(); } void loop() { delay(5000); //Write message to the slave Wire.beginTransmission(I2C_DEV_ADDR); Wire.printf("Hello World! %lu", i++); uint8_t error = Wire.endTransmission(true); Serial.printf("endTransmission: %u\n", error); //Read 16 bytes from the slave uint8_t bytesReceived = Wire.requestFrom(I2C_DEV_ADDR, 16); Serial.printf("requestFrom: %u\n", bytesReceived); if ((bool)bytesReceived) { //If received more than zero bytes uint8_t temp[bytesReceived]; Wire.readBytes(temp, bytesReceived); log_print_buf(temp, bytesReceived); } }Follower device
#include "Wire.h" #define I2C_DEV_ADDR 0x55 //Declare the device's unique address to Master board uint32_t i = 0;//start with uint32_t = 0 void onRequest() {//Define the onRequest function Wire.print(i++);//Every time request is received, increase i by 1 Wire.print(" Packets."); Serial.println("onRequest"); } void onReceive(int len) {//Define the onReceive function Serial.printf("onReceive[%d]: ", len); while (Wire.available()) { Serial.write(Wire.read()); } Serial.println(); } void setup() { Serial.begin(115200);//Initiate Serial communication Serial.setDebugOutput(true); Wire.onReceive(onReceive);//Execute onReceive Wire.onRequest(onRequest);//Execute onRequest Wire.begin((uint8_t)I2C_DEV_ADDR); #if CONFIG_IDF_TARGET_ESP32 char message[64]; snprintf(message, 64, "%lu Packets.", i++); Wire.slaveWrite((uint8_t *)message, strlen(message)); #endif } void loop() {}3. Read Input of another device via I2C¶
I wrote a code for the Master device to read button status of the 2nd I2C device.
Master device
#include "Wire.h" #define I2C_DEV_ADDR1 0x55 uint32_t i = 0; void setup() { Serial.begin(115200);//Prepare for serial communication Serial.setDebugOutput(true); Wire.begin(); } void loop() { delay(5000); //Write message to the slave Wire.beginTransmission(I2C_DEV_ADDR1);//Initiate transmission Wire.printf("Hello device1! %lu", i++); uint8_t error = Wire.endTransmission(true); Serial.printf("endTransmission: %u\n", error); //Read 16 bytes from the slave uint8_t bytesReceived = Wire.requestFrom(I2C_DEV_ADDR1, 2); Serial.printf("requestFrom: %u\n", bytesReceived); if ((bool)bytesReceived) { //If received more than zero bytes uint8_t temp[bytesReceived]; Wire.readBytes(temp, bytesReceived); log_print_buf(temp, bytesReceived); } }Follower device
#include "Wire.h" #define I2C_DEV_ADDR 0x55 uint32_t i = 0; const int buttonPinRed = D0; // the number of the pushbutton pin const int buttonPinBlue = D2; // the number of the pushbutton pin int buttonStateRed = 0; // variable for reading the pushbutton status int buttonStateBlue = 0; // variable for reading the pushbutton status void onRequest() { // Wire.print(i++); buttonStateRed = digitalRead(buttonPinRed);//read the buttonPinRed and assign status if (buttonStateRed == HIGH) { // check if red buttonState is HIGH: Wire.write(1);//If High, Send 1 to Master device //Wire.print(" Packets."); Serial.println(1);//and print 1 on Serial Monitor } else { Wire.write(2);//If not, send 2 to Master device Serial.println(2);//likewise } Serial.println("OnRequest"); } void onReceive(int len) { Serial.printf("onReceive[%d]: ", len); while (Wire.available()) { Serial.write(Wire.read()); } Serial.println(); } void setup() { Serial.begin(115200);//Prepare for serial communication pinMode(buttonPinRed, INPUT_PULLUP);//Set Red pin button as Pullup Input pinMode(buttonPinBlue, INPUT_PULLUP); Serial.setDebugOutput(true); Wire.onReceive(onReceive);//Execute Wire.onReceive Wire.onRequest(onRequest);//Execute Wire.onRequest Wire.begin((uint8_t)I2C_DEV_ADDR);//Initialize the Wire library and joins the I2C bus as a slave #if CONFIG_IDF_TARGET_ESP32 char message[64]; snprintf(message, 64, "%lu Packets.", i++); Wire.slaveWrite((uint8_t *)message, strlen(message)); #endif } void loop() {}4. Read Input of 2 other devices via I2C¶
Master device
5. Request another device to turn on LED¶
Master device
Files¶
Useful links:¶
Reflections:¶
This week I learnt to…
- Demonstrate workflows used in network design
- Implement and interpret networking protocols and/or communication protocols
- Documented what you have learned from implementing networking and/or communication protocols.
- Explained the programming process/es you used.
- Outlined problems and how you fixed them.
What worked well Having Nagano san by my side Adjusting learning objectives
Assignment Checklist:¶
- [] Linked to the group assignment page
- [] Documented my project and what I have learned from implementing networking and/or communication protocols
- [] Explained the programming process(es) I used
- [] Ensured and documented that my addressing for boards works
- [] Outlined problems and how I fixed them
- [] Included design files (or linked to where they are located if I am using a board I have designed and fabricated earlier) and original source code
- [] Included a ‘hero shot’ of my network and/or communications setup