I know this problem has been talked about here in many posts but try as I might I can't get this working. From my Master, I want to request an integer value from a Slave but all I'm getting in the Serial Monitor is "-1" when it should be 9.
Master
#include <Wire.h>
int numPWMChannels = 0;
void setup() {
Wire.begin(); // join I2C bus (address optional for master)
Serial.begin(9600); // start serial for output
}
void loop() {
Wire.requestFrom(2, 2); // request 2 bytes from secondary device #2
byte x1, x2;
x1 = Wire.read(); //x1 holds upper byte of received numPWMChannels
x2 = Wire.read(); //x2 holds lower byte of received numPWMChannels
numPWMChannels = (int)x1 << 8 | (int)x2;
Serial.print("numPWMChannels: ");
Serial.println(numPWMChannels);
delay(500);
}
Slave
#include <Wire.h>
int NUM_PWM_CHNLS = 9;
void setup() {
Wire.begin(2); // join I2C bus with address #2
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(highByte(NUM_PWM_CHNLS));
Wire.write(lowByte(NUM_PWM_CHNLS));
}
I don't have any pull-up resistors on SDA/SCL. The GNDs are connected together. I've been using i2c with the Wire library quite successfully until now - the only problem is sending/receiving integer values.
Low value pullup resistors are absolutely required for I2C to function reliably. They are part of the bus specification! Add 4.7K resistors from Vcc to SDA and SCL, and try again.
The internal pullups (typically 10K to 30K) are enabled by default and sometimes they are enough, but not in most situations. Especially not when you have long wires (> 10 cm) connecting master and slave.
2. If Slave is not found, then power down of both Arduinos. Connect 2x4.7k or 2x10k pull-up resistors with I2C Bus at the Master side. Power up both Arduinos and then press RESET buttons of both Arduinos.
3. If wiring is correct and the Arduinos are healthy, you must see the following message on the SM of Master.
There is no need to execute Wire.available() instruction as the requestFrom() method waits until all the requested data bytes are in Master's FIFO Buffer.
@RossAWaddell sometimes a bunch of different opinions flood a topic, causing only confusion. In this topic however, there are only good suggestions. You have to try a few things and give more information. Please read all the replies once more and follow the suggestions. At this moment your Master and Slave are not communicating, there is no I2C bus between them.
That's likely a clue. Wire is an instance of the TwoWire class. That inherits from the Stream class. The Stream class's read() function returns -1 if there's not an actual byte to read. So, I'd first try printing the value of Wire.available() to see if the library thinks there's anything to read.
Next, I'd get a Low-Cost Logic Analyzer and start snooping to see what's actually happening on the I2C bus.
In my project I have two slaves connected to the one master - do I need two sets of 4.7k resistors on each board, or can I have just one set on the SDA & SLC on the master?
With the Wire.requestFrom() you are trying to read from the Slave, but the Master can not find the Slave and stops the I2C session and returns zero for Wire.available().