Arduino nano hangs on I2C example after successfully receiving some frames

Hello,

I'm trying to read telemetry output of Hitec Aurora 9 module for remote controlled models.

I've used slave_receiver example from Arduino package and as it appeared to work I started to write my own routines to decode telemetry data. My program receives data, but stops after few seconds.

I've got back to slave_receiver example and albeit it receives more frames it stops in the same way like my sketch. I assume that sketch attached as an example to Arduino GUI is correct.

If I reset arduino with reset button it starts to receive again, but for a while. I2C transmitter is constantly on.

I've found something about strings which may clog the memory so I replaced them with printing only single char on serial to notify on frame receive. Haven't helped.

What can be wrong? Why it works on the beginning? Why, I think thoroughly tested example of slave_receiver, fails in my situation.

I'd be grateful for any tips.

Best regards
Kuba

I've found something about strings which may clog the memory so I replaced them with printing only single char on serial to notify on frame receive. Haven't helped.

Haven't posted any code, either.

What can be wrong?

See above.

Why it works on the beginning?

See above.

Why, I think thoroughly tested example of slave_receiver, fails in my situation.

See above.

I'd be grateful for any tips.

Probably not, but see above.

All the code is basically here http://arduino.cc/en/Tutorial/MasterWriter

The only change I made was Wire.begin(0); as transmitter has address 0.

Slave Receiver Code - Program for Arduino 2
// 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(0);                // join i2c bus with address #4
  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
}
void loop()
{
  delay(100);
}

Why? What possible reason is there for the delay()?

  while(1 < Wire.available()) // loop through all but the last

How would describe, in English, what this statement is doing?

  int x = Wire.read();    // receive byte as an integer

Why? Wire.read() does not return an integer. Why store the small value in a big variable?

A link to the device you are trying to read from would be useful.

Well... I used example published on genuine arduino.cc website to get rid of every mistake I could make. Please feed those question to example maker.

I've read some more posts and links inside them and I think I may try with different pull-up resistors. Not sure though why it works on the beginning then.

Please see my last comment.

Most of your questions were already answered in a text or are not really relevant. I'm trying to read I2C from Hitec Aurora 9 module:

I'm trying to read telemetry output of Hitec Aurora 9 module for remote controlled models.

It's described on:

I did not expect that someone has direct experience with this particular module. I rather asked for general experience on what can be checked in such a situation.

After digging in lots of posts I decided to try with variety of resistors, but I cannot do it right now.

I've added pull-up resistors (2k) between 5V pin and A4 and A5 and commented out pulling internal resistors by commenting out lines in twi.c library.

Result is exactly the same. Code noted in previous post taken straight from example hangs after few seconds.

I used different Arduino board. I even tried to run Blink example in order to check whether my board is not faulty and would hang whatever it does. It works.

I only confirm that it's connected with I2C because if I comment out Wire.onReceive(receiveEvent); then sketch doesn't hang (checked by constantly printing dot in a loop after delay).

I'm clueless...

Today I even tried to use the same code on Arduino Uno and effect is the same.

