/*
This code controls a single-color LED (led1), an RGB LED (rgb1),
and two 7-segment displays (sevseg1 and sevseg2) using two 74HC595 shift registers (sr1 and sr2).
- led1 toggles on/off every two seconds.
- rgb1 cycles through the colors: Red, Green, Blue, Yellow, Cyan, Magenta, and White,
each shown for two seconds.
- sevseg1 and sevseg2 display a two-digit counter (00 to 99), updated every two seconds.
The seven segment digits are driven using common-anode segment patterns.
*/
#include <Arduino.h>
// ----- Pin Definitions -----
const int ledPin = 5; // Controls led1
// RGB LED PWM (using PWM pins on mega)
const int redPin = 2; // rgb1 R
const int greenPin = 3; // rgb1 G
const int bluePin = 4; // rgb1 B
// Shift register for sevseg1 (for tens digit)
const int sr1_dataPin = 22; // DS
const int sr1_clockPin = 23; // SHCP
const int sr1_latchPin = 24; // STCP
// Shift register for sevseg2 (for units digit)
const int sr2_dataPin = 25; // DS
const int sr2_clockPin = 26; // SHCP
const int sr2_latchPin = 27; // STCP
// ----- Global Variables -----
bool ledState = false; // Toggle state for led1
int rgbIndex = 0; // Index for RGB color cycling
int counter = 0; // Counter value for 7-segment display (00-99)
// RGB color sequence array:
// Each entry is a struct with r, g, b intensity values.
struct Color {
int r;
int g;
int b;
};
const int numColors = 7;
Color colors[numColors] = {
{255, 0, 0}, // Red
{ 0, 255, 0}, // Green
{ 0, 0, 255}, // Blue
{255, 255, 0}, // Yellow
{ 0, 255, 255}, // Cyan
{255, 0, 255}, // Magenta
{255, 255, 255} // White
};
// Lookup table for seven-segment digits (common-anode)
// For digits 0 - 9, each bit in the byte corresponds to a segment (bit0 = A, bit1 = B, ... bit6 = G, bit7 = DP)
// A LOW output on a segment pin turns the segment ON.
// These values are the inversion of common-cathode patterns.
const byte digitPatterns[10] = {
0xC0, // 0 => 0x3F inverted -> 1100 0000
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90 // 9
};
// ----- Function to update a shift register for one digit -----
void updateShiftRegister(int dataPin, int clockPin, int latchPin, byte pattern) {
digitalWrite(latchPin, LOW);
// shiftOut sends the byte (MSB first)
shiftOut(dataPin, clockPin, MSBFIRST, pattern);
digitalWrite(latchPin, HIGH);
}
void setup() {
// Set LED pin as output
pinMode(ledPin, OUTPUT);
// Set RGB LED pins as outputs
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
// Set shift register pins as outputs for both sr1 (sevseg1) and sr2 (sevseg2)
pinMode(sr1_dataPin, OUTPUT);
pinMode(sr1_clockPin, OUTPUT);
pinMode(sr1_latchPin, OUTPUT);
pinMode(sr2_dataPin, OUTPUT);
pinMode(sr2_clockPin, OUTPUT);
pinMode(sr2_latchPin, OUTPUT);
// Optionally, initialize the LEDs to off and displays to "00"
digitalWrite(ledPin, LOW);
analogWrite(redPin, 0);
analogWrite(greenPin, 0);
analogWrite(bluePin, 0);
// Initialize displays to 0 by sending the pattern for '0'
updateShiftRegister(sr1_dataPin, sr1_clockPin, sr1_latchPin, digitPatterns[0]);
updateShiftRegister(sr2_dataPin, sr2_clockPin, sr2_latchPin, digitPatterns[0]);
}
void loop() {
// ----- 1. Toggle the single-color LED (led1) -----
ledState = !ledState; // Toggle state
digitalWrite(ledPin, ledState ? HIGH : LOW);
// ----- 2. Cycle through the RGB colors -----
Color currentColor = colors[rgbIndex];
analogWrite(redPin, currentColor.r);
analogWrite(greenPin, currentColor.g);
analogWrite(bluePin, currentColor.b);
// Update the rgbIndex for next color
rgbIndex = (rgbIndex + 1) % numColors;
// ----- 3. Update the 7-segment displays with the counter -----
// Get tens and ones digit
int tens = counter / 10;
int ones = counter % 10;
// Look-up the segment pattern for each digit.
byte patternTens = digitPatterns[tens];
byte patternOnes = digitPatterns[ones];
// Send patterns to the respective shift registers:
updateShiftRegister(sr1_dataPin, sr1_clockPin, sr1_latchPin, patternTens);
updateShiftRegister(sr2_dataPin, sr2_clockPin, sr2_latchPin, patternOnes);
// Increase the counter (and reset after 99)
counter = (counter + 1) % 100;
// ----- 4. Wait for 2 seconds (2000ms) -----
delay(2000);
}