SONOFF button to change relay state


#1

Hi i use this code for control SONOFF relay, Relay on digital pin 12, this device have button on digital pin 0, but how to change code to controll relay with this button. my idea is: i press button and relay chage state without intrnet.

[details=Summary]//#define CAYENNE_DEBUG // Uncomment to show debug messages
#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space
#include “CayenneDefines.h”
#include “BlynkSimpleEsp8266.h”
#include “CayenneWiFiClient.h”

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = “****";
// Your network name and password.
char ssid[] = "
”;
char password[] = “***************”;

void setup()
{
Serial.begin(9600);
Cayenne.begin(token, ssid, password);
}

void loop()
{
Cayenne.run();
}[/details]


#2

My first try is here but not working

[details=Summary]//#define CAYENNE_DEBUG // Uncomment to show debug messages
#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space
#include “CayenneDefines.h”
#include “BlynkSimpleEsp8266.h”
#include “CayenneWiFiClient.h”

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = “";
// Your network name and password.
char ssid[] = "
";
char password[] = "
************”;

void setup()
{

Serial.begin(9600);
Cayenne.begin(token, ssid, password);

}

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

int LEDka = 12; // relay on pin 12
int TLAC = 0; // button on pin 0
boolean svetlo = false; // Pomocná hodnota světlo

void checkSensor()
{
// If tlac HIGH (true)
if (digitalRead(TLAC))
{
//if světlo, then tma and conversely
if (svetlo) svetlo = false; else svetlo = true;
//write svetlo on output
digitalWrite(LEDka, svetlo);
//while button on wait 50ms
while (digitalRead(TLAC)) delay(50);
}

}[/details]


#3

Hi @Skeleton84,

Can you check out this post by @tad.dvor.

-B


#4

Hi
yes this is working for controll relay and led from cayenne, but my question is how to change code to controll relay with button (sonoff have 1 button on digital pin 0). my idea is: i press button and relay chage state without intrnet.


#5

Oh I see. You want to be able to push the button to turn on/off the relay, without relying on internet.

@kreggly or @adam should be able to help you better than me here :slight_smile:


#6

https://www.arduino.cc/en/Tutorial/Debounce

Here’s one option.

Cheers,

Craig


#7

However, I much prefer a packaged cleaner solution, so I prefer this one:

/* 
 DESCRIPTION
 ====================
 Simple example of the Bounce library that switches the debug LED when a button is pressed.
 */
// Include the Bounce2 library found here :
// https://github.com/thomasfredericks/Bounce-Arduino-Wiring
#include <Bounce2.h>

#define BUTTON_PIN 2
#define LED_PIN 13

// Instantiate a Bounce object
Bounce debouncer = Bounce(); 

void setup() {

  // Setup the button with an internal pull-up :
  pinMode(BUTTON_PIN,INPUT_PULLUP);

  // After setting up the button, setup the Bounce instance :
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5); // interval in ms

  //Setup the LED :
  pinMode(LED_PIN,OUTPUT);

}

void loop() {
  // Update the Bounce instance :
  debouncer.update();

  // Get the updated value :
  int value = debouncer.read();

  // Turn on or off the LED as determined by the state :
  if ( value == LOW ) {
    digitalWrite(LED_PIN, HIGH );
  } 
  else {
    digitalWrite(LED_PIN, LOW );
  }

}

#8

…works 4 me!
Damn, I love these $4 Sonoff devices!
I bought a bunch of’em!
And, yes, I had been trying to make that integrated button toggle on and off!

Only problem here is- now, it’s not running Cayenne! :confused:
Ya, I’m NEVER satisfied! Heheheheh-
Keep up the fine work, @kreggly
One step at a time, one step at a time. :wink:
Dang, I’m a horrible programmer-
Cayenne needs to integrate BOOLEAN functions in the “If Then” triggers. I sure hope it’s on the roadmap…or roadGPS…whatever…


#9

I am going to buy a bunch of these too. For the price, they can’t be beat.

Do you have a schematic, Bill?

Cheers,

Craig


#10

Sonof schematic.
https://www.itead.cc/wiki/File:Sonoff-Schmatic.pdf


#11

Their power supply is mostly SMT, I noticed, using a TINY AC transformer, and a SMT buck regulator. I actually DID try to decode their circuit.

I’m jealous that they got the PS so small. The bastards are making this Sonoff device cheaper than I can possibly make my Charlette or Allie devices. The ONLY thing I don’t like is- the relay isn’t Form C, -it’s Power ON / Power OFF. Still, it’s simple, inexpensive and effective.

I’ve made ALL my Sonoff devices “extension cords”. I bought $2 18" long standard white extension cords, cut them in half, then screwed each half of the extension cords onto the Sonoff terminals. It makes a VERY nice, ultra inexpensive IoT extension cord.


#12

