From 5ff3a3b28285c9f7178fc4ce1ab9ca1d517f9858 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sun, 7 Jul 2024 23:47:23 +0200 Subject: [PATCH] Running all devices --- all-functions/all-functions.ino | 331 ++++++++++++++++++++++++ all-functions/center-column-saa1064.ino | 123 +++++++++ 2 files changed, 454 insertions(+) create mode 100644 all-functions/all-functions.ino create mode 100644 all-functions/center-column-saa1064.ino diff --git a/all-functions/all-functions.ino b/all-functions/all-functions.ino new file mode 100644 index 0000000..bdfebbb --- /dev/null +++ b/all-functions/all-functions.ino @@ -0,0 +1,331 @@ +#include "Wire.h" +#include // Load the PCA9554 Library + +#define TCAADDR 0x70 + +// byte saa1064 = 0x3B; +PCA9554 ioCon1(0x24); // Create an object at this address + + +// LEDs have two addresses, one for RED another for GREEN +bool fanGreenLED; +bool fanRedLED; +bool tempGreenLED; +bool tempRedLED; +bool powerGreenLED; +bool powerRedLED; +bool modeSelect; + +bool nic1State = 0; +bool nic2State = 0; +bool lockButtonState = 1; +bool modeButtonState = 1; + +int powerState = 0; +// first bit is current value, second bit is alarm state +int fanState[2] = {0, 0}; +int tempState[2] = {0, 0}; + +byte centerColumnsMemoryMap[2][4] = { + {0b00000000, 0b00000000, 0b00000000, 0b00000000}, // left column + {0b00000000, 0b00000000, 0b00000000, 0b00000000} // right column +}; + +byte ioHash = 0; + +// --- ADDRESS MAPs --- +int IOMapLength = 8; +bool* mapIO[8] = {&powerGreenLED, &powerRedLED, &fanGreenLED, &fanRedLED, &tempGreenLED, &tempRedLED, &lockButtonState, &modeSelect}; +// bool mapNics[3] = {nic1State, nic2State}; + +// --- PIN DEFINITIONS --- +int POWER_FAIL_PIN = 8; +int FAN_PIN = 9; +int POWER_PIN = 12; +int NIC_1_PIN = 10; +int NIC_2_PIN = 11; +int BUTTON_LOCK_PIN = A3; +int BUTTON_MODE_PIN = A2; + +unsigned long lastDebounceTimeLock = 0; +unsigned long lastDebounceTimeMode = 0; +const int DEBOUNCE_DELAY = 30; + +unsigned long lastUpdateIO = 0; +const int IO_UPDATE_INTERVAL = 200; + +void setup() { + Serial.begin(9600); + // Serial.println(mapIO[0]); + pinMode(POWER_FAIL_PIN, INPUT); + pinMode(FAN_PIN, INPUT); + pinMode(NIC_1_PIN, INPUT); + pinMode(NIC_2_PIN, INPUT); + pinMode(POWER_PIN, INPUT); + + pinMode(BUTTON_LOCK_PIN, INPUT_PULLUP); + pinMode(BUTTON_MODE_PIN, INPUT_PULLUP); + + Serial.println("setup all pinouts"); + Wire.begin(); // start up I2C bus + Serial.println("i2c setup"); + + ioCon1.portMode(ALLOUTPUT); + Serial.println("iocon1 setup"); + + delay(500); + + selectRightHalf(); + lightUpIO(); + selectLeftHalf(); + lightUpIO(); +} + +void lightUpIO() { + Serial.println("ligthing up top io"); + for (int i = 0; i < IOMapLength; ++i) { + ioCon1.digitalWrite(i, mapIO[i]); + } + Serial.println("finished ligthing up top io"); +} + +unsigned long currentTime = millis(); + +void updateTime() { + currentTime = millis(); +} + +int fanBlinkCounter = 0; + +unsigned long fanToggledAt; +void updateFanState(int state) { + // fan changed and did so within 1 second + bool stateChanged = state != fanState[0]; + fanState[0] = state; + + // detect that blinking is happening + if (stateChanged && (currentTime - fanToggledAt > 250)) { + fanState[1] = 1; + fanToggledAt = currentTime; + } + + // detect that blinking stopped + // if alarm && it changes && it has been more then 2 times the frex since last toggle + if (fanState[1] == 1 && (currentTime > fanToggledAt + 1000)) { + // nothing to see here + fanState[1] = 0; + } +} + +unsigned long tempToggledAt; +void updateTempState(int state) { + bool stateChanged = state != tempState[0]; + tempState[0] = state; + + // was 2 seconds ago last time it toggled + if (stateChanged == 1 && (currentTime - tempToggledAt > 250)) { + tempState[1] = 1; + tempToggledAt = currentTime; + } + + // detect that blinking stopped + // if alarm && it changes && it has been more then 2 times the frex since last toggle + if (tempState[1] == 1 && (currentTime > tempToggledAt + 1000)) { + // nothing to see here + tempState[1] = 0; + } +} + +// TODO check that this goes RED when off +void greenRed(bool* greenLED, bool* redLED, bool value) { + // if no power set red led + if (value == 0) { + *greenLED = 0; + *redLED = 1; + // else if power set green led + } else { + *greenLED = 1; + *redLED = 0; + } +} + +void greenRedOnAlarm(bool* greedLED, bool* redLED, bool alarm) { + // if not alarm set green led + if (alarm == 0) { + *greedLED = 1; + *redLED = 0; + // if alarm set red led + } else { + *greedLED = 0; + *redLED = 1; + } +} + +void greenRedBlinkOnAlarm(bool* greenLED, bool* redLED, bool value, bool alarm) { +// void greenRedBlinkOnAlarm(bool* greenLED, bool* redLED, bool* currentState, bool* alarmState) { + // if no alarm --> set green led + if (alarm == 0) { + *greenLED = 1; + *redLED = 0; + return; + } + + // everything below assumes alarm state + // alarm and signal --> red led (blink on) + if (value == 0) { + *greenLED = 0; + *redLED = 1; + } + // alarm and no signal --> no led (blink off) + else { + *greenLED = 0; + *redLED = 0; + } +} + +void writeIOLEDPoweredOff() { + ioCon1.digitalWrite(0, HIGH); + ioCon1.digitalWrite(1, LOW); + ioCon1.digitalWrite(2, HIGH); + ioCon1.digitalWrite(3, HIGH); + ioCon1.digitalWrite(4, HIGH); + ioCon1.digitalWrite(5, HIGH); + ioCon1.digitalWrite(6, *(mapIO[6]) == 1 ? 0 : 1); +} + +void updateIOLED() { + if (powerState == 0) { + writeIOLEDPoweredOff(); + return; + } + + for (int i = 0; i < IOMapLength; ++i) { + ioCon1.digitalWrite(i, *(mapIO[i]) == 1 ? 0 : 1); + } +} + +int lastIOHash = -1; +bool shouldUpdateIOLed() { + greenRedBlinkOnAlarm(&fanGreenLED, &fanRedLED, fanState[0], fanState[1]); + greenRedOnAlarm(&tempGreenLED, &tempRedLED, tempState[1]); + greenRed(&powerGreenLED, &powerRedLED, powerState); + + byte ioHash = 0; + for (byte i = 0; i < IOMapLength; i++) + { + bitWrite(ioHash, i, *(mapIO[i])); + } + + if (ioHash == lastIOHash) { + // Don't update i2c ctrl if same value + // Serial.println("Not updating!!"); + return false; + } + + // Serial.println("Updating IO!!"); + lastIOHash = ioHash; + return true; +} + +void updateState() { + bool fanS = digitalRead(FAN_PIN); + updateFanState(fanS); + updateTempState(fanS); + powerState = digitalRead(POWER_PIN); + + nic1State = !digitalRead(NIC_1_PIN); + nic2State = !digitalRead(NIC_2_PIN); +} + +bool handleButtonPress(int address, bool* value, long unsigned int* debounce) { + bool btnVal = !digitalRead(address); + + if (btnVal != *value) { + *debounce = currentTime; + *value = btnVal; + } + + if (*debounce > 0 && (currentTime - *debounce) > DEBOUNCE_DELAY) { + *debounce = 0; + return true; + } + + return false; +} + +void changeModes() { + bool btnVal = !digitalRead(BUTTON_MODE_PIN); + + if (btnVal == 1) { + modeSelect = !modeSelect; + } +} + +void tcaselect(uint8_t i) { + if (i > 7) return; + + Wire.beginTransmission(TCAADDR); + Wire.write(1 << i); + Wire.endTransmission(); +} + +void selectLeftHalf() { + tcaselect(2); +} + +void selectRightHalf() { + tcaselect(1); +} + +void writeEthernetActivity() { + selectLeftHalf(); + resetEthernetBit(centerColumnsMemoryMap[0]); + computeEthernetActivity(centerColumnsMemoryMap[0], nic1State); + writeCenterColumnFirstBank(centerColumnsMemoryMap[0]); + delay(1); + + selectRightHalf(); + resetEthernetBit(centerColumnsMemoryMap[1]); + computeEthernetActivity(centerColumnsMemoryMap[1], nic2State); + writeCenterColumnFirstBank(centerColumnsMemoryMap[1]); +} + +void loop() { + // Serial.println("loop start"); + + updateTime(); + updateState(); + handleButtonPress(BUTTON_LOCK_PIN, &lockButtonState, &lastDebounceTimeLock); + if (handleButtonPress(BUTTON_MODE_PIN, &modeButtonState, &lastDebounceTimeMode)) { + changeModes(); + } + + writeEthernetActivity(); + + if (shouldUpdateIOLed() == true) { + resetBanks(centerColumnsMemoryMap[0]); + + selectLeftHalf(); + updateIOLED(); + // displayUpToNumber(21); + displayPercentage(centerColumnsMemoryMap[0], 0.91); + + delay(1); + resetBanks(centerColumnsMemoryMap[1]); + selectRightHalf(); + updateIOLED(); + displayUpToNumber(centerColumnsMemoryMap[1], random(24)); + } + // if (currentTime - lastUpdateIO > IO_UPDATE_INTERVAL) { + // lastUpdateIO = currentTime; + // updateIOLED(); + // } +// selectRightHalf(); +// selectLeftHalf(); +// shouldUpdateIOLed + +// updateRightIOLED(); + + delay(20); + // Serial.println("loop end"); +} \ No newline at end of file diff --git a/all-functions/center-column-saa1064.ino b/all-functions/center-column-saa1064.ino new file mode 100644 index 0000000..0e8c768 --- /dev/null +++ b/all-functions/center-column-saa1064.ino @@ -0,0 +1,123 @@ +// #include "Wire.h" // enable I2C bus + +byte saa1064 = 0x3B; // define the I2C bus address for our SAA1064 + +byte bank1; +byte bank2; +byte bank3; +byte bank4; + +int TOTAL_LEDS = 23; +byte activityLED = 0b00000001; +byte leds[23][4] = { + {0b00000010, 0b00000000, 0b00000000, 0b00000000}, // 1 + {0b00000000, 0b00000010, 0b00000000, 0b00000000}, // 2 + {0b00000100, 0b00000000, 0b00000000, 0b00000000}, // 3 + {0b00000000, 0b00000100, 0b00000000, 0b00000000}, // 4 + {0b00001000, 0b00000000, 0b00000000, 0b00000000}, // 5 + {0b00000000, 0b00001000, 0b00000000, 0b00000000}, // 6 + {0b00010000, 0b00000000, 0b00000000, 0b00000000}, // 7 + {0b00000000, 0b00010000, 0b00000000, 0b00000000}, // 8 + {0b00100000, 0b00000000, 0b00000000, 0b00000000}, // 9 + {0b00000000, 0b00100000, 0b00000000, 0b00000000}, // 10 + {0b01000000, 0b00000000, 0b00000000, 0b00000000}, // 11 + {0b00000000, 0b01000000, 0b00000000, 0b00000000}, // 12 + {0b00000000, 0b00000000, 0b00000001, 0b00000000}, // 13 + {0b00000000, 0b00000000, 0b00000000, 0b00000001}, // 14 + {0b00000000, 0b00000000, 0b00000010, 0b00000000}, // 15 + {0b00000000, 0b00000000, 0b00000000, 0b00000010}, // 16 + {0b00000000, 0b00000000, 0b00000100, 0b00000000}, // 17 + {0b00000000, 0b00000000, 0b00000000, 0b00000100}, // 18 + {0b00000000, 0b00000000, 0b00001000, 0b00000000}, // 19 + {0b00000000, 0b00000000, 0b00000000, 0b00001000}, // 20 + {0b00000000, 0b00000000, 0b00010000, 0b00000000}, // 21 + {0b00000000, 0b00000000, 0b00100000, 0b00000000}, // 22 + {0b00000000, 0b00000000, 0b01000000, 0b00000000} // 23 +}; + +// void setup() +// { +// Wire.begin(); // start up I2C bus + +// Serial.println("setting up ports"); + +// resetBanks(); +// } + +// resetBanks(); + + +void writeCenterColumn(byte* banks) { + Wire.beginTransmission(saa1064); + Wire.write(1); + + Wire.write(banks[0]); + Wire.write(banks[1]); + Wire.write(banks[2]); + Wire.write(banks[3]); + + Wire.endTransmission(); +} + +void writeCenterColumnFirstBank(byte* banks) { + Wire.beginTransmission(saa1064); + Wire.write(1); + + Wire.write(banks[0]); + + Wire.endTransmission(); +} + +// TODO prevent this from overwriting ethernet bit +void resetBanks(byte* banks) { + banks[0] = 0; + banks[1] = 0; + banks[2] = 0; + banks[3] = 0; +} + +void resetEthernetBit(byte* banks) { + bitWrite(banks[0], 0, 0); +} + +void displayNumber(byte* banks, int number) { + banks[0] = leds[number - 1][0]; + banks[1] = leds[number - 1][1]; + banks[2] = leds[number - 1][2]; + banks[3] = leds[number - 1][3]; + + writeCenterColumn(banks); +} + +void displayUpToNumber(byte* banks, int number) { + for (int i = 0; i < number; i++) { + banks[0] |= leds[i][0]; + banks[1] |= leds[i][1]; + banks[2] |= leds[i][2]; + banks[3] |= leds[i][3]; + } + + writeCenterColumn(banks); +} + +void displayNumbers(byte* banks, int* numbersList, size_t length) { + for (int i = 0; i < length; i++) { + int num = numbersList[i] - 1; + banks[0] |= leds[num][0]; + banks[1] |= leds[num][1]; + banks[2] |= leds[num][2]; + banks[3] |= leds[num][3]; + } + + writeCenterColumn(banks); +} + +void displayPercentage(byte* banks, double percentDecimal) { + int numberOfTotal = round(percentDecimal * TOTAL_LEDS); + displayUpToNumber(banks, numberOfTotal); +} + +void computeEthernetActivity(byte* banks, bool val) { + // bitWrite(bank1, 0, val); + banks[0] |= val; // 0 or 1 +}