// Copyright (C) 2018, ETH Zurich, D-ITET
// Martin Reinhard remartin @ee.ethz.ch
//
// This file is part of D-FaLL-System.
//
// D-FaLL-System is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// D-FaLL-System is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with D-FaLL-System. If not, see .
//
//
// ----------------------------------------------------------------------------------
// DDDD FFFFF L L SSSS Y Y SSSS TTTTT EEEEE M M
// D D F aaa L L S Y Y S T E MM MM
// D D --- FFFF a a L L --- SSS Y SSS T EEE M M M
// D D F a aa L L S Y S T E M M
// DDDD F aa a LLLL LLLL SSSS Y SSSS T EEEEE M M
//
//
// DESCRIPTION:
// Arduino program required to control the spotlight.
// Listens to serial port and translates int the DMX protocol.
//
// ----------------------------------------------------------------------------------
#include
const byte channelMode = 25; // The spotlight requires all values.
byte currentDmxMessage[channelMode];
byte channelOffset = 0; // corresponding to the device addressed.
byte posPT = 3; // offset of the pan/tilt DMX values.
unsigned long time = 0;
// open the serial connection.
void setup(){
Serial.begin(9600); // 9600 baud
Serial.println("Arduino_DMX has started.");
Serial.println();
Serial.println("Syntax:");
Serial.print(" c*c : DMX channel index is *. ");
Serial.println("Must be below 128-(14/25) due to Arduino limitations.");
Serial.println(" m199,255,40,10,0,33,m : some DMX command. Comma at the end! ");
Serial.println(" p200,200,30,0,p : setting pan, pan fine, tilt, tilt fine only. ");
Serial.println();
Serial.println();
sendFullDmxMessage(); // required to send it out once.
}
void loop() {
// t2 = milis()
//printCurrentDmxMessage();
//sendDmxMessage();
}
void sendFullDmxMessage(){
//Serial.print("Sent out (ch/Setting):");
for(int gg = channelOffset; gg < channelOffset + channelMode; gg++){
//if(gg>128) Serial.println(std7); covered when setting
DmxSimple.write(gg, currentDmxMessage[gg-channelOffset]);
// Serial.print(gg);
// Serial.print("/");
// Serial.print(currentDmxMessage[gg-channelOffset]);
// Serial.print(", ");
}
// Serial.println();
}
void printCurrentDmxMessage(){
Serial.print("Msg atm: ");
for(int a = channelOffset; a < channelOffset + 14; a++){
Serial.print(currentDmxMessage[a-channelOffset]);
Serial.print(", ");
}
Serial.println();
}
int parserTemp = 0;
int i = 0; // Offset in the currentDmxMessage-Array
bool readingMessage = false;
bool readingChannelOffset = false;
bool readingPT = false;
// Reads messages from the serial port: Either new channel numbers (= channelOffset) or DmxMessages.
void serialEvent(){
//Serial.println("Received some stuff here");
//Serial.print("Received nr. of bytes: ");
//Serial.println(Serial.available());
while(Serial.available()){
char ch = Serial.read();
//Serial.write(ch); // Necessary as ACK?
// Detection structure: dm
// Problem: Arduino sends some info by default -> needs to match precise format.
if(!readingMessage && ch == 'm'){
readingMessage = true;
i = 0;
time = micros();
}else if(!readingChannelOffset && ch == 'c'){
readingChannelOffset = true;
}else if(!readingPT && ch == 'p'){
readingPT = true;
i = 3;
time = micros();
}else if(readingMessage){
if(ch == 'm'){//End reached
parserTemp = 0;
i = 0; // reset array offset
readingMessage = false;
time = micros() - time;
Serial.print("Parsing took uS: ");
Serial.println(time, DEC);
}else if(ch == ','){
if(parserTemp>255 || parserTemp<0){
Serial.println("Warning: DMX-Range"); //(std3);
}else{
currentDmxMessage[i] = parserTemp;
DmxSimple.write(channelOffset+i, parserTemp);
}
parserTemp = 0;
i++;
}else if(isDigit(ch)){
parserTemp = 10*parserTemp + (ch-'0');
}else{// abort that attempt and reset everything.
parserTemp = 0;
i = 0;
readingMessage = false;
//Serial.println("Error while parsing a message.");
}
}else if(readingChannelOffset){
if(ch == 'c'){//End of channel setting
if(parserTemp>103){
Serial.println("Warning: ChNr");//(std4);
}else{
channelOffset = parserTemp;
Serial.print("New offset: ");
Serial.print(channelOffset);
Serial.println();
}
parserTemp = 0;
readingChannelOffset = false;
}else if(isDigit(ch)){
parserTemp = 10*parserTemp + (ch-'0');
}else{
parserTemp = 0;
readingChannelOffset = false;
//Serial.println("Error while parsing a channel number.");
}
}else if(readingPT){
if(ch == 'p'){//End reached
parserTemp = 0;
i = 0; // reset array offset
readingPT = false;
time = micros() - time;
Serial.print("Parsing a PT took uS: ");
Serial.println(time, DEC);
//printCurrentDmxMessage();
}else if(ch == ','){
if(parserTemp>255 || parserTemp<0){
Serial.println("Warning: DMX-Range"); //(std3);
}else{
currentDmxMessage[i] = parserTemp;
DmxSimple.write(channelOffset+i, parserTemp);
}
parserTemp = 0;
i++;
}else if(isDigit(ch)){
parserTemp = 10*parserTemp + (ch-'0');
}else{// abort that attempt and reset everything.
parserTemp = 0;
i = 0;
readingPT = false;
//Serial.println("Error while parsing a PT.");
}
}else{// all other stuff
// Arduino sends some info stuff at startup -> need to disable those error messages.
// Serial.println("Received Gibberish. That one:");
// Serial.write(ch);
}
}
}