Here’s the SonOff On/Off code for MQTT. Perhaps @adam can integrate this into Cayenne-
/*

 It connects to an MQTT server then:
  - on 0 switches off relay
  - on 1 switches on relay
  - on 2 switches the state of the relay

  - sends 0 on off relay
  - sends 1 on on relay

 It will reconnect to the server if the connection is lost using a blocking
 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
 achieve the same result without blocking the main loop.

 The current state is stored in EEPROM and restored on bootup

*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Bounce2.h>
#include <EEPROM.h>


const char* ssid = "YourSSID";
const char* password = "YourPASS";
const char* mqtt_server = "YourMQTTBroker'sIP";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

const char* outTopic = "Sonoff1out";
const char* inTopic = "Sonoff1in";

int relay_pin = 12;
int button_pin = 0;
bool relayState = LOW;

// Instantiate a Bounce object :
Bounce debouncer = Bounce(); 


void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    extButton();
    for(int i = 0; i<500; i++){
      extButton();
      delay(1);
    }
    Serial.print(".");
  }
  digitalWrite(13, LOW);
  delay(500);
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13, LOW);
  delay(500);
  digitalWrite(13, HIGH);
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '0') {
    digitalWrite(relay_pin, LOW);   // Turn the LED on (Note that LOW is the voltage level
    Serial.println("relay_pin -> LOW");
    relayState = LOW;
    EEPROM.write(0, relayState);    // Write state to EEPROM
    EEPROM.commit();
  } else if ((char)payload[0] == '1') {
    digitalWrite(relay_pin, HIGH);  // Turn the LED off by making the voltage HIGH
    Serial.println("relay_pin -> HIGH");
    relayState = HIGH;
    EEPROM.write(0, relayState);    // Write state to EEPROM
    EEPROM.commit();
  } else if ((char)payload[0] == '2') {
    relayState = !relayState;
    digitalWrite(relay_pin, relayState);  // Turn the LED off by making the voltage HIGH
    Serial.print("relay_pin -> switched to ");
    Serial.println(relayState); 
    EEPROM.write(0, relayState);    // Write state to EEPROM
    EEPROM.commit();
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish(outTopic, "Sonoff1 booted");
      // ... and resubscribe
      client.subscribe(inTopic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      for(int i = 0; i<5000; i++){
        extButton();
        delay(1);
      }
    }
  }
}

void extButton() {
  debouncer.update();
   
   // Call code if Bounce fell (transition from HIGH to LOW) :
   if ( debouncer.fell() ) {
     Serial.println("Debouncer fell");
     // Toggle relay state :
     relayState = !relayState;
     digitalWrite(relay_pin,relayState);
     EEPROM.write(0, relayState);    // Write state to EEPROM
     if (relayState == 1){
      client.publish(outTopic, "1");
     }
     else if (relayState == 0){
      client.publish(outTopic, "0");
     }
   }
}

void setup() {
  EEPROM.begin(512);              // Begin eeprom to store on/off state
  pinMode(relay_pin, OUTPUT);     // Initialize the relay pin as an output
  pinMode(button_pin, INPUT);     // Initialize the relay pin as an output
  pinMode(13, OUTPUT);
  relayState = EEPROM.read(0);
  digitalWrite(relay_pin,relayState);
  
  debouncer.attach(button_pin);   // Use the bounce2 library to debounce the built in button
  debouncer.interval(50);         // Input must be low for 50 ms
  
  digitalWrite(13, LOW);          // Blink to indicate setup
  delay(500);
  digitalWrite(13, HIGH);
  delay(500);
  
  Serial.begin(115200);
  setup_wifi();                   // Connect to wifi 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  extButton();
}

#13

Yeah, would be incredibly simple. If you want to try for yourself here is the code:


#14

-I still don’t understand how it integrates with Cayenne?
For example- the MQTT server.
I dunno it’s IP address. How to I assign it? PW, login and such? Huh?
I’m told Cayenne enables the MQTT server by default. How?
Thank you! :slight_smile:


#15

-but you didn’t answer the question in the form of Cayenne.:confused:

/* 
 DESCRIPTION
 ====================
 Simple example of the Bounce library that switches the debug LED when a button is pressed.
 */
// Include the Bounce2 library found here :
// https://github.com/thomasfredericks/Bounce-Arduino-Wiring
#include <Bounce2.h>

#define BUTTON_PIN 2
#define LED_PIN 13

// Instantiate a Bounce object
Bounce debouncer = Bounce(); 

void setup() {

  // Setup the button with an internal pull-up :
  pinMode(BUTTON_PIN,INPUT_PULLUP);

  // After setting up the button, setup the Bounce instance :
  debouncer.attach(BUTTON_PIN);
  debouncer.interval(5); // interval in ms

  //Setup the LED :
  pinMode(LED_PIN,OUTPUT);

}

void loop() {
  // Update the Bounce instance :
  debouncer.update();

  // Get the updated value :
  int value = debouncer.read();

  // Turn on or off the LED as determined by the state :
  if ( value == LOW ) {
    digitalWrite(LED_PIN, HIGH );
  } 
  else {
    digitalWrite(LED_PIN, LOW );
  }

}

#16

All that info is presented to you when you create the MQTT device.


#17

Thanks.


#18

could you…possible, please re-paste that previously pasted code?
It doesn’t look like it pasted correctly.
And I’m so noob that I don’t know any better-
it doesn’t work.
Compile error.
G’night. Too late to keep playing.