diff --git a/center-column/addressing_patterns-tcaa/addressing_patterns-tcaa.ino b/center-column/addressing_patterns-tcaa/addressing_patterns-tcaa.ino new file mode 100644 index 0000000..e95ca4b --- /dev/null +++ b/center-column/addressing_patterns-tcaa/addressing_patterns-tcaa.ino @@ -0,0 +1,145 @@ +#include "Wire.h" // enable I2C bus + +#define TCAADDR 0x70 +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 initDisplay() +{ + Serial.println("starting display"); + Wire.beginTransmission(saa1064); + Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte + Wire.endTransmission(); +} + +void setup() +{ + Serial.begin(9600); + Wire.begin(); // start up I2C bus + + Serial.println("setting up ports"); + + resetBanks(); + _write(); +} + +void tcaselect(uint8_t i) { + if (i > 7) return; + + Wire.beginTransmission(TCAADDR); + Wire.write(1 << i); + Wire.endTransmission(); +} + +void selectLeft() { tcaselect(2); } +void selectRight() { tcaselect(1); } + +void _write() { + selectLeft(); + write(); + delay(1); + selectRight(); + write(); +} + +void write() { + Wire.beginTransmission(saa1064); + Wire.write(1); + + Wire.write(bank1); + Wire.write(bank2); + Wire.write(bank3); + Wire.write(bank4); + + Wire.endTransmission(); +} + +void resetBanks() { + bank1 = 0; + bank2 = 0; + bank3 = 0; + bank4 = 0; +} + +void displayNumber(int number) { + bank1 = leds[number - 1][0]; + bank2 = leds[number - 1][1]; + bank3 = leds[number - 1][2]; + bank4 = leds[number - 1][3]; +} + +void displayUpToNumber(int number) { + for (int i = 0; i < number; i++) { + bank1 |= leds[i][0]; + bank2 |= leds[i][1]; + bank3 |= leds[i][2]; + bank4 |= leds[i][3]; + } +} + +void displayNumbers(int* numbersList, size_t length) { + for (int i = 0; i < length; i++) { + int num = numbersList[i] - 1; + bank1 |= leds[num][0]; + bank2 |= leds[num][1]; + bank3 |= leds[num][2]; + bank4 |= leds[num][3]; + } +} + +void displayPercentage(double percentDecimal) { + int numberOfTotal = round(percentDecimal * TOTAL_LEDS); + displayUpToNumber(numberOfTotal); +} + +void computeEthernetActivity(bool val) { + bank1 |= val; // 0 or 1 +} + +void loop() { + resetBanks(); + delay(10); + + int length = 8; + int numbers[8] = {2,3,5,6,7,13,17,22}; + displayNumbers(numbers, length); + // displayUpToNumber(15); + // displayNumber(16); + // displayPercentage(0.91); + computeEthernetActivity(false); + + _write(); + delay(1000); +} \ No newline at end of file diff --git a/center-column/waterfall/waterfall.ino b/center-column/waterfall/waterfall.ino new file mode 100644 index 0000000..3290e56 --- /dev/null +++ b/center-column/waterfall/waterfall.ino @@ -0,0 +1,200 @@ + + +/* + Example 39.1 - NXP SAA1064 I2C LED Driver IC Demo I + Demonstrating display of digits + http://tronixstuff.com + */ +#include "Wire.h" // enable I2C bus +#include // Load the PCA9554 Library + +byte saa1064 = 0x3B; // define the I2C bus address for our SAA1064 (pin 1 to GND) **** +PCA9554 ioCon1(0x24); // Create an object at this address + +int digits[16]={63, 6, 91, 79, 102, 109, 125,7, 127, 111, 119, 124, 57, 94, 121, 113}; +// these are the byte representations of pins required to display each digit 0~9 then A~F +void setup() +{ + Serial.begin(9600); + Wire.begin(); // start up I2C bus + + Serial.println("setting up ports"); + ioCon1.portMode(ALLOUTPUT); + + delay(500); + initDisplay(); + lightUpIO(); +} +void initDisplay() +// turns on dynamic mode and adjusts segment current to 12mA +{ +Serial.println("starting display"); + Wire.beginTransmission(saa1064); + Wire.write(B00000000); // this is the instruction byte. Zero means the next byte is the control byte + Wire.write(B01000111); // control byte (dynamic mode on, digits 1+3 on, digits 2+4 on, 12mA segment current + Wire.endTransmission(); +} + +void lightUpIO() { + Serial.println("light up IO"); + ioCon1.digitalWrite(0, LOW); // power green + ioCon1.digitalWrite(1, HIGH); // power red + ioCon1.digitalWrite(2, LOW); // fan green + ioCon1.digitalWrite(3, HIGH); // fan red + ioCon1.digitalWrite(4, LOW); // temp green + ioCon1.digitalWrite(5, HIGH); // temp red + ioCon1.digitalWrite(6, LOW); // lock +} + +int cursor = 0; +#define WORD_SIZE 25 + +byte registers[4] = {0, 0, 0, 0}; + +byte words[WORD_SIZE][4] = { + { 0x00, 0x00, 0x00, 0x00 }, + { 0x01, 0x00, 0x00, 0x00 }, + { 0x03, 0x00, 0x00, 0x00 }, + { 0x03, 0x03, 0x00, 0x00 }, + { 0x07, 0x03, 0x00, 0x00 }, + { 0x07, 0x07, 0x00, 0x00 }, + { 0x0F, 0x07, 0x00, 0x00 }, + { 0x0F, 0x0F, 0x00, 0x00 }, + { 0x1F, 0x0F, 0x00, 0x00 }, + { 0x1F, 0x1F, 0x00, 0x00 }, + { 0x3F, 0x1F, 0x00, 0x00 }, + { 0x3F, 0x3F, 0x00, 0x00 }, + { 0x7F, 0x3F, 0x00, 0x00 }, + { 0x7F, 0x7F, 0x00, 0x00 }, + { 0x7F, 0x7F, 0x01, 0x00 }, + { 0x7F, 0x7F, 0x01, 0x01 }, + { 0x7F, 0x7F, 0x03, 0x01 }, + { 0x7F, 0x7F, 0x03, 0x03 }, + { 0x7F, 0x7F, 0x07, 0x03 }, + { 0x7F, 0x7F, 0x07, 0x07 }, + { 0x7F, 0x7F, 0x0F, 0x07 }, + { 0x7F, 0x7F, 0x0F, 0x0F }, + { 0x7F, 0x7F, 0x1F, 0x0F }, + { 0x7F, 0x7F, 0x3F, 0x1F }, + { 0x7F, 0x7F, 0x7F, 0x1F } +}; + +byte words_reversed[WORD_SIZE][4] = { + // { 0x7F, 0x7F, 0x7F, 0x1F }, + { 0x7F, 0x7F, 0x3F, 0x1F }, + { 0x7F, 0x7F, 0x1F, 0x0F }, + { 0x7F, 0x7F, 0x0F, 0x0F }, + { 0x7F, 0x7F, 0x0F, 0x07 }, + { 0x7F, 0x7F, 0x07, 0x07 }, + { 0x7F, 0x7F, 0x07, 0x03 }, + { 0x7F, 0x7F, 0x03, 0x03 }, + { 0x7F, 0x7F, 0x03, 0x01 }, + { 0x7F, 0x7F, 0x01, 0x01 }, + { 0x7F, 0x7F, 0x01, 0x00 }, + { 0x7F, 0x7F, 0x00, 0x00 }, + { 0x7F, 0x3F, 0x00, 0x00 }, + { 0x3F, 0x3F, 0x00, 0x00 }, + { 0x3F, 0x1F, 0x00, 0x00 }, + { 0x1F, 0x1F, 0x00, 0x00 }, + { 0x1F, 0x0F, 0x00, 0x00 }, + { 0x0F, 0x0F, 0x00, 0x00 }, + { 0x0F, 0x07, 0x00, 0x00 }, + { 0x07, 0x07, 0x00, 0x00 }, + { 0x07, 0x03, 0x00, 0x00 }, + { 0x03, 0x03, 0x00, 0x00 }, + { 0x03, 0x00, 0x00, 0x00 }, + { 0x01, 0x00, 0x00, 0x00 } + // { 0x00, 0x00, 0x00, 0x00 } +}; + +void displayDigits() +// show all digits 0~9, A~F on all digits of display +{ + Serial.println("displaying digits"); + + + // first array + // 000000 + // 000001 + // 000011 + // 000111 + + Wire.beginTransmission(saa1064); + Wire.write(1); + + // write whatever we have placed in these registers + Wire.write(registers[0]); + Wire.write(registers[1]); + Wire.write(registers[2]); + Wire.write(registers[3]); + + Wire.endTransmission(); +} + +void movePage() { + cursor = cursor + 1; + + if (cursor > (WORD_SIZE * 2)) { + cursor = 0; + } + + if (cursor <= 24) { + registers[0] = words[cursor][0]; + registers[1] = words[cursor][1]; + registers[2] = words[cursor][2]; + registers[3] = words[cursor][3]; + } else { + registers[0] = words_reversed[cursor - WORD_SIZE][0]; + registers[1] = words_reversed[cursor - WORD_SIZE][1]; + registers[2] = words_reversed[cursor - WORD_SIZE][2]; + registers[3] = words_reversed[cursor - WORD_SIZE][3]; + } +} + +void clearDisplay() +// clears all digits +{ + Wire.beginTransmission(saa1064); + + Wire.write(1); // instruction byte - first digit to control is 1 (right hand side) + Wire.write(0); // digit 1 (RHS) + Wire.write(0); // digit 2 + Wire.write(0); // digit 3 + Wire.write(0); // digit 4 (LHS) + Wire.endTransmission(); +} + +#define TCAADDR 0x70 + +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 loop() +{ + selectRightHalf(); + displayDigits(); + delay(1); + + selectLeftHalf(); + displayDigits(); + + movePage(); + delay(20 + (cursor * 2)); + // clearDisplay(); +} +/* **** We bitshift the address as the SAA1064 doesn't have the address 0x70 (ADR pin +to GND) but 0x38 and Arduino uses 7-bit addresses- so 8-bit addresses have to +be shifted to the right one bit. Thanks to Malcolm Cox */ \ No newline at end of file