Arduino stops working after a few min

Hello,

i'm having an issue with the Arduino, where it stops working after a few min. It's supposed to continously provide Serial-Output, though after a few min, that serial output will stop and the Jetson Nano won't receive any more data via i2c. At that point, pressing the reboot button on the arduino will make it work again for a short time If the Arduino is not connected to the jetson nano, (so all wires removed) and only connected via USB, the serial output will work continuously.

So there's 3 scenarios, where two show the faulty behavior:
arduino connected to jetson nano and pc via usb: -> Arduino will stop after some time
arduino is connected to jetson nano only: -> Arduino will stop after some time
arduino is connected only to pc via usb: Arduino will work fine
The Arduino is connected to a Jetson Nano to communicate via i2c.
Arduino -- Jetson Nano
VIN -- 5V
Ground -- Ground
A4 -- 27
A5 -- 28

Any ideas, what could be causing this issue? Considering, the issue doesn't occur, when the Arduino Nano is connected solely via USB, i was thinking, whether it could be faulty soldering points.

Below is the full code, which uses the Arduino to read distance via a tof sensor and sends that distance, whenever the jetson nano sends a request via i2c.

#include <Wire.h>

int x_mm; // distance in millimeters
unsigned short lenth_val = 0;
unsigned char i2c_rx_buf[16];
int i2cAddress = 0x04; // i2c of jetson nano

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  Wire.begin(i2cAddress);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
}

void loop()
{
  x_mm = ReadDistance();
  Serial.println(x_mm);
  delay(50);
}
void SensorRead(unsigned char addr,unsigned char* datbuf,unsigned char cnt) 
{
  unsigned short result=0;
  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(82); // transmit to device #82 (0x52), you can also find this address using the i2c_scanner code, which is available on electroniclinic.com
  // the address specified in the datasheet is 164 (0xa4)
  // but i2c adressing uses the high 7 bits so it's 82
  Wire.write(byte(addr));      // sets distance data address (addr)
  Wire.endTransmission();      // stop transmitting
  // step 2: wait for readings to happen
  delay(1);                   // datasheet suggests at least 30uS
  // step 3: request reading from sensor
  Wire.requestFrom(82, cnt);    // request cnt bytes from slave device #82 (0x52)
  // step 5: receive reading from sensor
  if (cnt <= Wire.available()) { // if two bytes were received
    *datbuf++ = Wire.read();  // receive high byte (overwrites previous reading)
    *datbuf++ = Wire.read(); // receive low byte as lower 8 bits
  }
}

int ReadDistance(){
    SensorRead(0x00,i2c_rx_buf,2);
    lenth_val=i2c_rx_buf[0];
    lenth_val=lenth_val<<8;
    lenth_val|=i2c_rx_buf[1];
    delay(10); 
    return lenth_val;
}    

void writeString(int cm)
{
  byte buf[4];
  buf[0] = (byte) cm;
  buf[1] = (byte) cm>>8;
  buf[2] = (byte) cm>>16;
  buf[3] = (byte) cm>>24;
  Wire.write(buf, 4);}

void receiveEvent()
{
  int x = 5; // dummy. Nothing implemented yet
}

void requestEvent()
{
  //Serial.println("Request received");
  writeString(x_mm);
}

Nvidia Jetson Code:

import smbus
import time
import os
from IPython.display import clear_output

bus = smbus.SMBus(0) # Nvidia Jetson i2c bus. SDA 27, SCL 28
address = 0x04 # arduino i2c-address

def readNumber():
    number = bus.read_byte_data(address, 0)
    return number

while True:
    number = readNumber()
    print(number, " cm")
    time.sleep(1)

What are the logic levels of that Nano?
Did you use level converters?
Leo..

You've likely got a problem with the Nvidia Jetson (not calling it a Nano, that’s too confusing), probably overflowing your fixed size I2C buffer. You’d never know because you do no bounds checking. Overall, that’s some really poor programming practices with magic number I2C addresses, unreferenced header files and honestly who knows what else. I’ve seen enough to say the problem is very likely in your code. Somewhere. In the Arduino or the Nvidia Jetson side.

Oh, I’ll echo Wawa’s question. If the Arduino is a 5V device, you need level translation. Be careful because the Jetson I2C channels 0 and 1 are 3v3 only and not 5V tolerant. Channel 2 is 1v8 which is quite unusable in the Arduino world because the usual fet based level translators will not function at those voltages.

Decreasing the frequency, with which the nvidia jetson sends a request to the arduino from 0.01 to 1s delays the non-responsive behavior from the Arduino. Though it will still occur after ~10-15min.
So solving the i2c-buffer seems to be the way. Could you recommend anything to research for this? How would I check the bounds? What is the problem with magic number i2c addresses? Shouldn't the project work fine with a defined address, given that both sides (Jetson and Arduino) use this address?

The i2c-wires (SCL & SDA) go through a bidirectional level converter:
Arduino on the HV(5V)-side,
nvidia jetson on the LV(3.3V) side.

Updated the initial post with the nvidia jetson code, which requests the data from the arduino.
Also removed unused parts of the code, header-files for i2c-display, etc.

NVIDIA Jetson Nano: https://developer.nvidia.com/embedded/jetson-nano-developer-kit.

The NVIDIA Jetson is a Master for the Arduino.
The Arduino is a Master for the sensor.
So you have a multi-master bus. In my opinion a multi-master bus with Arduino is a fairy tale. Your fairy tale lasts for 10 to 15 minutes ? That is a long time for a fairy tale :wink:

Do you know if the NVIDIA Jetson supports clock pulse stretching ? Because that is what the Arduino does when executing the onRequest handler.

Can you replace the NVIDIA Jetson with a Raspberry Pi ? Even then I recommend not to use I2C to communicate with a Arduino. See my opinion here: How to make a reliable I2C bus.

Use a USB cable to connect the Arduino to the NVIDIA Jetson. Then you have solved all timing, buffer, interrupt and voltage level problems. There are libraries for serial communication with a Arduino library and a Python script.

In the code below, it would be called index checking. What happens if the variable cnt is larger than 8?

Wire.requestFrom(82, cnt);    // request cnt bytes from slave device #82 (0x52)

It would cause a buffer overflow which results in crashes and/or very hard to find bugs.

Buffer overflow: Buffer overflow - Wikipedia

Magic numbers: language agnostic - What are "magic numbers" in computer programming? - Stack Overflow

All the above is informational only, I think Koepel summed up the situation best. Having multiple processors talking to one another is never as simple as it appears. Could the Arduino be eliminated and have the Jetson communication directly with the distance sensor? That would be the best arrangement to implement.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.