0
$\begingroup$

I am working on a wheel mobile robot with multiple sensors which are IMU, two encoders, four ultrasonic sensors, and using two Arduino: Uno and Mega. The IMU, encoders, and ultrasonic sensors are connected to Arduino Mega while the motor controller with every other sensor attached to the robot is connected to the Arduino-Uno. The Uno is attached to the robot by the manufacturer and nearly all the pins have been used or attached to a function on the robot. To use I2C to communicate these two Arduinos I connect SDL to SDL, SDA to SDA, GND, and VCC. Do I need to connect two separate Arduino USB cables to the Arduino simultaneously? Also, do I need to attach these lines of code from each Arduino before I can further write the codes? Attached below the slave and then the master code

// Include the required Wire library for I2C<br>
#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(8); 
  // 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);
  }
  //If value received is 3 blink LED for 400 ms
  if (x == 1) {
    digitalWrite(LED, HIGH);
    delay(400);
    digitalWrite(LED, LOW);
    delay(400);
  }
  if (x == 2){
    digitalWrite(LED,HIGH);
  }
}

this is the master code

#include <Wire.h>

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

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
  Wire.beginTransmission(8);
  Wire.write(x);
  Wire.endTransmission();
  x++; // Increment x
  if (x > 3) x = 0; // `reset x once it gets 6
  delay(500);
}
$\endgroup$

2 Answers 2

1
$\begingroup$
  1. The code you provide is only to give you example on how 2 arduino communicate using I2C protocol. You will need to modify it so it can fully work as intended. You can modify it so Arduino Mega can send command to Arduino Uno and Arduino Uno can send sensor data to Arduino Mega

  2. When using I2C communication, you need common ground, so connect both arduino ground.

Edit (March 9, 2020)

  1. Example on reading sensor, processing it and send. Case : Arduino mega will receive range from SRF, if obstacle still far away it will keep moving. If it too close, robot stop.

Master.ino

#include <Wire.h>
const unsigned int TRIG_PIN=13;
const unsigned int ECHO_PIN=12;
int data;
byte buffer1, buffer2;

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
  //For SRF
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
}

int readSRF()
{
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  const unsigned long duration= pulseIn(ECHO_PIN, HIGH);
  int distance= duration/29/2;
  if(duration==0)
  {
    return -1; // if pulse from srf not found
  } 
  else
  {
    return distance;
  }
}

void loop()
{

  Wire.beginTransmission(4); // transmit to device #4
  //sending 2 byte, so u can have more resolution of data to send (if u want)
  int read = readSRF()
  if(read==-1)
  {
    send = 0; //Stop
  }
  else if(read<5)
  {
    send = 0; //Stop too
  }
  else
  {
    send = 2; // Move
  }
  buffer1 = send >> 8; //high order byte
  buffer2 = send;      //lower order byte
  Wire.write(buffer1);              // sends one byte
  Wire.write(buffer2);  
  Wire.endTransmission();    // stop transmitting

}

Slave.ino

#include <Wire.h>

byte temp1, temp2;
int setpoint;

void setup()
{
  Wire.begin(4); //Address of slave
  Wire.onReceive(receiveEvent); //point where the function that handle if data arrive to slave
}

void loop()
{
  if(setpoint == 0)
  {
  //some code to stop motor
  }
  else if(setpoint ==2)
  {
  //some code to run motor
  }
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  if(Wire.available() >= 2)
  {
    temp1 = Wire.read();
    temp2 = Wire.read();
    setpoint = ((unsigned int)temp1<<8)+temp2; //combining 2 bytes
  }
}
$\endgroup$
5
  • $\begingroup$ thanks for your response but can u guide me on how to achieve that. the common ground and VCC are connected $\endgroup$ Commented Apr 8, 2020 at 23:36
  • $\begingroup$ what I intend to do with Arduino Uno is to control the wheel movement while the mega housing the sensor pin such as imu, encoder, the ultrasonic sensor. pls, how do I achieve this communication between these two sensors? $\endgroup$ Commented Apr 9, 2020 at 4:03
  • 1
    $\begingroup$ is the encoder fixed to arduino mega? it easier to control motor if motor and encoder on the same microcontroller $\endgroup$
    – Albert H M
    Commented Apr 9, 2020 at 11:28
  • $\begingroup$ i have give example of i2c communication on my answer.. feel free to ask if something still unclear $\endgroup$
    – Albert H M
    Commented Apr 9, 2020 at 11:54
  • $\begingroup$ @ Albert H M, am trying to work with the example you posted above as guideline. I believe the master Arduino transmits to the slave while the slave reads out the data. if I want to print out data from the ultrasonic sensor above, am I got to use slave ino print $\endgroup$ Commented Jun 5, 2020 at 11:43
0
$\begingroup$

Dronebot workshop has a good video on communicating with I2C between two Arduinos; https://www.youtube.com/watch?v=PnG4fO5_vU4

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.