From ea15951f365238a9271c96a5bc6dda2bc6ad3365 Mon Sep 17 00:00:00 2001 From: Rik Veenboer Date: Thu, 16 Jul 2015 15:55:07 +0100 Subject: [PATCH] Start implementing complete protocol buffer protocol --- proto/tm1638.proto | 112 +++++++++++++---- src/main.cpp | 297 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 327 insertions(+), 82 deletions(-) diff --git a/proto/tm1638.proto b/proto/tm1638.proto index 766f628..b005dbf 100644 --- a/proto/tm1638.proto +++ b/proto/tm1638.proto @@ -17,49 +17,117 @@ enum Module { message Command { enum Type { - SERVER = 1; - PING = 2; - CONSTRUCT = 3; - SET_LED = 4; + PING = 1; + CONSTRUCT = 2; + CLEAR_DISPLAY = 3; + CLEAR_DISPLAY_DIGIT = 4; + SET_DISPLAY = 5; + SET_DISPLAY_DIGIT = 6; + SET_DISPLAY_TO_BIN_NUMBER = 7; + SET_DISPLAY_TO_DEC_NUMBER = 8; + SET_DISPLAY_TO_HEX_NUMBER = 9; + SET_DISPLAY_TO_ERROR = 10; + SET_DISPLAY_TO_STRING = 11; + SET_LED = 12; + SET_LEDS = 13; + SETUP_DISPLAY = 14; } required Type type = 1; - optional Server server = 2; - optional Ping ping = 3; - optional Construct construct = 4; - optional SetLed setLed = 5; -} - -message Server { - optional string host = 1; - required int32 port = 2; + optional Ping ping = 2; + optional Construct construct = 3; + optional ClearDisplayDigit clearDisplayDigit = 4; + optional SetDisplay setDisplay = 5; + optional SetDisplayDigit setDisplayDigit = 6; + optional SetDisplayToNumber setDisplayToNumber = 7; + optional SetDisplayToString setDisplayToString = 8; + optional SetLED setLED = 9; + optional SetLEDs setLEDs = 10; + optional SetupDisplay setupDisplay = 11; } message Ping { required int32 id = 1; } -message Echo { - required int32 id = 1; - optional string message = 2 [(nanopb).max_size = 40]; -} - message Construct { required int32 dataPin = 1; required int32 clockPin = 2; optional int32 strobePin = 3; - optional bool activateDisplay = 4 [default = true]; - optional int32 intensity = 5 [default = 7]; optional Module module = 6 [default = TM1638]; optional int32 id = 7 [default = 0]; } -message SetLed { +message ClearDisplayDigit { + required int32 pos = 1; + required bool dot = 2; +} + +message SetDisplay { + required bytes values = 1; +} + +message SetDisplayDigit { + required int32 digit = 1; + required int32 pos = 2; + required bool dot = 3; + required bool has_font = 4; + optional bytes font = 5; +} + +message SetDisplayToNumber { + required sint32 number = 1; + required int32 dots = 2; + required bool has_font = 3; + optional bytes font = 4; + optional bool leadingZeros = 5 [default = false]; + optional bool sign = 6 [default = true]; +} + +message SetDisplayToString { + required string string = 1 [(nanopb).max_size = 40]; + required int32 dots = 2; + required int32 pos = 3; + required bool has_font = 4; + optional bytes font = 5; +} + +message SetLED { required Color color = 1; required int32 pos = 2; optional int32 id = 3 [default = 1]; } +message SetLEDs { + required int32 led = 1; +} + +message SetupDisplay { + optional bool active = 1 [default = true]; + optional int32 intensity = 2 [default = 7]; +} + +message Message { + enum Type { + PONG = 1; + BUTTONS = 2; + TEXT = 3; + } + + required Type type = 1; + optional Pong pong = 2; + optional Buttons buttons = 3; + optional Text text = 4; +} + +message Pong { + required int32 id = 1; +} + message Buttons { - required byte buttons; + required int32 buttons = 1; +} + +message Text { + required string text = 1 [(nanopb).max_size = 40]; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 9d4fac6..7d4dd34 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,43 +15,113 @@ TM1640 *tm1640; TM1638 *tm1638[6]; TM16XX *module; -int t = 123; -int id = 0; +tm1638_Construct construct; +int pong = 0; +String text; byte pressed = 0; -_tm1638_Construct construct; -void setup() { - Serial.begin(9600); - tm1638[0] = new TM1638(8, 9, 7); - tm1638[0]->setupDisplay(true, 1); - tm1638[0]->setLED(TM1638_COLOR_RED, 2); - tm1638[0]->setDisplayToDecNumber(111, 0); -} +byte values[256]; +uint8_t font[256]; -void sendButtons(int id, byte buttons) { - /*_tm1638_Buttons x = {id, buttons}; +void sendMessage(_tm1638_Message message) { uint8_t out_buffer[256]; pb_ostream_t ostream = pb_ostream_from_buffer(out_buffer, sizeof(out_buffer)); - if (pb_encode_delimited(&ostream, tm1638_Buttons_fields, &x)) { - Serial.write(out_buffer, ostream.bytes_written); - }*/ -} - -void sendEcho(int id, char message[]) { - _tm1638_Echo echo = {id, true}; - strncpy(echo.message, message, 40); - uint8_t out_buffer[256]; - pb_ostream_t ostream = pb_ostream_from_buffer(out_buffer, sizeof(out_buffer)); - if (pb_encode_delimited(&ostream, tm1638_Echo_fields, &echo)) { + if (pb_encode_delimited(&ostream, tm1638_Message_fields, &message)) { Serial.write(out_buffer, ostream.bytes_written); + Serial.flush(); } } +void sendPong(int id) { + tm1638_Pong pong = {id}; + tm1638_Message message = tm1638_Message_init_default; + message.type = tm1638_Message_Type_PONG; + message.pong = pong; + message.has_pong = true; + sendMessage(message); +} + +void sendText(char buffer[]) { + tm1638_Text text = tm1638_Text_init_default; + tm1638_Message message = tm1638_Message_init_default; + message.type = tm1638_Message_Type_TEXT; + strcpy(message.text.text, buffer); + message.has_text = true; + sendMessage(message); +} + +void sendText(String string) { + char buffer[40]; + string.toCharArray(buffer, sizeof(buffer)); + sendText(buffer); +} + +void sendButtons(byte pressed) { + tm1638_Buttons buttons = {pressed}; + tm1638_Message message = tm1638_Message_init_default; + message.type = tm1638_Message_Type_BUTTONS; + message.buttons = buttons; + message.has_buttons = true; + sendMessage(message); +} + +byte parseColor(tm1638_Color color) { + switch (color) { + case tm1638_Color_GREEN: + return TM1638_COLOR_GREEN; + case tm1638_Color_RED: + return TM1638_COLOR_RED; + case tm1638_Color_BOTH: + return TM1638_COLOR_GREEN + TM1638_COLOR_RED; + case tm1638_Color_NONE: + break; + } + return TM1638_COLOR_NONE; +} + +bool callbackValues(pb_istream_t *stream, const pb_field_t *field, void **arg) { + memset(values, 0, sizeof(values)); + if (stream->bytes_left > sizeof(values) - 1) { + return false; + } + if (!pb_read(stream, values, stream->bytes_left)) { + return false; + } + return true; +} + +bool callbackFont(pb_istream_t *stream, const pb_field_t *field, void **arg) { + memset(font, 0, sizeof(font)); + if (stream->bytes_left > sizeof(font) - 1) { + return false; + } + if (!pb_read(stream, font, stream->bytes_left)) { + return false; + } + return true; +} + +void setup() { + tm1638[0] = new TM1638(8, 9, 7); + tm1638[0]->setupDisplay(true, 1); + tm1638[0]->setDisplayToError(); + + Serial.begin(19200); + sendText("setup()"); +} + void loop() { + if (pong > 0) { + sendPong(pong); + pong = 0; + } + if (text.length() > 0) { + sendText(text); + text = ""; + } byte buttons = tm1638[0]->getButtons(); if (buttons != pressed) { - //sendButtons(0, buttons); - sendEcho(buttons, "Buttons!"); + sendButtons(buttons); pressed = buttons; } } @@ -70,51 +140,158 @@ void serialEvent() { return; } + // tm1638[0]->setDisplayDigit(command.type / 10, 0, false); + // tm1638[0]->setDisplayDigit(command.type, 1, false); + switch (command.type) { case tm1638_Command_Type_PING: if (command.has_ping) { - _tm1638_Ping ping = command.ping; - sendEcho(ping.id, "Pong"); - tm1638[0]->setDisplayToDecNumber(ping.id, 0); + tm1638_Ping ping = command.ping; + tm1638[0]->setDisplayToDecNumber(ping.id, 0, false); + pong = ping.id; } break; case tm1638_Command_Type_CONSTRUCT: - construct = command.construct; - id = construct.id; - switch (construct.module) { - case tm1638_Module_TM1638: - tm1638[0] = new TM1638((byte) construct.dataPin, (byte) construct.clockPin, (byte) construct.strobePin, construct.activateDisplay, (byte) construct.intensity); - tm1638[0]->setupDisplay(true, 1); - break; - case tm1638_Module_InvertedTM1638: - tm1638[0] = new InvertedTM1638((byte) construct.dataPin, (byte) construct.clockPin, (byte) construct.strobePin, construct.activateDisplay, (byte) construct.intensity); - break; - case tm1638_Module_TM1640: - tm1640 = new TM1640((byte) construct.dataPin, (byte) construct.clockPin, construct.activateDisplay, (byte) construct.intensity); - break; + if (command.has_construct) { + construct = command.construct; + switch (construct.module) { + case tm1638_Module_TM1638: + tm1638[0] = new TM1638((byte) construct.dataPin, (byte) construct.clockPin, (byte) construct.strobePin); + break; + case tm1638_Module_InvertedTM1638: + tm1638[0] = new InvertedTM1638((byte) construct.dataPin, (byte) construct.clockPin, (byte) construct.strobePin); + break; + case tm1638_Module_TM1640: + tm1640 = new TM1640((byte) construct.dataPin, (byte) construct.clockPin); + break; + } + } + break; + case tm1638_Command_Type_CLEAR_DISPLAY: + tm1638[0]->clearDisplay(); + break; + case tm1638_Command_Type_CLEAR_DISPLAY_DIGIT: + if (command.has_clearDisplayDigit) { + tm1638_ClearDisplayDigit clearDisplayDigit = command.clearDisplayDigit; + tm1638[0]->clearDisplayDigit(clearDisplayDigit.pos, clearDisplayDigit.dot); + } + break; + case tm1638_Command_Type_SET_DISPLAY: + if (command.has_setDisplay) { + tm1638_SetDisplay setDisplay = command.setDisplay; + setDisplay.values.funcs.decode = &callbackValues; + if (pb_decode(&istream, tm1638_SetDisplay_fields, &setDisplay)) { + tm1638[0]->setDisplay(values); + } + } + break; + case tm1638_Command_Type_SET_DISPLAY_DIGIT: + if (command.has_setDisplayDigit) { + tm1638_SetDisplayDigit setDisplayDigit = command.setDisplayDigit; + byte digit = setDisplayDigit.digit; + byte pos = setDisplayDigit.pos; + bool dot = setDisplayDigit.dot; + bool has_font = setDisplayDigit.has_font; + if (has_font) { + setDisplayDigit.font.funcs.decode = &callbackFont; + if (pb_decode(&istream, tm1638_SetDisplayDigit_fields, &setDisplayDigit)) { + tm1638[0]->setDisplayDigit(digit, pos, dot, font); + } + } else { + tm1638[0]->setDisplayDigit(digit, pos, dot); + } + } + break; + case tm1638_Command_Type_SET_DISPLAY_TO_BIN_NUMBER: + if (command.has_setDisplayToNumber) { + tm1638_SetDisplayToNumber setDisplayToNumber = command.setDisplayToNumber; + byte number = setDisplayToNumber.number; + byte dots = setDisplayToNumber.dots; + bool has_font = setDisplayToNumber.has_font; + if (has_font) { + setDisplayToNumber.font.funcs.decode = &callbackFont; + if (pb_decode(&istream, tm1638_SetDisplayToNumber_fields, &setDisplayToNumber)) { + tm1638[0]->setDisplayToBinNumber(number, dots, font); + } + } else { + tm1638[0]->setDisplayToBinNumber(number, dots); + } + } + break; + case tm1638_Command_Type_SET_DISPLAY_TO_DEC_NUMBER: + if (command.has_setDisplayToNumber) { + tm1638_SetDisplayToNumber setDisplayToNumber = command.setDisplayToNumber; + signed int number = setDisplayToNumber.number; + byte dots = setDisplayToNumber.dots; + bool leadingZeros = setDisplayToNumber.leadingZeros; + bool has_font = setDisplayToNumber.has_font; + if (has_font) { + setDisplayToNumber.font.funcs.decode = &callbackFont; + if (pb_decode(&istream, tm1638_SetDisplayToNumber_fields, &setDisplayToNumber)) { + if (number < 0) { + tm1638[0]->setDisplayToSignedDecNumber(number, dots, leadingZeros, font); + } else { + tm1638[0]->setDisplayToDecNumber(number, dots, leadingZeros, font); + } + } + } else { + if (number < 0) { + tm1638[0]->setDisplayToSignedDecNumber(number, dots, leadingZeros); + } else { + tm1638[0]->setDisplayToDecNumber(number, dots, leadingZeros); + } + } + } + break; + case tm1638_Command_Type_SET_DISPLAY_TO_HEX_NUMBER: + if (command.has_setDisplayToNumber) { + tm1638_SetDisplayToNumber setDisplayToNumber = command.setDisplayToNumber; + signed int number = setDisplayToNumber.number; + byte dots = setDisplayToNumber.dots; + bool leadingZeros = setDisplayToNumber.leadingZeros; + tm1638[0]->setDisplayToHexNumber(number, dots, leadingZeros); + } + break; + case tm1638_Command_Type_SET_DISPLAY_TO_ERROR: + tm1638[0]->setDisplayToError(); + break; + case tm1638_Command_Type_SET_DISPLAY_TO_STRING: + if(command.has_setDisplayToString) { + tm1638_SetDisplayToString setDisplayToString = command.setDisplayToString; + pb_decode(&istream, tm1638_SetDisplayToString_fields, &setDisplayToString); + byte dots = setDisplayToString.dots; + byte pos = setDisplayToString.dots; + tm1638[0]->setDisplayToString(setDisplayToString.string, dots, pos); + bool has_font = setDisplayToString.has_font; + if (has_font) { + setDisplayToString.font.funcs.decode = &callbackFont; + if (pb_decode(&istream, tm1638_SetDisplayToString_fields, &setDisplayToString)) { + tm1638[0]->setDisplayToString(setDisplayToString.string, dots, pos, font); + } + } else { + tm1638[0]->setDisplayToString(setDisplayToString.string, dots, pos); + } } break; case tm1638_Command_Type_SET_LED: - if (command.has_setLed) { - _tm1638_SetLed setLed = command.setLed; - byte color; - switch (setLed.color) { - case tm1638_Color_GREEN: - color = TM1638_COLOR_GREEN; - break; - case tm1638_Color_RED: - color = TM1638_COLOR_RED; - break; - case tm1638_Color_BOTH: - color = TM1638_COLOR_GREEN + TM1638_COLOR_RED; - break; - case tm1638_Color_NONE: - color = TM1638_COLOR_NONE; - break; - } - tm1638[0]->setLED(color, setLed.pos); + if (command.has_setLED) { + tm1638_SetLED setLED = command.setLED; + byte color = parseColor(setLED.color); + tm1638[0]->setLED(color, setLED.pos); } - break; + break; + case tm1638_Command_Type_SET_LEDS: + if (command.has_setLEDs) { + tm1638_SetLEDs setLEDs = command.setLEDs; + tm1638[0]->setLEDs(setLEDs.led); + } + break; + case tm1638_Command_Type_SETUP_DISPLAY: + if (command.has_setupDisplay) { + tm1638_SetupDisplay setupDisplay = command.setupDisplay; + tm1638[0]->setupDisplay(setupDisplay.active, setupDisplay.intensity); + } + break; } } } \ No newline at end of file