2018/19 Jaguar I-PACE eTROPHY calendar

 

 

Ad Diriyah                  Saudi Arabia           December 15, 2018

Mexico City                Mexico                    February 16, 2019

Hong Kong                  Hong Kong             March 10, 2019

Sanya                          China                       March 23, 2019

Rome                           Italy                          April 13, 2019

Paris                            France                      April 27, 2019

Monaco                      Monaco                   May 11, 2019

Berlin                          Germany                  May 25, 2019

New York City           USA                          July 13, 2019

New York City           USA                          July 14, 2019

2018 SAUDIA Ad Diriyah E-Prix 15 Dec 2018

Driven by the latest innovations in electric vehicle technology, alternative energy solutions and thrilling racing in the heart of the Saudi capital of history – Ad Diriyah. Formula E redefines the very boundaries of what a sport can be through the unique fusion of entertainment, sustainability, technology and innovation. We are fighting climate change by offering electric vehicles as a solution to air pollution in city centers and breaking down the barriers to the electric vehicle market.

 

 

Canonical Extends Ubuntu 18.04 LTS Linux Support to 10 Years

BERLIN — In a keynote at the OpenStack Summit here, Mark Shuttleworth, founder and CEO of Canonical Inc and Ubuntu, detailed the progress made by his Linux distribution in the cloud and announced new extended support.

Mark Shuttleworth

The Ubuntu 18.04 LTS (Long Term Support) debuted back on April 26, providing new server and cloud capabilities. An LTS release comes with five year of support, but during his keynote Shuttleworth announced that 18.04 would have support that is available for up to 10 years.

Revisiting the Unix philosophy in 2018

In 1984, Rob Pike and Brian W. Kernighan published an article called “Program Design in the Unix Environment” in the AT&T Bell Laboratories Technical Journal, in which they argued the Unix philosophy, using the example of BSD’s cat -v implementation. In a nutshell that philosophy is: Build small, focused programs—in whatever language—that do only one thing but do this thing well, communicate via stdin/stdout, and are connected through pipes.

Image result for unix logo att

e-mobility

Revisione 0.05

Sta avvenendo il cambio tecnologico nella mobilità dal motore termico a quello elettrico.

Assistiamo ad una enorme offerta tecnologica e nuove complessità da gestire in modo radicalmente diverso da quanto siamo abituati.

E’ necessario un approccio diverso basato su un osservatorio sulle tecnologie e periodi incontri per costruire sensibilità e gruppi di interesse, esperienza e tendenza.

A cavallo del 2020 assisteremo all’avvio decisivo della e-mobilità.
Si sta già passando dalle e-biciclette, ormai mature con favolosi motori Bosh e batterie Samsung o Panasonic, a motorini e scooter e moto equivalenti ai 125cc.
Nella prossima primavera prenderanno piede le e-motociclette, seguiranno e-quadricicli, poi auto compatte, tipo Aixam o Renault Tweezy, poi city car come Smart.
Ci saranno i veicoli commerciali ed il trasporto pesante con serbatoi ad idrogeno liquido e fuel cell.

La tradizionale produzione elettrica da fotovoltaico, eolico o diesel con colza e biodiesel avranno un nuovo grande impulso.

Comunque sono già in commercio prodotti che sono modelli ed apri pista di interi nuovi segmenti.

Come esempio delle nuove motociclette, fascia 50 cavalli, citiamo la californiana Zeta Motor.
Nel segmento quadricicli deve essere citata la Tweezy della Renault.
Nell’ambito delle city car  la Smart.
Toyota sta presentando il suo piano di smart car come suo principale piano industriale.
Assistiamo a start up di marchi nati da garage con proposte rivoluzionarie, ma fattibili: si consideri, per dire, la tedesca Sono Motor
La Cina ha deciso di passare direttamente alla produzione e-mobilty saltando completamente l’industria automobilista sul motore termico. Si vedano le proposte di guida autonoma livello 2 ed addirittura primi modelli con quattro eliche. Inoltre la Cina si è garantita la fornitura di materie prime africane per produrre batterie.
La Russia ha in Siberia grandi risorse di materie prime per produrre batterie.
BMW sta da qualche anno progettando e costruendo a Monaco quello che aprirà nel 2019 e sarà uno tra i più grandi centri di progettazione pacchi batterie per automobili.
Tesla, USA, ha ormai da anni, e da prima, commercializzato le prime grande automobili, equivalenti alla classe E Mercedes o alla BMW 530, provando che tutto funziona come previsto, anzi ci sono già i primi usati in vendita a 40000 €, contro il prezzo di acquisto di circa due anni fa di oltre 80000€: mezzi dati come perfetti e senza problemi che lavoreranno ancora per molti altri anni, ma poi si realizza che si sta parlando di automobili con 200.000 – 300.000 Km! Impensabile per i vecchi mezzi a motore termico.
Tesla è attualmente il primo produttore del segmento, ma nel 2022 scenderà forse al sesto posto, dopo tutti i grandi marchi da Toyota a BMW.
Hunday ha già commercializzato la prima automobile, rivoluzionaria, con fuel cell. In Norvegia è andata a ruba e si sono già organizzati per il rifornimento per l’idrogeno.

