Skip to content
This repository
Newer
Older
100644 466 lines (406 sloc) 17.512 kb
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
1 /* Serial 7 Segment Display Firmware
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
2 Version: 3.0.1
3 By: Jim Lindblom (SparkFun Electronics)
4 Date: August 24, 2012
5 License: This code is beerware: feel free to use it, with or without attribution,
6 in your own projects. If you find it helpful, buy me a beer next time you see me
7 at the local pub.
8
9 Description: This firmware goes on the SparkFun Serial 7-Segment displays.
10 https://www.sparkfun.com/search/results?term=serial+7+segment&what=products
11
12 You can send the display serial data over either UART, SPI, or I2C. It'll
13 sequentially display what it reads. There are special commands to control
14 individual segments, clear the display, reset the cursor, adjust the display's
15 brightness, UART baud rate, i2c address or factory reset.
16
17 Arduino addon: This code should remain with the Serial7Seg Arduino hardware
18 addon. New pin defines are required for pins 22 and 23 - PB6:7. Because the
19 Serial 7-Segment runs on the ATmega328's internal oscillator, these two pins
20 open up for our use.
21
22 Hardware: You can find the Serial 7-Segment Display Schematic here:
23 !!! Add schematic link
24
25 */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
26 #include <Wire.h> // Handles I2C
27 #include <EEPROM.h> // Brightness, Baud rate, and I2C address are stored in EEPROM
28 #include "settings.h" // Defines command bytes, EEPROM addresses, display data
29
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
30 /* Digit Defines
31 Used with cathodes[] array (below) to reference specific segments */
32 const int A_SEG = 0;
33 const int B_SEG = 1;
34 const int C_SEG = 2;
35 const int D_SEG = 3;
36 const int E_SEG = 4;
37 const int F_SEG = 5;
38 const int G_SEG = 6;
39 const int DP_SEG = 7;
40
41 /* Pin defines for LED anodes and cathodes */
42 const byte anodes[6] = {A2, A3, 3, 4, 2, 9}; // Dig0, Dig1, Dig2, Dig3, Colon, Apostrophe
43 const byte cathodes[8] = {8, A0, 6, A1, 23, 7, 5, 22}; // A, B, C, D, E, F, G, DP
44 //const byte cathodes[8] = {6, 8, A0, A1, 23, 7, 5, 22}; // A, B, C, D, E, F, G, DP
45
46 /* Struct for circular data buffer
47 data received over UART, SPI and I2C are all sent into a single buffer */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
48 struct dataBuffer
49 {
50 unsigned char data[BUFFER_SIZE]; // THE data buffer
51 unsigned int head; // store new data at this index
52 unsigned int tail; // read oldest data from this index
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
53 } buffer; // our data buffer is creatively named - buffer
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
54
55 unsigned char commandMode = 0; // Used to indicate if a commandMode byte has been received
56
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
57 /* Struct for 4-digit, 7-segment display
58 Stores display value (digits), decimal status (decimals) for each digit,
59 and cursor for overall display */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
60 struct display
61 {
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
62 unsigned char digits[4];
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
63 unsigned char decimals;
64 unsigned char cursor;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
65 } display; // displays be displays
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
66
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
67 /* displayPeriod conrols the brightness of the display
68 it controls how long in microseconds a display will be active */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
69 const int displayPeriodMax = 10000; //microseconds - how long to run through one cycle of display PWM
70 int displayPeriod = 2000; // microseconds, maximum of 3000 - length of time each digit on display is active
71
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
72 /* SPI byte received interrupt routine */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
73 ISR(SPI_STC_vect)
74 {
75 noInterrupts(); // don't be rude! I'll be quick...
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
76
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
77 unsigned int i = (buffer.head + 1) % BUFFER_SIZE; // read buffer head position and increment
78 unsigned char c = SPDR; // Read data byte into c, from SPI data register
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
79
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
80 if (i != buffer.tail) // As long as the buffer isn't full, we can store the data in buffer
81 {
82 buffer.data[buffer.head] = c; // Store the data into the buffer's head
83 buffer.head = i; // update buffer head, since we stored new data
84 }
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
85
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
86 interrupts(); // Fine, you were saying?
87 }
88
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
89 /* UART0 byte received interrupt routine */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
90 ISR(USART_RX_vect)
91 {
92 noInterrupts(); // We'll be quick...
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
93
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
94 unsigned int i = (buffer.head + 1) % BUFFER_SIZE; // read buffer head position and increment
95 unsigned char c = UDR0; // Read data byte into c, from UART0 data register
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
96
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
97 if (i != buffer.tail) // As long as the buffer isn't full, we can store the data in buffer
98 {
99 buffer.data[buffer.head] = c; // Store the data into the buffer's head
100 buffer.head = i; // update buffer head, since we stored new data
101 }
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
102
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
103 interrupts(); // Okay, resume interrupts
104 }
105
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
106 /* I2C byte receive interrupt routine
107 Note: this isn't an ISR. I'm using wire library (because it just works), so
108 Wire.onReceive(twiReceive); should be called */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
109 void twiReceive(int rxCount)
110 {
111 while(Wire.available() > 0) // Do this while data is available in Wire buffer
112 {
113 unsigned int i = (buffer.head + 1) % BUFFER_SIZE; // read buffer head position and increment
114 unsigned char c = Wire.read(); // Read data byte into c, from Wire data buffer
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
115
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
116 if (i != buffer.tail) // As long as the buffer isn't full, we can store the data in buffer
117 {
118 buffer.data[buffer.head] = c; // Store the data into the buffer's head
119 buffer.head = i; // update buffer head, since we stored new data
120 }
121 }
122 }
123
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
124 /* The display data is updated on a Timer interrupt */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
125 ISR(TIMER1_COMPA_vect)
126 {
127 noInterrupts();
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
128
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
129 // if head and tail are not equal, there's data to be read from the buffer
130 if (buffer.head != buffer.tail)
131 updateBufferData(); // updateBufferData() will update the display info, or peform special commands
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
132
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
133 interrupts();
134 }
135
136 void setup()
137 {
138 pinMode(10, OUTPUT);
139 digitalWrite(10, LOW);
140 delayMicroseconds(1);
141 pinMode(10, INPUT_PULLUP);
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
142
143 /* Set the initial state of displays and decimals 'x' = off */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
144 display.digits[0] = 'x';
145 display.digits[1] = 'x';
146 display.digits[2] = 'x';
147 display.digits[3] = 'x';
148 display.decimals = 0x00; // Turn all decimals off
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
149
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
150 display.cursor = 0; // Set cursor to first (left-most) digit
151 buffer.head = 0; // Initialize buffer values
152 buffer.tail = 0;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
153
154 /* Initialize anode pin states to OUTPUTS, all LOWs */
155 for (int i=0; i<6; i++)
156 {
157 pinMode(anodes[i], OUTPUT);
158 digitalWrite(anodes[i], LOW);
159 }
160
161 /* Initialize cathode pin states to OUTPUTS all HIGHs */
162 for (int i = 0 ; i < 8 ; i++)
163 {
164 pinMode(cathodes[i], OUTPUT);
165 digitalWrite(cathodes[i], HIGH);
166 }
167
168 /* displayPeriod controls the brightness of our display
169 read the brightness value from EEPROM and map the 0 */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
170 displayPeriod = map(EEPROM.read(BRIGHTNESS_ADDRESS), 0, 255, 0, 2000);
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
171
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
172 setupTimer(); // Setup timer to control interval reading from buffer
173 setupUart(); // initialize UART stuff (interrupts, enable, baud)
174 setupSPI(); // Initialize SPI stuff (enable, mode, interrupts)
175 setupTWI(); // Initialize I2C stuff (address, interrupt, enable)
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
176
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
177 interrupts(); // Turn interrupts on, and les' go
178 }
179
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
180 /* The display is constantly PWM'd in the loop() */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
181 void loop()
182 {
183 int delayTimer = 0;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
184
185 for (int i = 0 ; i < 5 ; i++) // Run through this once for each digit and once for the decimals
186 {
187 displayDigit(display.digits[i], i); // Set all the segments correctly
188
189 delayMicroseconds(displayPeriod+1); // Blocking delay while the digit is on
190 }
191
192 clearDisplay(); // Clear the display, this is how we adjust brightness
193 /* delay for whats left of our maximum displayPeriod */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
194 delayMicroseconds((displayPeriodMax - 5 * displayPeriod) + 1);
195 }
196
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
197 /* updateBufferData(): This beast of a function is called by the Timer 1 ISR if there is
198 new data in the buffer.
199 If the data controls display data, that'll be updated.
200 If the data relates to a command, commandmode will be set accordingly or a command
201 will be executed from this function. */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
202 void updateBufferData()
203 {
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
204 /* First we read from the oldest data in the buffer */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
205 unsigned char c = buffer.data[buffer.tail];
206 buffer.tail = (buffer.tail + 1) % BUFFER_SIZE; // and update the tail to the next oldest
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
207
208 /* if the last byte received wasn't a command byte (commandMode=0)
209 and if the data is displayable (0-0x76 or 0x78), the display will be updated*/
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
210 if ((commandMode == 0) && ((c < 0x76) || (c == 0x78)))
211 {
212 display.digits[display.cursor] = c; // just store the read data into the cursor-active digit
213 display.cursor = ((display.cursor + 1) % 4); // Increment cursor, set back to 0 if necessary
214 }
215 else if (c == RESET_CMD) // If the received char is the reset command
216 {
217 for (int i=0; i<4; i++)
218 display.digits[i] = 'x'; // clear all digits
219 display.decimals = 0; // clear all decimals
220 display.cursor = 0; // reset the cursor
221 }
222 else if (commandMode != 0) // Otherwise, if data is non-displayable and we're in a commandMode
223 {
224 unsigned int baud = 103; // Default to 9600 if non-usable data received
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
225
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
226 switch (commandMode)
227 {
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
228 case DECIMAL_CMD: // Decimal setting mode
229 display.decimals = c; // decimals are set by one byte
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
230 break;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
231 case BRIGHTNESS_CMD: // Brightness setting mode
232 displayPeriod = map(c, 0, 255, 0, 2000); // Adjust the amount of time digits are on
233 EEPROM.write(BRIGHTNESS_ADDRESS, c); // write the new value to EEPROM
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
234 break;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
235 case BAUD_CMD: // Baud setting mode
236 switch (c)
237 {
238 case 0: // 2400
239 baud = 416;
240 break;
241 case 1: // 4800
242 baud = 207;
243 break;
244 case 2: // 9600
245 baud = 103;
246 break;
247 case 3: // 14400
248 baud = 68;
249 break;
250 case 4: // 19200
251 baud = 51;
252 break;
253 case 5: // 38400
254 baud = 25;
255 break;
256 case 6: // 57600
257 baud = 16;
258 break;
259 case 7: // 76800
260 baud = 12;
261 break;
262 case 8: // 115200
263 baud = 8;
264 break;
265 case 9: // 250000
266 baud = 3;
267 break;
268 case 10: // 500000
269 baud = 1;
270 break;
271 case 11: // 1000000
272 baud = 0;
273 break;
274 }
275 UBRR0 = baud; // UBRR0 is set with no regard to F_CPU, assuming 8MHz 2x speed
276 EEPROM.write(BAUD_ADDRESS_H, (unsigned char)(baud>>8)); // Update EEPROM baud setting
277 EEPROM.write(BAUD_ADDRESS_L, (unsigned char)(baud & 0xFF));
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
278 break;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
279 case CURSOR_CMD: // Set the cursor
280 if (c <= 3) // Limited error checking, if >3 cursor command will have no effect
281 display.cursor = c; // Update the cursor value
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
282 break;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
283 case TWI_ADDRESS_CMD: // Set the I2C Address
284 if ((c > 0) && (c < 0x7F))
285 { // As long as the address value is valid msb can't be set, can't be 0 (general call)
286 EEPROM.write(TWI_ADDRESS_ADDRESS, c); // Update the EEPROM value
287 Wire.begin(c); // on-the fly I2C address update
288 }
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
289 break;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
290 case FACTORY_RESET_CMD: // Factory reset
291 factoryReset(); // Let's do that in a function
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
292 break;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
293 case DIGIT1_CMD: // Single-digit control for digit 1
294 display.digits[0] = c | 0x80; // set msb to indicate single digit control mode
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
295 break;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
296 case DIGIT2_CMD: // Single-digit control for digit 2
297 display.digits[1] = c | 0x80;
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
298 break;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
299 case DIGIT3_CMD: // Single-digit control for digit 3
300 display.digits[2] = c | 0x80;
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
301 break;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
302 case DIGIT4_CMD: // Single-digit control for digit 4
303 display.digits[3] = c | 0x80;
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
304 break;
305 }
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
306 /* Leaving commandMode
307 !!! If the commandMode isn't a valid command, we'll leave command mode, should be checked below? */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
308 commandMode = 0;
309 }
310 else // Finally, if we weren't in command mode, if the byte isn't displayable, we'll enter command mode
311 {
312 commandMode = c; // which command mode is reflected by value of commandMode
313 }
314 }
315
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
316 /* seutpTimer(): Set up timer 1, which controls interval reading from the buffer */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
317 void setupTimer()
318 {
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
319 /* Timer 1 is se to CTC mode, 16-bit timer counts up to 0xFF */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
320 TCCR1B = (1<<WGM12) | (1<<CS10);
321 OCR1A = 0x00FF;
322 TIMSK1 = (1<<OCIE1A); // Enable interrupt on compare
323 }
324
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
325 /* setupUart(): Initializes UART0 hardware pins, sets up UART interrupt
326 Sets baud rate, parity, stop bit and data bits */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
327 void setupUart()
328 {
329 pinMode(0, INPUT); // RX set as an INPUT
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
330
331 UCSR0A = (1<<U2X0); // DOUBLE SPEEEEEEED!
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
332 UCSR0B = (1<<RXCIE0) | (1<<RXEN0); // Enable RX, RX complete interrupt
333 UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); // Asynchronous, no parity, 1 stop bit, 8 bit
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
334
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
335 //EEPROM.write(BAUD_ADDRESS_L, 0xFF); // These are useful if you need to reset...
336 //EEPROM.write(BAUD_ADDRESS_H, 0xFF); // ...the baud rate values in EEPROM
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
337
338 /* read the baud rate setting from EEPROM */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
339 unsigned int baud = (EEPROM.read(BAUD_ADDRESS_H)<<8) | EEPROM.read(BAUD_ADDRESS_L);
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
340
341 /* Check if the baud rate setting is valid */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
342 if ((baud==416)||(baud==207)||(baud==103)||(baud==68)||(baud==51)||(baud==34)
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
343 ||(baud==25)||(baud==16)||(baud==12)||(baud==8)||(baud==3)||(baud==1)||(baud==0))
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
344 {
345 UBRR0 = baud; // and update the UBRR0 !!! This is dependent on double-speed and 8MHz clock
346 }
347 else // if the baud rate setting was invalid, default to 9600
348 {
349 baud = 103; // !!! dependent on 8MHz, double speed uart
350 UBRR0 = baud; // default to 9600
351 EEPROM.write(BAUD_ADDRESS_L, baud); // Update EEPROM to reflect 9600 buad
352 EEPROM.write(BAUD_ADDRESS_H, 0);
353 }
354 }
355
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
356 /* setupSPI(): Initialize SPI, sets up hardware pins and enables spi and receive interrupt
357 SPI is set to MODE 0 (CPOL=0, CPHA=0), slave mode, LSB first */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
358 void setupSPI()
359 {
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
360 pinMode(13, INPUT); // SCK
361 pinMode(11, INPUT); // MOSI
362 pinMode(10, INPUT_PULLUP); // SS
363
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
364 SPCR = (1<<SPIE) | (1<<SPE); // Enable SPI interrupt, enable SPI
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
365 /* DORD = 0, LSB First
366 MSTR = 0, SLAVE
367 CPOL = 0, sck low when idle } MODE 0
368 CPHA = 0, data sampled on leading clock edge } MODE 0
369 SPR1:0 = 0, no effect (slave mode) */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
370 }
371
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
372 /* setupTWI(): initializes I2C (err TWI! TWI! TWI!, can't bang that into my head enough)
373 I'm using the rock-solid Wire library for this. We'll initialize TWI, setup the address,
374 and tell it what interrupt function to jump to when data is received. */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
375 void setupTWI()
376 {
377 unsigned char twiAddress;
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
378
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
379 twiAddress = EEPROM.read(TWI_ADDRESS_ADDRESS); // read the TWI address from
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
380
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
381 if ((twiAddress == 0) || (twiAddress > 0x7F))
382 { // If the TWI address is invalid, use a default address
383 twiAddress = TWI_ADDRESS_DEFAULT;
384 EEPROM.write(TWI_ADDRESS_ADDRESS, TWI_ADDRESS_DEFAULT);
385 }
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
386
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
387 Wire.begin(twiAddress); // Initialize Wire library as slave at twiAddress address
388 Wire.onReceive(twiReceive); // setup interrupt routine for when data is received
389 }
390
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
391 /* factoryReset(): Uhoh! If something breaks, try sending a factory reset command to the device
392 This will reset baud, TWI address, and brightness to default values */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
393 void factoryReset()
394 {
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
395 /* Reset Baud (9600) */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
396 unsigned int baud = BAUD_DEFAULT;
397 UBRR0 = baud;
398 EEPROM.write(BAUD_ADDRESS_L, (unsigned char)(baud & 0xFF));
399 EEPROM.write(BAUD_ADDRESS_H, (unsigned char)(baud >> 8));
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
400
401
402 /* Reset TWI Address (0x71) */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
403 Wire.begin(TWI_ADDRESS_DEFAULT);
404 EEPROM.write(TWI_ADDRESS_ADDRESS, TWI_ADDRESS_DEFAULT);
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
405
406 /* Reset Brightness (FULL BRIGHNESS!) */
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
407 displayPeriod = map(255, 0, 255, 0, 2000);
408 EEPROM.write(BRIGHTNESS_ADDRESS, BRIGHTNESS_DEFAULT);
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
409
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
410 }
411
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
412 /* displayDigit(byte number, byte digit): Displays number on digit.
413 This function actually displays stuff. It sets the anodes to turn activate a digit,
414 and it sets the cathodes to turn on the proper segments. It'll decode 0-F and ASCII
415 e.g. displayDigit(8, 0) makes the left-most digit display '8'.
416 displayDigit('b', 3) displays 'b' on 3.
417 if digit=4, the colon and apostrophes are controlled */
418 void displayDigit(byte number, byte digit)
419 {
420 clearDisplay(); // Clear the display
421 digitalWrite(anodes[digit], HIGH); // pull the proper anode HIGH
422
423 if (digit == 4) // if digit=4, the colon and apostrophe are being controlled
424 {
425 digitalWrite(anodes[5], HIGH); // We'll also need to activate the apostrophe anode
426 if ((display.decimals & (1<<4))) // Turn the colon on if bit set
427 digitalWrite(6, LOW); // Colon cathode is shared with A segment cathode
428 if ((display.decimals & (1<<5))) // Turn the apostrophe on if bit set
429 digitalWrite(7, LOW); // Apostrophe cathode shared with F segment cathode
430 }
431 else // otherwise digit should be 0-3
432 {
433 if (number & 0x80) // If msb is set, we're in single-digit control mode for this digit
434 {
435 for (int i=0; i<7; i++) // in single digit control mode ASCII isn't decode, bit-for-segment control
436 {
437 if (number & (1<<i)) // if a bit is set
438 digitalWrite(cathodes[i], LOW); // turn on the corresponding segment
439 }
440 }
441 else // otherwise, we need to decode the ASCII or value of number before it's displayed
442 {
443 for (int i=0; i<7; i++)
444 {
445 // displayArray (defined in settings.h) decides which segments are turned on for each value of number
446 if (displayArray[number][i])
447 digitalWrite(cathodes[i], LOW); // if the bit is set, turn on that segment
448 }
449 }
450 /* finally, if the decimal bit for this digit is set, turn on the DP */
451 if ((display.decimals & (1<<digit)))
452 digitalWrite(cathodes[DP_SEG], LOW);
453 }
454 }
517d2f21 » jimblom
2012-10-31 Reverting to the latest working version
455
6ca112cc » jimblom
2012-10-31 Reverting to older, working, non SevSeg version
456 /* clearDisplay(): Turns off everything! */
457 void clearDisplay()
458 {
459 for (int i=0; i<6; i++)
460 digitalWrite(anodes[i], LOW); // anodes LOW
461
462 for (int i=0; i<8; i++)
463 {
464 digitalWrite(cathodes[i], HIGH); // cathodes HIGH
465 }
466 }
Something went wrong with that request. Please try again.