Simple keypad for talking to WLED

So I’ve been playing with WLED for a little while and wanted a simple hard-button remote for just turning on/off, brightness, and maybe cycle through effects. Now, not being any kind of coder but able to cut-and-paste my way through things, ok at following reference designs, and mildly handy with a soldering iron, I figured I’d give it a try. As a working prototype here’s what I have so far after a couple days…

I just blended together the BasicHTTPClient, and Digital>Button example sketches from the Arduino IDE to get something that takes button presses and sends corresponding HTTP API commands to the WLED controller.

/**
   BasicHTTPClient.ino

    Created on: 24.05.2015

*/

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>

#include <WiFiClient.h>

ESP8266WiFiMulti WiFiMulti;

const int button1Pin = 2;     // the number of the pushbutton pin
const int button2Pin = 0;
const int button3Pin = 4; //ADDED EXTERNAL 100K PULL-UP T.O.
const int button4Pin = 5; //ADDED EXTERNAL 100K PULL-UP T.O.

int button1State = 0;         // variable for reading the pushbutton status
int button2State = 0;
int button3State = 0;
int button4State = 0;

void setup() {

  // initialize the pushbutton pin as an input:
  pinMode(button1Pin, INPUT);
  pinMode(button2Pin, INPUT);
  pinMode(button3Pin, INPUT);
  pinMode(button4Pin, INPUT);
  
  Serial.begin(115200);
  // Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("SSID", "PASSWORD");

}

void loop() {
  
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
  button3State = digitalRead(button3Pin);
  button4State = digitalRead(button4Pin);
  
  // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {

    WiFiClient client;

    HTTPClient http;

    //Serial.print("[HTTP] begin...\n");
    if (button1State == LOW)
    (http.begin(client, "http://192.168.1.66/win&T=1")); //WLED ON T.O.

    if (button2State == LOW)
    (http.begin(client, "http://192.168.1.66/win&T=0")); //WLED OFF T.O.

    if (button3State == LOW)
    (http.begin(client, "http://192.168.1.66/win&A=~5")); //INCREMENT MASTER BRIGHTNESS T.O.

    if (button4State == LOW)
    (http.begin(client, "http://192.168.1.66/win&A=~-5")); //DECREMENT MASTER BRIGHTNESS T.O.
    
    //Serial.print("[HTTP] GET...\n");
      // start connection and send HTTP header
      int httpCode = http.GET();

      http.end();
        } else {
      Serial.printf("[HTTP} Unable to connect\n");
    }
    delay(100);
  }

I removed, or commented-out unnecessary stuff to just get what I needed. I’m sure it’s not the most elegant, but it actually works quite well.

My end goal for this project is to have a desktop unit, and then also something that will actually be able to be wired into an in-wall HV box, like any common Decora-style switch or dimmer. This way it will blend into any room with normal light switches, similar to Lutron SeeTouch keypads.

Anyway, I searched around here, but couldn’t find anything similar so here we are. Let me know if I totally missed something like this, or if I’m re-inventing the wheel here. Comments and suggestions welcome.

Tim

1 Like

Here’s an in-wall unit. Still have to figure out how to shoe-horn the AC-DC converter with associated support circuitry in the rest of the space. I can still go a little deeper with the back box though.


I think maybe the two middle buttons (not yet installed, just ordered more today), could be cycle through presets, and cycle through effects? I dunno.

You know IR remotes work pretty well too.

Yeah, but then with all the pointing, and either mounting the controller in line-of-sight from wherever you may be, or remotely locating the IR receiver, with the same problem, this is more flexible in regards to location. A little box on the nightstand with some buttons, only plugged into power, or the same, but right next to all the other light switches. Plus, what else am I going to do with my free time? :grinning_face_with_smiling_eyes:

Anyway, I ordered some different AC-DC converters with all the necessary external components already populated on a small board. 110v AC in, 5v DC out, and nothing is on fire.

I will have to extend the enclosure a bit to get this in, but it should all still fit into a standard US HV box.

