Whatis wrong with this Writer-Reader sketch?

I made a project by two UNO, the first one used 2 potentiometers as analog input, then send the ADC data to the second UNO via IIC, the second UNO use these data as input to 2 servos. And, my reference is here - Master Writer/Slave Receiver

the Writer code:

#include <Wire.h>

int potentioMeter2 = 0;
int potentioMeter1 = 0;

byte potentialSend1 = 0;
byte potentialSend2 = 0;

void setup()
{
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  
  Wire.begin(); // join i2c bus (address optional for master)
}

void loop()
{
  potentioMeter1 = analogRead(A0);
  potentioMeter2 = analogRead(A1);
  
  potentialSend1 = map(potentioMeter1, 0, 1023, 0, 180);
  potentialSend2 = map(potentioMeter2, 0, 1023, 0, 180);
  
  Wire.beginTransmission(0); // transmit to device #0
  Wire.write("Potential1 is: ");        // sends 15 bytes
  Wire.write(potentialSend1);              // sends one byte  
  Wire.endTransmission();    // stop transmitting
  
  Wire.beginTransmission(0); // transmit to device #0
  Wire.write("Potential2 is: ");        // sends 15 bytes
  Wire.write(potentialSend2);              // sends one byte  
  Wire.endTransmission();    // stop transmitting
 
  delay(10); // Delay a little bit to improve simulation performance
}

the Reader code:

#include <Wire.h>
#include <Servo.h>

Servo myServo1;
Servo myServo2;

void setup()
{
  Wire.begin(0);                // join i2c bus with address #0
  Wire.onReceive(receiveEvent1); // register event for myServo1
  Wire.onReceive(receiveEvent2); // register event for myServo2
  Serial.begin(9600);           // start serial for output

  myServo1.attach(5);
  myServo2.attach(6);
}

void loop()
{
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent1(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
  myServo1.write(x);
}

void receiveEvent2(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
  myServo2.write(x);
}

now, the problem is, when I started simulation, I found there was value in the first UNO, and there wasn't value in the second UNO, what maybe the reason for this situation?

Try understanding the Wire library, you can specify only 1 receiveEvent handler.

Start with only transferring the values without text.

Finish with hardware instead of only simulation. Heaven knows how the simulator implements I2C.

2 Likes

The address '0' is a special broadcast address. I think you should try some different address.

1 Like

Yes, I changed it from "0" to "1", then the date could be transferred - when I turning one of the 2 potentiometers, one of the 2 servos was twisting.

I found the 2 receiveEvents were all works - I could see the 2 data flow changing in the Serial Monitor, but only one Servo moving, the other fixed in most of the time, and some time would just sweep a little.

Only in your imagination :frowning:

Exclude one and you'll still see all data in Serial Monitor but only one servo reacting.

I'm sorry to say, but the official examples by Arduino are wrong.
We don't use readable text with variable length for I2C. Since the I2C bus is not a stream of data, but packages of data.

I agree with DrDiettrich, it is easier to transfer fixed size binary packages.
You could for example transfer an array of 2 integers.

I2C address 0 is the special "broadcast" address.
There are other special addresses, but those are not used on the Uno board. Most Arduino examples start with I2C address 8.

Do you use Tinkercad ? Can you give a public link to your project ?
Don't use the URL of your browser, that is private and can not be opened by others. There is perhaps a button somewhere to share your project.

Right.

Thanks.

I think that you used a "Send To" for a shared project instead of a public link.
Is that a shared project now ? I can not make a copy for myself of it and I can not store it to my own projects.
I have added a GND wire between the Arduino boards and two text labels. Can you see that ?

You might want to remove that link in your Reply #10 or someone else might change things.

Can you change the sketch to transfer a block of binary data with a fixed size ?

Yes, I saw your GND and text labels. How to make this project shared?
Could you make a copy of it now? I have clicked "Invite people" - "Generate new link" in "Send to".

That was indeed inviting others to take part in your project.
I rather make a new project to show an example and let you fix your own project.
There should be an option to make a public link, but I don't know how to do that.

You can try to improve your sketches and show them here. That is better for everyone. I just happen to use Tinkercad now and then, but most others don't.

It was said:

That is the same "share your project with others" link. I can not even save that to my own projects in Tinkercad. Please remove this link as well from this forum.

I can not find that link to make it public. Tinkercad has changed that, and not for the good. There is an option in the settings to make a project either public or private.

I'm a fan of Wokwi: https://wokwi.com/
They don't support two Arduino boards at the same time yet.