Pages: [1]   Go Down
Author Topic: I2C locking with any mor than 3 bytes sent  (Read 705 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have been switching over from I2C to RS485 serial for a project I have had working in the Arduino 022 revision days.  It appears that the 1.3 version of Arduino is giving me quite a head ache. 

One thing to note is that the sender is using Software Serial and the receiver is using FastSPI_LED code to run LED lights.  (www.facebook.com/ttoqe if you want to see the project).  I have run the FastSPI_LED for a long time with I2C communication with no issues.  FWIW, the SPI interrupt is higher precedence than the I2C interrupt.  The signal coming into the sender via SoftwareSerial (RS485) is read and then I2C is called to send the serial information to the LED driving arduino. 

I am trying to send out 4 bytes of information one arduino to the other.  If I send 2 bytes of information it works fine.  If I do 3 bytes of information and its locks up.

I have the pullup code on and have also just tried digital write for pull ups. 
Code:
pinMode(SDA,INPUT_PULLUP);
 pinMode(SCL,INPUT_PULLUP);

Here is the sender code.  All variables are a single unsigned byte:
Code:

void ContactAll()
{

Wire.beginTransmission(YOUR_ADDRESS); 

Wire.write(Choice);
Wire.write(Cur_Colormult);

//Wire.write(Cur_direction);
//Wire.write(Cur_patternx);

Wire.endTransmission() ;
delay(5);
}

Here is the receiver code:
Code:
void receiveEvent(int howMany){
 
    while(Wire.available()){
      for(readit=0;readit<howMany;readit++){
     data[readit]= Wire.read();
    Serial.print("received ");
     Serial.print(readit+1,DEC);
     Serial.print(" value=");
      Serial.print(data[readit],DEC);}}
 
}

I have attempted significant delays (3ms) after the Wire.read()s thinking slower might be better.

When I hook up the logic analyzer when sending 3 bytes, it shows it sending the signal one time and then the second time it shows the address of what is being sent and then both SCL and SDA go low and stay that way... 

When I look at the logic when sending 2 bytes, everything looks normal and chugs right along...

Any ideas?  Any help is much appreciated...  Been working on this for 10+ hours and not seeming to get anywhere!



Logged

Offline Offline
Edison Member
*
Karma: 43
Posts: 1551
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The receiver code is reading bytes even if there are none available.
If Wire.available() is non-zero it only means that there is at least one byte available - not that there are however many you need.
Try this (and note how it is been reformatted):
Code:
void receiveEvent(int howMany) {
  for(readit=0;readit<howMany;readit++) {
      // Wait for an available byte
      while(!Wire.available());
      // read it
      data[readit]= Wire.read();
      Serial.print("received ");
      Serial.print(readit+1,DEC);
      Serial.print(" value=");
      Serial.print(data[readit],DEC);
  }
}

Pete
P.S. this is a programming problem. Nothing to do with installation.
Logged

Where are the Nick Gammons of yesteryear?

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for this help Pete!  I like this approach much better and don't wonder if this was a cause of some of my lockup issues before... The main code does a lot of parm checking between the reads...

However, its not fixing the problem. 

It still locks up on the second I2C write 95ms after the first. 

First write is shows up on logic analyzer as would expect and second just has the address byte then holds both SDA and SCL low.


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the first write:
http://docs.google.com/file/d/0B7mKIsk9qKREcEdqRGtqdzFBSUU/edit
Here is the second write:
http://docs.google.com/file/d/0B7mKIsk9qKRESU9Sc0o3TlJzRTQ/edit
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is wrong:

Code:
while(Wire.available()){
      for(readit=0;readit<howMany;readit++){

If howMany is non-zero then you don't need to test Wire.available. In fact you don't need to test it anyway. Just read howMany bytes.

Second, don't do serial prints inside an ISR which is what receiveEvent is, in effect.

You will get away with some prints before it locks up (64 bytes I think) but your rather wordy debugging prints will, I estimate, use about 20 or so bytes each incoming byte. So after 3 incoming bytes the outgoing serial buffer will fill up and it will wait for interrupts to empty it, which won't happen because interrupts will be turned off.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I have attempted significant delays (3ms) after the Wire.read()s thinking slower might be better.

Adding delays will make things much, much worse. Using delay() inside an ISR is not recommended, and is quite likely to hang the code as it waits for the time to elapse, which it won't notice because the timer is not checked inside an ISR.

Once you are in the receiveEvent all the data is available. You don't need to do Wire.available, you don't need to delay. It's all there waiting in the Wire buffer.

However as I said above you can't do serial prints ... well you can, if you don't mind the program hanging. smiley-wink
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks so much for the advice... I will be spending the day tomorrow working on it..I WILL BE LESS WORDY!  I will report back. 

As always...
Workinonit!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This seems to work!  Removing all the serial comm and everything seems to be working!  Thanks so much for the help! 

I would only normally have that in the code during development.  Then remove it later...I will be taking it into consideration for future testing!

As always...
Workinonit!
Logged

Pages: [1]   Go Up
Jump to: