#define ClockPin 2 // clock pin for all displays #define ResetPin 7 // reset pin for all displays //Frames #define DISPLAYS 4 // Number of displays in use #define LINES 2 // Number of lines each display has #define FRAMES 3 // Number of frames to use // How many Chars/Numbers/displays per line, and how many segments each char has // Line one (7 14 segment displays) #define LINE_ONE_CHARS 7 #define LINE_ONE_SEGMENTS 14 // Line two (4 7 segement displays) #define LINE_TWO_CHARS 4 #define LINE_TWO_SEGMENTS 7 // Put the above into arrays, not sure how to make array constants int nbrChars[] = {LINE_ONE_CHARS,LINE_TWO_CHARS}; int nbrSegments[] = {LINE_ONE_SEGMENTS,LINE_TWO_SEGMENTS}; // Data pins, one for each display (again not sure how to make array constants) int DataPins[] = {3,4,5,6}; // Set default text to display. array format, one entry per display per frame per line. // disp is line 1 frame 1 / line 1 frame 2 / line 2 frame 1 / line 2 frame 2... etc // TODO - each "string" MUST be unique as its a pointer and somehow duplicates end up being the same pointer reference. // length does not matter, so thats why there is number padding after the 2nd line displays (to make them off by default, yet still unique) char *disp[] = { "ARDUINO","POWERED","DATA ","DISPLAY",// "CREATED","BY ","TIM ","WATSON ", " 1"," 2"," 3"," 4", " 01"," 02"," 03"," 04", " 11"," 12"," 13"," 14", " 21"," 22"," 23"," 24" }; char inString[7]; // storage for incoming buffer. Line one is 7 chars, so thats as long as we need int loopCnt = 0; // Loop counter int loopRst = 400; // How many loops before next frame int loopFrame = 0; // Current frame counter int incomingByte; // icoming byte from serial connection int incomingByteCount = 0; // counter for how many bytes received in this buffer // When incoming bytes... int dispToUpdate = 0; // Which display are we updating int lineToUpdate = 0; // Which line are we to update int frameToUpdate = 0; // Which frame are we to update void setup() { // set clock and reset as output pinMode(ClockPin, OUTPUT); pinMode(ResetPin, OUTPUT); // set each data pin as output for (int dp = 0; dp <= DISPLAYS; dp++) { pinMode(DataPins[dp], OUTPUT); } Serial.begin(9600); // RESET the displays digitalWrite(ResetPin,HIGH); delay(10); digitalWrite(ResetPin,LOW); } void loop() { // loopRst loop iterations have happened, increment frame count (or back to frame 0) if (loopCnt >= loopRst) { loopCnt = 0; if (loopFrame == (FRAMES - 1)) { loopFrame = 0; } else { loopFrame++; } } loopCnt++; if (Serial.available() > 0) { incomingByte = Serial.read(); //Serial.print("incomingByte: "); //Serial.println(incomingByte); if (incomingByteCount == 0) { // which display to update, expects 1-4 if (incomingByte >= 49 && incomingByte <= 52) { dispToUpdate = incomingByte - 49; //Serial.print("Display: "); //Serial.println(dispToUpdate); incomingByteCount++; } else { // ignore untill we get a display //Serial.println("Reset on disp"); } } else if (incomingByteCount == 1) { // which line to update, expects 1-2 if (incomingByte == 49 || incomingByte == 50) { lineToUpdate = incomingByte - 49; //Serial.print("Line: "); //Serial.println(lineToUpdate); incomingByteCount++; } else { // bad line # - reset all incomingByteCount = 0; //Serial.println("Reset on line"); } } else if (incomingByteCount == 2) { // which frame to update, expects 1-X if (incomingByte >= 49 && incomingByte <= (49 + FRAMES)) { frameToUpdate = incomingByte - 49; //Serial.print("Frame: "); //Serial.println(frameToUpdate); incomingByteCount++; } else { // bad frame # - reset all incomingByteCount = 0; //Serial.println("Reset on frame"); } } else if (incomingByteCount - 3 >= nbrChars[lineToUpdate] || incomingByte == 10 || incomingByte == 13) { // End of buffer //Serial.println("EOF "); //Serial.print("Disp: "); //Serial.println(dispToUpdate); //Serial.print("Text: "); //Serial.println(inString); // pad any open areas with blank int pad = incomingByteCount - 3; for (pad; pad < nbrChars[lineToUpdate]; pad++) { inString[pad] = 32; //Serial.println("padding"); } // update disp text holder //dlfToUpdate = dispToUpdate + (lineToUpdate * 8) + (frameToUpdate * 4); int dlfToUpdate = dispToUpdate + (lineToUpdate * (DISPLAYS * FRAMES)) + (frameToUpdate * DISPLAYS); for (int i=0; i= 3) && (i == 15)) { ShowChar(0,loopFrame,x+2); } // 2nd letter on row 3,4 // line 2 - 4 char 7 segments NUMERIALS else if (((x == 1) || (x == 2)) && (i == 15)) { ShowChar(1,loopFrame,x-1); } else if (((x == 1) || (x == 2)) && (i == 22)) { ShowChar(1,loopFrame,x+1); } else if ((x >= 1) && (i < 29)) { } // portion of letter + numbers.. writing of bitsis done in ShowChar else if (i == (30 + x)) { WritebitAll(1); } // transistor first line would be 10000... 2nd 01000 and so on else { WritebitAll(0); } // anything and everything else low } } } // definitions for 14 segment chars unsigned int LineOne(char index) { switch (index) { case 'A': return 0b11101100100010; case 'B': return 0b11110010101000; case 'C': return 0b10011100000000; case 'D': return 0b11110010001000; case 'E': return 0b10011100100010; case 'F': return 0b10001100100010; case 'G': return 0b10111100100000; case 'H': return 0b01101100100010; case 'I': return 0b10010010001000; case 'J': return 0b01110000000000; case 'K': return 0b00001101010010; case 'L': return 0b00011100000000; case 'M': return 0b01101101000001; case 'N': return 0b01101100010001; case 'O': return 0b11111100000000; case 'P': return 0b11001100100010; case 'Q': return 0b11111100010000; case 'R': return 0b11001100110010; case 'S': return 0b10110100100010; case 'T': return 0b10000010001000; case 'U': return 0b01111100000000; case 'V': return 0b00001101000100; case 'W': return 0b01101100010100; case 'X': return 0b00000001010101; case 'Y': return 0b00000001001001; case 'Z': return 0b10010001000100; default: return 0b00000000000000; } } // definitions for 7 segment displays unsigned int LineTwo(char index) { switch (index) { case '0': return 0b1111110; case '1': return 0b0110000; case '2': return 0b1101101; case '3': return 0b1111001; case '4': return 0b0110011; case '5': return 0b1011011; case '6': return 0b0011111; case '7': return 0b1110000; case '8': return 0b1111111; case '9': return 0b1111011; case 'H': return 0b0110111; case 'L': return 0b0001110; case '-': return 0b0000001; default: return 0b0000000; } } // write character.. takes line, a frame and a position (position being which char in string to display) void ShowChar(int line, int frame, int position){ unsigned int bit = 1; for( int i=0; i < nbrSegments[line]; i++) { //shift through all X bits (7 or 4 in this case) bit = 1<<(nbrSegments[line] -1 - i); for (int dp = 0; dp < DISPLAYS; dp++) { //shift through each display int dispIndex = dp + (line * (DISPLAYS * FRAMES)) + (frame * DISPLAYS); unsigned int currentNum; if (line == 0) { currentNum = LineOne(disp[dispIndex][position]); } else { currentNum = LineTwo(disp[dispIndex][position]); } if(currentNum & bit ) { digitalWrite(DataPins[dp], HIGH); } else { digitalWrite(DataPins[dp], LOW); } } WiggleClock(); } } // write a signle bit for all displays void WritebitAll(int hl) { if (hl == 1) { for (int dp = 0; dp < DISPLAYS; dp++) { digitalWrite(DataPins[dp],HIGH); } } else { for (int dp = 0; dp < DISPLAYS; dp++) { digitalWrite(DataPins[dp],LOW); } } WiggleClock(); } // wiggle clock to signal next bit coming void WiggleClock(){ // seems like there should be delays here and the tech sheet for the displays I guess mentions delays, // yet it works fine with no delays. (less shakes on updates with no delay, so leaving it) //delayMicroseconds(3); // pause digitalWrite(ClockPin, HIGH); // Clock set to high //delayMicroseconds(10); digitalWrite(ClockPin, LOW); // clock ends low }