Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,6 @@ data/

# Misc. Data
tests/
venv/
venv/

Doxyfile
13 changes: 12 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
{
"files.associations": {
"limits": "c",
"type_traits": "c"
"type_traits": "c",
"array": "cpp",
"deque": "cpp",
"list": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"string_view": "cpp",
"format": "cpp",
"initializer_list": "cpp",
"span": "cpp"
},
"C_Cpp.dimInactiveRegions": true,
"dotnet.defaultSolution": "disable",
Expand Down
2 changes: 1 addition & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -2451,4 +2451,4 @@ GENERATE_LEGEND = YES
# plantuml temporary files.
# The default value is: YES.

DOT_CLEANUP = YES
DOT_CLEANUP = YES
4 changes: 2 additions & 2 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name=Adafruit WipperSnapper
version=1.0.0-beta.110
version=1.0.0-beta.112
author=Adafruit
maintainer=Adafruit <[email protected]>
sentence=Arduino application for Adafruit.io WipperSnapper
paragraph=Arduino application for Adafruit.io WipperSnapper
category=Communication
url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino
architectures=*
depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 Library, Adafruit INA237 and INA238 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306
depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 Library, Adafruit INA237 and INA238 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, Adafruit EPD
7 changes: 4 additions & 3 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,17 @@ lib_deps =
https://github.com/tyeth/omron-devhub_d6t-arduino.git
https://github.com/pstolarz/OneWireNg.git
; COMMENT OUT FOR RP2040/RP2350 BOARDS
https://github.com/milesburton/Arduino-Temperature-Control-Library.git
;https://github.com/milesburton/Arduino-Temperature-Control-Library.git
; AND UNCOMMENT FOR RP2040/RP2350 BOARDS
; https://github.com/pstolarz/Arduino-Temperature-Control-Library.git
https://github.com/pstolarz/Arduino-Temperature-Control-Library.git
https://github.com/Sensirion/arduino-sht.git
https://github.com/Sensirion/arduino-i2c-scd4x.git
https://github.com/Sensirion/arduino-i2c-sen5x.git
https://github.com/Sensirion/arduino-i2c-sen66.git
https://github.com/adafruit/WiFiNINA.git
https://github.com/Starmbi/hp_BH1750.git
https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
Adafruit EPD



Expand Down Expand Up @@ -265,7 +266,7 @@ extends = common:esp32
board = adafruit_magtag29_esp32s2
build_flags = -DARDUINO_MAGTAG29_ESP32S2 -DBOARD_HAS_PSRAM
;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1
board_build.partitions = tinyuf2-partitions-4MB.csv
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
extra_scripts = pre:rename_usb_config.py

; Adafruit Metro ESP32-S2
Expand Down
186 changes: 186 additions & 0 deletions src/Wippersnapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ Wippersnapper::Wippersnapper() {

// DallasSemi (OneWire)
WS._ds18x20Component = new ws_ds18x20();

// Display controller
WS._displayController = new DisplayController();
};

/**************************************************************************/
Expand Down Expand Up @@ -1655,6 +1658,124 @@ void cbSignalUARTReq(char *data, uint16_t len) {
WS_DEBUG_PRINTLN("ERROR: Unable to decode UART Signal message");
}

/*!
@brief Deserializes a DisplayRequest message and sends it to the display
component.
@param stream
Incoming data stream from buffer.
@param field
Protobuf message's tag type.
@param arg
Optional arguments from decoder calling function.
@returns True if decoded successfully, False otherwise.
*/
bool cbDecodeDisplayMsg(pb_istream_t *stream, const pb_field_t *field,
void **arg) {
if (field->tag == wippersnapper_signal_v1_DisplayRequest_display_add_tag) {

// Decode message into a DisplayAddRequest
wippersnapper_display_v1_DisplayAddOrReplace msgAddReq =
wippersnapper_display_v1_DisplayAddOrReplace_init_zero;
if (!ws_pb_decode(stream,
wippersnapper_display_v1_DisplayAddOrReplace_fields,
&msgAddReq)) {
WS_DEBUG_PRINTLN("ERROR: Failure decoding DisplayAddOrReplace message!");
return false;
}

// Attempt to add or replace a display component
bool did_add =
WS._displayController->Handle_Display_AddOrReplace(&msgAddReq);

// Create a DisplayResponse message
wippersnapper_signal_v1_DisplayResponse msgResp =
wippersnapper_signal_v1_DisplayResponse_init_zero;
msgResp.which_payload =
wippersnapper_signal_v1_DisplayResponse_display_added_tag;
msgResp.payload.display_added.did_add = did_add;
strncpy(msgResp.payload.display_added.name, msgAddReq.name,
sizeof(msgResp.payload.display_added.name));

// Encode and publish response back to broker
memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing));
pb_ostream_t ostream = pb_ostream_from_buffer(WS._buffer_outgoing,
sizeof(WS._buffer_outgoing));
if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_DisplayResponse_fields,
&msgResp)) {
WS_DEBUG_PRINTLN("ERROR: Unable to encode display response message!");
return false;
}

