Help with Particle.subscribe in a void loop

Ok, I am trying to use two photon’s to talk to each other for a school project. Basically working towards a garage door status monitor and I am stuck.

My goal is to have one photon verify open/close status with a reed switch and publish it. I’ve only managed to get it to publish the open status and not both. However, when I do this I see 4 events pop up on the Particle Console for each time I move the magnet away.

Here is the publishing code:

int inputPin = D0;                  //pin for the reed switch
int reedState = HIGH;               //Initial State of the switch
int status;                         //variabe for reading the pin

void setup() {
  pinMode(D7,OUTPUT);
  pinMode(inputPin,INPUT);
}

void loop()
{
    readTheSensor();        // get the data from the sensor
    reportTheData();        // report it out, if the state has changed
}

void setLED( int state )
{
  digitalWrite(D7, state);
}

void readTheSensor() {
  status = digitalRead(inputPin);
}

void reportTheData() {

  if (status == LOW) {

    if (reedState == HIGH) {
      Particle.publish("open","open");
      reedState = LOW;
      setLED(reedState);
    }
  } else {
    if (reedState == LOW) {
      reedState = HIGH;
      setLED( reedState );
    }
  }
}

The subscribing code I haven’t been able to work right. Here is what I have so far, after I try to explain the logic I want:

  int led = D7;
  int state = 0;

        void setup()
        {
            pinMode(led,OUTPUT);
            digitalWrite(led,LOW);
            
            Particle.subscribe("open",myHandler,"using my device ID");
        }
        void myHandler (const char *event, const char *data)
        {
            
            if (strcmp(data,"open")==0)
            {
                digitalWrite(led,HIGH);
            delay(100);
            digitalWrite(led,LOW);
            }
        } 
        void loop()
            {
                
            }

What I want is a void loop that will continuously check for the published event, and it the reed switch is open it turns on the D7 led, and if the reed switch is closed it turns off the led.

This is my first real exposure to many of these concepts and coding in general, and I am at a loss. Too many hours of googling and testing other things and here we are.

Thank you in advance for your help/advice on this.

-Alchaun

in myHandler() you strobe the LED for only 100ms, that is a pretty brief flash. Perhaps you should make that a delay(1000) (== 1 second) to be sure to see it? Also, you can spit out messages on the serial or usb port with e.g. USBSerial1.printf() which is handy for debugging.

Is the publishing code you show responsible for the events you captured (picture) above? It seems it is not because you publishing an event named “open” in your code but it shows “My_Event” in the picture.

You should really debounce the reed switch i.e., read it several times in a row with a small delay to make sure it is done bouncing. So something like:

int readTheSensor() {
  int switchStatus = digitalRead(inputPin);
  delay(100);
  if switchStatus == digitalRead(inputPin)
    return switchStatus;
 else
   return -1;
}

(Hey there are better ways to debounce, this is just simple stuff) So this method returns:
0: switch is off
1: switch if on
-1: switch couldn’t be read.

Then your loop can be:

void loop()
{
  status = readTheSensor();
  if (status >= 0 )
   reportTheData();
}

And reportTheData:

void reportTheData() {

  if ( status == 1 ) {
    Particle.publish("GarageDoorStatus", "open" );
    setLED(status);
  }
 else if (status == 0 ) {
  Particle.publish("GarageDoorStatus", "closed");  // assuming you want this message
  setLED(status)  ;
 }
}

Notice that I didn’t use the reedState variable. Also, check my logic for assuming reedSwitch ==1 means open door etc.

hope this helps…

You don't need to continuously check for the published event in loop(), the subscribe handler will be called whenever your other device publishes.

If this is what you want, then you shouldn't have the delay followed by turning off the LED. Don't you want to have it stay on if you receive "open" in the data? If so, you probably want something like this,

void myHandler (const char *event, const char *data) {
            
    if (strcmp(data,"open")==0) {
        digitalWrite(led,HIGH);
    }else if (strcmp(data,"close")==0) {
        digitalWrite(led,LOW);
   }
}

You also want to use a pull-resistor on your read switch to prevent the pin from floating when the switch is open.
The easiest way to do that is by use of INPUT_PULLUP / INPUT_PULLDOWN (opposite to the level your switch closes to) instead of INPUT in pinMode()

I was able to get the publishing of both statuses to work thanks to the void report the data you gave, thank you! When I tried to use the loop the led just kept blinking and nothing reported, so I took it out and everything works as I need it to on the publishing side.

The other replies helped me with the subscribe, so now everything is working as I needed/wanted.

Thanks!

Wonderful! I was able to get this to work in seconds. I appreciate the help!

Thank you! This fixed my multiple reports problem like a charm. Now I get one message per state change of the reed switch. I’ll be able to clean everything up and once everything is tested working I’ll be able to post it in the projects section.

1 Like