#include "flipdot.h" Flipdot::Flipdot() { } void Flipdot::init() { 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); } void Flipdot::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(MICROS_SHIFTDELAY); digitalWrite(clockPin, HIGH); delayMicroseconds(MICROS_SHIFTDELAY); digitalWrite(clockPin, LOW); } } void Flipdot::selectColumnClear(uint8_t selcolumn) { selectColumn(selcolumn, true); } void Flipdot::selectColumnSet(uint8_t selcolumn) { selectColumn(selcolumn, false); } void Flipdot::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 Flipdot::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); delayMicroseconds(MICROS_DRIVEDOTCLEAR); digitalWrite(PIN_CLEAR, LOW); digitalWrite(PIN_DRIVE, LOW); return 1; } bool Flipdot::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); delayMicroseconds(MICROS_DRIVEDOTSET); //Drive Dot digitalWrite(PIN_OE, HIGH); //Active Low digitalWrite(PIN_DRIVE, LOW); return 1; } bool Flipdot::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 Flipdot::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(MICROS_SHIFT_LATCH); 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 Flipdot::resetColumns() { for (uint8_t i=0;i<7;i++) { col[i]=0; } }