// 595 Real Time Manager/Simulator // by Ido Gendel, 2014 // Share and enjoy! // Don't forget to set the Arduino Serial Monitor // Baud rate to 115,200 // Pin connection scheme is below. #define PIN_CONTROLS 6 #define NON_PIN 255 const byte SER_PIN = 7; const byte SRCLK_PIN = 8; const byte OE_PIN = 6; const byte RCLK_PIN = 9; const byte SRCLR_PIN = 10; char cmd = 0; byte SRCLKRecIndex; // Pin controls byte clocksTied = 0; // output simulator byte currSER = 0; byte SR = 0; byte SRClearing = 0; byte Q = 0; byte QEnabled = 1; byte QHPrime = 0; //--------------------------------------------------------- void SERChange(char state) { currSER = state; } // SERChange //--------------------------------------------------------- void SRCLKChange(char state) { if (!state) return; SR = ((SR << 1) + currSER) * (!SRClearing); QHPrime = SR >> 7; } // SRCLKChange //--------------------------------------------------------- void RCLKChange(char state) { if (state) Q = SR; if (clocksTied) cmd = 'C'; } // RCLKChange //--------------------------------------------------------- void OEChange(char state) { QEnabled = !state; } // OEChange //--------------------------------------------------------- void SRCLRChange(char state) { SRClearing = !state; if (SRClearing) SR = 0; } // SRCLRChange struct tPinCtrl { char enabled, id, arduinoPin, state; void (*fnPtr) (char); char name[11]; } pinCtrl[PIN_CONTROLS] = {{1, 'S', SER_PIN, currSER, SERChange, "SER"}, {1, 'C', SRCLK_PIN, 0, SRCLKChange, "SRCLK"}, {1, 'R', RCLK_PIN, 0, RCLKChange, "RCLK"}, {1, 'E', OE_PIN, !QEnabled, OEChange, "OE"}, {1, 'L', SRCLR_PIN, !SRClearing, SRCLRChange, "SRCLR"}, {1, 'T', NON_PIN, 0, ClockTieChange, "Tie Clocks"}}; //--------------------------------------------------------- void ClockTieChange(char state) { clocksTied = state; pinCtrl[SRCLKRecIndex].enabled = !clocksTied; } // ClockTieChange //--------------------------------------------------------- // Locate correct record to avoid "magic numbers" void findSRCLKRecIndex() { for (SRCLKRecIndex = 0; SRCLKRecIndex < PIN_CONTROLS; SRCLKRecIndex++) if (pinCtrl[SRCLKRecIndex].arduinoPin == SRCLK_PIN) break; } // findSRCLKRecIndex //--------------------------------------------------------- void setup() { for (byte j = 0; j < PIN_CONTROLS; j++) if (pinCtrl[j].arduinoPin != NON_PIN) { pinMode(pinCtrl[j].arduinoPin, OUTPUT); digitalWrite(pinCtrl[j].arduinoPin, pinCtrl[j].state); } // if findSRCLKRecIndex(); Serial.begin(115200); } // setup //--------------------------------------------------------- void printFormattedByte(byte b) { for (byte j = 0; j < 8; j++) { Serial.print(b & 128 ? "1" : "0"); b <<= 1; } // for } // printFormattedByte //--------------------------------------------------------- void printICState() { Serial.print(F("Shift Register (Hidden) = ")); printFormattedByte(SR); Serial.println(); Serial.print(F("Storage Register (Output) = ")); printFormattedByte(Q); Serial.println(QEnabled ? " (Enabled)" : " High Z (Disabled)"); Serial.print(F("QH' (Daisy chain output) = ")); Serial.println((byte)QHPrime); } // printICState //--------------------------------------------------------- void printOptions() { for (byte j = 0; j < PIN_CONTROLS; j++) { if (!pinCtrl[j].enabled) continue; Serial.print("["); Serial.print(pinCtrl[j].id); Serial.print("] "); Serial.print(pinCtrl[j].name); Serial.print(F(" (current state=")); Serial.print((byte)pinCtrl[j].state); Serial.println(")"); } // for } // printOptions //--------------------------------------------------------- void printHeader() { Serial.println(); Serial.println(F("==================================")); Serial.println(F("Current 595 IC state:")); printICState(); Serial.println(F("--------------------------------\n")); Serial.println(F("Select a pin/option to toggle:")); } // printHeader //--------------------------------------------------------- void loop() { char c, userInput = 0; byte j; printHeader(); printOptions(); while (!cmd) if (Serial.available()) { cmd = toupper(Serial.read()); userInput = 1; } // if c = cmd; cmd = 0; for (j = 0; j < PIN_CONTROLS; j++) if (c == pinCtrl[j].id) { if ((!pinCtrl[j].enabled) && userInput) continue; pinCtrl[j].state = !pinCtrl[j].state; if (pinCtrl[j].arduinoPin != NON_PIN) digitalWrite(pinCtrl[j].arduinoPin, pinCtrl[j].state); pinCtrl[j].fnPtr(pinCtrl[j].state); break; } // if if (j == PIN_CONTROLS) { Serial.println(F("\nSorry, I don't understand!")); delay(1000); } // if } // loop