YunServer + SoftwareSerial = periodic hangs

Hi all,

I have some periodic hangs if I combine the YunServer and the SoftwareSerial in my application.
My application is using the YunServer to publish sensor data which is collected by some XBee nodes. The SoftwareSerial is used to communicate with a XBee module which is mounted on a Sparkfun XBee shield.
I have written a demo application which combines the YunServer and the SoftwareSerial in the same way like in my production application and the hangs are also reproducable in the demo application.
For debugging, my loop method writes into a log file every 10 seconds and I can see the hangs clearly.
While the loop method hangs, it is not possible to make a web request to the arduino via the Bridge. In this case I receive an http error 500.
Here is my demo code:

#include <SoftwareSerial.h>
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
#include <FileIO.h>

// Software Serial
SoftwareSerial _serial(8, 9); // RX, TX

// Webserver
YunServer server;

const char* LOGDIRECTORY = "/mnt/sd/arduino/www/BridgeTest";
const char* LOGFILENAME = "/mnt/sd/arduino/www/BridgeTest/log.txt";

unsigned long _loopMillis = 0;

void setup()
{
  _serial.begin(9600);
  
  Bridge.begin();
  server.listenOnLocalhost();
  server.begin();

  FileSystem.begin();

  // Wait till the FileSystem-service is started
  while (!FileSystem.exists(LOGDIRECTORY))
    delay(1000);

  // Wait thill the clock is synchronized via NTP
  while (getDateTime().startsWith("08/08/13"))
    delay(1000);

  writeToLog("Setup");
}

void loop()
{
  if(getElapsedMillis(_loopMillis) > (unsigned long) 10000)
  {
    writeToLog("Loop");
    _loopMillis = millis();
  }
  
  String startTime = getDateTime();
  unsigned long startMillis = millis();
  
  processXBeePackets();
  
  if (getElapsedMillis(startMillis) > (unsigned long) 5000)
    writeToLog("processXBeePackets() took more than 5 seconds! Action started at " + startTime);
  
  startTime = getDateTime();
  startMillis = millis();
  
  processWebRequests();
  
  if (getElapsedMillis(startMillis) > (unsigned long) 5000)
    writeToLog("processWebRequests() took more than 5 seconds! Action started at " + startTime);
  
  delay(50);
}

void processXBeePackets()
{
  if (_serial.available())
  {
    while(_serial.available())
    {
      int inByte = _serial.read();
    }
  }
}

void processWebRequests()
{
  YunClient client = server.accept();

  if (client)
  {
    String command = client.readString();
    command.trim();
    command.toLowerCase();
    
    if(command == "clearlogfile")
    {
      clearLogFile();
    }
    
    client.print("Your command was: " + command);
  
    client.stop();    
  }
}

unsigned long getElapsedMillis(unsigned long milliseconds)
{
  unsigned long currentMillis = millis();
  unsigned long elapsedMillis;

  if (currentMillis >= milliseconds)
  {
    elapsedMillis = currentMillis - milliseconds;
  }
  // Es gab einen Überlauf des Wertebereiches!
  else
  {
    elapsedMillis = ((unsigned long) 4294967295 - milliseconds) + currentMillis;
  }

  return elapsedMillis;
}

void writeToLog(String message)
{
  String dateTime = getDateTime();
  File file = FileSystem.open(LOGFILENAME, FILE_APPEND);

  if (file)
  {
    file.println(dateTime + ": " + message);
    file.close();
  }
}

void clearLogFile()
{
  FileSystem.remove(LOGFILENAME);
}

String getDateTime()
{
  String dateTime;
  Process time;
  time.begin("date");
  time.addParameter("+%D %T");
  time.run();

  while (time.available() > 0)
  {
    char c = time.read();
    if (c != '\n')
      dateTime += c;
  }

  return dateTime;
}

Here is my log file:
11/01/13 12:46:11: Setup
11/01/13 12:46:18: Loop
11/01/13 12:46:28: Loop
11/01/13 12:46:39: Loop
11/01/13 12:46:49: Loop
11/01/13 12:47:00: Loop
11/01/13 12:47:10: Loop
11/01/13 12:49:15: Loop
11/01/13 12:50:04: Loop
11/01/13 12:50:14: Loop
11/01/13 12:50:25: Loop
11/01/13 12:50:41: Loop
11/01/13 12:50:51: Loop
11/01/13 12:51:02: Loop
11/01/13 12:51:13: Loop
11/01/13 12:51:24: Loop
11/01/13 12:52:32: Loop
11/01/13 12:52:43: Loop
11/01/13 12:52:53: Loop
11/01/13 12:53:04: Loop
11/01/13 12:53:14: Loop
11/01/13 12:53:26: Loop
11/01/13 12:53:37: Loop
11/01/13 12:53:47: Loop
11/01/13 12:53:58: Loop
11/01/13 12:57:47: Loop
11/01/13 12:57:58: Loop
11/01/13 12:58:08: Loop
11/01/13 12:59:19: Loop

