25 changed files with 2751 additions and 0 deletions
			
			
		- 
					336ascii_memory/ascii_memory.ino
- 
					49libraries/AT23C32/AT24C32.cpp
- 
					28libraries/AT23C32/AT24C32.h
- 
					33libraries/Button/Button.cpp
- 
					20libraries/Button/Button.h
- 
					406libraries/DS3231/DS3231.cpp
- 
					133libraries/DS3231/DS3231.h
- 
					128libraries/States/ControlColorState.cpp
- 
					77libraries/States/ControlDateState.cpp
- 
					26libraries/States/ControlSecondsState.cpp
- 
					130libraries/States/ControlStates.h
- 
					62libraries/States/ControlTextState..cpp
- 
					82libraries/States/ControlTimeState.cpp
- 
					92libraries/States/ControlViewState.cpp
- 
					50libraries/States/States.h
- 
					96libraries/States/ViewDateState.cpp
- 
					76libraries/States/ViewLEDState.cpp
- 
					11libraries/States/ViewRemoteState.cpp
- 
					28libraries/States/ViewSecondsState.cpp
- 
					29libraries/States/ViewState.cpp
- 
					142libraries/States/ViewStates.h
- 
					28libraries/States/ViewTemperatureState.cpp
- 
					85libraries/States/ViewTextState.cpp
- 
					219libraries/States/ViewTimeState.cpp
- 
					385wordclock.ino
| @ -0,0 +1,336 @@ | |||
| #include <Wire.h>
 | |||
| 
 | |||
| #include <AT24C32.h>
 | |||
| 
 | |||
| // init extended ascii font [https://github.com/ecraven/g13/blob/815e0001cb5e24a184186506d2c95f4171e48547/g13_fonts.cc]
 | |||
| // other font: [https://github.com/AdamCDunlap/arduino/blob/940c9db5cbeb55ffcba3661697cf0495dd54f8c2/libraries/LEDArray/includes/characters.h]
 | |||
| // other font: [https://github.com/basti79/LCD-fonts/blob/master/5x8_vertikal_LSB_1.h]
 | |||
| uint8_t ascii_font[256][5] = { | |||
|     {0x00, 0x00, 0x00, 0x00, 0x00}, // 0x00
 | |||
|     {0x1E, 0x35, 0x31, 0x35, 0x1E}, // 0x01
 | |||
|     {0x1E, 0x35, 0x37, 0x35, 0x1E}, // 0x02
 | |||
|     {0x0E, 0x1F, 0x3E, 0x1F, 0x0E}, // 0x03
 | |||
|     {0x08, 0x1C, 0x7F, 0x1C, 0x08}, // 0x04
 | |||
|     {0x18, 0x4A, 0x7F, 0x4A, 0x18}, // 0x05
 | |||
|     {0x1C, 0x4E, 0x7F, 0x4E, 0x1C}, // 0x06
 | |||
|     {0x00, 0x00, 0x00, 0x00, 0x00}, // 0x07
 | |||
|     {0x00, 0x00, 0x00, 0x00, 0x00}, // 0x08
 | |||
|     {0x00, 0x00, 0x00, 0x00, 0x00}, // 0x09
 | |||
|     {0x00, 0x00, 0x00, 0x00, 0x00}, // 0x0A
 | |||
|     {0x38, 0x44, 0x44, 0x47, 0x3B}, // 0x0B
 | |||
|     {0x0E, 0x51, 0xF1, 0x51, 0x0E}, // 0x0C
 | |||
|     {0x00, 0x00, 0x00, 0x00, 0x00}, // 0x0D
 | |||
|     {0x60, 0x7E, 0x02, 0x33, 0x3F}, // 0x0E
 | |||
|     {0x2A, 0x1C, 0x36, 0x1C, 0x2A}, // 0x0F
 | |||
|     {0x3E, 0x1C, 0x1C, 0x08, 0x08}, // 0x10
 | |||
|     {0x08, 0x08, 0x1C, 0x1C, 0x3E}, // 0x11
 | |||
|     {0x00, 0x22, 0x7F, 0x22, 0x00}, // 0x12
 | |||
|     {0x00, 0x2E, 0x00, 0x2E, 0x00}, // 0x13
 | |||
|     {0x06, 0x7F, 0x01, 0x7F, 0x00}, // 0x14
 | |||
|     {0x00, 0x4A, 0x55, 0x29, 0x00}, // 0x15
 | |||
|     {0x00, 0x18, 0x18, 0x18, 0x18}, // 0x16
 | |||
|     {0x00, 0x4A, 0x5F, 0x4A, 0x00}, // 0x17
 | |||
|     {0x00, 0x02, 0x7F, 0x02, 0x00}, // 0x18
 | |||
|     {0x00, 0x20, 0x7F, 0x20, 0x00}, // 0x19
 | |||
|     {0x00, 0x08, 0x08, 0x1C, 0x08}, // 0x1A
 | |||
|     {0x00, 0x08, 0x1C, 0x08, 0x08}, // 0x1B
 | |||
|     {0x00, 0x3C, 0x20, 0x20, 0x20}, // 0x1C
 | |||
|     {0x08, 0x1C, 0x08, 0x1C, 0x08}, // 0x1D
 | |||
|     {0x20, 0x38, 0x3E, 0x38, 0x20}, // 0x1E
 | |||
|     {0x02, 0x0E, 0x3E, 0x0E, 0x02}, // 0x1F
 | |||
|     {0x00, 0x00, 0x00, 0x00, 0x00}, // 0x20 (Space)
 | |||
|     {0x00, 0x00, 0x9E, 0x00, 0x00}, // 0x21 !
 | |||
|     {0x00, 0x0E, 0x00, 0x0E, 0x00}, // 0x22 "
 | |||
|     {0x28, 0xFE, 0x28, 0xFE, 0x28}, // 0x23 #
 | |||
|     {0x48, 0x54, 0xFE, 0x54, 0x24}, // 0x24 $
 | |||
|     {0x46, 0x26, 0x10, 0xC8, 0xC4}, // 0x25 %
 | |||
|     {0x6C, 0x92, 0xAA, 0x44, 0xA0}, // 0x26 &
 | |||
|     {0x00, 0x0A, 0x06, 0x00, 0x00}, // 0x27 '
 | |||
|     {0x00, 0x38, 0x44, 0x82, 0x00}, // 0x28 (
 | |||
|     {0x00, 0x82, 0x44, 0x38, 0x00}, // 0x29 )
 | |||
|     {0x10, 0x54, 0x38, 0x54, 0x10}, // 0x2A *
 | |||
|     {0x10, 0x10, 0x7C, 0x10, 0x10}, // 0x2B +
 | |||
|     {0x00, 0xA0, 0x60, 0x00, 0x00}, // 0x2C ,
 | |||
|     {0x10, 0x10, 0x10, 0x10, 0x10}, // 0x2D -
 | |||
|     {0x00, 0x60, 0x60, 0x00, 0x00}, // 0x2E .
 | |||
|     {0x40, 0x20, 0x10, 0x08, 0x04}, // 0x2F /
 | |||
|     {0x7C, 0xA2, 0x92, 0x8A, 0x7C}, // 0x30 0
 | |||
|     {0x00, 0x84, 0xFE, 0x80, 0x00}, // 0x31 1
 | |||
|     {0x84, 0xC2, 0xA2, 0x92, 0x8C}, // 0x32 2
 | |||
|     {0x42, 0x82, 0x8A, 0x96, 0x62}, // 0x33 3
 | |||
|     {0x30, 0x28, 0x24, 0xFE, 0x20}, // 0x34 4
 | |||
|     {0x4E, 0x8A, 0x8A, 0x8A, 0x72}, // 0x35 5
 | |||
|     {0x78, 0x94, 0x92, 0x92, 0x60}, // 0x36 6
 | |||
|     {0x02, 0xE2, 0x12, 0x0A, 0x06}, // 0x37 7
 | |||
|     {0x6C, 0x92, 0x92, 0x92, 0x6C}, // 0x38 8
 | |||
|     {0x0C, 0x92, 0x92, 0x52, 0x3C}, // 0x39 9
 | |||
|     {0x00, 0x6C, 0x6C, 0x00, 0x00}, // 0x3A :
 | |||
|     {0x00, 0xAC, 0x6C, 0x00, 0x00}, // 0x3B ;
 | |||
|     {0x00, 0x10, 0x28, 0x44, 0x82}, // 0x3C <
 | |||
|     {0x28, 0x28, 0x28, 0x28, 0x28}, // 0x3D =
 | |||
|     {0x82, 0x44, 0x28, 0x10, 0x00}, // 0x3E >
 | |||
|     {0x04, 0x02, 0xA2, 0x12, 0x0C}, // 0x3F ?
 | |||
|     {0x64, 0x92, 0xF2, 0x82, 0x7C}, // 0x40 @
 | |||
|     {0xFC, 0x22, 0x22, 0x22, 0xFC}, // 0x41 A
 | |||
|     {0xFE, 0x92, 0x92, 0x92, 0x6C}, // 0x42 B
 | |||
|     {0x7C, 0x82, 0x82, 0x82, 0x44}, // 0x43 C
 | |||
|     {0xFE, 0x82, 0x82, 0x44, 0x38}, // 0x44 D
 | |||
|     {0xFE, 0x92, 0x92, 0x92, 0x82}, // 0x45 E
 | |||
|     {0xFE, 0x12, 0x12, 0x02, 0x02}, // 0x46 F
 | |||
|     {0x7C, 0x82, 0x82, 0xA2, 0x64}, // 0x47 G
 | |||
|     {0xFE, 0x10, 0x10, 0x10, 0xFE}, // 0x48 H
 | |||
|     {0x00, 0x82, 0xFE, 0x82, 0x00}, // 0x49 I
 | |||
|     {0x40, 0x80, 0x82, 0x7E, 0x02}, // 0x4A J
 | |||
|     {0xFE, 0x10, 0x28, 0x44, 0x82}, // 0x4B K
 | |||
|     {0xFE, 0x80, 0x80, 0x80, 0x80}, // 0x4C L
 | |||
|     {0xFE, 0x04, 0x08, 0x04, 0xFE}, // 0x4D M
 | |||
|     {0xFE, 0x08, 0x10, 0x20, 0xFE}, // 0x4E N
 | |||
|     {0x7C, 0x82, 0x82, 0x82, 0x7C}, // 0x4F O
 | |||
|     {0xFE, 0x12, 0x12, 0x12, 0x0C}, // 0x50 P
 | |||
|     {0x7C, 0x82, 0xA2, 0x42, 0xBC}, // 0x51 Q
 | |||
|     {0xFE, 0x12, 0x32, 0x52, 0x8C}, // 0x52 R
 | |||
|     {0x8C, 0x92, 0x92, 0x92, 0x62}, // 0x53 S
 | |||
|     {0x02, 0x02, 0xFE, 0x02, 0x02}, // 0x54 T
 | |||
|     {0x7E, 0x80, 0x80, 0x80, 0x7E}, // 0x55 U
 | |||
|     {0x3E, 0x40, 0x80, 0x40, 0x3E}, // 0x56 V
 | |||
|     {0xFE, 0x40, 0x30, 0x40, 0xFE}, // 0x57 W
 | |||
|     {0xC6, 0x28, 0x10, 0x28, 0xC6}, // 0x58 X
 | |||
|     {0x06, 0x08, 0xF0, 0x08, 0x06}, // 0x59 Y
 | |||
|     {0xC2, 0xA2, 0x92, 0x8A, 0x86}, // 0x5A Z
 | |||
|     {0x00, 0x00, 0xFE, 0x82, 0x82}, // 0x5B [
 | |||
|     {0x04, 0x08, 0x10, 0x20, 0x40}, // 0x5C "\"
 | |||
|     {0x82, 0x82, 0xFE, 0x00, 0x00}, // 0x5D ]
 | |||
|     {0x08, 0x04, 0x02, 0x04, 0x08}, // 0x5E ^
 | |||
|     {0x80, 0x80, 0x80, 0x80, 0x80}, // 0x5F _
 | |||
|     {0x00, 0x02, 0x04, 0x08, 0x00}, // 0x60 `
 | |||
|     {0x40, 0xA8, 0xA8, 0xA8, 0xF0}, // 0x61 a
 | |||
|     {0xFE, 0x90, 0x88, 0x88, 0x70}, // 0x62 b
 | |||
|     {0x70, 0x88, 0x88, 0x88, 0x40}, // 0x63 c
 | |||
|     {0x70, 0x88, 0x88, 0x90, 0xFE}, // 0x64 d
 | |||
|     {0x70, 0xA8, 0xA8, 0xA8, 0x30}, // 0x65 e
 | |||
|     {0x10, 0xFC, 0x12, 0x02, 0x04}, // 0x66 f
 | |||
|     {0x10, 0x28, 0xA8, 0xA8, 0x78}, // 0x67 g
 | |||
|     {0xFE, 0x10, 0x08, 0x08, 0xF0}, // 0x68 h
 | |||
|     {0x00, 0x88, 0xFA, 0x80, 0x00}, // 0x69 i
 | |||
|     {0x40, 0x80, 0x88, 0x7A, 0x00}, // 0x6A j
 | |||
|     {0x00, 0xFE, 0x20, 0x50, 0x88}, // 0x6B k
 | |||
|     {0x00, 0x82, 0xFE, 0x80, 0x00}, // 0x6C l
 | |||
|     {0xF8, 0x08, 0x30, 0x08, 0xF0}, // 0x6D m
 | |||
|     {0xF8, 0x10, 0x08, 0x08, 0xF0}, // 0x6E n
 | |||
|     {0x70, 0x88, 0x88, 0x88, 0x70}, // 0x6F o
 | |||
|     {0xF8, 0x28, 0x28, 0x28, 0x10}, // 0x70 p
 | |||
|     {0x10, 0x28, 0x28, 0x30, 0xF8}, // 0x71 q
 | |||
|     {0xF8, 0x10, 0x08, 0x08, 0x10}, // 0x72 r
 | |||
|     {0x90, 0xA8, 0xA8, 0xA8, 0x40}, // 0x73 s
 | |||
|     {0x08, 0x7E, 0x88, 0x80, 0x40}, // 0x74 t
 | |||
|     {0x78, 0x80, 0x80, 0x40, 0xF8}, // 0x75 u
 | |||
|     {0x38, 0x40, 0x80, 0x40, 0x38}, // 0x76 v
 | |||
|     {0x78, 0x80, 0x60, 0x80, 0x78}, // 0x77 w
 | |||
|     {0x88, 0x50, 0x20, 0x50, 0x88}, // 0x78 x
 | |||
|     {0x18, 0xA0, 0xA0, 0xA0, 0x78}, // 0x79 y
 | |||
|     {0x88, 0xC8, 0xA8, 0x98, 0x88}, // 0x7A z
 | |||
|     {0x00, 0x10, 0x6C, 0x82, 0x00}, // 0x7B {
 | |||
|     {0x00, 0x00, 0xFE, 0x00, 0x00}, // 0x7C |
 | |||
|     {0x00, 0x82, 0x6C, 0x10, 0x00}, // 0x7D }
 | |||
|     {0x20, 0x10, 0x10, 0x20, 0x10}, // 0x7E
 | |||
|     {0xF0, 0x88, 0x84, 0x88, 0xF0}, // 0x7F 
 | |||
|     {0x28, 0x7C, 0xAA, 0x82, 0x44}, // 0x80 €
 | |||
|     {0xF0, 0x29, 0x27, 0x21, 0xFF}, // 0x81 
 | |||
|     {0x00, 0xA0, 0x60, 0x00, 0x00}, // 0x82 ‚
 | |||
|     {0x40, 0x90, 0x7C, 0x12, 0x04}, // 0x83 ƒ
 | |||
|     {0xC0, 0xA0, 0x00, 0xC0, 0xA0}, // 0x84 „
 | |||
|     {0x80, 0x00, 0x80, 0x00, 0x80}, // 0x85 …
 | |||
|     {0x00, 0x04, 0xFE, 0x04, 0x00}, // 0x86 †
 | |||
|     {0x00, 0x44, 0xFE, 0x44, 0x00}, // 0x87 ‡
 | |||
|     {0x00, 0x04, 0x02, 0x04, 0x00}, // 0x88 ˆ
 | |||
|     {0xC3, 0xD3, 0x08, 0xC4, 0xC2}, // 0x89 ‰
 | |||
|     {0x4C, 0x93, 0x92, 0x93, 0x64}, // 0x8A Š
 | |||
|     {0x00, 0x10, 0x28, 0x00, 0x00}, // 0x8B ‹
 | |||
|     {0x7C, 0x82, 0x82, 0x7C, 0x92}, // 0x8C Œ
 | |||
|     {0x02, 0xFE, 0x90, 0x90, 0x60}, // 0x8D 
 | |||
|     {0xC2, 0xA3, 0x92, 0x8B, 0x86}, // 0x8E Ž
 | |||
|     {0x44, 0x92, 0x8A, 0x92, 0x7C}, // 0x8F 
 | |||
|     {0x70, 0x88, 0x90, 0x60, 0x98}, // 0x90 
 | |||
|     {0x00, 0x02, 0x04, 0x08, 0x00}, // 0x91 ‘
 | |||
|     {0x00, 0x08, 0x04, 0x02, 0x00}, // 0x92 ’
 | |||
|     {0x02, 0x04, 0x0A, 0x04, 0x08}, // 0x93 “
 | |||
|     {0x08, 0x04, 0x0A, 0x04, 0x02}, // 0x94 ”
 | |||
|     {0x00, 0x38, 0x38, 0x38, 0x00}, // 0x95 •
 | |||
|     {0x00, 0x10, 0x10, 0x10, 0x10}, // 0x96 –
 | |||
|     {0x10, 0x10, 0x10, 0x10, 0x10}, // 0x97 —
 | |||
|     {0x02, 0x01, 0x02, 0x04, 0x02}, // 0x98 ˜
 | |||
|     {0xF1, 0x5B, 0x55, 0x51, 0x51}, // 0x99 ™
 | |||
|     {0x90, 0xA9, 0xAA, 0xA9, 0x40}, // 0x9A š
 | |||
|     {0x00, 0x88, 0x50, 0x20, 0x00}, // 0x9B ›
 | |||
|     {0x70, 0x88, 0x70, 0xA8, 0xB0}, // 0x9C ϡ
 | |||
|     {0x38, 0x7C, 0xF8, 0x7C, 0x38}, // 0x9D 
 | |||
|     {0x88, 0xC9, 0xAA, 0x99, 0x88}, // 0x9E ž
 | |||
|     {0x1C, 0x21, 0xC0, 0x21, 0x1C}, // 0x9F Ÿ
 | |||
|     {0x00, 0x00, 0x00, 0x00, 0x00}, // 0xA0
 | |||
|     {0x00, 0x00, 0xF2, 0x00, 0x00}, // 0xA1 ¡
 | |||
|     {0x38, 0x44, 0xFE, 0x44, 0x20}, // 0xA2 ¢
 | |||
|     {0x90, 0x7C, 0x92, 0x82, 0x40}, // 0xA3 £
 | |||
|     {0x44, 0x38, 0x28, 0x38, 0x44}, // 0xA4 ¤
 | |||
|     {0x2A, 0x2C, 0xF8, 0x2C, 0x2A}, // 0xA5 ¥
 | |||
|     {0x00, 0x00, 0xEE, 0x00, 0x00}, // 0xA6 ¦
 | |||
|     {0x40, 0x94, 0xAA, 0x52, 0x04}, // 0xA7 §
 | |||
|     {0x00, 0x02, 0x00, 0x02, 0x00}, // 0xA8 ¨
 | |||
|     {0xFE, 0x82, 0xBA, 0x92, 0xFE}, // 0xA9 ©
 | |||
|     {0x90, 0xAA, 0xAA, 0xAA, 0xBC}, // 0xAA ª
 | |||
|     {0x20, 0x50, 0xA8, 0x50, 0x88}, // 0xAB «
 | |||
|     {0x20, 0x20, 0x20, 0x20, 0xE0}, // 0xAC ¬
 | |||
|     {0x20, 0x20, 0x20, 0x20, 0x20}, // 0xAD 
 | |||
|     {0xFE, 0x82, 0xCA, 0xA2, 0xFE}, // 0xAE ®
 | |||
|     {0x02, 0x02, 0x02, 0x02, 0x02}, // 0xAF ¯
 | |||
|     {0x0E, 0x11, 0x11, 0x0E, 0x00}, // 0xB0 °
 | |||
|     {0x88, 0x88, 0xBE, 0x88, 0x88}, // 0xB1 ±
 | |||
|     {0x12, 0x19, 0x15, 0x12, 0x00}, // 0xB2 ²
 | |||
|     {0x11, 0x15, 0x15, 0x0A, 0x00}, // 0xB3 ³
 | |||
|     {0x00, 0x08, 0x04, 0x02, 0x00}, // 0xB4 ´
 | |||
|     {0xFE, 0x20, 0x20, 0x10, 0x3E}, // 0xB5 µ
 | |||
|     {0x0C, 0x12, 0x12, 0xFE, 0xFE}, // 0xB6 ¶
 | |||
|     {0x00, 0x30, 0x30, 0x00, 0x00}, // 0xB7 ·
 | |||
|     {0x00, 0x80, 0xB0, 0x40, 0x00}, // 0xB8 ¸
 | |||
|     {0x00, 0x02, 0x0F, 0x00, 0x00}, // 0xB9 ¹
 | |||
|     {0x00, 0x02, 0x05, 0x02, 0x00}, // 0xBA º
 | |||
|     {0x44, 0x28, 0x54, 0x28, 0x10}, // 0xBB »
 | |||
|     {0x22, 0x1F, 0x68, 0x54, 0xFA}, // 0xBC ¼
 | |||
|     {0x02, 0x1F, 0x90, 0xC8, 0xB0}, // 0xBD ½
 | |||
|     {0x15, 0x1F, 0x60, 0x50, 0xF8}, // 0xBE ¾
 | |||
|     {0x60, 0x90, 0x8A, 0x80, 0x40}, // 0xBF ¿
 | |||
|     {0xF0, 0x29, 0x26, 0x28, 0xF0}, // 0xC0 À
 | |||
|     {0xF0, 0x28, 0x26, 0x29, 0xF0}, // 0xC1 Á
 | |||
|     {0xF0, 0x2A, 0x29, 0x2A, 0xF0}, // 0xC2 Â
 | |||
|     {0xF2, 0x29, 0x29, 0x2A, 0xF1}, // 0xC3 Ã
 | |||
|     {0xF0, 0x29, 0x24, 0x29, 0xF0}, // 0xC4 Ä
 | |||
|     {0xF0, 0x2A, 0x2D, 0x2A, 0xF0}, // 0xC5 Å
 | |||
|     {0xF8, 0x24, 0xFE, 0x92, 0x92}, // 0xC6 Æ
 | |||
|     {0x1E, 0x21, 0xA1, 0xE1, 0x12}, // 0xC7 Ç
 | |||
|     {0xF8, 0xA9, 0xAA, 0xA8, 0x88}, // 0xC8 È
 | |||
|     {0xF8, 0xA8, 0xAA, 0xA9, 0x88}, // 0xC9 É
 | |||
|     {0xF8, 0xAA, 0xA9, 0xAA, 0x88}, // 0xCA Ê
 | |||
|     {0xF8, 0xAA, 0xA8, 0xAA, 0x88}, // 0xCB Ë
 | |||
|     {0x00, 0x89, 0xFA, 0x88, 0x00}, // 0xCC Ì
 | |||
|     {0x00, 0x88, 0xFA, 0x89, 0x00}, // 0xCD Í
 | |||
|     {0x00, 0x8A, 0xF9, 0x8A, 0x00}, // 0xCE Î
 | |||
|     {0x00, 0x8A, 0xF8, 0x8A, 0x00}, // 0xCF Ï
 | |||
|     {0x10, 0xFE, 0x92, 0x82, 0x7C}, // 0xD0 Ð
 | |||
|     {0xFA, 0x11, 0x21, 0x42, 0xF9}, // 0xD1 Ñ
 | |||
|     {0x78, 0x85, 0x86, 0x84, 0x78}, // 0xD2 Ò
 | |||
|     {0x78, 0x84, 0x86, 0x85, 0x78}, // 0xD3 Ó
 | |||
|     {0x70, 0x8A, 0x89, 0x8A, 0x70}, // 0xD4 Ô
 | |||
|     {0x72, 0x89, 0x89, 0x8A, 0x71}, // 0xD5 Õ
 | |||
|     {0x78, 0x85, 0x84, 0x85, 0x78}, // 0xD6 Ö
 | |||
|     {0x44, 0x28, 0x10, 0x28, 0x44}, // 0xD7 ×
 | |||
|     {0x10, 0xAA, 0xFE, 0xAA, 0x10}, // 0xD8 Ø
 | |||
|     {0x7C, 0x81, 0x82, 0x80, 0x7C}, // 0xD9 Ù
 | |||
|     {0x7C, 0x80, 0x82, 0x81, 0x7C}, // 0xDA Ú
 | |||
|     {0x78, 0x82, 0x81, 0x82, 0x78}, // 0xDB Û
 | |||
|     {0x7C, 0x81, 0x80, 0x81, 0x7C}, // 0xDC Ü
 | |||
|     {0x04, 0x08, 0xF2, 0x09, 0x04}, // 0xDD Ý
 | |||
|     {0x81, 0xFF, 0x24, 0x24, 0x18}, // 0xDE Þ
 | |||
|     {0x80, 0x7C, 0x92, 0x92, 0x6C}, // 0xDF ß
 | |||
|     {0x40, 0xA9, 0xAA, 0xA8, 0xF0}, // 0xE0 à
 | |||
|     {0x40, 0xA8, 0xAA, 0xA9, 0xF0}, // 0xE1 á
 | |||
|     {0x40, 0xAA, 0xA9, 0xAA, 0xF0}, // 0xE2 â
 | |||
|     {0x42, 0xA9, 0xA9, 0xAA, 0xF1}, // 0xE3 ã
 | |||
|     {0x40, 0xAA, 0xA8, 0xAA, 0xF0}, // 0xE4 ä
 | |||
|     {0x40, 0xAA, 0xAD, 0xAA, 0xF0}, // 0xE5 å
 | |||
|     {0x64, 0x94, 0x78, 0x94, 0x58}, // 0xE6 æ
 | |||
|     {0x18, 0x24, 0xA4, 0xE4, 0x10}, // 0xE7 ç
 | |||
|     {0x70, 0xA9, 0xAA, 0xA8, 0x30}, // 0xE8 è
 | |||
|     {0x70, 0xA8, 0xAA, 0xA9, 0x30}, // 0xE9 é
 | |||
|     {0x70, 0xAA, 0xA9, 0xAA, 0x30}, // 0xEA ê
 | |||
|     {0x70, 0xAA, 0xA8, 0xAA, 0x30}, // 0xEB ë
 | |||
|     {0x00, 0x91, 0xFA, 0x80, 0x00}, // 0xEC ì
 | |||
|     {0x00, 0x90, 0xFA, 0x81, 0x00}, // 0xED í
 | |||
|     {0x00, 0x92, 0xF9, 0x82, 0x00}, // 0xEE î
 | |||
|     {0x00, 0x92, 0xF8, 0x82, 0x00}, // 0xEF ï
 | |||
|     {0x4A, 0xA4, 0xAA, 0xB0, 0x60}, // 0xF0 ð
 | |||
|     {0xFA, 0x11, 0x09, 0x0A, 0xF1}, // 0xF1 ñ
 | |||
|     {0x70, 0x89, 0x8A, 0x88, 0x70}, // 0xF2 ò
 | |||
|     {0x70, 0x88, 0x8A, 0x89, 0x70}, // 0xF3 ó
 | |||
|     {0x60, 0x94, 0x92, 0x94, 0x60}, // 0xF4 ô
 | |||
|     {0x64, 0x92, 0x92, 0x94, 0x62}, // 0xF5 õ
 | |||
|     {0x70, 0x8A, 0x88, 0x8A, 0x70}, // 0xF6 ö
 | |||
|     {0x10, 0x10, 0x54, 0x10, 0x10}, // 0xF7 ÷
 | |||
|     {0x10, 0xA8, 0x7C, 0x2A, 0x10}, // 0xF8 ø
 | |||
|     {0x78, 0x81, 0x82, 0x40, 0xF8}, // 0xF9 ù
 | |||
|     {0x78, 0x80, 0x82, 0x41, 0xF8}, // 0xFA ú
 | |||
|     {0x78, 0x82, 0x81, 0x42, 0xF8}, // 0xFB û
 | |||
|     {0x78, 0x82, 0x80, 0x42, 0xF8}, // 0xFC ü
 | |||
|     {0x18, 0xA0, 0xA4, 0xA2, 0x78}, // 0xFD v
 | |||
|     {0x00, 0x82, 0xFE, 0xA8, 0x10}, // 0xFE þ
 | |||
|     {0x18, 0xA2, 0xA0, 0xA2, 0x78}  // 0xFF ÿ
 | |||
| }; | |||
| 
 | |||
