Skip to content

Commit 02ace5c

Browse files
authored
Merge pull request #751 from adafruit/api-v1-add-i2c-output
[API v1]: Add support for I2C Output Components
2 parents 3eed1bc + d784e8a commit 02ace5c

29 files changed

+1269
-47
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,8 @@ examples/Wippersnapper_demo/build/
4848
.pio/
4949

5050
# Secrets
51-
data/
51+
data/
52+
53+
# Misc. Data
54+
tests/
55+
venv/

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper
77
category=Communication
88
url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino
99
architectures=*
10-
depends=SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 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
10+
depends=SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 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 SSD1306

platformio.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ lib_deps =
6767
stm32duino/STM32duino VL53L4CD
6868
stm32duino/STM32duino VL53L4CX
6969
adafruit/Adafruit_VL6180X
70-
adafruit/Adafruit PM25 AQI Sensor
7170
adafruit/Adafruit VEML7700 Library
7271
adafruit/Adafruit LC709203F
7372
adafruit/Adafruit LPS2X
@@ -82,6 +81,10 @@ lib_deps =
8281
adafruit/Adafruit TouchScreen
8382
adafruit/Adafruit MQTT Library
8483
bblanchon/ArduinoJson
84+
adafruit/Adafruit LiquidCrystal
85+
adafruit/Adafruit LED Backpack Library
86+
adafruit/Adafruit PM25 AQI Sensor
87+
adafruit/Adafruit SSD1306
8588
https://github.com/pstolarz/OneWireNg.git
8689
https://github.com/milesburton/Arduino-Temperature-Control-Library.git
8790
https://github.com/Sensirion/arduino-sht.git

