Skip to content

14. Networking and communications

Group assignment

Send a message between two projects

Individual assignment

Design, build, and connect wired or wireless node(s) with network or bus addresses

Documentation
1. AT85I2CEagleFiles
2. LightAT85I2CEagleFiles
3. LightAT44I2CEagleFiles

This week I’m going to sense something with a microcontroller and send the sensor values to my boatduino board via I2C. I’ll also experiment with bluetooth.



The I2C communication

The I2C communication is a two wire communication (SCL and SDA). The important thing with it is that we can plug up to 120 different slave devices to thoses two wires and get datas. What it implies is that we need to get different adresses for each device and set time for each slave device to communicate with the master board. I’ll try different configutations.

Get datas from a sensor which communicate via I2C.

In the lab I found a temperature and humidity sensor from adafruit. As per the sensor datasheet we can learn few important things :

  • We need to supply the senosr with 5V
  • We need to put a 10K pullup resistor on SDA and SCL to get the proper communication
  • The sensor I2C adress is 0x5C (92 in decimal) and it cannot be changed, which means if I plug another I2C sensor I’ll need to give it a different I2C adress.

Knowing all this, I’ve designed a very simple PCB to add the resistors :

Schematic
Paths

I’ve made the PCB using the lasercutter and soldered the components

PCB
Components

I’ve used the sensor library, uploaded the test code into my boatduino and I could see the values of the sensor on the serial monitor.

Connection
Working sensor

NOTE : I noticed that I didn’t need the serial library for my FTDI to see the values. I’m not sure why but it’s working.

I2C Master and Slave communication between two Atmega 328p

Getting the connection

I’ve been through the Wire library which allow two arduinos to communicate via I2C.

I’ve decided to use my boatduino V0.2 as a slave and my Boatduino V0.1 as the master here.

For the slave, I’ve uploaded a code so it sends to the master “hello”

// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>

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

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  Wire.write("hello "); // respond with message of 6 bytes
  // as expected by master
}

Few important information in this code :

  • I’ll give as I2C adress the number 8
  • The data is sent only if the master requires it

For the master I’ve uploaded a code to request the slave number 8 to send 6 bytes of datas and display the package received in the serial monitor.

// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop() {
  Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}

I then connected each board :

  • VCC with VCC (they share the same supply from the FTDI cable)
  • GND with GND (they need the same ground)
  • SCL with SCL
  • SDA with SDA

I uploaded both codes and I could see the communication going between the two boards.

Connection
Working sensor

I then probbed SCL and SDA signal on the oscilloscope to see how the signals would look like .

Signal
Package

NOTE : It’s interesting to imagine how the signal is transformed into digits and later on displayed in the serial monitor

Getting values from ADC

My focus for this week is to make a board with a sensor that can communicate to my main boatduino. To test this I plugged a potentiometer to a slave arduino uno and wanted to get the senor values in boatduino via I2C.

Here the code I used for the Arduino as slave :

// Include the required Wire library for I2C
#include <Wire.h>

int x = 0;
int sensorPin = A0;
int sensorValue = 0;

void setup() {

// Start the I2C Bus as Master
Wire.begin();
Serial.begin(9600);

}

void loop() {
sensorValue = analogRead(sensorPin);
Serial.println(sensorValue);
Wire.beginTransmission(9);
// transmit to device #9
Wire.write(sensorValue);
delay(100);
Wire.endTransmission();
// stop transmitting

}

Here the I2C adress of the sensor is 9. Here’s the code for the Arduino slave :

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

void setup() {
// Start the I2C Bus as Slave on address 9
Wire.begin(9);
// Attach a function to trigger when something is received.
Wire.onReceive(receiveEvent);
//bit rate for data transfer over Serial communication
Serial.begin(9600);
}

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

void loop() {

//potentiometer value from sensor
Serial.print("Sensor Value is: ");
Serial.println(x);
delay(100);

}

Here are the results I had.

Connection
Working sensor

Then I plugged everything and it worked. That’s great, it means I can design a board with a sensor on it and send the value of the sensor to another board using I2C communication.

Going ATtiny

The process is working but I feel it’s a bit overkill to use 326P to put a sensor on it while the ATtiny can also communicate via I2C.

I’ve decided to make few boards to try different configurtions :