For changing brightness or cylcing effect, you could use API Command on the preset and use preset ID on macro button in WLED ui or mobile app. I think it’s more simple
https://kno.wled.ge/features/macros/

1 Like

Ok, so here’s the desktop unit. I’ll probably end up making a different enclosure because the buttons I bought are longer then a thought with the terminals so I would have to increase the depth of the box slightly to fit 8 buttons. I only hooked up 6 right now, but it’s working correctly.

And then the close-to-final version of the in-wall unit. I did have to increase the depth of the box, but I was able to cram it all in without shorting anything. I’m going to design an insert so that the voltage converter is completely surrounded with plastic so that there is no chance of something touching where it shouldn’t.

Here’s the updated code…

/**
   BasicHTTPClient.ino

    Created on: 24.05.2015

*/

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>

#include <WiFiClient.h>

ESP8266WiFiMulti WiFiMulti;

String newHostname = "WLED-WiFi-Remote";

const int button1Pin = 2;     // the number of the pushbutton pin
const int button2Pin = 0;
const int button3Pin = 4; //ADDED EXTERNAL 100K PULL-UP T.O.
const int button4Pin = 5; //ADDED EXTERNAL 100K PULL-UP T.O.
const int button5Pin = 13; //ADDED EXTERNAL 100K PULL-UP T.O.
const int button6Pin = 12; //ADDED EXTERNAL 100K PULL-UP T.O.

int button1State = 0;         // variable for reading the pushbutton status
int button2State = 0;
int button3State = 0;
int button4State = 0;
int button5State = 0;
int button6State = 0;

void setup() {

  // initialize the pushbutton pin as an input:
  pinMode(button1Pin, INPUT);
  pinMode(button2Pin, INPUT);
  pinMode(button3Pin, INPUT);
  pinMode(button4Pin, INPUT);
  pinMode(button5Pin, INPUT);
  pinMode(button6Pin, INPUT);
  
  
  Serial.begin(115200);
  // Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("SSID", "PASSWORD");

  //Set new hostname
  WiFi.hostname(newHostname.c_str());
}

void loop() {
  
  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
  button3State = digitalRead(button3Pin);
  button4State = digitalRead(button4Pin);
  button5State = digitalRead(button5Pin);
  button6State = digitalRead(button6Pin);
  
  // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {

    WiFiClient client;

    HTTPClient http;

    //Serial.print("[HTTP] begin...\n");
    if (button1State == LOW)
    (http.begin(client, "http://192.168.1.66/win&T=1")); //WLED ON T.O.
  

    if (button2State == LOW)
    (http.begin(client, "http://192.168.1.66/win&T=0")); //WLED OFF T.O.
    

    if (button3State == LOW)
    (http.begin(client, "http://192.168.1.66/win&A=~5")); //INCREMENT MASTER BRIGHTNESS T.O.
    

    if (button4State == LOW)
    (http.begin(client, "http://192.168.1.66/win&A=~-5")); //DECREMENT MASTER BRIGHTNESS T.O.

    if (button5State == LOW)
    (http.begin(client, "http://192.168.1.66/win&PL=~")); //NEXT PRESET T.O.

    if (button6State == LOW)
    (http.begin(client, "http://192.168.1.66/win&PL=~-")); //PREVIOUS PRESET T.O.
    
    
    //Serial.print("[HTTP] GET...\n");
      // start connection and send HTTP header
      int httpCode = http.GET();

      http.end();
        } else {
      Serial.printf("[HTTP} Unable to connect\n");
    }
    delay(200);
  }

@denuj Yeah, I’m using the PL=~ and PL=~- API code to cycle next and previous through presets. Although now looking at that page you referenced, I wonder if I can use an analog input for the brightness and use a pot. I’ll have to figure out how to make another loop in the code to read the analog input and send the corresponding value.

there are several usermod that handle analog input, such as: rotary brightness, fourmod display, etc. You could use platform io to edit wled code. Please visit wled wiki for further information and I think it will be easy enough considering you have good coding

