sure @developer_bt, see below. I still have failures but is not too bad. Goes through after several attempts. I still need to debug more but its better than before when it was impossible to update.
// This #include statement was automatically added by the Particle IDE.
#include "ThingSpeak/ThingSpeak.h"
#include "application.h"
#define MB1043_5V_PIN D2
#define MB1043_SENSOR_PIN D4
#define LEDPin D7
#define publish_cycle 15000 // Only publish every 10 minutes
/* Thingspeak */
TCPClient client;
unsigned long myChannelNumber = XXXXXX;
const char * myWriteAPIKey = "YYYYYYYY";
//
unsigned int lastPublish = 0;
int arraysize =9;
FuelGauge fuel;
//float analogValue0;
float distance;
char publishStr[20];
//declare an array to store the samples from the ultrasonic sensor
//not necessary to zero the array values here, it just makes the code clearer
int rangevalue[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0};
int rangevalue2;
long pulse;
int modE;
uint32_t lastTime = millis()-(1800*1000UL);
void setup() {
// Connect to ThingSpeak
ThingSpeak.begin(client);
// Give power to the sensor
pinMode(MB1043_5V_PIN, OUTPUT);
digitalWrite(MB1043_5V_PIN, HIGH);
pinMode(LEDPin, OUTPUT);
// Connect variables to particle cloud
// This allows you to save data to particle.io, and run commands against it such as "particle variable Photon get light"
Particle.variable("dist", double(distance));
Particle.function("batt", batteryStatus);
Serial.begin(9600);
// Wait for the sensor to stabilize
delay(10);
}
void loop() {
//Serial.print("testing loop");
unsigned long now = millis();
// Read value from sensor Pin
distance = float(get_distance()); // get mean distance from sonar sensor
/*
We will publish and update ThingSpeak channel only when values of distance correspond to object detection range
so that we do not keep the little guy busy with data we do not care about, thus avoid OTA update failures
*/
if (distance < 450.00 ) {
//Turn on visual LED so we can have visual clue when it 'sees' something from
digitalWrite(LEDPin, HIGH);
// Update the ThingSpeak fields with the new data
ThingSpeak.setField(1, distance );
// Write the fields that you've set all at once.
// Publish to thinkspeak. We only publish if it has been 60 seconds since the last time we published
//if ((now - lastPublish) > publish_cycle) {
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
lastPublish = now; // update the last time we published to current time
Serial.println(" - Published!");
Serial.println(String(distance));
Particle.publish("B",
"v:" + String::format("%.2f",fuel.getVCell()) +
",c:" + String::format("%.2f",fuel.getSoC()),
60, PRIVATE);
Particle.publish("D",
"d:" + String::format("%.2f",distance,60,PRIVATE));
Particle.process(); // Looks like this helps with OTA updates
}
// else {
// Serial.println("Still under 2 minutes");
//}
//}
else {
Serial.println("No object detected");
digitalWrite(LEDPin, LOW);
Particle.process(); // looks like this helps with OTA updates
}
/*
static uint32_t msSoftDelay;
if (millis() - msSoftDelay < 1000) return;
msSoftDelay = millis(); */
}
//get the distance from the sonar sensor
int get_distance() {
///for(int i = 0; i < arraysize; i++)
//{
pulse = pulseIn(MB1043_SENSOR_PIN, HIGH);
//rangevalue[i] = pulse/10;
rangevalue2 =pulse/10;
//delay(10);
Particle.process(); // May be they are too many now, don't know but they seem to help with OTA updates
//}
//isort(rangevalue,arraysize);
//modE = mode(rangevalue,arraysize);
return rangevalue2;
}
// sort function (Author: Bill Gentles, Nov. 12, 2010)
void isort(int *a, int n){
// *a is an array pointer function
for (int i = 1; i < n; ++i)
{
int j = a[i];
int k;
for (k = i - 1; (k >= 0) && (j < a[k]); k--)
{
a[k + 1] = a[k];
}
a[k + 1] = j;
}
}
//Mode function, returning the mode or median.
int mode(int *x,int n){
int i = 0;
int count = 0;
int maxCount = 0;
int mode = 0;
int bimodal =0;
int prevCount = 0;
while(i<(n-1)){
prevCount=count;
count=0;
while(x[i]==x[i+1]){
count++;
i++;
}
if((count>prevCount)&(count>maxCount)){
mode=x[i];
maxCount=count;
bimodal=0;
}
if(count==0){
i++;
}
if(count==maxCount){//If the dataset has 2 or more modes.
bimodal=1;
}
if(mode==0||bimodal==1){//Return the median if there is no mode.
mode=x[(n/2)];
}
return mode;
}
}
// Lets you remotely check the battery status by calling the function "batt"
// Triggers a publish with the info (so subscribe or watch the dashboard)
// and also returns a '1' if there's >10% battery left and a '0' if below
int batteryStatus(String command){
// Publish the battery voltage and percentage of battery remaining
// if you want to be really efficient, just report one of these
// the String::format("%f.2") part gives us a string to publish,
// but with only 2 decimal points to save space
Particle.publish("B",
"v:" + String::format("%.2f",fuel.getVCell()) +
",c:" + String::format("%.2f",fuel.getSoC()),
60, PRIVATE
);
// if there's more than 10% of the battery left, then return 1
if(fuel.getSoC()>10){ return 1;}
// if you're running out of battery, return 0
else { return 0;}
}