With reference from http://www.gammon.com.au/i2c I tried the example there. However I am getting the wrong response and readings. At startup the Master will request for slave address. I should get a reading of "8" but I don't get it. Subsequently, A0 on the slave is connected to a miniature solar panel, that I have tested and it is working, however I keep getting a value -1 from it. No doubt I did modify a little bit to suit my inputs not sure if what I did affected the program.
This is the master code:
#include <Wire.h>
const int slaveAddressA = 8;
enum {
cmd_slaveAddress = 1,
cmd_read_A0 = 2,
cmd_read_A1 = 3
};
void sendCommand_toSlaveA (const byte cmd, const int responseSize)
{
Wire.beginTransmission(slaveAddressA);
Wire.write(cmd);
Wire.endTransmission();
Wire.requestFrom(slaveAddressA, responseSize);
}
void setup() {
Wire.begin();
Serial.begin(9600);
sendCommand_toSlaveA(cmd_slaveAddress, 1);
if(Wire.available())
{
Serial.print ("Slave address is: ");
Serial.println (Wire.read (), DEC);
}
else
{
Serial.println ("No response to slave address request");
}
}
void startupTest() {
Wire.beginTransmission(slaveAddressA);
}
void loop() {
int val;
sendCommand_toSlaveA(cmd_read_A0, 2);
val = Wire.read();
val <<= 8;
val |= Wire.read();
Serial.print("Value of A0: ");
Serial.println(val, DEC);
delay(500);
}
This is the slave code:
#include <Wire.h>
const byte my_address = 8;
enum{
cmd_address = 1,
cmd_read_A0 = 2,
cmd_read_A1 = 3
};
char command;
void setup() {
command = 0;
pinMode (A0, INPUT);
digitalWrite (A0, LOW); // disable pull-up
pinMode (A1, INPUT);
digitalWrite (A1, LOW); // disable pull-up
Serial.begin(9600);
Wire.begin (my_address);
Wire.onReceive (receiveEvent); // interrupt handler for incoming messages
Wire.onRequest (requestEvent); // interrupt handler for when data is wanted
}
void loop(){
//everything is done using interrupts
}
void receiveEvent(int howMany)
{
command = Wire.read();
}
void sendSensor (const byte which)
{
int val = analogRead (which);
byte buf [2];
buf [0] = val >> 8;
buf [1] = val & 0xFF;
Wire.write (buf, 2);
}
void requestEvent ()
{
switch (command)
{
case cmd_address: Wire.write(0x55); break; // send slave address
case cmd_read_A0: sendSensor(A0); break; // send A0 value
case cmd_read_A1: sendSensor(A1); break; // send A1 value
}
}
Also I'm wondering if I have to add a "Wire.begin(8);" at the slave program setup. ---------------------------I would like to know what did I do wrongly?
UPDATE: The 2 boards are now communicating with one another. However, requested address gives a '85' instead of an '8'. As for input A0, for example it should show '700' with a little bit of variant, but now it shows a repeated pattern of e.g '0 0 0 400 500 800 1040 1040 1040 800 500 400 0 0 0'
1 Answer 1
When you send 'buf', how do you know that buf[0] is transmitted first and buf[1] is transmitted second ? Not long ago a bug in Wire library was fixed and it is now allowed to use multiple Wire.send() in the requestEvent() function. I suggest to send two bytes in sendSensor() in the Slave without using the 'buf'.
When you request the Slave addres, you send 0x55. That is not the Slave address. Do you receive 0x55 ?
It is not needed to remove pullup resistors from the analog input pins. It is also not needed to set the pinMode for those pins. You can use analogRead() without something else.
Did you connect the GNDs ? And did you connect SDA to SDA and also SCL to SCL. Which Arduino boards do you use ? Do you know that you can start the Arduino IDE twice, each connected to a board and each with its own serial monitor. That way you can work on both sketches at the same time. As soon as the Slave is running with Wire.begin(8), the Master can run a i2c_scanner and it should find I2C address 8. That is the first test to verify that the I2C bus is working.
-
I have checked that the master and slave are indeed connected and working. I missed out the GND connection. The slave address i received is 85 instead.bytk– bytk2017年01月27日 02:14:11 +00:00Commented Jan 27, 2017 at 2:14
-
@bytk - Are you saying it is working now? That the whole problem was a missing ground wire?2017年01月27日 04:06:43 +00:00Commented Jan 27, 2017 at 4:06
-
@NickGammon It is communicating with each other now, but it doesn't communicate correctly. As mentioned now the requested address gives a '85' instead of a '8' as for input A0, for example it should show '700' with a little bit of variant, but now it shows a repeated pattern of e.g '0 0 0 400 500 800 1040 1040 1040 800 500 400 0 0 0'bytk– bytk2017年01月27日 17:34:46 +00:00Commented Jan 27, 2017 at 17:34
-
The slave address is not returned, but the value 0x55. That is decimal 85. Reading analogRead() while the input is open, can result into anything.Jot– Jot2017年01月27日 18:08:12 +00:00Commented Jan 27, 2017 at 18:08
analogRead
inside an ISR. ISRs are supposed to be fast, and ananalogRead
will take over 100 µs. Try doing theanalogRead
inside loop, and just send the latest reading in thesendSensor
function. My (main) computer is currently doing an operating system upgrade, so I can't test this right now.my_address
is 8.sendSensor(A0);