Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By CaptClaude
#67733 Can I use Ticker with a function that returns a value? Starting with an IO.Adafruit publish example, I use millis() to check if 30s has elapsed and then I call a function that reads a DHT22 sensor and publishes three values to io.adafruit.com. Works great (even if the DHT22 is occasionally flaky). I have a while() that loops if bad data was returned, with a delay(100). On a 0 return, I go do something else. I also subscribe to a toggle to turn and LED on and off and would like to publish the state of the LED back to io.adafruit so I can tell if the remote toggle actually worked. If the toggle subscription notification arrives while the DHT22 is being read out, the LED is not toggled.

I'd like to eliminate the millis() and use Ticker.

I am at the learning-experiment phase here.

Suggestions?

Code: Select all// Adafruit IO Publish Example, modified to do other stuff too

#include "config.h"
#include <DHT.h>
#define DHTPIN D4 //pin gpio 2 in sensor
#define LED_PIN D5
#define LED_TOGGLE D3
#define BUTTON_PIN D6
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
unsigned long previousMillis = 0;
unsigned long currentMillis;
const long interval = 30000;
bool ToggleState = false;

float humid = 0.0;
float temp_C = 0.0;
float temp_F = 0.0;
int good_temp;
int errorcount = 0;

// Functions
int gettemp();
// set up the feeds
AdafruitIO_Feed *humidity = io.feed("humidity");
AdafruitIO_Feed *temperatureC = io.feed("temp_C");
AdafruitIO_Feed *temperatureF = io.feed("temp_F");
AdafruitIO_Feed *LEDState = io.feed("ToggleState");
AdafruitIO_Feed *digital = io.feed("digital");

void setup() {
  dht.begin();
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  pinMode(LED_TOGGLE, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
  digitalWrite(LED_TOGGLE, HIGH);

  // start the serial connection
  Serial.begin(115200);

  // wait for serial monitor to open
  while(! Serial);

  Serial.print("Connecting to Adafruit IO");

  // connect to io.adafruit.com
  io.connect();

  // wait for a connection
  while(io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  // we are connected
  Serial.println();
  Serial.println(io.statusText());
  digital->onMessage(handleMessage);

}

void loop() {
  errorcount = 0;
  // io.run(); is required for all sketches.
  // it should always be present at the top of your loop
  // function. it keeps the client connected to
  // io.adafruit.com, and processes any incoming data.
  io.run();
  currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   
    digitalWrite(LED_PIN, LOW);
    while( good_temp = gettemp() ){
      Serial.println( errorcount++ );
      delay(100);
    }
  }
  digitalWrite(LED_PIN, HIGH);
  ToggleState = digitalRead(D3);
}
int gettemp(){
    // Grab the current state of the sensor
  humid = (int)dht.readHumidity();
  temp_C = (int)dht.readTemperature();
  temp_F = (int)dht.readTemperature(true);

  if( temp_C < 200 || humid < 150 ){  // filter out the integer-cast NANs
    // Publish data
    if (! temperatureC->save(temp_C))
      Serial.println(F("Failed to publish temperature"));
    else
      Serial.print(F("Temperature published: "));
      Serial.print(temp_C);
      Serial.println(F("C"));
     if (! temperatureF->save(temp_F))
      Serial.println(F("Failed to publish temperature"));
    else
      Serial.print(F("Temperature published: "));
      Serial.print(temp_F);
      Serial.println(F("F"));

    if (! humidity->save(humid))
      Serial.println(F("Failed to publish humidity"));
    else
      Serial.print(F("Humidity published:"));
      Serial.println(humid);
    return 0;
  }else{
    Serial.println(F("invalid data received from sensor"));
    return 1;
  }
}

void handleMessage(AdafruitIO_Data *data) {
  Serial.print("received <- ");
  Serial.println(data->value());
  if(data->toPinLevel() == HIGH){
    digitalWrite(LED_TOGGLE, LOW);
    Serial.println("HIGH");
  }else{
    Serial.println("LOW");
    digitalWrite(LED_TOGGLE, HIGH);
  }
}
User avatar
By CaptClaude
#67841 In retrospect, I no longer think that my question is meaningful. Ticker calls a function every X time units and there is no way for anything to receive the what the function returns (as near as I can tell): ergo, not a meaningful question. If I'm wrong about that, please correct me.

A more meaningful question is: What are the restrictions or caveats to using Ticker? Is there a limit on how long a Ticker-called function can take to complete? Can I call an MQTT publish? Can I read a sensor (like a DHT22)?

Thanks,

CC
User avatar
By torntrousers
#67842 From the library doc:

"It is currently not recommended to do blocking IO operations (network, serial, file) from Ticker callback functions. Instead, set a flag inside the ticker callback and check for that flag inside the loop function."

See here: http://esp8266.github.io/Arduino/versio ... tml#ticker
User avatar
By CaptClaude
#68153 Thanks. And thanks for the pointer to the documentation (which I somehow missed).
Currently logging temp/humidity from the deck of the condo we are staying at in Cozumel. Testing the extremes of the DHT22 temp and humidity range it would seem. It hit 110F / 43C yesterday in direct sun. Humidity currently 83%.