WEEK 13 - NETWORKING AND COMMUNICATIONS

hero shot

b o motor with i2c communication allowing to control the motors. TECHNICALLY we can add 128 motors ( 7 bit addressing). in a row

this week, our focus will be on learning how to establish connections between two or more boards, whether with or without wires. Understanding this concept is crucial as it enables us to facilitate communication between boards, which is essential for various projects including my final project.

assignment

individual assignment

  • design, build, and connect wired or wireless node(s) with network or bus addresses and local input &/or output device(s
    group assignment
  • send a message between two projects

group assignmnet

You can find our group page hereand this week is here.

final_pic.jpg

setup - linking two PROJECTs

about communication protocols

I2C (Inter-Integrated Circuit)

  • Type: Synchronous, Multi-master, Multi-slave
  • Lines: Two (SDA - Serial Data, SCL - Serial Clock)
  • Speed: Typically up to 400 kHz, but can go up to 3.4 MHz in High-Speed mode
  • Addressing: Uses 7-bit or 10-bit addresses to communicate with multiple devices
  • Pros:
    • Only two wires needed, reducing pin count and wiring complexity.
    • Supports multiple masters and multiple slaves.
    • Devices can be easily added to the bus.
  • Cons:
    • Slower compared to other protocols like SPI.
    • Limited to short distances due to capacitance on the bus lines.

SPI (Serial Peripheral Interface)

  • Type: Synchronous, Master-Slave
  • Lines: Four (MOSI - Master Out Slave In, MISO - Master In Slave Out, SCLK - Serial Clock, SS - Slave Select)
  • Speed: Typically up to tens of MHz
  • Pros:
    • High-speed communication.
    • Full-duplex (simultaneous send and receive).
    • Simple protocol with no addressing overhead.
  • Cons:
    • Requires more pins than I2C.
    • No standard for daisy-chaining devices; requires separate slave select lines for each device.
    • More complex wiring for multiple slaves.

UART (Universal Asynchronous Receiver/Transmitter)

  • Type: Asynchronous, Point-to-Point
  • Lines: Typically two (TX - Transmit, RX - Receive), plus optional control lines
  • Speed: Variable, typically up to 115200 bps or higher
  • Pros:
    • Simple and widely used for serial communication.
    • No clock line needed; each device uses its own clock.
    • Can be used for communication over longer distances.
  • Cons:
    • Typically only supports point-to-point communication.
    • Requires matching baud rates between devices.
    • Error handling is more complex compared to synchronous protocols.

CAN (Controller Area Network)

  • Type: Synchronous, Multi-master, Multi-slave
  • Lines: Two (CAN_H, CAN_L)
  • Speed: Up to 1 Mbps (Classical CAN), up to 8 Mbps (CAN FD)
  • Pros:
    • Robust error handling and fault tolerance.
    • Efficient for high-speed communication in noisy environments (e.g., automotive).
    • Supports multiple masters and slaves.
  • Cons:
    • More complex protocol with higher overhead.
    • Requires CAN transceivers for communication.

RS-485

  • Type: Asynchronous, Multi-point
  • Lines: Two (A, B)
  • Speed: Typically up to 10 Mbps
  • Pros:
    • Supports long-distance communication (up to 1200 meters).
    • Multi-drop capability, allowing multiple devices on the same bus.
    • Differential signaling provides noise immunity.
  • Cons:
    • Requires transceivers for communication.
    • Protocol handling must be implemented in software or additional hardware.

USB (Universal Serial Bus)

  • Type: Synchronous, Master-Slave
  • Lines: Four (VCC, GND, D+, D-)
  • Speed: Various standards (e.g., USB 2.0 up to 480 Mbps, USB 3.0 up to 5 Gbps)
  • Pros:
    • High-speed data transfer.
    • Supports power delivery and data communication.
    • Standardized connectors and widespread use.
  • Cons:
    • More complex protocol and hardware requirements.
    • Typically requires host controllers (e.g., PC or USB hubs).

Summary

  • I2C: Best for simple, low-speed communication with multiple devices using only two wires.
  • SPI: Ideal for high-speed communication but requires more wiring.
  • UART: Simple and effective for point-to-point communication, widely used in serial ports.
  • CAN: Suitable for robust communication in noisy environments, especially in automotive applications.
  • RS-485: Good for long-distance, multi-point communication with noise immunity.
  • USB: Standard for high-speed data transfer with power delivery capabilities, used in peripherals like keyboards, mice, and storage devices.

making the board with i2c pins

this week i am making two boards powered by attiny 412 and i2c communicate it with a master attiny 1614 board made in WEEK 9 - OUTPUT DEVICES

Pasted image 20240501185722.jpg
the schematics

Pasted image 20240501191338.jpg
constraints

Pasted image 20240502193153.jpg
bom

teh board making process is explained in the WEEK 4 - ELECTRONICS PRODUCTION.
Pasted image 20240517143620.jpg
routing

the boards are woking independently. but i was not able to establish i2c with . reason i found was that i pulled down line with RESISTORS instead of pull up. i removed the resistors . EVEN THOUGH i need to pullup the line. i shoudl figure it out

debugging

so what i have done is i added pull up in WEEK 9 - OUTPUT DEVICES master board. which sorted the issue .

IMG_7660.jpg

and i REFERRED to what done beforehand . got sample code for from saheeen's documentation.

#include <Wire.h>

void setup() {
  Wire.begin();  // join i2c bus (address optional for master)
}

byte x = 0;

void loop() {
  Wire.beginTransmission(8);  // transmit to device #8
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte
  Wire.endTransmission();     // stop transmitting

  x++;
  delay(500);
}

the student code i took for reference



//
// Slave-reader
//
// Wire Slave Receiver
//
// by Nicholas Zambetti < http://www.zambetti.com> and modified by Saheen Palayi 06/06/2022
//
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose, but must
// acknowledge this project. Copyright is retained and
// must be preserved. The work is provided as is; no
// warranty is provided, and users accept all liability.
//


// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006 by Nicholas Zambetti

// This example code is in the public domain.


//Added software serial for Attiny84
#include <Wire.h>






void setup() {
  
  Wire.begin(8);                 // join i2c bus with address #8
  Wire.onReceive(receiveEvent);  // register event
  Serial.begin(9600);            // start serial for output
}

void loop() {
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  while (1 < Wire.available()) {  // loop through all but the last
    char c = Wire.read();         // receive byte as a character
    Serial.print(c);              // print the character
  }
  int x = Wire.read();  // receive byte as an integer
  Serial.println(x);    // print the integer
}







master code

for the i2c wiring i made this connector with 2*2 conn header

IMG_7607.jpg

IMG_7608.jpg
made the connection wire

IMG_7619.jpg
the setup
Pasted image 20240628161412.jpg
the circuit diagram

SUCCESSFUL debugging

yes i was finally able to debug successfully.

final coding

this is done using the help of chat gpt. the prompt log is like

Initial Request:

Prompt: "I have motors on pin 4 of both slaves. I have established I2C communication between master and slave devices. Now, I want to control the motors using serial input to the master. Inputting the slave address (8 or 9) and a command (1 or 0) should turn the motor on or off."

ChatGPT Response: ChatGPT provided an outline of the steps and sample code for setting up the master and slave Arduinos to achieve the desired motor control.

Clarification on Commands:

Prompt: "I need an example of how the master sends the command to the slaves and how the slaves interpret these commands to control the motors."

ChatGPT Response: ChatGPT gave detailed Arduino code for both the master and the slave devices, including how to parse serial inputs on the master, send commands to the appropriate slave, and control the motor on the slave.

Confirming Communication Setup:

Prompt: "I've set up the master and slave code. How can I test if the I2C communication is working properly before integrating motor control?"

ChatGPT Response: ChatGPT suggested using basic I2C communication test code to ensure the master can send and the slaves can receive messages.

Final Integration:

Prompt: "How do I integrate the motor control part after confirming the communication works?"

ChatGPT Response: ChatGPT provided the complete integrated code for the master and the slave to parse commands and control the motors based on the serial input.

we are using the Serial Monitor to send commands to the master Arduino, which then relayed the commands to the appropriate student Arduino. The commands included the student address and the desired state of the motor (on or off).

Student 1 Code (Device Address 8)

#include <Wire.h>

const int motorPin = 4;

void setup() {
  pinMode(motorPin, OUTPUT);
  Wire.begin(8);                // join I2C bus with address #8
  Wire.onReceive(receiveEvent); // register event
}

void loop() {
  // Nothing to do here
}

// function that executes whenever data is received from master
void receiveEvent(int howMany) {
  if (Wire.available()) {
    byte command = Wire.read();
    if (command == 1) {
      digitalWrite(motorPin, HIGH);  // turn motor on
    } else if (command == 0) {
      digitalWrite(motorPin, LOW);   // turn motor off
    }
  }
}

Student 2 Code (Device Address 9)

#include <Wire.h>

const int motorPin = 4;

void setup() {
  pinMode(motorPin, OUTPUT);
  Wire.begin(9);                // join I2C bus with address #9
  Wire.onReceive(receiveEvent); // register event
}

void loop() {
  // Nothing to do here
}

// function that executes whenever data is received from master
void receiveEvent(int howMany) {
  if (Wire.available()) {
    byte command = Wire.read();
    if (command == 1) {
      digitalWrite(motorPin, HIGH);  // turn motor on
    } else if (command == 0) {
      digitalWrite(motorPin, LOW);   // turn motor off
    }
  }
}

Master Code

#include <Wire.h>

void setup() {
  Wire.begin();               // join I2C bus as master
  Serial.begin(9600);         // start serial for output
  Serial.println("Enter commands in the format: <address> <command>");
  Serial.println("For example, '8 1' to turn on motor on student 8");
}

void loop() {
  if (Serial.available()) {
    String input = Serial.readStringUntil('\n');
    int spaceIndex = input.indexOf(' ');
    if (spaceIndex > 0) {
      int address = input.substring(0, spaceIndex).toInt();
      int command = input.substring(spaceIndex + 1).toInt();
      sendCommand(address, command);
    }
  }
}

void sendCommand(int address, int command) {
  Wire.beginTransmission(address);
  Wire.write(command);
  Wire.endTransmission();
  Serial.print("Sent command ");
  Serial.print(command);
  Serial.print(" to student ");
  Serial.println(address);
}

Explanation

Student 1 and Student 2 Code

  1. Initialisation: Both students initialised the I2C communication with specific addresses (8 and 9 respectively).
  2. Motor Pin Setup: The motor pin (pin 4) was set as an output.
  3. Event Handling: The receiveEvent function was registered to handle incoming data from the master.
  4. Command Handling: When data was received from the master, the receiveEvent function read the command. If the command was 1, the motor turned on. If the command was 0, the motor turned off.

Master Code

  1. Initialisation: The master initialised the I2C communication and the Serial Monitor.
  2. Command Input: The master read input from the Serial Monitor in the format <address> <command>. For example, 8 1 meant sending command 1 to the student at address 8.
  3. Command Transmission: The sendCommand function sent the specified command to the designated student address via I2C.
  4. Feedback: The master printed feedback to the Serial Monitor to confirm the command was sent successfully.

This setup allowed us to control multiple student devices from a single master device using the I2C protocol.

the result

IMG_7621 1.jpg

Reflection

This involves a lot of debugging. I've gained confidence that I can make things right even in the worst situations, especially when it comes to working with boards.