Yet Another 433 light switches example

About This Project

This is yet another example how to integrate (programmable) power switches into Cayenne.
Because I did not work for a few months with Cayenne I had to re-learn some basic again.
One of them, due to the limited program space of the UNO, I wanted to use CAYENNE_IN_DEFAULT().
But how to identify which widget/channel changed → OK: “request.channel” (check).
In principle this project is not earthshaking, hardly a ripple but perhaps it will help a newbie with his first Cayenne project.

General tips for everybody:

  • document inside your sketch
  • make references to location where to find libraries

What’s Connected

Arduino UNO plus W5100 internet Shield
433 receiver

Triggers & Alerts

None yet

Scheduling

None yet, still missing sunrise/sunset?

Dashboard Screenshots

The sketch

/*
==============================================================================
SKETCH NAME: Cayenne_433_MQTT_UNO created/stiched together by WJ4me aka WJ4IoT
==============================================================================
Cayenne Button Widget Example

This sketch shows how to set up a Button Widget with Cayenne.
The CayenneMQTTEthernet.h is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.

Steps:
1. In the Cayenne Dashboard add a new Button Custom Widget.
2. Select a channel number for the widget. NOW SKETCH WORKS AS FOLLOWS
   - For ELRO switches : request.channel <= 10
   - For FLAMINGO switches : request.channel > 10
5. Set the ACTUATOR_PIN value below to the pin number you used when connecting your 433 transmmitter.
6. Set the Cayenne authentication info to match the authentication info from the Dashboard.
7. Compile and upload this sketch.
8. Once the Arduino connects to the Dashboard you can use the widget button to send digital values.
*/

#define CAYENNE_PRINT Serial     // Comment this out to disable prints and save space
#include <CayenneMQTTEthernet.h> // CayenneMQTT version 1.2.0

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "your username;
char password[] = "your password";
char clientID[] = "your clientid";

// where to connect the data pin of the 433 transmitter
#define ACTUATOR_PIN 7 // INFO: Do not use digital pins 0 or 1 since those conflict with the use of Serial.

// INFO: remark for all next libraries if not in use please disable from sketch to avoid low memory on Arduino UNO + W5100
// for KLIK AAN / KLIK UIT switches (
// #include <RemoteTransmitter.h>                  //https://bitbucket.org/fuzzillogic/433mhzforarduino/wiki/Home
// KaKuTransmitter kaKuTransmitter(ACTUATOR_PIN);  //data-pin 433 on pin 7

// for Flamingo SF-501PWD (among others, the switch need to be learned to listen to the code, read instructions switch how to program them)
// INFO: most of the time put them in the outlet socket and while flashing it can be programmed
#include <NewRemoteTransmitter.h> //library can be found on https://bitbucket.org/fuzzillogic/433mhzforarduino/wiki/Home
NewRemoteTransmitter transmitter(14727168, ACTUATOR_PIN, 260, 3); //values are transmittercode (change?), pin, miliseconds, repeat

// for Elro switches (with dipswitches requires also void Elro(int device, int deviceSwitch))
#include <RCSwitch.h> //using library: https://github.com/sui77/rc-switch (version 2.6.2)
RCSwitch mySwitch = RCSwitch();    

void setup()
{
	Serial.begin(115200);
	pinMode(ACTUATOR_PIN, OUTPUT);
	Cayenne.begin(username, password, clientID);
  // elro 433 test
  /*
  Elro(3, 0);
  delay(2000);
  Elro(3, 1);
  */
}

void loop()
{
	Cayenne.loop();
}

// This function is called when data is sent from Cayenne.
CAYENNE_IN_DEFAULT()
{
  CAYENNE_LOG("CAYENNE_IN_DEFAULT(%u) - %s, actuator: %d, action: %s", request.channel, getValue.getId(), ACTUATOR_PIN, getValue.asString());

  if ( request.channel <= 10 ) {
    Elro(request.channel, getValue.asInt());    
  } else {
    transmitter.sendUnit(request.channel - 10, !getValue.asInt()); //action is reversed so !
    // kaKuTransmitter.sendSignal('B',request.channel, getValue.asInt()); // not checked, no switches 
  }
  /*
  Serial.println(request.channel);
  Serial.println(getValue.asInt());
  */
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void Elro(int device, int deviceSwitch)
// INFO: the ELRO switch works with dipswitches, this consist in two parts the transmitter part in this example '11111'
// and the device part; the request.channel from is here converted into the correct dipswitch sequence (more efficient programming is possible).
// if you have more than 4/5 switches it is likely you want add the transmitter id into this funtion.
{
  char* elro_id;
  //Serial.println(device);
  if      (device == 1) { elro_id = "10000";} 
  else if (device == 2) { elro_id = "01000";}
  else if (device == 3) { elro_id = "00100";}
  else if (device == 4) { elro_id = "00010";
  } else { elro_id = "00001";  
  }
  mySwitch.enableTransmit(ACTUATOR_PIN);
  if (deviceSwitch == 1) {
    mySwitch.switchOn("11111", elro_id);
    //Serial.println(elro_id);
  } else { //(deviceSwitch == 0)
    mySwitch.switchOff("11111", elro_id);
    //Serial.println(elro_id);
  }
  mySwitch.disableTransmit();
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

That’s all folks

Nice project @wj4me.
You can use this to get data of each channel when changed in CAYENNE_IN_DEFAULT()

CAYENNE_IN_DEFAULT()
{
  switch (request.channel) {
    case 1 :
      x = getValue.asInt();
      break;
    case 2 : 
      x = getValue.asInt();
  }
}
1 Like

I fully agree that the use of the case function is more distinct and clearer than a (complex) if…else construction and would have been gaining valuable bytes in the elro function (50 bytes) when:

  if      (device == 1) { elro_id = "10000";} 
  else if (device == 2) { elro_id = "01000";}
  else if (device == 3) { elro_id = "00100";}
  else if (device == 4) { elro_id = "00010";
  } else {                elro_id = "00001";  
  }

is replaced by:

  switch (device) {
    case 1 :
      elro_id = "10000";
      break;
    case 2 :
      elro_id = "01000";  
      break;
    case 3 :
      elro_id = "00100";  
      break;  
     case 4 :
      elro_id = "00010";  
      break;
    default :
      elro_id = "00001";  
      break;
  }

But what i am missing in the Arduino case function is the possibility to do: “case 1, 2, 3, 4, 5 :” because in this sketch those values have in “CAYENNE_IN_DEFAULT()” the same actions (same as 11,12).

i did not understand what you mean here.

in VBA it is possible to group inside a case function (see here) so in principle only towo cases are required: 1 to 5 and (11, 12), think this is missing in the Arduino case function so you need to repeat yourself in case 1, case 2 case etc ergo if…else might be the better solution.

depends on how one handles their code, i would prefer the switch case. You can use if else if it works for you.