Before I get too far, would someone mind just checking my code?

So I’ve got a basic proof of concept working…

I’ve got four Particle Cores. I want to have each of them hooked up to various buttons and switches and various LEDs. I want to have them selectively react to button presses on other Cores.

I started by adapting Quantumly Entangled LEDs and now have this code:-


/*
Core1.
*/


int sendLedPin = D7; //choose the pin for the send (local) LED
int inputPin = D4; //choose the input pin (for a pushbutton)
int receiveLedPin = D0; //choose the pin for the receive (Core2-dependent LED)
int val = 0; //variable for reading the pushbutton pin status
int sendLedVal = 0; //variable for keeping the state of the local pushbutton dependent LED (D2)
void ledTwoToggle(const char *toggle, const char *onOff); //handler function for Spark.subscribe()

void setup() {
    pinMode(receiveLedPin, OUTPUT); //Set the pin controlling the Core2-dependent LED as an OUTPUT
    pinMode(sendLedPin, OUTPUT); //Set the pin controlling the local pushbutton-dependent LED as an OUTPUT
    pinMode(inputPin, INPUT); //Set the pin connected to the pushbutton as an INPUT
    digitalWrite(sendLedPin, LOW); //Ensure the local LED is set to off to begin with
    digitalWrite(receiveLedPin, HIGH); //Ensure the local LED is set to off to begin with
    Spark.publish("Core1Toggle", "State", 0); //Set up Spark.publish() so that the state of the local LED is published to the Spark Cloud PRIVATELY
    Spark.subscribe("Core2Toggle", ledTwoToggle); //Set up Spark.subscribe() so that the state of Core1's Led is recorded and handled by ledTwoToggle
}

void loop() {
    val = digitalRead(inputPin); //read value of pushbutton
    
    if (val == LOW) { //if clause activated if pushbutton pressed and thus inputPin reads LOW
        sendLedVal = !sendLedVal; //if clause activated if pushbutton pressed and thus inputPin reads LOW
        digitalWrite(sendLedPin, sendLedVal ? HIGH : LOW); //write the appropriate HIGH/LOW to the sendLed pin to turn it ON/OFF
        Spark.publish("Core1Toggle", sendLedVal ? "ON" : "OFF"); //publish the state to the Spark Cloud as ON/OFF
        delay(250); //primitive button debouncing
    }
}

void ledTwoToggle(const char *toggle, const char *onOff){ //handler function for Spark.subscribe()
    if (strcmp(onOff, "ON") == 0){ //if sendLed on Core2 is ON according to Spark.publish()
        digitalWrite(receiveLedPin, HIGH); //then turn on receiveLed
    } else if (strcmp(onOff, "OFF") == 0){ //if sendLed on Core2 is OFF according to Spark.publish()
        digitalWrite(receiveLedPin, LOW); //then turn off receiveLed
    }
}

which just seems rather complicated for the act of transmitting a button press over the interwebs to another Core and turning an LED on. Anyway if that’s how it has to be, that’s how it has to be. I wondered if someone would mind just commenting on whether there is an easier way to do this before I set about adapting/writing more code. Thank you! :slight_smile:

it doesn’t look over complicated… rather over-commented, though.

If you take out all that superfluous commentary, you have quite a simple program!

a few (untested) mods:

int sendLedPin = D7;
int inputPin = D4;
int receiveLedPin = D0;
int lastVal = 0;
int sendLedVal = 0;

void ledTwoToggle(const char *toggle, const char *onOff); //handler function for Spark.subscribe()

void setup()
{
  pinMode(receiveLedPin, OUTPUT);
  pinMode(sendLedPin, OUTPUT);
  pinMode(inputPin, INPUT);
  digitalWrite(sendLedPin, LOW);
  digitalWrite(receiveLedPin, HIGH);
  Particle.publish("Core1Toggle", "State", 0);
  Particle.subscribe("Core2Toggle", ledTwoToggle);
}

void loop()
{
  static unsigned long lastPressTime =0;
  int val = digitalRead(inputPin);
  if (val == LOW && lastVal == HIGH)
  {
    if (millis() - lastPressTime > 25UL) //less primitive (non-blocking) debounce time
    {
      sendLedVal = !sendLedVal;
      digitalWrite(sendLedPin, sendLedVal ? HIGH : LOW);
      Particle.publish("Core1Toggle", sendLedVal ? "ON" : "OFF");
    }
    lastPressTime = millis();
  }
  lastVal = val;
}

