connect 2 arduino board with ic2 Serial communication

Hi guys
I am trying to develop a small project, connecting 2 arduino boards In Tinkercard, with one input device on the master, that and one output on the slave that should display the signal, an example of what I am trying to do can be a temperature sensor, with an led on the slave, that turn of if a temperature is higher than a value, and turn off if is lower. I have coded the master and the slave but the 2 arduino and added master and code slave but they do not connect
Here the code, I have now an ultrasonic distance sensor in the master, and a LED in the slave, . I would like to turn the led on, when the distance sensor shows an X distance. otherwise it should be turned off, but seems that the 2 arduinos can not connect:
Master code:
<// Include the required Wire library for I2C

#include <Wire.h>
int x = 0;
void setup() {
Serial.begin(9600);
// 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++; // Increment x
if (x > 5) x = 0; // `reset x once it gets 6
delay(500);
}>

SLAVE CODE <
// Include the required Wire library for I2C

#include <Wire.h>
int LED = 13;
int x = 0;
void setup() {
Serial.begin(9600);
// 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);
}
//If value received is 3 blink LED for 400 ms
if (x > 3) {
digitalWrite(LED, HIGH);
delay(400);
digitalWrite(LED, LOW);
delay(400);
}
}>

Any suggestions and help is highly appreciated. Thank you

Did you get the Wire library example codes to work before you wrote your code?

Read the how get the most out of this forum sticky to see how to properly post code. Remove useless white space and format the code with the IDE autoformat tool (crtl-t or Tools, Auto Format) before posting code in code tags.

I tried the posted codes on two of my (real) Unos. The code works. I inserted a serial print to see what is received. The slave gets:

0
1
2
3
4
5
0
1
2
3
4
5
0

and the LED turns on and off as expected.

Thanks for your advice. I post my code again without blank spaces, hope this help. I want to specify that the code works (LED and distance sensor are turning on, but they would even removing the arduino connecting cables, so there is an issue within the 2 boards I think), if I am not wrong, without touching the ultrasonic sensor (0), the led should be off, and turn on when the ultrasonic sensor get a signal, but the led works even without touching the sensor. Hope someone can help, or if you know where to check a similar small project please let me know. below my code:
Master code:
<// Include the required Wire library for I2C

#include <Wire.h>
int x = 0;
void setup() {
Serial.begin(9600);
// 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++; // Increment x
if (x > 5) x = 0; // `reset x once it gets 6
delay(500);
}>
SLAVE CODE <
// Include the required Wire library for I2C

#include <Wire.h>
int LED = 13;
int x = 0;
void setup() {
Serial.begin(9600);
// 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);}
//If value received is 3 blink LED for 400 ms
if (x > 3) {
digitalWrite(LED, HIGH);
delay(400);
digitalWrite(LED, LOW);
delay(400); }}>
Thank you for your help

Read the how get the most out of this forum sticky to see how to properly post code.

When posted in code tags the code will look like this:

// Include the required Wire library for I2C

#include <Wire.h>
int x = 0;
void setup() {
 Serial.begin(9600);
 // 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++; // Increment x
 if (x > 5) x = 0; // `reset x once it gets 6
 delay(500);
}

To post in code tags, highlight the code and click on the </> in the left end of the menu bar (next to the B).

There is nothing relating to an ultrasonic rangefinder sensor in your code.

using the begin.Trasmission, the connected sensor should not send the signal to the slave and the led? Or am I missing any line of code for this? As I said, I am a beginner so what I am saying could be wrong.

We are talking about two real Arduino boards.

TinkerCad is not bad, I use it myself and I like it.

You should see this as one block of code:

Wire.beginTransmission(9);
Wire.write(x);
Wire.endTransmission();

As soon as you assume that Wire.beginTransmission() does something, then you are probably wrong. The Slave has the data when that block of code has finished.

yes, this is the part of the slave code where it says what output the led should have based on X value. But even if I change to LOW LOW, so in one condition should stay off, the led keeps blinking changing the input, so I assumed that the two boards are not connected, or is there anything else wrong? I tried in many ways but I could not figure out the problem

 Wire.onReceive(receiveEvent);}[color=#222222][/color]
void receiveEvent(int bytes) {[color=#222222][/color]
 x = Wire.read();    // read one character from the I2C}[color=#222222][/color]
void loop() {[color=#222222][/color]
 //If value received is 0 blink LED for 200 ms[color=#222222][/color]
 if (x == 0) {[color=#222222][/color]
   digitalWrite(LED, HIGH);[color=#222222][/color]
   delay(200);[color=#222222][/color]
   digitalWrite(LED, LOW);[color=#222222][/color]
   delay(200);}[color=#222222][/color]
 //If value received is 3 blink LED for 400 ms[color=#222222][/color]
 if (x > 3) {[color=#222222][/color]
   digitalWrite(LED, HIGH);[color=#222222][/color]
   delay(400);[color=#222222][/color]
   digitalWrite(LED, LOW);[color=#222222][/color]
   delay(400); }}

I'm sorry, but even if I remove the color-things, then I can not make anything of that code.
Can you show a screen dump of your TinkerCad ? So we can see the wiring.
There is a way to make a TinderCad project public and share it with a certain link (I forgot how).

here is the project link, basically what I would like to do, is to make the led blink when the ultrasonic sensor has the green area on, when it is out of the green area the led should stay off. Or I could even change the ultrasonic sensor with a thermometer, and based on the temperature I keep the led on or off. Is anything missing in the code?

That link does not work for me. When you are in the editing workspace (tinkering), then there is a "Share" button in the upper-right corner. Or you can change the settings and set Privacy to Public.

Just tried generating an invite link in tinkercard, let me know if this works

thank you

I'm not sure how picky tinkercad is with interrupts, receiveEvent() is called by an interrupts handler, so the variable x should be declared as volatile.

checking the invite link that I shared, do you think that the issue is in the arduino connections or the other part of the code? Do you have any suggestions about where I can check similar projects to find the issue or check how to fix it? Thanks

I have a list of things:

  • You really should show the picture and both sketches here in the forum.
  • In the Slave you should make the variable 'x' volatile as david_2018 already wrote.
  • See the number that is sent by the Master as a command. What should the Slave do ? Suppose the Slave should do nothing when nothing is received. You can use value 0 for that. Suppose a value of 1 is fast blinking and 2 is slow blinking. If you want to turn the led off, then make the value 0 after the blink.
  • You have to use a resistor with a led. For example a resistor of 220Ω.
  • If you create a new circuit, then select Starter, Arduino, and select the ultrasonic distance sensor. If you understand how it works, then you can add it to your sketch.

I did a check and seems that the issue is in the master board code, that send the signal when I start the program even before touching the ultrasonic sensor, if I change in the below code 1 with 0, the signal does not go to the slave starting the simulation, I need to find a way to send the signal only when I put the ultrasonic sensor on the green area, and not when I start the simulation, I assume this is just a code question, I realized that the two boards are connected.

x++; // Increment x
  if (x > 1) x = 0; // `reset x once it gets 6
  delay(500);}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.