#define FIRMWARE_VERSION "0.18.08"
/*Language: Wiring/Arduino Serial Console 115200 baud \n ASCII 10 */
#define WATCH_DOG_ENABLED
#define LCD_ENABLED // pin 4,5,6,7,8,9 reserved
#define MACRO_01 // per utilizzi specifici
#define SEMAFORO
/* 001
Si osservi l'utilizzo del C preprocessor,
macro processor, per compilare il minor codice
possibile al fine di poter utilizzare
microcontroller con modeste risorse.
Il generatore codice sorgente firmware
provvederà a includere le opportune
righe di definizione variabili
per il prepocessor
*/
// #include <Wire.h>
#if defined(WATCH_DOG_ENABLED)
#include <avr/wdt.h>
#endif
/* 002
Importante predisposione dei microcontroller:
watch dog al livello hardware
che firmware successivi andranno a
implementare in modo migliore.
Dovranno tener conto anche del tipo di scheda
che esegue il firmware, infatti Uno e Mega
hanno gestione diverse del watch dog
a livello hardware
*/
#if defined(LCD_ENABLED)
#include <LiquidCrystal.h>
#endif
/* 003
La connessione LCD al controller
adottata lo standard DF-Robots
*/
#if defined(TEENSYDUINO)
/* 004
Riconoscimento della scheda
che esegue il Firmware
*/
// --------------- Teensy -----------------
#if defined(__AVR_ATmega32U4__)
#define BOARD "Teensy 2.0"
#elif defined(__AVR_AT90USB1286__)
#define BOARD "Teensy++ 2.0"
#elif defined(__MK20DX128__)
#define BOARD "Teensy 3.0"
#elif defined(__MK20DX256__)
#define BOARD "Teensy 3.2" // and Teensy 3.1 (obsolete)
#elif defined(__MKL26Z64__)
#define BOARD "Teensy LC"
#elif defined(__MK64FX512__)
#define BOARD "Teensy 3.5"
#elif defined(__MK66FX1M0__)
#define BOARD "Teensy 3.6"
#else
#error "Unknown board"
#endif
#else // --------------- Arduino ------------------
#if defined(ARDUINO_AVR_ADK)
#define BOARD "Mega Adk"
#elif defined(ARDUINO_AVR_BT) // Bluetooth
#define BOARD "Bt"
#elif defined(ARDUINO_AVR_DUEMILANOVE)
#define BOARD "Duemilanove"
#elif defined(ARDUINO_AVR_ESPLORA)
#define BOARD "Esplora"
#elif defined(ARDUINO_AVR_ETHERNET)
#define BOARD "Ethernet"
#elif defined(ARDUINO_AVR_FIO)
#define BOARD "Fio"
#elif defined(ARDUINO_AVR_GEMMA)
#define BOARD "Gemma"
#elif defined(ARDUINO_AVR_LEONARDO)
#define BOARD "Leonardo"
#elif defined(ARDUINO_AVR_LILYPAD)
#define BOARD "Lilypad"
#elif defined(ARDUINO_AVR_LILYPAD_USB)
#define BOARD "Lilypad Usb"
#elif defined(ARDUINO_AVR_MEGA)
#define BOARD "Mega"
#elif defined(ARDUINO_AVR_MEGA2560)
#define BOARD "Mega 2560"
#elif defined(ARDUINO_AVR_MICRO)
#define BOARD "Micro"
#elif defined(ARDUINO_AVR_MINI)
#define BOARD "Mini"
#elif defined(ARDUINO_AVR_NANO)
#define BOARD "Nano"
#elif defined(ARDUINO_AVR_NG)
#define BOARD "NG"
#elif defined(ARDUINO_AVR_PRO)
#define BOARD "Pro"
#elif defined(ARDUINO_AVR_ROBOT_CONTROL)
#define BOARD "Robot Ctrl"
#elif defined(ARDUINO_AVR_ROBOT_MOTOR)
#define BOARD "Robot Motor"
#elif defined(ARDUINO_AVR_UNO)
#define BOARD "Uno"
#elif defined(ARDUINO_AVR_YUN)
#define BOARD "Yun"
// These boards must be installed separately:
#elif defined(ARDUINO_SAM_DUE)
#define BOARD "Due"
#elif defined(ARDUINO_SAMD_ZERO)
#define BOARD "Zero"
#elif defined(ARDUINO_ARC32_TOOLS)
#define BOARD "101"
#else
#define BOARD "Unknown board"
#endif
#endif
boolean lcd_print_sec = true;
#if defined(LCD_ENABLED)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// lcd_print_sec = true;
#endif
#if defined(SEMAFORO)
String semaforo_stato = "automatico"; // manuale|automatico|disabilitato
String semaforo_luce = "rossa"; // rossa|gialla|verde
int semaforo_durata_rosso = 3; // in secondi
int semaforo_durata_giallo = 1; // in secondi
int semaforo_durata_verde = 3; // in secondi
int semaforo_pin_rosso = 2;
int semaforo_pin_giallo = 4;
int semaforo_pin_verde = 6;
#endif
boolean request_response = true;
String end_response = "Done ";
/* 006
Il protocollo sviluppato utilizza
lo schema naturale request / response
con stringhe di testo e terminate da capo riga
Il Firmware prevede di poter terminare
la risposta del controller con una riga
che inizia con Done ...
*/
// const int TIMEOUT_CICLE = 200;
int CYCLE_DELAY = 20;
/* 007
CYCLE_DELAY è il ritardo nel ciclo principale
che realizza il poll mediante porta USB
verrà gestito il comando che
permetterà di variare il contenuto
*/
byte portType[54];
/* 008
Matrice fondamentale che contiene la
configurazione dei PIN del microcontroller
che è assegnata dal comando CONFIG
*/
char incomingChar = '\0';
String incomingString = "";
String command = "";
String parameters = "";
String parameter = "";
String tempString = "";
String tempString1= "";
String tempString2= "";
int port = 0;
String portvalue = "";
String portname = "";
int pos = 0;
int pos1 = 0;
int pos2 = 0;
int pos3 = 0;
int tempInt = 0;
char tempChar = '\0';
int inPortMap[7];
int loop_100 = 0;
int loop_10000 = 0;
/* 009
variabili che realizzano due cicli
demoltiplicati rispetto al ciclo principale
ovvero loop_100 diventa vera ogni cento
cicli principali
*/
void setup()
{
#if defined(WATCH_DOG_ENABLED)
wdt_enable(WDTO_8S);
#endif
Serial.begin(115200);
delay(50);
#if defined(LCD_ENABLED)
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("IoT ");
lcd.print(FIRMWARE_VERSION);
#endif
for (int i = 0; i <= 53; i++)
{
portType[i] = 0;
}
/* 010
La matrice portType contiene la configurazione
dei PIN del microcontroller
Le Schede Mega hanno
54 port digital, from 9 to 53
16 port AD, from 0 to 13
I valori in portType significano:
0 not defined
1 IN
2 OUT
3 PWM
4 LCD
5 I2C
6 SPI
7 SERIAL
*/
#if defined(LCD_ENABLED)
// 8, 9, 4, 5, 6, 7
portType[4] = 4;
portType[5] = 4;
portType[6] = 4;
portType[7] = 4;
portType[8] = 4;
portType[9] = 4;
#endif
#if defined(SEMAFORO)
pinMode(semaforo_pin_rosso, OUTPUT);
pinMode(semaforo_pin_giallo, OUTPUT);
pinMode(semaforo_pin_verde, OUTPUT);
#endif
// Wire.begin();
}
void loop()
{
loop_100 = loop_100 + 1;
if (loop_100 = 100)
{
loop_100 = 0;
loop_10000 = loop_10000 +1;
}
if (loop_10000 = 100)
{
loop_10000=0;
}
#if defined(WATCH_DOG_ENABLED)
wdt_reset();
#endif
#if defined(LCD_ENABLED)
if (lcd_print_sec)
{
lcd.setCursor(0,1);
lcd.print(millis()/1000);
}
#endif
#if defined(SEMAFORO)
if(semaforo_stato == “automatico”)
{
while(true) {
digitalWrite(semaforo_pin_rosso, HIGH);
delay(1000 * semaforo_durata_rosso);
digitalWrite(semaforo_pin_rosso, LOW);
digitalWrite(semaforo_pin_giallo, HIGH);
delay(1000 * semaforo_durata_giallo);
digitalWrite(semaforo_pin_giallo, LOW);
digitalWrite(semaforo_pin_verde, HIGH);
delay(1000 * semaforo_durata_verde);
digitalWrite(semaforo_pin_verde, LOW);
}
}
if (Serial.available() > 0)
{
incomingChar = Serial.read();
if (incomingChar == '\n')
{
execCommand();
incomingString = "";
}
else
{
incomingString += incomingChar;
if (incomingString.length() > 254)
{
Serial.print("Error: ");
Serial.println(incomingString);
incomingString = "";
}
}
}
}
void execCommand()
{
incomingString.trim();
command = incomingString;
if (incomingString.indexOf(" ")>0)
{
command = incomingString.substring(0,
incomingString.indexOf(" "));
command.trim();
parameters = incomingString.substring(pos);
parameters.trim();
}
command.toLowerCase();
if ((command == "version") || (command == "ver"))
{
Serial.println(FIRMWARE_VERSION);
}
else
if ((command == "board"))
{
Serial.println(BOARD);
}
else if ((command == "help"))
{
PrintHelp();
}
else if (command == "config")
{
configPort();
}
else if (command == "write" or command == "set")
{
writePort();
}
else if (command == "read" or command == "get")
{
readPort();
}
else if (command == "lcd")
{
#if defined(LCD_ENABLED)
lcdExecCommand();
#endif
}
else
{
Serial.println("command unknown");
}
};
void PrintHelp()
{
Serial.println( "--------------------------------------------------------");
Serial.println("");
Serial.println("Commands (case not sensitive)");
Serial.println("");
Serial.println("ver|version");
Serial.println("board");
Serial.println("config port 0..53 type unused|IN|OUT|PWM|LCD|I2C|SPI|SERIAL");
Serial.println("set|write port <n> value 0|low|1|high");
Serial.println("get|read port <n>");
Serial.println("lcd on|enable|off|disable");
Serial.println("lcd clear");
Serial.println("lcd clear row 1|2");
Serial.println("lcd print row 1|2 <string>");
Serial.println("lcd print seconds on|off");
Serial.println("request_response on|off");
Serial.println("");
Serial.println( "------------------------------------------------");
}
void configPort()
{
// CONFIG PORT n TYPE out
parameters = parameters.substring(parameters.indexOf("port") + 5);
parameters.trim();
pos = parameters.indexOf(" ");
String port_number = parameters.substring(0, pos);
port_number.trim();
String port_type = parameters.substring(parameters.indexOf("type")+4);
port_type.trim();
port_type.toLowerCase();
int int_port_number = -1;
if(port_number.length()>0)
{
int_port_number = port_number[0] - '0';
}
if(port_number.length()>1)
{
int_port_number = int_port_number * 10 + port_number[1] - '0';
}
if (int_port_number>=0 and (BOARD=="Mega" or (BOARD=="Uno" and int_port_number< 14)) )
{
if (port_type=="unused")
{
portType[int_port_number] = 0;
}
else if (port_type=="in" or port_type=="input")
{
portType[int_port_number] = 1;
pinMode(int_port_number, INPUT);
}
else if (port_type=="out" or port_type=="output")
{
portType[int_port_number] = 2;
pinMode(int_port_number, OUTPUT);
}
else if (port_type=="pwm")
{
portType[int_port_number] = 3;
pinMode(int_port_number, OUTPUT);
}
else if (port_type=="i2c")
{
portType[int_port_number] = 5;
}
else if (port_type=="spi")
{
portType[int_port_number] = 6;
}
else if (port_type=="serial")
{
portType[int_port_number] = 7;
}
else
{
incomingString = "not "+incomingString;
}
} else
{
incomingString = " not "+incomingString;
}
/* Mega
54 port digital, from 9 to 53
16 port AD, from 0 to 13
portType value
0 unused
1 IN
2 OUT
3 PWM
4 LCD
5 I2C
6 SPI
7 SERIAL
*/
if (request_response)
{
Serial.println(end_response+ incomingString);
}
}
void lcdExecCommand()
{
#if defined(LCD_ENABLED)
if (parameters.indexOf("clear")>0 or parameters.indexOf("CLEAR")>0 )
{
lcd_print_sec = false;
if (parameters.indexOf("row")>0 or parameters.indexOf("ROW")>0 )
{
if (parameters.indexOf("1")>0 )
{
lcd.setCursor(0,0);
lcd.print(" ");
}
if (parameters.indexOf("2")>0 )
{
lcd.setCursor(0,1);
lcd.print(" ");
}
}
else
{
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" ");
}
if (request_response)
{
Serial.println(end_response+ incomingString);
}
} else if (parameters.indexOf("print")>0 and (parameters.indexOf("seconds")>0 or parameters.indexOf("second")>0 or parameters.indexOf("SECOND")>0 or parameters.indexOf("SECONDS")>0 ))
{
if (parameters.indexOf("off")>0 or parameters.indexOf("OFF")>0 )
lcd_print_sec = false;
else
lcd_print_sec = true;
if (request_response)
{
Serial.println(end_response+ incomingString);
}
} else if (parameters.indexOf("print")>0 and ( parameters.indexOf("row 1")>0) )
{
lcd.setCursor(0,0);
lcd.print(parameters.substring( parameters.indexOf("row") + 6 ) );
if (request_response)
{
Serial.println(end_response+ incomingString);
}
} else if (parameters.indexOf("print")>0 and (parameters.indexOf("row 1")>0) )
{
lcd.setCursor(0,0);
lcd.print(parameters.substring( parameters.indexOf("row") + 7 ) );
if (request_response)
{
Serial.println(end_response+ incomingString);
}
} else if (parameters.indexOf("print")>0 and (parameters.indexOf("row 2")>0) )
{
lcd.setCursor(0,1);
lcd.print(parameters.substring( parameters.indexOf("row") + 6 ) );
if (request_response)
{
Serial.println(end_response+ incomingString);
}
} else if (parameters.indexOf("print")>0 and (parameters.indexOf("row 2")>0) )
{
lcd.setCursor(0,1);
lcd.print(parameters.substring( parameters.indexOf("row") + 7 ) );
if (request_response)
{
Serial.println(end_response+ incomingString);
}
} else
{
Serial.println("lcd on");
}
#endif
}
void writePort()
{
// WRITE PORT n VALUE out
parameters = parameters.substring( parameters.indexOf("port") + 5);
parameters.trim();
pos = parameters.indexOf(" ");
String port_number = parameters.substring(0, pos);
port_number.trim();
String port_value = parameters.substring( parameters.indexOf("value")+5);
port_value.trim();
port_value.toLowerCase();
int int_port_number = -1;
if(port_number.length()>0)
{
int_port_number = port_number[0] - '0';
}
if(port_number.length()>1)
{
int_port_number = int_port_number * 10 + port_number[1] - '0';
}
if (int_port_number>=0 and (BOARD=="Mega" or (BOARD=="Uno" and int_port_number< 14) ) and portType[int_port_number]== 2 )
{
if (port_value=="1" or port_value=="true" or port_value=="high")
{
digitalWrite(int_port_number, HIGH);
}
else if (port_value=="0" or port_value=="false" or port_value=="low")
{
digitalWrite(int_port_number, LOW);
}
else
{
incomingString = " not "+incomingString;
}
} else
{
incomingString = " not "+incomingString;
}
if (request_response)
{
Serial.println(end_response+ incomingString);
}
}
void readPort()
{
// WRITE PORT n VALUE out
parameters = parameters.substring(parameters.indexOf("port") + 5);
parameters.trim();
pos = parameters.indexOf(" ");
String port_number = parameters.substring(0, pos);
port_number.trim();
int int_port_number = -1;
if(port_number.length()>0)
{
int_port_number = port_number[0] - '0';
}
if(port_number.length()>1)
{
int_port_number = int_port_number * 10 + port_number[1] - '0';
}
if (int_port_number>=0 and (BOARD=="Mega" or (BOARD=="Uno" and int_port_number< 14) ) and portType[int_port_number]== 1 )
{
Serial.println(digitalRead( int_port_number));
}
else
{
incomingString = " not "+incomingString;
}
if (request_response)
{
Serial.println(end_response+incomingString);
}
}
void getPort()
{
pos = parameters.indexOf(" ");
while ( pos > 0 )
{
parameter = parameters.substring(0, pos);
parameter.trim();
parameters = parameters.substring(pos);
parameters.trim();
if (parameter.length() == 1 )
{
parameter.setCharAt(1, tempChar);
tempChar = tempChar - 48;
if ((tempChar >= 0) && (tempChar <= 7))
{
port = tempChar + 22 ;
// digitalRead(port);
}
}
else
{
// Errore:
};
};
}