#include <SPI.h>
// Define the maximum number of modules
#define MAX_MODULES 4
// Define the structure for a module
struct Module {
int latchPin;
int clockPin;
int dataPin;
int buttonPin;
int ledSwitchPin;
byte continuityData[8];
};
// Array to store the modules
Module modules[MAX_MODULES];
// Function prototypes
void setupModule(Module& module, int latchPin, int clockPin, int dataPin, int buttonPin, int ledSwitchPin);
void readContinuityData(Module& module);
void updateLEDs(Module& module);
void turnOffLEDs(Module& module);
void activatePins(Module& module);
void writeShiftRegister(Module& module, byte redLEDState, byte greenLEDState);
void writeSingleShiftRegister(Module& module, byte outputState);
void setup() {
Serial.begin(9600);
// Initialize the modules
setupModule(modules[0], 8, 12, 11, 7, 6); // Example setup for Module 1
setupModule(modules[1], 9, 13, 10, 5, 4); // Example setup for Module 2
// Add more modules as needed
}
void loop() {
for (int i = 0; i < MAX_MODULES; i++) {
Module& module = modules[i];
// Read continuity data
readContinuityData(module);
// Check the state of the LED control switch
if (digitalRead(module.ledSwitchPin) == LOW) {
// LED switch is ON, update LEDs based on the continuity data
updateLEDs(module);
} else {
// LED switch is OFF, turn off all LEDs
turnOffLEDs(module);
}
// Check if the button is pressed
if (digitalRead(module.buttonPin) == LOW) {
// Button is pressed, activate corresponding pins
activatePins(module);
}
}
delay(1000); // Update every second
}
void setupModule(Module& module, int latchPin, int clockPin, int dataPin, int buttonPin, int ledSwitchPin) {
module.latchPin = latchPin;
module.clockPin = clockPin;
module.dataPin = dataPin;
module.buttonPin = buttonPin;
module.ledSwitchPin = ledSwitchPin;
pinMode(module.latchPin, OUTPUT);
pinMode(module.clockPin, OUTPUT);
pinMode(module.dataPin, OUTPUT);
pinMode(module.buttonPin, INPUT_PULLUP); // Button input with internal pull-up
pinMode(module.ledSwitchPin, INPUT_PULLUP); // LED control switch input with internal pull-up
}
void readContinuityData(Module& module) {
digitalWrite(module.latchPin, LOW);
digitalWrite(module.latchPin, HIGH);
byte incoming = shiftIn(module.dataPin, module.clockPin, MSBFIRST);
// Store the continuity state in the array
for (int i = 0; i < 8; i++) {
module.continuityData[i] = bitRead(incoming, i);
}
}
void updateLEDs(Module& module) {
byte redLEDState = 0;
byte greenLEDState = 0;
for (int i = 0; i < 8; i++) {
if (module.continuityData[i] == 1) {
bitSet(greenLEDState, i);
} else {
bitSet(redLEDState, i);
}
}
// Update the shift registers with the LED states
writeShiftRegister(module, redLEDState, greenLEDState);
}
void turnOffLEDs(Module& module) {
// Turn off all LEDs by writing 0 to the shift registers controlling the LEDs
writeShiftRegister(module, 0, 0);
}
void activatePins(Module& module) {
byte outputState = 0;
for (int i = 0; i < 8; i++) {
if (module.continuityData[i] == 1) {
bitSet(outputState, i);
writeSingleShiftRegister(module, outputState);
delay(200);
bitClear(outputState, i);
}
}
}
void writeShiftRegister(Module& module, byte redLEDState, byte greenLEDState) {
digitalWrite(module.latchPin, LOW);
// Shift out the red LED state
shiftOut(module.dataPin, module.clockPin, MSBFIRST, redLEDState);
// Shift out the green LED state
shiftOut(module.dataPin, module.clockPin, MSBFIRST, greenLEDState);
digitalWrite(module.latchPin, HIGH);
}
void writeSingleShiftRegister(Module& module, byte outputState) {
digitalWrite(module.latchPin, LOW);
// Shift out the output state
shiftOut(module.dataPin, module.clockPin, MSBFIRST, outputState);
digitalWrite(module.latchPin, HIGH);
}
/*
Creating a modular system with multiple connected modules can be achieved by defining a structure for each module and iterating through the connected modules to perform the required operations. Here's a step-by-step approach to achieve this:
1. Define a structure for each module.
2. Implement a way to detect and initialize connected modules.
3. Modify the main loop to handle multiple modules.
Here's an example of how you might structure the code to accomplish this:
Define the Module Structure
Each module will have its own shift registers, button, and switch pins.
1. Module Structure:
o struct Module is defined to encapsulate all the necessary pins and continuity data for each module.
2. Modules Array:
o Module modules[MAX_MODULES]; is defined to store all the modules.
3. Setup Function:
o setupModule() is called for each module to initialize it with the appropriate pins.
4. Loop Function:
o Iterates through each module, reads continuity data, updates LEDs based on the switch state, and activates pins if the button is pressed.
5. Module Functions:
o setupModule() initializes the pins for each module.
o readContinuityData() reads the continuity data from the shift register into the module's array.
o updateLEDs(), turnOffLEDs(), activatePins(), writeShiftRegister(), and writeSingleShiftRegister() are modified to work with a module.
Modular System Considerations:
• Wiring:
o Ensure each module is connected correctly with its own shift registers and control pins.
o Each module should have unique pin assignments for latch, clock, data, button, and switch.
• Expansion:
o To add more modules, simply define additional modules in the modules array and initialize them in the setup() function.
o Adjust MAX_MODULES as needed to match the number of connected modules.
This setup makes the system modular and expandable, allowing you to easily add or remove modules and handle their functionality within the main loop.
*/