void ledTwoToggle(const char *toggle, const char *onOff) 
{ 
  if (strcmp(onOff, "ON") == 0)
  { 
    digitalWrite(receiveLedPin, HIGH);
  }
  else if (strcmp(onOff, "OFF") == 0)
  { 
    digitalWrite(receiveLedPin, LOW); 
  }
}

Thank you - I will try that tomorrow morning - much appreciated.

I have another version of the code with some non-blocking debounce but it’s using a library, which I had to incorporate into the body of the code (am I right I can’t ‘call’ on libraries in separate files like I can with Arduino?).

This is much neater, though, so thank you!

So for every separate state I want to keep track of I’ll need a separate “void ledtwotoggle” ? Fine if so, I’ll get copying and pasting! :smiley:

Try clicking the small + icon in the top right corner. That creates a new .h and .ccp file in which you can paste your library.

marvellous! a new feature or something I’ve missed? thank you!

It’s been there for quite some time :wink:

No, if you wrap your sending device ID and any other useful info into your event name and data payload you can just get along with one handler.

There might me some doc reading to be done, but one hint is that the event name you are subscribing to is only a prefix filter (e.g. CoreToggle would fire for CoreToggle1 and CoreToggle2 and even CoreToggleAnyOtherSuffix).

Just check the contents of toggle along side onOff.

If you use your DeviceID rather than an arbitrary number you can even flash the same code to all of your Cores and each Core would know if it’s receiving own events or one of the others without the need to set that number in code for each individual Core.

This sounds great. I’m trying to wrap my head around it. I keep revisiting your message and having another read of it and it does get clearer each time.

I’ll try and find some documentation to read. Thanks.

Thanks @BulldogLowell, once I changed particle.subscribe etc back to spark.subscribe it compiled and uploaded without a hitch and you’re quite right, without all the comments, it’s actually easier to read! So thanks.

Bit of a weird problem… I seem to have a problem with a floating button. Moving (like raising my arm) anywhere near the prototyping area causes the button to act as if it’s been pressed really quickly.

But this shouldn’t be happening, right? Because I’m using the internal pullup on the input button to avoid this?

pinMode(inputPin, INPUT_PULLUP);

Bit confused. It’s as if something’s acting as an antenna and transmitting my movements to the Core.

@daneboomer,

Your personality may be too magnetic. If I had that much personality, I might try a bigger external pullup. :wink:

but seriously :smiley: what gives?? :slight_smile: :wink:

seriously, try an external pullup and see if you still have the issue… perhaps a 10kOhm and see what happens.

from time to time, and I cannot say why it happens, I’ve had your issue with MCU’s.

oK, I’ll give it a go. Although I have just gone back to basics and tried the arduino “button” example sketch (but with internal pullup on rather than using an external one) and it’s stable as anything. It’s almost like it’s the complication of spark publish/subscribe which is introducing the noise. Which doesn’t make any sense, right?

right, but I would try it, If I had a spare resistor kicking around

Hi @ScruffR, believe it or not now has been my first opportunity to have a play with your suggestion and try to implement it.

The good news? I have no floating problems at all anymore. Everything is as solid as a rock. I presume this is down to the new firmware. I am delighted.

The slightly less good news is that I cannot figure out how I can get away with only using one ‘voidledtwotoggle’, because I have noticed in my attempt to implement to “share the void” that the void controls the status of digitalwrite to my output LED.

Any help in making one void work for multiple buttons and multiple LEDs would be much appreciated because I am aware I cannot have more than four spark subscribe/spark publish. Thanks again

While there is a limit for subscriptions, there is none for publishes and when you subscribe to e.g. "myPrefix" your handler will be triggered for anything that starts with "myPrefix", so you can use do e.g. Particle.publish("myPrefixLED1", "ON") and Particle.publish("myPrefixLED2", "OFF") and both wil trigger the same handler. To check which LED is meant, you look at the first parameter you called *toggle.

Or you send something like "LED1=OFF"/LED2=ON", split this up and use the seperated values.