Changed measurements to be async to keep handling button presses
Implemented calibration screen Implemented pre-move stabilization Had to remove the nice font to save on program space :-(
This commit is contained in:
parent
1ca611e504
commit
7ec4fa3394
Binary file not shown.
@ -3,7 +3,7 @@ As I really do not want to explain to my employer how I broke my desk, this docu
|
|||||||
|
|
||||||
## Startup
|
## Startup
|
||||||
|
|
||||||
1. Height sensor must report at least 3 values within 5mm of each other in 500 ms intervals to be considered stable.
|
1. Height sensor must report at least 3 values within 10mm of each other to be considered stable.
|
||||||
1. If the EEPROM has not been initialized yet, the height offset setup screen must be displayed.
|
1. If the EEPROM has not been initialized yet, the height offset setup screen must be displayed.
|
||||||
1. Otherwise, the home screen must be displayed.
|
1. Otherwise, the home screen must be displayed.
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
https: //github.com/MvRens/AdafruitGFXFontTools
|
https: //github.com/MvRens/AdafruitGFXFontTools
|
||||||
|
|
||||||
Source: FreeSansBold18pt7b.h
|
Source: FreeSansBold18pt7b.h
|
||||||
Filter: [0-9\.mSTOPMenu]
|
Filter: [ 0-9\.mSTOPMenuERCalibrt]
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -52,54 +52,101 @@ const uint8_t FreeSansBold18pt7bTrimmedBitmaps[] PROGMEM = {
|
|||||||
0xE0, 0x3D, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x83,
|
0xE0, 0x3D, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x83,
|
||||||
0xF7, 0xE3, 0xFB, 0xFF, 0xFC, 0xFF, 0xFE, 0x3F, 0xDF, 0x07, 0xCF, 0x80,
|
0xF7, 0xE3, 0xFB, 0xFF, 0xFC, 0xFF, 0xFE, 0x3F, 0xDF, 0x07, 0xCF, 0x80,
|
||||||
0x07, 0x80, 0x03, 0xDF, 0x03, 0xE7, 0xC3, 0xE3, 0xFF, 0xF0, 0xFF, 0xF0,
|
0x07, 0x80, 0x03, 0xDF, 0x03, 0xE7, 0xC3, 0xE3, 0xFF, 0xF0, 0xFF, 0xF0,
|
||||||
0x3F, 0xF0, 0x07, 0xE0, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
|
0x3F, 0xF0, 0x07, 0xE0, 0x00, 0x00, 0xFF, 0x00, 0x07, 0xFF, 0x80, 0x3F,
|
||||||
0x00, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFF,
|
0xFF, 0xC0, 0xFF, 0xFF, 0xC3, 0xF8, 0x1F, 0x87, 0xE0, 0x1F, 0x9F, 0x80,
|
||||||
0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFB, 0xC3, 0xDF, 0xFB, 0xC3, 0xDF, 0xFB,
|
0x1F, 0x3E, 0x00, 0x1F, 0x7C, 0x00, 0x3F, 0xF0, 0x00, 0x03, 0xE0, 0x00,
|
||||||
0xC3, 0xDF, 0xFB, 0xC3, 0xDF, 0xF9, 0xC7, 0xDF, 0xF9, 0xE7, 0x9F, 0xF9,
|
0x07, 0xC0, 0x00, 0x0F, 0x80, 0x00, 0x1F, 0x00, 0x00, 0x3E, 0x00, 0x00,
|
||||||
0xE7, 0x9F, 0xF9, 0xE7, 0x9F, 0xF9, 0xE7, 0x9F, 0xF8, 0xFF, 0x1F, 0xF8,
|
0x7C, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x7D, 0xF0, 0x00, 0xFB,
|
||||||
0xFF, 0x1F, 0xF8, 0xFF, 0x1F, 0xF8, 0xFF, 0x1F, 0xF8, 0x7F, 0x1F, 0xF8,
|
0xF0, 0x03, 0xF3, 0xF0, 0x0F, 0xC7, 0xF0, 0x3F, 0x87, 0xFF, 0xFE, 0x07,
|
||||||
0x7E, 0x1F, 0xF8, 0x7E, 0x1F, 0xF8, 0x7E, 0x1F, 0xF8, 0x3E, 0x1F, 0x00,
|
0xFF, 0xF8, 0x03, 0xFF, 0xC0, 0x01, 0xFE, 0x00, 0xFF, 0xFF, 0xDF, 0xFF,
|
||||||
0x7F, 0x00, 0x01, 0xFF, 0xF0, 0x01, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0x01,
|
0xFB, 0xFF, 0xFF, 0x7F, 0xFF, 0xEF, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00,
|
||||||
0xFC, 0x1F, 0xC1, 0xF8, 0x03, 0xF1, 0xF8, 0x00, 0xFC, 0xF8, 0x00, 0x3E,
|
0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7F, 0xFF,
|
||||||
0x7C, 0x00, 0x1F, 0x7C, 0x00, 0x07, 0xFE, 0x00, 0x03, 0xFF, 0x00, 0x01,
|
0xCF, 0xFF, 0xF9, 0xFF, 0xFF, 0x3F, 0xFF, 0xE7, 0xC0, 0x00, 0xF8, 0x00,
|
||||||
0xFF, 0x80, 0x00, 0xFF, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xF0, 0x00,
|
0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00,
|
||||||
0x1F, 0xF8, 0x00, 0x0F, 0xBE, 0x00, 0x0F, 0x9F, 0x00, 0x07, 0xCF, 0xC0,
|
0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00,
|
||||||
0x07, 0xE3, 0xF0, 0x07, 0xE0, 0xFE, 0x0F, 0xE0, 0x7F, 0xFF, 0xE0, 0x0F,
|
0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x81,
|
||||||
0xFF, 0xE0, 0x03, 0xFF, 0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFF, 0xFC, 0x1F,
|
0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFB, 0xC3,
|
||||||
0xFF, 0xE3, 0xFF, 0xFE, 0x7F, 0xFF, 0xEF, 0x80, 0xFF, 0xF0, 0x0F, 0xFE,
|
0xDF, 0xFB, 0xC3, 0xDF, 0xFB, 0xC3, 0xDF, 0xFB, 0xC3, 0xDF, 0xF9, 0xC7,
|
||||||
0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x1F, 0xFC,
|
0xDF, 0xF9, 0xE7, 0x9F, 0xF9, 0xE7, 0x9F, 0xF9, 0xE7, 0x9F, 0xF9, 0xE7,
|
||||||
0x07, 0xEF, 0xFF, 0xFD, 0xFF, 0xFF, 0x3F, 0xFF, 0xC7, 0xFF, 0xE0, 0xF8,
|
0x9F, 0xF8, 0xFF, 0x1F, 0xF8, 0xFF, 0x1F, 0xF8, 0xFF, 0x1F, 0xF8, 0xFF,
|
||||||
0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0,
|
0x1F, 0xF8, 0x7F, 0x1F, 0xF8, 0x7E, 0x1F, 0xF8, 0x7E, 0x1F, 0xF8, 0x7E,
|
||||||
0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x00, 0x07,
|
0x1F, 0xF8, 0x3E, 0x1F, 0x00, 0x7F, 0x00, 0x01, 0xFF, 0xF0, 0x01, 0xFF,
|
||||||
0xF8, 0x01, 0xFF, 0xF0, 0x3F, 0xFF, 0x87, 0xFF, 0xFC, 0x7E, 0x0F, 0xCF,
|
0xFC, 0x03, 0xFF, 0xFF, 0x01, 0xFC, 0x1F, 0xC1, 0xF8, 0x03, 0xF1, 0xF8,
|
||||||
0xC0, 0x7E, 0xF8, 0x03, 0xEF, 0x80, 0x3E, 0xF8, 0x00, 0x0F, 0xC0, 0x00,
|
0x00, 0xFC, 0xF8, 0x00, 0x3E, 0x7C, 0x00, 0x1F, 0x7C, 0x00, 0x07, 0xFE,
|
||||||
0xFF, 0x00, 0x07, 0xFF, 0xC0, 0x3F, 0xFF, 0x81, 0xFF, 0xFC, 0x03, 0xFF,
|
0x00, 0x03, 0xFF, 0x00, 0x01, 0xFF, 0x80, 0x00, 0xFF, 0xC0, 0x00, 0x7F,
|
||||||
0xE0, 0x01, 0xFF, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0xF8, 0x01, 0xFF, 0x80,
|
0xE0, 0x00, 0x3F, 0xF0, 0x00, 0x1F, 0xF8, 0x00, 0x0F, 0xBE, 0x00, 0x0F,
|
||||||
0x1F, 0xFC, 0x03, 0xFF, 0xE0, 0x7E, 0x7F, 0xFF, 0xE3, 0xFF, 0xFC, 0x1F,
|
0x9F, 0x00, 0x07, 0xCF, 0xC0, 0x07, 0xE3, 0xF0, 0x07, 0xE0, 0xFE, 0x0F,
|
||||||
0xFF, 0x00, 0x3F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
0xE0, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xE0, 0x03, 0xFF, 0xE0, 0x00, 0x3F,
|
||||||
0xFF, 0xF0, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01,
|
0x80, 0x00, 0xFF, 0xFC, 0x1F, 0xFF, 0xE3, 0xFF, 0xFE, 0x7F, 0xFF, 0xEF,
|
||||||
0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03,
|
0x80, 0xFF, 0xF0, 0x0F, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF,
|
||||||
0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07,
|
0x00, 0x7F, 0xE0, 0x1F, 0xFC, 0x07, 0xEF, 0xFF, 0xFD, 0xFF, 0xFF, 0x3F,
|
||||||
0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F,
|
0xFF, 0xC7, 0xFF, 0xE0, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C,
|
||||||
0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xE0, 0x07, 0xFE, 0x03, 0xFF,
|
0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8,
|
||||||
0xE0, 0xFF, 0xF8, 0x7E, 0x1F, 0x1F, 0x03, 0xCF, 0x80, 0xFB, 0xE0, 0x1E,
|
0x00, 0x1F, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0xFF, 0xFE, 0x3F, 0xFF, 0xF9,
|
||||||
0xFF, 0xFF, 0xBF, 0xFF, 0xEF, 0xFF, 0xFB, 0xE0, 0x00, 0xF8, 0x00, 0x3F,
|
0xFF, 0xFF, 0xCF, 0x80, 0x3F, 0x7C, 0x00, 0xFB, 0xE0, 0x07, 0xDF, 0x00,
|
||||||
0x03, 0xE7, 0xE1, 0xF9, 0xFF, 0xFC, 0x3F, 0xFE, 0x07, 0xFF, 0x00, 0x7F,
|
0x3E, 0xF8, 0x01, 0xF7, 0xC0, 0x0F, 0x3E, 0x00, 0xF9, 0xFF, 0xFF, 0x8F,
|
||||||
0x00, 0xF8, 0xF8, 0x3F, 0x1F, 0x7F, 0x9F, 0xF3, 0xFF, 0xFF, 0xFF, 0x7F,
|
0xFF, 0xF8, 0x7F, 0xFF, 0xC3, 0xFF, 0xFF, 0x1F, 0x00, 0xFC, 0xF8, 0x03,
|
||||||
0xFF, 0xFF, 0xFF, 0xC3, 0xF8, 0x7F, 0xF8, 0x3F, 0x07, 0xFE, 0x07, 0xC0,
|
0xE7, 0xC0, 0x1F, 0x3E, 0x00, 0xF9, 0xF0, 0x07, 0xCF, 0x80, 0x3E, 0x7C,
|
||||||
0xFF, 0xC0, 0xF8, 0x1F, 0xF8, 0x1F, 0x03, 0xFF, 0x03, 0xE0, 0x7F, 0xE0,
|
0x01, 0xF3, 0xE0, 0x0F, 0x9F, 0x00, 0x7C, 0xF8, 0x03, 0xF7, 0xC0, 0x0F,
|
||||||
0x7C, 0x0F, 0xFC, 0x0F, 0x81, 0xFF, 0x81, 0xF0, 0x3F, 0xF0, 0x3E, 0x07,
|
0xC0, 0x07, 0xF8, 0x01, 0xFF, 0xF0, 0x3F, 0xFF, 0x87, 0xFF, 0xFC, 0x7E,
|
||||||
0xFE, 0x07, 0xC0, 0xFF, 0xC0, 0xF8, 0x1F, 0xF8, 0x1F, 0x03, 0xFF, 0x03,
|
0x0F, 0xCF, 0xC0, 0x7E, 0xF8, 0x03, 0xEF, 0x80, 0x3E, 0xF8, 0x00, 0x0F,
|
||||||
0xE0, 0x7F, 0xE0, 0x7C, 0x0F, 0x80, 0xF8, 0xF8, 0x7D, 0xFF, 0x3F, 0xFF,
|
0xC0, 0x00, 0xFF, 0x00, 0x07, 0xFF, 0xC0, 0x3F, 0xFF, 0x81, 0xFF, 0xFC,
|
||||||
0xDF, 0xFF, 0xEF, 0xE1, 0xFF, 0xE0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8,
|
0x03, 0xFF, 0xE0, 0x01, 0xFF, 0x00, 0x03, 0xF0, 0x00, 0x1F, 0xF8, 0x01,
|
||||||
0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F,
|
0xFF, 0x80, 0x1F, 0xFC, 0x03, 0xFF, 0xE0, 0x7E, 0x7F, 0xFF, 0xE3, 0xFF,
|
||||||
0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xE0, 0xF8,
|
0xFC, 0x1F, 0xFF, 0x00, 0x3F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F,
|
0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F,
|
||||||
0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01,
|
0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F,
|
||||||
0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x9F,
|
0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3E,
|
||||||
0xF7, 0xC7, 0xE3, 0xE0 };
|
0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C,
|
||||||
|
0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xF8, 0x07, 0xFF,
|
||||||
|
0x83, 0xFF, 0xF1, 0xFF, 0xFE, 0x7C, 0x1F, 0xBE, 0x03, 0xE0, 0x00, 0xF8,
|
||||||
|
0x01, 0xFE, 0x0F, 0xFF, 0x8F, 0xFF, 0xE7, 0xF8, 0xFB, 0xF0, 0x3E, 0xF8,
|
||||||
|
0x0F, 0xBE, 0x07, 0xEF, 0xC3, 0xFB, 0xFF, 0xFE, 0x7F, 0xFF, 0x8F, 0xFB,
|
||||||
|
0xF1, 0xF8, 0xFC, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00,
|
||||||
|
0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE7, 0xE0, 0xFB, 0xFC, 0x3F,
|
||||||
|
0xFF, 0xCF, 0xFF, 0xF3, 0xF8, 0x7E, 0xFC, 0x0F, 0xBF, 0x03, 0xFF, 0x80,
|
||||||
|
0x7F, 0xE0, 0x1F, 0xF8, 0x07, 0xFE, 0x01, 0xFF, 0x80, 0x7F, 0xF0, 0x3F,
|
||||||
|
0xFC, 0x0F, 0xBF, 0x87, 0xEF, 0xFF, 0xF3, 0xFF, 0xFC, 0xFB, 0xFC, 0x3E,
|
||||||
|
0x7E, 0x00, 0x07, 0xE0, 0x07, 0xFE, 0x03, 0xFF, 0xE0, 0xFF, 0xF8, 0x7E,
|
||||||
|
0x1F, 0x1F, 0x03, 0xCF, 0x80, 0xFB, 0xE0, 0x1E, 0xFF, 0xFF, 0xBF, 0xFF,
|
||||||
|
0xEF, 0xFF, 0xFB, 0xE0, 0x00, 0xF8, 0x00, 0x3F, 0x03, 0xE7, 0xE1, 0xF9,
|
||||||
|
0xFF, 0xFC, 0x3F, 0xFE, 0x07, 0xFF, 0x00, 0x7F, 0x00, 0xFF, 0xFF, 0xF0,
|
||||||
|
0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xF8, 0xF8, 0x3F, 0x1F, 0x7F,
|
||||||
|
0x9F, 0xF3, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xC3, 0xF8, 0x7F,
|
||||||
|
0xF8, 0x3F, 0x07, 0xFE, 0x07, 0xC0, 0xFF, 0xC0, 0xF8, 0x1F, 0xF8, 0x1F,
|
||||||
|
0x03, 0xFF, 0x03, 0xE0, 0x7F, 0xE0, 0x7C, 0x0F, 0xFC, 0x0F, 0x81, 0xFF,
|
||||||
|
0x81, 0xF0, 0x3F, 0xF0, 0x3E, 0x07, 0xFE, 0x07, 0xC0, 0xFF, 0xC0, 0xF8,
|
||||||
|
0x1F, 0xF8, 0x1F, 0x03, 0xFF, 0x03, 0xE0, 0x7F, 0xE0, 0x7C, 0x0F, 0x80,
|
||||||
|
0xF8, 0xF8, 0x7D, 0xFF, 0x3F, 0xFF, 0xDF, 0xFF, 0xEF, 0xE1, 0xFF, 0xE0,
|
||||||
|
0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF,
|
||||||
|
0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0, 0x3F, 0xF0, 0x1F, 0xF8, 0x0F,
|
||||||
|
0xFC, 0x07, 0xFE, 0x03, 0xE0, 0xF8, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xE1,
|
||||||
|
0xF8, 0x3E, 0x07, 0xC0, 0xF8, 0x1F, 0x03, 0xE0, 0x7C, 0x0F, 0x81, 0xF0,
|
||||||
|
0x3E, 0x07, 0xC0, 0xF8, 0x1F, 0x03, 0xE0, 0x00, 0x3E, 0x1F, 0x0F, 0x87,
|
||||||
|
0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0,
|
||||||
|
0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xF3, 0xF8, 0xFC, 0x3E, 0xF8, 0x0F,
|
||||||
|
0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x7F, 0xE0,
|
||||||
|
0x3F, 0xF0, 0x1F, 0xF8, 0x0F, 0xFC, 0x07, 0xFE, 0x03, 0xFF, 0x01, 0xFF,
|
||||||
|
0x80, 0xFF, 0xC0, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x9F, 0xF7,
|
||||||
|
0xC7, 0xE3, 0xE0 };
|
||||||
|
|
||||||
const GFXglyph FreeSansBold18pt7bTrimmedGlyphs[] PROGMEM = {
|
const GFXglyph FreeSansBold18pt7bTrimmedGlyphs[] PROGMEM = {
|
||||||
|
{ 0, 0, 0, 10, 0, 1 }, // 0x20 ' '
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x21 '!'
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x22 '"'
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x23 '#'
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x24 '$'
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x25 '%'
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x26 '&'
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x27 '''
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x28 '('
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x29 ')'
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x2A '*'
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x2B '+'
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x2C ','
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }, // 0x2D '-'
|
||||||
{ 0, 5, 5, 9, 2, -4 }, // 0x2E '.'
|
{ 0, 5, 5, 9, 2, -4 }, // 0x2E '.'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x2F '/'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x2F '/'
|
||||||
{ 4, 17, 25, 19, 1, -24 }, // 0x30 '0'
|
{ 4, 17, 25, 19, 1, -24 }, // 0x30 '0'
|
||||||
@ -121,9 +168,9 @@ const GFXglyph FreeSansBold18pt7bTrimmedGlyphs[] PROGMEM = {
|
|||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x40 '@'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x40 '@'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x41 'A'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x41 'A'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x42 'B'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x42 'B'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x43 'C'
|
{ 521, 23, 26, 25, 1, -25 }, // 0x43 'C'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x44 'D'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x44 'D'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x45 'E'
|
{ 596, 19, 26, 23, 3, -25 }, // 0x45 'E'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x46 'F'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x46 'F'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x47 'G'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x47 'G'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x48 'H'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x48 'H'
|
||||||
@ -131,14 +178,14 @@ const GFXglyph FreeSansBold18pt7bTrimmedGlyphs[] PROGMEM = {
|
|||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x4A 'J'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x4A 'J'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x4B 'K'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x4B 'K'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x4C 'L'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x4C 'L'
|
||||||
{ 521, 24, 26, 30, 3, -25 }, // 0x4D 'M'
|
{ 658, 24, 26, 30, 3, -25 }, // 0x4D 'M'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x4E 'N'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x4E 'N'
|
||||||
{ 599, 25, 26, 27, 1, -25 }, // 0x4F 'O'
|
{ 736, 25, 26, 27, 1, -25 }, // 0x4F 'O'
|
||||||
{ 681, 19, 26, 24, 3, -25 }, // 0x50 'P'
|
{ 818, 19, 26, 24, 3, -25 }, // 0x50 'P'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x51 'Q'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x51 'Q'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x52 'R'
|
{ 880, 21, 26, 25, 3, -25 }, // 0x52 'R'
|
||||||
{ 743, 20, 26, 24, 2, -25 }, // 0x53 'S'
|
{ 949, 20, 26, 24, 2, -25 }, // 0x53 'S'
|
||||||
{ 808, 19, 26, 23, 2, -25 }, // 0x54 'T'
|
{ 1014, 19, 26, 23, 2, -25 }, // 0x54 'T'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x55 'U'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x55 'U'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x56 'V'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x56 'V'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x57 'W'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x57 'W'
|
||||||
@ -151,31 +198,31 @@ const GFXglyph FreeSansBold18pt7bTrimmedGlyphs[] PROGMEM = {
|
|||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x5E '^'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x5E '^'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x5F '_'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x5F '_'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x60 '`'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x60 '`'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x61 'a'
|
{ 1076, 18, 19, 20, 1, -18 }, // 0x61 'a'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x62 'b'
|
{ 1119, 18, 26, 22, 2, -25 }, // 0x62 'b'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x63 'c'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x63 'c'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x64 'd'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x64 'd'
|
||||||
{ 870, 18, 19, 20, 1, -18 }, // 0x65 'e'
|
{ 1178, 18, 19, 20, 1, -18 }, // 0x65 'e'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x66 'f'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x66 'f'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x67 'g'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x67 'g'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x68 'h'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x68 'h'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x69 'i'
|
{ 1221, 5, 26, 10, 2, -25 }, // 0x69 'i'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x6A 'j'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x6A 'j'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x6B 'k'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x6B 'k'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x6C 'l'
|
{ 1238, 5, 26, 9, 2, -25 }, // 0x6C 'l'
|
||||||
{ 913, 27, 19, 31, 2, -18 }, // 0x6D 'm'
|
{ 1255, 27, 19, 31, 2, -18 }, // 0x6D 'm'
|
||||||
{ 978, 17, 19, 21, 2, -18 }, // 0x6E 'n'
|
{ 1320, 17, 19, 21, 2, -18 }, // 0x6E 'n'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x6F 'o'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x6F 'o'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x70 'p'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x70 'p'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x71 'q'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x71 'q'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x72 'r'
|
{ 1361, 11, 19, 14, 2, -18 }, // 0x72 'r'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x73 's'
|
{ 0, 0, 0, 0, 0, 0 }, // 0x73 's'
|
||||||
{ 0, 0, 0, 0, 0, 0 }, // 0x74 't'
|
{ 1388, 9, 23, 12, 1, -22 }, // 0x74 't'
|
||||||
{ 1019, 17, 19, 21, 2, -18 } }; // 0x75 'u'
|
{ 1414, 17, 19, 21, 2, -18 } }; // 0x75 'u'
|
||||||
|
|
||||||
const GFXfont FreeSansBold18pt7bTrimmed PROGMEM = {
|
const GFXfont FreeSansBold18pt7bTrimmed PROGMEM = {
|
||||||
(uint8_t *)FreeSansBold18pt7bTrimmedBitmaps,
|
(uint8_t *)FreeSansBold18pt7bTrimmedBitmaps,
|
||||||
(GFXglyph *)FreeSansBold18pt7bTrimmedGlyphs,
|
(GFXglyph *)FreeSansBold18pt7bTrimmedGlyphs,
|
||||||
0x2E, 0x75, 42 };
|
0x20, 0x75, 42 };
|
||||||
|
|
||||||
// Approx. 1571 bytes
|
// Approx. 2064 bytes
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
REM It is a nuisance to keep the filter up-to-date with whatever is printed
|
REM It is a nuisance to keep the filter up-to-date with whatever is printed
|
||||||
REM in the actual source, but the space savings are worth it.
|
REM in the actual source, but the space savings are worth it.
|
||||||
AdafruitGFXFontTrim [ 0-9\.mSTOPMenuER] FreeSansBold18pt7b.h
|
AdafruitGFXFontTrim "[ 0-9\.mSTOPMenuERCalibrt]" FreeSansBold18pt7b.h
|
||||||
|
|
||||||
pause
|
pause
|
@ -12,9 +12,9 @@ class Config
|
|||||||
Buttons
|
Buttons
|
||||||
|
|
||||||
*/
|
*/
|
||||||
static const uint8_t ButtonPinUp = 3;
|
static const uint8_t ButtonPinTop = 3;
|
||||||
static const uint8_t ButtonPinMenu = 5;
|
static const uint8_t ButtonPinMiddle = 5;
|
||||||
static const uint8_t ButtonPinDown = 6;
|
static const uint8_t ButtonPinBottom = 6;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -38,7 +38,7 @@ class Config
|
|||||||
|
|
||||||
|
|
||||||
static const uint16_t DisplayIdleTime = 10000;
|
static const uint16_t DisplayIdleTime = 10000;
|
||||||
static const uint16_t DisplayMoveRefreshRate = 1000;
|
static const uint16_t DisplayRefreshRate = 1000;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -59,6 +59,7 @@ class Config
|
|||||||
// How much the measurements can change to still be considered "stable"
|
// How much the measurements can change to still be considered "stable"
|
||||||
static const uint8_t HeightMeasurementDeltaStable = 10;
|
static const uint8_t HeightMeasurementDeltaStable = 10;
|
||||||
static const uint8_t HeightMeasurementDeltaStableCount = 3;
|
static const uint8_t HeightMeasurementDeltaStableCount = 3;
|
||||||
|
static const uint16_t HeightMeasurementDeltaStableMoveTimeout = 2000;
|
||||||
|
|
||||||
// How far in advance to stop the motor
|
// How far in advance to stop the motor
|
||||||
static const uint8_t HeightMeasurementDeltaStop = 0;
|
static const uint8_t HeightMeasurementDeltaStop = 0;
|
||||||
@ -99,10 +100,13 @@ class Config
|
|||||||
#define ColorDarkerGray 0x2965
|
#define ColorDarkerGray 0x2965
|
||||||
|
|
||||||
#define ColorStopRed 0xF9A6
|
#define ColorStopRed 0xF9A6
|
||||||
|
#define ColorDarkRed 0x4861
|
||||||
#define ColorSoftGreen 0x2BE7
|
#define ColorSoftGreen 0x2BE7
|
||||||
#define ColorSoftBlue 0x3376
|
#define ColorSoftBlue 0x3376
|
||||||
#define ColorDarkBlue 0x0907
|
#define ColorDarkBlue 0x0907
|
||||||
|
|
||||||
|
#define ColorOrange 0xF443
|
||||||
|
|
||||||
|
|
||||||
// Init sequence
|
// Init sequence
|
||||||
static const uint16_t ColorInitSeqBackground = ColorBlack;
|
static const uint16_t ColorInitSeqBackground = ColorBlack;
|
||||||
@ -139,7 +143,8 @@ class Config
|
|||||||
|
|
||||||
|
|
||||||
// Move error / overcurrent
|
// Move error / overcurrent
|
||||||
static const uint16_t ColorMoveErrorText = ColorStopRed;
|
static const uint16_t ColorErrorBackground = ColorDarkRed;
|
||||||
|
static const uint16_t ColorErrorText = ColorStopRed;
|
||||||
|
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
@ -149,8 +154,11 @@ class Config
|
|||||||
static const uint16_t ColorMenuSelectedText = ColorWhite;
|
static const uint16_t ColorMenuSelectedText = ColorWhite;
|
||||||
static const uint16_t ColorMenuSelectedBackground = ColorDarkBlue;
|
static const uint16_t ColorMenuSelectedBackground = ColorDarkBlue;
|
||||||
|
|
||||||
|
static const uint16_t ColorCalibrateBackground = ColorBlack;
|
||||||
static const uint16_t ColorCalibrateIndicators = ColorWhite;
|
static const uint16_t ColorCalibrateIndicators = ColorWhite;
|
||||||
static const uint16_t ColorCalibrateValue = ColorWhite;
|
static const uint16_t ColorCalibrateValue = ColorWhite;
|
||||||
|
static const uint16_t ColorCalibrateInvalidValue = ColorOrange;
|
||||||
|
static const uint16_t ColorCalibrateDigitMarker = ColorWhite;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -2,7 +2,7 @@
|
|||||||
#define __metrics
|
#define __metrics
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "fonts/FreeSansBold18pt7b.trimmed.h"
|
//#include "fonts/FreeSansBold18pt7b.trimmed.h"
|
||||||
|
|
||||||
class Metrics
|
class Metrics
|
||||||
{
|
{
|
||||||
@ -14,6 +14,7 @@ class Metrics
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
static constexpr const GFXfont* SmallFont = nullptr;
|
static constexpr const GFXfont* SmallFont = nullptr;
|
||||||
|
static const uint8_t SmallFontTextSize = 1;
|
||||||
|
|
||||||
static const uint16_t SmallFontBaseline = 0;
|
static const uint16_t SmallFontBaseline = 0;
|
||||||
static const uint16_t SmallFontHeight = 8;
|
static const uint16_t SmallFontHeight = 8;
|
||||||
@ -23,15 +24,21 @@ class Metrics
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
Large font
|
Large font
|
||||||
Uses a trimmed version of the FreeSansBold 18pt font.
|
Originally used a trimmed version of the FreeSansBold 18pt font.
|
||||||
|
Unfortunately due to program size constraints (I already ordered
|
||||||
|
PCBs based on the ATMega328P) I'll use a scaled version of the
|
||||||
|
built-in font for now.
|
||||||
*/
|
*/
|
||||||
static constexpr const GFXfont* LargeFont = &FreeSansBold18pt7bTrimmed;
|
static constexpr const GFXfont* LargeFont = nullptr;//&FreeSansBold18pt7bTrimmed;
|
||||||
|
static const uint8_t LargeFontTextSize = 3;
|
||||||
|
|
||||||
static const uint16_t LargeFontBaseline = 25;
|
//static const uint16_t LargeFontBaseline = 25;
|
||||||
static const uint16_t LargeFontHeight = Metrics::LargeFontBaseline;
|
//static const uint16_t LargeFontHeight = Metrics::LargeFontBaseline;
|
||||||
static const uint16_t LargeFontMaxHeight = 42;
|
//static const uint16_t LargeFontMaxHeight = 42;
|
||||||
|
|
||||||
|
static const uint16_t LargeFontBaseline = 0;
|
||||||
|
static const uint16_t LargeFontHeight = 24;
|
||||||
|
static const uint16_t LargeFontMaxHeight = 24;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
15
src/include/screenids.h
Normal file
15
src/include/screenids.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef __screenids
|
||||||
|
#define __screenids
|
||||||
|
|
||||||
|
enum class ScreenId
|
||||||
|
{
|
||||||
|
Home,
|
||||||
|
Calibrate,
|
||||||
|
Move,
|
||||||
|
MoveOvercurrent,
|
||||||
|
MoveSensorError,
|
||||||
|
Menu,
|
||||||
|
Manual
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -1,9 +1,9 @@
|
|||||||
#include "./control.h"
|
#include "./control.h"
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include "./motor.h"
|
|
||||||
#include "./Control.h"
|
|
||||||
#include "./settings.h"
|
|
||||||
#include "./debug.h"
|
#include "./debug.h"
|
||||||
|
#include "./motor.h"
|
||||||
|
#include "./state.h"
|
||||||
|
#include "./settings.h"
|
||||||
#include "include/config.h"
|
#include "include/config.h"
|
||||||
|
|
||||||
|
|
||||||
@ -12,6 +12,7 @@ ControlManager Control = ControlManager();
|
|||||||
|
|
||||||
VL53L0XInitResult ControlManager::init()
|
VL53L0XInitResult ControlManager::init()
|
||||||
{
|
{
|
||||||
|
dln("[ CONTROL ] Initializing");
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
|
|
||||||
this->heightSensor.setTimeout(500);
|
this->heightSensor.setTimeout(500);
|
||||||
@ -26,45 +27,182 @@ VL53L0XInitResult ControlManager::init()
|
|||||||
|
|
||||||
ControlUpdateResult ControlManager::update()
|
ControlUpdateResult ControlManager::update()
|
||||||
{
|
{
|
||||||
|
// Always read the range if in async reading mode, even if we're not supposed to
|
||||||
|
// be moving anymore, so it clears the status.
|
||||||
|
bool asyncReading = heightSensor.asyncReading();
|
||||||
|
|
||||||
|
uint16_t measurement = asyncReading
|
||||||
|
? heightSensor.asyncReadRangeSingleMillimeters()
|
||||||
|
: VL53L0XRangeNotReady;
|
||||||
|
|
||||||
|
|
||||||
|
vl("[ CONTROL ] Update: asyncReading = "); vl(asyncReading); vl(", measurement = "); vl(measurement);
|
||||||
|
vl(", moveDirection = "); vl((uint8_t)this->moveDirection); vl(", stabilizationStart = "); vln(this->stabilizationStart);
|
||||||
|
|
||||||
|
|
||||||
|
bool moving = this->moveDirection != MoveDirection::None && this->stabilizationStart == 0;
|
||||||
|
if (!moving && this->stabilizationStart == 0)
|
||||||
|
{
|
||||||
|
vl("[ CONTROL ] Idle");
|
||||||
|
return ControlUpdateResult::Idle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check for over-current
|
||||||
|
// TODO: don't check current every update
|
||||||
|
if (moving && motorIsOvercurrent())
|
||||||
|
{
|
||||||
|
dln("[ CONTROL ] Overcurrent detected!");
|
||||||
|
this->moveStop();
|
||||||
|
|
||||||
|
return ControlUpdateResult::Overcurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read sensor
|
||||||
|
if (!asyncReading)
|
||||||
|
{
|
||||||
|
vln("[ CONTROL ] Starting async read");
|
||||||
|
heightSensor.asyncStartReadRangeSingleMillimeters();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (measurement != VL53L0XRangeNotReady)
|
||||||
|
{
|
||||||
|
if (measurement > Config::HeightMeasurementMax)
|
||||||
|
// Treat invalid results as a timeout, so the checks further on are more readable
|
||||||
|
measurement = VL53L0XRangeTimeout;
|
||||||
|
|
||||||
|
|
||||||
|
dl("[ CONTROL ] Measurement: "); dln(measurement);
|
||||||
|
this->lastMeasurement = measurement != VL53L0XRangeTimeout ? measurement : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (measurement != VL53L0XRangeNotReady && measurement != VL53L0XRangeTimeout)
|
||||||
|
{
|
||||||
|
this->currentHeight = measurement;
|
||||||
|
this->lastValidMeasurement = CurrentTime;
|
||||||
|
|
||||||
|
// Check if target has been reached
|
||||||
|
if (moving && this->targetReached())
|
||||||
|
{
|
||||||
|
this->moveStop();
|
||||||
|
|
||||||
|
return ControlUpdateResult::TargetReached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (measurement == VL53L0XRangeTimeout && moving)
|
||||||
|
{
|
||||||
|
// While moving, allow incidental invalid results
|
||||||
|
if (CurrentTime - lastValidMeasurement >= Config::HeightMeasurementAbortTimeout)
|
||||||
|
{
|
||||||
|
dln("[ CONTROL ] Timeout while moving!");
|
||||||
|
this->moveStop();
|
||||||
|
|
||||||
|
return ControlUpdateResult::SensorError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (measurement == VL53L0XRangeTimeout && this->moveDirection == MoveDirection::None)
|
||||||
|
{
|
||||||
|
// In pure stabilization (not pre-move), immediately return the sensor error
|
||||||
|
return ControlUpdateResult::SensorError;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (this->stabilizationStart && this->moveDirection != MoveDirection::None)
|
||||||
|
{
|
||||||
|
// Pre-move stabilization
|
||||||
|
if (this->stabilized())
|
||||||
|
{
|
||||||
|
dln("[ CONTROL ] Pre-move stabilization successful");
|
||||||
|
|
||||||
|
// Sensor looks good, let's go!
|
||||||
|
motorStart(this->moveDirection == MoveDirection::Up ? MotorDirection::Up : MotorDirection::Down);
|
||||||
|
return ControlUpdateResult::Moving;
|
||||||
|
}
|
||||||
|
else if (CurrentTime - this->stabilizationStart >= Config::HeightMeasurementDeltaStableMoveTimeout)
|
||||||
|
{
|
||||||
|
dln("[ CONTROL ] Timeout in pre-move stabilization!");
|
||||||
|
|
||||||
|
// Timeout expired, abort the move
|
||||||
|
this->stabilizationStart = 0;
|
||||||
|
this->moveDirection = MoveDirection::None;
|
||||||
|
|
||||||
|
return ControlUpdateResult::SensorError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return moving ? ControlUpdateResult::Moving : ControlUpdateResult::Stabilizing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ControlManager::stabilizeStart()
|
void ControlManager::stabilizeStart()
|
||||||
{
|
{
|
||||||
this->stabilizing = true;
|
dln("[ CONTROL ] Starting stabilization");
|
||||||
|
|
||||||
|
this->stabilizationStart = CurrentTime;
|
||||||
|
this->stabilizeTarget = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ControlManager::stabilized()
|
bool ControlManager::stabilized()
|
||||||
{
|
{
|
||||||
// TODO: stabilized
|
if (this->stabilizeTarget == 0)
|
||||||
}
|
{
|
||||||
|
this->stabilizeTarget = this->currentHeight;
|
||||||
|
this->stabilizationLastCheck = this->lastValidMeasurement;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only count if we have a new measurement
|
||||||
void ControlManager::movePrepare(uint16_t height)
|
if (this->stabilizationLastCheck == this->lastValidMeasurement)
|
||||||
{
|
|
||||||
this->moveTarget = height;
|
|
||||||
this->moveDirection = height > this->currentHeight ? MoveDirection::Up : MoveDirection::Down;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ControlManager::moveStart()
|
|
||||||
{
|
|
||||||
// TODO: moveStart - wait for stable / timeout
|
|
||||||
|
|
||||||
this->moveDirection = MoveDirection::None;
|
|
||||||
this->stabilizeStart();
|
|
||||||
//this->sensorError = true;
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
motorStart(this->moveDirection == MoveDirection::Up ? MotorDirection::Up : MotorDirection::Down);
|
this->stabilizationLastCheck = this->lastValidMeasurement;
|
||||||
|
|
||||||
|
|
||||||
|
int16_t delta = this->currentHeight - this->stabilizeTarget;
|
||||||
|
if (abs(delta) <= Config::HeightMeasurementDeltaStable)
|
||||||
|
{
|
||||||
|
this->stabilizeCount++;
|
||||||
|
|
||||||
|
if (this->stabilizeCount >= Config::HeightMeasurementDeltaStableCount)
|
||||||
|
{
|
||||||
|
dln("[ CONTROL ] Stable");
|
||||||
|
this->stabilizationStart = 0;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If it's this much off, chances are the actual value is somewhere in the middle
|
||||||
|
this->stabilizeTarget += (delta / 2);
|
||||||
|
this->stabilizeCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ControlManager::moveStart(uint16_t height)
|
||||||
|
{
|
||||||
|
dl("[ CONTROL ] Starting move to: "); dln(height);
|
||||||
|
|
||||||
|
this->moveTarget = height;
|
||||||
|
this->moveDirection = height > this->currentHeight ? MoveDirection::Up : MoveDirection::Down;
|
||||||
|
|
||||||
|
// Wait for a stable result
|
||||||
|
this->stabilizeStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ControlManager::moveStop()
|
void ControlManager::moveStop()
|
||||||
{
|
{
|
||||||
|
dln("[ CONTROL ] Stopping move");
|
||||||
|
|
||||||
motorStop();
|
motorStop();
|
||||||
this->moveDirection = MoveDirection::None;
|
this->moveDirection = MoveDirection::None;
|
||||||
}
|
}
|
||||||
@ -84,8 +222,52 @@ void ControlManager::snapToPreset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ControlManager::targetReached()
|
||||||
|
{
|
||||||
|
// Checks depend on the direction, so it returns true immediately if we've overshot the target
|
||||||
|
switch (this->moveDirection)
|
||||||
|
{
|
||||||
|
case MoveDirection::Up:
|
||||||
|
if (this->currentHeight >= this->moveTarget - Config::HeightMeasurementDeltaStop)
|
||||||
|
{
|
||||||
|
// Snap to the target
|
||||||
|
if (this->currentHeight - this->moveTarget <= Config::HeightMeasurementDeltaOnTarget)
|
||||||
|
this->currentHeight = this->moveTarget;
|
||||||
|
|
||||||
|
dln("[ CONTROL ] Target reached");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MoveDirection::Down:
|
||||||
|
if (this->currentHeight <= this->moveTarget + Config::HeightMeasurementDeltaStop)
|
||||||
|
{
|
||||||
|
// Snap to the target
|
||||||
|
if (this->moveTarget - this->currentHeight <= Config::HeightMeasurementDeltaOnTarget)
|
||||||
|
this->currentHeight = this->moveTarget;
|
||||||
|
|
||||||
|
dln("[ CONTROL ] Target reached");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ControlManager::getDisplayHeight(char* buffer, uint16_t value)
|
void ControlManager::getDisplayHeight(char* buffer, uint16_t value)
|
||||||
{
|
{
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
buffer[0] = '-';
|
||||||
|
buffer[1] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t displayValue = (value + Settings.Height.Offset) / 10;
|
uint8_t displayValue = (value + Settings.Height.Offset) / 10;
|
||||||
|
|
||||||
if (displayValue > 99)
|
if (displayValue > 99)
|
||||||
@ -99,148 +281,3 @@ void ControlManager::getDisplayHeight(char* buffer, uint16_t value)
|
|||||||
buffer[4] = 'm';
|
buffer[4] = 'm';
|
||||||
buffer[5] = 0;
|
buffer[5] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
bool controlCheckTargetReached()
|
|
||||||
{
|
|
||||||
dl("controlCheckTargetReached: direction = "); dl((uint8_t)Control.getMoveDirection()); dl(", currentHeight = "); dln(Control.getCurrentHeight());
|
|
||||||
|
|
||||||
switch (Control.getMoveDirection())
|
|
||||||
{
|
|
||||||
case Direction::Up:
|
|
||||||
if (Control.getCurrentHeight() >= Control.getMoveTarget() - Config::HeightMeasurementDeltaStop)
|
|
||||||
{
|
|
||||||
if (Control.getCurrentHeight() - Control.getMoveTarget() <= Config::HeightMeasurementDeltaOnTarget)
|
|
||||||
Control.getCurrentHeight() = Control.getMoveTarget();
|
|
||||||
|
|
||||||
controlStop();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Direction::Down:
|
|
||||||
if (Control.getCurrentHeight() <= Control.getMoveTarget() + Config::HeightMeasurementDeltaStop)
|
|
||||||
{
|
|
||||||
if (Control.getMoveTarget() - Control.getCurrentHeight() <= Config::HeightMeasurementDeltaOnTarget)
|
|
||||||
Control.getCurrentHeight() = Control.getMoveTarget();
|
|
||||||
|
|
||||||
controlStop();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool controlCheckOverCurrent()
|
|
||||||
{
|
|
||||||
if (motorIsOverCurrent())
|
|
||||||
{
|
|
||||||
dln("controlCheckOverCurrent: overcurrent detected!");
|
|
||||||
|
|
||||||
controlStop();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (Control.getMoveDirection() != Direction::None)
|
|
||||||
{
|
|
||||||
if (controlCheckOverCurrent())
|
|
||||||
screenManager.show<MoveOverCurrentScreen>();
|
|
||||||
else
|
|
||||||
updateHeight();
|
|
||||||
}
|
|
||||||
else if (Control.SensorError)
|
|
||||||
updateHeight();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void updateHeight()
|
|
||||||
{
|
|
||||||
uint16_t measurement;
|
|
||||||
|
|
||||||
if (heightSensorGetRange(&measurement))
|
|
||||||
{
|
|
||||||
Control.getCurrentHeight() = measurement;
|
|
||||||
|
|
||||||
if (Control.getMoveDirection() != Direction::None)
|
|
||||||
{
|
|
||||||
lastValidMeasurement = CurrentTime;
|
|
||||||
|
|
||||||
if (controlCheckTargetReached())
|
|
||||||
screenManager.show<HomeScreen>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Control.getMoveDirection() != Direction::None && CurrentTime - lastValidMeasurement >= Config::HeightMeasurementAbortTimeout)
|
|
||||||
{
|
|
||||||
dln("Out of range timeout!");
|
|
||||||
Control.moveStop();
|
|
||||||
|
|
||||||
screenManager.show<MoveSensorErrorScreen>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool heightSensorGetRange(uint16_t* measurement)
|
|
||||||
{
|
|
||||||
*measurement = heightSensor.readRangeSingleMillimeters();
|
|
||||||
dl("Range: "); dln(*measurement);
|
|
||||||
|
|
||||||
return *measurement <= Config::HeightMeasurementMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t reference = 0;
|
|
||||||
uint8_t closeCount = 0;
|
|
||||||
uint16_t measurement;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (heightSensorGetRange(&measurement))
|
|
||||||
{
|
|
||||||
initSequenceDisplayHeight(measurement);
|
|
||||||
|
|
||||||
if (abs(measurement - reference) <= Config::HeightMeasurementDeltaStable)
|
|
||||||
closeCount++;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reference = measurement;
|
|
||||||
closeCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
initSequenceDisplayHeight(0);
|
|
||||||
|
|
||||||
reference = 0;
|
|
||||||
closeCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closeCount < Config::HeightMeasurementDeltaStableCount)
|
|
||||||
delay(500);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
initSequenceSuccess(InitSequenceStep::HeightSensorTest);
|
|
||||||
return reference;
|
|
||||||
|
|
||||||
*/
|
|
@ -7,19 +7,20 @@
|
|||||||
|
|
||||||
enum class ControlUpdateResult
|
enum class ControlUpdateResult
|
||||||
{
|
{
|
||||||
Idle = 0,
|
Idle,
|
||||||
Moving = 1,
|
Stabilizing,
|
||||||
TargetReached = 2,
|
Moving,
|
||||||
SensorError = 3,
|
TargetReached,
|
||||||
OverCurrent = 4
|
SensorError,
|
||||||
|
Overcurrent
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum class MoveDirection
|
enum class MoveDirection
|
||||||
{
|
{
|
||||||
None = 0,
|
None,
|
||||||
Up = 1,
|
Up,
|
||||||
Down = 2
|
Down
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -34,8 +35,7 @@ class ControlManager
|
|||||||
void stabilizeStart();
|
void stabilizeStart();
|
||||||
bool stabilized();
|
bool stabilized();
|
||||||
|
|
||||||
void movePrepare(uint16_t height);
|
void moveStart(uint16_t height);
|
||||||
bool moveStart();
|
|
||||||
void moveStop();
|
void moveStop();
|
||||||
|
|
||||||
void snapToPreset();
|
void snapToPreset();
|
||||||
@ -48,18 +48,26 @@ class ControlManager
|
|||||||
|
|
||||||
|
|
||||||
uint16_t getCurrentHeight() { return this->currentHeight; }
|
uint16_t getCurrentHeight() { return this->currentHeight; }
|
||||||
|
uint16_t getLastMeasurement() { return this->lastMeasurement; }
|
||||||
MoveDirection getMoveDirection() { return this->moveDirection; }
|
MoveDirection getMoveDirection() { return this->moveDirection; }
|
||||||
uint16_t getMoveTarget() { return this->moveTarget; }
|
uint16_t getMoveTarget() { return this->moveTarget; }
|
||||||
|
bool getIsStabilizing() { return this->stabilizationStart != 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool targetReached();
|
||||||
|
|
||||||
VL53L0X heightSensor = VL53L0X();
|
VL53L0X heightSensor = VL53L0X();
|
||||||
uint16_t currentHeight;
|
uint16_t currentHeight;
|
||||||
|
uint16_t lastMeasurement = 0;
|
||||||
|
uint32_t lastValidMeasurement = 0;
|
||||||
|
|
||||||
MoveDirection moveDirection;
|
MoveDirection moveDirection;
|
||||||
uint16_t moveTarget;
|
uint16_t moveTarget;
|
||||||
|
|
||||||
bool stabilizing = false;
|
uint32_t stabilizationStart = 0;
|
||||||
uint32_t lastValidMeasurement = 0;
|
uint8_t stabilizeCount = 0;
|
||||||
|
uint16_t stabilizeTarget = 0;
|
||||||
|
uint32_t stabilizationLastCheck = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
#define SerialDebug
|
#define DebugLog
|
||||||
|
//#define VerboseLog
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DebugLog
|
||||||
#ifdef SerialDebug
|
#define DebugInit() Serial.begin(115200)
|
||||||
#define DebugInit() Serial.begin(9600)
|
|
||||||
#define dl(value) Serial.print(value)
|
#define dl(value) Serial.print(value)
|
||||||
#define dln(value) Serial.println(value)
|
#define dln(value) Serial.println(value)
|
||||||
#else
|
#else
|
||||||
@ -18,4 +18,13 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef VerboseLog
|
||||||
|
#define vl(value) Serial.print(value)
|
||||||
|
#define vln(value) Serial.println(value)
|
||||||
|
#else
|
||||||
|
#define vl(value)
|
||||||
|
#define vln(value)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -31,9 +31,9 @@ void motorStop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool motorIsOverCurrent()
|
bool motorIsOvercurrent()
|
||||||
{
|
{
|
||||||
// TODO: implement motorIsOverCurrent
|
// TODO: implement motorIsOvercurrent
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
// Low-level functions to control the motor
|
// Low-level functions to control the motor
|
||||||
enum class MotorDirection
|
enum class MotorDirection
|
||||||
{
|
{
|
||||||
Up = 0,
|
Up,
|
||||||
Down = 1
|
Down
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern void motorInit();
|
extern void motorInit();
|
||||||
extern void motorStart(MotorDirection direction);
|
extern void motorStart(MotorDirection direction);
|
||||||
extern void motorStop();
|
extern void motorStop();
|
||||||
extern bool motorIsOverCurrent();
|
extern bool motorIsOvercurrent();
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -3,33 +3,33 @@
|
|||||||
#include "include/metrics.h"
|
#include "include/metrics.h"
|
||||||
|
|
||||||
|
|
||||||
Adafruit_GFX* BaseScreen::getDisplay()
|
|
||||||
{
|
|
||||||
return this->screenManager->getDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t BaseScreen::printCentered(const char* text, int16_t y)
|
uint16_t BaseScreen::printCentered(const char* text, int16_t y)
|
||||||
{
|
{
|
||||||
auto display = this->getDisplay();
|
|
||||||
|
|
||||||
int16_t textX;
|
int16_t textX;
|
||||||
int16_t textY;
|
int16_t textY;
|
||||||
uint16_t textW;
|
uint16_t textW;
|
||||||
uint16_t textH;
|
uint16_t textH;
|
||||||
display->getTextBounds(text, 0, 0, &textX, &textY, &textW, &textH);
|
this->display->getTextBounds(text, 0, 0, &textX, &textY, &textW, &textH);
|
||||||
|
|
||||||
textX = (Config::DisplayWidth - textW) / 2;
|
textX = (Config::DisplayWidth - textW) / 2;
|
||||||
display->setCursor(textX, y);
|
this->display->setCursor(textX, y);
|
||||||
display->print(text);
|
this->display->print(text);
|
||||||
|
|
||||||
return textW;
|
return textW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseScreen::drawLargeTextLineCentered(const char* text, int16_t y, uint16_t textColor, uint16_t backgroundColor)
|
||||||
|
{
|
||||||
|
this->display->fillRect(0, y, Config::DisplayWidth, Metrics::LargeTextLineHeight, backgroundColor);
|
||||||
|
this->display->setTextColor(textColor);
|
||||||
|
this->printCentered(text, y + Metrics::LargeTextLineYOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BaseScreen::drawArrowLeft(int16_t x, int16_t y, uint16_t color)
|
void BaseScreen::drawArrowLeft(int16_t x, int16_t y, uint16_t color)
|
||||||
{
|
{
|
||||||
this->getDisplay()->fillTriangle(
|
this->display->fillTriangle(
|
||||||
x + Metrics::HArrowWidth, y, // Top right
|
x + Metrics::HArrowWidth, y, // Top right
|
||||||
x, y + (Metrics::HArrowHeight / 2), // Middle left
|
x, y + (Metrics::HArrowHeight / 2), // Middle left
|
||||||
x + Metrics::HArrowWidth, y + Metrics::HArrowHeight, // Bottom right
|
x + Metrics::HArrowWidth, y + Metrics::HArrowHeight, // Bottom right
|
||||||
@ -37,9 +37,19 @@ void BaseScreen::drawArrowLeft(int16_t x, int16_t y, uint16_t color)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BaseScreen::drawArrowRight(int16_t x, int16_t y, uint16_t color)
|
||||||
|
{
|
||||||
|
this->display->fillTriangle(
|
||||||
|
x, y, // Top left
|
||||||
|
x + + Metrics::HArrowWidth, y + (Metrics::HArrowHeight / 2), // Middle right
|
||||||
|
x, y + Metrics::HArrowHeight, // Bottom left
|
||||||
|
color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BaseScreen::drawArrowUp(int16_t x, int16_t y, uint16_t color)
|
void BaseScreen::drawArrowUp(int16_t x, int16_t y, uint16_t color)
|
||||||
{
|
{
|
||||||
this->getDisplay()->fillTriangle(
|
this->display->fillTriangle(
|
||||||
x + (Metrics::VArrowWidth / 2), y, // Top middle
|
x + (Metrics::VArrowWidth / 2), y, // Top middle
|
||||||
x, y + Metrics::VArrowHeight, // Bottom left
|
x, y + Metrics::VArrowHeight, // Bottom left
|
||||||
x + Metrics::VArrowWidth, y + Metrics::VArrowHeight, // Bottom right
|
x + Metrics::VArrowWidth, y + Metrics::VArrowHeight, // Bottom right
|
||||||
@ -49,7 +59,7 @@ void BaseScreen::drawArrowUp(int16_t x, int16_t y, uint16_t color)
|
|||||||
|
|
||||||
void BaseScreen::drawArrowDown(int16_t x, int16_t y, uint16_t color)
|
void BaseScreen::drawArrowDown(int16_t x, int16_t y, uint16_t color)
|
||||||
{
|
{
|
||||||
this->getDisplay()->fillTriangle(
|
this->display->fillTriangle(
|
||||||
x, y, // Top left
|
x, y, // Top left
|
||||||
x + Metrics::VArrowWidth, y, // Top right
|
x + Metrics::VArrowWidth, y, // Top right
|
||||||
x + (Metrics::VArrowWidth / 2), y + Metrics::VArrowHeight, // Bottom middle
|
x + (Metrics::VArrowWidth / 2), y + Metrics::VArrowHeight, // Bottom middle
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <Adafruit_ST7789.h>
|
#include <Adafruit_ST7789.h>
|
||||||
#include "include/config.h"
|
#include "include/config.h"
|
||||||
|
#include "include/screenids.h"
|
||||||
|
|
||||||
|
|
||||||
class ScreenManager;
|
class ScreenManager;
|
||||||
@ -10,18 +11,19 @@ class ScreenManager;
|
|||||||
|
|
||||||
enum class Button
|
enum class Button
|
||||||
{
|
{
|
||||||
Up = 0,
|
Top,
|
||||||
Menu = 1,
|
Middle,
|
||||||
Down = 2
|
Bottom
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BaseScreen
|
class BaseScreen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BaseScreen(ScreenManager* screenManager)
|
BaseScreen(ScreenManager* screenManager, Adafruit_GFX* display)
|
||||||
{
|
{
|
||||||
this->screenManager = screenManager;
|
this->screenManager = screenManager;
|
||||||
|
this->display = display;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~BaseScreen() {}
|
virtual ~BaseScreen() {}
|
||||||
@ -30,18 +32,20 @@ class BaseScreen
|
|||||||
virtual void onButton(Button button) = 0;
|
virtual void onButton(Button button) = 0;
|
||||||
virtual void onTick() = 0;
|
virtual void onTick() = 0;
|
||||||
|
|
||||||
protected:
|
virtual ScreenId screenId() = 0;
|
||||||
ScreenManager* getScreenManager() { return this->screenManager; }
|
|
||||||
Adafruit_GFX* getDisplay();
|
|
||||||
|
|
||||||
|
protected:
|
||||||
uint16_t printCentered(const char* text, int16_t y);
|
uint16_t printCentered(const char* text, int16_t y);
|
||||||
|
|
||||||
|
void drawLargeTextLineCentered(const char* text, int16_t y, uint16_t textColor, uint16_t backgroundColor);
|
||||||
|
|
||||||
void drawArrowLeft(int16_t x, int16_t y, uint16_t color);
|
void drawArrowLeft(int16_t x, int16_t y, uint16_t color);
|
||||||
|
void drawArrowRight(int16_t x, int16_t y, uint16_t color);
|
||||||
void drawArrowUp(int16_t x, int16_t y, uint16_t color);
|
void drawArrowUp(int16_t x, int16_t y, uint16_t color);
|
||||||
void drawArrowDown(int16_t x, int16_t y, uint16_t color);
|
void drawArrowDown(int16_t x, int16_t y, uint16_t color);
|
||||||
|
|
||||||
private:
|
|
||||||
ScreenManager* screenManager;
|
ScreenManager* screenManager;
|
||||||
|
Adafruit_GFX* display;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -60,7 +64,6 @@ class ScreenManager
|
|||||||
inline void tick() { this->getCurrentScreen()->onTick(); }
|
inline void tick() { this->getCurrentScreen()->onTick(); }
|
||||||
|
|
||||||
inline BaseScreen* getCurrentScreen() { return this->currentScreen; }
|
inline BaseScreen* getCurrentScreen() { return this->currentScreen; }
|
||||||
inline Adafruit_GFX* getDisplay() { return this->display; }
|
|
||||||
|
|
||||||
|
|
||||||
template<class T> void show()
|
template<class T> void show()
|
||||||
@ -71,17 +74,22 @@ class ScreenManager
|
|||||||
delete this->currentScreen;
|
delete this->currentScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->currentScreen = new T(this);
|
this->currentScreen = new T(this, this->display);
|
||||||
this->currentScreen->onShow();
|
this->currentScreen->onShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T> void show(ScreenId onlyIfNotOn)
|
||||||
|
{
|
||||||
|
if (this->currentScreen == nullptr || this->currentScreen->screenId() != onlyIfNotOn)
|
||||||
|
this->show<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void displayOff();
|
void displayOff();
|
||||||
void displayOn();
|
void displayOn();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Adafruit_ST7789* display;
|
Adafruit_ST7789* display;
|
||||||
|
|
||||||
BaseScreen* currentScreen = nullptr;
|
BaseScreen* currentScreen = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,19 +1,205 @@
|
|||||||
#include "./calibrate.h"
|
#include "./calibrate.h"
|
||||||
|
#include "./home.h"
|
||||||
|
#include "include/metrics.h"
|
||||||
|
#include "lib/settings.h"
|
||||||
|
|
||||||
|
|
||||||
void CalibrateScreen::onShow()
|
void CalibrateScreen::onShow()
|
||||||
{
|
{
|
||||||
//auto display = this->getDisplay();
|
this->display->setFont(Metrics::LargeFont);
|
||||||
|
this->display->setTextSize(Metrics::LargeFontTextSize);
|
||||||
|
|
||||||
// TODO: implement CalibrateScreen
|
this->display->fillScreen(Config::ColorHomeBackground);
|
||||||
|
|
||||||
|
this->drawTitle();
|
||||||
|
this->height[CalibrateStepCurrent] = Control.getCurrentHeight() + Settings.Height.Offset;
|
||||||
|
this->height[CalibrateStepMax] = 1969; // TODO: read min/max from settings
|
||||||
|
this->height[CalibrateStepMin] = 0;
|
||||||
|
|
||||||
|
this->drawArrowUp(Metrics::ArrowMargin, Metrics::LargeTextLineHeight + Metrics::LargeTextLineVArrowYOffset, Config::ColorCalibrateIndicators);
|
||||||
|
this->drawArrowRight(Metrics::ArrowMargin, Metrics::MiddleLargeTextLineY + Metrics::LargeTextLineHArrowYOffset, Config::ColorCalibrateIndicators);
|
||||||
|
|
||||||
|
this->display->setTextColor(Config::ColorCalibrateIndicators);
|
||||||
|
this->display->setCursor(Metrics::ArrowMargin, Config::DisplayHeight - Metrics::LargeTextLineHeight + Metrics::LargeTextLineYOffset);
|
||||||
|
this->display->print("OK");
|
||||||
|
|
||||||
|
this->drawSetHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Credit: https://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int
|
||||||
|
uint16_t ipow(uint16_t base, uint8_t exp)
|
||||||
|
{
|
||||||
|
int result = 1;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (exp & 1)
|
||||||
|
result *= base;
|
||||||
|
|
||||||
|
exp >>= 1;
|
||||||
|
if (!exp)
|
||||||
|
break;
|
||||||
|
|
||||||
|
base *= base;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CalibrateScreen::onButton(Button button)
|
void CalibrateScreen::onButton(Button button)
|
||||||
{
|
{
|
||||||
|
switch (button)
|
||||||
|
{
|
||||||
|
case Button::Top:
|
||||||
|
{
|
||||||
|
uint16_t height = this->height[this->step];
|
||||||
|
uint16_t increment = ipow(10, 3 - this->editingDigit);
|
||||||
|
uint16_t modulus = increment * 10;
|
||||||
|
|
||||||
|
uint16_t remainder = height % modulus;
|
||||||
|
uint16_t offset = height - remainder;
|
||||||
|
|
||||||
|
height = offset + ((remainder + increment) % modulus);
|
||||||
|
if (height > 1999)
|
||||||
|
height %= 2000;
|
||||||
|
|
||||||
|
this->height[this->step] = height;
|
||||||
|
this->drawSetHeight();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Button::Middle:
|
||||||
|
{
|
||||||
|
this->editingDigit++;
|
||||||
|
if (this->editingDigit > 3)
|
||||||
|
this->editingDigit = 0;
|
||||||
|
|
||||||
|
this->drawSetHeight();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Button::Bottom:
|
||||||
|
{
|
||||||
|
if (!this->isValidHeight())
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->step = (CalibrateStep)(this->step + 1);
|
||||||
|
if (this->step == CalibrateStepCount)
|
||||||
|
{
|
||||||
|
// TODO: store new settings
|
||||||
|
this->screenManager->show<HomeScreen>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->drawTitle();
|
||||||
|
this->drawSetHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CalibrateScreen::onTick()
|
void CalibrateScreen::onTick()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CalibrateScreen::isValidHeight()
|
||||||
|
{
|
||||||
|
switch (this->step)
|
||||||
|
{
|
||||||
|
case CalibrateStepCurrent:
|
||||||
|
return this->height[CalibrateStepCurrent] >= Control.getCurrentHeight();
|
||||||
|
|
||||||
|
case CalibrateStepMin:
|
||||||
|
return this->height[CalibrateStepMin] <= this->height[CalibrateStepCurrent];
|
||||||
|
|
||||||
|
case CalibrateStepMax:
|
||||||
|
return
|
||||||
|
this->height[CalibrateStepMax] > this->height[CalibrateStepMin] &&
|
||||||
|
this->height[CalibrateStepMax] >= this->height[CalibrateStepCurrent];
|
||||||
|
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CalibrateScreen::drawTitle()
|
||||||
|
{
|
||||||
|
switch (this->step)
|
||||||
|
{
|
||||||
|
case CalibrateStepCurrent:
|
||||||
|
this->drawLargeTextLineCentered("Calibrate", 0, Config::ColorMenuHeaderText, Config::ColorMenuHeaderBackground);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CalibrateStepMin:
|
||||||
|
this->drawLargeTextLineCentered("Minimum", 0, Config::ColorMenuHeaderText, Config::ColorMenuHeaderBackground);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CalibrateStepMax:
|
||||||
|
this->drawLargeTextLineCentered("Maximum", 0, Config::ColorMenuHeaderText, Config::ColorMenuHeaderBackground);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CalibrateScreen::drawSetHeight()
|
||||||
|
{
|
||||||
|
char heightText[7];
|
||||||
|
uint16_t height = this->height[this->step];
|
||||||
|
|
||||||
|
if (height > 999)
|
||||||
|
heightText[0] = '0' + ((height / 1000) % 10);
|
||||||
|
else
|
||||||
|
heightText[0] = '0';
|
||||||
|
|
||||||
|
heightText[1] = '.';
|
||||||
|
heightText[2] = '0' + ((height / 100) % 10);
|
||||||
|
heightText[3] = '0' + ((height / 10) % 10);
|
||||||
|
heightText[4] = '0' + (height % 10);
|
||||||
|
heightText[5] = 'm';
|
||||||
|
heightText[6] = 0;
|
||||||
|
|
||||||
|
|
||||||
|
int16_t textX;
|
||||||
|
int16_t textY;
|
||||||
|
uint16_t textW;
|
||||||
|
uint16_t textH;
|
||||||
|
this->display->getTextBounds(&heightText[0], 0, 0, &textX, &textY, &textW, &textH);
|
||||||
|
textX = (Config::DisplayWidth - textW) / 2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t editingChar = this->editingDigit;
|
||||||
|
|
||||||
|
// Skip the dot
|
||||||
|
if (editingChar > 0)
|
||||||
|
editingChar++;
|
||||||
|
|
||||||
|
|
||||||
|
if (this->lastTextWidth > 0)
|
||||||
|
this->display->fillRect((Config::DisplayWidth - this->lastTextWidth) / 2, Metrics::MiddleLargeTextLineY, this->lastTextWidth, Metrics::LargeTextLineHeight, Config::ColorCalibrateBackground);
|
||||||
|
|
||||||
|
this->lastTextWidth = textW;
|
||||||
|
|
||||||
|
this->display->setTextColor(this->isValidHeight() ? Config::ColorCalibrateValue : Config::ColorCalibrateInvalidValue);
|
||||||
|
this->display->setCursor(textX, Metrics::MiddleLargeTextLineY + Metrics::LargeTextLineYOffset);
|
||||||
|
|
||||||
|
// Draw each character ourselves so we can keep track of where the line should be drawn
|
||||||
|
for (uint8_t i = 0; i < sizeof(heightText); i++)
|
||||||
|
{
|
||||||
|
int16_t cursorStart = this->display->getCursorX();
|
||||||
|
|
||||||
|
this->display->print(heightText[i]);
|
||||||
|
|
||||||
|
if (i == editingChar)
|
||||||
|
this->display->drawFastHLine(cursorStart, Metrics::MiddleLargeTextLineY + Metrics::LargeTextLineHeight - 1, this->display->getCursorX() - cursorStart, Config::ColorCalibrateDigitMarker);
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,21 @@
|
|||||||
#ifndef __screen_calibrate
|
#ifndef __screen_calibrate
|
||||||
#define __screen_calibrate
|
#define __screen_calibrate
|
||||||
|
|
||||||
|
#include "include/screenids.h"
|
||||||
#include "../screen.h"
|
#include "../screen.h"
|
||||||
#include "../control.h"
|
#include "../control.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum CalibrateStep : uint8_t
|
||||||
|
{
|
||||||
|
CalibrateStepCurrent = 0,
|
||||||
|
CalibrateStepMax,
|
||||||
|
CalibrateStepMin,
|
||||||
|
|
||||||
|
CalibrateStepCount
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calibrate screen
|
* Calibrate screen
|
||||||
* Configures the absolute height (calculates the offset) and
|
* Configures the absolute height (calculates the offset) and
|
||||||
@ -13,13 +24,24 @@
|
|||||||
class CalibrateScreen : public BaseScreen
|
class CalibrateScreen : public BaseScreen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CalibrateScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { }
|
CalibrateScreen(ScreenManager* screenManager, Adafruit_GFX* display) : BaseScreen(screenManager, display) { }
|
||||||
|
|
||||||
void onShow();
|
void onShow();
|
||||||
void onButton(Button button);
|
void onButton(Button button);
|
||||||
void onTick();
|
void onTick();
|
||||||
|
|
||||||
|
ScreenId screenId() { return ScreenId::Calibrate; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool isValidHeight();
|
||||||
|
void drawTitle();
|
||||||
|
void drawSetHeight();
|
||||||
|
|
||||||
|
CalibrateStep step = CalibrateStepCurrent;
|
||||||
|
|
||||||
|
uint16_t height[CalibrateStepCount];
|
||||||
|
uint16_t lastTextWidth = 0;
|
||||||
|
uint8_t editingDigit = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "./home.h"
|
#include "./home.h"
|
||||||
#include "./move.h"
|
#include "./move.h"
|
||||||
|
#include "./move-sensorerror.h"
|
||||||
#include "include/config.h"
|
#include "include/config.h"
|
||||||
#include "include/metrics.h"
|
#include "include/metrics.h"
|
||||||
#include "lib/settings.h"
|
#include "lib/settings.h"
|
||||||
@ -13,10 +14,10 @@ void HomeScreen::onShow()
|
|||||||
{
|
{
|
||||||
this->showTime = CurrentTime;
|
this->showTime = CurrentTime;
|
||||||
|
|
||||||
auto display = this->getDisplay();
|
this->display->setFont(Metrics::LargeFont);
|
||||||
|
this->display->setTextSize(Metrics::LargeFontTextSize);
|
||||||
|
|
||||||
display->setFont(Metrics::LargeFont);
|
this->display->fillScreen(Config::ColorHomeBackground);
|
||||||
display->fillScreen(Config::ColorHomeBackground);
|
|
||||||
|
|
||||||
this->drawPreset1();
|
this->drawPreset1();
|
||||||
this->drawMenu();
|
this->drawMenu();
|
||||||
@ -30,33 +31,35 @@ void HomeScreen::onButton(Button button)
|
|||||||
{
|
{
|
||||||
if (this->idle)
|
if (this->idle)
|
||||||
{
|
{
|
||||||
this->getScreenManager()->displayOn();
|
this->screenManager->displayOn();
|
||||||
this->idle = false;
|
this->idle = false;
|
||||||
this->showTime = CurrentTime;
|
this->showTime = CurrentTime;
|
||||||
|
|
||||||
// Preset buttons activate immediately
|
// Preset buttons activate immediately
|
||||||
if (button == Button::Menu)
|
if (button == Button::Middle)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t targetHeight;
|
||||||
|
|
||||||
switch (button)
|
switch (button)
|
||||||
{
|
{
|
||||||
case Button::Up:
|
case Button::Top:
|
||||||
Control.movePrepare(Settings.Height.Preset[0]);
|
targetHeight = Settings.Height.Preset[0];
|
||||||
this->getScreenManager()->show<MoveScreen>();
|
|
||||||
Control.moveStart();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Button::Down:
|
case Button::Bottom:
|
||||||
Control.movePrepare(Settings.Height.Preset[1]);
|
targetHeight = Settings.Height.Preset[1];
|
||||||
this->getScreenManager()->show<MoveScreen>();
|
|
||||||
Control.moveStart();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Button::Menu:
|
case Button::Middle:
|
||||||
this->getScreenManager()->show<MenuScreen>();
|
this->screenManager->show<MenuScreen>();
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Control.moveStart(targetHeight);
|
||||||
|
this->screenManager->show<MoveScreen>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -64,7 +67,7 @@ void HomeScreen::onTick()
|
|||||||
{
|
{
|
||||||
if (!this->idle && CurrentTime - this->showTime >= Config::DisplayIdleTime)
|
if (!this->idle && CurrentTime - this->showTime >= Config::DisplayIdleTime)
|
||||||
{
|
{
|
||||||
this->getScreenManager()->displayOff();
|
this->screenManager->displayOff();
|
||||||
this->idle = true;
|
this->idle = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,13 +87,12 @@ void HomeScreen::drawPreset2()
|
|||||||
|
|
||||||
void HomeScreen::drawNonPresetHeight()
|
void HomeScreen::drawNonPresetHeight()
|
||||||
{
|
{
|
||||||
auto display = this->getDisplay();
|
|
||||||
auto y = Metrics::LargeTextLineHeight;
|
auto y = Metrics::LargeTextLineHeight;
|
||||||
|
|
||||||
if (Control.getCurrentHeight() != Settings.Height.Preset[0] &&
|
if (Control.getCurrentHeight() != Settings.Height.Preset[0] &&
|
||||||
Control.getCurrentHeight() != Settings.Height.Preset[1])
|
Control.getCurrentHeight() != Settings.Height.Preset[1])
|
||||||
{
|
{
|
||||||
display->setTextColor(Config::ColorNonPresetText);
|
this->display->setTextColor(Config::ColorNonPresetText);
|
||||||
this->drawHeight(y, Control.getCurrentHeight());
|
this->drawHeight(y, Control.getCurrentHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,7 +100,6 @@ void HomeScreen::drawNonPresetHeight()
|
|||||||
|
|
||||||
void HomeScreen::drawPreset(int16_t y, uint16_t value)
|
void HomeScreen::drawPreset(int16_t y, uint16_t value)
|
||||||
{
|
{
|
||||||
auto display = this->getDisplay();
|
|
||||||
uint16_t textColor;
|
uint16_t textColor;
|
||||||
uint16_t backgroundColor;
|
uint16_t backgroundColor;
|
||||||
uint16_t arrowColor;
|
uint16_t arrowColor;
|
||||||
@ -117,12 +118,12 @@ void HomeScreen::drawPreset(int16_t y, uint16_t value)
|
|||||||
arrowColor = Config::ColorPresetArrow;
|
arrowColor = Config::ColorPresetArrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
display->fillRect(0, y, Config::DisplayWidth, Metrics::LargeTextLineHeight, backgroundColor);
|
this->display->fillRect(0, y, Config::DisplayWidth, Metrics::LargeTextLineHeight, backgroundColor);
|
||||||
|
|
||||||
if (arrowColor)
|
if (arrowColor)
|
||||||
this->drawArrowLeft(Metrics::ArrowMargin, y + Metrics::LargeTextLineHArrowYOffset, arrowColor);
|
this->drawArrowLeft(Metrics::ArrowMargin, y + Metrics::LargeTextLineHArrowYOffset, arrowColor);
|
||||||
|
|
||||||
display->setTextColor(textColor);
|
this->display->setTextColor(textColor);
|
||||||
this->drawHeight(y, value);
|
this->drawHeight(y, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,10 +139,8 @@ void HomeScreen::drawHeight(int16_t y, uint16_t value)
|
|||||||
|
|
||||||
void HomeScreen::drawMenu()
|
void HomeScreen::drawMenu()
|
||||||
{
|
{
|
||||||
auto display = this->getDisplay();
|
|
||||||
|
|
||||||
this->drawArrowLeft(Metrics::ArrowMargin, Metrics::MiddleLargeTextLineY, Config::ColorHomeMenuArrow);
|
this->drawArrowLeft(Metrics::ArrowMargin, Metrics::MiddleLargeTextLineY, Config::ColorHomeMenuArrow);
|
||||||
|
|
||||||
display->setTextColor(Config::ColorHomeMenuText);
|
this->display->setTextColor(Config::ColorHomeMenuText);
|
||||||
this->printCentered("Menu", Metrics::MiddleLargeTextLineY + Metrics::LargeTextLineYOffset);
|
this->printCentered("Menu", Metrics::MiddleLargeTextLineY + Metrics::LargeTextLineYOffset);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef __screen_home
|
#ifndef __screen_home
|
||||||
#define __screen_home
|
#define __screen_home
|
||||||
|
|
||||||
|
#include "include/screenids.h"
|
||||||
#include "../screen.h"
|
#include "../screen.h"
|
||||||
#include "../Control.h"
|
#include "../Control.h"
|
||||||
|
|
||||||
@ -12,12 +13,14 @@
|
|||||||
class HomeScreen : public BaseScreen
|
class HomeScreen : public BaseScreen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HomeScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { }
|
HomeScreen(ScreenManager* screenManager, Adafruit_GFX* display) : BaseScreen(screenManager, display) { }
|
||||||
|
|
||||||
void onShow();
|
void onShow();
|
||||||
void onButton(Button button);
|
void onButton(Button button);
|
||||||
void onTick();
|
void onTick();
|
||||||
|
|
||||||
|
ScreenId screenId() { return ScreenId::Home; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t showTime = 0;
|
uint32_t showTime = 0;
|
||||||
bool idle = false;
|
bool idle = false;
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
void ManualScreen::onShow()
|
void ManualScreen::onShow()
|
||||||
{
|
{
|
||||||
//auto display = this->getDisplay();
|
|
||||||
|
|
||||||
// TODO: implement ManualScreen
|
// TODO: implement ManualScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef __screen_manual
|
#ifndef __screen_manual
|
||||||
#define __screen_manual
|
#define __screen_manual
|
||||||
|
|
||||||
|
#include "include/screenids.h"
|
||||||
#include "../screen.h"
|
#include "../screen.h"
|
||||||
#include "../Control.h"
|
#include "../Control.h"
|
||||||
|
|
||||||
@ -12,12 +13,14 @@
|
|||||||
class ManualScreen : public BaseScreen
|
class ManualScreen : public BaseScreen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ManualScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { }
|
ManualScreen(ScreenManager* screenManager, Adafruit_GFX* display) : BaseScreen(screenManager, display) { }
|
||||||
|
|
||||||
void onShow();
|
void onShow();
|
||||||
void onButton(Button button);
|
void onButton(Button button);
|
||||||
void onTick();
|
void onTick();
|
||||||
|
|
||||||
|
ScreenId screenId() { return ScreenId::Manual; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
void MenuScreen::onShow()
|
void MenuScreen::onShow()
|
||||||
{
|
{
|
||||||
//auto display = this->getDisplay();
|
|
||||||
|
|
||||||
// TODO: implement MenuScreen
|
// TODO: implement MenuScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef __screen_menu
|
#ifndef __screen_menu
|
||||||
#define __screen_menu
|
#define __screen_menu
|
||||||
|
|
||||||
|
#include "include/screenids.h"
|
||||||
#include "../screen.h"
|
#include "../screen.h"
|
||||||
#include "../Control.h"
|
#include "../Control.h"
|
||||||
|
|
||||||
@ -13,12 +14,14 @@
|
|||||||
class MenuScreen : public BaseScreen
|
class MenuScreen : public BaseScreen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MenuScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { }
|
MenuScreen(ScreenManager* screenManager, Adafruit_GFX* display) : BaseScreen(screenManager, display) { }
|
||||||
|
|
||||||
void onShow();
|
void onShow();
|
||||||
void onButton(Button button);
|
void onButton(Button button);
|
||||||
void onTick();
|
void onTick();
|
||||||
|
|
||||||
|
ScreenId screenId() { return ScreenId::Menu; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
#include "./move-overcurrent.h"
|
#include "./move-overcurrent.h"
|
||||||
|
|
||||||
|
|
||||||
void MoveOverCurrentScreen::onShow()
|
void MoveOvercurrentScreen::onShow()
|
||||||
{
|
{
|
||||||
//auto display = this->getDisplay();
|
// TODO: implement MoveOvercurrentScreen
|
||||||
|
|
||||||
// TODO: implement MoveOverCurrentScreen
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MoveOverCurrentScreen::onButton(Button button)
|
void MoveOvercurrentScreen::onButton(Button button)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MoveOverCurrentScreen::onTick()
|
void MoveOvercurrentScreen::onTick()
|
||||||
{
|
{
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef __screen_move_overcurrent
|
#ifndef __screen_move_overcurrent
|
||||||
#define __screen_move_overcurrent
|
#define __screen_move_overcurrent
|
||||||
|
|
||||||
|
#include "include/screenids.h"
|
||||||
#include "../screen.h"
|
#include "../screen.h"
|
||||||
#include "../Control.h"
|
#include "../Control.h"
|
||||||
|
|
||||||
@ -9,15 +10,17 @@
|
|||||||
* Move overcurrent screen
|
* Move overcurrent screen
|
||||||
* Displays a warning that the motor driver has reached the set maximum current.
|
* Displays a warning that the motor driver has reached the set maximum current.
|
||||||
*/
|
*/
|
||||||
class MoveOverCurrentScreen : public BaseScreen
|
class MoveOvercurrentScreen : public BaseScreen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MoveOverCurrentScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { }
|
MoveOvercurrentScreen(ScreenManager* screenManager, Adafruit_GFX* display) : BaseScreen(screenManager, display) { }
|
||||||
|
|
||||||
void onShow();
|
void onShow();
|
||||||
void onButton(Button button);
|
void onButton(Button button);
|
||||||
void onTick();
|
void onTick();
|
||||||
|
|
||||||
|
ScreenId screenId() { return ScreenId::MoveOvercurrent; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "./move-sensorerror.h"
|
#include "./move-sensorerror.h"
|
||||||
|
#include "./home.h"
|
||||||
#include "include/config.h"
|
#include "include/config.h"
|
||||||
#include "include/metrics.h"
|
#include "include/metrics.h"
|
||||||
#include "lib/control.h"
|
#include "lib/control.h"
|
||||||
@ -7,15 +8,21 @@
|
|||||||
|
|
||||||
void MoveSensorErrorScreen::onShow()
|
void MoveSensorErrorScreen::onShow()
|
||||||
{
|
{
|
||||||
auto display = this->getDisplay();
|
|
||||||
auto y = Metrics::LargeTextLineHeight + Metrics::LargeTextLineYOffset;
|
auto y = Metrics::LargeTextLineHeight + Metrics::LargeTextLineYOffset;
|
||||||
|
|
||||||
display->setFont(Metrics::LargeFont);
|
this->display->fillScreen(Config::ColorErrorBackground);
|
||||||
display->setTextColor(Config::ColorMoveErrorText);
|
|
||||||
|
|
||||||
|
this->display->setFont(Metrics::LargeFont);
|
||||||
|
this->display->setTextSize(Metrics::LargeFontTextSize);
|
||||||
|
|
||||||
|
this->display->setTextColor(Config::ColorErrorText);
|
||||||
this->printCentered("ERROR", y);
|
this->printCentered("ERROR", y);
|
||||||
y += Metrics::LargeTextLineHeight;
|
y += Metrics::LargeTextLineHeight;
|
||||||
|
|
||||||
display->setFont(Metrics::SmallFont);
|
this->display->setFont(Metrics::SmallFont);
|
||||||
|
this->display->setTextSize(Metrics::SmallFontTextSize);
|
||||||
|
|
||||||
this->printCentered("height sensor failed", y);
|
this->printCentered("height sensor failed", y);
|
||||||
y += Metrics::SmallTextLineHeight;
|
y += Metrics::SmallTextLineHeight;
|
||||||
|
|
||||||
@ -24,8 +31,14 @@ void MoveSensorErrorScreen::onShow()
|
|||||||
|
|
||||||
this->currentHeightY = y;
|
this->currentHeightY = y;
|
||||||
|
|
||||||
|
|
||||||
|
this->display->setFont(Metrics::LargeFont);
|
||||||
|
this->display->setTextSize(Metrics::LargeFontTextSize);
|
||||||
|
|
||||||
this->lastRefresh = CurrentTime;
|
this->lastRefresh = CurrentTime;
|
||||||
this->drawCurrentHeight();
|
this->drawLastMeasurement();
|
||||||
|
|
||||||
|
Control.stabilizeStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -36,19 +49,28 @@ void MoveSensorErrorScreen::onButton(Button button)
|
|||||||
|
|
||||||
void MoveSensorErrorScreen::onTick()
|
void MoveSensorErrorScreen::onTick()
|
||||||
{
|
{
|
||||||
|
if (Control.stabilized())
|
||||||
|
{
|
||||||
|
this->screenManager->show<HomeScreen>();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CurrentTime - this->lastRefresh >= Config::DisplayRefreshRate)
|
||||||
|
{
|
||||||
|
this->drawLastMeasurement();
|
||||||
|
this->lastRefresh = CurrentTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MoveSensorErrorScreen::drawCurrentHeight()
|
void MoveSensorErrorScreen::drawLastMeasurement()
|
||||||
{
|
{
|
||||||
auto display = this->getDisplay();
|
|
||||||
|
|
||||||
char currentHeightText[6];
|
char currentHeightText[6];
|
||||||
Control.getDisplayHeight(¤tHeightText[0], Control.getCurrentHeight());
|
Control.getDisplayHeight(¤tHeightText[0], Control.getLastMeasurement());
|
||||||
|
|
||||||
if (this->lastTextWidth > 0)
|
if (this->lastTextWidth > 0)
|
||||||
display->fillRect((Config::DisplayWidth - this->lastTextWidth) / 2, this->currentHeightY, this->lastTextWidth, Metrics::LargeTextLineHeight, Config::ColorMoveBackground);
|
this->display->fillRect((Config::DisplayWidth - this->lastTextWidth) / 2, this->currentHeightY, this->lastTextWidth, Metrics::LargeTextLineHeight, Config::ColorErrorBackground);
|
||||||
|
|
||||||
display->setTextColor(Config::ColorMoveTarget);
|
this->display->setTextColor(Config::ColorMoveTarget);
|
||||||
this->lastTextWidth = this->printCentered(¤tHeightText[0], this->currentHeightY + Metrics::LargeFontBaseline);
|
this->lastTextWidth = this->printCentered(¤tHeightText[0], this->currentHeightY + Metrics::LargeFontBaseline);
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef __screen_move_sensorerror
|
#ifndef __screen_move_sensorerror
|
||||||
#define __screen_move_sensorerror
|
#define __screen_move_sensorerror
|
||||||
|
|
||||||
|
#include "include/screenids.h"
|
||||||
#include "../screen.h"
|
#include "../screen.h"
|
||||||
#include "../Control.h"
|
#include "../Control.h"
|
||||||
|
|
||||||
@ -13,18 +14,20 @@
|
|||||||
class MoveSensorErrorScreen : public BaseScreen
|
class MoveSensorErrorScreen : public BaseScreen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MoveSensorErrorScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { }
|
MoveSensorErrorScreen(ScreenManager* screenManager, Adafruit_GFX* display) : BaseScreen(screenManager, display) { }
|
||||||
|
|
||||||
void onShow();
|
void onShow();
|
||||||
void onButton(Button button);
|
void onButton(Button button);
|
||||||
void onTick();
|
void onTick();
|
||||||
|
|
||||||
|
ScreenId screenId() { return ScreenId::MoveSensorError; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t lastRefresh;
|
uint32_t lastRefresh;
|
||||||
uint8_t currentHeightY;
|
uint8_t currentHeightY;
|
||||||
uint16_t lastTextWidth = 0;
|
uint16_t lastTextWidth = 0;
|
||||||
|
|
||||||
void drawCurrentHeight();
|
void drawLastMeasurement();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,25 +9,28 @@
|
|||||||
|
|
||||||
void MoveScreen::onShow()
|
void MoveScreen::onShow()
|
||||||
{
|
{
|
||||||
auto display = this->getDisplay();
|
|
||||||
auto startY = Metrics::LargeTextLineHeight;
|
auto startY = Metrics::LargeTextLineHeight;
|
||||||
auto arrowY = startY + Metrics::LargeTextLineHeight + Metrics::LargeTextLineVArrowYOffset;
|
auto arrowY = startY + Metrics::LargeTextLineHeight + Metrics::LargeTextLineVArrowYOffset;
|
||||||
auto arrowX = (Config::DisplayWidth - Metrics::VArrowWidth) / 2;
|
auto arrowX = (Config::DisplayWidth - Metrics::VArrowWidth) / 2;
|
||||||
auto stopY = Config::DisplayHeight - Metrics::LargeTextLineHeight;
|
auto stopY = Config::DisplayHeight - Metrics::LargeTextLineHeight;
|
||||||
|
|
||||||
display->fillScreen(Config::ColorMoveBackground);
|
this->display->fillScreen(Config::ColorMoveBackground);
|
||||||
|
|
||||||
// Stop
|
// Stop
|
||||||
display->setFont(Metrics::SmallFont);
|
this->display->setFont(Metrics::SmallFont);
|
||||||
display->setTextColor(Config::ColorMoveStop);
|
this->display->setTextSize(Metrics::SmallFontTextSize);
|
||||||
|
|
||||||
|
this->display->setTextColor(Config::ColorMoveStop);
|
||||||
this->printCentered("Press any button to", stopY - Metrics::SmallTextLineHeight);
|
this->printCentered("Press any button to", stopY - Metrics::SmallTextLineHeight);
|
||||||
|
|
||||||
display->setFont(Metrics::LargeFont);
|
this->display->setFont(Metrics::LargeFont);
|
||||||
|
this->display->setTextSize(Metrics::LargeFontTextSize);
|
||||||
|
|
||||||
this->printCentered("STOP", stopY + Metrics::LargeTextLineYOffset);
|
this->printCentered("STOP", stopY + Metrics::LargeTextLineYOffset);
|
||||||
|
|
||||||
char targetHeightText[6];
|
char targetHeightText[6];
|
||||||
Control.getDisplayHeight(&targetHeightText[0], Control.getMoveTarget());
|
Control.getDisplayHeight(&targetHeightText[0], Control.getMoveTarget());
|
||||||
display->setTextColor(Config::ColorMoveCurrent);
|
this->display->setTextColor(Config::ColorMoveCurrent);
|
||||||
|
|
||||||
// Target and arrow
|
// Target and arrow
|
||||||
if (Control.getMoveDirection() == MoveDirection::Up)
|
if (Control.getMoveDirection() == MoveDirection::Up)
|
||||||
@ -53,32 +56,37 @@ void MoveScreen::onShow()
|
|||||||
void MoveScreen::onButton(Button button)
|
void MoveScreen::onButton(Button button)
|
||||||
{
|
{
|
||||||
Control.moveStop();
|
Control.moveStop();
|
||||||
this->getScreenManager()->show<HomeScreen>();
|
this->screenManager->show<HomeScreen>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MoveScreen::onTick()
|
void MoveScreen::onTick()
|
||||||
{
|
{
|
||||||
|
bool isStabilizing = Control.getIsStabilizing();
|
||||||
|
|
||||||
// Don't update every tick, monitoring the current height is more
|
// Don't update every tick, monitoring the current height is more
|
||||||
// important and the flicker would be unpleasant as well.
|
// important and the flicker would be unpleasant as well.
|
||||||
if (CurrentTime - this->lastRefresh >= Config::DisplayMoveRefreshRate)
|
if (this->lastIsStabilizing != isStabilizing || CurrentTime - this->lastRefresh >= Config::DisplayRefreshRate)
|
||||||
{
|
{
|
||||||
this->drawCurrentHeight();
|
this->drawCurrentHeight();
|
||||||
this->lastRefresh = CurrentTime;
|
this->lastRefresh = CurrentTime;
|
||||||
|
this->lastIsStabilizing = isStabilizing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MoveScreen::drawCurrentHeight()
|
void MoveScreen::drawCurrentHeight()
|
||||||
{
|
{
|
||||||
auto display = this->getDisplay();
|
|
||||||
|
|
||||||
char currentHeightText[6];
|
char currentHeightText[6];
|
||||||
|
|
||||||
|
if (Control.getIsStabilizing())
|
||||||
|
Control.getDisplayHeight(¤tHeightText[0], 0);
|
||||||
|
else
|
||||||
Control.getDisplayHeight(¤tHeightText[0], Control.getCurrentHeight());
|
Control.getDisplayHeight(¤tHeightText[0], Control.getCurrentHeight());
|
||||||
|
|
||||||
if (this->lastTextWidth > 0)
|
if (this->lastTextWidth > 0)
|
||||||
display->fillRect((Config::DisplayWidth - this->lastTextWidth) / 2, this->currentHeightY, this->lastTextWidth, Metrics::LargeTextLineHeight, Config::ColorMoveBackground);
|
this->display->fillRect((Config::DisplayWidth - this->lastTextWidth) / 2, this->currentHeightY, this->lastTextWidth, Metrics::LargeTextLineHeight, Config::ColorMoveBackground);
|
||||||
|
|
||||||
display->setTextColor(Config::ColorMoveTarget);
|
this->display->setTextColor(Config::ColorMoveTarget);
|
||||||
this->lastTextWidth = this->printCentered(¤tHeightText[0], this->currentHeightY + Metrics::LargeFontBaseline);
|
this->lastTextWidth = this->printCentered(¤tHeightText[0], this->currentHeightY + Metrics::LargeTextLineYOffset);
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef __screen_move
|
#ifndef __screen_move
|
||||||
#define __screen_move
|
#define __screen_move
|
||||||
|
|
||||||
|
#include "include/screenids.h"
|
||||||
#include "../screen.h"
|
#include "../screen.h"
|
||||||
#include "../Control.h"
|
#include "../Control.h"
|
||||||
|
|
||||||
@ -12,16 +13,19 @@
|
|||||||
class MoveScreen : public BaseScreen
|
class MoveScreen : public BaseScreen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MoveScreen(ScreenManager* screenManager) : BaseScreen(screenManager) { }
|
MoveScreen(ScreenManager* screenManager, Adafruit_GFX* display) : BaseScreen(screenManager, display) { }
|
||||||
|
|
||||||
void onShow();
|
void onShow();
|
||||||
void onButton(Button button);
|
void onButton(Button button);
|
||||||
void onTick();
|
void onTick();
|
||||||
|
|
||||||
|
ScreenId screenId() { return ScreenId::Move; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t lastRefresh;
|
uint32_t lastRefresh;
|
||||||
uint8_t currentHeightY;
|
uint8_t currentHeightY;
|
||||||
uint16_t lastTextWidth = 0;
|
uint16_t lastTextWidth = 0;
|
||||||
|
bool lastIsStabilizing = true;
|
||||||
|
|
||||||
void drawCurrentHeight();
|
void drawCurrentHeight();
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
struct SettingsHeights
|
struct SettingsHeights
|
||||||
{
|
{
|
||||||
uint8_t Offset;
|
uint16_t Offset;
|
||||||
|
uint16_t Minimum;
|
||||||
|
uint16_t Maximum;
|
||||||
uint16_t Preset[2];
|
uint16_t Preset[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// Slightly modified version of https://github.com/pololu/vl53l0x-arduino
|
// Slightly modified version of https://github.com/pololu/vl53l0x-arduino
|
||||||
// which returns an error code if initialization fails.
|
// which returns an error code if initialization fails, and allows for
|
||||||
|
// asynchronous readings.
|
||||||
|
|
||||||
// Most of the functionality of this library is based on the VL53L0X API
|
// Most of the functionality of this library is based on the VL53L0X API
|
||||||
// provided by ST (STSW-IMG005), and some of the explanatory comments are quoted
|
// provided by ST (STSW-IMG005), and some of the explanatory comments are quoted
|
||||||
@ -866,6 +867,89 @@ uint16_t VL53L0X::readRangeSingleMillimeters(void)
|
|||||||
return readRangeContinuousMillimeters();
|
return readRangeContinuousMillimeters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Asynchronous reading - call asyncStartReadSingle to begin a measurement,
|
||||||
|
// then call asyncReadSingle in the loop to determine if a measurement is
|
||||||
|
// available. This will return VL53L0XRangeNotReady if not ready, or VL53L0XRangeTimeout if a timeout occured.
|
||||||
|
void VL53L0X::asyncStartReadRangeSingleMillimeters()
|
||||||
|
{
|
||||||
|
if (asyncReading())
|
||||||
|
return;
|
||||||
|
|
||||||
|
async_state = VL53L0XAsyncStateWaitingForStart;
|
||||||
|
writeReg(0x80, 0x01);
|
||||||
|
writeReg(0xFF, 0x01);
|
||||||
|
writeReg(0x00, 0x00);
|
||||||
|
writeReg(0x91, stop_variable);
|
||||||
|
writeReg(0x00, 0x01);
|
||||||
|
writeReg(0xFF, 0x00);
|
||||||
|
writeReg(0x80, 0x00);
|
||||||
|
|
||||||
|
writeReg(SYSRANGE_START, 0x01);
|
||||||
|
|
||||||
|
// "Wait until start bit has been cleared"
|
||||||
|
startTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t VL53L0X::asyncReadRangeSingleMillimeters()
|
||||||
|
{
|
||||||
|
if (async_state == VL53L0XAsyncStateWaitingForStart)
|
||||||
|
{
|
||||||
|
if (readReg(SYSRANGE_START) & 0x01)
|
||||||
|
{
|
||||||
|
if (checkTimeoutExpired())
|
||||||
|
{
|
||||||
|
did_timeout = true;
|
||||||
|
async_state = VL53L0XAsyncStateNotStarted;
|
||||||
|
return VL53L0XRangeTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VL53L0XRangeNotReady;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startTimeout();
|
||||||
|
async_state = VL53L0XAsyncStateWaitingForStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (async_state == VL53L0XAsyncStateWaitingForStatus)
|
||||||
|
{
|
||||||
|
if ((readReg(RESULT_INTERRUPT_STATUS) & 0x07) == 0)
|
||||||
|
{
|
||||||
|
if (checkTimeoutExpired())
|
||||||
|
{
|
||||||
|
did_timeout = true;
|
||||||
|
async_state = VL53L0XAsyncStateNotStarted;
|
||||||
|
return VL53L0XRangeTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VL53L0XRangeNotReady;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// assumptions: Linearity Corrective Gain is 1000 (default);
|
||||||
|
// fractional ranging is not enabled
|
||||||
|
uint16_t range = readReg16Bit(RESULT_RANGE_STATUS + 10);
|
||||||
|
writeReg(SYSTEM_INTERRUPT_CLEAR, 0x01);
|
||||||
|
|
||||||
|
async_state = VL53L0XAsyncStateNotStarted;
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return VL53L0XRangeNotStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Indicates whether an async read has started, but not yet finished by
|
||||||
|
// calling asyncReadRangleSingleMillimeters.
|
||||||
|
bool VL53L0X::asyncReading()
|
||||||
|
{
|
||||||
|
return (async_state != VL53L0XAsyncStateNotStarted);
|
||||||
|
}
|
||||||
|
|
||||||
// Did a timeout occur in one of the read functions since the last call to
|
// Did a timeout occur in one of the read functions since the last call to
|
||||||
// timeoutOccurred()?
|
// timeoutOccurred()?
|
||||||
bool VL53L0X::timeoutOccurred()
|
bool VL53L0X::timeoutOccurred()
|
||||||
|
@ -9,14 +9,23 @@
|
|||||||
|
|
||||||
enum class VL53L0XInitResult
|
enum class VL53L0XInitResult
|
||||||
{
|
{
|
||||||
Success = 0,
|
Success,
|
||||||
InvalidIdentification = 1,
|
InvalidIdentification,
|
||||||
GetSpadInfoFailed = 2,
|
GetSpadInfoFailed,
|
||||||
VHVCalibrationFailed = 3,
|
VHVCalibrationFailed,
|
||||||
PhaseCalibrationFailed = 4,
|
PhaseCalibrationFailed,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const uint16_t VL53L0XRangeNotStarted = 65533;
|
||||||
|
static const uint16_t VL53L0XRangeNotReady = 65534;
|
||||||
|
static const uint16_t VL53L0XRangeTimeout = 65535;
|
||||||
|
|
||||||
|
static const uint8_t VL53L0XAsyncStateNotStarted = 0;
|
||||||
|
static const uint8_t VL53L0XAsyncStateWaitingForStart = 1;
|
||||||
|
static const uint8_t VL53L0XAsyncStateWaitingForStatus = 2;
|
||||||
|
|
||||||
|
|
||||||
class VL53L0X
|
class VL53L0X
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -141,6 +150,10 @@ class VL53L0X
|
|||||||
uint16_t readRangeContinuousMillimeters(void);
|
uint16_t readRangeContinuousMillimeters(void);
|
||||||
uint16_t readRangeSingleMillimeters(void);
|
uint16_t readRangeSingleMillimeters(void);
|
||||||
|
|
||||||
|
void asyncStartReadRangeSingleMillimeters();
|
||||||
|
uint16_t asyncReadRangeSingleMillimeters();
|
||||||
|
bool asyncReading();
|
||||||
|
|
||||||
inline void setTimeout(uint16_t timeout) { io_timeout = timeout; }
|
inline void setTimeout(uint16_t timeout) { io_timeout = timeout; }
|
||||||
inline uint16_t getTimeout(void) { return io_timeout; }
|
inline uint16_t getTimeout(void) { return io_timeout; }
|
||||||
bool timeoutOccurred(void);
|
bool timeoutOccurred(void);
|
||||||
@ -171,6 +184,8 @@ class VL53L0X
|
|||||||
uint8_t stop_variable; // read by init and used when starting measurement; is StopVariable field of VL53L0X_DevData_t structure in API
|
uint8_t stop_variable; // read by init and used when starting measurement; is StopVariable field of VL53L0X_DevData_t structure in API
|
||||||
uint32_t measurement_timing_budget_us;
|
uint32_t measurement_timing_budget_us;
|
||||||
|
|
||||||
|
uint8_t async_state = VL53L0XAsyncStateNotStarted;
|
||||||
|
|
||||||
bool getSpadInfo(uint8_t * count, bool * type_is_aperture);
|
bool getSpadInfo(uint8_t * count, bool * type_is_aperture);
|
||||||
|
|
||||||
void getSequenceStepEnables(SequenceStepEnables * enables);
|
void getSequenceStepEnables(SequenceStepEnables * enables);
|
||||||
|
70
src/main.cpp
70
src/main.cpp
@ -4,6 +4,7 @@
|
|||||||
#include <Bounce2.h>
|
#include <Bounce2.h>
|
||||||
|
|
||||||
#include "./include/config.h"
|
#include "./include/config.h"
|
||||||
|
#include "./include/screenids.h"
|
||||||
#include "./lib/debug.h"
|
#include "./lib/debug.h"
|
||||||
#include "./lib/settings.h"
|
#include "./lib/settings.h"
|
||||||
#include "./lib/screen.h"
|
#include "./lib/screen.h"
|
||||||
@ -21,8 +22,8 @@
|
|||||||
enum class InitSequenceStep
|
enum class InitSequenceStep
|
||||||
{
|
{
|
||||||
EEPROM = 0,
|
EEPROM = 0,
|
||||||
HeightSensorInit = 1,
|
HeightSensorInit,
|
||||||
HeightSensorTest = 2,
|
HeightSensorTest,
|
||||||
|
|
||||||
Last = HeightSensorTest
|
Last = HeightSensorTest
|
||||||
};
|
};
|
||||||
@ -30,7 +31,7 @@ enum class InitSequenceStep
|
|||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
inline void setupHeightSensor();
|
inline void setupHeightSensor();
|
||||||
inline uint16_t testHeightSensor();
|
inline void testHeightSensor();
|
||||||
|
|
||||||
void initSequenceStart();
|
void initSequenceStart();
|
||||||
void initSequenceSuccess(InitSequenceStep step);
|
void initSequenceSuccess(InitSequenceStep step);
|
||||||
@ -45,6 +46,7 @@ auto screenManager = ScreenManager(&display);
|
|||||||
Bounce buttons[3];
|
Bounce buttons[3];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Setup
|
Setup
|
||||||
@ -53,11 +55,11 @@ Bounce buttons[3];
|
|||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
DebugInit();
|
DebugInit();
|
||||||
dln("Debug log active");
|
dln("[ MAIN ] Debug log started");
|
||||||
|
|
||||||
buttons[0].attach(Config::ButtonPinUp, INPUT_PULLUP);
|
buttons[0].attach(Config::ButtonPinTop, INPUT_PULLUP);
|
||||||
buttons[1].attach(Config::ButtonPinMenu, INPUT_PULLUP);
|
buttons[1].attach(Config::ButtonPinMiddle, INPUT_PULLUP);
|
||||||
buttons[2].attach(Config::ButtonPinDown, INPUT_PULLUP);
|
buttons[2].attach(Config::ButtonPinBottom, INPUT_PULLUP);
|
||||||
|
|
||||||
display.init(Config::DisplayWidth, Config::DisplayHeight, SPI_MODE3);
|
display.init(Config::DisplayWidth, Config::DisplayHeight, SPI_MODE3);
|
||||||
display.setRotation(Config::DisplayRotation);
|
display.setRotation(Config::DisplayRotation);
|
||||||
@ -73,8 +75,10 @@ void setup()
|
|||||||
|
|
||||||
|
|
||||||
// Initialize VL53L0X sensor
|
// Initialize VL53L0X sensor
|
||||||
|
CurrentTime = millis();
|
||||||
|
|
||||||
setupHeightSensor();
|
setupHeightSensor();
|
||||||
auto currentHeight = testHeightSensor();
|
testHeightSensor();
|
||||||
|
|
||||||
initSequenceEnd();
|
initSequenceEnd();
|
||||||
|
|
||||||
@ -84,7 +88,6 @@ void setup()
|
|||||||
|
|
||||||
if (initialized)
|
if (initialized)
|
||||||
{
|
{
|
||||||
// Control.getCurrentHeight() = currentHeight;
|
|
||||||
Control.snapToPreset();
|
Control.snapToPreset();
|
||||||
|
|
||||||
screenManager.show<HomeScreen>();
|
screenManager.show<HomeScreen>();
|
||||||
@ -135,8 +138,26 @@ inline void setupHeightSensor()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline uint16_t testHeightSensor()
|
inline void testHeightSensor()
|
||||||
{
|
{
|
||||||
|
Control.stabilizeStart();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (Control.update() != ControlUpdateResult::SensorError)
|
||||||
|
{
|
||||||
|
initSequenceDisplayHeight(Control.getCurrentHeight());
|
||||||
|
|
||||||
|
if (Control.stabilized())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
initSequenceDisplayHeight(0);
|
||||||
|
|
||||||
|
CurrentTime = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
initSequenceSuccess(InitSequenceStep::HeightSensorTest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -158,11 +179,11 @@ void loop()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ControlUpdateResult::SensorError:
|
case ControlUpdateResult::SensorError:
|
||||||
screenManager.show<MoveSensorErrorScreen>();
|
screenManager.show<MoveSensorErrorScreen>(ScreenId::MoveSensorError);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ControlUpdateResult::OverCurrent:
|
case ControlUpdateResult::Overcurrent:
|
||||||
screenManager.show<MoveOverCurrentScreen>();
|
screenManager.show<MoveOvercurrentScreen>(ScreenId::MoveOvercurrent);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -174,21 +195,28 @@ void loop()
|
|||||||
buttons[1].update();
|
buttons[1].update();
|
||||||
buttons[2].update();
|
buttons[2].update();
|
||||||
|
|
||||||
|
if (buttons[0].fell())
|
||||||
|
{
|
||||||
|
dln("[ MAIN ] Button pressed: Top");
|
||||||
|
screenManager.button(Button::Top);
|
||||||
|
}
|
||||||
|
|
||||||
if (buttons[0].rose())
|
if (buttons[1].fell())
|
||||||
screenManager.button(Button::Up);
|
{
|
||||||
|
dln("[ MAIN ] Button pressed: Middle");
|
||||||
|
screenManager.button(Button::Middle);
|
||||||
|
}
|
||||||
|
|
||||||
if (buttons[1].rose())
|
if (buttons[2].fell())
|
||||||
screenManager.button(Button::Menu);
|
{
|
||||||
|
dln("[ MAIN ] Button pressed: Bottom");
|
||||||
if (buttons[2].rose())
|
screenManager.button(Button::Bottom);
|
||||||
screenManager.button(Button::Down);
|
}
|
||||||
|
|
||||||
screenManager.tick();
|
screenManager.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Helper functions for the status display during the initialization sequence
|
Helper functions for the status display during the initialization sequence
|
||||||
|
Loading…
Reference in New Issue
Block a user