Skip to content

Commit cc3a3c5

Browse files
committed
Add write commands for quadalphanum
1 parent 5265e25 commit cc3a3c5

File tree

5 files changed

+194
-12
lines changed

5 files changed

+194
-12
lines changed

src/Wippersnapper.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,21 @@ 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+
WS._i2cPort0->Handle_I2cDeviceOutputWrite(&msgDeviceWrite);
888+
WS_DEBUG_PRINTLN("[app] I2C Device Output Write Done");
874889
} else {
875890
WS_DEBUG_PRINTLN("ERROR: Undefined I2C message tag");
876891
return false; // fail out, we didn't encode anything to publish

src/components/i2c/WipperSnapper_I2C.cpp

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -839,8 +839,11 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
839839
drivers.push_back(_adt7410);
840840
WS_DEBUG_PRINTLN("ADT7410 Initialized Successfully!");
841841
} else if (strcmp("quadalphanum", msgDeviceInitReq->i2c_device_name) == 0) {
842-
_quadAlphaNum = new WipperSnapper_I2C_Driver_Out_QuadAlphaNum(this->_i2c, i2cAddress);
843-
// _quadAlphaNum->ConfigureI2CBackpack(msgDeviceInitReq->i2c_output_add.config.led_backpack_config);
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);
844847
if (!_quadAlphaNum->begin()) {
845848
WS_DEBUG_PRINTLN("ERROR: Failed to initialize Quad Alphanum. Display!");
846849
_busStatusResponse =
@@ -1087,6 +1090,48 @@ void WipperSnapper_Component_I2C::displayDeviceEventMessage(
10871090
}
10881091
}
10891092

