Skip to content

Commit cb5be47

Browse files
committed
First add of multimode capability.
Not fully tested but somewhat working.
1 parent 6230ffc commit cb5be47

File tree

3 files changed

+160
-15
lines changed

3 files changed

+160
-15
lines changed

firmware/Serial 7-Segment Display/Arduino_Examples/S7S_Example_Serial_Basic/S7S_Example_Serial_Basic.ino

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
http://github.com/sparkfun/Serial7SegmentDisplay/wiki/Special-Commands#wiki-baud
1515
1616
To get this code to work, attached an Serial7Segment to an Arduino Uno using the following pins:
17-
Pin 7 on Uno (software serial RX) to TX on Serial7Segment
18-
Pin 8 on Uno to RX on Serial7Segment
17+
Pin 8 on Uno (software serial TX) to RX on Serial7Segment
1918
VIN to PWR
2019
GND to GND
2120

firmware/Serial 7-Segment Display/Serial_7_Segment_Display_Firmware/Serial_7_Segment_Display_Firmware.ino

Lines changed: 152 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ SevSeg myDisplay; //Create an instance of the object
3737
#define OPENSEGMENT 2
3838
#define DISPLAY_TYPE OPENSEGMENT
3939

40-
//Global variables for the analog pins
41-
unsigned int analogValue6 = 0;
40+
//Global variables
41+
unsigned int analogValue6 = 0; //These are used in analog meter mode
4242
unsigned int analogValue7 = 0;
43+
char deviceMode; //This variable is useds to select which mode the device should be in
4344

4445
// Struct for circular data buffer data received over UART, SPI and I2C are all sent into a single buffer
4546
struct dataBuffer
@@ -103,6 +104,7 @@ void setup()
103104
setupSPI(); // Initialize SPI stuff (enable, mode, interrupts)
104105
setupTWI(); // Initialize I2C stuff (address, interrupt, enable)
105106
setupAnalog(); // Initialize the analog inputs
107+
setupMode(); // Determine which mode we should be in
106108

107109
interrupts(); // Turn interrupts on, and les' go
108110

@@ -111,17 +113,128 @@ void setup()
111113
display.digits[1] = 2;
112114
display.digits[2] = 3;
113115
display.digits[3] = 4;
114-
116+
115117
myDisplay.SetBrightness(100); //Set the display to 100% bright
116118
}
117119

