//code by MustangGX
#include <Arduino.h>
#include <U8g2lib.h>
#include <MUIU8g2.h>
#include <Versatile_RotaryEncoder.h>
#include <Wire.h> // LCD has a ICC connector
// Set IR sensors
#define sensor1 0 // A0
#define sensor2 1 // A1
// Set lights for the sensors
#define light1 A2 // A2
#define light2 A3 // A3
// Set here your encoder reading pins
#define clk 2
#define dt 3
#define sw 4
// LEDs setup
#define FlashingInterval 2000 // 2 Seconds
#define FadingInterval 2
#define nLEDsperTower 2
int PINList[nLEDsperTower] = {5, 6}; // PWN pin used
// Photoresistor setup
const int photo_sensor_pin = A4; // sensor pin
int photo_sensor; // sensor reading
const int photo_threshold = 500; // threshold to turn LED on
// Create encoder object
Versatile_RotaryEncoder versatile_encoder(clk, dt, sw);
// Screen definition
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
MUIU8G2 mui;
/*
user defined variables
*/
float traveldistance=172; // in cm.
uint8_t scale=87; // HO:87
/*
global variables
*/
unsigned long startmillis=0;
unsigned long endmillis=0;
int x_SteamLok=-76; // initial x position for the locomotive animation
int8_t speed=0;
uint8_t MenuTitle=0; // 0:Märklin, 1:Light Show, 2:Speed Measurment, 3:Märklin Digital Logo
//uint8_t MenuSelection=1;
enum COUNTSTATES
{
ST_OFF,
ST_COUNTING,
ST_TIMEDOUT,
ST_DONE,
};
COUNTSTATES countState=ST_OFF;
/*enum MENU_TITLES
{
"Märklin",
"High Voltage Tower Lights",
"Speed Measurment",
"Märklin Digital Logo",
}
MENU_TITLES Menu_Title="Märklin";
*/
// global variables for menu redraw and input event handling
bool is_redraw = true;
uint8_t rotate_event = 0; // 0 = not turning, 1 = CW, 2 = CCW
bool press_event = false; // 0 = not pushed, 1 = pushed
bool long_press_event = false; // 0 = not pushed, 1 = pushed
// global variables for functions
bool is_speed_measured = false;
// Images
// image2cpp (convert images into C code): https://javl.github.io/image2cpp/
// 'marklin', 128x16px
const unsigned char bitmap_marklin [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3d, 0x38, 0xe0, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1e, 0x38, 0xe0, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0x38, 0xe0, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xdc, 0x73, 0xf0, 0xf1, 0x3e, 0xef, 0xdc, 0x39, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xfc, 0xf7, 0x3f, 0xef, 0xdc, 0x7f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x1d, 0xf7, 0xff, 0xe7, 0xdc, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0xe7, 0x01, 0xf7, 0xf9, 0xe3, 0xdc, 0xf3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0xe7, 0xf9, 0xf7, 0xf8, 0xe3, 0xdc, 0xe3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0xe7, 0x3d, 0xf7, 0xf8, 0xe3, 0xdc, 0xe3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0xe7, 0x1d, 0xf7, 0xf8, 0xe7, 0xdc, 0xe3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0xe7, 0xbd, 0xf7, 0x38, 0xe7, 0xdc, 0xe3, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0xe7, 0xfd, 0xf7, 0x38, 0xef, 0xdc, 0xe1, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1c, 0xe7, 0x30, 0x67, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'marklin digital', 128x48px
const unsigned char bitmap_marklin_digital [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0xfc, 0x03, 0xe0, 0x0f, 0x00, 0xfe, 0x00, 0xfe, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0xff, 0x01, 0xe0, 0x0f, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf0, 0x8f, 0xff, 0x00, 0xe0, 0x07, 0x00, 0xfe, 0x80, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf8, 0xc7, 0x3f, 0x00, 0xe0, 0x07, 0x00, 0xfe, 0xc0, 0x3f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfc, 0xe3, 0x1f, 0x00, 0xe0, 0x07, 0x00, 0xfe, 0xf0, 0x1f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xf1, 0x0f, 0x00, 0xe0, 0x07, 0x00, 0xfe, 0xf8, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x78, 0xe0, 0x07, 0xc0, 0x7f, 0x00, 0x00, 0xe7, 0x07, 0x00, 0xfe, 0x00, 0x00, 0x80, 0x0f,
0x7f, 0xfe, 0xf1, 0x0f, 0xf8, 0xff, 0x81, 0x9f, 0xe7, 0x87, 0x3f, 0xfe, 0xf8, 0xf1, 0xe7, 0x3f,
0xff, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0x87, 0xff, 0xe7, 0xc7, 0x3f, 0xfe, 0xf8, 0xf1, 0xff, 0x7f,
0xff, 0xff, 0xff, 0x3f, 0xfe, 0xfb, 0x87, 0xff, 0xe7, 0xc7, 0x1f, 0xfe, 0xf8, 0xf1, 0xff, 0x7f,
0xff, 0xff, 0xff, 0x3f, 0xfe, 0xe0, 0x8f, 0xff, 0xe7, 0xe7, 0x1f, 0xfe, 0xf8, 0xf1, 0xff, 0x7f,
0xff, 0xff, 0xff, 0x3f, 0xfe, 0xe0, 0x8f, 0xff, 0xe7, 0xff, 0x0f, 0xfe, 0xf8, 0xf1, 0x9f, 0xff,
0xff, 0xf8, 0x87, 0x3f, 0x00, 0xe0, 0x8f, 0xff, 0xe7, 0xff, 0x07, 0xfe, 0xf8, 0xf1, 0x07, 0xff,
0x7f, 0xf0, 0x07, 0x3f, 0xc0, 0xff, 0x8f, 0x7f, 0xe0, 0xff, 0x07, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xf8, 0xff, 0x8f, 0x3f, 0xe0, 0xff, 0x03, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xfc, 0xff, 0x8f, 0x3f, 0xe0, 0xff, 0x03, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xfe, 0xff, 0x8f, 0x1f, 0xe0, 0xff, 0x03, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xfe, 0xe0, 0x8f, 0x1f, 0xe0, 0xff, 0x07, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xfe, 0xe0, 0x8f, 0x1f, 0xe0, 0xff, 0x07, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xfe, 0xe0, 0x8f, 0x1f, 0xe0, 0xe7, 0x0f, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xfe, 0xe0, 0x8f, 0x1f, 0xe0, 0xe7, 0x1f, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xfe, 0xfb, 0x8f, 0x1f, 0xe0, 0xc7, 0x1f, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xfe, 0xff, 0x8f, 0x1f, 0xe0, 0xc7, 0x3f, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xfc, 0xff, 0x8f, 0x1f, 0xe0, 0x87, 0x3f, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x7f, 0xf0, 0x07, 0x3f, 0xf8, 0xef, 0x8f, 0x1f, 0xe0, 0x07, 0x7f, 0xfe, 0xf8, 0xf1, 0x07, 0xfe,
0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x03, 0x00, 0x60,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x60,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x60, 0x00, 0x70,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0xc3, 0x8f, 0xfb, 0xfc, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1c, 0xe3, 0x8e, 0x71, 0xcc, 0x31,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1c, 0x63, 0x8c, 0x31, 0xc0, 0x38,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x9c, 0x73, 0x8e, 0x31, 0xf8, 0x38,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x8c, 0x73, 0xce, 0x31, 0xee, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x8c, 0x31, 0xc6, 0x39, 0xc6, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x8e, 0x31, 0xc6, 0x38, 0xe7, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x8e, 0x71, 0xc7, 0x38, 0x67, 0x1c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc7, 0x71, 0xc7, 0x38, 0x6e, 0x1c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00
};
// 'steam_lok', 76x48px
const unsigned char bitmap_steam_lok [] PROGMEM = {
0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xc0, 0x04, 0x00,
0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x6f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x23, 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x80, 0x3b, 0xdf, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x08, 0x00, 0xa0, 0x71, 0xf3, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0xe0, 0xff, 0x4f, 0x00, 0x40, 0x00,
0x00, 0xc0, 0x03, 0x00, 0xfc, 0xff, 0x4f, 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x03, 0x00, 0xf8, 0xff,
0x47, 0x00, 0xfe, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x40, 0x64, 0x00, 0xfe, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x70, 0x64, 0x00, 0xfe, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70, 0x04, 0x00,
0xfe, 0xf8, 0x00, 0x80, 0x03, 0x00, 0x00, 0x70, 0x04, 0x00, 0xfe, 0xf8, 0x01, 0xc0, 0x11, 0x00,
0x00, 0x70, 0x24, 0x00, 0xfe, 0xf8, 0x01, 0x54, 0x0e, 0x00, 0x00, 0x70, 0xf5, 0x7f, 0x00, 0xfd,
0xfb, 0xd7, 0x07, 0x00, 0x00, 0x78, 0x84, 0x7f, 0xfe, 0xfd, 0xfb, 0xd7, 0x07, 0x00, 0x00, 0xff,
0x77, 0x70, 0xfe, 0xfd, 0xfb, 0xd7, 0x07, 0x00, 0x00, 0x01, 0xf0, 0x0f, 0xfe, 0xfd, 0xfb, 0xd7,
0x07, 0x00, 0x00, 0xff, 0xf7, 0x7f, 0xe0, 0xfd, 0xfb, 0xd7, 0x17, 0x00, 0x00, 0xff, 0xf7, 0x7f,
0x1e, 0xfc, 0xfb, 0x57, 0x30, 0x00, 0x00, 0xff, 0xf7, 0x7f, 0xfe, 0x81, 0xfb, 0x97, 0x0b, 0x00,
0x00, 0xff, 0x87, 0x7f, 0x0e, 0x70, 0xf8, 0x9f, 0x0b, 0x00, 0x00, 0xff, 0x07, 0xff, 0x06, 0xe0,
0xf9, 0x9f, 0x0b, 0x00, 0x00, 0xff, 0x07, 0xfe, 0x03, 0x80, 0xf9, 0xbf, 0x6b, 0x00, 0x00, 0xff,
0x07, 0x00, 0x00, 0x00, 0x18, 0xb8, 0x0b, 0x00, 0x80, 0x01, 0xe0, 0xfc, 0x49, 0x1e, 0x38, 0x84,
0x0f, 0x00, 0xc8, 0xaf, 0x0d, 0x79, 0x11, 0x03, 0x00, 0xe0, 0x7f, 0x00, 0x08, 0x6f, 0xd0, 0x75,
0x01, 0x02, 0x03, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x35, 0xbc, 0x03, 0xe0, 0x9f, 0x00,
0x00, 0x80, 0x82, 0x05, 0x44, 0x00, 0x98, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x33, 0x1d, 0x00, 0x80,
0x02, 0xe0, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xc2, 0x27, 0x00, 0x00, 0x80,
0x5c, 0xfe, 0x81, 0x01, 0x80, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00,
0x60, 0x04, 0x40, 0x06, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'chronograph', 43x48px
const unsigned char bitmap_chronograph [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f,
0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xc0, 0x01, 0xfe, 0x03, 0x00, 0x00,
0xe0, 0xc3, 0xff, 0x0f, 0x78, 0x00, 0xe0, 0xff, 0x03, 0x3f, 0x7c, 0x00, 0xe0, 0x3f, 0x00, 0xf0,
0x7f, 0x00, 0xc0, 0x0f, 0x00, 0xc0, 0x7f, 0x00, 0x80, 0x07, 0x00, 0x80, 0x3f, 0x00, 0xc0, 0x01,
0x00, 0x00, 0x1f, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x60, 0x00, 0x00, 0x00, 0x1c, 0x00,
0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x18, 0x00, 0x00, 0x00,
0x60, 0x00, 0x18, 0x00, 0x00, 0x00, 0x60, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x0c, 0x00,
0x00, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x0e, 0x00, 0x40, 0x00, 0xc0, 0x01,
0x0e, 0x00, 0x60, 0x00, 0xc0, 0x01, 0x06, 0x00, 0x30, 0x00, 0x80, 0x01, 0x06, 0x00, 0x3c, 0x00,
0x80, 0x01, 0x06, 0x00, 0x3c, 0x00, 0x80, 0x01, 0x0e, 0x00, 0x3c, 0x00, 0xc0, 0x01, 0x0e, 0x00,
0x1c, 0x00, 0xc0, 0x01, 0x0c, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xc0, 0x00,
0x0c, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, 0x00, 0x00,
0x61, 0x00, 0x38, 0x00, 0x00, 0x00, 0x73, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x70, 0x00,
0x00, 0x00, 0x3e, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xfe, 0x00,
0x80, 0x03, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x3e, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x80,
0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'finish_line', 39x48px
const unsigned char bitmap_finish_line [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0xfe,
0xff, 0x3f, 0x00, 0xc0, 0xff, 0xff, 0x3f, 0x06, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff,
0x3f, 0xfe, 0xff, 0xff, 0x3f, 0x3f, 0xfe, 0xff, 0xff, 0x3b, 0x3f, 0xfe, 0xff, 0x8f, 0x39, 0x3f,
0xfe, 0xff, 0x0d, 0x39, 0x3f, 0xfe, 0xbf, 0x04, 0x39, 0x3f, 0xfe, 0x93, 0x04, 0x39, 0x3f, 0x3e,
0x82, 0x20, 0x39, 0x3f, 0x1e, 0x82, 0x60, 0x39, 0x3f, 0x1e, 0x82, 0xe0, 0x01, 0x3f, 0xde, 0x82,
0xc4, 0x01, 0x3f, 0xde, 0x82, 0x84, 0x01, 0x3f, 0x9e, 0x82, 0x0c, 0x01, 0x3f, 0x1e, 0x82, 0x1c,
0x11, 0x3f, 0x1e, 0x82, 0x1c, 0x39, 0x3f, 0x1e, 0x82, 0x3c, 0x39, 0x3f, 0xde, 0x82, 0x20, 0x39,
0x3f, 0xde, 0x82, 0x20, 0x39, 0x3f, 0xde, 0x92, 0x00, 0x39, 0x3f, 0xde, 0x92, 0x04, 0x39, 0x3f,
0xde, 0x92, 0x84, 0x39, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0xfe,
0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff,
0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0x06, 0x00, 0x00, 0x00, 0x3c, 0x06, 0x00, 0x00,
0x00, 0x38, 0x06, 0x00, 0x00, 0x00, 0x38, 0x06, 0x00, 0x00, 0x00, 0x38, 0x06, 0x00, 0x00, 0x00,
0x38, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38
};
// 'hv tower', 41x48px
const unsigned char bitmap_hv_tower [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x0f,
0x00, 0x00, 0x00, 0xf8, 0x03, 0x3f, 0x00, 0x00, 0x00, 0x9e, 0x01, 0xf3, 0x00, 0x00, 0x80, 0x87,
0x01, 0xc3, 0x03, 0x00, 0xe0, 0x83, 0x01, 0x03, 0x0f, 0x00, 0xf8, 0x80, 0x01, 0x03, 0x3e, 0x00,
0xfc, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x08, 0xc0, 0xc7, 0x07,
0x20, 0x00, 0x08, 0xc0, 0xc7, 0x07, 0x20, 0x00, 0x1c, 0xc0, 0xfc, 0x06, 0x70, 0x00, 0x3e, 0xc0,
0x78, 0x06, 0xf8, 0x00, 0x1c, 0xc0, 0x78, 0x06, 0x70, 0x00, 0x00, 0xc0, 0xfc, 0x06, 0x00, 0x00,
0x00, 0xc0, 0xef, 0x07, 0x00, 0x00, 0x00, 0xc0, 0xc7, 0x07, 0x00, 0x00, 0x00, 0xc0, 0x83, 0x07,
0x00, 0x00, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xfc,
0x00, 0xfe, 0x00, 0x00, 0x00, 0xcf, 0x00, 0xe6, 0x03, 0x00, 0xc0, 0xc3, 0x00, 0x84, 0x07, 0x00,
0xf0, 0xc0, 0x00, 0x0c, 0x1e, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xfc, 0xff, 0xff, 0xff,
0x7f, 0x00, 0x08, 0xf0, 0x87, 0x1f, 0x20, 0x00, 0x08, 0x70, 0x87, 0x1f, 0x20, 0x00, 0x1c, 0x30,
0xce, 0x19, 0x70, 0x00, 0x3e, 0x30, 0xfc, 0x38, 0xf8, 0x00, 0x1c, 0x38, 0x78, 0x30, 0x70, 0x00,
0x00, 0x18, 0x78, 0x30, 0x00, 0x00, 0x00, 0x1c, 0xfc, 0x70, 0x00, 0x00, 0x00, 0x0c, 0xc6, 0x61,
0x00, 0x00, 0x00, 0x0c, 0x83, 0x63, 0x00, 0x00, 0x00, 0x8e, 0x01, 0xc7, 0x00, 0x00, 0x00, 0xc6,
0x01, 0xce, 0x00, 0x00, 0x00, 0xf6, 0x00, 0xdc, 0x01, 0x00, 0x00, 0x7b, 0x00, 0xb8, 0x01, 0x00,
0x00, 0x3f, 0x00, 0xf0, 0x01, 0x00, 0x80, 0x1f, 0x00, 0xe0, 0x03, 0x00, 0x80, 0x0f, 0x00, 0xe0,
0x03, 0x00, 0xf0, 0x7f, 0x00, 0xfc, 0x3f, 0x00, 0xf0, 0x7f, 0x00, 0xfc, 0x3f, 0x00, 0xf0, 0x7f,
0x00, 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'timeout', 48x48px
const unsigned char bitmap_timeout [] PROGMEM = {
0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xe0,
0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x07,
0x00, 0x00, 0x38, 0x00, 0x80, 0x01, 0x00, 0x00, 0x60, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00,
0x60, 0x00, 0xc0, 0x00, 0x80, 0x01, 0x30, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x30, 0x00, 0xc0, 0x00,
0x00, 0x03, 0x18, 0x00, 0xc0, 0x00, 0x00, 0x06, 0x0c, 0x00, 0xc0, 0x00, 0x00, 0x0c, 0x0c, 0x00,
0xc0, 0x00, 0x00, 0x0c, 0x04, 0x00, 0xc0, 0x00, 0x00, 0x08, 0x06, 0x00, 0xc0, 0x00, 0x00, 0x18,
0x06, 0x00, 0xc0, 0x00, 0x00, 0x18, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x10, 0x03, 0x00, 0xe0, 0x00,
0x00, 0x30, 0x03, 0x00, 0xe0, 0x00, 0x00, 0x30, 0x03, 0x00, 0xe0, 0x01, 0x00, 0x30, 0x03, 0x00,
0xe0, 0x01, 0x00, 0x30, 0x03, 0x00, 0xe0, 0x01, 0x00, 0x30, 0x03, 0x00, 0xf0, 0x01, 0x00, 0x30,
0x03, 0x00, 0xf8, 0x00, 0x00, 0x30, 0x03, 0x00, 0x7c, 0x00, 0x00, 0x30, 0x03, 0x00, 0x3e, 0x00,
0x00, 0x30, 0x02, 0x00, 0x0f, 0x00, 0x00, 0x10, 0x06, 0x80, 0x07, 0x00, 0x00, 0x10, 0x06, 0x00,
0x03, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00, 0x70, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xfe, 0x03,
0x0c, 0x00, 0x00, 0x00, 0xff, 0x07, 0x18, 0x00, 0x00, 0x00, 0x8f, 0x07, 0x30, 0x00, 0x00, 0x80,
0x8f, 0x0f, 0x30, 0x00, 0x00, 0x80, 0x8f, 0x0f, 0x60, 0x00, 0x00, 0x80, 0x8f, 0x0f, 0xc0, 0x00,
0x00, 0x80, 0x8f, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xff, 0x0f, 0x00, 0x07, 0x00, 0x80, 0x8f, 0x0f,
0x00, 0x0e, 0x00, 0x00, 0x8f, 0x07, 0x00, 0x38, 0x00, 0x00, 0xfe, 0x03, 0x00, 0xf0, 0x01, 0x00,
0xfc, 0x01, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 544)
const int bitmap_allArray_LEN = 7;
const unsigned char* bitmap_allArray[7] = {
bitmap_marklin,
bitmap_marklin_digital,
bitmap_steam_lok,
bitmap_chronograph,
bitmap_finish_line,
bitmap_hv_tower,
bitmap_timeout
};
uint8_t mui_trule(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_DRAW ) {
switch(MenuTitle) {
case 0:
u8g2.drawXBMP(0, -1, 128, 16, bitmap_marklin);
break;
case 1:
u8g2.drawStr(0,10,"Light Show");
break;
case 2:
u8g2.drawStr(0,10,"Speed Measurment");
break;
}
}
return 0;
}
uint8_t mui_hrule(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_DRAW ) {
u8g2.drawHLine(0, mui_get_y(ui), u8g2.getDisplayWidth());
}
return 0;
}
uint8_t light_show(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_DRAW ) {
/* */
}
return 0;
}
uint8_t speed_measurment_show(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_DRAW ) {
uint16_t value1=analogRead(sensor1);
uint16_t value2=analogRead(sensor2);
switch(countState) {
case ST_OFF:
countoff(value1,value2);
break;
case ST_COUNTING:
counting(value1,value2);
break;
case ST_TIMEDOUT:
timedout();
break;
case ST_DONE:
countdone();
break;
}
}
return 0;
}
uint8_t mui_stop_speed_measurment(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_FORM_START )
is_speed_measured = false;
return 0;
}
uint8_t mui_start_speed_measurment(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_FORM_START ) {
is_speed_measured = true;
startmillis=0;
endmillis=0;
countState=ST_OFF;
return 0;
}
}
uint8_t mui_show_speed(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_DRAW ) {
int16_t travel_time=endmillis-startmillis; // in milliseconds
countdone();
countState=ST_OFF;
return 0;
}
}
uint8_t marklin_digital_logo_show(mui_t *ui, uint8_t msg) {
if ( msg == MUIF_MSG_DRAW ) {
u8g2.drawXBMP(0, 16, 128, 48, bitmap_marklin_digital);
}
return 0;
}
muif_t muif_list[] = {
MUIF_U8G2_FONT_STYLE(0, u8g2_font_luIS08_tf), /* menu title */
MUIF_U8G2_FONT_STYLE(1, u8g2_font_helvR08_tf), /* regular font */
MUIF_U8G2_FONT_STYLE(2, u8g2_font_helvB08_tf), /* bold font */
MUIF_U8G2_FONT_STYLE(3, u8g2_font_ncenB14_tr), /* Speed Measurment */
MUIF_RO("TL", mui_trule),
MUIF_RO("HR", mui_hrule),
MUIF_U8G2_LABEL(),
MUIF_RO("GP",mui_u8g2_goto_data),
MUIF_BUTTON("GC", mui_u8g2_goto_form_w1_pi),
/* register custom function to show the data */
MUIF_RO("LS", light_show),
MUIF_RO("SP", speed_measurment_show),
MUIF_RO("SO", mui_stop_speed_measurment),
MUIF_RO("SS", mui_start_speed_measurment),
MUIF_RO("DS", mui_show_speed),
MUIF_RO("ML", marklin_digital_logo_show),
/* a button for the menu... */
//MUIF_BUTTON("GO", mui_u8g2_btn_goto_wm_fi)
MUIF_EXECUTE_ON_SELECT_BUTTON("GO", mui_u8g2_btn_goto_wm_fi)
};
fds_t fds_data[] =
MUI_FORM(1)
MUI_STYLE(1)
MUI_XY("TL", 0,0)
MUI_AUX("SO")
MUI_DATA("GP",
MUI_10 "Lights Show|"
MUI_20 "Speed Measurment|"
MUI_30 "Märklin Digital Logo")
MUI_XYA("GC", 5, 24, 0)
MUI_XYA("GC", 5, 36, 1)
MUI_XYA("GC", 5, 48, 2)
// Lights Show
MUI_FORM(10)
MUI_STYLE(0)
MUI_LABEL(5, 8, "Lights Show")
MUI_XY("HR", 0,11)
MUI_STYLE(2)
MUI_LABEL(5,23, "Bitmap placeholder")
MUI_XYAT("GO", 114, 60, 1, " Back ")
// Speed Measurment
MUI_FORM(20)
MUI_STYLE(0)
MUI_LABEL(5, 8, "Speed Measurment")
MUI_XY("HR", 0,11)
MUI_STYLE(3)
MUI_AUX("SS")
MUI_XY("SP", 0, 23)
MUI_XYAT("GO", 0, 80, 1, "") // out of sight
MUI_FORM(21)
MUI_STYLE(0)
MUI_LABEL(5, 8, "Speed Measurment")
MUI_XY("HR", 0,11)
MUI_STYLE(3)
MUI_XY("DS", 0, 23)
MUI_STYLE(1)
MUI_XYAT("GO", 0, 80, 1, "") // out of sight
// Märklin Digital Logo
MUI_FORM(30)
MUI_XY("ML", 0, 23)
MUI_XYAT("GO", 0, 80, 1, "") // out of sight
;
// Functions prototyping to be handled on each Encoder Event
void handleRotate(int8_t rotation) {
if ( rotation > 0 )
rotate_event = 2; // CW
else
rotate_event = 1; // CCW
}
void handlePressRelease() {
press_event = true;
}
void handleLongPressRelease() {
long_press_event = true;
}
void setup() {
Serial.begin(9600);
// Load to the encoder all nedded handle functions here (up to 9 functions)
versatile_encoder.setHandleRotate(handleRotate);
versatile_encoder.setHandlePressRelease(handlePressRelease);
versatile_encoder.setHandleLongPressRelease(handleLongPressRelease);
// u8g2.setBusClock(400000);
// u8g2.setDrawColor(1);
u8g2.begin();
// u8g2.setFontMode(1);
// u8g2.setBitmapMode(1);
pinMode(sensor1,INPUT);
pinMode(sensor2,INPUT);
pinMode(light1,OUTPUT);
pinMode(light2,OUTPUT);
mui.begin(u8g2, fds_data, muif_list, sizeof(muif_list)/sizeof(muif_t));
mui.gotoForm(/* form_id= */ 1, /* initial_cursor_position= */ 0);
u8g2.firstPage();
do {
u8g2.drawXBMP(0, 16, 128, 48, bitmap_marklin_digital);
}
while( u8g2.nextPage() );//end of picture loop
u8g2.sendBuffer();
//delay(5000);
}
void handle_events(void) {
// 0 = not pushed, 1 = pushed
if (press_event) {
mui.sendSelect();
is_redraw = true;
press_event = false;
}
// 0 = not pushed, 1 = pushed
if (long_press_event) {
mui.sendSelectWithExecuteOnSelectFieldSearch();
is_redraw = true;
long_press_event = false;
}
// 0 = not turning, 1 = CW, 2 = CCW
if ( rotate_event == 1 ) {
mui.nextField();
is_redraw = true;
rotate_event = 0;
}
if ( rotate_event == 2 ) {
mui.prevField();
is_redraw = true;
rotate_event = 0;
}
}
void loop() {
/* check whether the menu is active */
if ( mui.isFormActive() ) {
/* update the display content, if the redraw flag is set */
if ( is_redraw ) {
u8g2.firstPage();
do {
versatile_encoder.ReadEncoder(); // Do the encoder reading and processing
mui.draw();
versatile_encoder.ReadEncoder(); // Do the encoder reading and processing
} while( u8g2.nextPage() );
is_redraw = false; /* clear the redraw flag */
}
versatile_encoder.ReadEncoder(); // Do the encoder reading and processing
handle_events();
if ( is_speed_measured ) {
//stop_watch_timer = millis() - stop_watch_millis;
is_redraw = true; // always redraw the screen so that the timer gets updated
}
} else {
/* the menu should never become inactive, but if so, then restart the menu system */
mui.gotoForm(/* form_id= */ 1, /* initial_cursor_position= */ 0);
}
}
void PowerlinePole() {
//needs to be implemented
}
void countoff(uint16_t value1, uint16_t value2) {
if (value1>100) {
// if (value1<500) {
digitalWrite(light1,LOW);
digitalWrite(light2,HIGH);
startmillis=(millis());
countState=ST_COUNTING;
} else {
digitalWrite(light1,HIGH);
x_SteamLok += 1;
if (x_SteamLok>128) {x_SteamLok=-76;}
u8g2.drawXBMP(x_SteamLok, 16, 76, 48, bitmap_steam_lok);
}
}
void counting(uint8_t value1, uint8_t value2) {
endmillis=(millis());
if (endmillis-startmillis>30000) { // 30 seconds
digitalWrite(light2,LOW);
startmillis=(millis());
countState=ST_TIMEDOUT;
} else {
if (value2>100) {
// if (value2<500) {
// Let's do the math
int16_t traveltime=endmillis-startmillis; // in milliseconds
float speedscale=(traveldistance/traveltime)*36; // from cm/millis to km/h
speed=speedscale*scale;
countState=ST_DONE;
} else {
u8g2.drawXBMP(10, 16, 43, 48, bitmap_chronograph);
u8g2.setCursor(60, 49);
int seconds = (endmillis-startmillis)/1000;
int millis = (endmillis-startmillis)%1000;
String str = String(millis).substring(0,2);
u8g2.print(seconds);
u8g2.print(".");
u8g2.print(str);
u8g2.print(" s");
}
}
}
void timedout() {
endmillis=(millis());
if (endmillis-startmillis<5000) { // 5 seconds
u8g2.drawXBMP(5, 16, 48, 48, bitmap_timeout);
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(55,40);
u8g2.print("Measurment");
u8g2.setCursor(60,50);
u8g2.print("timed out");
} else {
countState=ST_OFF;
startmillis=0;
endmillis=0;
}
}
void countdone() {
digitalWrite(light2,LOW);
u8g2.drawXBMP(90, 16, 39, 48, bitmap_finish_line);
u8g2.setFont(u8g2_font_inb30_mn);
u8g2.setCursor(0,50);
u8g2.print(speed);
u8g2.setFont(u8g2_font_crox1cb_mr);
u8g2.setCursor(50,61);
u8g2.print("km/h");
}