Issues with Particle.subscribe / Particle.publish


#1

I have an application that sends data to a Firebase database via Webhooks on the Particle site. The database is linked to a simple one page website. I have a Bluz DK sending sensor data to the Bluz Gateway (Particle Photon) and displaying on the website. The website has buttons to turn on and off a pin on the Particle Photon.

I have buttons on my website that update the Firebase database item “valve” to open or closed. The Particle Photon does a GET request every 10 seconds to see if “valve” is open or closed. If it is open it will write to pin D7. If it is closed it will turn off D7.

The sensor data is reading in every 10 seconds just fine, UNTIL I use the buttons on the website. What happens is after 1 or 2 times pushing the website buttons to open and close the valve, the Bluz DK will stop sending values to the Particle Photon. The weird thing is that the Bluz DK shows that it is OFFLINE on the Particle website, however, the Bluz DK continues to blink blue as if it were connected. After this happens and the Bluz DK goes offline and the sensor values stop coming in, the website buttons still work with the Partice Photon.

If I hit the RST button on the Bluz DK it will connect to the Photon again and start sending sensor values to the website.

Hopefully this makes sense! Thanks!

Gateway code:

// This #include statement was automatically added by the Particle IDE.
#include <bluz_gateway.h>



SYSTEM_MODE(SEMI_AUTOMATIC);
bluz_gateway gateway;
String valveData;
unsigned long previousMillis = 0;
const long interval = 10000;


void setup() {
    gateway.init();
    //only set this if you want the nrf51 central to not connect, recomended for Electron gateway
    // gateway.set_ble_local(true);
    pinMode(D7,OUTPUT);
    digitalWrite(D7,LOW);
    pinMode(D6,OUTPUT);
    digitalWrite(D6,LOW);
    Particle.subscribe("hook-response/valve/0", gotValveData, MY_DEVICES);
}

void gotValveData(const char *event, const char *data) {
    String water = data;
    if (water == "\"open\""){
        digitalWrite(D7,HIGH);
        digitalWrite(D6,HIGH);
        
    }
    if (water == "\"closed\""){
        digitalWrite(D7,LOW);
        digitalWrite(D6,LOW);
    }
}


void loop() {
    gateway.loop();
    unsigned long currentMillis = millis();
    
    if (currentMillis - previousMillis >= interval){
        previousMillis = currentMillis;
        Particle.publish("valve");
    }
}

Bluz DK code:

#include <Adafruit_Si7021.h>
#include <elapsedMillis.h>
#include <Arduino.h>
#include "DHT.h"
#include <PietteTech_DHT.h>
#include <Adafruit_TSL2561_U.h>
#include <Adafruit_Sensor.h>

elapsedMillis read_timer;
void dht_wrapper();
Adafruit_Si7021 thsensor = Adafruit_Si7021();
//Constants
#define DHTPIN 4     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)

//DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor

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

// Lib Initialize
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);

//Variables
Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);
int chk;
float hum;  //Stores humidity value
float temp; //Stores temperature value
int val = 0; //value for storing moisture value
int soilMoisturePin = A0;//Declare a variable for the soil moisture sensor
int soilMoisturePower = 6;//Variable for Soil moisture Power
int soilTempPin = A5;
int soilTempPower = D2;

void setup()
{
  Serial1.begin(9600);
  thsensor.begin();
  //dht.begin();
  
  pinMode(soilTempPower, OUTPUT);
  pinMode(soilMoisturePower, OUTPUT);
  digitalWrite(soilTempPower, LOW);
  digitalWrite(soilMoisturePower, LOW);
  
  //pinMode(soilPower, OUTPUT);//Set D7 as an OUTPUT
  //digitalWrite(soilPower, LOW);//Set to LOW so no power is flowing through the sensor
  if (!tsl.begin())
  {
    /* There was a problem detecting the TSL2561 ... check your connections */
    Particle.publish("Error","TSL2561_not_detected");
    while (1);
  }
}

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

void loop()
{
  //tdelay();
  delay(10000);
  DHT.acquire();
  /* Get a new light sensor event */
  sensors_event_t event;
  tsl.getEvent(&event);
  //Read data and store it to variables hum and temp
  hum = thsensor.readHumidity();
  temp = thsensor.readTemperature();
  //float hum = dht.readHumidity();
  //float temp = dht.readTemperature(true);
  
  int tempint = (int) temp;
  int humint = (int) hum;
  double tempdouble = (double) temp;
  String tempstring = String(temp);
  
//   Serial1.println(temp);
//   Serial1.println(tempint);
//   Serial1.println(tempdouble);
//   Serial1.println(tempstring);
  
//   Serial1.println("hello");
//   Serial1.println(readSoil());
  
  //publish to cloud
  Particle.publish("Humidity", String(humint));
  Particle.publish("Temp", String(tempint));
  Particle.publish("Soil_Temperature", String(readSoilTemp()));
  Particle.publish("Soil_Moisture", String(readSoil()));
  delay(1500);
  if (event.light)
  {
    Particle.publish("Light", String(event.light,2));
  }
  else
  {
    /* If event.light = 0 lux the sensor is probably saturated
      and no reliable data could be generated! */
    Particle.publish("Error", "Sensor_overload");
  }
  //delay(1000); //Delay 2 sec.
}

// int tdelay(){
//     if (read_timer < READ_INTERVAL) {
//         return 0;
//     }
    
//     //time is up, so reset timer
//     read_timer = 0;
  
// }

int readSoilTemp()
{
    digitalWrite(soilTempPower, HIGH);
    delay(10);
    val = analogRead(soilTempPin);
    digitalWrite(soilTempPower, LOW);
    return val;
}

int readSoil()
{
  digitalWrite(soilMoisturePower, HIGH);//turn D7 "On"
  delay(10);//wait 10 milliseconds
  val = analogRead(soilMoisturePin);//Read the SIG value form sensor
  digitalWrite(soilMoisturePower, LOW);//turn D7 "Off"
  return val;//send current moisture value
}

#2

So if the system is left alone, the bluz DK will continue to publish without issues? And if you press the buttons on the website, that seem to send an event to the Photon, this will stop the bluz DK from sending data?

Do the buttons on the website have any connection to bluz? Or just to the Photon?

In the bluz code, there are a lot of waits and delays. These are generally bad practice as they block the system firmware from maintaining a connection to the cloud, and they also force the CPU to constantly stay on and kill battery performance. You can look into software timers as a way to perform regular tasks on an interval that won’t interrupt the system firmware. That is certainly one thing to try


#3

Yes exactly.

The buttons have no connection to the bluz. They only turn on and off a pin on the Photon.

Okay I will try that. Thanks


#4

Just a note on this here: This will violate the rate limit for Particle.publish().
You are sending a burst of four events which will require a 4+ seconds of radio silence to recover, so the following fifth even is most likely to not get published.
Better practice would be to bundle the four seperate events into one by packaging the sensor readings into one string.
Also consider marking your events as PRIVATE - future versions of Particle firmware will make the scope parameter compulsory.

Also this infinite loop in case of an undetectable TSL sensor may cause disconnect from the cloud.