ATtiny85 I2C board

I designed a simple board to try I2C communication with an ATtiny85.

Schematic
Paths

I’ve made the PCB using the lasercutter and soldered the components

PCB
Components

ATtiny85 I2C light sensor board

Based on the previous design and my design of the light sensor boards I’ve made during the Input device week I’ve designed this board.

Schematic
Paths

I’ve made the PCB using the lasercutter and soldered the components.

PCB
Components

I found out I forgot to supply the Attiny so I had to soldered extra wires.

ATTiny44A I2C light sensor board

Finally I tried to make the same board but with an ATtiny44.

Schematic
Paths

I’ve made the PCB using the lasercutter and soldered the components.

PCB
Components

I’ve tested the board with the code I’ve made during the input device week and the board works well.

Trying to get somewhere with it

The Wire.h library do not support the ATtiny microcontroller family. Fortunately there are two libraries that does :

I’ve been through some good documentation online :

  • Andrea Spiess video on I2C communication (great to understand the concept)
  • Andrea Spiess video to make I2C sensor using an aTtiny85 as salve
  • This Tutorial to use an ATtiny as I2C slave to send values from its ADC

I’ve been through different codes, here’s the last one I came up with :

#include <TinyWireS.h>       // Requires fork by Rambo with onRequest support

void setup()
{
  TinyWireS.begin(8);      // Begin I2C Communication
  TinyWireS.onRequest(transmit);         // When requested, call function transmit()
}

void transmit()
{
  TinyWireS.send("hello ");
}

void loop()
{
  delay(100);                          
}

I’ve tried many things but I could get even a “hello ” signal toi my master. I’ve check many things to try understand where’s my mistake :

  • I checked if the board got supply
  • I checked the signals on my oscilloscope
  • I checked the connections and my design
  • I tried to change the values of the pull up resistors for I2C communication
  • I compiled and uploaded many codes without error messages
  • I changed the value of the resonator

I’m not quite sure where’s my mistake :

  • Is it because I use an ATtiny85V and not an ATtiny85 ?
  • Is it because I miss something in the code ?
  • Is it because of a problem in the design of my board ?

I still have to experiment.

The bluetooth communication

Testing the bluetooth connectivity with my Boatduino

I’ve found a keyes bluetooth module and I decided to test it out.

I first uploaded the test code provided (just changed the LED pin to 8 as per my design):

int val;
int ledpin=8;

void setup()
{
Serial.begin(9600);
pinMode(ledpin,OUTPUT);
}

void loop()
{ val=Serial.read();
if(val=='a')
{
digitalWrite(ledpin,HIGH);
delay(250);
digitalWrite(ledpin,LOW);
delay(250);
Serial.println("keyestudio");
}
}

Using this code, each time I’ll send the command “a” in the serial monitor, I’ll get “keyesstudio” written and my led will blink.

I then dowloaded an android app to be able to communicate.

Once I’ve uploaded my code, I removed the FTDI cable and plugged the bluetooth module instead :

  • VCC to VCC (to supply the module)
  • GND to GND (to have common ground)
  • RX to TX (to communicate)
  • TX to RX (to communicate)

I then openned the app I dowloaded, paired my device and in the monitor each time I send “a” I had as return “keyestudio”.

It worked well with a really simple code. I decided to go further and try to have the value of the yaw angle of my boat directly on my phone.

Getting the YAW angle of the boat via bluetooth

After this success I’ve mixed the previous code and my code to control my two motors to read the value of the YAW angle of my boat on my phone. Here again, the idea is to send the command “a” to have in return the value of the yaw angle.

#include <Wire.h>
#include <MPU6050.h>

MPU6050 mpu;

int val;

// Timers
unsigned long timer = 0;
float timeStep = 0.01;

// Yaw values
float yaw = 0;

void setup()
{
  Serial.begin(9600);

  pinMode(8, OUTPUT);

  // Initialize MPU6050
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }

  // Calibrate gyroscope. The calibration must be at rest.
  // If you don't want calibrate, comment this line.
  mpu.calibrateGyro();

}

void loop()
{
  timer = millis();

  // Read normalized values
  Vector norm = mpu.readNormalizeGyro();

  // Calculate Yaw
  yaw = yaw + norm.ZAxis * timeStep;

  // Wait to full timeStep period
  delay((timeStep*1000) - (millis() - timer));

  val=Serial.read();
if(val=='a')
 {
digitalWrite(8,HIGH);
delay(250);
digitalWrite(8,LOW);
delay(250);

   // Output
  Serial.print(" Yaw = ");
  Serial.println(yaw);
}

delay(10);
}

NOTE : Here I’m using the I2C communication with my sensor to get the value of the YAW angle of my boat and the bluetooth to send datas wirelessly. It worked well which is quite satisfying.

The bluetooth connectivity is a great imporvement to bring to my boatduino board.

Controlling the boat using a bluetooth app

Using the android app I’ve seen there are different modes. The Terminal mode is the one I used to send and recieve datas from my boatduino. In the Controller mode I can make a bluetooth remote controller for my boat.

I need to configure each button (at least the one I need) to send comands to my boatduino. Here I made a code with the following features :

  • Press “a” : Go straight
  • Press “b” : Go backwards
  • Press “c” : Turn Right
  • Press “d” : Turn Left
  • Press “e” : Make a U turn
  • Press “f” : Stop

Here’s how it looks like :

Here’s the code :

int val;

const int controlPin1 = 5; // connected to pin 7 on the H-bridge
const int controlPin2 = 12; // connected to pin 2 on the H-bridge
const int enablePin = 6;   // connected to pin 1 on the H-bridge
int motorEnabled = 0; // Turns the motor on/off
int motorSpeed = 0; // speed of the motor

const int controlPin3 = 9; // connected to pin 7 on the H-bridge
const int controlPin4 = 11; // connected to pin 2 on the H-bridge
const int enablePin2 = 10;   // connected to pin 1 on the H-bridge
int motor2Enabled = 0; // Turns the motor on/off
int motor2Speed = 0; // speed of the motor

void setup()
{
Serial.begin(9600);

  pinMode(controlPin1, OUTPUT);
  pinMode(controlPin2, OUTPUT);
  pinMode(controlPin3, OUTPUT);
  pinMode(controlPin4, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(enablePin2, OUTPUT);

  // pull the enable pin LOW to start
  digitalWrite(enablePin, LOW);
  digitalWrite(enablePin2, LOW);

}

void loop()
{ val= Serial.read();

if(val=='a'){ //Go straight
    digitalWrite(controlPin1, HIGH);
    digitalWrite(controlPin2, LOW);
    digitalWrite(controlPin3, HIGH);
    digitalWrite(controlPin4, LOW);
    analogWrite(enablePin, 255);
    analogWrite(enablePin2, 255);
}

if(val=='b'){ //Go backwards
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, HIGH);
    digitalWrite(controlPin3, LOW);
    digitalWrite(controlPin4, HIGH);
    analogWrite(enablePin, 255);
    analogWrite(enablePin2, 255);
}

if(val=='c'){ //Turn Right
    digitalWrite(controlPin1, HIGH);
    digitalWrite(controlPin2, LOW);
    digitalWrite(controlPin3, HIGH);
    digitalWrite(controlPin4, LOW);
    analogWrite(enablePin, 255);
    analogWrite(enablePin2, 80);
}

if(val=='d'){ //Turn Left
    digitalWrite(controlPin1, HIGH);
    digitalWrite(controlPin2, LOW);
    digitalWrite(controlPin3, HIGH);
    digitalWrite(controlPin4, LOW);
    analogWrite(enablePin, 80);
    analogWrite(enablePin2, 255);
}

if(val=='e'){ //Do a U turn
    digitalWrite(controlPin1, HIGH);
    digitalWrite(controlPin2, LOW);
    digitalWrite(controlPin3, LOW);
    digitalWrite(controlPin4, HIGH);
    analogWrite(enablePin, 255);
    analogWrite(enablePin2, 255);
}

if(val=='f'){ //STOP
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, LOW);
    digitalWrite(controlPin3, LOW);
    digitalWrite(controlPin4, LOW);
}
delay(100);

}

Here’s a video of it working.

Making my boarduino board V0.3

I wanted to improve my Boatduino design :

  • By adding a bluetooth chip
  • By adding a reset bouton
  • By adding some indication on it

Licence Creative Commons
Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.