1093+
/*******************************************************************************/
1094+
/*!
1095+
@brief Handles an I2CDeviceOutputWrite message.
1096+
@param msgDeviceWrite
1097+
A decoded I2CDeviceOutputWrite message.
1098+
@returns True if the message was handled successfully, false otherwise.
1099+
*/
1100+
/*******************************************************************************/
1101+
bool WipperSnapper_Component_I2C::Handle_I2cDeviceOutputWrite(
1102+
wippersnapper_i2c_v1_I2CDeviceOutputWrite *msgDeviceWrite) {
1103+
1104+
// Create a ptr to the base driver out
1105+
WipperSnapper_I2C_Driver_Out *driver_out = nullptr;
1106+
// Find the matching driver by address in the _drivers_out vector
1107+
WS_DEBUG_PRINT("Searching for i2c output driver with address: ");
1108+
WS_DEBUG_PRINT(msgDeviceWrite->i2c_device_address);
1109+
for (size_t i = 0; i < _drivers_out.size(); i++) {
1110+
if (_drivers_out[i]->getI2CAddress() ==
1111+
msgDeviceWrite->i2c_device_address) {
1112+
driver_out = _drivers_out[i];
1113+
break;
1114+
}
1115+
}
1116+
if (driver_out == nullptr) {
1117+
WS_DEBUG_PRINTLN("ERROR: Driver not found within drivers_out!");
1118+
return false;
1119+
}
1120+
1121+
// Call the output_msg
1122+
if (msgDeviceWrite->which_output_msg ==
1123+
wippersnapper_i2c_v1_I2CDeviceOutputWrite_write_led_backpack_tag) {
1124+
driver_out->WriteLedBackpack(&msgDeviceWrite->output_msg.write_led_backpack);
1125+
} else if (msgDeviceWrite->which_output_msg ==
1126+
wippersnapper_i2c_v1_I2CDeviceOutputWrite_write_char_lcd_tag) {
1127+
// TODO: Write to the char LCD
1128+
} else {
1129+
WS_DEBUG_PRINTLN("ERROR: Unknown output message type!");
1130+
return false;
1131+
}
1132+
return true;
1133+
}
1134+
10901135
/*******************************************************************************/
10911136
/*!
10921137
@brief Queries all I2C device drivers for new values. Fills and sends an

src/components/i2c/WipperSnapper_I2C.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
#include <Wire.h>
2121

2222
#include "drivers/WipperSnapper_I2C_Driver.h"
23-
#include "drivers/WipperSnapper_I2C_Driver_Out.h"
24-
#include "drivers/WipperSnapper_I2C_Driver_Out_QuadAlphaNum.h"
2523
#include "drivers/WipperSnapper_I2C_Driver_ADT7410.h"
2624
#include "drivers/WipperSnapper_I2C_Driver_AHTX0.h"
2725
#include "drivers/WipperSnapper_I2C_Driver_BH1750.h"
@@ -52,6 +50,8 @@
5250
#include "drivers/WipperSnapper_I2C_Driver_MPRLS.h"
5351
#include "drivers/WipperSnapper_I2C_Driver_MS8607.h"
5452
#include "drivers/WipperSnapper_I2C_Driver_NAU7802.h"
53+
#include "drivers/WipperSnapper_I2C_Driver_Out.h"
54+
#include "drivers/WipperSnapper_I2C_Driver_Out_QuadAlphaNum.h"
5555
#include "drivers/WipperSnapper_I2C_Driver_PCT2075.h"
5656
#include "drivers/WipperSnapper_I2C_Driver_PM25.h"
5757
#include "drivers/WipperSnapper_I2C_Driver_SCD30.h"
@@ -106,6 +106,9 @@ class WipperSnapper_Component_I2C {
106106

107107
void update();
108108

109+
bool Handle_I2cDeviceOutputWrite(
110+
wippersnapper_i2c_v1_I2CDeviceOutputWrite *msgDeviceWrite);
111+
109112
void sensorEventRead(
110113
std::vector<WipperSnapper_I2C_Driver *>::iterator &iter,
111114
unsigned long curTime,
@@ -136,8 +139,10 @@ class WipperSnapper_Component_I2C {
136139
int32_t _portNum;
137140
TwoWire *_i2c = nullptr;
138141
wippersnapper_i2c_v1_BusResponse _busStatusResponse;
139-
std::vector<WipperSnapper_I2C_Driver *> drivers; ///< List of i2c sensor drivers
140-
std::vector<WipperSnapper_I2C_Driver_Out *> _drivers_out; ///< List of i2c output drivers
142+
std::vector<WipperSnapper_I2C_Driver *>
143+
drivers; ///< List of i2c sensor drivers
144+
std::vector<WipperSnapper_I2C_Driver_Out *>
145+
_drivers_out; ///< List of i2c output drivers
141146
// Sensor driver objects
142147
WipperSnapper_I2C_Driver_AHTX0 *_ahtx0 = nullptr;
143148
WipperSnapper_I2C_Driver_DPS310 *_dps310 = nullptr;

src/components/i2c/drivers/WipperSnapper_I2C_Driver_Out.h

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class WipperSnapper_I2C_Driver_Out : public WipperSnapper_I2C_Driver {
3232
@param sensorAddress
3333
The I2C sensor's unique address.
3434
*/
35-
WipperSnapper_I2C_Driver_Out(TwoWire *i2c, uint16_t sensorAddress):WipperSnapper_I2C_Driver(i2c, sensorAddress) {
35+
WipperSnapper_I2C_Driver_Out(TwoWire *i2c, uint16_t sensorAddress)
36+
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
3637
// No-op constructor
3738
}
3839

@@ -43,11 +44,11 @@ class WipperSnapper_I2C_Driver_Out : public WipperSnapper_I2C_Driver {
4344
// No-op destructor
4445
}
4546

46-
/*!
47-
@brief Writes a message to an i2c output device.
48-
@param message
49-
The message to be displayed.
50-
*/
47+
/*!
48+
@brief Writes a message to an i2c output device.
49+
@param message
50+
The message to be displayed.
51+
*/
5152
virtual void WriteMessage(const char *message) {
5253
// noop
5354
}
@@ -92,6 +93,32 @@ class WipperSnapper_I2C_Driver_Out : public WipperSnapper_I2C_Driver {
9293
// noop
9394
}
9495