| AT24C32 at24c32; | |||
| uint8_t data; | |||
| 
 | |||
| /**
 | |||
|     setup | |||
|  */ | |||
| void setup() | |||
| { | |||
|     Serial.begin(115200); | |||
| 
 | |||
|     at24c32.begin(); | |||
| 
 | |||
|     for (int ascii = 0; ascii < 256; ascii++) | |||
|     { | |||
|         for (int b = 0; b < 5; b++) | |||
|         { | |||
|             at24c32.write(ascii * 5 + b, ascii_font[ascii][b]); | |||
|             Serial.print(ascii * 5 + b); | |||
|             if (at24c32.read(ascii * 5 + b) == ascii_font[ascii][b]) | |||
|             { | |||
|                 Serial.println(F(": check")); | |||
|             } | |||
|             else | |||
|             { | |||
|                 Serial.print(F(": ERROR! ")); | |||
|                 Serial.print(ascii_font[ascii][b]); | |||
|                 Serial.print(F(" - ")); | |||
|                 Serial.println(at24c32.read(ascii * 5 + b)); | |||
|             } | |||
|         } | |||
|     } | |||
| 
 | |||
|     Serial.println(F("ascii chars written!")); | |||
| 
 | |||
|     for (int i = 0; i < 256; i++) | |||
|     { | |||
|         at24c32.write(TEXT_ADDRESS + i, char('A')); | |||
|     } | |||
| 
 | |||
|     Serial.println(F("Text resets to 'A'")); | |||
| 
 | |||
|     String text = "Liebe Rohrers, frohe Weihnachten (nachtrAglich)!"; | |||
| 
 | |||
|     at24c32.write(TEXT_SIZE_ADDRESS, text.length()); | |||
| 
 | |||
|     for (int i = 0; i < text.length(); i++) | |||
|     { | |||
|         at24c32.write(TEXT_ADDRESS + i, char(text[i])); | |||
|     } | |||
| 
 | |||
|     Serial.println(F("text written!")); | |||
| } | |||
| 
 | |||
| /**
 | |||
|     loop | |||
|  */ | |||
| void loop() | |||
| { | |||
|     // read text
 | |||
|     uint8_t length = at24c32.read(TEXT_SIZE_ADDRESS); | |||
| 
 | |||
|     for (uint8_t i = 0; i < length; i++) | |||
|     { | |||
|         Serial.print(char(at24c32.read(TEXT_ADDRESS + i))); | |||
|     } | |||
| 
 | |||
|     Serial.println(); | |||
| 
 | |||
|     delay(2000); | |||
| } | |||
| @ -0,0 +1,49 @@ | |||
| #include <Arduino.h>
 | |||
| 
 | |||
| #include <Wire.h>
 | |||
| 
 | |||
| #include <AT24C32.h>
 | |||
| 
 | |||
| void AT24C32::begin() | |||
| { | |||
|   Wire.begin(); | |||
| }; | |||
| 
 | |||
| uint8_t AT24C32::read(int address) | |||
| { | |||
|   uint8_t result = 0; | |||
|   bool read = true; | |||
|   Wire.beginTransmission(AT24C32_I2C_ADDRESS); | |||
|   if (Wire.endTransmission() == 0) | |||
|   { | |||
|     Wire.beginTransmission(AT24C32_I2C_ADDRESS); | |||
|     Wire.write(address >> 8); | |||
|     Wire.write(address & 0xff); | |||
|     if (Wire.endTransmission() == 0) | |||
|     { | |||
|       Wire.requestFrom(AT24C32_I2C_ADDRESS, 1); | |||
|       while (Wire.available() > 0 && read) | |||
|       { | |||
|         result = Wire.read(); | |||
|         read = false; | |||
|       } | |||
| 
 | |||
|       Wire.endTransmission(); | |||
|     } | |||
|   } | |||
|   return result; | |||
| } | |||
| 
 | |||
| void AT24C32::write(int address, uint8_t data) | |||
| { | |||
|   Wire.beginTransmission(AT24C32_I2C_ADDRESS); | |||
|   if (Wire.endTransmission() == 0) | |||
|   { | |||
|     Wire.beginTransmission(AT24C32_I2C_ADDRESS); | |||
|     Wire.write(address >> 8); | |||
|     Wire.write(address & 0xff); | |||
|     Wire.write(data); | |||
|     Wire.endTransmission(); | |||
|     delay(20); | |||
|   } | |||
| } | |||
| @ -0,0 +1,28 @@ | |||
| #ifndef AT24C32_h | |||
| #define AT24C32_h | |||
| 
 | |||
| #include <Arduino.h> | |||
| 
 | |||
| class AT24C32 | |||
| { | |||
| public: | |||
|   void begin(); | |||
|   uint8_t read(int address); | |||
|   void write(int address, uint8_t data); | |||
| }; | |||
| 
 | |||
| // I2C address | |||
| #define AT24C32_I2C_ADDRESS 0x57 | |||
| 
 | |||
| #define BRIGHTNESS_ADDRESS 0x0A00 | |||
| 
 | |||
| #define COLOR_ADDRESS 0x0A01 | |||
| 
 | |||
| #define VIEW_STATE_ADDRESS 0x0A02 | |||
| 
 | |||
| #define TIME_MODE_ADDRESS 0x0A03 | |||
| 
 | |||
| #define TEXT_SIZE_ADDRESS 0x0B00 | |||
| #define TEXT_ADDRESS 0x0B01 | |||
| 
 | |||
| #endif | |||
| @ -0,0 +1,33 @@ | |||
| #include <Arduino.h>
 | |||
| 
 | |||
| #include <Wire.h>
 | |||
| 
 | |||
| #include "Button.h"
 | |||
| 
 | |||
| Button::Button(uint8_t _pin, uint8_t _mode) | |||
| { | |||
|   pin = _pin; | |||
|   mode = _mode; | |||
| } | |||
| 
 | |||
| void Button::begin() | |||
| { | |||
|   if (mode == LOW) | |||
|   { | |||
|     pinMode(pin, INPUT_PULLUP); | |||
|   } | |||
|   else if (mode == HIGH) | |||
|   { | |||
|     pinMode(pin, INPUT); | |||
|   } | |||
| } | |||
| 
 | |||
| void Button::loop(ButtonCallbackFunction callback) | |||
| { | |||
|   if (digitalRead(pin) == mode) | |||
|   { | |||
|     (*callback)(); | |||
|     // debounce
 | |||
|     delay(250); | |||
|   } | |||
| } | |||
| @ -0,0 +1,20 @@ | |||
| #ifndef Button_h | |||
| #define Button_h | |||
| 
 | |||
| #include <Arduino.h> | |||
| 
 | |||
| typedef void (*ButtonCallbackFunction)(); | |||
| 
 | |||
| class Button | |||
| { | |||
| public: | |||
|   Button(uint8_t _pin, uint8_t _mode); | |||
|   void begin(); | |||
|   void loop(ButtonCallbackFunction callback); | |||
| 
 | |||
| private: | |||
|   uint8_t mode; | |||
|   uint8_t pin; | |||
| }; | |||
| 
 | |||
| #endif | |||
| @ -0,0 +1,406 @@ | |||
| #include <Arduino.h>
 | |||
| 
 | |||
| #include <Wire.h>
 | |||
| 
 | |||
| #include <DS3231.h>
 | |||
| 
 | |||
