#include <EEPROM.h>
#include <DMXSerial.h>
/*
Jeżeli stan na pinie CONFIG_PIN
jest niski to urządzenie wchodzi
w tryb konfiguracji
*/
#define CONFIG_PIN 4
#define RELAY_PIN 5
/*
Notatka: Jak rozbudujemy system nadający o dodatkowe komendy
to można pozbyć się kompletnie sprawdzanie stanów wysokich/niskich
na pinach w celu przerzucenia arduino w różne tryby
Uważam, że jest to do eksperymentowania głównie z arduino
które mają więcej niż jeden UART.
Będzie trzeba sprawdzić oraz wymyślić łatwy i szybki system do aktualizacji softu
być może esp z pamięcią flash aby przechowywać różne wersje firmwaru i możliwość dodawania nowych wersji
*/
#define UNIVERSE_EEPROM 0 // Address EEPROM dla universu
// Numer uniwersu jakiego urządzenie ma nasłuchiwać
int myUniverseAddress = 1;
bool commandReceived = false; // Kontrolka czy komenda jeszcze nie została wykonana
bool configSetup = false; // Kontrolka czy tryb konfiguracji został załączony
void setup() {
/*
Jest to implementacjia arduino odbierający sygnał DMX poprzez Serial1
Jeżeli odczytany pakiet DMX należy do nasłuchiwanego uniwersum
to zostaje on przesłany do biblioteki DMXSerial do wyświetlenia
danej wizualizacji (np. rura z ledami).
Jak numer universu się nie zgadza wtedy pakiet jest przesłany
do kolejnego urządzenia slv.
Ten sketch zakłada, że arduino posiada więcej niż jeden układ UART.
Rozmiar programu w pamięci dynamicznej zajmuje ok. 35% na Atmega 328p (2K RAM)
*/
Serial1.begin(250000);
DMXSerial.maxChannel(512);
DMXSerial.init(DMXController);
pinMode(CONFIG_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
myUniverseAddress = EEPROM.read(UNIVERSE_EEPROM); // Odczytaj wartość z EEPROM
}
void loop() {
if (digitalRead(CONFIG_PIN) == HIGH)
{
digitalWrite(RELAY_PIN,HIGH);
// Jesteśmy w trybie normalnej operacji
// Zakańczamy pracę SoftwareSerial
if (configSetup) {
configSetup = false;
}
// Sprawdzamy czy jest nowy pakiet DMX na lini Serial1
if (Serial1.available()) {
// Odczytujemy pierwszy znak - jest to numer universu
int universeAddress = Serial1.parseInt();
/*
Zakładamy na teraz, że pakiet przesyłany przez mastera rozpoczyna się od numeru universum + 512 wartości tego universu
*/
// Sprawdź czy universe jest zgodny z urządzeniem
if (universeAddress == myUniverseAddress) {
int addr = 0;
while (Serial1.available()) {
int data = Serial1.read();
DMXSerial.write(addr++, data); // Wyślij konkretne wartości DMX do biblioteki DMXSerial
}
} else {
// Prześlij pakiet bez zmian do kolejnego urządzenia slv
Serial1.write(universeAddress);
while (Serial1.available()) {
int data = Serial1.read();
Serial1.write(data);
}
}
}
} else {
// Jesteśmy w trybie konfiguracji
digitalWrite(RELAY_PIN,LOW);
// Inicjalizujemy SoftwareSerial jak nie jest uruchomiony
if (!configSetup) {
commandReceived = false; // Zresetuj odbieranie komend
}
/*
* Ten segment można potem powiększyć o konkretne ustawienia
* np. zdefiniować numer komendy, ilość parametrów i potem zliczać konkretne parametry i je ustawiać
* Po każdej operacji każdy po kolei z arduino by się blokował na czas uzyskania klucza zakończenia operacji
* albo po wyjściu z trybu konfiguracji
* Można też zaimplementować checksum aby upewnić się czy komenda poprawnie została odebrana
* Pomysł: Jeżeli system będzie posiadać diody RGB można zaimplementowac wizualny feedback w postaci ustawienia koloru czerwonego (np. checksuma była niezgodna) lub zielonego (wykonano poprawnie)
*/
/*
Pomysły:
1. Zaimplementować globalny tryb oświetlenia działający poza systemem artnetu jako failsafe - potencjometr regulujący stany zapalenia wszystkich lamp (0%, 25%, 50% 75%, 100%)
*/
// Sprawdź czy jest nowa komenda dostępna
while (Serial1.available()) {
int command = Serial1.read();
if (commandReceived)
{
Serial1.write(command); // Prześlij dalej komendę
}
else
{
if (command < 0 || command > 512) {
command = 0; // Błędna cyfra - Ustaw 0
}
myUniverseAddress = command; // Ustaw nowy adres do nasłuchiwania
EEPROM.update(UNIVERSE_EEPROM, myUniverseAddress); // Zapisz w EEPROM
commandReceived = true; // Komenda została wykonana na tą sesję
for(int i=0; i < 512; i++)
{
DMXSerial.write(i, 255); // Ustaw wszystkie wartości na maksa dla oznaczenia, że coś się stało
}
}
}
}
}