Example Code: Xenon reads light sensor, sends info to Argon, which then changes color on RGB LED and publishes to Particle Console

This is another basic code that might be of help to other programming novices like me who are attempting to use the Grove Starter Kit for Particle Mesh with their mesh devices.

Several members on this forum helped me complete my first project as described here:

For my current project, I connected the Light Sensor from the Kit to a Xenon and then connected the Chainable RGB LED to an Argon. With the following codes, the Xenon will read the light sensor and send that info using Mesh to the Argon. The RGB LED connected to the Argon will change colors (yellow if light intensity is above a specified threshold (i.e., "on") at the remote Xenon, and green if "off." The Argon will also publish a note of either "on" or "off" to the Particle Cloud.

I hope the code is of help. This code has NOT been reviewed by more experienced programmers so there are likely some better ways to do this but I know it works. Have fun!

Code for the Xenon:

int photoresistor;

int threshold = 700;//threshold for sensing light,if above
//light goes ON, if below light goes OFF (> = ON, < = OFF)

unsigned long lastSensorRead = 0;
unsigned long sensorInterval = 5000;//I choose to read the sensor every 5 seconds
//and then publish

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  //Use a millis timer for non-blocking code design.
  if (millis() - lastSensorRead > sensorInterval)
  {
    photoresistor = analogRead(A2);//read the photoresistor

    if (photoresistor > threshold)
    {
      Mesh.publish("light", "on");
      Serial.println("on");
    }

    else
    {
      Mesh.publish("light", "off");
      Serial.println("off");
    }

    //Update the sensor read millis timer.
    lastSensorRead = millis();
  }
}

Code for the Argon:

#include <Grove_ChainableLED.h>

#define NUM_LEDS  1//I only have one light in the chain

ChainableLED leds(D2, D3, NUM_LEDS);

int onR = 255;//color of led when light is on
int onG = 255;
int onB = 0;

int offR = 0;//color of led when light is off
int offG = 255;
int offB = 0;

bool light = false;

void lightHandler(const char *event, const char *data)
{
  Serial.printlnf(data);
  Particle.publish("X1-light", String(data), PRIVATE);

  if (strcmp(data, "on") == 0)
  {
    leds.setColorRGB(0, onR, onG, onB);
    light = true;
  }

  else
  {
    leds.setColorRGB(0, offR, offG, offB);
    light = false;
  }
}

void setup()
{
  leds.init();

  Serial.begin(9600);

  Mesh.subscribe("light", lightHandler);
}

void loop()
{

}
1 Like

Good job :+1:
Just a few minor notes
No need to create an intermediate String object (or rather don't do that for multiple reasons)

This is simpler and safer

  // const char* already is a string in this case
  Particle.publish("X1-light", data, PRIVATE);

And this should be the last line in your lightHandler() since the publish might actually corrupt the contents of the data buffer (not relevant in your particular example since you are just reposting the original, but if you were publishing some other string that would interfere with your received data).

Since you are using "on" and "off" twice in your Xenon code and boolean results are treated like numeric 0 and 1 you could write this

also like this

//global array 
const char state[][4] = { "off", "on" };
...
  bool trig = (photoresistor > threshold);
  Mesh.publish("light", state[trig]);
  Serial.println(state[trig]);

and similarly on the Argon the if() { ... } else { ... } can be rewritten like this

// global array for RGB settings (uses less RAM and allows for a more compact code)
// rgb[0] ... off state, rgb[1] ... on state
const byte rgb[][3] = { {0, 255, 0}, {255, 255, 0} };
...
  light = (strcmp(data, "on") == 0); // or less intuitive but shorter light = strcmp(date, "off");
  leds.setColorRGB(0, rgb[light][0], rgb[light][1], rgb[light][2]);

If you wanted, you could also declare an enum for this

enum COLOR_COMPONENTS { R, G, B };
...
  leds.setColorRGB(0, rgb[light][R], rgb[light][G], rgb[light][B]);
2 Likes

Thanks for looking at my code, @ScruffR. I'll go back in and play with your suggestions soon. I'd like to get this part cleaned up because I'm working on a more complicated version that's going to collect data from three (3) Xenons feeding to one (1) Argon with four (4) displays. The code starts to get a little harder to follow the longer it gets so it would be much easier to clean up while it's relatively brief and then expand it from there.

2 Likes