Stardate 98788.27
Day 5 trapped in my broken spaceship. I managed to cascade two SN74HC595 SIPO modules together to get 16 lights working front to back. The I2C computer is functioning.
I placed two 100μf capacitors on the 5V power bus just outside the 5V connections of slave 1 and 4 to clean up the DC power.
7 connections to Slave 1 for SN74HC165 and SN74HC595. 16 dip switches going to 16 LEDs. So 7 connections controls 32 things.
The two SN74HC595N SIPO Shift Registers are cascaded together.
Master – Slave HC74HC595N
Pin 9 to pin 13: Black
Pin 11 to pin 11: Blue:
Pin 12 to pin 12: White
Grounds and 5V are on the same buses.
I found in the back of the ship some 8 dip switches and SN74HC165 PISO shift registers. In order to save power in the ship, I connected each LED to a dip switch.
Dip switch 1 : front Red LED
Dip switch 2: front Blue LED
Dip switch 8: back Green LED
SN74HC165
A : switch 8
B: switch 7
C: switch 6
D: switch 5
E: switch 4
F: switch 3
G: switch 2
H: switch 1
Both of the SN74HC595 and SN74HC165 are cascaded so it was a 16 bit Byte.
SH74HC165 to Arduino
Pin 1 to Pin 7
Pin 2 to Pin 6
Pin 7 to Pin 5
Pin 15 to Pin 4
Master Arduino to Slave Arduino
Pin 10 to Pin 9
SN74HC165
A : switch 8
B: switch 7
C: switch 6
D: switch 5
E: switch 4
F: switch 3
G: switch 2
H: switch 1
switch
Master
// Include the required Wire library for I2C // Include the libraries: // LiquidCrystal_I2C.h: https://github.com/johnrickman/LiquidCrystal_I2C #include <Wire.h> // Library for I2C communication #include <LiquidCrystal_I2C.h> // Library for LCD // Wiring: SDA pin is connected to A4 and SCL pin to A5. // Connect to LCD via I2C, default address 0x27 (A0-A2 not jumpered) LiquidCrystal_I2C lcd16x2_23 = LiquidCrystal_I2C(0x23, 16, 2); // Change to (0x23,16,2) for 16x2 LCD. LiquidCrystal_I2C lcd20x4_27 = LiquidCrystal_I2C(0x27, 20, 4); // Change to (0x27,20,4) for 20x4 LCD. int x = 0; int LED = 13; void HeartOfStainlessSteel_20x4_27() { lcd20x4_27.init(); lcd20x4_27.backlight(); lcd20x4_27.setCursor(3, 0); // 4th column 1st row lcd20x4_27.print("Welcome aboard"); lcd20x4_27.setCursor(8, 1); // 9th column 2nd row lcd20x4_27.print("the"); lcd20x4_27.setCursor(6, 2); // 7th column 3rd row lcd20x4_27.print("Heart of"); lcd20x4_27.setCursor(2, 3); // 3rd column 4th row lcd20x4_27.print("Stainless Steel"); } void LCD16x2_23() { lcd16x2_23.init(); lcd16x2_23.backlight(); //LCD I2C 160X2_23 lcd16x2_23.setCursor(3, 0); // 4th column 1st row lcd16x2_23.print("I am 0x23"); //LCD I2C 160X2_23 } void I2C_Begin() { // I2C Scanner Code Serial.begin(9600); while (!Serial); // wait for serial monitor Serial.println("\nI2C Scanner"); // I2C Scanner Code } void I2C_Find_Address() { // I2C Scanner Code byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknown error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); // wait 5 seconds for next scan // I2C Scanner Code } void setup() { // comment out to stop the I2C find address //I2C_Begin(); // comment out to stop the I2C find address // These control the LCD displays LCD16x2_23(); HeartOfStainlessSteel_20x4_27(); // I2C counter for LEDs pinMode (LED, OUTPUT); // Start the I2C Bus as Master Wire.begin(); // I2C counter for LEDs } void loop() { // comment out to stop the I2C find address // I2C_Find_Address(); // comment out to stop the I2C find address // I2C counter for LEDs x++; // Increment x //From Left to Right // First UNO Wire.beginTransmission(1); // transmit to device #1 Wire.write(x); // sends x Wire.endTransmission(); // stop transmitting //Second UNO Wire.beginTransmission(2); // transmit to device #2 Wire.write(x); // sends x Wire.endTransmission(); // stop transmitting //Mega in the Middle //Third UNO Wire.beginTransmission(3); // transmit to device #3 Wire.write(x); // sends x Wire.endTransmission(); // stop transmitting //Fourth UNO Wire.beginTransmission(4); // transmit to device #4 Wire.write(x); // sends x Wire.endTransmission(); // stop transmitting if ( (x == 3) || (x == 6)) { digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); } if (x == 7) x = 0; // `reset x once it gets 6 delay(1000); // I2C counter for LEDs }
Slave 1
#include <Wire.h> /* * SN74HC165N_shift_reg * * Program to shift in the bit values from a SN74HC165N 8-bit * parallel-in/serial-out shift register. * * This sketch demonstrates reading in 16 digital states from a * pair of daisy-chained SN74HC165N shift registers while using * only 4 digital pins on the Arduino. * * You can daisy-chain these chips by connecting the serial-out * (Q7 pin) on one shift register to the serial-in (Ds pin) of * the other. * * Of course you can daisy chain as many as you like while still * using only 4 Arduino pins (though you would have to process * them 4 at a time into separate unsigned long variables). * */ uint8_t bytes_right; uint8_t bytes_left; uint8_t hex_left; uint8_t hex_right; /* How many shift register chips are daisy-chained. */ #define NUMBER_OF_SHIFT_CHIPS 2 /* Width of data (how many ext lines). */ #define DATA_WIDTH NUMBER_OF_SHIFT_CHIPS * 8 /* Width of pulse to trigger the shift register to read and latch. */ #define PULSE_WIDTH_USEC 5 /* Optional delay between shift register reads. */ #define POLL_DELAY_MSEC 1 /* You will need to change the "int" to "long" If the * NUMBER_OF_SHIFT_CHIPS is higher than 2. */ #define BYTES_VAL_T unsigned int //SN74HC595 int LED = 13; int num = 0; int Slave1_PR[1][2]; // ST_CP pin 12 int latchPin=10; // white // SH_CP pin 11 int clockIn=11; // blue // DS pin 14 int dataIn=12; // black //I2C int x = 0; int dt=250; //SN74HC165 int ploadPin = 7; // Connects to Parallel load pin the 165 int clockEnablePin = 4; // Connects to Clock Enable pin the 165 int dataPin = 5; // Connects to the Q7 pin the 165 int clockPin = 6; // Connects to the Clock pin the 165 byte dataArrayLeft; byte dataArrayRight; BYTES_VAL_T pinValues; BYTES_VAL_T oldPinValues; /* This function is essentially a "shift-in" routine reading the * serial Data from the shift register chips and representing * the state of those pins in an unsigned integer (or long). */ BYTES_VAL_T read_shift_regs() { long bitVal; BYTES_VAL_T bytesVal = 0; /* Trigger a parallel Load to latch the state of the data lines, */ digitalWrite(clockEnablePin, HIGH); digitalWrite(ploadPin, LOW); delayMicroseconds(PULSE_WIDTH_USEC); digitalWrite(ploadPin, HIGH); digitalWrite(clockEnablePin, LOW); /* Loop to read each bit value from the serial out line * of the SN74HC165N. */ for(int i = 0; i < DATA_WIDTH; i++) { bitVal = digitalRead(dataPin); /* Set the corresponding bit in bytesVal. */ bytesVal |= (bitVal << ((DATA_WIDTH-1) - i)); /* Pulse the Clock (rising edge shifts the next bit). */ digitalWrite(clockPin, HIGH); delayMicroseconds(PULSE_WIDTH_USEC); digitalWrite(clockPin, LOW); } return(bytesVal); } /* Dump the list of zones along with their current status. */ void display_pin_values() { //Serial.print("PinValues:\r\n"); //Serial.print(pinValues, HEX); //Serial.print("\r\n"); //Serial.print("\nInvert PinValues:\r\n"); //Serial.print(~pinValues, HEX); //Serial.print("\r\n"); } void setup() { Serial.begin(9600); pinMode (LED, OUTPUT); // Start the I2C Bus as Slave on address 2 Wire.begin(1); // Attach a function to trigger when something is received. Wire.onReceive(receiveEvent); // Serial.begin(9600); /* Initialize our digital pins... */ // 74HC165 pins pinMode(ploadPin, OUTPUT); pinMode(clockEnablePin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, INPUT); // 74HC595 pins pinMode(latchPin,OUTPUT); pinMode(dataIn,OUTPUT); pinMode(clockIn,OUTPUT); digitalWrite(latchPin, LOW); digitalWrite(clockPin, LOW); digitalWrite(ploadPin, HIGH); /* Read in and display the pin states at startup. */ pinValues = read_shift_regs(); display_pin_values(); oldPinValues = pinValues; //send photoresistor data to master pinMode(A0, INPUT); } void I2C_Counter() { if (x == 1) { digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); } if (x == 6) { digitalWrite(LED, HIGH); delay(500); digitalWrite(LED, LOW); } } //I2C counter that blinks LED 13 for the devices in order 1 to 5. All 5 come on when x == 6 void receiveEvent(int bytes) { x = Wire.read(); // read one character from the I2C } void loop() { I2C_Counter(); // send photoresistor data to master /* Read the state of all zones. */ pinValues = read_shift_regs(); bytes_right = ~pinValues >> 8; bytes_left = ~pinValues & 0x00FF; //Serial.print("Bytes Right\r\n"); //Serial.print(bytes_right, HEX); //Serial.print("\r\n"); //Serial.print("Bytes Left\r\n"); //Serial.print(bytes_left, HEX); //Serial.print("\r\n"); //Serial.print(pinValues, HEX); //Serial.print("\r\n"); uint8_t hex_left = (bytes_left); uint8_t hex_right = (bytes_right); //Serial.print("Hex Right\r\n"); //Serial.print(hex_right); //Serial.print("\r\n"); //Serial.print("Hex Left\r\n"); //Serial.print(hex_left); //Serial.print("\r\n"); if(pinValues != oldPinValues) { // Serial.print("*Pin value change detected*\r\n"); display_pin_values(); oldPinValues = pinValues; delay(POLL_DELAY_MSEC); } //Write to LEDs digitalWrite(latchPin, LOW); shiftOut(dataIn, clockIn, LSBFIRST, hex_right); digitalWrite(latchPin, LOW); shiftOut(dataIn, clockIn, LSBFIRST, hex_left ); //ST_CP HIGH change LEDs digitalWrite(latchPin, HIGH); //Photoresistor A0 int valueA0 = analogRead(A0); Serial.println("Analog value A0 : "); Serial.println(valueA0); delay(3000); }
Slave 2
#include <Wire.h> int LED = 13; int x = 0; void setup() { pinMode (LED, OUTPUT); // Start the I2C Bus as Slave on address 2 Wire.begin(2); // Attach a function to trigger when something is received. Wire.onReceive(receiveEvent); } void receiveEvent(int bytes) { x = Wire.read(); // read one character from the I2C if (x == 2) { digitalWrite(LED, HIGH); } else { digitalWrite(LED, LOW); } if (x == 6) { digitalWrite(LED, HIGH); delay(500); digitalWrite(LED, LOW); } } void loop() { }
Slave 3
#include <Wire.h> // Library for I2C communication #include <LiquidCrystal.h> // Library for LCD LiquidCrystal lcd(5); // int LED = 13; int x = 0; void setup() { // Start the I2C Bus as Slave on address 2 Wire.begin(3); // Attach a function to trigger when something is received. Wire.onReceive(receiveEvent); // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("hello, world!"); } void receiveEvent(int bytes) { x = Wire.read(); // read one character from the I2C } void loop() { // set the cursor to column 0, line 1 // (note: line 1 is the second row, since counting begins with 0): lcd.setCursor(0, 1); // print the number of seconds since reset: lcd.print(millis()/1000); }
Slave 4
#include <Wire.h> int LED = 13; // 8 segment LED for x counter int latchPin_7Segment=11; //white 595 pin 12 int clockPin_8Segment=9; //blue 595 pin 11 int dataPin_8Segment=12; //black 595 pin 14 // 8 segment LED for x counter // i2c counter int x = 0; int dt=250; // i2c counter // 8 segment LED for x counter byte LEDsOff=0b00000000; byte LEDsOn=0b11111111; byte LEDs1=0b10000000; byte LEDs2=0b01000000; byte LEDs3=0b00100000; byte LEDs4=0b00010000; byte LEDs5=0b00001000; byte LEDs6=0b00000100; byte LEDs7=0b00000010; byte LEDs8=0b00000001; byte LEDZero = 0b11111100; byte LEDOne = 0b01100000; byte LEDTwo = 0b11011010; byte LEDThree = 0b11110010; byte LEDFour = 0b01100110; byte LEDFive = 0b10110110; byte LEDSix = 0b00111110; // 8 segment LED for x counter void setup() { pinMode (LED, OUTPUT); pinMode (latchPin_7Segment,OUTPUT); pinMode (dataPin_8Segment,OUTPUT); pinMode (clockPin_8Segment,OUTPUT); // Start the I2C Bus as Slave on address 4 Wire.begin(4); // Attach a function to trigger when something is received. Wire.onReceive(receiveEvent); } void receiveEvent(int bytes) { x = Wire.read(); // read one character from the I2C } // i2c counter void loop() { /* // test all LED display digitalWrite(latchPin_7Segment,LOW); shiftOut(dataPin_8Segment,clockPin_8Segment,LSBFIRST,LEDsOn); digitalWrite(latchPin_7Segment,HIGH); delay(dt); */ // i2c counter if (x == 1) { //LED display digitalWrite(latchPin_7Segment,LOW); shiftOut(dataPin_8Segment,clockPin_8Segment,LSBFIRST,LEDOne); digitalWrite(latchPin_7Segment,HIGH); } if (x == 2) { digitalWrite(latchPin_7Segment,LOW); shiftOut(dataPin_8Segment,clockPin_8Segment,LSBFIRST,LEDTwo); digitalWrite(latchPin_7Segment,HIGH); } if (x == 3) { //LED display digitalWrite(latchPin_7Segment,LOW); shiftOut(dataPin_8Segment,clockPin_8Segment,LSBFIRST,LEDThree); digitalWrite(latchPin_7Segment,HIGH); } if (x == 4) { digitalWrite(latchPin_7Segment,LOW); shiftOut(dataPin_8Segment,clockPin_8Segment,LSBFIRST,LEDFour); digitalWrite(latchPin_7Segment,HIGH); } if (x == 5) { digitalWrite(LED, HIGH); //LED display digitalWrite(latchPin_7Segment,LOW); shiftOut(dataPin_8Segment,clockPin_8Segment,LSBFIRST,LEDFive); digitalWrite(latchPin_7Segment,HIGH); } else { digitalWrite(LED, LOW); } if (x == 6) { digitalWrite(LED, HIGH); // i2c counter // 8 segment LED for x counter digitalWrite(latchPin_7Segment,LOW); shiftOut(dataPin_8Segment,clockPin_8Segment,LSBFIRST,LEDSix); digitalWrite(latchPin_7Segment,HIGH); } }