Skip to content

Instantly share code, notes, and snippets.

@dschuetz
Last active April 26, 2021 13:51
Show Gist options
  • Save dschuetz/565c77233a73cfb121770460469af65b to your computer and use it in GitHub Desktop.
Save dschuetz/565c77233a73cfb121770460469af65b to your computer and use it in GitHub Desktop.
#include <dummy.h>
/*
David Schuetz @DarthNull
March, 2021
Minimal MQTT Interface for AdaFruit NeoTrellis 16-key keypad
Includes elements from:
* MQTT bits: https://RandomNerdTutorials.com/esp32-mqtt-publish-ds18b20-temperature-arduino/
* NeoTrellis: Adafruit examples
See https://darthnull.org/series/remote-keypad for more information
*/
#include "Adafruit_NeoTrellis.h"
Adafruit_NeoTrellis trellis;
#include <WiFi.h>
#define WIFI_SSID "MY-AP-NAME"
#define WIFI_PASSWORD "MY-AP-PASSWORD"
#include <AsyncMqttClient.h> // https://github.com/marvinroger/async-mqtt-client
#define MQTT_HOST IPAddress(192, 168, 1, 1)
#define MQTT_PORT 1883
AsyncMqttClient mqttClient;
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
/* **** Queueing up light color changes **** */
long int new_light_colors[16];
void setLight(int light, int r, int g, int b) {
new_light_colors[light] = 0x80000000 | (r<<16) | (g<<8) | b;
}
void setLightInt(int light, long int rgb) {
new_light_colors[light] = 0x80000000 | rgb;
}
/* *** WiFi Setup *** */
void connectToWifi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
void connectToMqtt() {
Serial.println("Connecting to MQTT...");
mqttClient.connect();
}
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
Serial.print("WiFi connected. IP address: ");
Serial.println(WiFi.localIP());
connectToMqtt();
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
xTimerStart(wifiReconnectTimer, 0);
break;
}
}
/* *** MQTT Setup *** */
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
mqttClient.subscribe("controller/keypad/srvr/light/#", 1);
}
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");
if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}
/* **** Respond to MQTT and Keyboad events **** */
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
int b_idx = 0;
if (! strncmp(topic, "controller/keypad/srvr/light/", 29)) {
char *ptr = topic;
ptr += 29;
int light_num = atoi(ptr);
long int rgb = strtol(payload, 0, 16);
setLightInt(light_num, rgb);
}
}
TrellisCallback onKey(keyEvent evt){
uint16_t packetIdPub1;
if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) {
setLight(evt.bit.NUM, 255,255,255);
Serial.print("Key pressed! Number: ");
Serial.println(evt.bit.NUM);
} else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
setLight(evt.bit.NUM, 0, 0, 0);
Serial.print("Key released! Number: ");
Serial.println(evt.bit.NUM);
char cmd[64];
snprintf(cmd, 64, "controller/keypad/srvr/key/%d", evt.bit.NUM);
packetIdPub1 = mqttClient.publish(cmd, 1, false, "pressed");
}
return 0;
}
/* **** Starting up after a reboot **** */
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
if (!trellis.begin()) {
Serial.println("Could not start trellis, check wiring?");
while(1);
} else {
Serial.println("NeoPixel Trellis started");
}
for (int i=0; i<NEO_TRELLIS_NUM_KEYS; i++) {
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
trellis.activateKey(i, SEESAW_KEYPAD_EDGE_FALLING);
trellis.registerCallback(i, onKey);
}
for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, i*16, i*16, i*16);
trellis.pixels.show();
delay(50);
}
for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
trellis.pixels.setPixelColor(i, 0x000000);
trellis.pixels.show();
delay(50);
}
for (int i=0; i < 16; i++) {
new_light_colors[i] = 0;
}
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
WiFi.onEvent(WiFiEvent);
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
mqttClient.onMessage(onMqttMessage);
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
connectToWifi();
}
/* **** The MAIN loop **** */
void loop() {
long int rgb;
byte c, r, g, b;
trellis.read();
for (int i=0; i<16; i++) {
rgb = new_light_colors[i];
r = (byte)(rgb>>16);
g = (byte)(rgb>>8);
b = (byte)(rgb);
if (rgb & 0x80000000) {
trellis.pixels.setPixelColor(i, r, g, b);
new_light_colors[i] = 0;
}
}
trellis.pixels.show();
delay(100);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment