Unable to read data from an I2C Master that is always writing.

I am having trouble reading data from an I2C master called the AirChip 3000 that has the following specifications:

  1. The AirChip 3000 always acts as a I2C Master writing to the bus. After the START condition (S), a slave address is sent. In accordance with the I2C protocol, this address is 7 bits long followed by an eighth bit which is the data direction bit (R/W). With the AirChip 3000 this bit is always a ‘zero’ indicating a transmission (WRITE).The AirChip 3000 device sends a data string automatically with each data refresh cycle (unsolicited data), as opposed to waiting for a data request. To get the data, the receiving device must be listening at all times

  2. In spite of the fact that the I2C data string includes an address, the AirChip 3000 is not addressable and communication is limited to a single AirChip 3000 device (no networking of several devices, AirChip 3000 or other).

The code I am using on the arduino uno is from the I2C reciever tutorial:

// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop() {
  delay(100);
}

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

The Arduino is not printing anything to the serial monitor. I tried using an I2C scanner but I believe the nature of the Airchip 3000 makes it so that it cannot be probed using the scanner.

void receiveEvent(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
}

You must never call any method of the Serial object inside interrupt context. As your receiveEvent() routine is called in interrupt context, this might end in a infinite loop where the code waits for the serial data to be transferred but the hardware cannot do it because you’re in an interrupt handler and other interrupts are disabled.

So store you data into a variable, set a flag in the interrupt handler, then check for the flag in the main loop() and print the data then.

@OP

From where have you got all these stated specifications of your post? Please, make a link to that documentation… The AirChip3000 book says that the chip has a UART Interface.

airchip3000.pdf (252 KB)

@GolamMostafa, that is what the normal datasheet says, but then there is a hard to find newer datasheet.

Starting with firmware 1.3 there is a I2C option with: "The AirChip 3000 always acts as a I2C Master writing to the bus".

@uhhuhhuny, do you have a logic analyzer ? I think it is sending 6 bytes, but the 'howMany' parameter will tell how many bytes are received. You use address 8, is that programmable ? How do you know that it is 8 ? It is possible to stop the I2C with Wire.end() and start with a new Slave address with a new Wire.begin(). You could make a reverse-I2C-scanner: a sketch that listens on all I2C addresses. How often is it transmitted ? I can not find that in the datasheet. Can you set the chip back to UART communication ?

I have not heard of a reverse-I2C-scanner before, but I'm sure that it is possible. We only have to think of a better name for a slave-reverse-scanner-address-listener sketch. If the sensor transmits data every 5 seconds, then the sketch needs at least 5 * 128 = 11 minutes.

Thanks @Koepel for referring to the appropriate documents.

Yes, the AirChip is sending 6-byte data. It is also my question that how the slave address could be 8? It has to be configured within the AirChip or there should be a default slave address that could be used for the slave Arduino.

The OP may execute the following codes to see if any data bytes are arriving at Arduino at address 0x08.

#include <Wire.h>
volatile bool flag1 = false;

void setup() 
{
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop() 
{
   if(flag1 == true)
   {
       for(int i=0; i<6; i++)
       {
          byte x = Wire.read();
          Serial.print(x, HEX);     //printing hex values
          Serial.print(' ');  //insert space
       }
       flag1 = false;
   }

}

void receiveEvent(int howMany) 
{
   flag1 = true;
}