diff --git a/include/main.h b/include/main.h new file mode 100644 index 0000000..9980393 --- /dev/null +++ b/include/main.h @@ -0,0 +1,51 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include +#include +#include + +// Config switches +#define DEBUG 0 // 1: DEBUG at 115200, 0: No DEBUG +#define DHCP 1 // 1: Use DHCP, 0: Use static IP as defined in main +#define TEST_MODE 1 // 1: Just run some LEDs on Red, 0: normal behaviour + +// Pin definitions +#define WS2812_DATA_PIN 6 +#define NETWORK_STATUS_PIN 4 +#define LED_WRITE_STATUS_PIN 3 + +// LED Configuration +#define NUM_LEDS 33 +#define ARTNET_PORT 6454 +#define START_UNIVERSE 0 // we may not want to begin on universe 0 (remember that artnet is 0-indexed) +#define LEDS_PER_UNIVERSE 170 +#define CHANNELS_PER_UNIVERSE (LEDS_PER_UNIVERSE * 3) + +// Calculated constants +extern const uint8_t NUM_UNIVERSES; +extern const uint8_t ALL_UNI_MASK; + +// Network configuration +extern byte mac[]; +extern IPAddress ip; +extern ArtnetEtherReceiver artnet; + +// LED data +extern CRGB leds[]; +extern uint8_t universesReceived; +extern unsigned long lastShowTime; +extern const unsigned long MIN_SHOW_INTERVAL; + +// Function declarations +void led_status(String led, bool state); +void artnet_callback(const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote); +void led_hello(); +void led_oh_shit(int led_pin); +void init_leds(); +void init_networking(); + +#endif // MAIN_H \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index cf558c0..6897eb7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,4 +12,5 @@ platform = atmelavr board = uno framework = arduino -monitor_speed = 115200 \ No newline at end of file +upload_protocol = usbtiny +upload_flags = -e \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b63bf95..6822c75 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,44 +4,36 @@ // All Rights Reserved 2025 // Licensed under the GNU GPL License. -#define DEBUG 1 // 1: DEBUG at 115200, 0: No DEBUG - -// Required libraries -#include -#include -#include -#include -#include - -// Defined constants -#define LED_PIN 6 -#define NUM_LEDS 33 -#define ARTNET_PORT 6454 -#define START_UNIVERSE 0 // we may not want to begin on universe 0 (remember that artnet is 0-indexed) -#define LEDS_PER_UNIVERSE 170 -#define CHANNELS_PER_UNIVERSE (LEDS_PER_UNIVERSE * 3) - -// Tracking for smart refresh +#include "main.h" + +// Global variable definitions const uint8_t NUM_UNIVERSES = (NUM_LEDS + LEDS_PER_UNIVERSE - 1) / LEDS_PER_UNIVERSE; const uint8_t ALL_UNI_MASK = (1 << NUM_UNIVERSES) - 1; - -// Static IP and MAC address byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; -IPAddress ip(192, 168, 1, 50); // Set your desired static IP here +IPAddress ip(192, 168, 1, 50); ArtnetEtherReceiver artnet; -/// @brief Array to hold the LED data CRGB leds[NUM_LEDS]; uint8_t universesReceived = 0; unsigned long lastShowTime = 0; const unsigned long MIN_SHOW_INTERVAL = 8; // ~125fps max -void artnet_callback( - const uint8_t *data, uint16_t size, - const ArtDmxMetadata &metadata, - const ArtNetRemoteInfo &remote -) { +void led_status(String led, bool state) { + #if DEBUG + Serial.print(led); + Serial.print(" LED is now "); + Serial.println(state ? "ON" : "OFF"); + #endif + + if (led == "network") { + digitalWrite(NETWORK_STATUS_PIN, state ? HIGH : LOW); + } else if (led == "led_write") { + digitalWrite(LED_WRITE_STATUS_PIN, state ? HIGH : LOW); + } +} + +void artnet_callback( const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote ) { uint8_t rel = metadata.universe - START_UNIVERSE; if (rel >= NUM_UNIVERSES) return; @@ -62,27 +54,115 @@ void artnet_callback( Serial.println(universesReceived, HEX); #endif - if (universesReceived == ALL_UNI_MASK && - now - lastShowTime >= MIN_SHOW_INTERVAL) { - + if (universesReceived == ALL_UNI_MASK && now - lastShowTime >= MIN_SHOW_INTERVAL) { + led_status("led_write", true); FastLED.show(); lastShowTime = now; universesReceived = 0; + led_status("led_write", false); } } +void led_hello() { + // do a little dance to say hello + digitalWrite(LED_WRITE_STATUS_PIN, HIGH); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, LOW); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, HIGH); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, LOW); + delay(200); + + digitalWrite(NETWORK_STATUS_PIN, HIGH); + delay(200); + digitalWrite(NETWORK_STATUS_PIN, LOW); + delay(200); + digitalWrite(NETWORK_STATUS_PIN, HIGH); + delay(200); + digitalWrite(NETWORK_STATUS_PIN, LOW); + delay(200); + + digitalWrite(LED_WRITE_STATUS_PIN, HIGH); + digitalWrite(NETWORK_STATUS_PIN, HIGH); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, LOW); + digitalWrite(NETWORK_STATUS_PIN, LOW); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, HIGH); + digitalWrite(NETWORK_STATUS_PIN, HIGH); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, LOW); + digitalWrite(NETWORK_STATUS_PIN, LOW); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, HIGH); + digitalWrite(NETWORK_STATUS_PIN, HIGH); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, LOW); + digitalWrite(NETWORK_STATUS_PIN, LOW); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, HIGH); + digitalWrite(NETWORK_STATUS_PIN, HIGH); + delay(200); + digitalWrite(LED_WRITE_STATUS_PIN, LOW); + digitalWrite(NETWORK_STATUS_PIN, LOW); + delay(200); +} + +void led_oh_shit(int led_pin) { + while(1) { + digitalWrite(led_pin, HIGH); + delay(250); + digitalWrite(led_pin, LOW); + delay(250); + } +} void init_leds() { - FastLED.addLeds(leds, NUM_LEDS); + // initialize FastLED + FastLED.addLeds(leds, NUM_LEDS); FastLED.setMaxRefreshRate(0); // Remove artificial frame rate limit FastLED.setDither(false); FastLED.setCorrection(UncorrectedColor); FastLED.clear(); FastLED.show(); + + // initialize status pins + pinMode(NETWORK_STATUS_PIN, OUTPUT); + pinMode(LED_WRITE_STATUS_PIN, OUTPUT); + + led_hello(); } void init_networking() { - Ethernet.begin(mac, ip); + if (DHCP) { + if (Ethernet.begin(mac)) { + // DHCP configured successfully :) + } else { + // shit shit shit shit shit + led_oh_shit(NETWORK_STATUS_PIN); + } + } else { + Ethernet.begin(mac, ip); + } + + if (Ethernet.linkStatus() == LinkON) { + led_status("network", true); + } else { + led_oh_shit(NETWORK_STATUS_PIN); + } + + #if DEBUG + Serial.print("Ethernet initialized with IP: "); + Serial.println(Ethernet.localIP()); + Serial.print("Subnet Mask: "); + Serial.println(Ethernet.subnetMask()); + Serial.print("Gateway IP: "); + Serial.println(Ethernet.gatewayIP()); + Serial.print("Link Status: "); + Serial.println(Ethernet.linkStatus() == LinkON ? "LinkON" : "LinkOFF"); + #endif + delay(100); artnet.begin(ARTNET_PORT); artnet.subscribeArtDmx(artnet_callback); @@ -106,5 +186,15 @@ void setup() { } void loop() { - artnet.parse(); + if (TEST_MODE) { + for (int i = 0; i < NUM_LEDS; i++) { + leds[i] = CRGB::Red; + } + + FastLED.show(); + while (1); // halt! + + } else { + artnet.parse(); + } }