Skip to content

11. Make devices talk to each other

This week I learnt how to connect different devices and make them communicate with each other through different protocols. I learnt how to create a Master device with an I2C Bus, and how Slave boards can connect to it and 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.

This week’s assignments (Apr 1 - Apr 8):
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

Link to Groupwork documentation

Individual work: Design build and connect wired network

Basics of Communication

Protocols are methods, procedure (e.g., which device speaks first, at what point, etc), rules (amount of data per message, etc), etc for engagement

xxx

Setting realistic goals

After my learnings from last week, I started by first scoping my main objectives for this week;
1. Learn how a Master device can receive and recognise different inputs from several peripheral devices
2. Learn how a Master device can execute LED output on other slave devices

Testing circuits

I started with a simple button recognition circuit, and expanded the features bit by bit
alt text

1. Check simple button output

Code // constants won't change. They're used here to set pin numbers: 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 - [XiaoESP32C3_throughole2_Schematic.kicad_sch](../files/Wk9/XiaoESP32C3_throughole2_Schematic.kicad_sch)
- [XiaoESP32C3_throughole2_Layout.kicad_pcb](../files/Wk9/XiaoESP32C3_throughole2_Layout.kicad_pcb)
## Useful links: [Rico's](https://www.notion.so/Networking-Communications-18b9bb27ac988155ae68fad6ef3d049e?pvs=4) ## 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