Last active
April 26, 2021 13:51
-
-
Save dschuetz/565c77233a73cfb121770460469af65b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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