size_t msgSz;
pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_DisplayResponse_fields,
&msgResp);
WS_DEBUG_PRINT("Publishing DisplayResponse Message...");
if (!WS._mqtt->publish(WS._topic_signal_display_device, WS._buffer_outgoing,
msgSz, 1)) {
WS_DEBUG_PRINTLN("ERROR: Failed to DisplayResponse Response!");
} else {
WS_DEBUG_PRINTLN("Published!");
}
} else if (field->tag ==
wippersnapper_signal_v1_DisplayRequest_display_write_tag) {
// Decode message into a DisplayAddRequest
wippersnapper_display_v1_DisplayWrite msgWrite =
wippersnapper_display_v1_DisplayWrite_init_zero;
if (!ws_pb_decode(stream, wippersnapper_display_v1_DisplayWrite_fields,
&msgWrite)) {
WS_DEBUG_PRINTLN("ERROR: Failure decoding DisplayWrite message!");
return false;
}
// Attempt to write to a display
WS._displayController->Handle_Display_Write(&msgWrite);
} else if (field->tag ==
wippersnapper_signal_v1_DisplayRequest_display_remove_tag) {
// Decode message into a DisplayRemoveRequest
wippersnapper_display_v1_DisplayRemove msgRemove =
wippersnapper_display_v1_DisplayRemove_init_zero;
if (!ws_pb_decode(stream, wippersnapper_display_v1_DisplayRemove_fields,
&msgRemove)) {
WS_DEBUG_PRINTLN("ERROR: Failure decoding DisplayRemove message!");
return false;
}
// Attempt to remove a display
WS._displayController->Handle_Display_Remove(&msgRemove);
} else {
WS_DEBUG_PRINTLN("ERROR: Display message type not found!");
return false;
}
return true;
}

/*!
@brief Called when the device receives a new message from the
/display/ topic.
@param data
Incoming data from MQTT broker.
@param len
Length of incoming data.
*/
void cbDisplayMessage(char *data, uint16_t len) {
WS_DEBUG_PRINTLN("* NEW MESSAGE [Topic: Display]: ");
WS_DEBUG_PRINT(len);
WS_DEBUG_PRINTLN(" bytes.");
// zero-out current buffer
memset(WS._buffer, 0, sizeof(WS._buffer));
// copy mqtt data into buffer
memcpy(WS._buffer, data, len);
WS.bufSize = len;

// Set up the payload callback, which will set up the callbacks for
// each oneof payload field once the field tag is known
WS.msgSignalDisplay.cb_payload.funcs.decode = cbDecodeDisplayMsg;

// Decode pixel message from buffer
pb_istream_t istream = pb_istream_from_buffer(WS._buffer, WS.bufSize);
if (!ws_pb_decode(&istream, wippersnapper_signal_v1_DisplayRequest_fields,
&WS.msgSignalDisplay))
WS_DEBUG_PRINTLN("ERROR: Unable to decode display message");
}

