// 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
Comments