Help with particle.subscribe and motion sensor

Hello,

I am attempting to use particle publish and subscribe to link 2 photons. I have one with a pir sensor and it uses particle publish
Here is the code from the one with the pir sensor

    int pir = 0;
void setup() {
  pinMode(D7, OUTPUT);
  pinMode(D4, INPUT);
}

void loop() {
    pir = digitalRead(D4);
    if(pir == HIGH )
    {
  digitalWrite(D7, HIGH);
  Particle.publish("Motion Detected", "True");
  delay(5000);

    }
    else{
        digitalWrite(D7, LOW);
    }
  // And repeat!
}

I am having trouble understanding particle subscribe. How can I have a second photon subscribe to light up D7 when the first photon publishes “True”

Thanks!

https://docs.particle.io/reference/firmware/photon/#particle-subscribe-

I already RTFM so no need to refer to it. Unfortunately I am still struggling as I am still learning.
If I had some more/better examples I might be able to deconstruct and understand.

I am typing this on my phone right now, so excuse the bad formatting.

On the second Photon your code would probably look like this.

void setup()
{
Particle.subscribe("Motion Detected", motionFunction);
pinMode(D7, OUTPUT);
}

void loop()
{
}

void motionFunction(const char *event, const char *data)
{
if (data == "True")
{
digitalWrite(D7, HIGH);
}
if (data == "False")
{
digitalWrite(D7, LOW);
}
}
1 Like

Are you sure?
https://docs.particle.io/guide/getting-started/examples/photon/#the-buddy-system-publish-and-subscribe

Ahh so that’s close to how it would be done. It felt weird not having anything in void loop, that’s why I was not sure I was doing it right.

Thanks

1 Like

You’re welcome.

Still having trouble, don’t know what I am missing
Code for Motion detector

int pir = 0;
void setup() {
  pinMode(D7, OUTPUT);
  pinMode(D4, INPUT);
}

void loop() {
    pir = digitalRead(D4);
    if(pir == HIGH )
    {
  digitalWrite(D7, HIGH);
  Particle.publish("Motion Detected", "True");
  delay(5000);

    }
    else{
        digitalWrite(D7, LOW);
        Particle.publish("Motion Detected", "False");
        delay(5000);
    }
}

Code For Receiver
Same as nrobinson2000 posted

void setup()
{
Particle.subscribe("Motion Detected", motionFunction);
pinMode(D7, OUTPUT);
}

void loop()
{
}

void motionFunction(const char *event, const char *data)
{
if (data == "True")
{
digitalWrite(D7, HIGH);
}
if (data == "False")
{
digitalWrite(D7, LOW);
}
}

Any Ideas what is going wrong?
According to the console I can see that the sensor is working for publish

You could add an unconditional Serial.println(data) statement in your handler and see what happens with your handler:

  • if it gets called at all
  • what the data parameter contains
  • if you get into any of your conditional branches
  • why not

And just to clarify const char* strings are not compared that way. That’d only work for String objects.
For C strings you’d use something like if (!strcmp(data, "True")

The == operator used that way would only check if the const char* of data points to the same memory location as the respective string literal - which it never will, since one will be in RAM while the other always sits in flash memory.

I tried

void setup()
{
    Serial.begin(9600);
Particle.subscribe("Motion Detected", motionFunction);
pinMode(D7, OUTPUT);
}

void loop()
{

}

void motionFunction(const char *event, const char *data)
{
  if (strcmp(data,"True")==0) {
    // if your buddy's beam is intact, then turn your board LED off
    digitalWrite(D7,LOW);
  }
  else if (strcmp(data,"False")==0) {
    // if your buddy's beam is broken, turn your board LED on
    digitalWrite(D7,LOW);
  }
        Serial.println(data);
}

No output via serial

Try removing the space from the event name, so it’s “MotionDetected”.

You intend to have D7 not lit in both cases?
How are you checking the serial output?
Can you double check the exact event name?
You could also use the prefix filter feature of subscribe and only subscribe to a shorter part of the event name.

Try this then

void setup()
{
  Serial.begin(115200);
  Particle.subscribe("Motion", motionFunction);
  pinMode(D7, OUTPUT);
}

void loop() 
{
  static uint32_t ms;
  if (millis() - ms > 1000)
  {
    ms = millis();
    Serial.print("."); // to see if you get serial output at all
  }
}

void motionFunction(const char *event, const char *data)
{
  Serial.printf("\r\n%s: \"%s\"\r\n", event, data);
  digitalWrite(D7, !digitalRead(D7));  // toggle D7 led on each subscribe firing

  if (strcmp(data,"True")==0) {
    // if your buddy's beam is intact, then turn your board LED off
    RGB.control(true);
    RGB.color(255, 128, 0);  // set RGB LED amber
  }
  else if (strcmp(data,"False")==0) {
    // if your buddy's beam is broken, turn your board LED on
    RGB.control(false);  // reestablish default RGB function 
  }
}