Unstable I2C communication

Discussion about Z-Uno product. Visit http://z-uno.z-wave.me for more details.
Post Reply
jucs
Posts: 35
Joined: 28 Dec 2016 17:56

Unstable I2C communication

Post by jucs »

Hello everyone,

I'm having trouble establishing a stable communication between the an AVR and Z-Uno using the Wire library. I was trying to use the AVR for ADC readings (as the ADC of the Z-Uno currently doesn't work after Wakeup). However, I'm having the following problems:

* If I run the AVR at 16Mhz, the communication randomly works or doesn't work. I would say it works in about 80% of the cases.
* If I run the AVR at 8Mhz (which is the maximum for 3.3V according to the manual), the communication always fails.

There are no communication problems when I use the an Arduino Due as communication partner instead of the Z-Uno (at both 8 and 16Mhz), so it seems like the problem is rooted in the I2C implementation of the Z-Uno.

I have connected SDA, SCL and GND using jumper wires. Any ideas?

p0lyg0n1
Posts: 181
Joined: 04 Aug 2016 07:14

Re: Unstable I2C communication

Post by p0lyg0n1 »

Hi,
Never try Arduino with Z-Uno as I2C slave. So, looks like it's time to do it... Anyway we fixed some problems during 2.0.7 in I2C already.
I will try your case before 2.0.8 release. Thank you.

jucs
Posts: 35
Joined: 28 Dec 2016 17:56

Re: Unstable I2C communication

Post by jucs »

Thanks :) To make it clear, in my setup the Z-Uno was the Master and the Atmega328p was the slave.

p0lyg0n1
Posts: 181
Joined: 04 Aug 2016 07:14

Re: Unstable I2C communication

Post by p0lyg0n1 »

I tried fixed Wire library with this:

Sketch that uploaded to my Arduino Mega 2560(I2C slave):

Code: Select all

#include <Wire.h>

#define COMMAND_READADC     0x40
#define COMMAND_PININ       0x20
#define COMMAND_PINOUTLOW   0x30
#define COMMAND_PINOUTHIGH  0x50
#define COMMAND_PINGET      0x70




void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
  Wire.onReceive(receiveEvent);
  Serial.begin(115200);
  Serial.println("Starting...");
}

void loop() {
  delay(100);
}

int last_result = 0;
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()

void receiveEvent(int howMany)
{
  if(Wire.available())
  {
    byte c  = Wire.read();
    byte pin = c &0x0F;
    c &= 0xF0;
    last_result = 0;
    switch(c)
    {
       case COMMAND_READADC:
         last_result = analogRead(A0+pin);
          break;
        case COMMAND_PININ:
          last_result = 1;
          pinMode(pin, INPUT_PULLUP);
          break;
        case COMMAND_PINOUTLOW:
          last_result = 1;
          pinMode(pin, OUTPUT);
          digitalWrite(pin, 0);
          break;
        case COMMAND_PINOUTHIGH:
          last_result = 1;
          pinMode(pin, OUTPUT);
          digitalWrite(pin, 1);
          break;   
        case COMMAND_PINGET:
          last_result = digitalRead(pin);
          break;   
    }
  } 
}
void requestEvent() {
  char my_buff[2];
  my_buff[0] = last_result >> 8;
  my_buff[1] = last_result & 0xFF;
  
  Wire.write(my_buff, 2); 
}
Sketch uploded to Z-Uno (I2C Master):

Code: Select all

#include <Wire.h>


#define COMMAND_READADC     0x40
#define COMMAND_PININ       0x20
#define COMMAND_PINOUTLOW   0x30
#define COMMAND_PINOUTHIGH  0x50
#define COMMAND_PINGET      0x70

#define MEGA_I2C_ADDR       8
#define MY_SERIAL           Serial0

void setup() {
  Wire.begin();                // join i2c bus with address #8
  MY_SERIAL.begin(115200);
  MY_SERIAL.println("Sketch is starting...");
}
byte last_error = 0;
word readADC(byte pin)
{
    word adc_val;
    Wire.beginTransmission(MEGA_I2C_ADDR);
    Wire.write(COMMAND_READADC | (pin & 0x0F));
    last_error = Wire.endTransmission();
    if(last_error != 0)
    {
        return 0xFFFF;
    }
    Wire.requestFrom(MEGA_I2C_ADDR,  2);

    adc_val = Wire.read();
    adc_val <<= 8;
    adc_val |= Wire.read();
    
    return adc_val;
}
word pinONOFF(byte pin, byte onoff)
{
    Wire.beginTransmission(MEGA_I2C_ADDR);
    if(onoff)
    {
      Wire.write(COMMAND_PINOUTHIGH | (pin & 0x0F));
    }
    else
    {
      Wire.write(COMMAND_PINOUTLOW | (pin & 0x0F)); 
    }
    last_error = Wire.endTransmission(); 
}
byte g_counter =0;
void loop() {

  pinONOFF(13, g_counter & 0x08);
  if(last_error != 0)
  {
     MY_SERIAL.print("I2C bus error (pinONOFF): ");
     MY_SERIAL.println(last_error);
        
  }

  byte i;
  for(i=0;i<7;i++)
  {
      word w =  readADC(i);
      MY_SERIAL.print("ADC ");
      MY_SERIAL.print(i);
      MY_SERIAL.print(" value:");
      MY_SERIAL.println(w, HEX);
      
  }
  g_counter++;

  delay(100);
}
They works great together now. We found problems with time intervals in I2C and fixed them. I tested updated Wire library with Arduino as slave, PN532 NFC reader (hope, we soon release library for it), AM2320 i2c temperature/humidity sensor (library will be added in 2.0.8) and it works correct in all cases.

ianakapilotlight
Posts: 2
Joined: 18 Nov 2017 13:06

Re: Unstable I2C communication

Post by ianakapilotlight »

Hello,

Does your code for the z-uno and arduino mega 2560 use all the available digitial & analogue pins on the mega 2560?

Thanks

Post Reply