add Counter/Timer model 1772 module

This commit is contained in:
Tibo Ulens 2022-02-15 19:37:42 +01:00
parent 60dbfdfea4
commit 1eb01e9448
No known key found for this signature in database
GPG key ID: A0907492D3E5089D
4 changed files with 197 additions and 0 deletions

View file

@ -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 |

View file

@ -0,0 +1,90 @@
//
// lcd_control.c
//
#include "lcd_control.h"
#include <LedControl.h>
#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;
}

View file

@ -0,0 +1,51 @@
//
// lcd_control.h
//
#include <LedControl.h>
#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

View file

@ -0,0 +1,36 @@
// (c) 2022, Tibo Ulens
// See the LICENSE file for conditions for copying
#include <obus_module.h>
#include <LedControl.h>
#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() {
}