src/Wippersnapper.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,28 @@ bool cbDecodeSignalRequestI2C(pb_istream_t *stream, const pb_field_t *field,
871871
if (!encodeI2CResponse(&msgi2cResponse)) {
872872
return false;
873873
}
874+
} else if (field->tag ==
875+
wippersnapper_signal_v1_I2CRequest_req_i2c_device_out_write_tag) {
876+
WS_DEBUG_PRINTLN("[app] I2C Device Output Write");
877+
// Decode stream into an I2CDeviceDeinitRequest
878+
wippersnapper_i2c_v1_I2CDeviceOutputWrite msgDeviceWrite =
879+
wippersnapper_i2c_v1_I2CDeviceOutputWrite_init_zero;
880+
// Decode stream into struct, msgI2CDeviceDeinitRequest
881+
if (!ws_pb_decode(stream, wippersnapper_i2c_v1_I2CDeviceOutputWrite_fields,
882+
&msgDeviceWrite)) {
883+
WS_DEBUG_PRINTLN(
884+
"[app] ERROR: Failed decoding I2CDeviceOutputWrite message.");
885+
return false;
886+
}
887+
888+
if (!WS._i2cPort0->Handle_I2cDeviceOutputWrite(&msgDeviceWrite)) {
889+
WS_DEBUG_PRINTLN("[app] ERROR: Failed to write to I2C output device.");
890+
return false; // fail out if we can't decode, we don't have a response to
891+
// publish
892+
}
893+
WS_DEBUG_PRINTLN("[app] I2C Device Output Write Done");
894+
return true; // we successfully wrote to the device, this subtype has no
895+
// response to publish to IO
874896
} else {
875897
WS_DEBUG_PRINTLN("ERROR: Undefined I2C message tag");
876898
return false; // fail out, we didn't encode anything to publish
@@ -2814,7 +2836,6 @@ void Wippersnapper::connect() {
28142836
#endif
28152837

28162838
// Configure hardware
2817-
WS.pinCfgCompleted = false;
28182839
while (!WS.pinCfgCompleted) {
28192840
WS_DEBUG_PRINTLN(
28202841
"Polling for message containing hardware configuration...");

src/components/i2c/WipperSnapper_I2C.cpp

Lines changed: 137 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,74 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
838838
_adt7410->configureDriver(msgDeviceInitReq);
839839
drivers.push_back(_adt7410);
840840
WS_DEBUG_PRINTLN("ADT7410 Initialized Successfully!");
841+
} else if (strcmp("quadalphanum", msgDeviceInitReq->i2c_device_name) == 0) {
842+
_quadAlphaNum =
843+
new WipperSnapper_I2C_Driver_Out_QuadAlphaNum(this->_i2c, i2cAddress);
844+
_quadAlphaNum->ConfigureI2CBackpack(
845+
msgDeviceInitReq->i2c_output_add.config.led_backpack_config.brightness,
846+
msgDeviceInitReq->i2c_output_add.config.led_backpack_config.alignment);
847+
if (!_quadAlphaNum->begin()) {
848+
WS_DEBUG_PRINTLN("ERROR: Failed to initialize Quad Alphanum. Display!");
849+
_busStatusResponse =
850+
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
851+
return false;
852+
}
853+
_drivers_out.push_back(_quadAlphaNum);
854+
WS_DEBUG_PRINTLN("Quad Alphanum. Display Initialized Successfully!");
855+
} else if (strcmp("chardisplay16x2", msgDeviceInitReq->i2c_device_name) ==
856+
0 ||
857+
strcmp("chardisplay20x4", msgDeviceInitReq->i2c_device_name) ==
858+
0) {
859+
_charLcd = new WipperSnapper_I2C_Driver_Out_CharLcd(this->_i2c, i2cAddress);
860+
_charLcd->ConfigureCharLcd(
861+
msgDeviceInitReq->i2c_output_add.config.char_lcd_config.rows,
862+
msgDeviceInitReq->i2c_output_add.config.char_lcd_config.columns);
863+
if (!_charLcd->begin()) {
864+
WS_DEBUG_PRINTLN("ERROR: Failed to initialize Character LCD!");
865+
_busStatusResponse =
866+
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
867+
return false;
868+
}
869+
_drivers_out.push_back(_charLcd);
870+
WS_DEBUG_PRINTLN("Char LCD Display Initialized Successfully!");
871+
} else if (strcmp("7seg", msgDeviceInitReq->i2c_device_name) == 0) {
872+
_sevenSeg = new WipperSnapper_I2C_Driver_Out_7Seg(this->_i2c, i2cAddress);
873+
_sevenSeg->ConfigureI2CBackpack(
874+
msgDeviceInitReq->i2c_output_add.config.led_backpack_config.brightness,
875+
msgDeviceInitReq->i2c_output_add.config.led_backpack_config.alignment);
876+
if (!_sevenSeg->begin()) {
877+
WS_DEBUG_PRINTLN("ERROR: Failed to initialize 7-Segement LED Matrix!");
878+
_busStatusResponse =
879+
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
880+
return false;
881+
}
882+
_drivers_out.push_back(_sevenSeg);
883+
WS_DEBUG_PRINTLN("7-Segement LED Matrix Initialized Successfully!");
884+
} else if (strcmp("oled128x32default", msgDeviceInitReq->i2c_device_name) ==
885+
0 ||
886+
strcmp("oled128x32large", msgDeviceInitReq->i2c_device_name) ==
887+
0 ||
888+
strcmp("oled128x64default", msgDeviceInitReq->i2c_device_name) ==
889+
0 ||
890+
strcmp("oled128x64large", msgDeviceInitReq->i2c_device_name) ==
891+
0) {
892+
WS_DEBUG_PRINTLN("SSD1306 display detected!");
893+
_ssd1306 = new WipperSnapper_I2C_Driver_Out_Ssd1306(this->_i2c, i2cAddress);
894+
WS_DEBUG_PRINTLN("Configuring SSD1306 display...");
895+
_ssd1306->ConfigureSSD1306(
896+
(uint8_t)msgDeviceInitReq->i2c_output_add.config.ssd1306_config.width,
897+
(uint8_t)msgDeviceInitReq->i2c_output_add.config.ssd1306_config.height,
898+
(uint8_t)
899+
msgDeviceInitReq->i2c_output_add.config.ssd1306_config.text_size);
900+
if (!_ssd1306->begin()) {
901+
WS_DEBUG_PRINTLN("ERROR: Failed to initialize ssd1306!");
902+
_busStatusResponse =
903+
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
904+
return false;
905+
}
906+
WS_DEBUG_PRINTLN("SSD1306 display configured successfully!");
907+
_drivers_out.push_back(_ssd1306);
908+
WS_DEBUG_PRINTLN("SSD1306 display initialized Successfully!");
841909
} else {
842910
WS_DEBUG_PRINTLN("ERROR: I2C device type not found!")
843911
_busStatusResponse =
@@ -886,8 +954,9 @@ void WipperSnapper_Component_I2C::updateI2CDeviceProperties(
886954
void WipperSnapper_Component_I2C::deinitI2CDevice(
887955
wippersnapper_i2c_v1_I2CDeviceDeinitRequest *msgDeviceDeinitReq) {
888956
uint16_t deviceAddr = (uint16_t)msgDeviceDeinitReq->i2c_device_address;
889-
std::vector<WipperSnapper_I2C_Driver *>::iterator iter, end;
890957

958+
// Check input (sensor) drivers
959+
std::vector<WipperSnapper_I2C_Driver *>::iterator iter, end;
891960
for (iter = drivers.begin(), end = drivers.end(); iter != end; ++iter) {
892961
if ((*iter)->getI2CAddress() == deviceAddr) {
893962
// Delete the object that iter points to
@@ -905,6 +974,28 @@ void WipperSnapper_Component_I2C::deinitI2CDevice(
905974
WS_DEBUG_PRINTLN("I2C Device De-initialized!");
906975
}
907976
}
977+
978+
// Check for output drivers
979+
std::vector<WipperSnapper_I2C_Driver_Out *>::iterator out_iter, out_end;
980+
for (out_iter = _drivers_out.begin(), out_end = _drivers_out.end();
981+
out_iter != out_end; ++out_iter) {
982+
if ((*out_iter)->getI2CAddress() == deviceAddr) {
983+
// Set the driver to nullptr
984+
*out_iter = nullptr;
985+
// ESP-IDF, Erase–remove iter ptr from driver vector
986+
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
987+
*out_iter = nullptr;
988+
_drivers_out.erase(
989+
remove(_drivers_out.begin(), _drivers_out.end(), nullptr),
990+
_drivers_out.end());
991+
#else
992+
// Arduino can not erase-remove, erase only
993+
_drivers_out.erase(out_iter);
994+
#endif
995+
WS_DEBUG_PRINTLN("I2C Device De-initialized!");
996+
}
997+
}
998+
908999
_busStatusResponse = wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_SUCCESS;
9091000
}
9101001

@@ -1073,14 +1164,58 @@ void WipperSnapper_Component_I2C::displayDeviceEventMessage(
10731164
}
10741165
}
10751166

1167+
/*******************************************************************************/
1168+
/*!
1169+
@brief Handles an I2CDeviceOutputWrite message.
1170+
@param msgDeviceWrite
1171+
A decoded I2CDeviceOutputWrite message.
1172+
@returns True if the message was handled successfully, false otherwise.
1173+
*/
1174+
/*******************************************************************************/
1175+
bool WipperSnapper_Component_I2C::Handle_I2cDeviceOutputWrite(
1176+
wippersnapper_i2c_v1_I2CDeviceOutputWrite *msgDeviceWrite) {
1177+
1178+
// Create a ptr to the base driver out
1179+
WipperSnapper_I2C_Driver_Out *driver_out = nullptr;
1180+
// Find the matching driver by address in the _drivers_out vector
1181+
for (size_t i = 0; i < _drivers_out.size(); i++) {
1182+
if (_drivers_out[i]->getI2CAddress() ==
1183+
msgDeviceWrite->i2c_device_address) {
1184+
driver_out = _drivers_out[i];
1185+
break;
1186+
}
1187+
}
1188+
if (driver_out == nullptr) {
1189+
WS_DEBUG_PRINTLN("ERROR: I2c output driver not found within drivers_out!");
1190+
return false;
1191+
}
1192+
1193+
// Call the output_msg
1194+
if (msgDeviceWrite->which_output_msg ==
1195+
wippersnapper_i2c_v1_I2CDeviceOutputWrite_write_led_backpack_tag) {
1196+
driver_out->WriteLedBackpack(
1197+
&msgDeviceWrite->output_msg.write_led_backpack);
1198+
} else if (msgDeviceWrite->which_output_msg ==
1199+
wippersnapper_i2c_v1_I2CDeviceOutputWrite_write_char_lcd_tag) {
1200+
driver_out->WriteMessageCharLCD(&msgDeviceWrite->output_msg.write_char_lcd);
1201+
} else if (msgDeviceWrite->which_output_msg ==
1202+
wippersnapper_i2c_v1_I2CDeviceOutputWrite_write_ssd1306_tag) {
1203+
driver_out->WriteMessageSSD1306(
1204+
msgDeviceWrite->output_msg.write_ssd1306.message);
1205+
} else {
1206+
WS_DEBUG_PRINTLN("ERROR: Unknown i2c output message type!");
1207+
return false;
1208+
}
1209+
return true;
1210+
}
1211+
10761212
/*******************************************************************************/
10771213
/*!
10781214
@brief Queries all I2C device drivers for new values. Fills and sends an
10791215
I2CSensorEvent with the sensor event data.
10801216
*/
10811217
/*******************************************************************************/
10821218
void WipperSnapper_Component_I2C::update() {
1083-
10841219
// Create response message
10851220
wippersnapper_signal_v1_I2CResponse msgi2cResponse =
10861221
wippersnapper_signal_v1_I2CResponse_init_zero;

src/components/i2c/WipperSnapper_I2C.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
#include "drivers/WipperSnapper_I2C_Driver_MPRLS.h"
5151
#include "drivers/WipperSnapper_I2C_Driver_MS8607.h"
5252
#include "drivers/WipperSnapper_I2C_Driver_NAU7802.h"
53+
#include "drivers/WipperSnapper_I2C_Driver_Out.h"
54+
#include "drivers/WipperSnapper_I2C_Driver_Out_7Seg.h"
55+
#include "drivers/WipperSnapper_I2C_Driver_Out_CharLcd.h"
56+
#include "drivers/WipperSnapper_I2C_Driver_Out_QuadAlphaNum.h"
57+
#include "drivers/WipperSnapper_I2C_Driver_Out_Ssd1306.h"
5358
#include "drivers/WipperSnapper_I2C_Driver_PCT2075.h"
5459
#include "drivers/WipperSnapper_I2C_Driver_PM25.h"
5560
#include "drivers/WipperSnapper_I2C_Driver_SCD30.h"
@@ -104,6 +109,9 @@ class WipperSnapper_Component_I2C {
104109

105110
void update();
106111

112+
bool Handle_I2cDeviceOutputWrite(
113+
wippersnapper_i2c_v1_I2CDeviceOutputWrite *msgDeviceWrite);
114+
107115
void sensorEventRead(
108116
std::vector<WipperSnapper_I2C_Driver *>::iterator &iter,
109117
unsigned long curTime,
@@ -134,7 +142,10 @@ class WipperSnapper_Component_I2C {
134142
int32_t _portNum;
135143
TwoWire *_i2c = nullptr;
136144
wippersnapper_i2c_v1_BusResponse _busStatusResponse;
137-
std::vector<WipperSnapper_I2C_Driver *> drivers; ///< List of sensor drivers
145+
std::vector<WipperSnapper_I2C_Driver *>
146+
drivers; ///< List of i2c sensor drivers
147+
std::vector<WipperSnapper_I2C_Driver_Out *>
148+
_drivers_out; ///< List of i2c output drivers
138149
// Sensor driver objects
139150
WipperSnapper_I2C_Driver_AHTX0 *_ahtx0 = nullptr;
140151
WipperSnapper_I2C_Driver_DPS310 *_dps310 = nullptr;
@@ -190,6 +201,10 @@ class WipperSnapper_Component_I2C {
190201
WipperSnapper_I2C_Driver_VL6180X *_vl6180x = nullptr;
191202
WipperSnapper_I2C_Driver_MAX17048 *_max17048 = nullptr;
192203
WipperSnapper_I2C_Driver_ADT7410 *_adt7410 = nullptr;
204+
WipperSnapper_I2C_Driver_Out_QuadAlphaNum *_quadAlphaNum = nullptr;
205+
WipperSnapper_I2C_Driver_Out_CharLcd *_charLcd = nullptr;
206+
WipperSnapper_I2C_Driver_Out_7Seg *_sevenSeg = nullptr;
207+
WipperSnapper_I2C_Driver_Out_Ssd1306 *_ssd1306 = nullptr;
193208
};
194209
extern Wippersnapper WS;
195210

0 commit comments

Comments
 (0)