Data transfer instability Arduino Yun

I’m using Arduino Yun to get measurement data from numerous sensors into cayenne widgets. My problem ist that after few minutes of proper operation the connection gets down and I need to restart my board in order to get upload working again.

It’s quite frustrating so I’d like to ask the following:

Is there a way to debug the data upload in order to see where the problem may be? …are there any official data volume, speed limitations I need to take into account but I don’t know about it?

Thanks!

Try adding some delays to your code. Arduinos can crash and stop responding if there is too much going on. If you post your code we can make some more suggestions.

@jungi77,

Also, quite a few people have had issues with power supplies whether on the Raspberry Pi or the Arduino.

How are you powering your Yun? What sensors? How many sensors? Are you powering the sensors with the same power supply?

AFAIK, if you don’t run Cayenne.Run() every 20 seconds or so, Cayenne might sense a disconnect, but I don’t know if this is truly the case. You can see what the current timeout is in the CayenneDefines.h file I think.

As @adam says, share your code. We need more details if we are to help.

Cheers,

Craig

Thanks for the quick response! Please see my script code below. I’ve been playing with this code trying to narrow down the potencial bug. Delays and reduction of the number of senors didn’t make any change, the transfer stops after 4-5 minutes anyway. I also noticed the stops watching the serial monitor and I started to think that my ardunio may indeed have a problem, but when I commented out the cayenne call in the main loop “Cayenne.run();” the board itself was working properly. I’ve tried o power it from my PC, power bank and mains adpter no change. What else can I try?

/*
  Cayenne BMP180 Example

  This sketch shows how to send luminosity data to a BMP180 Sensor in the Cayenne Dashboard.

  The Cayenne Library is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.

  Steps:
  1. Install the Adafruit Unified Sensor library (https://github.com/adafruit/Adafruit_Sensor) from the Arduino Library Manager.
  2. Install the Adafruit BMP085 Unified library (https://github.com/adafruit/Adafruit_BMP085_Unified) from the Arduino Library Manager.
  3. In the Cayenne Dashboard add a new BMP180 widget.
  4. Set the widget to Value Display.
  5. Select Virtual Pins and select virtual pins for the barometer and temperature.
  6. Set BAROMETER_PIN to the pin number you selected for the barometer.
  7. Set TEMPERATURE_PIN to the pin number you selected for the temperature.
  8. Attach a BMP180 to your Arduino.
   Schematic:
   BMP180    Arduino
   [VDD] --- [3V3]
   [GND] --- [GND]
   [SDA] --- [Analog Pin 4] (The SDA may be different on some devices, e.g. for Arduino Mega the SDA pin is Digital Pin 20)
   [SCL] --- [Analog Pin 5] (The SCL may be different on some devices, e.g. for Arduino Mega the SCL pin is Digital Pin 21)
  9. Set the token variable to match the Arduino token from the Dashboard.
  10. Compile and upload this sketch.
  11. Once the Arduino connects to the Dashboard it should automatically update the BMP180 widget with data.
*/

#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <Console.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>


// If you're not using the Ethernet W5100 shield, change this to match your connection type. See Communications examples.
#include <CayenneYun.h>

// Virtual Pins of the BMP180 widget.

#define TEMPERATURE_PIN V2
#define BAROMETER_PIN V3

Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10180);
bool bmpSensorDetected = true;

//Staubsensor
#define VIRTUAL_PIN V1
int pin = 8;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 3000;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;



// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "2flp3fjaer";

void setup()
{

  // Initialize Console and wait for port to open:
  Bridge.begin();
  Console.begin();

  // Wait for Console port to connect
 // while (!Console);

  Console.println("Console initialized");

  //Staubsenor
  pinMode(8, INPUT);
  starttime = millis();

  //Serial.begin(9600);
  Cayenne.begin(token);
  if (!bmp.begin())
  {
    CAYENNE_LOG("No BMP sensor detected");
    Console.println("BMP180 nie hula");

    bmpSensorDetected = false;
  }
}

void loop()
{
  Cayenne.run();
  delay (5000);
  Console.println("Cayenne run");
  Console.println(analogRead(A0));
}

// This function is called when the Cayenne widget requests data for the barometer's Virtual Pin.
CAYENNE_OUT(BAROMETER_PIN)
{
  Console.println ("Cayenne call pressure");
  if (bmpSensorDetected)
  {
    // Send the command to get data.
    sensors_event_t event;
    bmp.getEvent(&event);

    if (event.pressure)
    {
      // Send the value to Cayenne in hectopascals.
      Cayenne.hectoPascalWrite(BAROMETER_PIN, event.pressure);
      Console.println("event.pressure");
      Console.println(event.pressure);
    }
  }
  else
  {
    CAYENNE_LOG("No BMP sensor detected");
  }
  delay(20);
}

// This function is called when the Cayenne widget requests data for the temperature's Virtual Pin.
CAYENNE_OUT(TEMPERATURE_PIN)
{
  Console.println ("Cayenne call temperature");

  if (bmpSensorDetected)
  {
    float temperature;
    bmp.getTemperature(&temperature);
    // Send the value to Cayenne in Celsius.
    Cayenne.celsiusWrite(TEMPERATURE_PIN, temperature);
    Console.println("temperature");
    Console.println(temperature);
  }
  else
  {
    CAYENNE_LOG("No BMP sensor detected");
  }
  delay(20);
}

CAYENNE_OUT(VIRTUAL_PIN)
{

  //Staubsensor
  duration = pulseIn(pin, LOW);
  lowpulseoccupancy = lowpulseoccupancy + duration;

  if ((millis() - starttime) > sampletime_ms)
  {
    ratio = lowpulseoccupancy / (sampletime_ms * 10.0); // Integer percentage 0=>100
    concentration = 1.1 * pow(ratio, 3) - 3.8 * pow(ratio, 2) + 520 * ratio + 0.62; // using spec sheet curve
    Console.println("Staubsensor");
    Console.print(lowpulseoccupancy);
    Console.print(",");
    Console.print(ratio);
    Console.print(",");
    Console.println(concentration);
    lowpulseoccupancy = 0;
    starttime = millis();
  }
  Cayenne.virtualWrite(VIRTUAL_PIN, concentration, TEMPERATURE, CELSIUS);
  Console.println("concentration");
  Console.println(concentration);
  delay(20);


}

Hi, I’m facing a similar situation on my project. I have a MEGA reading sensors, then it stores measurements on an SD card and sends them to Cayenne.
If I disable Cayenne.run() , everything works continuously. If I enable Cayenne they do work for a few minutes and the connection to Cayenne starts failing, it reconnects a few times then the whole system stops.

My code’s main loop looks like this:
I use timer.h to simplify timed executions.

#include “Timer.h”

//**************************************
//*** MAIN ***
//*** LOOP ***
//**************************************
void loop() {
time_t tmk = now();
if ((tmk - tmPreviousOscilateLED) > 1) {
iAmAlive = !iAmAlive;
if (iAmAlive) DEBUG_PRINTS(“|”);
else DEBUG_PRINTS(“-”);
tmPreviousOscilateLED = tmk;
}
t.update(); // triggers all timer t objects defined on setup
}

//**************************************
//*** Configure all timed ***
//*** routines - key control ***
//**************************************
void triggerTimers() {
t.oscillate(ledPin, 400, LOW); //DEBUG_PRINTS(“LED blinking timer enabled\n”); // use timet t to blink the led 1/10 of sec (1000=1s)
t.every(1000 * smplFreq, takeReading); //DEBUG_PRINTS(“Measurements timer enabled\n”); // sensors reading routine at ajdusted frequency (1000=1s)
t.every(1000, updateTimeText); //DEBUG_PRINTS(“‘Time text’ timer enabled\n”); // keeps timeText String with the current date and time
t.every(1000 * smplFreq, writeResultsToSD); //DEBUG_PRINTS(“‘Write results to SD’ timer enabled\n”); // write results with the same read rate to SD
t.every(1000 * smplFreq / 2 , prindSnsrsLCD); // update LCD with measured values
t.every(1000, runCaienne); //
//t.every(1000 * smplFreq, freeMem); //DEBUG_PRINTS(" Prints freeMem for debugging\n");
// t.every(1000 * 3600 * timeUpdateFreq, updateNTS); // Syncs time with internet’s NTS from time to time
}

void runCaienne() {
// DEBUG_PRINTS(“I”);
Cayenne.run();
// DEBUG_PRINTS(“F”);
}

Are you getting any errors in your serial monitor?

Hello, I know this topic should focus on jungi77’s description, but given the similarity, I am sharing my discoveries here…
Perhaps jungi77 could try something similar to see if it has the same behavior.

I send temperature data using Virtual Ports back to Cayenne. I added some Serial.Prints on every stage of my code for each Virtual port. The code now looks like this for every Virtual Port.

CAYENNE_OUT(V1) {
  Serial.print(F("1")); //freeMem();
  byte i = 0;
  //  printV(i);// prints sensor information being sent to Cayenne
  if      (sensorUnit[i] == F(" C  ")) {
    Cayenne.virtualWrite(V1,        sensorMeasureVal[i],        TEMPERATURE,  CELSIUS);
    Serial.print(F("a")); //freeMem();
  } else if (sensorUnit[i] == F(" %  ")) {
    Cayenne.virtualWrite(V1,        sensorMeasureVal[i],        HUMIDITY,     PERCENT);
    Serial.print(F("b")); //freeMem();
  }  else if (sensorUnit[i] == F(" hPa")) {
    Cayenne.hectoPascalWrite(V1, sensorMeasureVal[i]);
    Serial.print(F("c")); //freeMem();
  }
  Serial.print(F(".")); //freeMem();
}

I am printing a letter just before Cayenne.virtualWrite() command and a “.” right after it.
During execution, my output looks like this:
1a.2a.3a.4a.5b.0.1a.2a.3a.4a.5b.0.1a.2a.3a.4a.5b.0.1a.2

sensors 1-4 are temperature and sensor 5 is humidity. Sensor 0 is just a blink to indicate on Cayenne the system is alive.

The code stops “randomly” on any of the sensors. In the above example it stopped on sensor 2 as there is no “.” after it at the end of the line.

The conclusion is that the call to write to cayenne is done but never returns.
Any suggestion for further debugging?

Hi, I enabled CAYENNE_DEBUG and CAYENNE_PRINT.
The final output lines before stopping were in this case:

b.[40609] >msg 20,36,4

vr0
0[40610] <msg 20,36,6
<vw00
.[43108] state 1, tconn 1
[43109] >msg 20,37,4
vr1
1[43111] <msg 20,37,18
<vw1temp,c=25.688
a.[43609] >msg 20,38,4
vr2
2[43610] <msg 20,38,18
<vw2temp,c=25.625

then it stops.

On other runs I got:

vr1
1[119617] <msg 20,13,18
<vw1temp,c=25.813
a.[120115] >msg 20,14,4
vr2
2[120117] <msg 20,14,18
<vw2temp,c=25.625
a.[120615] >msg 20,15,4
vr3
3[120617] <msg 20,15,18
<vw3temp,c=25.938
a.[121115] >msg 20,16,4
vr4
4[121117] <msg 20,16,18
<vw4temp,c=26.200
a.[121615] >msg 0,17,4
[122115] >msg 118,29184,13588
[125114] state 0, tconn 0
[128114] Connecting to arduino.mydevices.com:8442

then it stopped. This last one it crashes trying to connect.
I have other box with an arduino connected to the same hub that controls my home and works just fine 24x7 so I know I don’t have network connection problems.
Another detail, I replaced the ethernet shield just to be sure it was not it.

Any ideas or suggestions?
Thanks.

@carlos,

I suggest you simplify your code and see what happens.

Try this:

int counter = 0;

CAYENNE_OUT(V1) 
{
  Serial.println("Entering V1 Out");

  if(counter == 0)
  {
     Serial.println("Sending Temp...");
     Cayenne.virtualWrite(V1,10.0, TEMPERATURE, CELSIUS);
  }
  else if (counter == 1)
  {
     Serial.println("Sending Humidity...");
     Cayenne.virtualWrite(V1,20.0, HUMIDITY, PERCENT);
  }
  else 
  {
     Serial.println("Sending Pressure...");
     Cayenne.hectoPascalWrite(V1, 30.0);
  }

  counter++;
  if(counter > 2) counter = 0;

 Serial.println("Leaving V1 Out");
}

If this works consistently, then I would suggest you have other issues with array and F() processing to address.

Cheers,

Craig

Hi, thanks for your suggestion. F() is not an array but it is a function of the compiler to store Strings in flash, not memory, to save RAM. In the beginning of facing this error, I thought that I had lack of RAM and condensed every byte I could. I’ve been using this F() wrapper for quite some time but who knows…
http://playground.arduino.cc/Learning/Memory

I will try bringing the strings back to RAM and see what happens… and simplify the code as you suggested.
Will let you know.
Thanks again

Yep. I use F() too. Just want to isolate and see if there is a Cayenne bug
or something else.

Hi, I replaced my code with your example for the 5 sensors, giving each a different counter (counter, counter2, counter3… counter5) so each is unique.

Unfortunately… it stopped as before. Here is the output:
Sending Temp…
Leaving V1 Out
Entering V2 Out
Sending Temp…
Leaving V2 Out
Entering V3 Out
Sending Temp…
Leaving V3 Out
Entering V4 Out
Sending Temp…
Leaving V4 Out
Entering V5 Out
Sending Temp…
Leaving V5 Out
0.43_44_45_46_47_Entering V1 Out
Sending Pressure…
… and stopped here. The problem repeats stopping at different point, just as before.

I also moved Cayenne to the main loop instead of being called from a timer.
//**************************************
//*** MAIN ***
//*** LOOP ***
//**************************************
void loop() {
t.update(); // triggers all timer t objects defined on setup
Cayenne.run();
}

Still stops.

Then I tried commenting-out calls for new measurements and SD data storing so it is essentially Cayenne only running and a time ticker.

void triggerTimers() {
t.every(1000, updateTimeText); //DEBUG_PRINTS(“‘Time text’ timer enabled\n”); // keeps timeText String with the current date and time
t.every(1000, printSnsrsLCD); // update LCD with measured values
// t.every(1000 * smplFreq, takeReading); //DEBUG_PRINTS(“Measurements timer enabled\n”); // sensors reading routine at ajdusted frequency (1000=1s)
// t.every(1000 * smplFreq, writeResultsToSD); //DEBUG_PRINTS(“‘Write results to SD’ timer enabled\n”); // write results with the same read rate to SD
// t.every(300, runCayenne);
t.oscillate(ledPin, 400, LOW); //DEBUG_PRINTS(“LED blinking timer enabled\n”); // use timet t to blink the led 1/10 of sec (1000=1s)
t.every(1000, toogleAlive);
// t.every(1000 * 3600 * timeUpdateFreq, updateNTS); // Syncs time with internet’s NTS from time to time
}

Ran couple of times and the problem remains…
end of last output was:
end of setup()
11_12_13_14_15_16_17_18_19_20_21_Entering V1 Out
Sending Temp…
Leaving V1 Out
Entering V2 Out
Sending Temp…
Leaving V2 Out
Entering V3 Out
Sending Temp…
Leaving V3 Out
Entering V4 Out
Sending Temp…
Leaving V4 Out
Entering V5 Out
Sending Temp…
Leaving V5 Out
0.22_23_24_25_26_Entering V1 Out
Sending Pressure…
Leaving V1 Out
Entering V2 Out
Sending Humidity…
Leaving V2 Out
Entering V3 Out
Sending Temp…
Leaving V3 Out
Entering V4 Out
Sending Humidity…
Leaving V4 Out
Entering V5 Out
Sending Humidity…
Leaving V5 Out
27_0.28_29_30_31_Entering V1 Out
Sending Humidity…
Leaving V1 Out
Entering V2 Out
Sending Pressure…
Leaving V2 Out
Entering V3 Out
Sending Temp…
Leaving V3 Out
Entering V4 Out
Sending Pressure…
Leaving V4 Out
Entering V5 Out
Sending Pressure…
Leaving V5 Out
32_0.33_34_35_36_Entering V1 Out
Sending Pressure…
Leaving V1 Out
Entering V2 Out
Sending Temp…
Leaving V2 Out
Entering V3 Out
Sending Temp…
Leaving V3 Out
Entering V4 Out
Sending Temp…
Leaving V4 Out
37_38_39_40_41_

Any other ideas?
Thanks again.

No idea. Have you tried just running the standard Cayenne code with that VOUT function and watching it run consistently?

Craig

Hi kreggly and jungi77,

I have made a few more things but still no success…
jungi77, were you able to solve your problem on Yun?

Here’s what I did:

  1. Replaced arduino board and Ethernet shield with different brands.
  2. Simplified the code to bare bones (appended bellow). Started from Cayenne’s suggested base code and added 5 Virtual’s, passing fixed values as your suggested code. No sensors, no LCD, buzzers, internal clock or SD cards.
  3. Created a new machine from scratch on the web using a new token and simple displays all defaults.
  4. turned off all other Arduino’s connected to Cayenne at home (didn’t check but perhaps I thought it was a MAC address conflict.

After all this, it still locks after a minute or so apparently by not being able to connect to Cayenne. It all starts OK, then a few connection losses then it dies.
My other arduino’s work well, on the same network.

  1. I was powering the arduino on USB, Just to be sure, I connected also a power supply to ensure it’s not it.
  2. Reset my router (airport) just in case.
  3. Plugged the ethernet cable directly to my router ( It was on a hub connected to the router).

When I commented initially, mentioning that the problem was between Cayenne and the SD, I was not waiting enough to Cayenne to crash.

It still locks after a minute or so. It runs for a few looks (10-15) and starts loosing connection, recovering and the reconnect a few times with time increasing till full crash.

It’s getting really hard to believe it is not some sort of bug perhaps based on the particular case of 6 my Virtual sensors …
I have no other ideas to isolate the problem and am very frustrated as I’ve been very successful with Cayenne. I’ve been trying to solve this for weeks and spend many many hours on it.

The code I was running is now:

#define CAYENNE_DEBUG // Uncomment to show debug messages
#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space
#include <CayenneEthernet.h>
// Cayenne authentication token. This should be obtained from the Cayenne Dashboard
char token = “n4bs70uwdh”;
boolean iAmAlive;

void setup() {
Serial.begin(9600); // get ready to print info on serial if DEBUG_PRINT is enabled
Serial.print(F(“Hi”));
Cayenne.begin(token); }

void loop() { Cayenne.run(); } // couldn’t make is more simple :slight_smile:

// Sending Data to Cayenne.
CAYENNE_OUT(V0) {// When V0 is called, all remaining configured Virtual pins are also called afterwards
Serial.print(F(“0”));
Cayenne.virtualWrite(V0, iAmAlive); // This is the only addition to give an indication it is working on the web.
iAmAlive = !iAmAlive;
Serial.print(“.”);
}

int counter = 0;
CAYENNE_OUT(V1) { Serial.println(“Entering V1 Out”);
if(counter == 0) {
Serial.println(“Sending Temp…”);
Cayenne.virtualWrite(V1,10.0, TEMPERATURE, CELSIUS);
} else if (counter == 1) {
Serial.println(“Sending Humidity…”);
Cayenne.virtualWrite(V1,20.0, HUMIDITY, PERCENT);
} else {
Serial.println(“Sending Pressure…”);
Cayenne.hectoPascalWrite(V1, 30.0); }
counter++;
if(counter > 2) counter = 0;
Serial.println(“Leaving V1 Out”);
}
and I repeated V1 other 4 times adjusting the variables to V2…V5

Hi @rob,

Don’t know if it is possible to look into this for @carlos_benjamin

His bare bones sketch should work. Issue with the Yun maybe?

I’m going to try and run this code on the weekend and see if it continues to run.

Cheers,

Craig

Hi, I’running on a Mega 2560 (not Yun) and 5100 Ethernet Shield (tried also on official Arduino Ethernet).
I ordered a whole new set of hardware to change to everything new but it should take a few days to get my order here.
If I disable Cayenne, it runs fine off-line. Its either a bug on Cayenne, Ethernet shield problem ( although I tried three shields…) or a network issue (although other 2 Arduino’s doing different things running fine with Cayenne, all identical hardware the same network).

Folks, look what I found.

I added the 2 100 ohm resistor on one of the 5100 Shields I have and the instability seem to have disappeared. It’s running fine for 15 mins…
I will leave it for the night and tomorrow will try the real version if it is still alive.
Finally some progress.
I am just wandering why the official Ethernet Shield also gave problems.
Finally some hope.
Good weekend to all.
Carlos.

1 Like

Hi, unfortunately the problem returned when going to the full hardware version.
Going back to the lab… :frowning:
If I enable Cayenne.run(), the program stops at some point in time during loop() execution.
If I comment the line, it works.

Sounds like you have something that is blocking the cayenne loop. Can you post your entire code?

Hi, you can download the entire code here: http://www.cdtsilva.com/mainProgram.zip
There is a file called config.txt that must be in an SD card and it contais stuff like timezone, sensors types names and location on the board.
Hope it helps.
Thank you for helping me.
Carlos