It seems that the problem lies in Aurora 9 module if two different versions of board behave the same way without evident reason in the code (as it's example from arduino.cc).

Any ideas how to track what's wrong?

I have to add that whenever I hit reset button on arduino serial monitor shows some received frames and hangs again. I would mean that Aurora is constantly transmitting, but...

Please help..

Any ideas? I'm stuck...

Can you describe or better post a drawing of how you wired everything up? This would help to understand what exactly you are doing because at the moment I'm not sure if you just have a Master/Slave I2C setup or if your have any RF module in between. In the later case it's possible that the RF modules get stuck and your Arduino is still working properly.

There are only 3 wires between arduino and I2C master (radio control transmitter for models outputs I2C at the back and that's what I'm reading - there's no radio transmission between master and arduino slave.

There are 3 wired between Arduino and I2C master? The Arduino should be the I2C master, shouldn't it?

If there is no radio transmission between Arduino 1 and Arduino 2, there must be a wired connection. Are that the 3 wires? If yes from where to where are they going? How long are the wires? Are the 2k pullups still in use? At which side are they installed?

Connected devices:

  • Hitec Aurora 9 module which outputs I2C on 3 pin connector at the back
  • Arduino Nano v3
  • wires about 10cm in length

Power:

  • Aurora powered from its battery, battery is 7,2V Lipo
  • Arduino powered through USB port.
  • GND is connected between devices

I2C voltage:

  • 3,5V on Aurora
  • 5V on Arduino - reduced with external pull-up resistors to 3,5V

I2C roles:

  • Aurora is master by manufacturer design, I have no influence on that,
  • Arduino is set as slave on channel 0.

Tests:

  1. Aurora + Arduino with 3 wires, internal pull-up resistors -> few frames received then hang

  2. Aurora + Arduino with 3 wires, internal pull-up resistors disabled by commenting out two lines in twi.c, external pull-up resistors to have 3,5V on Arduino -> few frames received then hang

  3. Aurora + Arduino with 3 wires, variety of external resistors tested -> few frames received, then hang

  4. Aurora + Arduino with 3 wires, internal pull-ups disabled and no external ones -> nothing is received

I assume that wires are connected as they should because I do receive some proper frames (format of those few received matches what is documented to be send by Aurora).

Pull-up resistors are connected between I2C lines of Arduino and +5V pin on Arduino.

Ah... and I use Arduino 1.0.0 IDE on Windows 7.

Do you have a link to the manual with the description of the I2C interface the transmitter should support? The link you posted is not for an Aurora 9 but for a Spectra 2.4GHz Module. The manual for the Aurora 9 I found on the Internet does say nothing about an I2C interface. You must have some sort of specification how your Arduino is being called. I have the impression you're mixing some stuff up, based on the wording. I2C has addresses and not channels. I2C uses two lines, data and clock (as well as the GND connection), so pin 3 cannot deliver the I2C itself.

If the other device is running on 3V3 you have to use pullups to the 3V3 of your Arduino and not 5V or you may fry your device.

You won't find official document on aurora because whey simply sell some additional equipment using those I2C lines at the back of the module and don't want to have competition.

I2C transmission was "deciphered" in forum thread Aurora 9 advanced telemetry - RC Groups and some DIY peripherals are already built.

It's important to know that I do receive some correct frames. They match what others in the mentioned thread received.

Wires have to be connected properly because I do receive proper frames. The problem is that Arduino hangs after a while and it's for sure connected with I2C because if I comment out OnReceive method to prevent receiving then Arduino works.

I've checked that in fact Arduino fails because it even stops printing debug messages. If I reset Arduino with a button then some frames are received again so Aurora is constantly transmitting.

As I mentioned already I matched voltages from Arduino and Aurora module with proper pull-ups.

As I mentioned already I matched voltages from Arduino and Aurora module with proper pull-ups.

No, you mentioned that the pullups go to 5V. If your spec of the Aurora (3V3) is correct, than you have to pullup to that value and not 5V. It may be necessary to insert a level converter (an I2C level converter, example: Logic Level Converter - Microcontroller Accessories Interface - Boxtec Onlineshop) to have the different logic levels assimilated. 3V3 is just slightly above the 60% level at which the 5V Arduino should still recognize a logical one. At 2V9 it won't get there. The other way round if you give 5V to the input pins of a 3V3 device it may be fried immediately or just misbehave in some strange way. I guess you see the later.

I2C voltage:

  • 3,5V on Aurora
  • 5V on Arduino - reduced with external pull-up resistors to 3,5V

Now I see that arduino can stop recognizing signals sent from Aurora. I'll have a look for those converters nearby.

In the meantime... is there a way to change this threshold above which Arduino recognizes logical one? Is this in the code or defined by hardware?

Is this in the code or defined by hardware?

Hardware. According to the datasheet, it's 0.7 x Vcc.

Hmm... so I'll experiment with a bit lower Vcc while waiting for correct solution with converter.