118120
// The display is constantly PWM'd in the loop()
119121
void loop()
120122
{
121-
myDisplay.DisplayString(display.digits, display.decimals); //(numberToDisplay, decimal point location)
123+
if(deviceMode == MODE_DATA)
124+
{
125+
//Go into normal mode, monitoring UART/SPI/I2C
126+
while(deviceMode == MODE_DATA)
127+
{
128+
//Just hang out and update the display as new data comes in
129+
myDisplay.DisplayString(display.digits, display.decimals); //(numberToDisplay, decimal point location)
130+
131+
serialEvent(); //Check the serial buffer for new data
132+
}
133+
}
134+
else if(deviceMode == MODE_COUNTER)
135+
{
136+
//Turn off the SPI and watch for increment pulses on the SDO pin, decrement on SDI
137+
SPCR = 0; //Disable all SPI interrupts that may be turned on
138+
139+
int counterIncrement = SPI_MISO; //Labeled SDO
140+
int counterDecrement = SPI_MOSI; //Labeled SDI
141+
142+
pinMode(counterIncrement, INPUT_PULLUP);
143+
pinMode(counterDecrement, INPUT_PULLUP);
144+
145+
int counter = 0; //Watches the overall count
146+
boolean incrementCounted = false; //Watches the toggle the counter pins
147+
boolean decrementCounted = false;
148+
149+
while(deviceMode == MODE_COUNTER) //Loop until we receive a different mode command
150+
{
151+
//Check to see if there has been a low/high pulse on increment
152+
if(digitalRead(counterIncrement == LOW))
153+
{
154+
if(incrementCounted == false) //Only increment counter if this is a new pulse
155+
{
156+
counter++;
157+
incrementCounted = true; //We have now counted this pulse
158+
}
159+
}
160+
else
161+
{
162+
//The increment pin is high, so sdo can be counted again
163+
incrementCounted = false;
164+
}
165+
166+
//Check to see if there has been a low/high pulse on increment
167+
if(digitalRead(counterDecrement == LOW))
168+
{
169+
if(decrementCounted == false) //Only increment counter if this is a new pulse
170+
{
171+
counter--;
172+
decrementCounted = true; //We have now counted this pulse
173+
}
174+
}
175+
else
176+
{
177+
//The increment pin is high, so sdo can be counted again
178+
decrementCounted = false;
179+
}
180+
181+
//Display this count
182+
//char tempString[10]; //Used for sprintf
183+
sprintf(display.digits, "%4d", counter); //Convert counter into a string that is right adjusted
184+
185+
186+
//int tempCounter = counter;
187+
// for(int x = 0 ; x < 4 ; x++)
188+
// {
189+
// display.digits[3 - x] = (tempCounter % 10); //Pull off the right most digit and store in display array
190+
// tempCounter /= 10; //Shave number down by one digit
191+
// }
192+
193+
myDisplay.DisplayString(display.digits, 0); //(numberToDisplay, no decimals during counter mode)
194+
195+
serialEvent(); //Check the serial buffer for new data
196+
}
197+
198+
}
199+
else if(deviceMode == MODE_ANALOG)
200+
{
201+
//Do nothing but analog reads
202+
203+
while(deviceMode == MODE_ANALOG)
204+
{
205+
analogValue6 = analogRead(A6);
206+
analogValue7 = analogRead(A7);
207+
208+
//Serial.print("A6: ");
209+
//Serial.print(analogValue6);
210+
//Serial.print(" A7: ");
211+
//Serial.print(analogValue7);
212+
213+
//Do calculation for 1st voltage meter
214+
float fvoltage6 = ((analogValue6 * 50) / (float)1024);
215+
int voltage6 = round(fvoltage6);
216+
display.digits[0] = voltage6 / 10;
217+
display.digits[1] = voltage6 % 10;
218+
219+
//Do calculation for 2nd voltage meter
220+
float fvoltage7 = ((analogValue7 * 50) / (float)1024);
221+
int voltage7 = round(fvoltage7);
222+
display.digits[2] = voltage7 / 10;
223+
display.digits[3] = voltage7 % 10;
224+
225+
display.decimals = ((1<<DECIMAL1) | (1<<DECIMAL3)); //Turn on the decimals next to digit1 and digit3
226+
myDisplay.DisplayString(display.digits, display.decimals); //(numberToDisplay, decimal point location)
227+
228+
serialEvent(); //Check the serial buffer for new data
229+
}
230+
231+
}
232+
233+
//We will loop if we've received a new device mode command
122234
}
123235

124236
// This is effectively the UART0 byte received interrupt routine
237+
// But not quite: serialEvent is only called after each loop() interation
125238
void serialEvent()
126239
{
127240
while (Serial.available())
@@ -192,15 +305,19 @@ void updateBufferData()
192305
break;
193306
case BAUD_CMD: // Baud setting mode
194307
EEPROM.write(BAUD_ADDRESS, c); // Update EEPROM with new baud setting
195-
setupUART(); //Checks to see if this baud rate is valis and turns on UART at this speed
308+
setupUART(); //Checks to see if this baud rate is valid and turns on UART at this speed
196309
break;
197310
case CURSOR_CMD: // Set the cursor
198311
if (c <= 3) // Limited error checking, if >3 cursor command will have no effect
199312
display.cursor = c; // Update the cursor value
200313
break;
201314
case TWI_ADDRESS_CMD: // Set the I2C Address
202315
EEPROM.write(TWI_ADDRESS_ADDRESS, c); // Update the EEPROM value
203-
setupTWI(); //Checks to see if I2C address is valid an begins I2C
316+
setupTWI(); //Checks to see if I2C address is valid and begins I2C
317+
break;
318+
case MODE_CMD: // Set the device mode (example: data, analog, counter)
319+
EEPROM.write(MODE_ADDRESS, c); // Update the EEPROM value
320+
setupMode(); //Checks to see if this mode is valid and then enters new mode
204321
break;
205322
case FACTORY_RESET_CMD: // Factory reset
206323
setDefaultSettings(); // Reset baud, brightness, and TWI address
@@ -321,11 +438,11 @@ void setupDisplay()
321438

322439
//Initialize the SevSeg library with all the pins needed for this type of display
323440
myDisplay.Begin(displayType, numberOfDigits,
324-
digit1, digit2, digit3, digit4,
325-
digitColon, digitApostrophe,
326-
segA, segB, segC, segD, segE, segF, segG,
327-
segDP,
328-
segmentColon, segmentApostrophe);
441+
digit1, digit2, digit3, digit4,
442+
digitColon, digitApostrophe,
443+
segA, segB, segC, segD, segE, segF, segG,
444+
segDP,
445+
segmentColon, segmentApostrophe);
329446
#endif
330447
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
331448
}
@@ -389,6 +506,20 @@ void setupUART()
389506

390507
}
391508

509+
//This function reads the MODE setting from EEPROM and checks to see if there are
510+
//any hardware settings (closed jumpers for example) that puts the device into a
511+
//certain mode. Available modes are regular, analog meter, and counter modes.
512+
void setupMode()
513+
{
514+
deviceMode = EEPROM.read(MODE_ADDRESS); // Read the mode the device should be in
515+
516+
if (deviceMode > MODE_COUNTER)
517+
{ // If the mode is invalid, goto default mode
518+
deviceMode = MODE_DEFAULT;
519+
EEPROM.write(MODE_ADDRESS, MODE_DEFAULT);
520+
}
521+
}
522+
392523
//This sets up the two analog inputs
393524
void setupAnalog()
394525
{
@@ -465,7 +596,7 @@ void checkEmergencyReset(void)
465596
constantDisplay("0-00", 500);
466597
constantDisplay("-000", 500);
467598
}
468-
599+
469600
//Once we breakout of this loop (pin on RX is removed), system will init with new default settings
470601
}
471602

@@ -478,7 +609,7 @@ void constantDisplay (char *theString, long amountOfTime)
478609
}
479610

480611
// In case of emergency, resets all the system settings to safe values
481-
// This will reset baud, TWI address, and brightness to default values
612+
// This will reset baud, TWI address, brightness, and mode to default values
482613
void setDefaultSettings(void)
483614
{
484615
//Reset UART to 9600bps
@@ -490,5 +621,13 @@ void setDefaultSettings(void)
490621

491622
//Reset the I2C address to the default 0x71
492623
EEPROM.write(TWI_ADDRESS_ADDRESS, TWI_ADDRESS_DEFAULT);
624+
625+
//Reset the mode to the default data interface
626+
EEPROM.write(MODE_ADDRESS, MODE_DEFAULT);
627+
deviceMode = MODE_DEFAULT; //Return device's mode to default
493628
}
494629

630+
631+
632+
633+

firmware/Serial 7-Segment Display/Serial_7_Segment_Display_Firmware/settings.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,20 @@
2727
#define DECIMAL2 1
2828
#define DECIMAL1 0
2929

30+
#define MODE_DATA 0
31+
#define MODE_ANALOG 1
32+
#define MODE_COUNTER 2
33+
3034
const int TWI_ADDRESS_DEFAULT = 0x71;
3135
const int BAUD_DEFAULT = BAUD_9600; // 9600 for 8MHz, 2x speed
3236
const int BRIGHTNESS_DEFAULT = 100; // 100%, full brightness
37+
const int MODE_DEFAULT = MODE_DATA; // Watch for incoming data rather than pulses or analog voltages
3338

3439
//Internal EEPROM locations for the user settings
3540
const unsigned char BRIGHTNESS_ADDRESS = 0;
3641
const unsigned char BAUD_ADDRESS = 1;
3742
const unsigned char TWI_ADDRESS_ADDRESS = 2;
43+
const unsigned char MODE_ADDRESS = 3;
3844

3945
/* Command Modes */
4046
const unsigned char RESET_CMD = 0x76;
@@ -49,5 +55,6 @@ const unsigned char DIGIT4_CMD = 0x7E;
4955
const unsigned char BAUD_CMD = 0x7F;
5056
const unsigned char TWI_ADDRESS_CMD = 0x80; // !!! NEW
5157
const unsigned char FACTORY_RESET_CMD = 0x81; // !!! NEW
58+
const unsigned char MODE_CMD = 0x82; // !!! NEW
5259

5360
const int BUFFER_SIZE = 64;

0 commit comments

Comments
 (0)