Problem with Aarduino and RPI serial communication

Hi!

I'm a new in here but i'm dealing with Arduino's over a months and now i'm stucked one of my projects.
So my problem is with serial communication between Arduino and Raspberry PI. Arduino sends every 10 seconds interval DS1820, DHT11, photoresistor data to RPI over serial. PHP catch this data and prints out. But after Arduino is running a while then some weird characters appears in serial communications or some data is lost (please see pastebin log example line: 2967, 3023, 3033) and after that Arduino just dies and does not send anything out. Does someone know why this happening just in random times?

Hardware:
Raspberry PI
Atmega328p
DS1820
DHT11
Photoresistor

Arduino code:

#include <EEPROM.h>
#include <SimpleTimer.h>

#include <OneWire.h>
#include <DallasTemperature.h>

#include <dht11.h>

SimpleTimer t;

OneWire oneWire(3);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;

dht11 DHT11;

int call_time = EEPROM.read(100) * 1000;
int pin_count = 17;

int led_pin = 13;
int led_duration = 200;

/*
ATMEGA328P DIP 18pin

EEPROM(100) - CALL_TIME in seconds
EEPROM(1-17) - PIN nr

EEPROM values:
1 - Digital read
2 - Analog read
10 - 1wire temperature
11 - DHT11/22
*/

void setup(void)
{
  Serial.begin(9600);
  
  pinMode(led_pin, OUTPUT);
  
  out("START", true);
  
  if(call_time <= 0)
  {
    call_time = 5000;
   
    write_rom(100, 5); 
  }

  t.setInterval(call_time, getData);
}

void loop(void)
{
  t.run();
}

/* Serial output */
void out(String o, boolean ln)
{
  o.toUpperCase();

  if(ln)
  {
    Serial.println(o);
  }
  else
  {
    Serial.print(o); 
  }
  
  led();
}

void write_rom(int pos, int val)
{
  EEPROM.write(pos, val);
  
  out("ROM["+String(pos)+"="+String(val)+"]", true);
}

void led()
{
   digitalWrite(led_pin, HIGH);
   
   for(int i=0; i<=led_duration; i++)
   {
     if(i == led_duration)
     {
       digitalWrite(led_pin, LOW);
       break;
     }
   }
}

void getData()
{
  long st = millis();

  out("BEGIN", true);

  read1wire(3);
  readDHT(4);
  readA(0);

  long et = millis() - st;
  
  out("-"+String(et), true);
  
  out("END", true);
}

void readA(int pin)
{
  int v = analogRead(pin);

  out("["+String(pin)+":"+String(v)+"]", false);
}

void read1wire(int pin)
{  
  sensors.begin();
  sensors.requestTemperatures();

  // 1wire devices count
  int devices_count = sensors.getDeviceCount();

  out("["+String(pin)+":", false);

  if(devices_count)
  {
    // Get each device value
    for(int d=1; d<=devices_count; d++)
    {
      if( sensors.getAddress(tempDeviceAddress, d-1) )
      {
        for (uint8_t i = 0; i < 8; i++)
        {
          if (tempDeviceAddress[i] < 16)
          {
             out("0", false);
          }
  
          out(String(tempDeviceAddress[i], HEX), false);
        }
  
        int c = sensors.getTempC(tempDeviceAddress) * 1000;
 
        out("="+String(c), false);
  
        if(d < devices_count) out(",", false);
      }
    }
  }
  
  out("]", false);
}

// Read DHT sensor
void readDHT(int pin)
{
  out("["+String(pin)+":", false);

  int chk = DHT11.read(pin);

  if(chk == DHTLIB_OK)
  {
    int tempC = (float)DHT11.temperature * 100;
    int humC = (float)DHT11.humidity * 100;

    out(String(tempC)+","+String(humC), false);
  }
  else
  {
    out(String(chk), false);
  }

  out("]", false);
}

PHP code:

#include <EEPROM.h>
#include <SimpleTimer.h>

#include <OneWire.h>
#include <DallasTemperature.h>

#include <dht11.h>

SimpleTimer t;

OneWire oneWire(3);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;

dht11 DHT11;

int call_time = EEPROM.read(100) * 1000;
int pin_count = 17;

int led_pin = 13;
int led_duration = 200;

/*
ATMEGA328P DIP 18pin

EEPROM(100) - CALL_TIME in seconds
EEPROM(1-17) - PIN nr

EEPROM values:
1 - Digital read
2 - Analog read
10 - 1wire temperature
11 - DHT11/22
*/

void setup(void)
{
  Serial.begin(9600);
  
  pinMode(led_pin, OUTPUT);
  
  out("START", true);
  
  if(call_time <= 0)
  {
    call_time = 5000;
   
    write_rom(100, 5); 
  }

  t.setInterval(call_time, getData);
}