96+
bool WriteLedBackpack(wippersnapper_i2c_v1_LedBackpackWrite *msg_write) {
97+
// Check if we should adjust brightness
98+
if (msg_write->adjust_brightness)
99+
SetLedBackpackBrightness((uint8_t)msg_write->brightness);
100+
101+
// Write the message to a LED backpack
102+
switch (msg_write->which_message) {
103+
case wippersnapper_i2c_v1_LedBackpackWrite_text_tag:
104+
WS_DEBUG_PRINTLN("[i2c] Writing text to LED backpack...");
105+
WriteMessage(msg_write->message.text);
106+
break;
107+
case wippersnapper_i2c_v1_LedBackpackWrite_number_int_tag:
108+
WS_DEBUG_PRINTLN("[i2c] Writing int to LED backpack...");
109+
WriteValue(msg_write->message.number_int);
110+
break;
111+
case wippersnapper_i2c_v1_LedBackpackWrite_number_float_tag:
112+
WS_DEBUG_PRINTLN("[i2c] Writing float to LED backpack...");
113+
WriteValue(msg_write->message.number_float);
114+
break;
115+
default:
116+
WS_DEBUG_PRINTLN("[i2c] ERROR: Unable to determine message type!");
117+
return false;
118+
break;
119+
}
120+
return true;
121+
}
95122
};
96123

97124
#endif // WIPPERSNAPPER_I2C_DRIVER_OUT_H

src/components/i2c/drivers/WipperSnapper_I2C_Driver_Out_QuadAlphaNum.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,97 @@ class WipperSnapper_I2C_Driver_Out_QuadAlphaNum : public WipperSnapper_I2C_Drive
8787
_brightness = brightness;
8888
}
8989

90+
/*!
91+
@brief Sets the brightness of the LED backpack.
92+
@param b
93+
The brightness value, from 0 (off) to 15 (full brightness).
94+
*/
95+
void SetLedBackpackBrightness(uint8_t b) {
96+
if (_alpha4 == nullptr) {
97+
return;
98+
}
99+
_alpha4->setBrightness(b);
100+
}
101+
102+
/*!
103+
@brief Writes the first four characters of a message to the quad
104+
alphanumeric display.
105+
@param message
106+
The message to be displayed.
107+
*/
108+
void WriteMessage(const char *message) {
109+
if (_alpha4 == nullptr || message == nullptr) {
110+
return;
111+
}
112+
// Clear before writing
113+
_alpha4->clear();
114+
115+
// Calculate the number of characters to display
116+
size_t len_display = min(strlen(message), (size_t)LED_MAX_CHARS);
117+
118+
// Set the starting position based on alignment
119+
int pos_start;
120+
if (_alignment == LED_BACKPACK_ALIGNMENT_LEFT) {
121+
pos_start = 0; // start at the leftmost position of the display
122+
} else {
123+
// Exclude decimal points from the character count because those get
124+
// displayed on a "special" segment of the LED display
125+
int seg_chars = 0;
126+
for (size_t i = 0; i < len_display; i++) {
127+
if (message[i] != '.') {
128+
seg_chars++;
129+
}
130+
}
131+
// start at the rightmost position of the display
132+
pos_start = LED_MAX_CHARS - seg_chars;
133+
}
90134

135+
// Write to the display's buffer
136+
int cur_idx = pos_start;
137+
for (size_t i = 0; i < len_display; i++) {
138+
// Save the character because if there's a decimal, we need to skip it in
139+
// the buffer
140+
char ch = message[i];
141+
142+
// Look-ahead for a decimal point to attach to the current character
143+
bool display_dot = false;
144+
if (i + 1 < len_display && message[i + 1] == '.') {
145+
display_dot = true;
146+
i++;
147+
len_display++;
148+
}
149+
150+
// Write the character to the display buffer
151+
_alpha4->writeDigitAscii(cur_idx, ch, display_dot);
152+
cur_idx++;
153+
}
154+
// Issue the buffered data in RAM to the display
155+
_alpha4->writeDisplay();
156+
}
157+
158+
/*!
159+
@brief Writes a floating point value to the quad alphanumeric display.
160+
@param value
161+
The value to be displayed. Only the first four digits are
162+
displayed.
163+
*/
164+
void WriteValue(float value) {
165+
char message[8 + 1];
166+
snprintf(message, sizeof(message), "%.5f", value);
167+
WriteMessage(message);
168+
}
169+
170+
/*!
171+
@brief Writes an integer value to the quad alphanumeric display.
172+
@param value
173+
The value to be displayed. Only the first four digits are
174+
displayed.
175+
*/
176+
void WriteValue(int32_t value) {
177+
char message[LED_MAX_CHARS + 1];
178+
snprintf(message, sizeof(message), "%ld", value);
179+
WriteMessage(message);
180+
}
91181

92182
protected:
93183
Adafruit_AlphaNum4 *_alpha4 = nullptr; ///< ptr to a 4-digit alphanumeric display object

0 commit comments

Comments
 (0)