DS18B20 and Particle Core

@LukeUSMC, yes Spark.variables() (or Particle.variables() as they should be called now - on Core only with fw version >= 0.4.5) should be serviced during long delay()s too.

@peekay123, that’s a noble goal, but I fear that this would break a lot of existing code, that was not written in view of the cloud (even solely written code for Particles, since the cloud runs “unseen” and hence got forgotten ;-))
I’d be with you on that, but I’m scared of the riot it could cause :worried:

1 Like

How about a user controlled behavior? Let it switch to the expected behavior of fully blocking but allow it to be overridden for those that need it.

My head is spinning now! I think it time for a new paradigm, driven by IoT. On Linux, for example, a delay() in a Processing() app won’t stop the processor from running! The blocking delay() paradigm comes from Arduino and it time to break it IMO :stuck_out_tongue_closed_eyes:

2 Likes

@peekay123 @ScruffR
If I am reading this correctly you can already control this behavior, just set force_no_background_loop to true. Is that correct? From system_task.cpp on github, line

void system_delay_ms(unsigned long ms, bool force_no_background_loop=false)

I’d say so, but have to check.

But the normal delay() doesn’t come with this parameter (AFAIK) and what would one want that anyhow?
If you are aware of the possible implications of using delay() as is, you would rather go for an even less blocking approach than for a completely blocking that’s bound to break your cloud connection.
The only “advantage” I see there, is that the delay time would me a bit more exact.


But this discussion is leading away from @alexsh1 problem.

More of an education thing as I am trying to learn how to trace firmware behavior to the code that actually controls it. After I posted that I found delay() in spark_wiring.cpp which only allows ms to be passed into it and false is hardcoded when it is passed onto system_delay_ms. I avoid all blocking behavior personally but it is good know how to get to the things that control the different functions. I agree, I digress.

@alexsh1 sorry for the drift away from your question. What firmware level are you? It would seem the delay() behavior depends on which release you are on.

The cloud-servicing-delay was introduced quite early in :spark: Spark history (mark the Spark ;-)), so if your Code was flashed before long before October 2014 it might be an issue, otherwise it shouldn’t be.

@alexsh1, sorry I’ve lost track of your actual problem - as it seems.

Just to sum-up where we are:

  • Are you using firmware version 0.3.4 or 0.4.5? (consider 0.4.5)
  • You can read your sensor data with the code you posted (yes / no ?) [with the corrected &-issue]
  • You have (or should have) added some Serial.print() statements for debugging?
  • You want to Spark.publish() any of the data - and it actually publishes? (yes / no ?)
  • You have a Spark.variable() that you could retrieve with something like this or this? (yes / no ?)
  • You still cannot access this variable via your own web app? (yes / no ?)

Good question - I followed the instructions on GitHub - particle-iot/device-os at master pulling the latest git, therefore I think I am on 0.4.5 and CC3000 is 1.32

Thanks for you help @ScruffR

  • it is 0.4.5 I believe, I followed the instruction on GitHub - particle-iot/device-os at master pulling the latest one.
  • yes, I can. I can read all sensors at dashboard.particle.io
  • I have not yet.
  • Yes, all three 5 parameters are published and I can see them.
  • Yes, I can see all 5 parameters.
  • Correct, when I do 'curl' on the remote computer with a web app to pull a variable from cloud, I get 'time out' very often. Hence, variable are not published on my web app.

Very often I have such gaps though Core is breathing Cyan…

Can you try flashing your code from build.particle.io? It will force an update to the latest firmware so we can get the question of firmware out of the way…or remove the delay and time it another way.

EDIT: From your code it looks like you are flashing from WebIDE but you reference doing local compiles as well. Which method are you using?

I am flashing code via build.particle.io

I did not realise it would force an update to the latest firmware and hence built and flashed firmware locally according to the link above.

Currently, I have Cyan flashing with some red bursts. No idea why the connection to cloud is dropped.

Yup, if you click on Devices (the cross hairs) then the > sign and you will see a dropdown list for what version of firmware you are flashing.

it is 0.4.5

This works…change your pin to D0 I think is what it was, fix the includes (use the DS18B20 lib, makes it easier) and you are done. There was no reason to convert your temp to a STRING value since you are only sending the temp in Particle.variable It is tested and reports correct values in Variable and Dashboard. Except for the first publish which I will leave to you to correct the timing on that. You can crank down the publish interval as long as you keep it above 1/second.

// This #include statement was automatically added by the Spark IDE.
#include "OneWire.h"
#include "DS18B20.h"


DS18B20 ds18b20 = DS18B20(D2); //Sets Pin D2 for Water Temp Sensor
char szInfo[64];
float pubTemp;
double celsius;
unsigned int Metric_Publish_Rate = 50000;
unsigned int MetricnextPublishTime;
unsigned int DS18B20nextSampleTime;
unsigned int DS18B20_SAMPLE_INTERVAL = 2000;

void setup() {
    pinMode(D2, INPUT);
    Particle.variable("tempHotWater", &celsius, DOUBLE);
    Serial.begin(9600);
}

