Reputation: 73
I am trying to use the arduino yun to output the number of parts a machine has produced to a google spreadsheet. With the setup I have, I am able to output data to the spreadsheet temporarily. However, after some time, the yun stops working. The red LED I have on to indicate the code is running turns off, and I can no longer see the arduino in the port list. A reset of the 32u4 chip causes the LED to turn back on, indicating the code is running, but the board still does not appear in the port menu.
I have tested it at our workshop and it has run for 7-12 hours with no problems at all. It is only when we take it on to the production floor that we start experiencing these problems. Does anyone have any idea what the issue could be? Here is the most relevant part of the code:
#include <elapsedMillis.h>
#include <Process.h>
#include <Bridge.h>
#include "TimeLib.h"
// On Arduino: 0 - 1023 maps to 0 - 5 voltsf
#define VOLTAGE_MAX 5.0
#define VOLTAGE_MAXCOUNTS 1023.0
unsigned int buttonCount = 0;
float voltage = 0;
elapsedMillis timeSinceLastCycle = 0;
elapsedMillis transmitData = 0;
int pressFlag = 0;
Process date;
int hours, minutes, seconds;
int lastSecond = -1;
Process sendData;
String printDate() {
// String currTime = String(hours) + ":" + String(minutes) + ":" + String(seconds);
if (lastSecond != seconds) { // if a second has passed
// print the time:
if (hours <= 9) {
Console.print("0"); // adjust for 0-9
}
Console.print(hours);
Console.print(":");
if (minutes <= 9) {
Console.print("0"); // adjust for 0-9
}
Console.print(minutes);
Console.print(":");
if (seconds <= 9) {
Console.print("0"); // adjust for 0-9
}
Console.println(seconds);
// restart the date process:
if (!date.running()) {
date.begin("date");
date.addParameter("+%T");
date.run();
}
}
//if there's a result from the date process, parse it:
while (date.available() > 0) {
// get the result of the date process (should be hh:mm:ss):
String timeString = date.readString();
// find the colons:
int firstColon = timeString.indexOf(":");
int secondColon = timeString.lastIndexOf(":");
// get the substrings for hour, minute second:
String hourString = timeString.substring(0, firstColon);
String minString = timeString.substring(firstColon + 1, secondColon);
String secString = timeString.substring(secondColon + 1);
// convert to ints,saving the previous second:
hours = hourString.toInt();
minutes = minString.toInt();
lastSecond = seconds; // save to do a time comparison
seconds = secString.toInt();
String currTime = hourString + ":" + minString + ":" + String(seconds);
return currTime;
}
}
void checkVoltage() {
int sensorValue = analogRead(A0);
voltage = sensorValue * (VOLTAGE_MAX / VOLTAGE_MAXCOUNTS);
Console.println(voltage);
delay(50);
if (voltage >= 4.9 && pressFlag == 0) {
Console.println("Delaying");
sensorValue = analogRead(A0);
voltage = sensorValue * (VOLTAGE_MAX / VOLTAGE_MAXCOUNTS);
if (pressFlag == 0 && voltage >= 4.9) {
unsigned long int intCycleTime = timeSinceLastCycle;
timeSinceLastCycle = 0;
digitalWrite(LED_BUILTIN, LOW); // turn the LED on (HIGH is the voltage level)
printDate();
String pressTime = printDate();
Console.print("PressTime is ");
Console.println(pressTime);
buttonCount++;
Console.println(buttonCount);
pressFlag = 1;
String part1 = "curl -X POST -H \"Content-Type: application/json\" -d '{\"value1\":\"";
String timeString = pressTime;
Console.print(timeString + " seconds");
String part2 = "\",\"value2\":\"";
String numParts = String(buttonCount);
String part3 = "\",\"value3\":\"";
String strCycleTime = String(intCycleTime / 1000); // + " seconds";
String part4 = "\"}' https://maker.ifttt.com/trigger/arduino2Request/with/key/gL8YmxeaUChOMJvmwpdXp -k";
//curl -X POST -H "Content-Type: application/json" -d '{"value1":"1","value2":"2","value3":"3"}' https://maker.ifttt.com/trigger/arduino2Request/with/key/gL8YmxeaUChOMJvmwpdXp
String curlString = part1 + timeString + part2 + numParts + part3 + strCycleTime + part4;
// The curl string sends data to oue excel spreadhsheet using the IFTTT web service
sendData.runShellCommandAsynchronously(curlString);
elapsedMillis breakTimer = 0;
/*while(sendData.running()){
if(breakTimer > 5*1000){
break;
}
} */
Console.print("Data Available: "); // A value of 32 indicates a successful transmission of data, 0 also works if run asynchronously.
Console.println(sendData.available());
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
}
}
else if (voltage < 2.5) {
pressFlag = 0;
}
}
void setup() {
Bridge.begin();
Console.begin();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
// run an initial date process. Should return:
// hh:mm:ss :
if (!date.running()) {
date.begin("date");
date.addParameter("+%T");
date.run();
}
}
void loop() {
checkVoltage();
if ((timeSinceLastCycle > 300000) && (transmitData > 300000)) { // If 5 minutes have elapsed without a part being produced, output that the arduino is transmitting even if not part is available
sendData.runShellCommand("curl -X POST -H \"Content-Type: application/json\" -d '{\"value1\":\"1\",\"value2\":\"Arduino Transmitting\"}' https://maker.ifttt.com/trigger/transmitData/with/key/gKRo-zSur5rj6rD5rviCaV2RHI5g56Dy0Vc0S_XJ-oO -k");
transmitData = 0;
}
}
UPDATE: I added a series of print statements to the checkVoltage function. The code above has been updated to reflect this. I found that it hung when trying to use sendData.runShellCommandAsynchronously. The output looks like
1.58
1.54
5.00
Delaying
PressTime is n" -d
3
Could the network connection cutting out when trying to runShellCommand cause this issue?
Upvotes: 2
Views: 362
Reputation: 73
So after following user3629249's solution, this issue appears to be resolved. Have now had multiple weeks of error free runtime. user3629249, if you want to repost your advice as an answer, I will accept it. Thank you to user3629249 and Patrick Trentin for your help!
My update ProcessDate function now contains:
if(date.available() >0){
while (date.available() > 0) {
// get the result of the date process (should be hh:mm:ss):
String timeString = date.readString();
// find the colons:
int firstColon = timeString.indexOf(":");
int secondColon = timeString.lastIndexOf(":");
// get the substrings for hour, minute second:
String hourString = timeString.substring(0, firstColon);
String minString = timeString.substring(firstColon + 1, secondColon);
String secString = timeString.substring(secondColon + 1);
// convert to ints,saving the previous second:
lastSecond = seconds; // save to do a time comparison
lastMinute = minutes;
lastHour = hours;
hours = hourString.toInt();
minutes = minString.toInt();
seconds = secString.toInt();
String currTime = hourString + ":" + minString + ":" + String(seconds);
return currTime;
}
else{
String currTime = ""; // If there is no result from the date process, return nothing. Should not happen.
return currTime;
}
}
Upvotes: 1