0

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'

  • A possible problem is that you are doing an analogRead inside an ISR. ISRs are supposed to be fast, and an analogRead will take over 100 µs. Try doing the analogRead inside loop, and just send the latest reading in the sendSensor function. My (main) computer is currently doing an operating system upgrade, so I can't test this right now. – Nick Gammon Jan 26 '17 at 8:00
  • I'm wondering if I have to add a "Wire.begin(8);" at the slave program setup. - you did that, since my_address is 8. – Nick Gammon Jan 26 '17 at 8:02
  • Regarding my first comment, it looks like my code that you referenced does that as well (grin). – Nick Gammon Jan 26 '17 at 8:04
  • @NickGammon for this case I would like to know for void sendSensor (const byte which) { int val = analogRead (which); in the slave code, where is the which parameter passed? – bytk Jan 27 '17 at 2:02
  • Here: sendSensor(A0); – Nick Gammon Jan 27 '17 at 4:06
2

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 Jan 27 '17 at 2:14
  • @bytk - Are you saying it is working now? That the whole problem was a missing ground wire? – Nick Gammon Jan 27 '17 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 Jan 27 '17 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 Jan 27 '17 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.