Art project help - quite a noob

Hello guys!
I'm quite new to Photon and coding as well.
We're are trying to build a controller for an art piece and the eletronic part should be really simple:

We need to press one (or more) button on one Photon, in London, and light an (or more) assigned LED on a Photon in Congo. This has to be as Real Time as possible.

My questions at the moment are:
-Can I publish directly to another device or do I need IFTTT for this?
-Should I use Publish Event or Call a Function

These are the codes I have so far:

Publishing Photon:

int led = D7; // Uses inbuilt LED
int pushButton = D1; // Push button is connected to D1

// This routine runs only once upon reset
void setup() 
{
  pinMode(led, OUTPUT); // Initialize D7 pin as output
  pinMode(pushButton, INPUT_PULLUP); 
  // Initialize D1 pin as input with an internal pull-up resistor
}

// This routine loops forever
void loop() 
{
  int pushButtonState; 

  pushButtonState = digitalRead(pushButton);

  if(pushButtonState == LOW)
  { // If we push down on the push button
    digitalWrite(led, HIGH);  // Turn ON the LED
    Spark.publish("pushButtonState","Pressed",60,PRIVATE);
    // Add a delay to prevent getting tons of emails from IFTTT
    delay(300); 
  }
  else
  {
    digitalWrite(led, LOW);   // Turn OFF the LED 
  }

}

.
Subscribing Photon:

int led_green = D1;
int led_yellow = D2;

void setup() 
{
    Serial.begin(9600);
    
    pinMode(led_green, OUTPUT);
    pinMode(led_yellow, OUTPUT);
    
    Serial.println(Spark.subscribe("pressButton1State", greenOn, "230043000547343232363230"));
    Serial.println(Spark.subscribe("pressButton2State", yellowOn));
}

void loop() 
{
    delay(200);
}


void greenOn(const char *event, const char *data)
{
    digitalWrite(D7, HIGH);
}
void yellowOn(const char *event, const char *data)
{
    digitalWrite(D7, HIGH);
}

This pretty much does what you’re looking for, without having to go through IFTTT.
Do update it from “spark” to “particle” if you would:

I’m not sure that this line of code actually works (despite the docs)

 Serial.println(Spark.subscribe("pressButton1State", greenOn, "230043000547343232363230"));

Unless I missed the memo, subscribing to events of a particular device is not yet supported.
You’d rather use

 Serial.println(Particle.subscribe("pressButton1State", greenOn, MY_DEVICES));

and secondly, you’d need to subscribe to an event that starts with a common prefix, but you do

 Serial.println(Spark.subscribe("pressButton1State", greenOn, "230043000547343232363230"));

while publishing

Spark.publish("pushButtonState","Pressed",60,PRIVATE);

So you’d rather subscribe to

 Serial.println(Particle.subscribe("pushButtonState", someLedOn, MY_DEVICES));

then you only need one handler that deals with all kinds of published events (by evaluating the event name and data parameters) that start with "pushButtonState" like these

Particle.publish("pushButtonStateGreen","Pressed", PRIVATE);
// or
Particle.publish("pushButtonStateYellow","Pressed", PRIVATE);
// or
Particle.publish("pushButtonState","Yellow Pressed", PRIVATE);

And you should use a way to prevent multiple publishes when you press and hold the button and also ensure that you heed the one per second rate limit for Particle.publish() - delay(300) might be too short for that.

2 Likes

Thank you for the quick reply ScruffR!

So you're saying I should use IFTTT? (don't really know how to use webhooks)

This is really interesting. I think I understand what you mean.

so if I do:

if(pushButtonState1 == LOW)
  { 
    digitalWrite(led, HIGH);
    Particle.publish("pushButtonState","Green pressed",PRIVATE);
    delay(500); 

on the Publishing and:

Serial.println(Particle.subscribe("pressButtonState", someLedOn, MY_DEVICES));

How can I determine which LED to turn on (just by the content "Green pressed" of the event)?

Nope, I don't. I just said that way to subscribe to your own publish would not work.

exactly - by ...

... e.g. like this

void someLedOn(const char *event, const char *data)
{
   if (!strcmp(data, "Green pressed"))  // if there is zero difference between the two strings
    digitalWrite(greenLedPin, HIGH);    // light up
}

Although I'd rather use numeric values instead of string literals

1 Like

This is great, I was trying something similar but obviously didn't think of that.

Should I just replace

Particle.publish("pushButtonState","Green pressed",PRIVATE);

for

Particle.publish("pushButtonState",1,PRIVATE);

then or something similar?

How could I go about it if not IFTTT then?
(sorry again, complete noob here)

Almost there I think! Thank for the help so far anyway!

The code as is does already play without IFTTT - no extra work needed.

That would be sort of it, but the 1 would need to be a string (which will be converted back to an int again in the handler) and the real power of that would be unleashed when making that dynamic.

like this

  char evtData[32];
  int btnNr;

  // somehow get the pressed button number into btnNr

  snprintf(evtData, sizeof(evtData), "%d", btnNr); // that can even be more complex for multiple infos in one event
  Particle.publish("pushButtonState", evtData, PRIVATE);

and on the receiving end

void someLedOn(const char *event, const char *data)
{
  int btnNr = atoi(data);  // convert string back to int

  switch(btnNr)
  {
    case 1:
      // do something for button 1 like
      digitalWrite(greenLedPin, HIGH);    // light up
      break;
    case 2;
      // do something for button 2
      break;
    default:
      break;
  }
}
1 Like