Il 2020 sarà l’anno del giro di boa, ci si deve preparare ed essere pronti ad intercettare nuove occasioni.

Anche i lavori legati al mondo dell’automobile cambieranno radicalmente.

I brand non saranno i marchi, ma singoli prodotti.
Ci saranno i grandi marchi, ma, la semplificazione strutturale, permetterà a molte nuove startup da garage ad entrare e prendere posizione nel mercato. Infatti il nuovo scenario ridimensiona completamente l’assorbimento delle risorse per le parti meccaniche, spostando il tutto a forti sinergie inedite: informatica, scienza della mobilità, chimica, fonti energetiche diverse, …

Il compratore non sarà assorbito interamente, specialmente in termini economici, nell’assistenza, per esempio tagliandi vessatori, ma seguirà nuove offerte persino diventando inedito protagonista nel creare reddito.

Il motore elettrico può essere di una precisione estrema da permettere la robotica. Infatti si parla di livelli di guida autonoma, ovvero robotica, dei nuovi mezzi da 1 a 5. Quindi parte delle risorse che in prima erano riversate nelle officine per far sopravvivere i motori termici finiranno nella robotica, nella produzione di energia, anche locale, e nella gestione dell’informazione.

I livelli di robotica saranno determinanti per il traffico che sarà possibile, finalmente, poter sincronizzare e decongestionare. Nuovi modelli di flusso eviteranno ingorghi con inquinamenti da camere a gas.

Nasceranno inedite banche dati con chi crea servizi, produce e cede energia, chi costruisce parti di ricambio, sulle batterie, sulla gestione del traffico.

Verso la fine degli anni venti verranno commercializzati quelli che già esistono come prototipi: automezzi che si sollevano e si muovono senza toccare il pavimento.

Il grande problema attuale è il rifornimento:

  1. ricarica diretta del pacco batterie mediante colonnine da 7.5kW, 22, 50 e 100kW
  2. indiretto
    1. idrogeno gassoso in serbatoio trasportato dall’automezzo e trasformato nel veicolo da apposito dispositivo, detto fuel cell, in energia elettrica per i motori
    2. idrogeno a stato liquido
      1. in punti di distribuzione e conversione in colonnine per la ricarica
      2. oppure in serbatoi per mezzi pesanti

I paesi ben organizzati riusciranno a costruire una distribuzione, in particolare ultimo miglio, di energia da dotare il territorio nazionale delle moderne e veloci colonnine da 100KW.
In breve i paesi con entrali nucleari saranno indipendenti gli altri diventeranno ancora più dipendenti, soprattutto all’idrogeno prodotto mediante l’energia elettrica prodotta da centrali nucleari.
Le energie alternative porteranno un contributo forse non decisivo.

Le batterie e pacchi batterie, con il loro noleggio, assistenza e ricarica, costruiranno un enorme commercio con nuove possibilità.

I nuovi mezzi elettrici sono estremamente complessi sotto il profilo informatico:

  1. dotati di veri e propri computer invece delle modeste e vecchie centraline elettroniche
  2. connessi localmente ed a internet in molteplici modi
  3. predisposti ad Internet of Things, a gestire banche dati, il monitoraggio e la gestione remota