| void DS3231::begin() | |||
| { | |||
|     Wire.begin(); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getSeconds() | |||
| { | |||
|     uint8_t seconds; | |||
|     // read minutes
 | |||
|     seconds = getRegister(DS3231_SECONDS); | |||
|     return bcdtodec(seconds); | |||
| } | |||
| 
 | |||
| void DS3231::setSeconds(uint8_t seconds) | |||
| { | |||
|     // write seconds
 | |||
|     setRegister(DS3231_SECONDS, dectobcd(seconds)); | |||
| } | |||
| 
 | |||
| void DS3231::incrementSeconds() | |||
| { | |||
|     uint8_t seconds = getSeconds(); | |||
| 
 | |||
|     if (seconds == 58) | |||
|     { | |||
|         seconds = 0; | |||
|     } | |||
|     else | |||
|     { | |||
|         seconds += 2; | |||
|     } | |||
| 
 | |||
|     setSeconds(seconds); | |||
| } | |||
| 
 | |||
| void DS3231::decrementSeconds() | |||
| { | |||
|     uint8_t seconds = getSeconds(); | |||
| 
 | |||
|     if (seconds == 1) | |||
|     { | |||
|         seconds = 59; | |||
|     } | |||
|     else | |||
|     { | |||
|         seconds -= 2; | |||
|     } | |||
| 
 | |||
|     setSeconds(seconds); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getMinutes() | |||
| { | |||
|     uint8_t minutes; | |||
|     // read minutes
 | |||
|     minutes = getRegister(DS3231_MINUTES); | |||
|     return bcdtodec(minutes); | |||
| } | |||
| 
 | |||
| void DS3231::setMinutes(uint8_t minutes) | |||
| { | |||
|     // write minutes
 | |||
|     setRegister(DS3231_MINUTES, dectobcd(minutes)); | |||
| } | |||
| 
 | |||
| void DS3231::incrementMinutes() | |||
| { | |||
|     uint8_t minutes = getMinutes(); | |||
| 
 | |||
|     if (minutes == 59) | |||
|     { | |||
|         minutes = 0; | |||
|     } | |||
|     else | |||
|     { | |||
|         minutes++; | |||
|     } | |||
| 
 | |||
|     setMinutes(minutes); | |||
| } | |||
| 
 | |||
| void DS3231::decrementMinutes() | |||
| { | |||
|     uint8_t minutes = getMinutes(); | |||
| 
 | |||
|     if (minutes == 0) | |||
|     { | |||
|         minutes = 59; | |||
|     } | |||
|     else | |||
|     { | |||
|         minutes--; | |||
|     } | |||
| 
 | |||
|     setMinutes(minutes); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getHours() | |||
| { | |||
|     uint8_t hours; | |||
|     // read hours
 | |||
|     hours = getRegister(DS3231_HOURS); | |||
|     return bcdtodec(hours); | |||
| } | |||
| 
 | |||
| void DS3231::setHours(uint8_t hours) | |||
| { | |||
|     // write hours
 | |||
|     setRegister(DS3231_HOURS, dectobcd(hours)); | |||
| } | |||
| 
 | |||
| void DS3231::incrementHours() | |||
| { | |||
|     uint8_t hours = getHours(); | |||
| 
 | |||
|     if (hours == 23) | |||
|     { | |||
|         hours = 0; | |||
|     } | |||
|     else | |||
|     { | |||
|         hours++; | |||
|     } | |||
| 
 | |||
|     setHours(hours); | |||
| } | |||
| 
 | |||
| void DS3231::decrementHours() | |||
| { | |||
|     uint8_t hours = getHours(); | |||
| 
 | |||
|     if (hours == 0) | |||
|     { | |||
|         hours = 23; | |||
|     } | |||
|     else | |||
|     { | |||
|         hours--; | |||
|     } | |||
| 
 | |||
|     setHours(hours); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getDay() | |||
| { | |||
|     uint8_t day; | |||
|     // read day
 | |||
|     day = getRegister(DS3231_DAY); | |||
|     return bcdtodec(day); | |||
| } | |||
| 
 | |||
| void DS3231::setDay(uint8_t day) | |||
| { | |||
|     // write day
 | |||
|     setRegister(DS3231_DAY, dectobcd(day)); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getDate() | |||
| { | |||
|     uint8_t date; | |||
|     // read date
 | |||
|     date = getRegister(DS3231_DATE); | |||
|     return bcdtodec(date); | |||
| } | |||
| 
 | |||
| void DS3231::setDate(uint8_t date) | |||
| { | |||
|     // write date
 | |||
|     setRegister(DS3231_DATE, dectobcd(date)); | |||
| } | |||
| 
 | |||
| void DS3231::incrementDate() | |||
| { | |||
|     uint8_t date = getDate(); | |||
|     date++; | |||
|     if (date > 31) | |||
|     { | |||
|         date = 1; | |||
|     } | |||
|     setDate(date); | |||
| } | |||
| 
 | |||
| void DS3231::decrementDate() | |||
| { | |||
|     uint8_t date = getDate(); | |||
|     date--; | |||
|     if (date < 1) | |||
|     { | |||
|         date = 31; | |||
|     } | |||
|     setDate(date); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getMonth() | |||
| { | |||
|     uint8_t month; | |||
|     // read month
 | |||
|     month = getRegister(DS3231_MONTH); | |||
| 
 | |||
|     // read month, ingore century;
 | |||
|     return bcdtodec(month & 0x1F); | |||
| } | |||
| 
 | |||
| void DS3231::setMonth(uint8_t month) | |||
| { | |||
|     uint8_t century = getCentury(); | |||
| 
 | |||
|     month = dectobcd(month); | |||
| 
 | |||
|     if (century == 1) | |||
|     { | |||
|         month = month + 0x80; | |||
|     } | |||
| 
 | |||
|     // write month
 | |||
|     setRegister(DS3231_MONTH, month); | |||
| } | |||
| 
 | |||
| void DS3231::incrementMonth() | |||
| { | |||
|     uint8_t month = getMonth(); | |||
|     month++; | |||
|     if (month > 12) | |||
|     { | |||
|         month = 1; | |||
|     } | |||
|     setMonth(month); | |||
| } | |||
| 
 | |||
| void DS3231::decrementMonth() | |||
| { | |||
|     uint8_t month = getMonth(); | |||
|     month--; | |||
|     if (month < 1) | |||
|     { | |||
|         month = 12; | |||
|     } | |||
|     setMonth(month); | |||
| } | |||
| 
 | |||
| int16_t DS3231::getYear() | |||
| { | |||
|     uint8_t century = getCentury(); | |||
| 
 | |||
|     int16_t year; | |||
| 
 | |||
|     // read year
 | |||
|     year = getRegister(DS3231_YEAR); | |||
| 
 | |||
|     year = bcdtodec(year); | |||
| 
 | |||
|     if (century == 1) | |||
|     { | |||
|         year = 2000 + year; | |||
|     } | |||
|     else | |||
|     { | |||
|         year = 1900 + year; | |||
|     } | |||
| 
 | |||
|     return year; | |||
| } | |||
| 
 | |||
| void DS3231::setYear(int16_t year) | |||
| { | |||
|     if (year > 1999) | |||
|     { | |||
|         year = year - 2000; | |||
|         setCentury(0x80); | |||
|     } | |||
|     else | |||
|     { | |||
|         year = year - 1900; | |||
|         setCentury(0); | |||
|     } | |||
| 
 | |||
|     setRegister(DS3231_YEAR, dectobcd(year)); | |||
| } | |||
| 
 | |||
| void DS3231::incrementYear() | |||
| { | |||
|     int16_t year = getYear(); | |||
|     year++; | |||
|     if (year > 2099) | |||
|     { | |||
|         year = 1900; | |||
|     } | |||
|     setYear(year); | |||
| } | |||
| 
 | |||
| void DS3231::decrementYear() | |||
| { | |||
|     int16_t year = getYear(); | |||
|     year--; | |||
|     if (year < 1900) | |||
|     { | |||
|         year = 2099; | |||
|     } | |||
|     setYear(year); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getControlRegister() | |||
| { | |||
|     return bcdtodec(getRegister(DS3231_CONTROL)); | |||
| } | |||
| 
 | |||
| void DS3231::setControlRegister(uint8_t value) | |||
| { | |||
|     setRegister(DS3231_CONTROL, dectobcd(value)); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getStatusRegister() | |||
| { | |||
|     return bcdtodec(getRegister(DS3231_STATUS)); | |||
| } | |||
| 
 | |||
| void DS3231::setStatusRegister(uint8_t value) | |||
| { | |||
|     setRegister(DS3231_STATUS, dectobcd(value)); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getTemperature() | |||
| { | |||
|     int8_t msb_temp; | |||
|     uint8_t msb_value = getRegister(DS3231_MSB_TEMP); | |||
|     uint8_t lsb_temp = getRegister(DS3231_LSB_TEMP) >> 6; | |||
|     float result; | |||
| 
 | |||
|     if ((msb_value & 0x80) != 0) | |||
|     { | |||
|         msb_temp = msb_value | ~((1 << 8) - 1); | |||
|     } | |||
|     else | |||
|     { | |||
|         msb_temp = msb_value; | |||
|     } | |||
| 
 | |||
|     result = 0.25 * lsb_temp + msb_temp; | |||
| 
 | |||
|     return result; | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getRegister(uint8_t address) | |||
| { | |||
|     uint8_t value; | |||
| 
 | |||
|     Wire.beginTransmission(DS3231_I2C_ADDRESS); | |||
|     Wire.write(address); | |||
|     Wire.endTransmission(); | |||
| 
 | |||
|     // request 1 byte
 | |||
|     Wire.requestFrom(DS3231_I2C_ADDRESS, 1); | |||
| 
 | |||
|     // read value
 | |||
|     value = Wire.read(); | |||
| 
 | |||
|     return value; | |||
| } | |||
| 
 | |||
| void DS3231::setRegister(uint8_t address, uint8_t value) | |||
| { | |||
|     Wire.beginTransmission(DS3231_I2C_ADDRESS); | |||
|     // start at address
 | |||
|     Wire.write(address); | |||
| 
 | |||
|     // write value
 | |||
|     Wire.write(value); | |||
| 
 | |||
|     Wire.endTransmission(); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::dectobcd(uint8_t value) | |||
| { | |||
|     return ((value / 10 * 16) + (value % 10)); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::bcdtodec(uint8_t value) | |||
| { | |||
|     return ((value / 16 * 10) + (value % 16)); | |||
| } | |||
| 
 | |||
| uint8_t DS3231::getCentury() | |||
| { | |||
|     uint8_t century = 0; | |||
| 
 | |||
|     uint8_t month = getRegister(DS3231_MONTH); | |||
| 
 | |||
|     // read century from month
 | |||
|     century = (month & 0x80) >> 7; | |||
|     return century; | |||
| } | |||
| 
 | |||
| void DS3231::setCentury(uint8_t century) | |||
| { | |||
|     uint8_t month = getMonth(); | |||
| 
 | |||
|     month = month + century; | |||
| 
 | |||
|     setRegister(DS3231_MONTH, month); | |||
| } | |||
| @ -0,0 +1,133 @@ | |||
| #ifndef DS3231_h | |||
| #define DS3231_h | |||
| 
 | |||
| #include <Arduino.h> | |||
| 
 | |||
| /** | |||
|   TODO: alarms | |||
|  */ | |||
| class DS3231 | |||
| { | |||
| public: | |||
|   // begin function | |||
|   void begin(); | |||
|   // get seconds | |||
|   uint8_t getSeconds(); | |||
|   // set seconds | |||
|   void setSeconds(uint8_t seconds); | |||
|   // increment seconds | |||
|   void incrementSeconds(); | |||
|   // decrement seconds | |||
|   void decrementSeconds(); | |||
|   // get minutes | |||
|   uint8_t getMinutes(); | |||
|   // set minutes | |||
|   void setMinutes(uint8_t minutes); | |||
|   // increment minutes | |||
|   void incrementMinutes(); | |||
|   // decrement minutes | |||
|   void decrementMinutes(); | |||
|   // get hours | |||
|   uint8_t getHours(); | |||
|   // set hours | |||
|   void setHours(uint8_t hours); | |||
|   // increment hours | |||
|   void incrementHours(); | |||
|   // decrement hours | |||
|   void decrementHours(); | |||
|   // get day | |||
|   uint8_t getDay(); | |||
|   // set day | |||
|   void setDay(uint8_t day); | |||
|   // get date | |||
|   uint8_t getDate(); | |||
|   // set date | |||
|   void setDate(uint8_t date); | |||
|   // increment date | |||
|   void incrementDate(); | |||
|   // decrement date | |||
|   void decrementDate(); | |||
|   // get month | |||
|   uint8_t getMonth(); | |||
|   // set month | |||
|   void setMonth(uint8_t month); | |||
|   // increment month | |||
|   void incrementMonth(); | |||
|   // decrement month | |||
|   void decrementMonth(); | |||
|   // get year | |||
|   int16_t getYear(); | |||
|   // set year | |||
|   void setYear(int16_t year); | |||
|   // increment year | |||
|   void incrementYear(); | |||
|   // decrement year | |||
|   void decrementYear(); | |||
|   // get control register | |||
|   uint8_t getControlRegister(); | |||
|   // set control register | |||
|   void setControlRegister(uint8_t value); | |||
|   // set status register | |||
|   uint8_t getStatusRegister(); | |||
|   // set status register | |||
|   void setStatusRegister(uint8_t value); | |||
|   // get temperature | |||
|   uint8_t getTemperature(); | |||
|   // helpers | |||
| protected: | |||
|   // get register | |||
|   uint8_t getRegister(uint8_t address); | |||
|   // set register | |||
|   void setRegister(uint8_t address, uint8_t value); | |||
|   // decimal to binary coded decimal | |||
|   uint8_t dectobcd(uint8_t value); | |||
|   // binary coded decimal to decimal | |||
|   uint8_t bcdtodec(uint8_t value); | |||
|   // get century value | |||
|   uint8_t getCentury(); | |||
|   // set century value | |||
|   void setCentury(uint8_t century); | |||
| }; | |||
| 
 | |||
| // I2C address | |||
| #define DS3231_I2C_ADDRESS 0x68 | |||
| 
 | |||
| // I2C registers | |||
| #define DS3231_SECONDS 0x00 | |||
| #define DS3231_MINUTES 0x01 | |||
| #define DS3231_HOURS 0x02 | |||
| #define DS3231_DAY 0x03 | |||
| #define DS3231_DATE 0x04 | |||
| #define DS3231_MONTH 0x05 | |||
| #define DS3231_YEAR 0x06 | |||
| #define DS3231_ALARM1_SECONDS 0x07 | |||
| #define DS3231_ALARM1_MINUTES 0x08 | |||
| #define DS3231_ALARM1_HOURS 0x09 | |||
| #define DS3231_ALARM1_DATE 0x0A | |||
| #define DS3231_ALARM2_MINUTES 0x0B | |||
| #define DS3231_ALARM2_HOURS 0x0C | |||
| #define DS3231_ALARM1_DATE 0x0D | |||
| #define DS3231_CONTROL 0x0E | |||
| #define DS3231_STATUS 0x0F | |||
| #define DS3231_AGING_OFFSET 0x10 | |||
| #define DS3231_MSB_TEMP 0x11 | |||
| #define DS3231_LSB_TEMP 0x12 | |||
| 
 | |||
| // control registers | |||
| #define DS3231_CONTROL_A1IE 0x01 | |||
| #define DS3231_CONTROL_A2IE 0x02 | |||
| #define DS3231_CONTROL_INTCN 0x04 | |||
| #define DS3231_CONTROL_RS1 0x08 | |||
| #define DS3231_CONTROL_RS2 0x10 | |||
| #define DS3231_CONTROL_CONV 0x20 | |||
| #define DS3231_CONTROL_BBSQW 0x40 | |||
| #define DS3231_CONTROL_EOSC 0x80 | |||
| 
 | |||
| // status registers | |||
| #define DS3231_STATUSL_A1F 0x01 | |||
| #define DS3231_STATUSL_A2F 0x02 | |||
| #define DS3231_STATUSL_BSY 0x04 | |||
| #define DS3231_STATUSL_EN32KHZ 0x08 | |||
| #define DS3231_STATUSL_OSF 0x80 | |||
| 
 | |||
| #endif | |||
| @ -0,0 +1,128 @@ | |||
| #include <ControlStates.h>
 | |||
| 
 | |||
| ControlColorState::ControlColorState(AT24C32 &_at24c32) | |||
| { | |||
|   at24c32 = _at24c32; | |||
| } | |||
| 
 | |||
| void ControlColorState::leftPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::COLOR_R: | |||
|     controlState = ControlStates::COLOR_B; | |||
|     break; | |||
|   case ControlStates::COLOR_G: | |||
|     controlState = ControlStates::COLOR_R; | |||
|     break; | |||
|   case ControlStates::COLOR_B: | |||
|     controlState = ControlStates::COLOR_G; | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlColorState::rightPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::COLOR_R: | |||
|     controlState = ControlStates::COLOR_G; | |||
|     break; | |||
|   case ControlStates::COLOR_G: | |||
|     controlState = ControlStates::COLOR_B; | |||
|     break; | |||
|   case ControlStates::COLOR_B: | |||
|     controlState = ControlStates::COLOR_R; | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlColorState::enterPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   controlState = ControlStates::VIEW; | |||
| }; | |||
| 
 | |||
| void ControlColorState::decrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::COLOR_R: | |||
|     decrementColorR(); | |||
|     break; | |||
|   case ControlStates::COLOR_G: | |||
|     decrementColorG(); | |||
|     break; | |||
|   case ControlStates::COLOR_B: | |||
|     decrementColorB(); | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlColorState::incrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::COLOR_R: | |||
|     incrementColorR(); | |||
|     break; | |||
|   case ControlStates::COLOR_G: | |||
|     incrementColorG(); | |||
|     break; | |||
|   case ControlStates::COLOR_B: | |||
|     incrementColorB(); | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlColorState::decrementColorR() | |||
| { | |||
|   uint8_t color = at24c32.read(COLOR_ADDRESS); | |||
|   uint8_t red = (color >> 5); | |||
|   red = (red - 1) % 8; | |||
|   color = (red << 5) + (color & 0x1F); | |||
|   at24c32.write(COLOR_ADDRESS, color); | |||
| } | |||
| void ControlColorState::incrementColorR() | |||
| { | |||
|   uint8_t color = at24c32.read(COLOR_ADDRESS); | |||
|   uint8_t red = (color >> 5); | |||
|   red = (red + 1) % 8; | |||
|   color = (red << 5) + (color & 0x1F); | |||
|   at24c32.write(COLOR_ADDRESS, color); | |||
| } | |||
| 
 | |||
| void ControlColorState::decrementColorG() | |||
| { | |||
|   uint8_t color = at24c32.read(COLOR_ADDRESS); | |||
|   uint8_t green = (color >> 2) & 0x07; | |||
|   green = (green - 1) % 8; | |||
|   color = (green << 2) + (color & 0xE3); | |||
|   at24c32.write(COLOR_ADDRESS, color); | |||
| } | |||
| 
 | |||
| void ControlColorState::incrementColorG() | |||
| { | |||
|   uint8_t color = at24c32.read(COLOR_ADDRESS); | |||
|   uint8_t green = (color >> 2) & 0x07; | |||
|   green = (green + 1) % 8; | |||
|   color = (green << 2) + (color & 0xE3); | |||
|   at24c32.write(COLOR_ADDRESS, color); | |||
| } | |||
| 
 | |||
| void ControlColorState::decrementColorB() | |||
| { | |||
|   uint8_t color = at24c32.read(COLOR_ADDRESS); | |||
|   uint8_t blue = color & 0x03; | |||
|   blue = (blue - 1) % 4; | |||
|   color = blue + (color & 0xFC); | |||
|   at24c32.write(COLOR_ADDRESS, color); | |||
| } | |||
| 
 | |||
| void ControlColorState::incrementColorB() | |||
| { | |||
|   uint8_t color = at24c32.read(COLOR_ADDRESS); | |||
|   uint8_t blue = color & 0x03; | |||
|   blue = (blue + 1) % 4; | |||
|   color = blue + (color & 0xFC); | |||
|   at24c32.write(COLOR_ADDRESS, color); | |||
| } | |||
| @ -0,0 +1,77 @@ | |||
| 
 | |||
| #include <ControlStates.h>
 | |||
| 
 | |||
| ControlDateState::ControlDateState(DS3231 &_ds3231) | |||
| { | |||
|   ds3231 = _ds3231; | |||
| } | |||
| 
 | |||
| void ControlDateState::leftPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::DATE_YEAR: | |||
|     controlState = ControlStates::DATE_MONTH; | |||
|     break; | |||
|   case ControlStates::DATE_MONTH: | |||
|     controlState = ControlStates::DATE_DATE; | |||
|     break; | |||
|   case ControlStates::DATE_DATE: | |||
|     controlState = ControlStates::DATE_YEAR; | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlDateState::rightPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
| 
 | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::DATE_DATE: | |||
|     controlState = ControlStates::DATE_MONTH; | |||
|     break; | |||
|   case ControlStates::DATE_MONTH: | |||
|     controlState = ControlStates::DATE_YEAR; | |||
|     break; | |||
|   case ControlStates::DATE_YEAR: | |||
|     controlState = ControlStates::DATE_DATE; | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlDateState::enterPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   controlState = ControlStates::VIEW; | |||
| }; | |||
| 
 | |||
| void ControlDateState::decrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::DATE_DATE: | |||
|     ds3231.decrementDate(); | |||
|     break; | |||
|   case ControlStates::DATE_MONTH: | |||
|     ds3231.decrementMonth(); | |||
|     break; | |||
|   case ControlStates::DATE_YEAR: | |||
|     ds3231.decrementYear(); | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlDateState::incrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::DATE_DATE: | |||
|     ds3231.incrementDate(); | |||
|     break; | |||
|   case ControlStates::DATE_MONTH: | |||
|     ds3231.incrementMonth(); | |||
|     break; | |||
|   case ControlStates::DATE_YEAR: | |||
|     ds3231.incrementYear(); | |||
|     break; | |||
|   } | |||
| }; | |||
| @ -0,0 +1,26 @@ | |||
| 
 | |||
| #include <ControlStates.h>
 | |||
| 
 | |||
| ControlSecondsState::ControlSecondsState(DS3231 &_ds3231) | |||
| { | |||
|   ds3231 = _ds3231; | |||
| } | |||
| 
 | |||
| void ControlSecondsState::leftPressed(ViewStates &viewState, ControlStates &controlState){}; | |||
| 
 | |||
| void ControlSecondsState::rightPressed(ViewStates &viewState, ControlStates &controlState){}; | |||
| 
 | |||
| void ControlSecondsState::enterPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   controlState = ControlStates::VIEW; | |||
| }; | |||
| 
 | |||
| void ControlSecondsState::decrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   ds3231.decrementSeconds(); | |||
| }; | |||
| 
 | |||
| void ControlSecondsState::incrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   ds3231.incrementSeconds(); | |||
| }; | |||
| @ -0,0 +1,130 @@ | |||
| #ifndef ControlState_h | |||
| #define ControlState_h | |||
| 
 | |||
| #include <States.h> | |||
| #include <AT24C32.h> | |||
| #include <DS3231.h> | |||
| 
 | |||
| /* | |||
| 	abstract control state | |||
|  */ | |||
| class ControlState | |||
| { | |||
| public: | |||
|   virtual void leftPressed(ViewStates &viewState, ControlStates &controlState) = 0; | |||
|   virtual void rightPressed(ViewStates &viewState, ControlStates &controlState) = 0; | |||
|   virtual void enterPressed(ViewStates &viewState, ControlStates &controlState) = 0; | |||
|   virtual void decrementPressed(ViewStates &viewState, ControlStates &controlState) = 0; | |||
|   virtual void incrementPressed(ViewStates &viewState, ControlStates &controlState) = 0; | |||
| }; | |||
| 
 | |||
| /* | |||
| 	control view state | |||
|  */ | |||
| class ControlViewState : public ControlState | |||
| { | |||
| public: | |||
|   ControlViewState(AT24C32 &_at24c32); | |||
|   void leftPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void rightPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void enterPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void decrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void incrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
| 
 | |||
| protected: | |||
|   AT24C32 at24c32; | |||
| }; | |||
| 
 | |||
| /* | |||
| 	control time state | |||
|  */ | |||
| class ControlTimeState : public ControlState | |||
| { | |||
| public: | |||
|   ControlTimeState(DS3231 &_ds3231, AT24C32 &_at24c32); | |||
|   void leftPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void rightPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void enterPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void decrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void incrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
| 
 | |||
| protected: | |||
|   DS3231 ds3231; | |||
|   AT24C32 at24c32; | |||
| }; | |||
| 
 | |||
| /* | |||
| 	control seconds state | |||
|  */ | |||
| class ControlSecondsState : public ControlState | |||
| { | |||
| public: | |||
|   ControlSecondsState(DS3231 &_ds3231); | |||
|   void leftPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void rightPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void enterPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void decrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void incrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
| 
 | |||
| protected: | |||
|   DS3231 ds3231; | |||
| }; | |||
| 
 | |||
| /* | |||
| 	control date state | |||
|  */ | |||
| class ControlDateState : public ControlState | |||
| { | |||
| public: | |||
|   ControlDateState(DS3231 &_ds3231); | |||
|   void leftPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void rightPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void enterPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void decrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void incrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
| 
 | |||
| protected: | |||
|   DS3231 ds3231; | |||
| }; | |||
| 
 | |||
| /* | |||
| 	control color value state | |||
|  */ | |||
| class ControlColorState : public ControlState | |||
| { | |||
| public: | |||
|   ControlColorState(AT24C32 &_at24c32); | |||
|   void leftPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void rightPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void enterPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void decrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void incrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
| 
 | |||
| protected: | |||
|   AT24C32 at24c32; | |||
|   void decrementColorR(); | |||
|   void incrementColorR(); | |||
|   void decrementColorG(); | |||
|   void incrementColorG(); | |||
|   void decrementColorB(); | |||
|   void incrementColorB(); | |||
| }; | |||
| 
 | |||
| /* | |||
| 	control text state | |||
|  */ | |||
| class ControlTextState : public ControlState | |||
| { | |||
| public: | |||
|   ControlTextState(AT24C32 &_at24c32); | |||
|   void leftPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void rightPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void enterPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void decrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
|   void incrementPressed(ViewStates &viewState, ControlStates &controlState); | |||
| 
 | |||
| protected: | |||
|   AT24C32 at24c32; | |||
| }; | |||
| 
 | |||
| #endif | |||
| @ -0,0 +1,62 @@ | |||
| 
 | |||
| #include <ControlStates.h>
 | |||
| 
 | |||
| ControlTextState::ControlTextState(AT24C32 &_at24c32) | |||
| { | |||
|   at24c32 = _at24c32; | |||
| } | |||
| 
 | |||
| void ControlTextState::leftPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   uint8_t length = at24c32.read(TEXT_SIZE_ADDRESS); | |||
|   if (length > 2) | |||
|   { | |||
|     length--; | |||
|     at24c32.write(TEXT_SIZE_ADDRESS, length); | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlTextState::rightPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   uint8_t length = at24c32.read(TEXT_SIZE_ADDRESS); | |||
|   if (length < 0xFF) | |||
|   { | |||
|     length++; | |||
|     at24c32.write(TEXT_SIZE_ADDRESS, length); | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlTextState::enterPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   controlState = ControlStates::VIEW; | |||
| }; | |||
| 
 | |||
| void ControlTextState::decrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   uint8_t position = at24c32.read(TEXT_SIZE_ADDRESS) - 1; | |||
|   uint8_t char1 = at24c32.read(TEXT_ADDRESS + position); | |||
|   if (char1 > 0) | |||
|   { | |||
|     char1--; | |||
|   } | |||
|   else | |||
|   { | |||
|     char1 = 0xFF; | |||
|   } | |||
|   at24c32.write(TEXT_ADDRESS + position, char1); | |||
| }; | |||
| 
 | |||
| void ControlTextState::incrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   uint8_t position = at24c32.read(TEXT_SIZE_ADDRESS) - 1; | |||
|   uint8_t char1 = at24c32.read(TEXT_ADDRESS + position); | |||
|   if (char1 < 0xFF) | |||
|   { | |||
|     char1++; | |||
|   } | |||
|   else | |||
|   { | |||
|     char1 = 0; | |||
|   } | |||
|   at24c32.write(TEXT_ADDRESS + position, char1); | |||
| }; | |||
| @ -0,0 +1,82 @@ | |||
| 
 | |||
| #include <ControlStates.h>
 | |||
| 
 | |||
| ControlTimeState::ControlTimeState(DS3231 &_ds3231, AT24C32 &_at24c32) | |||
| { | |||
|   ds3231 = _ds3231; | |||
|   at24c32 = _at24c32; | |||
| } | |||
| 
 | |||
| void ControlTimeState::leftPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::TIME_HOURS: | |||
|     controlState = ControlStates::TIME_MODE; | |||
|     break; | |||
|   case ControlStates::TIME_MINUTES: | |||
|     controlState = ControlStates::TIME_HOURS; | |||
|     break; | |||
|   case ControlStates::TIME_MODE: | |||
|     controlState = ControlStates::TIME_MINUTES; | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlTimeState::rightPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
| 
 | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::TIME_HOURS: | |||
|     controlState = ControlStates::TIME_MINUTES; | |||
|     break; | |||
|   case ControlStates::TIME_MINUTES: | |||
|     controlState = ControlStates::TIME_MODE; | |||
|     break; | |||
|   case ControlStates::TIME_MODE: | |||
|     controlState = ControlStates::TIME_HOURS; | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlTimeState::enterPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   controlState = ControlStates::VIEW; | |||
| }; | |||
| 
 | |||
| void ControlTimeState::decrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::TIME_HOURS: | |||
|     ds3231.decrementHours(); | |||
|     break; | |||
|   case ControlStates::TIME_MINUTES: | |||
|     ds3231.decrementMinutes(); | |||
|     break; | |||
|   case ControlStates::TIME_MODE: | |||
|     uint8_t mode = at24c32.read(TIME_MODE_ADDRESS); | |||
|     mode = (mode - 1) % 3; | |||
|     at24c32.write(TIME_MODE_ADDRESS, mode); | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlTimeState::incrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::TIME_HOURS: | |||
|     ds3231.incrementHours(); | |||
|     break; | |||
|   case ControlStates::TIME_MINUTES: | |||
|     ds3231.incrementMinutes(); | |||
|     break; | |||
|   case ControlStates::TIME_MODE: | |||
|     uint8_t mode = at24c32.read(TIME_MODE_ADDRESS); | |||
|     mode = (mode + 1) % 3; | |||
|     at24c32.write(TIME_MODE_ADDRESS, mode); | |||
|     break; | |||
|   } | |||
| }; | |||
| @ -0,0 +1,92 @@ | |||
| #include <ControlStates.h>
 | |||
| 
 | |||
| ControlViewState::ControlViewState(AT24C32 &_at24c32) | |||
| { | |||
|   at24c32 = _at24c32; | |||
| } | |||
| 
 | |||
| void ControlViewState::leftPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (viewState) | |||
|   { | |||
|   case ViewStates::TIME: | |||
|     viewState = ViewStates::LED_DEMO; | |||
|     break; | |||
|   case ViewStates::TEMPERATURE: | |||
|     viewState = ViewStates::TIME; | |||
|     break; | |||
|   case ViewStates::SECONDS: | |||
|     viewState = ViewStates::TEMPERATURE; | |||
|     break; | |||
|   case ViewStates::DATE: | |||
|     viewState = ViewStates::SECONDS; | |||
|     break; | |||
|   case ViewStates::TEXT: | |||
|     viewState = ViewStates::DATE; | |||
|     break; | |||
|   case ViewStates::LED_DEMO: | |||
|     viewState = ViewStates::TEXT; | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlViewState::rightPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (viewState) | |||
|   { | |||
|   case ViewStates::TIME: | |||
|     viewState = ViewStates::TEMPERATURE; | |||
|     break; | |||
|   case ViewStates::TEMPERATURE: | |||
|     viewState = ViewStates::SECONDS; | |||
|     break; | |||
|   case ViewStates::SECONDS: | |||
|     viewState = ViewStates::DATE; | |||
|     break; | |||
|   case ViewStates::DATE: | |||
|     viewState = ViewStates::TEXT; | |||
|     break; | |||
|   case ViewStates::TEXT: | |||
|     viewState = ViewStates::LED_DEMO; | |||
|     break; | |||
|   case ViewStates::LED_DEMO: | |||
|     viewState = ViewStates::TIME; | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlViewState::enterPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   switch (viewState) | |||
|   { | |||
|   case ViewStates::TIME: | |||
|     controlState = ControlStates::TIME_HOURS; | |||
|     break; | |||
|   case ViewStates::SECONDS: | |||
|     controlState = ControlStates::TIME_SECONDS; | |||
|     break; | |||
|   case ViewStates::DATE: | |||
|     controlState = ControlStates::DATE_DATE; | |||
|     break; | |||
|   case ViewStates::TEXT: | |||
|     controlState = ControlStates::TEXT; | |||
|     break; | |||
|   case ViewStates::LED_DEMO: | |||
|     controlState = ControlStates::COLOR_R; | |||
|     break; | |||
|   } | |||
| }; | |||
| 
 | |||
| void ControlViewState::decrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   uint8_t value = at24c32.read(BRIGHTNESS_ADDRESS); | |||
|   value = (value - 5) % 256; | |||
|   at24c32.write(BRIGHTNESS_ADDRESS, value); | |||
| }; | |||
| 
 | |||
| void ControlViewState::incrementPressed(ViewStates &viewState, ControlStates &controlState) | |||
| { | |||
|   uint8_t value = at24c32.read(BRIGHTNESS_ADDRESS); | |||
|   value = (value + 5) % 256; | |||
|   at24c32.write(BRIGHTNESS_ADDRESS, value); | |||
| }; | |||
| @ -0,0 +1,50 @@ | |||
| #ifndef States_h | |||
| #define States_h | |||
| 
 | |||
| /** | |||
|   view states | |||
|  */ | |||
| enum class ViewStates | |||
| { | |||
|   TIME, | |||
|   SECONDS, | |||
|   TEMPERATURE, | |||
|   DATE, | |||
|   TEXT, | |||
|   LED_DEMO, | |||
|   REMOTE | |||
| }; | |||
| 
 | |||
| /** | |||
|   control states | |||
|  */ | |||
| enum class ControlStates | |||
| { | |||
|   VIEW, | |||
|   TIME_HOURS, | |||
|   TIME_MINUTES, | |||
|   TIME_MODE, | |||
|   TIME_SECONDS, | |||
|   COLOR_R, | |||
|   COLOR_G, | |||
|   COLOR_B, | |||
|   DATE_DATE, | |||
|   DATE_MONTH, | |||
|   DATE_YEAR, | |||
|   TEXT | |||
| }; | |||
| 
 | |||
| /** | |||
|   remote control states | |||
|  */ | |||
| enum class RemoteStates | |||
| { | |||
|   VIEW, | |||
|   TIME, | |||
|   COLOR, | |||
|   DATE, | |||
|   TEXT, | |||
|   DRAW | |||
| }; | |||
| 
 | |||
| #endif | |||
| @ -0,0 +1,96 @@ | |||
| 
 | |||
| #include <ViewStates.h>
 | |||
| 
 | |||
| ViewDateState::ViewDateState(DS3231 &_ds3231, AT24C32 &_at24c32, char _delimiter) : ViewTextState(at24c32) | |||
| { | |||
|   ds3231 = _ds3231; | |||
|   at24c32 = _at24c32; | |||
|   delimiter = _delimiter; | |||
|   renderOffset = (millis() / TEXT_INTERVAL); | |||
| }; | |||
| 
 | |||
| void ViewDateState::render(uint8_t matrix[121], ControlStates controlState) | |||
| { | |||
| 
 | |||
|   bool const blink = (millis() / CONTROL_BLINK_INTERVAL) % 2 == 0; | |||
| 
 | |||
|   length = 0; | |||
|   position = 0; | |||
| 
 | |||
|   uint8_t date = ds3231.getDate(); | |||
|   uint8_t month = ds3231.getMonth(); | |||
|   int16_t year = ds3231.getYear(); | |||
| 
 | |||
|   if (controlState == ControlStates::DATE_DATE && blink) | |||
|   { | |||
|     length = 2; | |||
|     text[0] = (date / 10) + 0x30; | |||
|     text[1] = (date % 10) + 0x30; | |||
|     ViewTextState::writeChars(matrix); | |||
|   } | |||
|   else if (controlState == ControlStates::DATE_MONTH && blink) | |||
|   { | |||
|     length = 2; | |||
|     text[0] = (month / 10) + 0x30; | |||
|     text[1] = (month % 10) + 0x30; | |||
|     ViewTextState::writeChars(matrix); | |||
|   } | |||
|   else if (controlState == ControlStates::DATE_YEAR && blink) | |||
|   { | |||
|     if (year == 2000 || year == 1900) | |||
|     { | |||
|       length = 4; | |||
|       text[0] = ((year / 100) / 10) + 0x30; | |||
|       text[1] = ((year / 100) % 10) + 0x30; | |||
|       position = (millis() / TEXT_INTERVAL) % length; | |||
|     } | |||
|     else | |||
|     { | |||
|       length = 2; | |||
|     } | |||
|     if (year > 1999) | |||
|     { | |||
|       year = year - 2000; | |||
|     } | |||
|     else | |||
|     { | |||
|       year = year - 1900; | |||
|     } | |||
| 
 | |||
|     text[length - 2] = (year / 10) + 0x30; | |||
|     text[length - 1] = (year % 10) + 0x30; | |||
| 
 | |||
|     ViewTextState::writeChars(matrix); | |||
|   } | |||
|   else if (controlState != ControlStates::DATE_DATE && controlState != ControlStates::DATE_MONTH && controlState != ControlStates::DATE_YEAR) | |||
|   { | |||
|     length = 10; | |||
|     text[0] = (date / 10) + 0x30; | |||
|     text[1] = (date % 10) + 0x30; | |||
| 
 | |||
|     text[2] = char(delimiter); | |||
| 
 | |||
|     text[3] = (month / 10) + 0x30; | |||
|     text[4] = (month % 10) + 0x30; | |||
| 
 | |||
|     text[5] = char(delimiter); | |||
| 
 | |||
|     text[6] = ((year / 100) / 10) + 0x30; | |||
|     text[7] = ((year / 100) % 10) + 0x30; | |||
|     if (year > 1999) | |||
|     { | |||
|       text[8] = ((year - 2000) / 10) + 0x30; | |||
|       text[9] = ((year - 2000) % 10) + 0x30; | |||
|     } | |||
|     else | |||
|     { | |||
|       text[8] = ((year - 1900) / 10) + 0x30; | |||
|       text[9] = ((year - 1900) % 10) + 0x30; | |||
|     } | |||
| 
 | |||
|     position = (millis() / TEXT_INTERVAL - renderOffset - 1) % length; | |||
|     ViewTextState::writeChars(matrix); | |||
|   } | |||
| 
 | |||
|   renderBinaryClock(matrix, ds3231); | |||
| }; | |||
| @ -0,0 +1,76 @@ | |||
| 
 | |||
| #include <ViewStates.h>
 | |||
| 
 | |||
| ViewLEDState::ViewLEDState(){ | |||
| 
 | |||
| }; | |||
| 
 | |||
| void ViewLEDState::render(uint8_t matrix[121], ControlStates controlState) | |||
| { | |||
| 
 | |||
|   if (controlState != ControlStates::COLOR_R && controlState != ControlStates::COLOR_G && controlState != ControlStates::COLOR_B) | |||
|   { | |||
|     int const color = (millis() / 500) % 256; | |||
| 
 | |||
|     for (int i = 0; i < 121; i++) | |||
|     { | |||
|       matrix[i] = color - i % 256; | |||
|     } | |||
|   } | |||
|   else | |||
|   { | |||
|     // special color edit view
 | |||
|     bool const blink = (millis() / CONTROL_BLINK_INTERVAL) % 2 == 0; | |||
| 
 | |||
|     if (controlState != ControlStates::COLOR_R || blink) | |||
|     { | |||
|       uint8_t red = color >> 5; | |||
|       matrix[0] = 0x07 << 5; | |||
|       matrix[10] = 0x07 << 5; | |||
|       matrix[11] = 0x07 << 5; | |||
|       matrix[21] = 0x07 << 5; | |||
|       for (int i = 0; i < red; i++) | |||
|       { | |||
|         // red
 | |||
|         matrix[i + 2] = red << 5; | |||
|         matrix[i + 13] = red << 5; | |||
|       } | |||
|     } | |||
| 
 | |||
|     if (controlState != ControlStates::COLOR_G || blink) | |||
|     { | |||
|       uint8_t green = (color >> 2) & 0x07; | |||
|       matrix[22] = 0x07 << 2; | |||
|       matrix[32] = 0x07 << 2; | |||
|       matrix[33] = 0x07 << 2; | |||
|       matrix[43] = 0x07 << 2; | |||
|       for (int i = 0; i < green; i++) | |||
|       { | |||
|         // green
 | |||
|         matrix[i + 24] = green << 2; | |||
|         matrix[i + 35] = green << 2; | |||
|       } | |||
|     } | |||
| 
 | |||
|     if (controlState != ControlStates::COLOR_B || blink) | |||
|     { | |||
| 
 | |||
|       uint8_t blue = color & 0x03; | |||
|       matrix[44] = 0x03; | |||
|       matrix[54] = 0x03; | |||
|       matrix[55] = 0x03; | |||
|       matrix[65] = 0x03; | |||
|       for (int i = 0; i < blue; i++) | |||
|       { | |||
|         // blue
 | |||
|         matrix[i + 46] = blue; | |||
|         matrix[i + 57] = blue; | |||
|       } | |||
|     } | |||
| 
 | |||
|     for (int i = 77; i < 121; i++) | |||
|     { | |||
|       matrix[i] = color; | |||
|     } | |||
|   } | |||
| } | |||
| @ -0,0 +1,11 @@ | |||
| 
 | |||
| #include <ViewStates.h>
 | |||
| 
 | |||
| ViewRemoteState::ViewRemoteState(){ | |||
| 
 | |||
| }; | |||
| 
 | |||
| void ViewRemoteState::render(uint8_t matrix[121], ControlStates controlState) | |||
| { | |||
|   // nothing, LEDs set via remote control
 | |||
| } | |||
| @ -0,0 +1,28 @@ | |||
| 
 | |||
| #include <ViewStates.h>
 | |||
| 
 | |||
| ViewSecondsState::ViewSecondsState(DS3231 &_ds3231, AT24C32 &_at24c32) : ViewTextState(at24c32) | |||
| { | |||
|   ds3231 = _ds3231; | |||
|   at24c32 = _at24c32; | |||
| }; | |||
| 
 | |||
| void ViewSecondsState::render(uint8_t matrix[121], ControlStates controlState) | |||
| { | |||
|   uint8_t const seconds = ds3231.getSeconds(); | |||
| 
 | |||
|   bool const blink = (millis() / CONTROL_BLINK_INTERVAL) % 2 == 0; | |||
| 
 | |||
|   length = 0; | |||
| 
 | |||
|   if (controlState != ControlStates::TIME_SECONDS || blink) | |||
|   { | |||
|     length = 2; | |||
|     text[0] = (seconds / 10) + 0x30; | |||
|     text[1] = (seconds % 10) + 0x30; | |||
|   } | |||
| 
 | |||
|   ViewTextState::writeChars(matrix); | |||
| 
 | |||
|   renderBinaryClock(matrix, ds3231); | |||
| } | |||
| @ -0,0 +1,29 @@ | |||
| 
 | |||
| #include <ViewStates.h>
 | |||
| 
 | |||
| void ViewState::setColor(uint8_t _color) | |||
| { | |||
|   color = _color; | |||
| }; | |||
| 
 | |||
| void ViewState::renderBinaryClock(uint8_t matrix[121], DS3231 &ds3231) | |||
| { | |||
|   uint8_t h = ds3231.getHours() % 12; | |||
|   uint8_t mm = ds3231.getMinutes(); | |||
| 
 | |||
|   for (int b = 0; b < 4; b++) | |||
|   { | |||
|     if (bitRead(h, b)) | |||
|     { | |||
|       matrix[110 + b] = color; | |||
|     } | |||
|   } | |||
| 
 | |||
|   for (int b = 0; b < 6; b++) | |||
|   { | |||
|     if (bitRead(mm, b)) | |||
|     { | |||
|       matrix[115 + b] = color; | |||
|     } | |||
|   } | |||
| }; | |||
| @ -0,0 +1,142 @@ | |||
| #ifndef ViewState_h | |||
| #define ViewState_h | |||
| 
 | |||
| #include <States.h> | |||
| #include <DS3231.h> | |||
| #include <AT24C32.h> | |||
| 
 | |||
| using namespace std; | |||
| 
 | |||
| // I2C address | |||
| #define TEXT_INTERVAL 1000 | |||
| #define CONTROL_BLINK_INTERVAL 250 | |||
| 
 | |||
| /** | |||
|   led matrix entry | |||
|  */ | |||
| struct matrix_entry | |||
| { | |||
|   uint8_t row; | |||
|   uint8_t columnFrom; | |||
|   uint8_t columnTo; | |||
|   bool notNull; | |||
| }; | |||
| 
 | |||
| /** | |||
|   abstract view state | |||
|  */ | |||
| class ViewState | |||
| { | |||
| public: | |||
|   virtual void render(uint8_t matrix[121], ControlStates controlState) = 0; | |||
|   void setColor(uint8_t _color); | |||
| 
 | |||
| protected: | |||
|   void renderBinaryClock(uint8_t matrix[121], DS3231 &ds3231); | |||
|   uint8_t color = 0xFF; | |||
| }; | |||
| 
 | |||
| /** | |||
|   view time state | |||
|  */ | |||
| class ViewTimeState : public ViewState | |||
| { | |||
| public: | |||
|   ViewTimeState(DS3231 &_ds3231, AT24C32 &_at24c32); | |||
|   void render(uint8_t matrix[121], ControlStates controlState); | |||
| 
 | |||
| protected: | |||
|   DS3231 ds3231; | |||
|   AT24C32 at24c32; | |||
|   matrix_entry text[2]; | |||
|   matrix_entry hours[12][2]; | |||
|   matrix_entry minutes[12][3]; | |||
|   uint8_t increment; | |||
|   uint8_t mode = 0; | |||
|   void init(); | |||
|   void setWord(uint8_t matrix[121], matrix_entry word); | |||
|   void setWessi(); | |||
|   void setOssi(); | |||
| }; | |||
| 
 | |||
| /** | |||
|   view text state | |||
|  */ | |||
| class ViewTextState : public ViewState | |||
| { | |||
| public: | |||
|   ViewTextState(AT24C32 &_at24c32); | |||
|   void render(uint8_t matrix[121], ControlStates controlState); | |||
| 
 | |||
| protected: | |||
|   void writeText(uint8_t matrix[121]); | |||
|   void writeChars(uint8_t matrix[121]); | |||
|   AT24C32 at24c32; | |||
|   uint8_t text[0xFF]; | |||
|   uint8_t length = 0; | |||
|   uint8_t position = 0; | |||
|   uint8_t v_offset = 1; | |||
|   long renderOffset; | |||
| }; | |||
| 
 | |||
| /** | |||
|   view seconds state | |||
|  */ | |||
| class ViewSecondsState : public ViewTextState | |||
| { | |||
| public: | |||
|   ViewSecondsState(DS3231 &_ds3231, AT24C32 &_at24c32); | |||
|   void render(uint8_t matrix[121], ControlStates controlState); | |||
| 
 | |||
| protected: | |||
|   DS3231 ds3231; | |||
| }; | |||
| 
 | |||
| /** | |||
|   view temperature state | |||
|  */ | |||
| class ViewTemperatureState : public ViewTextState | |||
| { | |||
| public: | |||
|   ViewTemperatureState(DS3231 &_ds3231, AT24C32 &_at24c32); | |||
|   void render(uint8_t matrix[121], ControlStates controlState); | |||
| 
 | |||
| protected: | |||
|   DS3231 ds3231; | |||
| }; | |||
| 
 | |||
| /** | |||
|   view date state | |||
|  */ | |||
| class ViewDateState : public ViewTextState | |||
| { | |||
| public: | |||
|   ViewDateState(DS3231 &_ds3231, AT24C32 &_at24c32, char _delimiter); | |||
|   void render(uint8_t matrix[121], ControlStates controlState); | |||
| 
 | |||
| protected: | |||
|   DS3231 ds3231; | |||
|   char delimiter; | |||
| }; | |||
| 
 | |||
| /** | |||
|   view LED demo state | |||
|  */ | |||
| class ViewLEDState : public ViewState | |||
| { | |||
| public: | |||
|   ViewLEDState(); | |||
|   void render(uint8_t matrix[121], ControlStates controlState); | |||
| }; | |||
| 
 | |||
| /** | |||
|   view Remote demo state | |||
|  */ | |||
| class ViewRemoteState : public ViewState | |||
| { | |||
| public: | |||
|   ViewRemoteState(); | |||
|   void render(uint8_t matrix[121], ControlStates controlState); | |||
| }; | |||
| 
 | |||
| #endif | |||
| @ -0,0 +1,28 @@ | |||
| 
 | |||
| #include <ViewStates.h>
 | |||
| 
 | |||
| ViewTemperatureState::ViewTemperatureState(DS3231 &_ds3231, AT24C32 &_at24c32) : ViewTextState(at24c32) | |||
| { | |||
|   ds3231 = _ds3231; | |||
|   at24c32 = _at24c32; | |||
| }; | |||
| 
 | |||
| void ViewTemperatureState::render(uint8_t matrix[121], ControlStates controlState) | |||
| { | |||
|   // °
 | |||
|   matrix[9] = color; | |||
|   matrix[10] = color; | |||
|   matrix[20] = color; | |||
|   matrix[21] = color; | |||
| 
 | |||
|   int temperature = floor(ds3231.getTemperature()); | |||
| 
 | |||
|   length = 2; | |||
| 
 | |||
|   text[0] = (temperature / 10) + 0x30; | |||
|   text[1] = (temperature % 10) + 0x30; | |||
| 
 | |||
|   ViewTextState::writeChars(matrix); | |||
| 
 | |||
|   renderBinaryClock(matrix, ds3231); | |||
| } | |||
| @ -0,0 +1,85 @@ | |||
| 
 | |||
| #include <ViewStates.h>
 | |||
| 
 | |||
| ViewTextState::ViewTextState(AT24C32 &_at24c32) | |||
| { | |||
|   at24c32 = _at24c32; | |||
|   renderOffset = (millis() / TEXT_INTERVAL); | |||
| }; | |||
| 
 | |||
| void ViewTextState::render(uint8_t matrix[121], ControlStates controlState) | |||
| { | |||
|   length = at24c32.read(TEXT_SIZE_ADDRESS); | |||
| 
 | |||
|   if (controlState != ControlStates::TEXT) | |||
|   { | |||
|     for (uint8_t i = 0; i < length; i++) | |||
|     { | |||
|       text[i] = at24c32.read(TEXT_ADDRESS + i); | |||
|     } | |||
|     writeText(matrix); | |||
|   } | |||
|   else | |||
|   { | |||
|     bool const blink = (millis() / CONTROL_BLINK_INTERVAL) % 2 == 0; | |||
|     position = 0; | |||
|     text[0] = 0x20; | |||
|     text[1] = 0x20; | |||
|     if (length > 2) | |||
|     { | |||
|       text[0] = at24c32.read(TEXT_ADDRESS + length - 2); | |||
|       if (blink) | |||
|       { | |||
|         text[1] = at24c32.read(TEXT_ADDRESS + length - 1); | |||
|       } | |||
|     } | |||
|     else if (length > 1 && blink) | |||
|     { | |||
|       text[0] = at24c32.read(TEXT_ADDRESS + length - 1); | |||
|     } | |||
|     writeChars(matrix); | |||
|   } | |||
| } | |||
| 
 | |||
| void ViewTextState::writeText(uint8_t matrix[121]) | |||
| { | |||
|   position = (millis() / TEXT_INTERVAL - renderOffset - 1) % (length + 2); | |||
|   writeChars(matrix); | |||
| } | |||
| 
 | |||
| void ViewTextState::writeChars(uint8_t matrix[121]) | |||
| { | |||
|   uint8_t char1 = 0x20; | |||
| 
 | |||
|   uint8_t char2 = 0x20; | |||
| 
 | |||
|   if (length > position) | |||
|   { | |||
|     char1 = text[position]; | |||
|   } | |||
| 
 | |||
|   if (length > position + 1) | |||
|   { | |||
|     char2 = text[position + 1]; | |||
|   } | |||
| 
 | |||
|   for (int col = 0; col < 5; col++) | |||
|   { | |||
|     // created ascii chars in 'ascii_memory.ino' to  AT23C32 epromm
 | |||
|     uint8_t char1Byte = at24c32.read(char1 * 5 + col); | |||
|     uint8_t char2Byte = at24c32.read(char2 * 5 + col); | |||
| 
 | |||
|     for (int row = 0; row < 8; row++) | |||
|     { | |||
|       if (!!(char1Byte & (1 << row))) | |||
|       { | |||
|         matrix[(row + v_offset) * 11 + col] = color; | |||
|       } | |||
| 
 | |||
|       if (!!(char2Byte & (1 << row))) | |||
|       { | |||
|         matrix[(row + v_offset) * 11 + col + 6] = color; | |||
|       } | |||
|     } | |||
|   } | |||
| } | |||
| @ -0,0 +1,219 @@ | |||
| 
 | |||
| #include <ViewStates.h>
 | |||
| 
 | |||
| ViewTimeState::ViewTimeState(DS3231 &_ds3231, AT24C32 &_at24c32) | |||
| { | |||
|   ds3231 = _ds3231; | |||
|   at24c32 = _at24c32; | |||
|   init(); | |||
| } | |||
| 
 | |||
| /*
 | |||
|   default german matrix layout | |||
| 
 | |||
|   'E', 'S', 'K', 'I', 'S', 'T', 'L', 'F', 'Ü', 'N', 'F', | |||
|   'Z', 'E', 'H', 'N', 'Z', 'W', 'A', 'N', 'Z', 'I', 'G', | |||
|   'D', 'R', 'E', 'I', 'V', 'I', 'E', 'R', 'T', 'E', 'L', | |||
|   'T', 'A', 'N', 'A', 'C', 'H', 'V', 'O', 'R', 'J', 'M', | |||
|   'H', 'A', 'L', 'B', 'X', 'Z', 'W', 'Ö', 'L', 'F', 'P', | |||
|   'Z', 'W', 'E', 'I', 'N', 'S', 'I', 'E', 'B', 'E', 'N', | |||
|   'K', 'D', 'R', 'E', 'I', 'R', 'H', 'F', 'Ü', 'N', 'F', | |||
|   'E', 'L', 'F', 'N', 'E', 'U', 'N', 'V', 'I', 'E', 'R', | |||
|   'W', 'A', 'C', 'H', 'T', 'Z', 'E', 'H', 'N', 'R', 'S', | |||
|   'B', 'S', 'E', 'C', 'H', 'S', 'F', 'M', 'U', 'H', 'R', | |||
|   'B', 'S', 'E', 'C', 'H', 'S', 'F', 'M', 'U', 'H', 'R', | |||
|   '□', '□', '□', '□', '▣', '□', '□', '□', '□', '□', '□', | |||
|    | |||
|  */ | |||
| void ViewTimeState::init() | |||
| { | |||
|   text[0] = {0, 0, 1, true}; | |||
|   text[1] = {0, 3, 5, true}; | |||
| 
 | |||
|   hours[0][0] = {4, 5, 9, true}; | |||
|   hours[0][1] = {0, 0, 0, false}; | |||
|   hours[1][0] = {5, 2, 4, true}; | |||
|   hours[1][1] = {5, 2, 5, true}; | |||
|   hours[2][0] = {5, 0, 3, true}; | |||
|   hours[2][1] = {0, 0, 0, false}; | |||
|   hours[3][0] = {6, 1, 4, true}; | |||
|   hours[3][1] = {0, 0, 0, false}; | |||
|   hours[4][0] = {7, 7, 10, true}; | |||
|   hours[4][1] = {0, 0, 0, false}; | |||
|   hours[5][0] = {6, 7, 10, true}; | |||
|   hours[5][1] = {0, 0, 0, false}; | |||
|   hours[6][0] = {9, 1, 5, true}; | |||
|   hours[6][1] = {0, 0, 0, false}; | |||
|   hours[7][0] = {5, 5, 10, true}; | |||
|   hours[7][1] = {0, 0, 0, false}; | |||
|   hours[8][0] = {8, 1, 4, true}; | |||
|   hours[8][1] = {0, 0, 0, false}; | |||
|   hours[9][0] = {7, 3, 6, true}; | |||
|   hours[9][1] = {0, 0, 0, false}; | |||
|   hours[10][0] = {8, 5, 8, true}; | |||
|   hours[10][1] = {0, 0, 0, false}; | |||
|   hours[11][0] = {7, 0, 2, true}; | |||
|   hours[11][1] = {0, 0, 0, false}; | |||
| 
 | |||
|   // 0
 | |||
|   minutes[0][0] = {9, 8, 10, true}; | |||
|   minutes[0][1] = {0, 0, 0, false}; | |||
|   minutes[0][2] = {0, 0, 0, false}; | |||
|   // 5
 | |||
|   minutes[1][0] = {0, 7, 10, true}; | |||
|   minutes[1][1] = {3, 2, 5, true}; | |||
|   minutes[1][2] = {0, 0, 0, false}; | |||
|   // 10
 | |||
|   minutes[2][0] = {1, 0, 3, true}; | |||
|   minutes[2][1] = {3, 2, 5, true}; | |||
|   minutes[2][2] = {0, 0, 0, false}; | |||
|   // 15
 | |||
|   minutes[3][0] = {2, 4, 10, true}; | |||
|   minutes[3][1] = {3, 2, 5, true}; | |||
|   minutes[3][2] = {0, 0, 0, false}; | |||
|   // 20
 | |||
|   minutes[4][0] = {1, 4, 10, true}; | |||
|   minutes[4][1] = {3, 2, 5, true}; | |||
|   minutes[4][2] = {0, 0, 0, false}; | |||
|   // 25
 | |||
|   minutes[5][0] = {0, 7, 10, true}; | |||
|   minutes[5][1] = {3, 6, 8, true}; | |||
|   minutes[5][2] = {4, 0, 3, true}; | |||
|   // 30
 | |||
|   minutes[6][0] = {4, 0, 3, true}; | |||
|   minutes[6][1] = {0, 0, 0, false}; | |||
|   minutes[6][2] = {0, 0, 0, false}; | |||
|   // 35
 | |||
|   minutes[7][0] = {0, 7, 10, true}; | |||
|   minutes[7][1] = {3, 2, 5, true}; | |||
|   minutes[7][2] = {4, 0, 3, true}; | |||
|   // 40
 | |||
|   minutes[8][0] = {1, 4, 10, true}; | |||
|   minutes[8][1] = {3, 6, 8, true}; | |||
|   minutes[8][2] = {0, 0, 0, false}; | |||
|   // 45
 | |||
|   minutes[9][0] = {2, 4, 10, true}; | |||
|   minutes[9][1] = {3, 6, 8, true}; | |||
|   minutes[9][2] = {0, 0, 0, false}; | |||
|   // 50
 | |||
|   minutes[10][0] = {1, 0, 3, true}; | |||
|   minutes[10][1] = {3, 6, 8, true}; | |||
|   minutes[10][2] = {0, 0, 0, false}; | |||
|   // 55
 | |||
|   minutes[11][0] = {0, 7, 10, true}; | |||
|   minutes[11][1] = {3, 6, 8, true}; | |||
|   minutes[11][2] = {0, 0, 0, false}; | |||
| 
 | |||
|   increment = 24; | |||
| } | |||
| 
 | |||
| void ViewTimeState::setWessi() | |||
| { | |||
|   init(); | |||
|   minutes[4][0] = {1, 0, 3, true}; | |||
|   minutes[4][1] = {3, 6, 8, true}; | |||
|   minutes[4][2] = {4, 0, 3, true}; | |||
| 
 | |||
|   minutes[8][0] = {1, 0, 3, true}; | |||
|   minutes[8][1] = {3, 2, 5, true}; | |||
|   minutes[8][2] = {4, 0, 3, true}; | |||
| 
 | |||
|   increment = 19; | |||
| } | |||
| 
 | |||
| void ViewTimeState::setOssi() | |||
| { | |||
|   setWessi(); | |||
| 
 | |||
|   minutes[3][0] = {2, 4, 10, true}; | |||
|   minutes[3][1] = {0, 0, 0, false}; | |||
| 
 | |||
|   minutes[9][0] = {2, 0, 10, true}; | |||
|   minutes[9][1] = {0, 0, 0, false}; | |||
|   increment = 14; | |||
| } | |||
| 
 | |||
| void ViewTimeState::setWord(uint8_t matrix[121], matrix_entry word) | |||
| { | |||
|   int row; | |||
|   for (int i = word.columnFrom; i <= word.columnTo; i++) | |||
|   { | |||
|     row = word.row * 11 + i; | |||
|     matrix[row] = color; | |||
|   } | |||
| } | |||
| 
 | |||
| void ViewTimeState::render(uint8_t matrix[121], ControlStates controlState) | |||
| { | |||
| 
 | |||
|   uint8_t currentMode = at24c32.read(TIME_MODE_ADDRESS); | |||
| 
 | |||
|   if (mode != currentMode) | |||
|   { | |||
|     mode = currentMode; | |||
|     switch (mode) | |||
|     { | |||
|     case 1: | |||
|       setWessi(); | |||
|       break; | |||
|     case 2: | |||
|       setOssi(); | |||
|       break; | |||
|     default: | |||
|       init(); | |||
|     } | |||
|   } | |||
| 
 | |||
|   bool const blink = (millis() / CONTROL_BLINK_INTERVAL) % 2 == 0; | |||
| 
 | |||
|   if (controlState != ControlStates::TIME_MODE || blink) | |||
|   { | |||
|     setWord(matrix, text[0]); | |||
|     setWord(matrix, text[1]); | |||
|   } | |||
| 
 | |||
|   uint8_t mm = ds3231.getMinutes(); | |||
|   uint8_t m = mm / 5; | |||
|   uint8_t h = ds3231.getHours() % 12; | |||
|   uint8_t s = ds3231.getSeconds(); | |||
| 
 | |||
|   // increment hours
 | |||
|   if (mm > increment) | |||
|   { | |||
|     h = (h + 1) % 12; | |||
|   } | |||
| 
 | |||
|   // set hours
 | |||
|   if (controlState != ControlStates::TIME_HOURS || blink) | |||
|   { | |||
|     setWord(matrix, hours[h][0]); | |||
|     if (mm >= 5 && hours[h][1].notNull == true) | |||
|     { | |||
|       setWord(matrix, hours[h][1]); | |||
|     } | |||
|   } | |||
| 
 | |||
|   // set 5 minutes
 | |||
|   if (controlState != ControlStates::TIME_MINUTES || blink) | |||
|   { | |||
|     for (int i = 0; i < 3; i++) | |||
|     { | |||
|       if (minutes[m][i].notNull == true) | |||
|       { | |||
|         setWord(matrix, minutes[m][i]); | |||
|       } | |||
|     } | |||
|   } | |||
| 
 | |||
|   // set minutes
 | |||
|   if (mm % 5 > 0) | |||
|   { | |||
|     if (controlState != ControlStates::TIME_MINUTES || blink) | |||
|     { | |||
|       setWord(matrix, {10, 0, mm % 5 - 1}); | |||
|     } | |||
|   } | |||
| 
 | |||
|   // set seconds
 | |||
|   setWord(matrix, {10, 5, 5 + (s / 10)}); | |||
| } | |||
| @ -0,0 +1,385 @@ | |||
| #include <Wire.h>
 | |||
| #include <Adafruit_NeoPixel.h>
 | |||
| 
 | |||
| #include <AT24C32.h>
 | |||
| #include <DS3231.h>
 | |||
| 
 | |||
| #include <States.h>
 | |||
| #include <ViewStates.h>
 | |||
| #include <ControlStates.h>
 | |||
| #include <Button.h>
 | |||
| 
 | |||
| // debug
 | |||
| #define DEBUG 1
 | |||
| 
 | |||
| // Neopixel
 | |||
| #define MATRIX_PIN 12
 | |||
| #define MATRIX_SIZE 121
 | |||
| Adafruit_NeoPixel pixels = Adafruit_NeoPixel(MATRIX_SIZE, MATRIX_PIN, NEO_GRB + NEO_KHZ800); | |||
| 
 | |||
| // Date view delimiter
 | |||
| #define DATE_DELIMITER '.'
 | |||
| 
 | |||
| // Buttons
 | |||
| #define LEFT_PIN 11
 | |||
| #define DECREMENT_PIN 10
 | |||
| #define ENTER_PIN 9
 | |||
| #define INCREMENT_PIN 8
 | |||
| #define RIGHT_PIN 7
 | |||
| 
 | |||
| Button leftBtn = Button(LEFT_PIN, LOW); | |||
| Button decrementBtn = Button(DECREMENT_PIN, LOW); | |||
| Button enterBtn = Button(ENTER_PIN, LOW); | |||
| Button incrementBtn = Button(INCREMENT_PIN, LOW); | |||
| Button rightBtn = Button(RIGHT_PIN, LOW); | |||
| 
 | |||
| // LED matrix
 | |||
| uint8_t matrix[MATRIX_SIZE]; | |||
| 
 | |||
| // EPROMM AT24C32
 | |||
| AT24C32 at24c32; | |||
| 
 | |||
| // RTC DS3231
 | |||
| DS3231 ds3231; | |||
| 
 | |||
| // states
 | |||
| ControlStates controlState = ControlStates::VIEW; | |||
| ControlStates oldControlState = ControlStates::VIEW; | |||
| ViewStates viewState = ViewStates::TIME; | |||
| ViewStates oldViewState = ViewStates::TIME; | |||
| 
 | |||
| // control state
 | |||
| ControlState *currentControlState = new ControlViewState(at24c32); | |||
| 
 | |||
| // view state
 | |||
| ViewState *currentViewState = new ViewTimeState(ds3231, at24c32); | |||
| 
 | |||
| /**
 | |||
|   setup | |||
|  */ | |||
| void setup() | |||
| { | |||
| #ifdef DEBUG
 | |||
|   Serial.begin(9600); | |||
| #endif
 | |||
|   pixels.begin(); | |||
|   ds3231.begin(); | |||
|   at24c32.begin(); | |||
| 
 | |||
|   leftBtn.begin(); | |||
|   decrementBtn.begin(); | |||
|   enterBtn.begin(); | |||
|   incrementBtn.begin(); | |||
|   rightBtn.begin(); | |||
| 
 | |||
|   viewState = ViewStates(at24c32.read(VIEW_STATE_ADDRESS) % 6); | |||
| 
 | |||
|   printStatus(); | |||
| } | |||
| 
 | |||
| /**
 | |||
|   loop | |||
|  */ | |||
| void loop() | |||
| { | |||
|   checkControlState(); | |||
|   controls(); | |||
|   checkViewState(); | |||
|   // render
 | |||
|   renderInterval(); | |||
| } | |||
| 
 | |||
| /**
 | |||
|   check current control state and change eventually | |||
|  */ | |||
| void checkControlState() | |||
| { | |||
|   if (controlState != oldControlState) | |||
|   { | |||
|     delete currentControlState; | |||
|     switch (controlState) | |||
|     { | |||
|     case ControlStates::VIEW: | |||
|       currentControlState = new ControlViewState(at24c32); | |||
|       break; | |||
|     case ControlStates::TIME_HOURS: | |||
|       currentControlState = new ControlTimeState(ds3231, at24c32); | |||
|       break; | |||
|     case ControlStates::TIME_MINUTES: | |||
|       currentControlState = new ControlTimeState(ds3231, at24c32); | |||
|       break; | |||
|     case ControlStates::TIME_MODE: | |||
|       currentControlState = new ControlTimeState(ds3231, at24c32); | |||
|       break; | |||
|     case ControlStates::TIME_SECONDS: | |||
|       currentControlState = new ControlSecondsState(ds3231); | |||
|       break; | |||
|     case ControlStates::DATE_DATE: | |||
|       currentControlState = new ControlDateState(ds3231); | |||
|       break; | |||
|     case ControlStates::DATE_MONTH: | |||
|       currentControlState = new ControlDateState(ds3231); | |||
|       break; | |||
|     case ControlStates::DATE_YEAR: | |||
|       currentControlState = new ControlDateState(ds3231); | |||
|       break; | |||
|     case ControlStates::COLOR_R: | |||
|       currentControlState = new ControlColorState(at24c32); | |||
|       break; | |||
|     case ControlStates::COLOR_G: | |||
|       currentControlState = new ControlColorState(at24c32); | |||
|       break; | |||
|     case ControlStates::COLOR_B: | |||
|       currentControlState = new ControlColorState(at24c32); | |||
|       break; | |||
|     case ControlStates::TEXT: | |||
|       currentControlState = new ControlTextState(at24c32); | |||
|       break; | |||
|     default: | |||
|       currentControlState = new ControlViewState(at24c32); | |||
|     } | |||
|     oldControlState = controlState; | |||
| 
 | |||
|     printStatus(); | |||
|   } | |||
| } | |||
| 
 | |||
| /**
 | |||
|   check current view state and change eventually | |||
|  */ | |||
| void checkViewState() | |||
| { | |||
|   if (viewState != oldViewState) | |||
|   { | |||
|     delete currentViewState; | |||
|     switch (viewState) | |||
|     { | |||
|     case ViewStates::TIME: | |||
|       currentViewState = new ViewTimeState(ds3231, at24c32); | |||
|       break; | |||
|     case ViewStates::SECONDS: | |||
|       currentViewState = new ViewSecondsState(ds3231, at24c32); | |||
|       break; | |||
|     case ViewStates::TEMPERATURE: | |||
|       currentViewState = new ViewTemperatureState(ds3231, at24c32); | |||
|       break; | |||
|     case ViewStates::DATE: | |||
|       currentViewState = new ViewDateState(ds3231, at24c32, DATE_DELIMITER); | |||
|       break; | |||
|     case ViewStates::TEXT: | |||
|       currentViewState = new ViewTextState(at24c32); | |||
|       break; | |||
|     case ViewStates::LED_DEMO: | |||
|       currentViewState = new ViewLEDState(); | |||
|       break; | |||
|     default: | |||
|       currentViewState = new ViewTimeState(ds3231, at24c32); | |||
|     } | |||
| 
 | |||
|     oldViewState = viewState; | |||
|     at24c32.write(VIEW_STATE_ADDRESS, uint8_t(viewState)); | |||
| 
 | |||
|     printStatus(); | |||
|   } | |||
| } | |||
| 
 | |||
| /**
 | |||
|   check inputs | |||
|  */ | |||
| void controls() | |||
| { | |||
|   leftBtn.loop(leftCallback); | |||
|   decrementBtn.loop(decrementCallback); | |||
|   enterBtn.loop(enterCallback); | |||
|   incrementBtn.loop(incrementCallback); | |||
|   rightBtn.loop(rightCallback); | |||
| } | |||
| 
 | |||
| /**
 | |||
|   left callback  | |||
|  */ | |||
| void leftCallback() | |||
| { | |||
|   // delegate to current control state
 | |||
|   currentControlState->leftPressed(viewState, controlState); | |||
| #ifdef DEBUG
 | |||
|   Serial.print(F("< ")); | |||
| #endif
 | |||
| } | |||
| 
 | |||
| /**
 | |||
|   decrement callback | |||
|  */ | |||
| void decrementCallback() | |||
| { | |||
|   // delegate to current control state
 | |||
|   currentControlState->decrementPressed(viewState, controlState); | |||
| #ifdef DEBUG
 | |||
|   Serial.print(F("- ")); | |||
| #endif
 | |||
| } | |||
| 
 | |||
| /**
 | |||
|   enter callback | |||
|  */ | |||
| void enterCallback() | |||
| { | |||
|   // delegate to current control state
 | |||
|   currentControlState->enterPressed(viewState, controlState); | |||
| #ifdef DEBUG
 | |||
|   Serial.print(F("# ")); | |||
| #endif
 | |||
| } | |||
| 
 | |||
| /**
 | |||
|   increment callback | |||
|  */ | |||
| void incrementCallback() | |||
| { | |||
|   // delegate to current control state
 | |||
|   currentControlState->incrementPressed(viewState, controlState); | |||
| #ifdef DEBUG
 | |||
|   Serial.print(F("+ ")); | |||
| #endif
 | |||
| } | |||
| 
 | |||
| /**
 | |||
|   right callback | |||
|  */ | |||
| void rightCallback() | |||
| { | |||
|   // delegate to current control state
 | |||
|   currentControlState->rightPressed(viewState, controlState); | |||
| #ifdef DEBUG
 | |||
|   Serial.print(F("> ")); | |||
| #endif
 | |||
| } | |||
| 
 | |||
| /**
 | |||
|   periodic rendering | |||
|  */ | |||
| void renderInterval() | |||
| { | |||
|   static const unsigned long REFRESH_INTERVAL = 100; | |||
|   static unsigned long lastRefreshTime = 0; | |||
| 
 | |||
|   if (millis() - lastRefreshTime >= REFRESH_INTERVAL) | |||
|   { | |||
|     lastRefreshTime += REFRESH_INTERVAL; | |||
|     render(); | |||
|   } | |||
| } | |||
| 
 | |||
| /**
 | |||
|   render | |||
|  */ | |||
| void render() | |||
| { | |||
|   // set default color
 | |||
|   uint8_t const color = at24c32.read(COLOR_ADDRESS); | |||
|   currentViewState->setColor(color); | |||
| 
 | |||
|   // set brightness
 | |||
|   uint8_t const brightness = at24c32.read(BRIGHTNESS_ADDRESS); | |||
|   pixels.setBrightness(brightness); | |||
| 
 | |||
|   // reset matrix (to black)
 | |||
|   for (int i = 0; i < MATRIX_SIZE; i++) | |||
|   { | |||
|     matrix[i] = 0x00; | |||
|   } | |||
| 
 | |||
|   // render matrix
 | |||
|   currentViewState->render(matrix, controlState); | |||
| 
 | |||
|   // set pixel
 | |||
|   for (int i = 0; i < MATRIX_SIZE; i++) | |||
|   { | |||
|     uint8_t const r = (matrix[i] >> 5) * 255 / 7; | |||
|     uint8_t const g = ((matrix[i] >> 2) & 0x07) * 255 / 7; | |||
|     uint8_t const b = (matrix[i] & 0x03) * 255 / 3; | |||
|     pixels.setPixelColor(i, pixels.Color(r, g, b)); | |||
|   } | |||
| 
 | |||
|   pixels.show(); | |||
| } | |||
| 
 | |||
| /**
 | |||
|   print current status VIEW STATE \t CONTROL STATE \t FREE RAM | |||
|  */ | |||
| void printStatus() | |||
| { | |||
| #ifdef DEBUG
 | |||
|   switch (viewState) | |||
|   { | |||
|   case ViewStates::TIME: | |||
|     Serial.print(F("TIME")); | |||
|     break; | |||
|   case ViewStates::SECONDS: | |||
|     Serial.print(F("SECS")); | |||
|     break; | |||
|   case ViewStates::TEMPERATURE: | |||
|     Serial.print(F("TEMP")); | |||
|     break; | |||
|   case ViewStates::DATE: | |||
|     Serial.print(F("DATE")); | |||
|     break; | |||
|   case ViewStates::TEXT: | |||
|     Serial.print(F("TEXT")); | |||
|     break; | |||
|   case ViewStates::LED_DEMO: | |||
|     Serial.print(F("LEDS")); | |||
|     break; | |||
|   default: | |||
|     Serial.print(F("TIME")); | |||
|   } | |||
| 
 | |||
|   Serial.print(F("\t")); | |||
|   switch (controlState) | |||
|   { | |||
|   case ControlStates::VIEW: | |||
|     Serial.print(F("VIEW ")); | |||
|     break; | |||
|   case ControlStates::TIME_HOURS: | |||
|     Serial.print(F("HOURS")); | |||
|     break; | |||
|   case ControlStates::TIME_MINUTES: | |||
|     Serial.print(F("MINS ")); | |||
|     break; | |||
|   case ControlStates::TIME_MODE: | |||
|     Serial.print(F("MODE ")); | |||
|     break; | |||
|   case ControlStates::TIME_SECONDS: | |||
|     Serial.print(F("SECS ")); | |||
|     break; | |||
|   case ControlStates::DATE_DATE: | |||
|     Serial.print(F("DATE ")); | |||
|     break; | |||
|   case ControlStates::DATE_MONTH: | |||
|     Serial.print(F("MONTH")); | |||
|     break; | |||
|   case ControlStates::DATE_YEAR: | |||
|     Serial.print(F("YEAR ")); | |||
|     break; | |||
|   case ControlStates::COLOR_R: | |||
|     Serial.print(F("COLOR_R")); | |||
|     break; | |||
|   case ControlStates::COLOR_G: | |||
|     Serial.print(F("COLOR_G")); | |||
|     break; | |||
|   case ControlStates::COLOR_B: | |||
|     Serial.print(F("COLOR_B")); | |||
|     break; | |||
|   case ControlStates::TEXT: | |||
|     Serial.print(F("TEXT ")); | |||
|     break; | |||
|   default: | |||
|     Serial.print(F("VIEW ")); | |||
|   } | |||
| 
 | |||
|   extern int __heap_start, *__brkval; | |||
|   int v; | |||
|   Serial.print(F("\tRAM: ")); | |||
|   Serial.println((int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval)); | |||
| #endif
 | |||
| } | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue