From 1eb01e944835e4bc402717c52d5f40d8ba6acfbb Mon Sep 17 00:00:00 2001 From: Tibo Ulens Date: Tue, 15 Feb 2022 19:37:42 +0100 Subject: [PATCH] add Counter/Timer model 1772 module --- .../doc/index.md | 20 +++++ .../lcd_control.cpp | 90 +++++++++++++++++++ .../lcd_control.h | 51 +++++++++++ .../puzzle_counter_timer_model_1772.ino | 36 ++++++++ 4 files changed, 197 insertions(+) create mode 100644 src/modules/puzzle_counter_timer_model_1772/doc/index.md create mode 100644 src/modules/puzzle_counter_timer_model_1772/lcd_control.cpp create mode 100644 src/modules/puzzle_counter_timer_model_1772/lcd_control.h create mode 100644 src/modules/puzzle_counter_timer_model_1772/puzzle_counter_timer_model_1772.ino diff --git a/src/modules/puzzle_counter_timer_model_1772/doc/index.md b/src/modules/puzzle_counter_timer_model_1772/doc/index.md new file mode 100644 index 0000000..9ec136a --- /dev/null +++ b/src/modules/puzzle_counter_timer_model_1772/doc/index.md @@ -0,0 +1,20 @@ +# counter_timer_model_1772 + +Schrijf de handleiding voor je module hier. Kijk gerust naar de handleiding +voor de "Doolhof"-module (`src/modules/puzzle_maze/doc/index.md`) + + +Hieronder wat voorbeelden van markup die je kan gebruiken. Daarnaast kan je ook LaTeX +gebruiken (zie bijvoorbeeld de "Doolhof"-module) + +Use drawings! Create the docs/images/your_module directory, put your image there and include them like this: + +![](./your_module/filename.png) + +Use tables! Write them like this: + +| Symbol | Action to take | +|--------------------------------|----------------| +| ![](./your_module/symbol1.png) | Do nothing | +| ![](./your_module/symbol2.png) | Press the red button | +| ![](./your_module/symbol3.png) | Press the yellow button | diff --git a/src/modules/puzzle_counter_timer_model_1772/lcd_control.cpp b/src/modules/puzzle_counter_timer_model_1772/lcd_control.cpp new file mode 100644 index 0000000..01526c4 --- /dev/null +++ b/src/modules/puzzle_counter_timer_model_1772/lcd_control.cpp @@ -0,0 +1,90 @@ +// +// lcd_control.c +// + +#include "lcd_control.h" + +#include + +#define LED_PIN_DIN 2 // Data In (MOSI) +#define LED_PIN_CS 3 // Chip Select +#define LED_PIN_CLK 5 // Clock + +LedControl lcd = LedControl(LED_PIN_DIN, LED_PIN_CLK, LED_PIN_CS, 1); + +byte LCD_STATE[6] = {B00000000, B00000000, B00000000, B00000000, B00000000, B00000000}; +uint8_t segment_map[7] = {0, 1, 3, 4, 5, 6, 7}; +byte character_map[10] = {B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000,B01111111,B01111011}; + +void lcd_draw() { + uint8_t digit_state; + for (int i=0; i<6; i++) { + digit_state = LCD_STATE[i]; + + for (int j=6; j>=0; j--) { + // Map j to missing-solder-pad adjusted value + // i + 1 because only digits 1-6 of possible 0-7 are used + // continually read the last digit of digit_state and shift it over by one + lcd.setLed(0, segment_map[j], i + 1, digit_state % 2); + digit_state = digit_state >> 1; + } + } +} + +void lcd_set_digit(uint8_t digit, uint8_t segments) { + LCD_STATE[digit] = segments; + + lcd_draw(); +} + +void lcd_set_display(uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6) { + LCD_STATE[0] = d1; + LCD_STATE[1] = d2; + LCD_STATE[2] = d3; + LCD_STATE[3] = d4; + LCD_STATE[4] = d5; + LCD_STATE[5] = d6; + + lcd_draw(); +} + +uint8_t lcd_print_number(int32_t num) { + if (num < -99999 || num > 999999) { + return 1; + } + + // Normally leading zeroes will be ignored, + // but if the number is exactly zero it should be printed + if (num == 0) { + lcd_set_digit(5, B01111110); + return 0; + } + + bool negative = false; + if (num < 0) { + negative = true; + + // Change from negative to positive in two's complement + // Faster than doing num * -1 + num = num ^ 0xFFFFFFFF; + num = num + 1; + } + + uint8_t index; + for (int8_t i=5; i>=0; i--) { + // Continually read the last decimal and then shift + // num over by one decimal + LCD_STATE[i] = character_map[num % 10]; + num /= 10; + + index = i; + if (num == 0) break; + } + + // Draw a minus symbol if the number was negative + if (negative) LCD_STATE[index - 1] = B00000001; + + lcd_draw(); + + return 0; +} diff --git a/src/modules/puzzle_counter_timer_model_1772/lcd_control.h b/src/modules/puzzle_counter_timer_model_1772/lcd_control.h new file mode 100644 index 0000000..769d412 --- /dev/null +++ b/src/modules/puzzle_counter_timer_model_1772/lcd_control.h @@ -0,0 +1,51 @@ +// +// lcd_control.h +// + +#include + +#ifndef LCD_CONTROL_H +#define LCD_CONTROL_H + +// Main LCD controller +extern LedControl lcd; + +// What will be printed on the next call of lcd_draw() +// The digits of each binary number represent the following segments (first digit unused) +// B0 x x x x x x x +// A B C D E F G +// With each segment being positioned as follows: +// A +// F B +// G +// E C +// D +extern byte LCD_STATE[6]; + +// Maps segment indices (A=0, B=1, ...) to their 'correct' hardware indices +// (pin 2 got its solder pad torn off :<) +extern uint8_t segment_map[7]; + +// Which segments to light up for each number from 0 to 9 +// Indices correspond to their numbers +extern byte character_map[10]; + +// Writes the current value of LCD_STATE to the lcd +void lcd_draw(); + +// Set a single digit on the LCD +void lcd_set_digit(uint8_t digit, uint8_t segments); + +// Set every digit on the LCD +void lcd_set_display(uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6); + +// Print a number to the LCD +// +// num should be in [-99999; 999999] (the display only has 6 digits) +// +// Exit codes: +// - 0: success +// - 1: num was out of bounds +uint8_t lcd_print_number(int32_t num); + +#endif diff --git a/src/modules/puzzle_counter_timer_model_1772/puzzle_counter_timer_model_1772.ino b/src/modules/puzzle_counter_timer_model_1772/puzzle_counter_timer_model_1772.ino new file mode 100644 index 0000000..c423766 --- /dev/null +++ b/src/modules/puzzle_counter_timer_model_1772/puzzle_counter_timer_model_1772.ino @@ -0,0 +1,36 @@ +// (c) 2022, Tibo Ulens +// See the LICENSE file for conditions for copying + +#include +#include + +#include "lcd_control.h" + +#define OBUS_PUZZLE_ID 2 + +void setup() { + Serial.begin(115200); + + lcd.shutdown(0, false); + lcd.setIntensity(0, 15); // 0: dimmest, 15: brightest + lcd.clearDisplay(0); + + lcd_print_number(987654); + + // Puzzle: a module that must be solved + obus_module::setup(OBUS_TYPE_PUZZLE, OBUS_PUZZLE_ID); +} + +obus_can::message message; + +void loop() { + bool is_message_valid = obus_module::loopPuzzle(&message, callback_game_start, callback_game_stop); +} + +void callback_game_start(uint8_t message) { + +} + +void callback_game_stop() { + +}