Comunque evidenziamo che il mezzo con motore termico è primitivo perché

  1. è molto complicato: pistoni, cambio, turbina, alternatore, batteria, motore avviamento, distribuzione, radiatori, impianto raffreddamento, impianto olio, centralina costosissima sebbene modestissima, …
    1. impossibile starci dietro a tutto ed è inevitabile il collasso sistemico
    2. tutte le risorse possibili vanno in manutenzioni costosissime, tagliandi, ma il mezzo continua a degradarsi inesorabilmente
    3. quindi non ci sono risorse per valori aggiunti quali la guida automatica, il monitoraggio e la connettività reale
  2. non ha un vero e proprio computer
  3. non permette la robotica, e quindi non entra nei cinque livelli previsti di guida automatica
  4. la manutenzione, oltre ad essere enorme senza evitare il degrado, vede politiche di prezzi vessatorie, tagliandi da 500€ per cambio olio e controllo livelli, creando un contesto nel quale è impensabile che l’acquirente abbia occasioni di diventare attivo, ovvero di guadagnare

Il mezzo con motore elettrico si semplifica enormemente il/i motore/i elettrico/i, il pacco batteria, carrozzeria e parti meccaniche essenziali ed il computer.

Se le batterie sono a noleggio, l’utilizzatore si dimentica ogni problema legato alle stesse, soprattutto al caso sventurato che si rompa questo componente costosissimo.

Il motore elettrico rimane praticamente inalterato anche dopo 200.000 o 300.000 Km: si vedano le Tesla usate ora in vendita …
Inoltre i motori elettrici possono avere una precisione tale necessaria alla robotica. Realtà impossibile dai rozzi ed inutilmente complessi motori termici.

Il computer di bordo è potente e non è nemmeno lontano parente delle centraline dei precedenti veicoli.

L’officina, come la conosciamo, non ci sarà più.
Il concessionario, come lo conosciamo, cambierà soprattutto in termini di leggerezza e rimarrà solo per i grandi marchi.

Saranno possibili tante startup con modelli nuovi e non legati ai grandi marchi, se non in particolari componenti. Per esempio Bosh sembra entrare nei segmento dei quadricicli offrendo a nuovi produttori il suo propulsore e computer di controllo.

 

IBM To Acquire Red Hat, Completely Changing The Cloud Landscape And Becoming World’s #1 Hybrid Cloud Provider

Most significant tech acquisition of 2018 will unlock true value of cloud for business

– IBM and Red Hat to provide open approach to cloud, featuring unprecedented security and portability across multiple clouds

[IBM Changes Cloud Landscape with Red Hat Acquisition]
IBM Changes Cloud Landscape with Red Hat Acquisition

– Deal accelerates IBM’s high-value business model, making IBM the #1 hybrid cloud provider in an emerging $1 trillion growth marke

 

E-Mobility Startup

Revisione 0.01.

Sta avvenendo il cambio tecnologico nella mobilità dal motore termico a quello elettrico.

Assistiamo ad una enorme offerta tecnologica e nuove complessità da gestire in modo radicalmente diverso da quanto siamo abituati

 

I nuovi mezzi elettrici sono estremamente complessi sotto il profilo informatico

  1. dotati di veri e propri computer
    1. connessi localmente ed a internet in molteplici modi
    2. invece delle vecchie, spartane e costosissime centraline elettroniche
  2. sono costruiti per essere connessi in diversi modi

    1. WiFi
    2. 3G 4G e prossimi
    3. bluetooth
      1. classe dal tipo 1 al tipo 5 con un gran numero di varianti
      2. bluetooth LE
    4. IoT
    5. banche dati
    6. monitoraggio remoto
    7. sistemi sorveglianza, sicurezza, antifurto
    8. controllo remoto
      1. stato ricarica
      2. stato batterie
      3. programmazione viaggi
    9. stradari con gestione automatica punti e tempi rifornimento
      1. tipo colonnine e connettori
        1. solo f.e.m. 220 V AC
        2. 22KW ovvero 400V 64A
        3. 50 KW
        4. 100 KW

Entro la fine del decennio assisteremo all’avvio decisivo della e-mobility. Si passerà dalle e-bike, ormai mature con favolosi motori Bosh e batterie Samsung o Panasonic, agli scooter alle moto che in primavera prossima vedremo in grande offerta, quadricicli, city car, automobili, veicoli commerciali.

I paesi ben organizzati riusciranno a costruire una distribuzione, in particolare ultimo miglio, di energia da dotare il territorio nazionale delle moderne e veloci colonnine da 100KW.

Gli altri paesi, arretrati e dipendenti, dovranno puntare forse sul fuel cell e l’idrogeno, in particolare allo stato liquido. Idrogeno prodotto altrove.

Comunque il mezzo con motore termico è primitivo perché

  1. è molto complicato: pistoni, cambio, turbina, alternatore, batteria, motore avviamento, distribuzione, radiatori, impianto raffreddamento, impianto olio, centralina costosissima sebbene modestissima, …
  2. quindi non si riesce a starci dietro, tutte le risorse vanno in manutenzioni costosissime, tagliandi, ed il mezzo degradanon permettendo di spendere risorse in valori aggiunti quali la guida automatica, il monitoraggio e la connettività reale.

 

Il mezzo con motore elettrico si semplifica enormemente il motore, il pacco batteria, carrozzeria e parti meccaniche essenziali ed il computer.

Se le batterie sono a noleggio, l’utilizzatore si dimentica ogni problema legato alle stesse.

Il motore elettrico rimane praticamente inalterato anche dopo 200.000 o 300.000 Km: si vedano le Tesla usate ora in vendita …

Inoltre i motori elettrici possono avere una precisione tale necessaria alla robotica. E quindi si entra nei cinque livelli previsti di guida automatica. Realtà impossibile dai rozzi ed inutilmente complessi motori termici.

Il computer di bordo è potente e non è nemmeno lontano parente delle centraline dei precedenti veicoli.

Computer che in breve permette di utilizzare o realizzare

      1. app mobile
      2. monitoraggio remoto
      3. banca dati informazioni
      4. robotica
      5. sicurezza
      6. multimedia ed intrattenimento
      7. assistenza

La proposta potrebbe essere di progettare una startup innovativa sulla mobilità elettrica per individuare, commercializzare e gestire proposte specifiche sostituendo la grande marca come brand a specifici modelli di nuovi produttori.

Primo Incontro Il Semaforo Arduino

Il primo incontro sull’Unità Didattica Il Semaforo Arduino si è tenuto con un gruppo ristretto di partecipanti dall’età prescolare, alle medie, alle superiori, a genitori ed appassionati.

Il bilancio è decisamente positivo e al centro dell’affermazione si può porre la piccola in età prescolare, che non sa ancora leggere e capace di seguire i discorsi introduttivi, ma nel momento di vivo laboratorio si è letteralmente scatenata nell’apprendere dalle immagini della guida stampata, a corredo del kit, come realizzare il Semaforo Arduino e vederlo funzionare. Non sapeva leggere numeri e parole quali GND, ma ha collocato i fili nel posto giusto, e nel momento di erogare energia alla scheda è rimasta visibilmente entusiasta: le luci colorate brillavano nella sequenza sperata. E’ stato un momento semplice, ma speciale vederla guardare soddisfatta per un bel po’ di tempo sua realizzazione.

I giovani, ma anche i genitori distratti da ben altri problemi, si sono rivolti all’esperienza con interesse vivo, ed alla fine un’affermazione di un genitore riassume l’intera esperienza: “non sapevo che fosse così interessante, adesso ho capito ed è importante“.

Quindi il gioco con i computer in miniatura per introdurre questioni realmente ostili, come la programmazione delle macchine calcolatrici, funziona ed alla grande.

Prevediamo di organizzare anche altri incontri allargati.

 

AMD Optimistic About 7nm EPYC Future for Servers

AMD first announced its EPYC Process for datacenter servers back in June 2017 and has been steadily evolving the silicon ever since.

“We are seeing the largest demand for our top of the stack 24 and 32-core EPYC processors, which combine industry-leading core counts and I/O to deliver performance advantages across cloud, virtualization and HPC workloads,” Su said.

AMD Product logos

The Ryzen is AMD’s desktop processor and Su noted that she has seen strong demand for the higher end Ryzen 7, Ryzen 5 and Ryzen Threadripper processors.

Vivaldi 2.1 Adds AV1 Video Codec Support, Puts More Power into Quick Commands

Vivaldi Technologies released today Vivaldi 2.1, the first point release to the 2.x series of the Chromium-based, cross-platform web browser.

Vivaldi is known as “the web browser for power users,” so Vivaldi 2.1 continues to bring more productivity additions in an attempt to make you more efficient when using Vivaldi to browse the Web or do whatever work you’re doing at the office.

Vivaldi 2.1 released

Mark Shuttleworth Details Ubuntu 18.10 Cosmic Cuttlefish Linux Release

The Ubuntu 18.10 Linux release became generally available on Oct 18, providing new capabilities for desktop, server and cloud users.

On the desktop side, there is a new theme called “Yaru” that provides a different look and feel than what was provided by default in the prior Ubuntu 18.04 LTS release.

On the server side, Ubuntu 18.10 benefits from an updated Linux 4.18 kernel as well as support for TLS 1.3 encryption. The Ubuntu Server 18.10 integrates the OpenStack Rocky release, providing users with a stable version of the most recent open source OpenStack cloud platform release.

Networking configuration gets a boost in 18.10 as well with netplan.io, which is a network configuration abstraction utility.

 

Linux 4.19

Date Mon, 22 Oct 2018 08:32:24 +0100
From Greg KH <>
Subject Linux 4.19

Hi everyone!

It’s been a long strange journey for this kernel release…

While it was not the largest kernel release every by number of commits,
it was larger than the last 3 releases, which is a non-trivial thing to
do. After the original -rc1 bumps, things settled down on the code side
and it looks like stuff came nicely together to make a solid kernel for
everyone to use for a while. And given that this is going to be one of
the “Long Term” kernels I end up maintaining for a few years, that’s
good news for everyone.

Ubuntu 18.10 (Cosmic Cuttlefish) released

Codenamed "Cosmic Cuttlefish", 18.10 continues Ubuntu's proud tradition of integrating the latest and greatest open source technologies into a high-quality, easy-to-use Linux distribution. The team has been hard at work through this cycle, introducing new features and fixing bugs.

Risultati immagini per ubuntu images

The Ubuntu kernel has been updated to the 4.18 based Linux kernel, our default toolchain has moved to gcc 8.2 with glibc 2.28, and we've
also updated to openssl 1.1.1 and gnutls 3.6.4 with TLS1.3 support.

Ubuntu Desktop 18.04 LTS brings a fresh look with the community-driven Yaru theme replacing our long-serving Ambiance and Radiance themes.  We
are shipping the latest GNOME 3.30, Firefox 63, LibreOffice 6.1.2, and many others.

Ubuntu Server 18.10 includes the Rocky release of OpenStack including the clustering enabled LXD 3.0, new network configuration via netplan.io,
and iteration on the next-generation fast server installer.  Ubuntu Server brings major updates to industry standard packages available on private
clouds, public clouds, containers or bare metal in your datacentre.

The newest Ubuntu Budgie, Kubuntu, Lubuntu, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, and Xubuntu are also being released today.

More details can be found for these at their individual release notes:

    https://wiki.ubuntu.com/CosmicCuttlefish/ReleaseNotes#Official_flavours

intenance updates will be provided for 9 months for all flavours releasing with 18.10.

Nuclear Reactor Startup Transatomic Power going Open Source after Closure

This recently happened with Transatomic Power (founded by Mark Massie and Dr. Leslie Dewan in April 2011), a Nuclear Startup that introduced a brand new design of its own Nuclear Reactor that is a lot more efficient than conventional ones.

Commenti al Firmware Arduino 0.18.08

Revisione 0.03

La nuova versione 0.18.08 del Firmware Arduino permette di realizzare l’Unità Didattica Il Semaforo Arduino.

L’Unità Didattica prevede di realizzare un modello di semaforo con tre LED colorati rosso, giallo e verde, collegati ai pin 2, 4 e 6.

All’avvio, se la sezione SEMAFORO nello sketch è attivata e la variabile semaforo_stato è automatico, allora si avvia il ciclo continuo di accensione e spegnimento con dati ritardi delle luci.

Seguirà l’ implementazione del comando
semaforo automatico|disabilitato|rosso|giallo|verde
da utilizzare nel consueto modo da remoto mediante canale USB .

Il codice sorgente relativo all’Unità Didattica viene attivato con

#define SEMAFORO

In questo caso vengono definite ed inizializzate le seguenti variabili:

#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

 

Quindi nella funzione setup()

#if defined(SEMAFORO)

     pinMode(semaforo_pin_rosso, OUTPUT);
     pinMode(semaforo_pin_giallo, OUTPUT);
     pinMode(semaforo_pin_verde, OUTPUT);

#endif

 

E nella funzione loop()

#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);
   }
}
#endif

Arduino Firmware 0.18.08

#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:
      };
   };
}