Can someone explain what is wrong with my code?
Thanks in advance!

Bye,
Sebastian

Can you try the latest nightly build of the IDE? We included a fix in Bridge that solved a similar issue

Hi Federico,

I have tested this with the nightly build from yesterday night and the same behavior appears.
Can you explain how the Bridge internally works and what could interfere with the SoftwareSerial?

Thanks!
Sebastian

Have you tried this:

  if (client) {
    client.setTimeout(5);
   ...

This hint from Federico helped in my project.

Hi skr1, I've run your sketch for half an hour and it behaved as expected, without big latencies between runs (I don't have an xbee module though)
How long does it take yours to show that weird behaviour?

Hello,

It looks I am having quite the same problems. Mostly it happens after quite a lot of hours. Like 8-30 hours. Also with the nightly from two days ago.

The strange thing is that I am still able to connect via ssh(/http). When I do this 'route' does not show the default route anymore. So any external http call will not succeed.
(In my test environment I only use eth1. wireless is on 'master' modus)

When I do:
route add default gw 192.168.1.1 eth1
will correct the problem temporarily.

But '/sbin/reboot' does mostly NOT work anymore after this has happened. Ssh connection is closed and will not recover (no ping, no ssh, no arduino output).

I am trying to make an example with a shorter period to 'crash'.

Kind regards.

Hi Federico,

I have played again with my demo sketch and I figured out that the hangs only occur if serial data is received!
I have connected the XBee shield to the Yun via the digital pins 8 (RX) and 9 (TX) and it takes only a few minutes when the first hangs occur. Then, I have disconnected pin 8 (RX) and everything worked fine. I kept the sketch running for an hour and everything was stable.
So, it has definitely to do with the serial data. I have 5 XBee nodes which send a IO sample every minute to the XBee coordinator which is connected to the Yun.
Could you simulate this load with a Arduino UNO which generates some test data and which you connect to the pins 8 and 9 of the Yun?
Could it be that the hangs have something to do with the interrupt which is used by the SoftwareSerial?

@Fred: It seems that you have another network related problem.

Bye,
Sebastian

I currently have no clue on what the problem may be, but maybe its worth a to try with AltSoftSerial?

http://www.pjrc.com/teensy/td_libs_AltSoftSerial.html

Hi cmaglie,

this is a good idea! I had a look into this, but it seems that the Yun is not yet supported by this library. If I use this library, I get an error because the header file "known_boards.h" does not contain some "Yun specific" defines.
Do you know which defines I have to set for the Yun?
Thanks!

Try to add this snippet to the board list:

// Arduino Leonardo or Arduino Yun
//
#elif defined(ARDUINO_AVR_YUN) || defined(ARDUINO_AVR_LEONARDO)

//#define ALTSS_USE_TIMER1
//#define INPUT_CAPTURE_PIN 4 // receive
//#define OUTPUT_COMPARE_A_PIN 9 // transmit
//#define OUTPUT_COMPARE_B_PIN 10 // unusable PWM
//#define OUTPUT_COMPARE_C_PIN 11 // unusable PWM

#define ALTSS_USE_TIMER3
#define INPUT_CAPTURE_PIN 13 // receive
#define OUTPUT_COMPARE_A_PIN 5 // transmit

I derived this one from the lib specification but I've not tried on the real hardware yet.

Note that you must use pin 13 for RX and 5 for TX.

Alternatively you can disable TIMER3 and enable TIMER1 (by commenting/uncommenting the relative sections), in this case you can use pin 4 for RX and pin 9 for TX, but you lose PWM functionality on pin 10 and 11.

Hi cmaglie,

thanks for the configuration! Now it is working since two days without any hangs! :smiley:

I am using pin 13 for RX and 5 for TX. I have attached a picture so that everyone can see how the Sparkfun XBee shield is now connected for using the AltSoftSerial library.

Although I have a working solution now, it would be great to figure out why the SoftwareSerial library is producing hangs. What is the main difference between both libraries? AFAIK, the SoftwareSerial library is using an interrupt. Is there a problem because I am using only 9600 baud for communicating with the XBee module?

Bye,
Sebastian

Cooool! :slight_smile:

I read that SoftwareSerial disables interrupts while it's receiving characters from the emulated com port.
Running at low speeds means that it keeps interrupts disabled for long time (low speed => longer bit duration), this may be the reason why you are experiencing the hangs, but I can't explain myself why it doesn't resume normal operation aftwards, I expect that the hang should be temporary.

For a final answer we should do a more deep debugging session but, at this point, I guess that it will hardly happen :wink:

I am really happy that everything is working now! :smiley:
Thanks again for the great support!

What you say about the interrupt sounds reasonable. Maybe I (or someone else) will test the SoftwareSerial library with a higher baud rate. :wink:

Same problem here.

I am/was successfully connecting to a HC-05-Bluetooth-Module over SoftSerial (Pins 9 and 10) and then wanted to use REST with Bridge+YunServer+YunClient and also got reboots... Altsoftserial didn't help ( included the standard altsoftserial sketch code and connected to Pins 5 an 13)... Could you explain what you mean with "board list"? If I paste your code into the Sketch I get an error "#elif without #if" ...

Code add into "known_boards.h". It is altsoftserial based solution.

Hi all

I want to use AltSoftSerial for my project. but i experience some latency problem...
what i want to do it's to send a request to a rs485 device and receive the response.
the device responds immediately but i don't receive anything (i see the response from a usb-rs485 interface between arduino and the device)
the baudrate it's 9600
I've tried to send manually the response (via hyperterminal). If i send the data before 5 or 6 seconds it doesn't receive anything... if i send after this time it works correctly and goes on.
I think there's some latency time before arduino is ready to receive something... it's only my opinion because i didn't find anything online about this....

some idea?

Hi all

Some news,

this is the code tha I used for testing:

#include <AltSoftSerial.h>

#define rxPin 13
#define txPin 5

int EN = 2;
int val = 0;
int i=0;

String risposta="";
AltSoftSerial mySerial;

void setup() {
        const int baudrate = 9600;
        
       Serial.begin(baudrate);	 
        
        pinMode(rxPin, INPUT);
        pinMode(txPin, OUTPUT);
        mySerial.begin(baudrate);
        
        delay(5000);
        Serial.println("START!!!!");

}

void loop() {
   i=0;
   risposta ="";
   //Serial.println("X");
   //String stringa = "01 03 00 00 00 0A C5 CD";
   int stringa[8]={0x01,0x03,0x00,0x00,0x00,0x0A,0xC5,0xCD};
   char c;
   //String stringa = "01" ;
   val = digitalRead(EN);
   Serial.print("Stato A: ");
   Serial.println(val);
   //Serial.print("val 1 = ");
   //Serial.println(val);
   digitalWrite(EN, HIGH);
   for (int j=0; j < 8; j++){
       mySerial.write(stringa[j]);  //era write
       Serial.print(stringa[j],HEX);
       stringa[j]= 9;}
   Serial.println("");
   digitalWrite(EN, LOW);
   val = digitalRead(EN);
   Serial.print("Stato B: ");
   Serial.println(val);
delay(5000); // Time that I have to wait to see the pin EN to change status !!!!!!!
   val = digitalRead(EN);
   Serial.print("Stato C: ");
   Serial.println(val);
     
   
    while ((mySerial.available()==0)&&(i<1000)) {
    i++;
    delay(1);
    //Serial.println(".");
    }
    
    while(mySerial.available()) {
    //Serial.print("RICEVUTO!!!!  ");
    c = mySerial.read();
   // Serial.print(c,HEX);
    risposta=risposta+c;
    delay(1);
    }
    delay(1);
    
   Serial.println("");
   Serial.println(risposta);
   Serial.println("");
}

The problem I found is that there is a delay between when the EN pin (enable pin of the RS485 shield - I/O expansion V5 shield) goes high and when it goes low.
I verified that pass at least 5 seconds.
I thought there was some problem with the DigitalWrite and DigitalRead commands and so I've controlled the pins directly (via pin manipulation), but the problem remains the same.....
The slave responds to the master, but the master, not being enabled in reading, does not receive packets.
Have any of you encountered the same problem?
some idea?

Hi,

I also have a problem with the Arduino Yún and an XBEE.

I use the Arduino Yun, a ArduinoXBee v1.1 shield and a Series 1 XBEE. I tried the setup with 13 and 5 for RX and TX. That didn't work. Now I use the setup with 8 and 9 for RX and TX. I also bent the two pins as the pictures show in a different post.

I tried it with the code above but it does not work for me. I actually do not need all these functions. I only need it to send an (empty) message to other XBees. From there I am going to use the RSSI to determine distance.

I can send between two XBees if they are both in explorers connected to the computer and the Yun seems to work fine.

Anybody with an idea what can be wrong or what I should try next?

Piero76:
The problem I found is that there is a delay between when the EN pin (enable pin of the RS485 shield - I/O expansion V5 shield) goes high and when it goes low.
I verified that pass at least 5 seconds.

I see where you are setting the EN pin high or low, but nowhere do you make it an output.

The power-on state for a pin is an input, and when a pin is an input, using digitalWrite() on the pin does not control the output state: all it does is enable or disable a weak pull-up resistor. I think what is happening is that this weak pullup resistor is slowly charging the stray capacitance on the line, resulting in slow transition times.

In setup, try adding pinMode(EN, OUTPUT); and see if that makes a difference.

sanne1234:
I also have a problem with the Arduino Yún and an XBEE.

Please do not cross-post the same problem in multiple threads. It wastes the time of people trying to help, and it spreads the possible solutions across several threads, making it harder to find the solution for people who come along later with the same problem.

I do not believe your issues have anything to do with the problem in this thread. You are both using SoftwareSerial, but other than that there is no correlation between your issues.

I have already responded to your other post on this matter, please continue the discussion there and do not reply to this thread.