Skip to content

Instantly share code, notes, and snippets.

@ar00n
Last active January 24, 2026 08:26
Show Gist options
  • Select an option

  • Save ar00n/c2c0e064b6826cbebecbcf93d6f3aa02 to your computer and use it in GitHub Desktop.

Select an option

Save ar00n/c2c0e064b6826cbebecbcf93d6f3aa02 to your computer and use it in GitHub Desktop.
Arduino program to control an 8 relay board from a Serial connection
// Configuration
const int RELAY_CNT = 8;
const int relayPins[RELAY_CNT] = {2, 3, 4, 5, 6, 7, 8, 9};
// Protocol
const char CMD_PREFIX[5] = "rlar"; // 2 chars + null terminator
const int TOTAL_CMD_LEN = 12; // "rl" (4) + "00000000" (8)
// State Variables
int recvIndex = 0; // Tracks which character we are waiting for (0 to 9)
char pendingStates[8]; // Temporary buffer to hold "01010101" before applying
char currentPins[RELAY_CNT] = {'0', '0', '0', '0', '0', '0', '0', '0'};
bool prefixFailOnce = 0; // Was the last read a fail?
void setup() {
Serial.begin(9600);
for (int i = 0; i < RELAY_CNT; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], HIGH); // Init OFF
}
Serial.println("ARDUINO SERIAL CONTROLLER LIVE");
}
void loop() {
// 1. Process data only if available
while (Serial.available() > 0) {
char c = Serial.read();
// ------------------------------------------------
// STAGE 1: Check Prefix ("rl")
// ------------------------------------------------
if (recvIndex < 4) {
if (c == CMD_PREFIX[recvIndex]) {
recvIndex++; // Valid prefix char, move to next
} else {
// Character did not match expected prefix.
// Smart Reset: If this char is actually 'r', start a new sequence immediately.
// This handles typos like "rrl..." gracefully.
recvIndex = (c == 'r') ? 1 : 0;
if (prefixFailOnce == 0) {
Serial.println("BAD_PREFIX");
prefixFailOnce = 1;
}
}
}
// ------------------------------------------------
// STAGE 2: Check Data ('0' or '1')
// ------------------------------------------------
else if (recvIndex < 12) {
prefixFailOnce = 0;
if (c == '0' || c == '1') {
// Store in temporary buffer. We do NOT write to relays yet.
// Index 4 corresponds to relay 0, so we subtract 4.
pendingStates[recvIndex - 4] = c;
recvIndex++;
} else {
// Invalid data char (e.g., '2', 'A', etc).
Serial.println("ERR_CHAR");
recvIndex = (c == 'r') ? 1 : 0; // Reset and wait for new 'r'
}
}
// ------------------------------------------------
// STAGE 3: Finalize (Command Complete)
// ------------------------------------------------
if (recvIndex == TOTAL_CMD_LEN) {
// We successfully received "rl" and 8 valid bits.
// Now apply the temporary buffer to the real hardware.
applyRelays();
Serial.println("DONE");
recvIndex = 0; // Reset and wait for next command
}
}
}
void applyRelays() {
for (int i = 0; i < RELAY_CNT; i++) {
// Only write if state is changing
if (currentPins[i] != pendingStates[i]) {
if (pendingStates[i] == '0') {
digitalWrite(relayPins[i], HIGH); // OFF
} else {
digitalWrite(relayPins[i], LOW); // ON
}
currentPins[i] = pendingStates[i];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment