Created
November 14, 2023 00:14
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
// 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