Skip to content

Instantly share code, notes, and snippets.

@Neumi
Created November 14, 2023 00:14
Show Gist options
  • Save Neumi/691b4d98fa5a53788514f6e34588541b to your computer and use it in GitHub Desktop.
Save Neumi/691b4d98fa5a53788514f6e34588541b to your computer and use it in GitHub Desktop.
Arduino and Python code to synchronize many hardware clients on a local LAN network via UDP broadcasts.
/*
// python code for sync command
// sends sync broadcast to the network to trigger all devices to synchronize
import socket
import time
UDP_IP = "255.255.255.255" # Broadcast IP address
UDP_PORT = 8888 # UDP port
def send_sync_command():
message = "sync"
# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Enable broadcasting on this socket
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
# Send the "sync" command
sock.sendto(message.encode(), (UDP_IP, UDP_PORT))
# Close the socket
sock.close()
# Send the "sync" command every second
send_sync_command()
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF};
EthernetUDP Udp;
unsigned int localPort = 8888;
const int NTP_PACKET_SIZE = 48;
byte byteBuffer[NTP_PACKET_SIZE];
#define LED_PIN PC13
#define END_STOP_PIN PA3
#define ENABLE_PIN PB8
boolean outputState = false;
unsigned long lastSyncTime = 0;
unsigned long blinkOffset = 0;
void setup() {
Ethernet.init(PB9); // Use PB9 as CS pin for W5500
Serial.begin(9600);
while (!Serial);
delay(250);
pinMode(LED_PIN, OUTPUT);
pinMode(END_STOP_PIN, OUTPUT);
pinMode(ENABLE_PIN, OUTPUT);
digitalWrite(ENABLE_PIN, HIGH);
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
Serial.println("Initialize Ethernet with DHCP:");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
while (true) {
delay(1);
}
}
Udp.begin(localPort);
Serial.println("Waiting for sync");
}
void loop() {
checkUDP();
synchronizeLED();
}
void checkUDP() {
int packetSize = Udp.parsePacket();
if (packetSize) {
byteBuffer[packetSize];
Udp.read(byteBuffer, packetSize);
if (strcmp((char*)byteBuffer, "sync") == 0) {
lastSyncTime = millis();
//Serial.println("LEDs synchronized!");
outputState = true;
blinkOffset = 0; // Reset the blink offset on synchronization
}
}
}
void synchronizeLED() {
// Calculate the adjusted blink time based on the offset
unsigned long adjustedBlinkTime = lastSyncTime + blinkOffset;
// Check if it's time to blink
if (millis() >= adjustedBlinkTime) {
// Save the next blink time
lastSyncTime = millis();
// Blink the LED
//outputState = !outputState;
//digitalWrite(LED_PIN, outputState);
//digitalWrite(END_STOP_PIN, outputState);
digitalWrite(LED_PIN, HIGH);
digitalWrite(END_STOP_PIN, HIGH);
delayMicroseconds(50);
digitalWrite(LED_PIN, LOW);
digitalWrite(END_STOP_PIN, LOW);
// Update the blink offset for synchronization
blinkOffset = 10; // Assuming the LED blinks every 1000ms
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment