Data transfer instability Arduino Yun

This morning I thought about having some sort of MAC address conflict on my network between multiple arduino’s so I basically turned off all of them at home as well as most devices (TV, repeaters, most computers and phones etc. so I could be certain that there wasn’t any type of network conflict.
Still no success. If I disable Cayenne.run() the program works fine, if I enable it, it stops randomly.

I have a question though. How can I set the mac address when starting Cayenne while still using DHCP in order to have an IP? From the examples I found it’s either

Cayenne.begin(token);
or
Cayenne.begin(token, ipAddress, ipDNS, ipGateway, subnet_mask, mac);
I tried
Cayenne.begin(token, , , , , mac);
but it gave me an error.

So, I used a small code that the first time it runs, it generates a random mac and stores it on EEPROM, from that on, if the mac is on EEPROM, it uses it.
I then tried to use the following:

  Ethernet.begin(mac);
  Cayenne.begin(token);

and it does not give me any error, but when I enable “#define CAYENNE_PRINT Serial” it prints a completely different MAC. This is why I decided to check the MAC id’s.

How can I do it properly?

( I am still fighting to figure out what is wrong with Cayenne… please see if you find a bug or something wrong with my code).

Thanks.

Well, seems like by reversing the lines it works, even thought the crash still happens, but the network uses the MAC I defined:

Cayenne.begin(token);
Ethernet.begin(mac); // this seems to change the MAC to the one I defined.

Is this the right way to do it?

Thank you

@carlos_benjamin,

I have yet to see a complete sketch. Some people have had issues with older ethernet libraries. Some have had issues with dns lookups. The ethernet shields can be a nightmare. I haven’t had one yet that worked right.

You can also try connecting your Yun directly through the USB, and running the serial redirector script. to isolate.

If you are still having problems, I suggest sending a complete sketch so someone else can run it and perhaps confirm the issue.

Moving the order of the calls doesn’t ring a bell to me.

Cheers,

Craig

Craig,
I have tried all I could think of.
checked ip and mac uniqueness, tested with fixed and w/ DHCP, connected in hub and straight to the internet’s router. Replaced the Arduino and the ethernet shield, powered the boards with a power supply in addition to USB. I tried your suggestion to write back a constant instead of a variable with no luck.
Bare bone works but when adding the real hardware/sensors and associated code the problem returns and the code stops during calls to virtualWrite().
I even tried reading sensors once during setup() and just send data in the main() loop without reading or writing anything so only Cayenne was being called in the main() loop.

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

Seems like for some reason the connections is being lost

I enabled Cayenne_Debug and Cayenne_Print and pasted below only the last line before crash from 6 consecutive runs. Sometimes it crashes in the middle of a result transfer, sometimes while trying to connect.

  1. [54412] Connecting to arduino.mydevices.com:8442
  2. [130018] <msg 20,13,18 <vw1temp,c=26.750
  3. [25700] Connecting to arduino.mydevices.com:8442
  4. 4[90952] <msg 20,28,18
  5. [28550] Connecting to arduino.mydevices.com:8442
  6. [27696] Connecting to arduino.mydevices.com:8442

Important to note that it contacts to Cayenne and gets the data sent a few time before stopping.
You can read the values on mydevices.com, then it stops.
I bought another Arduino and shield but don’t believe it will change a thing. If I knew how to dig deeper I would.

What did you mean by:

Thank you.
Carlos.

When you create a new device, you can pick the serial connection sketch.
The run a script on your pc to redirect serial traffic to the Cayenne
server port.

This will bypass your shield ethernet connections, using your computer’s
ethernet connection.

We aren’t seeing this issue often with other’s setups, so there must be
something with your hardware, your network, power, interference, etc.

I really want to see a full sketch to see if someone else can repeat this
issue. The entire sketch should include the header declarations, the setup,
loop, and other used functions.

Cheers,

Craig

Craig,

Yesterday, I searched for an older version of the code that was working. I was willing to loose my work and start again from it, step by step, and then I started copying code from the problematic one replacing the older code in the good older version, feature by feature, enhancement by enhancement. I truly thought that this would give me a lot o work but I was willing to do it. For my surprise, given that the overall architecture was obviously the same, the migration was quite fast and the necessary features were all migrated and IT IS WORKING!!! You have no idea of how happy I am, but what I want, now that I have a working one, is to compare the remaining differences cause the key points of data measurement, time keeping LCD display and data storing to SD and Cayenne interface are now the same, so what a heck is wrong with the code I had? Honestly I have no idea.
If I find what the problem was, I will post the solution here so if this ever happens again with someone else, the solution will be shared.
Thank you for your support, I know you and the Cayenne team was probably getting into it to figure out. I am a fan of the solution Cayenne provides and will continue to use it.

Thanks again.
Carlos.

I’m glad you finally got there. Good job! Persistence is the key to development.

A couple other things that might help you going forward, test things modularly, and use source control. I’m in the habit of checking in every time I get up for a cup of coffee, or build a module. Then test each piece you build to make sure it works reliably, and if it’s broken, you retrieve your latest working image, and do a textual diff to see what you did that broke things.

We are fortunate that today you have Git, SVN, and many other tools integrated that makes this a no brainer. When I started programming, we had SCS, but only on Unix machines. We’ve come a long way baby.

Cheers,

Craig

Hi, unfortunatelly I cannot always keep up with the technical discussion, but I’ve been following it trying to do some RCA by myself. What I’ve observed so far is that there is no difference if I use WiFi or Ethernet cable. Setting a different delay value in the main loop allowed me to count the number of calls and notice the delay between the data transfer from my YUN and it’s apperance on the dashboard. So, no matter what delay I set there are 7 to 10 calls before the tranfer crashes and there is a delay bewteen 1 and 2 calls before data appears on the dashbord. So that’s it I guess. I hope for a solution one day… keep up the good work!

@jungi77,

What does your current code look like? Did you try it with just Cayenne.run() in your loop?

Have you considered putting your calls to the BMP library and your Staubsensor reading into separate functions that get called periodically using timer.h functions? Get them to update global variables, and just drop the global variables in the CAYENNE_OUT functions.

Cheers,

Craig

@kreggly

sorry again for not responding for so long. I’ve been checking my Arduino Yun on the general ability to continously transfer data, and it seems that my hardware is fine.
This mornig I’ve finally followed your suggestion and simplified the code and it works fine! I have a transfer that has been going for one hour now!!! …I’ll let it run for few hours to see if it stays this way.
In the coming days I’ll try to add more different senors - I’ll be back with more input in the course of this week.

Cheers!

 /*
Cayenne Generic Analog Input Example

This sketch shows how to automatically send data to a Generic Analog Input 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. In the Cayenne Dashboard add a new Generic Analog Input widget.
2. Set the widget to Value Display.
3. Select the Integrated ADC and a pin number.
4. Attach an analog input device (e.g. a potentiometer) to the analog pin on your Arduino matching the selected pin.
   Make sure to use an analog pin, not a digital pin.
5. Set the token variable to match the Arduino token from the Dashboard.
6. Compile and upload this sketch.
7. Once the Arduino connects to the Dashboard it should automatically update the Generic Analog Input widget with data.
*/

#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space

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


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

void setup()
{
  //Serial.begin(9600);
 // Bridge.begin();
  Cayenne.begin(token);
}

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

Super.

Just a note, when you share code, please highlight it and hit pre-format </> on the toolbar. I did it for you this time, but as you can see, it helps with readability.

Let us know how we can help when you start adding extra sensors. We want to start adding good coding practice bits to our library.

Cheers,

Craig

@kreggly
Hi, I haven’t got to timer.h usage yet but I’ve made another few steps towards narrwing the issue, which I susspect is related to CAYENNE_OUT function.

So far, I’ve testes a single and multiple analog data transfer - works just fine. I’ve also tested transfering both digital and analog data unsing virtual pin over CAYENNE_OUT function (see the code below) - works fine again .

But when I try to include the autmatically generated BMP180 widget code, I don’t even get a dashboard connection.

#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <CayenneYun.h>

char token[] = "xxxxxx";

#define VIRTUAL_PIN V0

int pin = 8;
unsigned long temperature;


void setup()
{
  Cayenne.begin(token);
}


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

CAYENNE_OUT(VIRTUAL_PIN)
{
  //temperature = analogRead(A2);
  temperature = pulseIn(pin, LOW);
  Cayenne.virtualWrite(VIRTUAL_PIN, temperature);
}

Das weird

Is the code you posted there the BMP180 code? I don’t see anywhere that it even reads the BMP180 sensor.

@adam & @kreggly

The code I posted lately is the one that actually worked and I was refering to that code explicitely in my last response.

But nevertheless, I’ve just found the problem with BMP180. The problem was, that the automatically generated code for BMP180 supposed to be generated for arduino Yun but in the code itself insted of Yun library like:

#include <CayenneYun.h>

Ethernet shield library was included:

#include <CayenneEthernet.h>

I fixed that and it works fine!

…I’ll do some long time tests and play with timer.h a bit and be back to you with the results. But so far I happy with Cayenne :slight_smile: Thanks guys!

2 Likes

Neato. It feels good to solve stuff don’t it :slight_smile:

Craig

1 Like

Hi @kreggly,

I’ve just done some observation and it comes out that my transfer is stable for at least 24h, if I have max 3 widgets in place, no matter if connectivity is analog, digital or virtual. The more widgets I conntect the faster the contection is down. Do you have any explanation for that behaviuor? Is there any data transfer, or widget number limitation? …I’ve also noticed that Cayenne makes data calls every minute, but having more than 3 wigets running I can see that some of the calls are being skipped. Is this the moment where Timer.h comes into play? Will setting a longer delay than 1 minute over Timer.h help me get more widgets running stable?

I have also two questions:

  1. How do I use #define CAYENNE_PRINT Serial on arduino YUN?
  2. Is there any posibility to get history data reagrding connection time, data transfer etc for the widgets I have running?

Please include the entire sketch that is giving you the most problems.

That way, someone can try and reproduce the issue you are seeing.

I don’t have a Yun, so it would have to be someone else.

  1. As far as the CAYENNE_PRINT and CAYENNE_DEBUG, try them and see if you get more messages on the console.
  2. You can create Virtual widgets that display accumulated up time, etc.

Cheers,

Craig

Hi Craig,

please see me code below. Im just adding and deleting new wigets in the dashborad, the code stays the same.

…I cannot use Serial Monitor for debugging since Arduino Yun uses it otherwise. The alternative here is to use Bridge library #include <Console.h> but even thou the Serial Monitor shows nothing… I geuess Cayenne library doesn’t include that option.

I was thinking more of a log file or a list accesible from the dashboard but I like the idea of a virtual widgets that display accumulated up time anyway :slight_smile: … I’ll try it out.

cheers,

Artur

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



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


//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);
}

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

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);
  //  Console.println("concentration");
  //  Console.println(concentration);


}

Hi @carlos_benjamin

…I’m looking for an option to extend the period between the single cayeene calls. Therfore I’m very intersted if you old good code you mentioned in you last post works with the cayenne.run being called over a function?

Cheers,

Artur