/****************************************************************************/
/*!
@brief Handles MQTT messages on signal topic until timeout.
Expand Down Expand Up @@ -2344,6 +2465,63 @@ bool Wippersnapper::generateWSTopics() {
WS_DEBUG_PRINTLN("FATAL ERROR: Failed to allocate memory for UART topic!");
return false;
}

// /display topic //

// Pre-determine topic size
topicLen = strlen(WS._config.aio_user) + strlen("/") + strlen(_device_uid) +
strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + strlen("broker") +
strlen(TOPIC_DISPLAY) + 1;

// Pre-allocate memory for topic
#ifdef USE_PSRAM
WS._topic_signal_display_brkr = (char *)ps_malloc(topicLen);
#else
WS._topic_signal_display_brkr = (char *)malloc(topicLen);
#endif

// Generate the topic
if (WS._topic_signal_display_brkr != NULL) {
snprintf(WS._topic_signal_display_brkr, topicLen, "%s/wprsnpr/%s%sbroker%s",
WS._config.aio_user, _device_uid, TOPIC_SIGNALS, TOPIC_DISPLAY);
} else {
WS_DEBUG_PRINTLN(
"FATAL ERROR: Failed to allocate memory for DISPLAY topic!");
return false;
}

// Subscribe to signal's DISPLAY sub-topic and set callback
_topic_signal_display_sub =
new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_display_brkr, 1);
WS_DEBUG_PRINTLN("Subscribing to DISPLAY topic: ");
WS_DEBUG_PRINTLN(WS._topic_signal_display_brkr);
WS._mqtt->subscribe(_topic_signal_display_sub);
WS_DEBUG_PRINTLN("Subscribed to DISPLAY topic!");
_topic_signal_display_sub->setCallback(cbDisplayMessage);

// Calculate length of the topic for device-to-broker DISPLAY topic
topicLen = strlen(WS._config.aio_user) + strlen("/") + strlen(_device_uid) +
strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + strlen("device") +
strlen(TOPIC_DISPLAY) + 1;

// Allocate memory for dynamic MQTT topic
#ifdef USE_PSRAM
WS._topic_signal_display_device = (char *)ps_malloc(topicLen);
#else
WS._topic_signal_display_device = (char *)malloc(topicLen);
#endif

// Generate the topic if memory was allocated successfully
if (WS._topic_signal_display_device != NULL) {
snprintf(WS._topic_signal_display_device, topicLen,
"%s/wprsnpr/%s%sdevice%s", WS._config.aio_user, _device_uid,
TOPIC_SIGNALS, TOPIC_DISPLAY);
} else {
WS_DEBUG_PRINTLN(
"FATAL ERROR: Failed to allocate memory for DISPLAY topic!");
return false;
}

return true;
}

Expand Down Expand Up @@ -2837,6 +3015,14 @@ void Wippersnapper::connect() {
WS._ui_helper->build_scr_monitor();
#endif

WS.pinCfgCompleted = true;

// Initialize Digital IO class
WS._digitalGPIO = new Wippersnapper_DigitalGPIO(20);
// Initialize Analog IO class
WS._analogIO = new Wippersnapper_AnalogIO(5, 3.3);
WS._boardStatus = WS_BOARD_DEF_OK;

// Configure hardware
while (!WS.pinCfgCompleted) {
WS_DEBUG_PRINTLN(
Expand Down
16 changes: 15 additions & 1 deletion src/Wippersnapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
#include "display/ws_display_ui_helper.h"
#endif

#include "components/display/controller.h"
#include "components/ds18x20/ws_ds18x20.h"
#include "components/pixels/ws_pixels.h"
#include "components/pwm/ws_pwm.h"
Expand All @@ -142,7 +143,7 @@
#endif

#define WS_VERSION \
"1.0.0-beta.110" ///< WipperSnapper app. version (semver-formatted)
"1.0.0-beta.112" ///< WipperSnapper app. version (semver-formatted)

// Reserved Adafruit IO MQTT topics
#define TOPIC_IO_THROTTLE "/throttle" ///< Adafruit IO Throttle MQTT Topic
Expand All @@ -153,6 +154,7 @@
#define TOPIC_INFO "/info/" ///< Registration sub-topic
#define TOPIC_SIGNALS "/signals/" ///< Signals sub-topic
#define TOPIC_I2C "/i2c" ///< I2C sub-topic
#define TOPIC_DISPLAY "/display" ///< Display sub-topic (EPD, OLED, TFT, etc.)
#define MQTT_TOPIC_PIXELS_DEVICE \
"/signals/device/pixel" ///< Pixels device->broker topic
#define MQTT_TOPIC_PIXELS_BROKER \
Expand Down Expand Up @@ -245,6 +247,7 @@ class ws_pwm;
class ws_ds18x20;
class ws_pixels;
class ws_uart;
class DisplayController;

/**************************************************************************/
/*!
Expand Down Expand Up @@ -368,6 +371,8 @@ class Wippersnapper {
ws_servo *_servoComponent; ///< Instance of servo class
ws_ds18x20 *_ds18x20Component; ///< Instance of DS18x20 class
ws_uart *_uartComponent; ///< Instance of UART class
DisplayController
*_displayController; ///< Instance of display controller class

// TODO: does this really need to be global?
uint8_t _macAddr[6]; /*!< Unique network iface identifier */
Expand Down Expand Up @@ -404,6 +409,10 @@ class Wippersnapper {
char *_topic_signal_pixels_device = NULL; /*!< Topic carries pixel messages */
char *_topic_signal_uart_brkr = NULL; /*!< Topic carries UART messages */
char *_topic_signal_uart_device = NULL; /*!< Topic carries UART messages */
char *_topic_signal_display_brkr =
NULL; /*!< Topic carries messages from a device to a broker. */
char *_topic_signal_display_device =
NULL; /*!< Topic carries messages from a broker to a device. */

wippersnapper_signal_v1_CreateSignalRequest
_incomingSignalMsg; /*!< Incoming signal message from broker */
Expand All @@ -430,6 +439,9 @@ class Wippersnapper {
wippersnapper_signal_v1_UARTRequest
msgSignalUART; ///< UARTReq wrapper message

wippersnapper_signal_v1_DisplayRequest
msgSignalDisplay; ///< DisplayRequest wrapper message

char *throttleMessage; /*!< Pointer to throttle message data. */
int throttleTime; /*!< Total amount of time to throttle the device, in
milliseconds. */
Expand Down Expand Up @@ -490,6 +502,8 @@ class Wippersnapper {
*_topic_signal_pixels_sub; /*!< Subscribes to pixel device topic. */
Adafruit_MQTT_Subscribe
*_topic_signal_uart_sub; /*!< Subscribes to signal's UART topic. */
Adafruit_MQTT_Subscribe *_topic_signal_display_sub; /*!< Subscription callback
for display topic. */

Adafruit_MQTT_Subscribe
*_err_sub; /*!< Subscription to Adafruit IO Error topic. */
Expand Down
Loading
Loading