Go Down

Topic: Rest API gets slower and slower and finally webserver hangs... (Read 12868 times) previous topic - next topic

olivb

Nov 14, 2013, 02:43 pm Last Edit: Nov 14, 2013, 02:45 pm by olivb Reason: 1
Hello,

I'm working on a project with an arduino Yun.

A temperature sensor is connected by I2C to the mcu and my sketch pulls the temperature value every 10 seconds (by a Bridge.put call). I've also created a web page that make asynchronous calls to the REST api by ajax (http://localip/data/get) : it updates a content every 2 seconds. the calls from the webpage starts witha delay of 500ms (already pretty slow on a local network) and I let this page running, the calls gets slower and slower (above 3s and more).

And if Iwait enough, the webserver hangs. It can only be recovered by unplugging the board (no software reboot or reset button works).

Can someone has the same problem or can help me?
    regards,

O.Boesch

federicofissore

Could it be an already fixed but not yet released issue with Bridge? Can you try using one of the nightly build of the IDE? http://arduino.cc/en/Main/Software#toc4

olivb


Could it be an already fixed but not yet released issue with Bridge? Can you try using one of the nightly build of the IDE? http://arduino.cc/en/Main/Software#toc4


I already tried the last nightly build and nothing changes. It's not a great surprise to me since my sketch works well  but the problem seems to be on linino. maybe something wrong with the rest api that makes the server hangs (sometimes no response at all, sometimes internal server error/500) ?

O Boesch

olivb

news about this problem:
when I call http://yunip/data/get the server answers :
Session data invalid! stack traceback: [C]: in function 'assert' ?: in function 'read' ?: in function 'reap' ?: in function 'dispatch' ?: in function <?:194>

any idea?

simon_schvartzman

olivb, any progress with your issue? I'm experiencing what may be a similar problem.

I have a very simple HTTP client sketch sending data every 10 seconds, it runs fine for long periods of time (> 1 day)  and then suddenly stops completely.

I'm considering to have some kind of watchdog involved to overcome the problem but with so many resets on the Yun I don't know where to start.

Federico, I would appreciate any hints from you side.

Cheers!

federicofissore

I'm sorry to say that it shouldn't happen and that I have no idea how to reproduce the issue.
With yun out-of-the-box configuration, uhttpd accepts only two concurrent http requests. The (lua) code that connects to the Bridge has a 5 seconds timeout. So it shouldn't directly related to the http part of your project

My only guess is that something is eating up RAM, so dealing with your REST requests is harder and harder as time passes, until there is no more ram left and the REST requests are dropped.

Can you describe in details the composition of your project? (I mean the sketch and any additional software and hardware it uses)

olivb

My goal is to make an automation of a swimming pool (light, pump,...). There are two hardwares : An IPX800v3 from gce electronics and a yun equiped with and lcd shield from sparkfun and a DS1621 (temperature sensor via I2C).


A functionnal diagram is given as attachment...



and here is the code of the sketch (not finished yet but the temperature is sent to the bridge...):
Code: [Select]

/*---------------------------------------------------------------------------------------------------------------------
  BelPoolConsole - Arduino Side
  Author : Olivier Boesch
  date : nov 2013
---------------------------------------------------------------------------------------------------------------------*/
//-- Mode debug (uncomment to debug)
//#define DEBUG_BELPOOL

//-- Librairies
#include <Wire.h>
#include <LiquidCrystal.h>
#include <TimedEvent.h>
#include <ButtonEvent.h>
#include<MenuBackend.h>
#include <Bridge.h>
#ifdef DEBUG_BELPOOL
  #include <Console.h>
#endif

//-- Led d'activité
#define ACT_LED 13

//-- Boutons
#define NUM_KEYS 5
int adc_key_val[5] ={50, 200, 400, 600, 800 };

//-- Sonde de temperature (adresse et mise a jour)
#define DS1621 (0x90 >> 1)
#define TAIR_UPDATE_TIME 10000 //mise a jour de Tair toutes les 10 secondes

//-- Lcd
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define BACKLIGHT_PIN 10

//-- Menu
MenuBackend menu = MenuBackend(menuUse, menuChange);
  MenuItem miVolet = MenuItem(menu,"Volet",1);
    MenuItem miDeverVolet = MenuItem(menu, "Deverr. Volet",2);
    MenuItem miVerVolet = MenuItem(menu, "Verr. Volet",2);
  MenuItem miLumiere = MenuItem(menu, "Lumiere",1);
    MenuItem miLumiereOn = MenuItem(menu, "Lumiere Mar For",2);
    MenuItem miLumiereOff = MenuItem(menu, "Lumiere Arr For",2);
    MenuItem miLumiereAuto = MenuItem(menu, "Lumiere Auto",2);
  MenuItem miFiltration = MenuItem(menu, "Filtration",1);
    MenuItem miFiltrationDebor = MenuItem(menu, "Filt. Debord...",2);
    MenuItem miFiltrationFond = MenuItem(menu, "Filt. Fond...",2);
  MenuItem miPompe = MenuItem(menu, "Pompe",1);
    MenuItem miPompeOn = MenuItem(menu, "Pompe Mar For",2);
    MenuItem miPompeOff = MenuItem(menu, "Pompe Arr For",2);
    MenuItem miPompeAuto = MenuItem(menu, "Pompe Auto",2);
  MenuItem miSysteme = MenuItem(menu, "Systeme",1);
    MenuItem miSystemeRedemCent = MenuItem(menu, "Redem. Centrale",2);
    MenuItem miSystemeRedemConsole = MenuItem(menu, "Redem. Console",2);
    MenuItem miSystemeRedemControlleur = MenuItem(menu, "Redem Controll.",2);
   
//---- menu utilisé
void menuUse(MenuUseEvent used){
}

void menuChange(MenuChangeEvent changed){
}
 
//---- Setup de l'arduino
void setup(){
  pinMode(BACKLIGHT_PIN,OUTPUT);
  pinMode(ACT_LED,OUTPUT);
  pinMode(A5,INPUT);
  digitalWrite(ACT_LED,HIGH);
  Bridge.begin();
  #ifdef DEBUG_BELPOOL
    Console.begin();
    while (!Console); // Attente de connection de la console.
  #endif
  #ifdef DEBUG_BELPOOL
    Console.println("Demarrage de BelPoolConsole...");
  #endif
  buttons_setup();
  lcd_setup();
  menu_setup();
  ds1621_setup(); 
  TimedEvent.addTimer(TAIR_UPDATE_TIME,Tair_event);
  Tair_event(NULL); //force mise a jour de Tair des le debut
  digitalWrite(BACKLIGHT_PIN,HIGH);
  digitalWrite(ACT_LED,LOW);
}

//---- Configuration des boutons
void buttons_setup(){
  //buffer initial pour 5 boutons
  ButtonEvent.initialCapacity = sizeof(ButtonInformation)*5;
  //Bouton droit
  ButtonEvent.addButton(0,        //analog button pin
                        0,  //analog value
                        50,       //deviation
                        onDownBtnRight,   //onDown event function
                        NULL,
                        NULL,
                        1000,
                        NULL,
                        400);

  //Bouton haut
  ButtonEvent.addButton(0,        //analog button pin
                        145,  //analog value
                        50,       //deviation
                        onDownBtnUp,   //onDown event function
                        NULL,
                        NULL,
                        1000,
                        NULL,
                        400);
  //Bouton bas
  ButtonEvent.addButton(0,        //analog button pin
                        329,  //analog value
                        50,       //deviation
                        onDownBtnDown,   //onDown event function
                        NULL,
                        NULL,
                        1000,
                        NULL,
                        400);
  //Bouton gauche
  ButtonEvent.addButton(0,        //analog button pin
                        505,  //analog value
                        50,       //deviation
                        onDownBtnLeft,   //onDown event function
                        NULL,     //onUp event function
                        onHoldBtnLeft,   //onHold event function
                        1000,             //hold time in milliseconds
                        NULL,
                        400);     
  //Bouton select
  ButtonEvent.addButton(0,        //analog button pin
                        741,  //analog value
                        50,       //deviation
                        onDownBtnSelect,   //onDown event function
                        NULL,
                        NULL,
                        1000,             //hold time in milliseconds
                        NULL,
                        400);
}

void onDownBtnRight(ButtonInformation* Sender) {
  #ifdef DEBUG_BELPOOL
    Console.println("Bouton Droit");
  #endif
}

void onDownBtnLeft(ButtonInformation* Sender) {
  #ifdef DEBUG_BELPOOL
    Console.println("Bouton Gauche");
  #endif
}

void onDownBtnUp(ButtonInformation* Sender) {
  #ifdef DEBUG_BELPOOL
    Console.println("Bouton Haut");
  #endif
}

void onDownBtnDown(ButtonInformation* Sender) {
  #ifdef DEBUG_BELPOOL
    Console.println("Bouton Bas");
  #endif
}

void onDownBtnSelect(ButtonInformation* Sender) {
  #ifdef DEBUG_BELPOOL
    Console.println("Bouton Select");
  #endif
}

void onHoldBtnLeft(ButtonInformation* Sender) {
  #ifdef DEBUG_BELPOOL
    Console.println("Bouton Gauche Long");
  #endif
}



//---- Configuration des menus de l'ecran LCD
void menu_setup(){
  #ifdef DEBUG_BELPOOL
    Console.print("Setup Menu...");
  #endif
  //menu.getRoot()
    //.onChangeTo(display_idle)
    //.add(miVolet);
  #ifdef DEBUG_BELPOOL
    Console.println("Ok");
  #endif
}

//---- Configuration de l'ecran LCD
void lcd_setup(){
  #ifdef DEBUG_BELPOOL
    Console.print("Setup Lcd...");
  #endif
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("BelPool v1.0");
  lcd.setCursor(0,1);
  lcd.print("    Demarrage");
  delay(1000); 
  #ifdef DEBUG_BELPOOL
    Console.println("Ok");
  #endif
}

//---- Configuration du DS1621
void ds1621_setup(){
  #ifdef DEBUG_BELPOOL
    Console.print("Setup DS1621...");
  #endif
  Wire.begin();
  Wire.beginTransmission(DS1621);           // connect to DS1621 (#0)
  Wire.write(0xAC);                          // Access Config
  Wire.write(0x02);                          // set for continuous conversion
  Wire.endTransmission();
  delay(50);
  Wire.beginTransmission(DS1621);           // restart
  Wire.write(0xEE);                          // start conversions
  Wire.endTransmission();
  #ifdef DEBUG_BELPOOL
    Console.println("Ok");
  #endif
}

//---- Lecture de la temperature sur le DS1621
float ds1621_read(){
  #ifdef DEBUG_BELPOOL
    Console.print("Lecture DS1621...");
  #endif
  float temp = 0.;
  Wire.beginTransmission(DS1621);
  //lecture de temperature
  Wire.write(0xAA);
  Wire.endTransmission();
  //demande de 2 octets
  Wire.requestFrom(DS1621, 2);
  //partie entiere de la temperature
  temp = (float)((int)(Wire.read()));
  //ajout de 0.5 deg au besoin
  if(Wire.read()) temp+=0.5;
  #ifdef DEBUG_BELPOOL
    Console.print("Tair: ");
    Console.print(temp);
    Console.println(" deg C");
  #endif
  return temp;
}

//---- Evenement de lecture du DS1621
void Tair_event(TimerInformation* Sender){
  //lecture du DS1621 et ecriture sur le bridge REST
  digitalWrite(ACT_LED,HIGH);
  Bridge.put("Tair",String(ds1621_read()));
  digitalWrite(ACT_LED,LOW);
}
//---- Fonction de Boucle
void loop(){
  TimedEvent.loop();  //timers
  ButtonEvent.loop(); //boutons
  //messages_loop();    //messages de la mailbox
}

simon_schvartzman

#7
Nov 18, 2013, 02:12 pm Last Edit: Nov 20, 2013, 09:54 am by simon_schvartzman Reason: 1
Federico, in my case the program reads the  wind speed and direction from an Sparkfun weather station (https://www.sparkfun.com/products/8942) and sends a request to a Web server to display the data.

If you want to run the program use W2S26 as your Yun's name  and see the post on http://wind2surf.com/ choosing Torino, Italy as your "Praia" (beach). (you don't need to have a weather station...)

Let me know what you find out.

Thanks

.


woniol

I have the same problem.
with Yun out of the box , i run Bridge example without modifications.
I can connect to Yun via Web browser and call http://192.168.0.22/arduino/digital/13/1

Then i set the GET request to Youn from extenal program like curl and call this request with 500ms time inteval.
After some time I don't get response from Yun,
When i call http://192.168.0.22/arduino/digital/13/1 via Web Browser again i get:
Session data invalid!
stack traceback:
   [C]: in function 'assert'
   ?: in function 'read'
   ?: in function 'reap'
   ?: in function 'dispatch'
   ?: in function <?:194>

It is clear Yun config and clear Bridge sketch.
I set password option in Yun's Rest config.

OttoF

i have the same Problem

i work on a Aquarium light controll.
For this i build a sql database to write the the set values from a php webpage on linino ( works fine )
Now a cron job reads every minute the values from the sql database and write it with bridge put into the arduino.
The Arduino reads the values with bridge get to controll the lights.
Everything works fine for a while.
But after a few houres the linino webconnection hangs
so the php webpage on linino is not accessible and the wifi connection to linino do not work at all.
So i have to setup the linino wifi complete new and ressart the arduino board with power off.
Afterwards it works to for the next hours, and so on.
Any idea ?

olivb

Hello,

Could this be a problem of memory management of python ?
Because if don't make repetitive calls to the bridge for about 1h, everything seems to be ok again.

woniol

Hi,
It looks similar in my case.
The slow down isn't only ralated to REST, when I try to login via ssh,  reponse is olaso very slow.
I was doing some tests with wired connection and at first it looked like the problem was only on WIFI, but
after some time like an hour or two, the 'slow down' apeared again.

simon_schvartzman

Olivb, at least in my case your theory
Quote
memory management of python

doesn't apply. I'm not using Python, just plain Arduino C code and another thing to point out is the fact that the problem occurs without a timing pattern. Sometimes the Yun stops after a few hours and now it has been working for 3 days.

woniol


OttoF

This is really annoying,
this makes the yun nearly senseless.
On Arduinos side is too less Memory for extensive projekt
so we have to go on lininos side,
but if the communication do not work i see no way for use.
I think it is very important to solve this problem.

Go Up