I optimized the code which allowed for different delays before re-reading the button state according to function. By only having one delay in the loop, too high and button presses wouldn’t register sometimes, too low and button holds would act too fast and would miss the intended stopping point. On/Off now has a 1000ms delay, dimming has a 50ms delay and I changed the increment to 1 instead of 5, and preset cycling also has a 1000ms delay so that it doesn’t skip presets if you lingered on the button with the press.

/**
   BasicHTTPClient.ino

    Created on: 24.05.2015

*/

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>

#include <WiFiClient.h>

ESP8266WiFiMulti WiFiMulti;

String newHostname = "WLED-WiFi-Remote";

const int button1Pin = 2;     // the number of the pushbutton pin
const int button2Pin = 0;
const int button3Pin = 4; //ADDED EXTERNAL 100K PULL-UP T.O.
const int button4Pin = 5; //ADDED EXTERNAL 100K PULL-UP T.O.
const int button5Pin = 13; //ADDED EXTERNAL 100K PULL-UP T.O.
const int button6Pin = 12; //ADDED EXTERNAL 100K PULL-UP T.O.

int button1State = 0;         // variable for reading the pushbutton status
int button2State = 0;
int button3State = 0;
int button4State = 0;
int button5State = 0;
int button6State = 0;

void setup() {

  // initialize the pushbutton pin as an input:
  pinMode(button1Pin, INPUT);
  pinMode(button2Pin, INPUT);
  pinMode(button3Pin, INPUT);
  pinMode(button4Pin, INPUT);
  pinMode(button5Pin, INPUT);
  pinMode(button6Pin, INPUT);


  Serial.begin(115200);
  // Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("SSID", "PASSWORD");

  //Set new hostname
  WiFi.hostname(newHostname.c_str());
}

void loop() {

  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
  button3State = digitalRead(button3Pin);
  button4State = digitalRead(button4Pin);
  button5State = digitalRead(button5Pin);
  button6State = digitalRead(button6Pin);

   //wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {

    if (button1State == LOW) {
      pressbutton1();
    }

    if (button2State == LOW){
      pressbutton2();
    }
  
    if (button3State == LOW){
      pressbutton3();
    }
   
    if (button4State == LOW){
      pressbutton4();
    }
  
    if (button5State == LOW){
      pressbutton5();
    }
   
    if (button6State == LOW){
      pressbutton6();
    }
      
  } else {
    Serial.printf("[HTTP} Unable to connect\n");
  }
  
}
void pressbutton1() {
  WiFiClient client;
  HTTPClient http;

  (http.begin(client, "http://192.168.1.66/win&T=1")); //WLED ON T.O.
  
  int httpCode = http.GET();

    http.end();
    delay(1000);
}
void pressbutton2(){
  WiFiClient client;
  HTTPClient http;

  (http.begin(client, "http://192.168.1.66/win&T=0")); //WLED OFF T.O.
  
  int httpCode = http.GET();

    http.end();
    delay(1000);
}
void pressbutton3(){
  WiFiClient client;
  HTTPClient http;

  (http.begin(client, "http://192.168.1.66/win&A=~1")); //INCREMENT MASTER BRIGHTNESS T.O.
  
  int httpCode = http.GET();

    http.end();
    delay(50);
}
void pressbutton4(){
  WiFiClient client;
  HTTPClient http;

  (http.begin(client, "http://192.168.1.66/win&A=~-1")); //DECREMENT MASTER BRIGHTNESS T.O.
  
  int httpCode = http.GET();

    http.end();
    delay(50);
}
void pressbutton5(){
  WiFiClient client;
  HTTPClient http;

  (http.begin(client, "http://192.168.1.66/win&PL=~")); //NEXT PRESET T.O.
  
  int httpCode = http.GET();

    http.end();
    delay(1000);
}
void pressbutton6(){
  WiFiClient client;
  HTTPClient http;

  (http.begin(client, "http://192.168.1.66/win&PL=~-")); //PREVIOUS PRESET T.O.
  
  int httpCode = http.GET();

    http.end();
    delay(1000);
}
1 Like