Particle.subscribe Firmware

Hi All,

I have problem with my small project of make two photons communicate.
The Project for indicating the normal status by lit LED 7 (D7) when “NORMAL” message published in cloud.

I think I have problem with compare two strings and not function the if condition.
here below my Firmware. and when i tested by the serial print I can see “NORMAL” message received from cloud.

int LED7=D7;
String CDATA; // STRING CALLED FROM CLOULD 
String TEST="NORMAL"; // TEST VALUE FOR COMPEARATION 


void setup() {

pinMode(LED7, OUTPUT);
digitalWrite(LED7, HIGH);
delay(5000);
digitalWrite(LED7, LOW);


Particle.subscribe("FAP", RunAlarm, MY DEVICE ID);

Serial.begin(9600);

}

void loop(){
    // to lit LED 7 as normal indicator 
       if (CDATA.equals(TEST)){
           
        digitalWrite(LED7, HIGH);
        delay(1000);
        }
        
    else
        {
      digitalWrite(LED7, LOW);
      delay(1000);
      
        }
}// end loop

int i=0;
// the handeler function 
void RunAlarm(const char *event, const char *data)
{
 
 String CDATA=data; // convert from Car to String
 
  i++;
  Serial.print(i);
  Serial.print(event);
  Serial.print(", data: ");
  if (data)
    Serial.println(CDATA);
  else
    Serial.println("NULL");
        
}

The MY_DEVICE_ID version of Particle.subscribe() does not work.
You should rather use Particle.subscribe("FAP", RunAlarm, MY_DEVICES);.

And you need to drop the data type here

void RunAlarm(const char *event, const char *data)
{
 
 String CDATA=data; // convert from Car to String
 ...       
}

This creates a new local variable that just happens to have the same name as your global CDATA but it’s not the same thing. When you copy data into that you it will just be gone once you leave the function.

It’s just like having two red buckets. When you pour water into one red bucket the other one wouldn’t get full either.

Thanks ScruffR,
I understood why the comparison not working as the data will be cleared after left the function RunAlarm.

However, I tried article.subscribe("FAP", RunAlarm, MY_DEVICES)
doesn’t work. I s there any library need to include or do something else?

indent preformatted text by 4 spaces

Hmm, did you really write this in your code?

Then I'm not surprised :wink:
Should be Particle.subscribe("FAP", RunAlarm, MY_DEVICES)

Ohh! :smile:
yes, Let me try it again.

regards,

Hi ScruffR,
It is working now. Thanks for your support.
here below the code,
The question now how we can return some value from myHandler to loop function.
or I can active any pins or generate output signal inside myHandler?

int LED7=D7;
String CDATA; // STRING CALLED FROM CLOULD 
String TEST="NORMAL"; // TEST VALUE FOR COMPEARATION 

void setup() {
  pinMode(LED7, OUTPUT);
  digitalWrite(LED7, HIGH);
  delay(5000);
  digitalWrite(LED7, LOW);

  Particle.subscribe("FAP", RunAlarm, MY_DEVICES);
  Serial.begin(9600);
}

// the handeler function 
void RunAlarm(const char *event, const char *data)
{
  int buzzerPin=A4;
  int FreqRate=30;
 
 String CDATA=data; // convert from Car to String
 
  if (CDATA.equals("NORMAL")){
    digitalWrite(LED7, HIGH);
    delay(1000);
    digitalWrite(LED7, LOW);
  }
        
  if (CDATA.equals("ALARM!"))
  {
    tone(buzzerPin,FreqRate);
    digitalWrite(LED7, LOW);
    delay(1000);   

    digitalWrite(LED7, HIGH);
    delay(1000);
      
    digitalWrite(LED7, LOW);
    delay(1000);
      
    digitalWrite(LED7, HIGH);
    delay(1000);
  }      
}

I would not call Particle.subscribe() after delay(5000) otherwise you may run the risk that your subscription will not be registered with the cloud.

You should also not have all these delay(1000) calls inside the subscription handler.
Subscription handlers should return as fast as possible.

That would be done via global variables.
If you remove the datatype from your CDATA=data; line then the string will be accessible in loop() via your global CDATA variable.

I am having an issue with an Electron subscribing to another Electron. I have setup the following subscription statement:

Particle.subscribe("fnvoc", myHandler, MY_DEVICES);

Both of the Electrons are in a product together (not sure if it matters). The event name is lowercase, not sure if that matters?

But I do know, if I take out the MY_DEVICES flag, it works, but I don't want to risk getting a public message named the same. I'm on firmware 0.7.0... can't figure out what the problem is...

Are you publishing the event as PRIVATE?
But I think having the devices as products may well play a role.

Usually as a customer I’d agree with my device to talk to the vendor, but may not be willing to share any information with any other customer I don’t know (unless explicitly and clearly stated in the terms of use and the possibility to opt-out).
The “proper” way to handle such kind of communication would (IMO) be to have one device send info back to you, you anonymise the data and then relay back to another device.

No

That is then not going to work. MY_DEVICES subscriptions can only receive PRIVATE events.
But with products, you may want to consider my update above (Particle may even enforce that - but I’m not sure).

1 Like

Always the little details… Thanks again ScruffR!