#include #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) /* D7 - Ser (data) D5 - clock D1 - _OE D2 - latch D3 - _clear */ //Pins connected to Shift registers on own controller board #define PIN_DATA 13 #define PIN_CLK 14 #define PIN_OE 27 //active low #define PIN_LATCH 26 //Pins connected to stuff on annax driver board #define PIN_DATA_DRVBRD 33 #define PIN_CLK_DRVBRD 32 //#define PIN_CLEAR 25 //active low #define PIN_DRIVE 25 //enables 12v to panels via transistor #define PIN_CLEAR 12 //connects CLEAR Pin from Annax board to GND (clears column) #define NUMPANELS 1 void shiftOutSlow(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); bool clearSelectedColumn(); bool setSelectedDot(); void selectColumnClear(uint8_t selcolumn); void selectColumnSet(uint8_t selcolumn); void selectColumn(uint8_t selcolumn, bool clear); bool HBridgeOK(); void shiftData(); void resetColumns(); unsigned long loopmillis=0; unsigned long last_update=0; #define UPDATE_INTERVAL 10 void setup() { pinMode(PIN_DATA, OUTPUT); pinMode(PIN_CLK, OUTPUT); pinMode(PIN_OE, OUTPUT); pinMode(PIN_LATCH, OUTPUT); pinMode(PIN_CLEAR, OUTPUT); pinMode(PIN_DRIVE, OUTPUT); pinMode(PIN_DATA_DRVBRD, OUTPUT); pinMode(PIN_CLK_DRVBRD, OUTPUT); digitalWrite(PIN_OE, HIGH); //Active Low digitalWrite(PIN_LATCH, LOW); digitalWrite(PIN_DRIVE, LOW); Serial.begin(115200); } int countz=0; uint16_t row; //controls shift registers on own controller pcb uint8_t col[7]; //column drivers and shift registers on annax pcb void loop() { loopmillis = millis(); static bool init=false; if (!init) { delay(2000); row=0; Serial.println("Clearing Display"); for (int l=0;l<25;l++) { selectColumnClear(l%25); shiftData(); if (!clearSelectedColumn()) { Serial.println("Error clearing column!"); }else{ Serial.println("Cleared"); } delay(10); } init=true; delay(1000); } if (loopmillis > last_update + UPDATE_INTERVAL) { Serial.print("count="); Serial.print(countz);Serial.print(": "); //setting colX to 128, 32, 8,2 (or a combination of), then appling 12V to driver and GND to Clear, clears these colums // this applies +12v to selected columns //setting colX to 64,16,4,1 (or a combination of), then setting row shift registers to some setting sets the selected dots // this applies GND to selected columns //reset pin on annax board input should be used (not pulled to gnd for a short time) after dots have been flipped (to disable potentially activated transistors) //cycle testing set dots selectColumnSet(countz/16); //lower column number is on the left row=pow(2, (countz)%16);//low significant bits are lower rows (when connector at top) Serial.print("Row="); Serial.print(row); Serial.print(" Col="); for (uint8_t i=0;i<7;i++) { Serial.print(","); Serial.print(col[i]); } Serial.println(); //reset pin on ribbon cable high (12Vpullup/open), then low (via Transistor) shiftData(); setSelectedDot(); last_update=loopmillis; countz++; if (countz>=16*25) { countz=0; init=false; } } } #define SHIFTDELAYMICROS 100 void shiftOutSlow(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) { uint8_t i; for (i = 0; i < 8; i++) { if (bitOrder == LSBFIRST) digitalWrite(dataPin, !!(val & (1 << i))); else digitalWrite(dataPin, !!(val & (1 << (7 - i)))); delayMicroseconds(SHIFTDELAYMICROS); digitalWrite(clockPin, HIGH); delayMicroseconds(SHIFTDELAYMICROS); digitalWrite(clockPin, LOW); delayMicroseconds(SHIFTDELAYMICROS); } } void selectColumnClear(uint8_t selcolumn) { selectColumn(selcolumn, true); } void selectColumnSet(uint8_t selcolumn) { selectColumn(selcolumn, false); } void selectColumn(uint8_t selcolumn, bool clear) { uint8_t sc_bit=3-(selcolumn%4); //each two shift registers control four columns uint8_t sc_byte=selcolumn/4; resetColumns(); col[sc_byte]=pow(2, (sc_bit*2+clear)); // possible numbers for clear=false: 1,4,16,64 } bool clearSelectedColumn() { //Clear Columns if (row!=0) { return 0; //error. row is selected (short circuit!) } for (uint8_t cc=0;cc<7;cc++) { //Serial.print("checking cc="); Serial.println(cc); for (uint8_t i=0;i<8;i+=2) { if (CHECK_BIT(col[cc],i)) { Serial.print("Error on bit "); Serial.print(i); Serial.print(" col="); Serial.println(cc); return 0; //a column is set to ground (should not be set for clear column) } } } digitalWrite(PIN_DRIVE, HIGH); digitalWrite(PIN_CLEAR, HIGH); delay(50); digitalWrite(PIN_CLEAR, LOW); digitalWrite(PIN_DRIVE, LOW); return 1; } bool setSelectedDot() { for (uint8_t cc=0;cc<7;cc++) { //Serial.print("checking cc="); Serial.println(cc); for (uint8_t i=1;i<8;i+=2) { if (CHECK_BIT(col[cc],i)) { Serial.print("Error on bit "); Serial.print(i); Serial.print(" col="); Serial.println(cc); return 0; //a column is set to ground (should not be set for clear column) } } } if (!HBridgeOK) { return 0; } digitalWrite(PIN_OE, LOW); //Active Low digitalWrite(PIN_DRIVE, HIGH); delay(10); digitalWrite(PIN_OE, HIGH); //Active Low digitalWrite(PIN_DRIVE, LOW); return 1; } bool HBridgeOK() { for (uint8_t cc=0;cc<7;cc++) { //Serial.print("checking cc="); Serial.println(cc); for (uint8_t i=0;i<8;i+=2) { if (CHECK_BIT(col[cc],i) && CHECK_BIT(col[cc],i+1)) { Serial.print("Short circuit on bit "); Serial.print(i); Serial.print(" col="); Serial.println(cc); return 0; //a column is set to ground (should not be set for clear column) } } } return 1; } void shiftData() { //send out all data to shift registers //select Rows via shift registers on own controller board shiftOutSlow(PIN_DATA, PIN_CLK, LSBFIRST, row&0xff); //lower byte shiftOutSlow(PIN_DATA, PIN_CLK, LSBFIRST, row>>8); //LSBFIRST= LSB is QH, bit 8 is QA. //upper byte digitalWrite(PIN_LATCH, HIGH); delayMicroseconds(100); digitalWrite(PIN_LATCH, LOW); //Select Columns via Shift registers for (uint8_t i=0;i<7;i++) { shiftOutSlow(PIN_DATA_DRVBRD, PIN_CLK_DRVBRD, LSBFIRST, col[6-i]); } } void resetColumns() { for (uint8_t i=0;i<7;i++) { col[i]=0; } }