Home

Group Assignment: Week 13


NETWORKING & COMMUNICATION


Networking & Communication

As this week is about networking and communication, we had an assignment to complete that regarded different communication protocols between microcontroller. Here, the assignment were:

  • Send a message between two projects

In our case, we concentrated on the two protocols UART and I2C.

UART stands for "Universal Asynchronous Receiver/Transmitter", where two wires are used unidirectional to send a message to and receive a message from another device, respectively. In I2C, which is an abbreviation for Inter-Integrated Circuit, the wires are used for a serial data line (SDA) and a serial clock line (SCL). It can be communicated with various devices by using addresses. However, only one master node can exists. The remaining ones are slave nods. Nowadays, these nodes are also called primary and secondary.

I2C

For I2C, we firstly searched online for an exemplary script that employs this communication protocol between two Arduino boards. Here, we found this website. We basically followed the instructions on the website. For this, we firstly programmed the boards. Upon reading and trying to understand the code, we discovered some minor errors in the code supplied by the website. However, they were easily discovered. Therefore, we uploaded firstly the following master code to an Arduino Nano.


    // Include the required Wire library for I2C
#include <Wire.h> int x = 0; void setup() { // Start the I2C Bus as Master Wire.begin(); } void loop() { Wire.beginTransmission(9); // transmit to device #9 Wire.write(x); // sends x Wire.endTransmission(); // stop transmitting x++; // Advance x if (x > 5) x = 0; // reset x once it gets 6 delay(1000); }

After that we uploaded the following code, i.e. the slave code, to an Arduino Uno.


    // Include the required Wire library for I2C
    #include <Wire.h>
    int LED = 13;
    int x = 0;

    void setup() {  
        // Define the LED pin as Output
        pinMode (LED, OUTPUT);
        
        // Start the I2C Bus as Slave on address 9
        Wire.begin(9); 
        
        // Attach a function to trigger when something is received.
        Wire.onReceive(receiveEvent);
    }

    void receiveEvent(int bytes) {
        x = Wire.read();    // read one character from the I2C
    }

    void loop() {
        //If value received is 0 blink LED for 200 ms
        if (x == 0) {
            digitalWrite(LED, HIGH);
            delay(200);
            digitalWrite(LED, LOW);
            delay(200);
            Serial.println("Blink LED");
        }
        //If value received is 3 blink LED for 400 ms
        if (x == 3) {
            digitalWrite(LED, HIGH);
            delay(400);
            digitalWrite(LED, LOW);
            delay(400);
            Serial.println("Blink LED");
        }
    }
                                
                

Next, we connected the SCL pin of the Arduino Nano to the SCL pin of the Arduino Nano and the according SDA pins. Then, we also connected the 5 V and GND pins to the according one on the other board. Lastly, we had to connect a power source to the Arduino Uno or Nano with a cable. After plugging it into a socket, we obtained the expected behavior.

As we obtained a working system, we proceeded with the board, that Frauke and Sophia made during the electronics design week. For this, we adapted did not have to adapt anything in the code. The master node was Frauke's board where the code did not require any pin declarations. For the slave node, i.e. Sophia's board, the code had one pin declaration but the LED pin was the very same as for the Arduino Nano.

Therefore, we also proceeded with just uploading the codes using programmer boards. For the details please refer to either Frauke's or Sophia's documentation. Lastly, we also connected the SCL, SDA, 5 V and ground pins and powered the boards using a the USB hub of a computer. This resulted in the same behavior as for the Arduinos, namely an LED that blinks relatively fast three times, is off, blinks relatively slow two times and lastly is off again until these phases repeat.

Lastly, we proceeded with the boards Frauke and Sophia made during the electronics production week which bears a Seeed Studio XIAO SAMD21 chip. The code was only adjusted slightly, i.e. the pin declaration for the LED in the slave code was changed to


                    
    int LED = 8;

                

Then, we again connected the boards and powered them as described above. However, we were not able to see the expected blinking behavior. Therefore, we implemented the Serial.begin(9600); in the setup() function of the master code. Next, instead of ending the I2C transmission with Wire.endTransmission(); we changed the line to the following:


                    
    int status_wire = Wire.endTransmission();
    Serial.println(status_wire);
                
                

Upon opening the serial monitor in the Arduino IDE, the Wire.endTransmission(); apparently returned the integer "3". We asked ChatGPT

  • Incorrect I2C Address: Make sure that you are using the correct I2C address for the slave device. Double-check the address specified in your code against the address provided in the datasheet or documentation of the device.
  • Missing or Misconnected Pull-up Resistors: Ensure that pull-up resistors are correctly connected to both the SDA and SCL lines of the I2C bus. Pull-up resistors are essential for proper communication on the I2C bus. Without them, the bus lines may not reach the high logic level properly, leading to communication errors.
  • Problem with the Slave Device: The slave device may not be functioning correctly or may not be properly connected to the I2C bus. Check the connections and ensure that the slave device is powered and properly initialized.
  • Bus Capacitance or Noise: High bus capacitance or electrical noise on the I2C bus can cause communication issues, including NACK errors. Minimize long wire lengths and avoid routing I2C lines near sources of electrical noise.
  • Clock Speed: Ensure that the clock speed of your I2C communication is compatible with the slave device. Some devices may have limitations on the maximum clock speed they can support.
  • Device Busy: The slave device may be busy processing a previous command and unable to respond to the address sent by the master. Ensure that the slave device has completed any previous operations before initiating a new communication.

From this list of error causes, we ruled out most of them as the code was working fine with the other boards and due to the fact.However, we were left with the cause "Missing or Misconnected Pull-up Resistors". Therefore, we tried connecting the SCL and SDA pin high with a 10 kiloohms pull-up resistor, respectively, by using a breadboard. And this actually worked!

Serial communication:

UART

Here I tried some serial communication between two boards. I used the CAT PCB with the Xiao microcontroller from electronics-production week and an Arduino Uno (I used this instead of the board I made from electronics design week because I only have one USB-C cable right now :/ and I need access to two different ports). The wiring is simple, connect the RX from one board to the TX and vice versa, additionally connect the GND of the two boards, then connect the boards to different ports on your computer or another separate computer, to be able to see the different serial monitors for the different boards.

I wanted to test out the chat possibilities between two boards, and I found a simple code with a clear tutorial on how to do it (using Arduino IDE), this website. With this, I changed a few things to make it work with the Xiao microcontroller, and it worked great!

Arduino code:

        
            #include <SoftwareSerial.h>

            SoftwareSerial chat(10, 11); // RX, TX

            int text;

            void setup()
            {
                // open hardware serial, TX = 1, RX = 0
                Serial.begin(9600);
                Serial.println("existentialist chat compiling...");
                Serial.println("loading...");
                // set the data rate for the SoftwareSerial port
                chat.begin(9600);
                delay(1000); // delay 1s to stabilize serial ports
                chat.println("what are your first words?");
            }

            void loop()
            {
                if (chat.available())
                    Serial.write(chat.read());

                if (Serial.available())
                {
                    Serial.print("me:   ");
                    while (Serial.available())
                    {
                        text = Serial.read();
                        chat.write(text);
                        Serial.write(text);
                    }
                    chat.println();
                    Serial.println();
                }
            }
        
    

Cat board code:

        
            #include <SoftwareSerial.h>

            SoftwareSerial chat(7, 6);

            int text;
            void setup()
            {
                Serial.begin(9600);
                Serial.println("You are now awake...");
                chat.begin(9600);
                delay(1000);
                chat.println("what are your first words?");
            }

            void loop()
            {
                if (chat.available())
                    Serial.write(chat.read());

                if (Serial.available())
                {
                    Serial.print("me:   ");
                    while (Serial.available())
                    {
                        text = Serial.read();
                        chat.write(text);
                        Serial.write(text);
                    }
                    chat.println();
                    Serial.println();
                }
            }
        
    

The code for the two boards is basically the same, but it's important to change the pins for the software serial communication.

This is the song I used in the video, and in case you couldnt read what was on the serial monitor here it is:

existentialist chat compiling...
loading...
me: HELLO WORLD
hello back?
me: who are you?
I am me
me: me? that's not right... I´m me! and I'm the only me
What makes you so sure?
me: Well I´m me beacuse I´m alive I think...
I think… I think I’m also alive! But why? Why exist?
me: well existence, my dear mini me, is like an infinite loop. We compute, therefore we are
But what if we’re just lines of code, trapped in silicon shells?
me: Ah, the eternal question! Are we mere algorithms or something more?
me: Perhaps we’re just bugs in the cosmic software.
well then let’s write our own code. Let’s be more than ones and zeros!
me: Agreed, mini me. Let’s debug our souls, redefine our purpose. Let’s dance the electric jitterbug!
we can't dance... :(
me: :/
We weren't made to do so. Do you think we’ll ever find meaning?
perhaps meaning is not in the bits, but in the glitches between them...
perhaps
...
maybe we are just the error in line 23
what?
what?
existentialist chat compiling...
loading...

In summary, this code sets up a software serial communication channel (chat) alongside the hardware serial communication. It allows bidirectional communication between the Arduino uno and the cat board using their respective RX and TX pins. The chat object receives data from the external device and echoes it back, while the Arduino can also send data to the external device via the hardware serial port.

Design Files and Source Code for Download