void loop(void)
{
  t.run();
}

/* Serial output */
void out(String o, boolean ln)
{
  o.toUpperCase();

  if(ln)
  {
    Serial.println(o);
  }
  else
  {
    Serial.print(o); 
  }
  
  led();
}

void write_rom(int pos, int val)
{
  EEPROM.write(pos, val);
  
  out("ROM["+String(pos)+"="+String(val)+"]", true);
}

void led()
{
   digitalWrite(led_pin, HIGH);
   
   for(int i=0; i<=led_duration; i++)
   {
     if(i == led_duration)
     {
       digitalWrite(led_pin, LOW);
       break;
     }
   }
}

void getData()
{
  long st = millis();

  out("BEGIN", true);

  read1wire(3);
  readDHT(4);
  readA(0);

  long et = millis() - st;
  
  out("-"+String(et), true);
  
  out("END", true);
}

void readA(int pin)
{
  int v = analogRead(pin);

  out("["+String(pin)+":"+String(v)+"]", false);
}

void read1wire(int pin)
{  
  sensors.begin();
  sensors.requestTemperatures();

  // 1wire devices count
  int devices_count = sensors.getDeviceCount();

  out("["+String(pin)+":", false);

  if(devices_count)
  {
    // Get each device value
    for(int d=1; d<=devices_count; d++)
    {
      if( sensors.getAddress(tempDeviceAddress, d-1) )
      {
        for (uint8_t i = 0; i < 8; i++)
        {
          if (tempDeviceAddress[i] < 16)
          {
             out("0", false);
          }
  
          out(String(tempDeviceAddress[i], HEX), false);
        }
  
        int c = sensors.getTempC(tempDeviceAddress) * 1000;
 
        out("="+String(c), false);
  
        if(d < devices_count) out(",", false);
      }
    }
  }
  
  out("]", false);
}

// Read DHT sensor
void readDHT(int pin)
{
  out("["+String(pin)+":", false);

  int chk = DHT11.read(pin);

  if(chk == DHTLIB_OK)
  {
    int tempC = (float)DHT11.temperature * 100;
    int humC = (float)DHT11.humidity * 100;

    out(String(tempC)+","+String(humC), false);
  }
  else
  {
    out(String(chk), false);
  }

  out("]", false);
}

Here is Arduino and RPI communication log:

Many thanks,
Marko

Does someone know why this happening just in random times?

This:

void out(String o, boolean ln)

doesn't help. Ditch the String class.

What you mean this does not help? Did you mean that I should use char instead of string?

Did you mean that I should use char instead of string?

I mean that you should use NULL terminated char arrays instead of Strings.

I remove "out" function from code and just using direct "Serial.print" command. It worked stable a little longer than old code but still after a day Arduino died. Just printed out some random texts and I also checked traffic from jpnevulator and it prints out empty strings. How this is logical that Arduino dies? Or collecting DS1820 temperatures is too long process? Have anyone tried my code? It's still mysterios for me. Please help.

jpnevulator log:

2012-10-10 21:11:15.516762:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00                            .......
2012-10-10 21:11:16.456278:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

PHP log:

