Random SMBus IOError when writing to an Arduino Slave

This is my first embedded systems project and my first request for help from a forum.

Basically the goal is to get a Christmas light show as directed by the Pi playing a song over FM transmission while parsing a .csv file (the script of lighting control) using a python script. The Pi would send I2C bytes to addressable Arduino slaves (eventually just atmega328P MCUs) which will perform AC phase control on a set of Christmas lights (Wire library on Arduino and SMBus on the Pi). The intent is that the Pi would send a byte to a unique Arduino address to indicate the level of brightness for the lights (i.e. 0-full brightness, 100-full dim, 101-255 commands reserved for basic fade up/down at various rates). The AC phase control works on the Arduino, no real issue there albeit with 2 interrupts (the zero crossing detection and Timer1 for TRIAC control) perhaps this is part of the problem? I've read that the Wire library also uses interrupts, perhaps the problem lies there, as interrupts are conflicting?

I have successfully written information to the Arduino slave, however I continue to get random and unexplainable IOError as follows:

I've tried my code with and without the Arduino internal pulll-up resistors disabled, with and without 4k7 external resistors. The Pi and Arduino are connected using the adafruit bi-directional level shifter. I've tried writing at slower speeds (just by modifying the sleep variable).

I honestly just picked this whole thing up as a hobby no more than 3 months ago with a Sparkfun Arduino Uno kit and got hooked. I've learned a ton in that short time, I'm worried though that the solution to this problem may involve either an oscilloscope and or data analyzers which I obviously do not own or even know how to use.

I'm not committed to using python as the controlling script (in fact I have more experience with Java) and it seems that the documentation for the SMBus is lacking. Does anybody have better luck using Java as the I2C controlling language?

int freqStep = 83; // This is the delay-per-brightness step in microseconds.// It is calculated based on the frequency of your voltage supply (50Hz or 60Hz)// and the number of brightness steps you want. // // The only tricky part is that the chopper circuit chops the AC wave twice per// cycle, once on the positive half and once at the negative half. This meeans// the chopping happens at 120Hz for a 60Hz supply or 100Hz for a 50Hz supply.

// To calculate freqStep you divide the length of one full half-wave of the power// cycle (in microseconds) by the number of brightness steps. //// (1000000 uS / 120 Hz) / 128 brightness steps = 65 uS / brightness step//// 1000000 us / 120 Hz = 8333 uS, length of one half-wave.

void setup() { // Begin setup pinMode(AC_pin, OUTPUT); // Set the Triac pin as output attachInterrupt(0, zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need Timer1.attachInterrupt(dim_check, freqStep); // Use the TimerOne Library to attach an interrupt // to the function we use to check to see if it is // the right time to fire the triac. This function // will now run every freqStep in microseconds. pinMode(9, OUTPUT); digitalWrite(9,HIGH);

I have been struggling for a few hours with this same problem, and i stumbled upon a very simple work around. I thought it was novel enough to create an account here just to share with you guys. So here it is, as succinctly as possible.

See my diagnostic output for context.

I wrote a short python script which sends the same 24 bytes to the arduino, the arduino then sends it back.If we see the same data we transmitted echoed back to the pi that confirms the data was received correctly.

The pattern below, which begins in 254 and ends with 255, is the arduino echoing back the data pattern it was sent

The write function then pops IOError5, usually ending the program. I found if I ran i2cdetect there is a device showing at 0x03 that does not exist. The arduino is the only device on the bus at 0x4a. I have no idea what causes this to pop up. You can also see the corrupted data below the output of i2cdetect.

Without calling i2cdetect, reattempts to write to the i2c bus cause the arduino to disappear from the bus completely and have to be reset before being accessible.

The ********important******** part is that i noticed calling i2cdetect seems to somehow help clear/reinitialize the i2c connection.Instead of the arduino disappearing from the bus like it had been. If a subprocess call is made to i2c detect during the error handling routine, the bus errors seem to be cleaned up and the program can continue reading/writing for a 400-1000 more cycles before again needing to call i2c detect.

This method even ensures that all transmissions to the arduino from the pi are error free. with minor alterations and another pass of the message back and forth it could easily check errors in the other direction as well.