void loop() {

  if (millis() > DS18B20nextSampleTime){
  getTemp();
  Serial.print("Temp is: ");
  Serial.println(celsius);
  }

  if (millis() > MetricnextPublishTime){
    Serial.println("Publishing now.");
    publishData();
  }
}

void publishData(){
  sprintf(szInfo, "%2.2f", celsius);
  Particle.publish("dsTmp", szInfo, PRIVATE);
  MetricnextPublishTime = millis() + Metric_Publish_Rate;
}

void getTemp(){
    if(!ds18b20.search()){
      ds18b20.resetsearch();
      celsius = ds18b20.getTemperature();
      DS18B20nextSampleTime = millis() + DS18B20_SAMPLE_INTERVAL;
      Serial.print(celsius);
    }
  }

OK, apologies, but I still have the same issue. Sometimes, I
have cyan bursting on the Core for hours. I have internet connection working
fine.

Basically, I have three sensors (DS18B20, DHT11 and Water
sensors) connected to the Core.

The code which was considerably changed compare to my first post above:

// This #include statement was automatically added by the Particle IDE.
#include "PietteTech_DHT/PietteTech_DHT.h"

// This #include statement was automatically added by the Particle IDE.
#include "OneWire/OneWire.h"

// This #include statement was automatically added by the Particle IDE.
#include "spark-dallas-temperature/spark-dallas-temperature.h"




// DHT sensor type & pin
#define DHTTYPE  DHT11       // Sensor type DHT11/21/22/AM2301/AM2302
#define DHTPIN   D6          // Digital pin for communications D6
// One Wire pin
#define ONE_WIRE_BUS D5  //data on pin D5
// Water sensor pins
#define WATER_SENSOR D4
#define LED D7
// How long to wait before noting that the alarm has switched states -- this
// helps stop a super-sensitive sensor from ping-ponging back and forth a lot.
#define DEBOUNCE_SECONDS 5

// Variables

// the alarm state: 0 = off, 1 = on
int alarmState = 0;
// the last tiem we switched alarm states (ms since Unix epoch)
int lastStateSwitchTime = 0;

int temp=0;
int hum=0;
double tempc;
char tempInfo[10];

// Declaration
void dht_wrapper(); // must be declared before the lib initialization

// Lib instantiate
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
OneWire oneWire(ONE_WIRE_BUS);  // Setup a oneWire instance to communicate with any OneWire devices 
DallasTemperature sensors(&oneWire);  // Pass our oneWire reference to Dallas Temperature.

void setup(void)
{
//Serial.begin(9600);    
Spark.variable("tempHotWater", tempInfo, STRING);   //expose vars to web interface  
sensors.begin();    // IC defaults to 9 bit. If you have trouble consider changing to 12.
sensors.setResolution(12);


Spark.variable("temperature", &temp, INT);
Spark.variable("humidity", &hum, INT);
  
//Serial.begin(9600);
//while (!Serial.available()) {
//Serial.println("Press any key to start.");
//delay (1000);
//}
//Serial.println("DHT Example program using DHT.acquireAndWait");
//Serial.print("LIB version: ");
//Serial.println(DHTLIB_VERSION);
//Serial.println("---------------"); 

// initialize our pins I/O
pins_init();
    
// tell the world we're online
Spark.publish("online");
    
// publish the alarm state variable
Spark.variable("alarmState", &alarmState, INT);

}

void dht_wrapper() {
    DHT.isrCallback();}

void loop(void) {
sensors.requestTemperatures();
tempc= sensors.getTempCByIndex(0);
sprintf(tempInfo, "%2.1f", tempc);

DHT.acquireAndWait();
    
    // Humidity measurement
    //temperature = dht.getTempCelcius();
temp = DHT.getCelsius();
hum = DHT.getHumidity();

Spark.publish("temperature_Hot_Water_Tank", String(tempc) + "°C");
//delay (2000);
Spark.publish("temperature", String(temp) + "°C");
//delay (2000);
Spark.publish("humidity", String(hum) + "%");
delay (5000);

//Serial.print("Hot Water (oC): ");
//Serial.println(tempc, 2);

//Serial.print("Temperature (oC): ");
//Serial.println(temp, 2);

//Serial.print("Humidity (%): ");
//Serial.println(hum, 2);

    if(isExposedToWater()) {
        //
        // Alarm ON
        //
        if (alarmState == 0) {
            // only alarm if we're past the debounce interval
            int now = Time.now();
            if (now - lastStateSwitchTime > DEBOUNCE_SECONDS) {
                alarmState = 1;
                lastStateSwitchTime = now;
                digitalWrite(LED, HIGH);
                Spark.publish("alarm", "on", 60, PRIVATE);
            }
        }
    } else {
        //
        // Alarm off
        //
        if (alarmState == 1) {
            // only alarm if we're past the debounce interval
            int now = Time.now();
            if (now - lastStateSwitchTime > DEBOUNCE_SECONDS) {
                alarmState = 0;    
                lastStateSwitchTime = now;
                digitalWrite(LED, LOW);
                Spark.publish("alarm", "off", 60, PRIVATE);
            }
        }

    }
}

// initialize our pins
void pins_init()
{
    pinMode(LED, OUTPUT);
    pinMode(WATER_SENSOR, INPUT);
}

// determine if we're exposed to water or not
boolean isExposedToWater()
{
    if (digitalRead(WATER_SENSOR) == LOW) {
        return true;
    } else {
        return false;
    }
}

</unquote>
Continuing the discussion from [DS18B20 and Particle Core](https://community.particle.io/t/ds18b20-and-particle-core/15910/38):

[quote="LukeUSMC, post:38, topic:15910, full:true"]
This works...change your pin to D0 I think is what it was, fix the includes (use the DS18B20 lib, makes it easier) and you are done.  There was no reason to convert your temp to a STRING value since you are only sending the temp in `Particle.variable` It is tested and reports correct values in Variable and Dashboard.  Except for the first publish which I will leave to you to correct the timing on that.  You can crank down the publish interval as long as you keep it above 1/second.
```cpp
// This #include statement was automatically added by the Spark IDE.
#include "OneWire.h"
#include "DS18B20.h"


DS18B20 ds18b20 = DS18B20(D2); //Sets Pin D2 for Water Temp Sensor
char szInfo[64];
float pubTemp;
double celsius;
unsigned int Metric_Publish_Rate = 50000;
unsigned int MetricnextPublishTime;
unsigned int DS18B20nextSampleTime;
unsigned int DS18B20_SAMPLE_INTERVAL = 2000;

void setup() {
    pinMode(D2, INPUT);
    Particle.variable("tempHotWater", &celsius, DOUBLE);
    Serial.begin(9600);
}

void loop() {

  if (millis() > DS18B20nextSampleTime){
  getTemp();
  Serial.print("Temp is: ");
  Serial.println(celsius);
  }

  if (millis() > MetricnextPublishTime){
    Serial.println("Publishing now.");
    publishData();
  }
}

void publishData(){
  sprintf(szInfo, "%2.2f", celsius);
  Particle.publish("dsTmp", szInfo, PRIVATE);
  MetricnextPublishTime = millis() + Metric_Publish_Rate;
}

void getTemp(){
    if(!ds18b20.search()){
      ds18b20.resetsearch();
      celsius = ds18b20.getTemperature();
      DS18B20nextSampleTime = millis() + DS18B20_SAMPLE_INTERVAL;
      Serial.print(celsius);
    }
  }

[/quote]

Continuing the discussion from DS18B20 and Particle Core:

[quote=“LukeUSMC, post:38, topic:15910, full:true”]
This works…change your pin to D0 I think is what it was, fix the includes (use the DS18B20 lib, makes it easier) and you are done. There was no reason to convert your temp to a STRING value since you are only sending the temp in Particle.variable It is tested and reports correct values in Variable and Dashboard. Except for the first publish which I will leave to you to correct the timing on that. You can crank down the publish interval as long as you keep it above 1/second.

// This #include statement was automatically added by the Spark IDE.
#include "OneWire.h"
#include "DS18B20.h"


DS18B20 ds18b20 = DS18B20(D2); //Sets Pin D2 for Water Temp Sensor
char szInfo[64];
float pubTemp;
double celsius;
unsigned int Metric_Publish_Rate = 50000;
unsigned int MetricnextPublishTime;
unsigned int DS18B20nextSampleTime;
unsigned int DS18B20_SAMPLE_INTERVAL = 2000;

void setup() {
    pinMode(D2, INPUT);
    Particle.variable("tempHotWater", &celsius, DOUBLE);
    Serial.begin(9600);
}

void loop() {

  if (millis() > DS18B20nextSampleTime){
  getTemp();
  Serial.print("Temp is: ");
  Serial.println(celsius);
  }

  if (millis() > MetricnextPublishTime){
    Serial.println("Publishing now.");
    publishData();
  }
}

void publishData(){
  sprintf(szInfo, "%2.2f", celsius);
  Particle.publish("dsTmp", szInfo, PRIVATE);
  MetricnextPublishTime = millis() + Metric_Publish_Rate;
}

void getTemp(){
    if(!ds18b20.search()){
      ds18b20.resetsearch();
      celsius = ds18b20.getTemperature();
      DS18B20nextSampleTime = millis() + DS18B20_SAMPLE_INTERVAL;
      Serial.print(celsius);
    }
  }

The cloud looks like:

The Core is simply not talking to cloud from time to time hence the variables
cannot be pulled/updated. I thinking about a faulty Core…

I suppose it is possible. Try running the code I posted and see if it does the same thing. I know that delay shouldn’t be an issue but I saw a couple of other threads yesterday that delay statements were affecting Particle.variable(). If the code that works on mine loses connection on yours then we will have a better idea of where to go next.

I feel somehow my problem is related to

Thanks @LukeUSMC, I am going to try your code now. Stupid question though - how do I include #include "DS18B20.h" in the WebIDE? You code is probably a local one.