2012-10-10 21:07:45.675890-04000019289AC14303000003030000B94:]-1095
2012-10-10 21:07:55.713765-04000019=22375,28C9C043=22375][2100,2400][0:114
2012-10-10 21:08:05.773631-04000019289AC143=22375,030000B94:2100,250]-1094
2012-10-10 21:08:15.813650-[3:283C1907=4750,03000003030000B94:2100,250]-1095
[3:283C19070400001903000003030000B94:2100,240]-1095
2012-10-10 21:08:35.873936-04000019289AC143=22375,28C9C043=22375][4:2100,250]-1094
2012-10-10 21:08:45.913600-[3:283C190704000019=4750,289AC143=22375,28C9C043=22375][4:2100,240]-1095
2012-10-10 21:08:55.953763-[3:283C1907=4750,289AC143=22375,28C9C043=22375][0][0:114
2012-10-10 21:09:05.995302-04000019289AC143=22375,28C9C043=22375][0][0:115
2012-10-10 21:09:16.033640-[3:283C1907=4750,289AC143=22437,28C9C043=22375][4:2100,240]-1095
2012-10-10 21:09:26.113718-04000019289AC143=22375,28C9C043=22375][0][0:114]-1094
2012-10-10 21:09:36.154187-[3:283C190703000003030000B94:2100,240]-1095
283C190704000019289AC143=22375,28C9C043=22375][2100,2400][0:113

I remove "out" function from code and just using direct "Serial.print" command.

But did not post the revised code.

It worked stable a little longer than old code but still after a day Arduino died.

You know this because serial data stopped appearing, or what?

Just printed out some random texts

Generally, this is an indication of a memory corruption problem.

Have anyone tried my code?

I would if you'd send me your Pi.

  1. Revised code:
#include <EEPROM.h>
#include <SimpleTimer.h>

#include <OneWire.h>
#include <DallasTemperature.h>

#include <dht11.h>

SimpleTimer t;

OneWire oneWire(3);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;

dht11 DHT11;

int call_time = EEPROM.read(100) * 1000;
int pin_count = 17;

int led_pin = 13;
int led_duration = 200;

/*
ATMEGA328P DIP 18pin

EEPROM(100) - CALL_TIME in seconds
EEPROM(1-17) - PIN nr

EEPROM values:
1 - Digital read
2 - Analog read
10 - 1wire temperature
11 - DHT11/22
*/

void setup(void)
{
  Serial.begin(9600);
  
  pinMode(led_pin, OUTPUT);
  
  Serial.println("START");
  
  if(call_time <= 0)
  {
    call_time = 5000;
   
    write_rom(100, 5); 
  }

  t.setInterval(call_time, getData);
}

void loop(void)
{
  t.run();
}

void write_rom(int pos, int val)
{
  EEPROM.write(pos, val);
  
  Serial.println("ROM["+String(pos)+"="+String(val)+"]");
}

void led()
{
   digitalWrite(led_pin, HIGH);
   
   for(int i=0; i<=led_duration; i++)
   {
     if(i == led_duration)
     {
       digitalWrite(led_pin, LOW);
       break;
     }
   }
}

void getData()
{
  long st = millis();

  Serial.println("BEGIN");
  
  led();

  read1wire(3);
  readDHT(4);
  readA(0);

  long et = millis() - st;
  
  Serial.println("-"+String(et));
  
  Serial.println("END");
}

void readA(int pin)
{
  int v = analogRead(pin);

  Serial.print("["+String(pin)+":"+String(v)+"]");
}

void read1wire(int pin)
{  
  sensors.begin();
  sensors.requestTemperatures();

  // 1wire devices count
  int devices_count = sensors.getDeviceCount();

  Serial.print("["+String(pin)+":");

  if(devices_count)
  {
    // Get each device value
    for(int d=1; d<=devices_count; d++)
    {
      if( sensors.getAddress(tempDeviceAddress, d-1) )
      {
        for (uint8_t i = 0; i < 8; i++)
        {
          if (tempDeviceAddress[i] < 16)
          {
             Serial.print("0");
          }
  
          Serial.print(tempDeviceAddress[i], HEX);
        }
  
        int c = sensors.getTempC(tempDeviceAddress) * 1000;
 
        Serial.print("=");
        Serial.print(c);
  
        if(d < devices_count) Serial.print(",");
      }
    }
  }
  
  Serial.print("]");
}

// Read DHT sensor
void readDHT(int pin)
{
  Serial.print("[");
  Serial.print(pin);
  Serial.print(":");

  int chk = DHT11.read(pin);

  if(chk == DHTLIB_OK)
  {
    int tempC = (float)DHT11.temperature * 100;
    int humC = (float)DHT11.humidity * 100;

    Serial.print(tempC);
    Serial.print(",");
    Serial.print(humC);
  }
  else
  {
    Serial.print(chk);
  }

  Serial.print("]");
}
  1. No, I'm still retrieving serial data.
  2. How to figure out where or why this memory corruption happened?
  3. You don't have to use RPI. You can use whatever linux board or just Arduino serial output.
  1. How to figure out where or why this memory corruption happened?

You said you removed the out() function, implying that you removed the String class. No, you didn't. You simply started using it somewhere else.

  Serial.println("ROM["+String(pos)+"="+String(val)+"]");
  Serial.println("-"+String(et));
  Serial.print("["+String(pin)+":"+String(v)+"]");
  Serial.print("["+String(pin)+":");

Absolutely none of those uses are needed or logical. Get rid of them. It really isn't that much work to use 2 or 3 or 5 Serial.print() statements instead of shooting yourself in the foot.

Looks like after removing out String-s from Serial.print function it works stable for over 3 days. Seems there were a problem. Thanks.

Seems there were a problem. Thanks.

And thank you for the confirmation and follow-up.

very interesting project...care to share the revised code at possibly also the connections (for at least sensors signal pins)
it would be very usefull for me,and sure others at first attempts to programming (i'm studying python from only a month..but no c skills here)
thanks if you will answer me and help out... :slight_smile:

My ICSC library communicates between Pi and Arduino quite nicely. I even have the Pi driving a MAX3485 chip properly for RS-485 comms.

My Pi updates the time on my bedside clock through serial comms :slight_smile: