/* Driving multiple 7-seg displays with 74HC595 shift registers. Feel free to re-use. 01/30/2010 */ // This pin gets sets low when I want the 595s to listen const int g_pinCommLatch = 6; // This pin is used by ShiftOut to toggle to say there's another bit to shift const int g_pinClock = 7; // This pin is used to pass the next bit const int g_pinData = 4; // Definitions of the 7-bit values for displaying digits byte g_digits [10]; // Current number being displayed int g_numberToDisplay = 0; // Number of shift registers in use const int g_registers = 4; // Array of numbers to pass to shift registers byte g_registerArray [g_registers]; void setup() { pinMode (g_pinCommLatch, OUTPUT); pinMode (g_pinClock, OUTPUT); pinMode (g_pinData, OUTPUT); Serial.begin (56600); // Setup the digits array // a = 8 b = 4 c = 2 d = 64 e = 32 f = 1 g = 16 g_digits [0] = 8 + 4 + 2 + 64 + 32 + 1; g_digits [1] = 4 + 2; g_digits [2] = 8 + 4 + 16 + 32 + 64; g_digits [3] = 8 + 4 + 16 + 2 + 64; g_digits [4] = 1 + 16 + 4 + 2; g_digits [5] = 8 + 1 + 16 + 2 + 64; g_digits [6] = 8 + 1 + 16 + 2 + 64 + 32; g_digits [7] = 8 + 4 + 2; g_digits [8] = 8 + 4 + 2 + 64 + 32 + 1 + 16; g_digits [9] = 8 + 4 + 2 + 1 + 16 + 64; } // setup // Simple function to send serial data to one or more shift registers by iterating backwards through an array. // Although g_registers exists, they may not all be being used, hence the input parameter. void sendSerialData ( byte registerCount, // How many shift registers? byte *pValueArray) // Array of bytes with LSByte in array [0] { // Signal to the 595s to listen for data digitalWrite (g_pinCommLatch, LOW); for (byte reg = registerCount; reg > 0; reg--) { byte value = pValueArray [reg - 1]; for (byte bitMask = 128; bitMask > 0; bitMask >>= 1) { digitalWrite (g_pinClock, LOW); digitalWrite (g_pinData, value & bitMask ? HIGH : LOW); digitalWrite (g_pinClock, HIGH); } } // Signal to the 595s that I'm done sending digitalWrite (g_pinCommLatch, HIGH); } // sendSerialData // Print a message specifying valid inputs, given the number of registers defined and then consume all current input. void badNumber () { int dummy; Serial.print ("Please enter a number from 0 to "); for (int loop = 0; loop < g_registers; loop++) { Serial.print ("9"); } Serial.println (" inclusive."); while (Serial.available () > 0) { dummy = Serial.read (); // Necessary to get all input in one go. delay (10); } } //badNumber // Read a number from the PC with no more digits than the defined number of registers. // Returns: number to display. If an invalid number was read, the number returned is the current number being displayed // int readNumberFromPC () { byte incomingByte; int numberRead; byte incomingCount; if (Serial.available () > 0) { numberRead = 0; incomingCount = 0; while (Serial.available () > 0) { incomingByte = Serial.read () - 48; incomingCount++; if (incomingByte < 0 || incomingByte > 9 || incomingCount > g_registers) { badNumber (); return g_numberToDisplay; } numberRead = 10 * numberRead + incomingByte; // Necessary to get all input in one go. delay (10); } Serial.print ("Now displaying: "); Serial.println (numberRead, DEC); return numberRead; } return g_numberToDisplay; } // readNumberFromPC void loop() { g_numberToDisplay = readNumberFromPC (); if (g_numberToDisplay < 10) { g_registerArray [3] = g_digits [0]; g_registerArray [2] = g_digits [0]; g_registerArray [1] = g_digits [0]; g_registerArray [0] = g_digits [g_numberToDisplay]; } else if (g_numberToDisplay < 100) { g_registerArray [3] = g_digits [0]; g_registerArray [2] = g_digits [0]; g_registerArray [1] = g_digits [g_numberToDisplay / 10]; g_registerArray [0] = g_digits [g_numberToDisplay % 10]; } else if (g_numberToDisplay < 1000) { g_registerArray [3] = g_digits [0]; g_registerArray [2] = g_digits [g_numberToDisplay / 100]; g_registerArray [1] = g_digits [(g_numberToDisplay % 100) / 10]; g_registerArray [0] = g_digits [g_numberToDisplay % 10]; } else { g_registerArray [3] = g_digits [g_numberToDisplay / 1000]; g_registerArray [2] = g_digits [(g_numberToDisplay % 1000) / 100]; g_registerArray [1] = g_digits [(g_numberToDisplay % 100) / 10]; g_registerArray [0] = g_digits [g_numberToDisplay % 10]; } sendSerialData (g_registers, g_registerArray); } // loop