Working on a project that will require an esp32 to send a number to a mega. based on that number when the esp requests data the mega will send one of 2 dataPackages. I can get the esp to read the mega and get a dataPackage but I can't get the mega to read a number sent by the esp. Going back to basics I have a script on the esp that just sends a number and one on the mega that only reads (or should read) the number sent. Thanks.
include <Wire.h>
uint8_t x=0;
uint8_t xold=0;
void setup()
{
Wire.begin(0x55); // join i2c bus with address #55H
Wire.onReceive(receiveEvent); // register event
Serial.begin(115200); // start serial for output
}
void loop()
{
if (x > xold){
Serial.println("");
Serial.print("new x = ");
Serial.println(x);
if (x>5){
Serial.print("x=");
Serial.println(x);
Serial.println("");
}
xold=x;
Serial.println("");
Serial.println("");
}
delay(100);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
//byte* ptr1 = (byte*)&x;
Serial.print("howMany = ");
Serial.println(howMany);
x=Wire.read();
Serial.print(x);
Serial.println("");
}
To test something, you need to go to the basics. Make a test sketch that has no extra things.
This: "if (x > xold){" makes things harder. Just print the value.
We use a flag. With that flag, there is no need for a delay() in the loop(). If the flag is set, then process the data.
// global variable
volatile bool newData;
void loop()
{
if (newData)
{
// do something with the new data
Serial.println( x);
newData = false;
}
}
void receiveEvent(int howMany)
{
x = Wire.read();
newData = true;
}
A few more things to consider:
The Arduino Mega has a 5V I2C bus with 10k pullup resistors to 5V and it needs 3.5V for SDA and SCL to see it as a logic high. The ESP32 does not have 5V tolerant pins. You need a I2C level shifter.
Please don't use a string or printf() with the I2C bus. Use binary data and fixed size packages. Use Wire.write().
The final version should not have Serial functions in the interrupt routines such as receiveEvent().
Why use the I2C bus ? Can you use a Serial bus ?
Did you know that the GND wire is the most important wire of the I2C bus ?
'printf' or 'print' will take your one-byte 'uint8_t' variable and turn it into one to three human-readable ASCII characters: "0" through "255". That means at the other end you have to read the 1 to 3 characters and turn them back into a machine-readable number.
Use Wire.write(i++); to send the one byte as one byte. Your receiving code should then get the correct value.
I am aware of the different voltages. Have a level translator between.
Was using printf because that was the example I could find.
Final version will not have any serial functions. Only there now for debug.
Already have the two connected using an i2c. Planning on adding additional sensors using i2c so I don't have to have a one-two-one connection. just connect another to the bus.
and yes, I am well aware of the importance of ground.
So I can ha e multiple items use the same interface. all are no more than 6 inches apart. I thought i2c was for processors to communicate with each other.
It's more suited for processors to communicate with things like sensors and memory. If it were my project I'd use UART for the inter-processor Comms and I2C for peripherals.