gobot.io/x/gobot/v2@v2.1.0/drivers/gpio/tm1638_driver.go (about) 1 package gpio 2 3 import ( 4 "math" 5 6 "strings" 7 8 "gobot.io/x/gobot/v2" 9 ) 10 11 // Colors of the display 12 const ( 13 TM1638None = iota 14 TM1638Red 15 TM1638Green 16 ) 17 18 // Commands of the driver 19 const ( 20 TM1638DataCmd = 0x40 21 TM1638DispCtrl = 0x80 22 TM1638AddrCmd = 0xC0 23 24 TM1638WriteDisp = 0x00 25 TM1638ReadKeys = 0x02 26 TM1638FixedAddr = 0x04 27 ) 28 29 // TM1638Driver is the gobot driver for modules based on the TM1638, which has 8 7-segment displays, 8 LEDs and 8 buttons 30 // Buttons are not supported 31 // 32 // Datasheet EN: https://retrocip.cz/files/tm1638.pdf 33 // Datasheet CN: http://www.datasheetspdf.com/pdf/775356/TitanMicro/TM1638/1 34 // 35 // Ported from the Arduino driver https://github.com/rjbatista/tm1638-library 36 type TM1638Driver struct { 37 pinClock *DirectPinDriver 38 pinData *DirectPinDriver 39 pinStrobe *DirectPinDriver 40 fonts map[string]byte 41 name string 42 connection gobot.Connection 43 gobot.Commander 44 } 45 46 // NewTM1638Driver return a new TM1638Driver given a gobot.Connection and the clock, data and strobe pins 47 func NewTM1638Driver(a gobot.Connection, clockPin string, dataPin string, strobePin string) *TM1638Driver { 48 t := &TM1638Driver{ 49 name: gobot.DefaultName("TM1638"), 50 pinClock: NewDirectPinDriver(a, clockPin), 51 pinData: NewDirectPinDriver(a, dataPin), 52 pinStrobe: NewDirectPinDriver(a, strobePin), 53 fonts: NewTM1638Fonts(), 54 connection: a, 55 Commander: gobot.NewCommander(), 56 } 57 58 /* TODO : Add commands */ 59 60 return t 61 } 62 63 // Start initializes the tm1638, it uses a SPI-like communication protocol 64 func (t *TM1638Driver) Start() (err error) { 65 66 t.pinStrobe.On() 67 t.pinClock.On() 68 69 t.sendCommand(TM1638DataCmd) 70 t.sendCommand(TM1638DispCtrl | 8 | 7) 71 72 t.pinStrobe.Off() 73 t.send(TM1638AddrCmd) 74 for i := 0; i < 16; i++ { 75 t.send(TM1638WriteDisp) 76 } 77 t.pinStrobe.On() 78 79 return 80 } 81 82 // Halt implements the Driver interface 83 func (t *TM1638Driver) Halt() (err error) { return } 84 85 // Name returns the TM1638Drivers name 86 func (t *TM1638Driver) Name() string { return t.name } 87 88 // SetName sets the TM1638Drivers name 89 func (t *TM1638Driver) SetName(n string) { t.name = n } 90 91 // Connection returns the TM1638Driver Connection 92 func (t *TM1638Driver) Connection() gobot.Connection { 93 return t.connection 94 } 95 96 // sendCommand is an auxiliary function to send commands to the TM1638 module 97 func (t *TM1638Driver) sendCommand(cmd byte) { 98 t.pinStrobe.Off() 99 t.send(cmd) 100 t.pinStrobe.On() 101 } 102 103 // send writes data on the module 104 func (t *TM1638Driver) send(data byte) { 105 for i := 0; i < 8; i++ { 106 t.pinClock.Off() 107 108 if (data & 1) > 0 { 109 t.pinData.On() 110 } else { 111 t.pinData.Off() 112 } 113 data >>= 1 114 115 t.pinClock.On() 116 } 117 } 118 119 // sendData is an auxiliary function to send data to the TM1638 module 120 func (t *TM1638Driver) sendData(address byte, data byte) { 121 t.sendCommand(TM1638DataCmd | TM1638FixedAddr) 122 t.pinStrobe.Off() 123 t.send(TM1638AddrCmd | address) 124 t.send(data) 125 t.pinStrobe.On() 126 } 127 128 // SetLED changes the color (TM1638None, TM1638Red, TM1638Green) of the specific LED 129 func (t *TM1638Driver) SetLED(color byte, pos byte) { 130 if pos > 7 { 131 return 132 } 133 t.sendData((pos<<1)+1, color) 134 } 135 136 // SetDisplay cuts and sends a byte array to the display (without dots) 137 func (t *TM1638Driver) SetDisplay(data []byte) { 138 minLength := int(math.Min(8, float64(len(data)))) 139 for i := 0; i < minLength; i++ { 140 t.SendChar(byte(i), data[i], false) 141 } 142 } 143 144 // SetDisplayText cuts and sends a string to the display (without dots) 145 func (t *TM1638Driver) SetDisplayText(text string) { 146 data := t.fromStringToByteArray(text) 147 minLength := int(math.Min(8, float64(len(data)))) 148 for i := 0; i < minLength; i++ { 149 t.SendChar(byte(i), data[i], false) 150 } 151 } 152 153 // SendChar sends one byte to the specific position in the display 154 func (t *TM1638Driver) SendChar(pos byte, data byte, dot bool) { 155 if pos > 7 { 156 return 157 } 158 var dotData byte 159 if dot { 160 dotData = TM1638DispCtrl 161 } 162 t.sendData(pos<<1, data|(dotData)) 163 } 164 165 // fromStringToByteArray translates a string to a byte array with the corresponding representation for the 7-segment LCD, return and empty character if the font is not available 166 func (t *TM1638Driver) fromStringToByteArray(str string) []byte { 167 chars := strings.Split(str, "") 168 data := make([]byte, len(chars)) 169 170 for index, char := range chars { 171 if val, ok := t.fonts[char]; ok { 172 data[index] = val 173 } 174 } 175 return data 176 } 177 178 // AddFonts adds new custom fonts or modify the representation of existing ones 179 func (t *TM1638Driver) AddFonts(fonts map[string]byte) { 180 for k, v := range fonts { 181 t.fonts[k] = v 182 } 183 } 184 185 // ClearFonts removes all the fonts from the driver 186 func (t *TM1638Driver) ClearFonts() { 187 t.fonts = make(map[string]byte) 188 } 189 190 // NewTM1638Fonts returns a map with fonts and their corresponding byte for proper representation on the 7-segment LCD 191 func NewTM1638Fonts() map[string]byte { 192 return map[string]byte{ 193 " ": 0x00, 194 "!": 0x86, 195 "'": 0x22, 196 "#": 0x7E, 197 "$": 0x6D, 198 "%": 0x00, 199 "&": 0x00, 200 "\"": 0x02, 201 "(": 0x30, 202 ")": 0x06, 203 "*": 0x63, 204 "+": 0x00, 205 ",": 0x04, 206 "-": 0x40, 207 ".": 0x80, 208 "/": 0x52, 209 "0": 0x3F, 210 "1": 0x06, 211 "2": 0x5B, 212 "3": 0x4F, 213 "4": 0x66, 214 "5": 0x6D, 215 "6": 0x7D, 216 "7": 0x27, 217 "8": 0x7F, 218 "9": 0x6F, 219 ":": 0x00, 220 ";": 0x00, 221 "<": 0x00, 222 "=": 0x48, 223 ">": 0x00, 224 "?": 0x53, 225 "@": 0x5F, 226 "A": 0x77, 227 "B": 0x7F, 228 "C": 0x39, 229 "D": 0x3F, 230 "E": 0x79, 231 "F": 0x71, 232 "G": 0x3D, 233 "H": 0x76, 234 "I": 0x06, 235 "J": 0x1F, 236 "K": 0x69, 237 "L": 0x38, 238 "M": 0x15, 239 "N": 0x37, 240 "O": 0x3F, 241 "P": 0x73, 242 "Q": 0x67, 243 "R": 0x31, 244 "S": 0x6D, 245 "T": 0x78, 246 "U": 0x3E, 247 "V": 0x2A, 248 "W": 0x1D, 249 "X": 0x76, 250 "Y": 0x6E, 251 "Z": 0x5B, 252 "[": 0x39, 253 "\\": 0x64, // (this can't be the last char on a line, even in comment or it'll concat) 254 "]": 0x0F, 255 "^": 0x00, 256 "_": 0x08, 257 "`": 0x20, 258 "a": 0x5F, 259 "b": 0x7C, 260 "c": 0x58, 261 "d": 0x5E, 262 "e": 0x7B, 263 "f": 0x31, 264 "g": 0x6F, 265 "h": 0x74, 266 "i": 0x04, 267 "j": 0x0E, 268 "k": 0x75, 269 "l": 0x30, 270 "m": 0x55, 271 "n": 0x54, 272 "o": 0x5C, 273 "p": 0x73, 274 "q": 0x67, 275 "r": 0x50, 276 "s": 0x6D, 277 "t": 0x78, 278 "u": 0x1C, 279 "v": 0x2A, 280 "w": 0x1D, 281 "x": 0x76, 282 "y": 0x6E, 283 "z": 0x47, 284 "{": 0x46, 285 "|": 0x06, 286 "}": 0x70, 287 "~": 0x01, 288 } 289 }