Minor Formatting changes + Added Optional M2 DMA Demo

Added revision history
Minor formatting changes
Added M2IO ADC DMA demonstration
Added Optional support to enable M2_12VIO library to work in unision
with M2RET
Added Preprocessor defines to include M212IO

--- M2RET.ino
+++ M2RET.ino
@@ -3,6 +3,11 @@

  Created: March 4, 2017
  Author: Collin Kidder
+
+ Revision History:
+    344    TonyD 25/11/2017.
+        Updated support for Analogue background DMA updates, M2 Digital I/O as well as M2_12VIO library support in SYS_io.cpp
+

 Copyright (c) 2014-2017 Collin Kidder, Michael Neuweiler, Charles Galpin

@@ -27,7 +32,10 @@

  */

-#include "M2RET.h"
+
+//  (!!! else comment out !!!)
+//#define _M2IO   // define to enable the use of the M2_12VIO library & the safe use of the I/O pins as well as PWM in M2RET
+
 #include "config.h"
 #include <due_can.h>
 #include <Arduino_Due_SD_HSMCI.h> // This creates the object SD (HSMCI connected sdcard)
@@ -40,6 +48,13 @@
 #include "EEPROM.h"
 #include "SerialConsole.h"

+#ifdef _M2IO
+    #include "M2RET.h"
+#else
+    #undef _M2IO
+#endif
+
+
 /*
 Notes on project:
 This code should be autonomous after being set up. That is, you should be able to set it up
@@ -65,7 +80,7 @@
 SystemSettings SysSettings;
 DigitalCANToggleSettings digToggleSettings;

-//file system on sdcard (HSCMI connected)
+//file system on sdcard (HSMCI connected)
 FileStore FS;

 SWcan SWCAN(SPI0_CS3, SWC_INT);
@@ -75,10 +90,28 @@

 ELM327Emu elmEmulator;

+#ifdef _M2IO
+    M2_12VIO M2IO;  // M2_12VIO constructor !!!! DONT CHANGE !!!
+
+    // !!! Uncomment to display M2_IO usage with M2RET Demonstration !!!
+    //#define _M2IO_Demo
+
+    #ifdef _M2IO_Demo
+        uint32_t Display_Time = 0;   //Debugging M2_12VIO Analohue & digital demonstration usage in main loop()
+    #else
+        #undef _M2IO_Demo
+    #endif
+#else
+    #undef _M2IO_Demo
+#endif
+
 SerialConsole console;

 bool digTogglePinState;
 uint8_t digTogglePinCounter;
+
+
+

 void CANHandler() {
     SWCAN.intHandler();
@@ -225,7 +258,7 @@
     //delay(5000); //just for testing. Don't use in production

     Serial.begin(115200);
-
+
     Wire.begin();
     SPI.begin();

@@ -254,6 +287,7 @@

     sys_early_setup();
     setup_sys_io();
+

     if (digToggleSettings.enabled) {
         SerialUSB.println("Digital Toggle System Enabled");
@@ -287,7 +321,9 @@
         Can0.begin(settings.CAN0Speed, 255);
         SerialUSB.print("Enabled CAN0 with speed ");
         SerialUSB.println(settings.CAN0Speed);
-    } else Can0.disable();
+    } else{
+        Can0.disable();
+    }

     if (settings.CAN1_Enabled) {
         if (settings.CAN1ListenOnly) {
@@ -299,18 +335,17 @@
         Can1.begin(settings.CAN1Speed, 255);
         SerialUSB.print("Enabled CAN1 with speed ");
         SerialUSB.println(settings.CAN1Speed);
-    } else Can1.disable();
+    } else{
+        Can1.disable();
+    }

     if (settings.SWCAN_Enabled) {
         SWCAN.setupSW(settings.SWCANSpeed);
         delay(20);
         SWCAN.mode(3); // Go to normal mode. 0 - Sleep, 1 - High Speed, 2 - High Voltage Wake-Up, 3 - Normal
-        if (settings.SWCANListenOnly)
-        {
+        if (settings.SWCANListenOnly){
             SWCAN.setListenOnlyMode(true);
-        }
-        else
-        {
+        }else{
             SWCAN.setListenOnlyMode(false);
         }
         attachInterrupt(SWC_INT, CANHandler, FALLING); //enable interrupt for SWCAN
@@ -346,6 +381,13 @@
     //elmEmulator.setup();

     SerialUSB.print("Done with init\n");
+
+#ifdef _M2IO
+    M2IO.Init_12VIO();
+    #ifdef _M2IO_Demo
+        Display_Time = 0;
+    #endif
+#endif
 }

 void setPromiscuousMode()
@@ -467,8 +509,7 @@
                 SerialUSB.print(" ");
                 SerialUSB.print(frame.data.bytes[d], HEX);
             }
-        }
-        else {
+        }else {
             if (frame.extended) {
                 SerialUSB.print("T");
                 sprintf((char *)buff, "%08x", frame.id);
@@ -532,7 +573,7 @@
 void sendFrameToFile(CAN_FRAME &frame, int whichBus)
 {
     uint8_t buff[40];
-    uint8_t temp;
+    //uint8_t temp;
     uint32_t timestamp;
     if (settings.fileOutputType == BINARYFILE) {
         if (frame.extended) frame.id |= 1 << 31;
@@ -633,7 +674,7 @@
 */
 void loop()
 {
-    static int loops = 0;
+    //static int loops = 0;
     CAN_FRAME incoming;
     static CAN_FRAME build_out_frame;
     static int out_bus;
@@ -644,8 +685,8 @@
     static uint32_t build_int;
     uint8_t temp8;
     uint16_t temp16;
-    uint32_t temp32;
-    static bool markToggle = false;
+    //uint32_t temp32;
+    //static bool markToggle = false;
     bool isConnected = false;
     int serialCnt;
     uint32_t now = micros();
@@ -661,8 +702,11 @@
         busLoad[1].bitsPerQuarter = settings.CAN1Speed / 4;
         busLoad[0].bitsSoFar = 0;
         busLoad[1].bitsSoFar = 0;
-        if (busLoad[0].busloadPercentage > busLoad[1].busloadPercentage) updateBusloadLED(busLoad[0].busloadPercentage);
-        else updateBusloadLED(busLoad[1].busloadPercentage);
+        if(busLoad[0].busloadPercentage > busLoad[1].busloadPercentage){
+            updateBusloadLED(busLoad[0].busloadPercentage);
+        } else{
+            updateBusloadLED(busLoad[1].busloadPercentage);
+        }
     }

     /*if (SerialUSB)*/ isConnected = true;
@@ -748,518 +792,623 @@
         serialCnt++;
         in_byte = SerialUSB.read();
         switch (state) {
-        case IDLE:
-            if (in_byte == 0xF1) state = GET_COMMAND;
-            else if (in_byte == 0xE7) {
-                settings.useBinarySerialComm = true;
-                SysSettings.lawicelMode = false;
-                setPromiscuousMode(); //going into binary comm will set promisc. mode too.
-            } else {
-                console.rcvCharacter((uint8_t)in_byte);
-            }
-            break;
-        case GET_COMMAND:
-            switch (in_byte) {
-            case PROTO_BUILD_CAN_FRAME:
-                state = BUILD_CAN_FRAME;
-                buff[0] = 0xF1;
-                step = 0;
-                break;
-            case PROTO_TIME_SYNC:
-                state = TIME_SYNC;
-                step = 0;
-                buff[0] = 0xF1;
-                buff[1] = 1; //time sync
-                buff[2] = (uint8_t)(now & 0xFF);
-                buff[3] = (uint8_t)(now >> 8);
-                buff[4] = (uint8_t)(now >> 16);
-                buff[5] = (uint8_t)(now >> 24);
-                SerialUSB.write(buff, 6);
-                break;
-            case PROTO_DIG_INPUTS:
-                //immediately return the data for digital inputs
-                temp8 = getDigital(0) + (getDigital(1) << 1) + (getDigital(2) << 2) + (getDigital(3) << 3);
-                buff[0] = 0xF1;
-                buff[1] = 2; //digital inputs
-                buff[2] = temp8;
-                temp8 = checksumCalc(buff, 2);
-                buff[3] = temp8;
-                SerialUSB.write(buff, 4);
-                state = IDLE;
-                break;
-            case PROTO_ANA_INPUTS:
-                //immediately return data on analog inputs
-                temp16 = getAnalog(0);
-                buff[0] = 0xF1;
-                buff[1] = 3;
-                buff[2] = temp16 & 0xFF;
-                buff[3] = uint8_t(temp16 >> 8);
-                temp16 = getAnalog(1);
-                buff[4] = temp16 & 0xFF;
-                buff[5] = uint8_t(temp16 >> 8);
-                temp16 = getAnalog(2);
-                buff[6] = temp16 & 0xFF;
-                buff[7] = uint8_t(temp16 >> 8);
-                temp16 = getAnalog(3);
-                buff[8] = temp16 & 0xFF;
-                buff[9] = uint8_t(temp16 >> 8);
-                temp8 = checksumCalc(buff, 9);
-                buff[10] = temp8;
-                SerialUSB.write(buff, 11);
-                state = IDLE;
-                break;
-            case PROTO_SET_DIG_OUT:
-                state = SET_DIG_OUTPUTS;
-                buff[0] = 0xF1;
-                break;
-            case PROTO_SETUP_CANBUS:
-                state = SETUP_CANBUS;
-                step = 0;
-                buff[0] = 0xF1;
-                break;
-            case PROTO_GET_CANBUS_PARAMS:
-                //immediately return data on canbus params
-                buff[0] = 0xF1;
-                buff[1] = 6;
-                buff[2] = settings.CAN0_Enabled + ((unsigned char)settings.CAN0ListenOnly << 4);
-                buff[3] = settings.CAN0Speed;
-                buff[4] = settings.CAN0Speed >> 8;
-                buff[5] = settings.CAN0Speed >> 16;
-                buff[6] = settings.CAN0Speed >> 24;
-                buff[7] = settings.CAN1_Enabled + ((unsigned char)settings.CAN1ListenOnly << 4); //+ (unsigned char)settings.singleWireMode << 6;
-                buff[8] = settings.CAN1Speed;
-                buff[9] = settings.CAN1Speed >> 8;
-                buff[10] = settings.CAN1Speed >> 16;
-                buff[11] = settings.CAN1Speed >> 24;
-                SerialUSB.write(buff, 12);
-                state = IDLE;
-                break;
-            case PROTO_GET_DEV_INFO:
-                //immediately return device information
-                buff[0] = 0xF1;
-                buff[1] = 7;
-                buff[2] = CFG_BUILD_NUM & 0xFF;
-                buff[3] = (CFG_BUILD_NUM >> 8);
-                buff[4] = EEPROM_VER;
-                buff[5] = (unsigned char)settings.fileOutputType;
-                buff[6] = (unsigned char)settings.autoStartLogging;
-                buff[7] = 0; //was single wire mode. Should be rethought for this board.
-                SerialUSB.write(buff, 8);
-                state = IDLE;
-                break;
-            case PROTO_SET_SW_MODE:
-                buff[0] = 0xF1;
-                state = SET_SINGLEWIRE_MODE;
-                step = 0;
-                break;
-            case PROTO_KEEPALIVE:
-                buff[0] = 0xF1;
-                buff[1] = 0x09;
-                buff[2] = 0xDE;
-                buff[3] = 0xAD;
-                SerialUSB.write(buff, 4);
-                state = IDLE;
-                break;
-            case PROTO_SET_SYSTYPE:
-                buff[0] = 0xF1;
-                state = SET_SYSTYPE;
-                step = 0;
-                break;
-            case PROTO_ECHO_CAN_FRAME:
-                state = ECHO_CAN_FRAME;
-                buff[0] = 0xF1;
-                step = 0;
-                break;
-            case PROTO_GET_NUMBUSES:
-                buff[0] = 0xF1;
-                buff[1] = 12;
-                buff[2] = 3; //number of buses actually supported by this hardware (TODO: will be 5 eventually)
-                SerialUSB.write(buff, 3);
-                state = IDLE;
-                break;
-             case PROTO_GET_EXT_BUSES:
-                buff[0] = 0xF1;
-                buff[1] = 13;
-                buff[2] = settings.SWCAN_Enabled + ((unsigned char)settings.SWCANListenOnly << 4);
-                buff[3] = settings.SWCANSpeed;
-                buff[4] = settings.SWCANSpeed >> 8;
-                buff[5] = settings.SWCANSpeed >> 16;
-                buff[6] = settings.SWCANSpeed >> 24;
-                buff[7] = settings.LIN1_Enabled;
-                buff[8] = settings.LIN1Speed;
-                buff[9] = settings.LIN1Speed >> 8;
-                buff[10] = settings.LIN1Speed >> 16;
-                buff[11] = settings.LIN1Speed >> 24;
-                buff[12] = settings.LIN2_Enabled;
-                buff[13] = settings.LIN2Speed;
-                buff[14] = settings.LIN2Speed >> 8;
-                buff[15] = settings.LIN2Speed >> 16;
-                buff[16] = settings.LIN2Speed >> 24;
-                SerialUSB.write(buff, 17);
-                state = IDLE;
-                break;
-             case PROTO_SET_EXT_BUSES:
-                state = SETUP_EXT_BUSES;
-                step = 0;
-                buff[0] = 0xF1;
+            case IDLE:{
+                    if(in_byte == 0xF1){
+                        state = GET_COMMAND;
+                    }else if(in_byte == 0xE7){
+                        settings.useBinarySerialComm = true;
+                        SysSettings.lawicelMode = false;
+                        setPromiscuousMode(); //going into binary comm will set promisc. mode too.
+                    } else{
+                        console.rcvCharacter((uint8_t) in_byte);
+                    }
+                    break;
+                }
+            case GET_COMMAND:{
+                    switch(in_byte){
+                        case PROTO_BUILD_CAN_FRAME:{
+                                state = BUILD_CAN_FRAME;
+                                buff[0] = 0xF1;
+                                step = 0;
+                                break;
+                            }
+                        case PROTO_TIME_SYNC:{
+                                state = TIME_SYNC;
+                                step = 0;
+                                buff[0] = 0xF1;
+                                buff[1] = 1; //time sync
+                                buff[2] = (uint8_t) (now & 0xFF);
+                                buff[3] = (uint8_t) (now >> 8);
+                                buff[4] = (uint8_t) (now >> 16);
+                                buff[5] = (uint8_t) (now >> 24);
+                                SerialUSB.write(buff, 6);
+                                break;
+                            }
+                        case PROTO_DIG_INPUTS:{
+                                //immediately return the data for digital inputs
+                                temp8 = getDigital(0) + (getDigital(1) << 1) + (getDigital(2) << 2) + (getDigital(3) << 3) + (getDigital(4) << 4) + (getDigital(5) << 5);
+                                buff[0] = 0xF1;
+                                buff[1] = 6; //digital inputs
+                                buff[2] = temp8;
+                                temp8 = checksumCalc(buff, 2);
+                                buff[3] = temp8;
+                                SerialUSB.write(buff, 4);
+                                state = IDLE;
+                                break;
+                            }
+                        case PROTO_ANA_INPUTS:{
+                                //immediately return data on analog inputs
+                                temp16 = getAnalog(0);  // Analogue input 1
+                                buff[0] = 0xF1;
+                                buff[1] = 3;
+                                buff[2] = temp16 & 0xFF;
+                                buff[3] = uint8_t(temp16 >> 8);
+                                temp16 = getAnalog(1);  // Analogue input 2
+                                buff[4] = temp16 & 0xFF;
+                                buff[5] = uint8_t(temp16 >> 8);
+                                temp16 = getAnalog(2);  // Analogue input 3
+                                buff[6] = temp16 & 0xFF;
+                                buff[7] = uint8_t(temp16 >> 8);
+                                temp16 = getAnalog(3);  // Analogue input 4
+                                buff[8] = temp16 & 0xFF;
+                                buff[9] = uint8_t(temp16 >> 8);
+                                temp16 = getAnalog(4);  // Analogue input 5
+                                buff[10] = temp16 & 0xFF;
+                                buff[11] = uint8_t(temp16 >> 8);
+                                temp16 = getAnalog(5);  // Analogue input 6
+                                buff[12] = temp16 & 0xFF;
+                                buff[13] = uint8_t(temp16 >> 8);
+                                temp16 = getAnalog(6);  // Vehicle Volts
+                                buff[14] = temp16 & 0xFF;
+                                buff[15] = uint8_t(temp16 >> 8);
+                                temp8 = checksumCalc(buff, 9);
+                                buff[16] = temp8;
+                                SerialUSB.write(buff, 17);
+                                state = IDLE;
+                                break;
+                            }
+                        case PROTO_SET_DIG_OUT:{
+                                state = SET_DIG_OUTPUTS;
+                                buff[0] = 0xF1;
+                                break;
+                            }
+                        case PROTO_SETUP_CANBUS:{
+                                state = SETUP_CANBUS;
+                                step = 0;
+                                buff[0] = 0xF1;
+                                break;
+                            }
+                        case PROTO_GET_CANBUS_PARAMS:{
+                                //immediately return data on canbus params
+                                buff[0] = 0xF1;
+                                buff[1] = 6;
+                                buff[2] = settings.CAN0_Enabled + ((unsigned char) settings.CAN0ListenOnly << 4);
+                                buff[3] = settings.CAN0Speed;
+                                buff[4] = settings.CAN0Speed >> 8;
+                                buff[5] = settings.CAN0Speed >> 16;
+                                buff[6] = settings.CAN0Speed >> 24;
+                                buff[7] = settings.CAN1_Enabled + ((unsigned char) settings.CAN1ListenOnly << 4); //+ (unsigned char)settings.singleWireMode << 6;
+                                buff[8] = settings.CAN1Speed;
+                                buff[9] = settings.CAN1Speed >> 8;
+                                buff[10] = settings.CAN1Speed >> 16;
+                                buff[11] = settings.CAN1Speed >> 24;
+                                SerialUSB.write(buff, 12);
+                                state = IDLE;
+                                break;
+                            }
+                        case PROTO_GET_DEV_INFO:{
+                                //immediately return device information
+                                buff[0] = 0xF1;
+                                buff[1] = 7;
+                                buff[2] = CFG_BUILD_NUM & 0xFF;
+                                buff[3] = (CFG_BUILD_NUM >> 8);
+                                buff[4] = EEPROM_VER;
+                                buff[5] = (unsigned char) settings.fileOutputType;
+                                buff[6] = (unsigned char) settings.autoStartLogging;
+                                buff[7] = 0; //was single wire mode. Should be rethought for this board.
+                                SerialUSB.write(buff, 8);
+                                state = IDLE;
+                                break;
+                            }
+                        case PROTO_SET_SW_MODE:{
+                                buff[0] = 0xF1;
+                                state = SET_SINGLEWIRE_MODE;
+                                step = 0;
+                                break;
+                            }
+                        case PROTO_KEEPALIVE:{
+                                buff[0] = 0xF1;
+                                buff[1] = 0x09;
+                                buff[2] = 0xDE;
+                                buff[3] = 0xAD;
+                                SerialUSB.write(buff, 4);
+                                state = IDLE;
+                                break;
+                            }
+                        case PROTO_SET_SYSTYPE:{
+                                buff[0] = 0xF1;
+                                state = SET_SYSTYPE;
+                                step = 0;
+                                break;
+                            }
+                        case PROTO_ECHO_CAN_FRAME:{
+                                state = ECHO_CAN_FRAME;
+                                buff[0] = 0xF1;
+                                step = 0;
+                                break;
+                            }
+                        case PROTO_GET_NUMBUSES:{
+                                buff[0] = 0xF1;
+                                buff[1] = 12;
+                                buff[2] = 3; //number of buses actually supported by this hardware (TODO: will be 5 eventually)
+                                SerialUSB.write(buff, 3);
+                                state = IDLE;
+                                break;
+                            }
+                        case PROTO_GET_EXT_BUSES:{
+                                buff[0] = 0xF1;
+                                buff[1] = 13;
+                                buff[2] = settings.SWCAN_Enabled + ((unsigned char) settings.SWCANListenOnly << 4);
+                                buff[3] = settings.SWCANSpeed;
+                                buff[4] = settings.SWCANSpeed >> 8;
+                                buff[5] = settings.SWCANSpeed >> 16;
+                                buff[6] = settings.SWCANSpeed >> 24;
+                                buff[7] = settings.LIN1_Enabled;
+                                buff[8] = settings.LIN1Speed;
+                                buff[9] = settings.LIN1Speed >> 8;
+                                buff[10] = settings.LIN1Speed >> 16;
+                                buff[11] = settings.LIN1Speed >> 24;
+                                buff[12] = settings.LIN2_Enabled;
+                                buff[13] = settings.LIN2Speed;
+                                buff[14] = settings.LIN2Speed >> 8;
+                                buff[15] = settings.LIN2Speed >> 16;
+                                buff[16] = settings.LIN2Speed >> 24;
+                                SerialUSB.write(buff, 17);
+                                state = IDLE;
+                                break;
+                            }
+                        case PROTO_SET_EXT_BUSES:{
+                                state = SETUP_EXT_BUSES;
+                                step = 0;
+                                buff[0] = 0xF1;
+                                break;
+                            }
+                    }
+                    break;
+                }
+            case BUILD_CAN_FRAME:{
+                    buff[1 + step] = in_byte;
+                    switch(step){
+                        case 0:{
+                                build_out_frame.id = in_byte;
+                                break;
+                            }
+                        case 1:{
+                                build_out_frame.id |= in_byte << 8;
+                                break;
+                            }
+                        case 2:{
+                                build_out_frame.id |= in_byte << 16;
+                                break;
+                            }
+                        case 3:{
+                                build_out_frame.id |= in_byte << 24;
+                                if(build_out_frame.id & 1 << 31){
+                                    build_out_frame.id &= 0x7FFFFFFF;
+                                    build_out_frame.extended = true;
+                                } else build_out_frame.extended = false;
+                                break;
+                            }
+                        case 4:{
+                                out_bus = in_byte & 3;
+                                break;
+                            }
+                        case 5:{
+                                build_out_frame.length = in_byte & 0xF;
+                                if(build_out_frame.length > 8) build_out_frame.length = 8;
+                                break;
+                            }
+                        default:{
+                                if(step < build_out_frame.length + 6){
+                                    build_out_frame.data.bytes[step - 6] = in_byte;
+                                } else{
+                                    state = IDLE;
+                                    //this would be the checksum byte. Compute and compare.
+                                    temp8 = checksumCalc(buff, step);
+                                    //if (temp8 == in_byte){
+                                        /*
+                                        if (settings.singleWireMode == 1){
+                                            if (build_out_frame.id == 0x100){
+                                                if (out_bus == 1){
+                                                    setSWCANWakeup();
+                                                    delay(5);
+                                                    }
+                                            }
+                                        }
+                                    */
+                                    build_out_frame.rtr = 0;
+                                    if(out_bus == 0) sendFrame(&Can0, build_out_frame);
+                                    if(out_bus == 1) sendFrame(&Can1, build_out_frame);
+                                    if(out_bus == 2) sendFrame(&SWCAN, build_out_frame);
+                                    /*
+                                    if (settings.singleWireMode == 1){
+                                        if (build_out_frame.id == 0x100){
+                                            if (out_bus == 1){
+                                                delay(5);
+                                                setSWCANEnabled();
+                                                }
+                                            }
+                                        } */
+                                    //}
+                                }
+                                break;
+                            }
+                    }
+                    step++;
+                    break;
+                }
+            case TIME_SYNC:{
+                    state = IDLE;
+                    break;
+                }
+            case GET_DIG_INPUTS:{
+                    // nothing to do
+                    break;
+                }
+            case GET_ANALOG_INPUTS:{
+                    // nothing to do
+                    break;
+                }
+            case SET_DIG_OUTPUTS:{ //todo: validate the XOR byte
+                    buff[1] = in_byte;
+                    //temp8 = checksumCalc(buff, 2);
+                    for(int c = 0; c < 8; c++){
+                        if(in_byte & (1 << c)) setOutput(c, true);
+                        else setOutput(c, false);
+                    }
+                    state = IDLE;
+                    break;
+                }
+            case SETUP_CANBUS:{ //todo: validate checksum
+                switch(step){
+                    case 0:{
+                            build_int = in_byte;
+                            break;
+                        }
+                    case 1:{
+                            build_int |= in_byte << 8;
+                            break;
+                        }
+                    case 2:{
+                            build_int |= in_byte << 16;
+                            break;
+                        }
+                    case 3:{
+                            build_int |= in_byte << 24;
+                            if(build_int > 0){
+                                if(build_int & 0x80000000){ //signals that enabled and listen only status are also being passed
+                                    if(build_int & 0x40000000){
+                                        settings.CAN0_Enabled = true;
+                                        Can0.enable();
+                                    } else{
+                                        settings.CAN0_Enabled = false;
+                                        Can0.disable();
+                                    }
+                                    if(build_int & 0x20000000){
+                                        settings.CAN0ListenOnly = true;
+                                        Can0.enable_autobaud_listen_mode();
+                                    } else{
+                                        settings.CAN0ListenOnly = false;
+                                        Can0.disable_autobaud_listen_mode();
+                                    }
+                                } else{
+                                    Can0.enable(); //if not using extended status mode then just default to enabling - this was old behavior
+                                    settings.CAN0_Enabled = true;
+                                }
+                                build_int = build_int & 0xFFFFF;
+                                if(build_int > 1000000) build_int = 1000000;
+                                Can0.begin(build_int, 255);
+                                //Can0.set_baudrate(build_int);
+                                settings.CAN0Speed = build_int;
+                            } else{ //disable first canbus
+                                Can0.disable();
+                                settings.CAN0_Enabled = false;
+                            }
+                            break;
+                        }
+                    case 4:{
+                            build_int = in_byte;
+                            break;
+                        }
+                    case 5:{
+                            build_int |= in_byte << 8;
+                            break;
+                        }
+                    case 6:{
+                            build_int |= in_byte << 16;
+                            break;
+                        }
+                    case 7:{
+                            build_int |= in_byte << 24;
+                            if(build_int > 0){
+                                if(build_int & 0x80000000){ //signals that enabled and listen only status are also being passed
+                                    if(build_int & 0x40000000){
+                                        settings.CAN1_Enabled = true;
+                                        Can1.enable();
+                                    } else{
+                                        settings.CAN1_Enabled = false;
+                                        Can1.disable();
+                                    }
+                                    if(build_int & 0x20000000){
+                                        settings.CAN1ListenOnly = true;
+                                        Can1.enable_autobaud_listen_mode();
+                                    } else{
+                                        settings.CAN1ListenOnly = false;
+                                        Can1.disable_autobaud_listen_mode();
+                                    }
+                                } else{
+                                    Can1.enable(); //if not using extended status mode then just default to enabling - this was old behavior
+                                    settings.CAN1_Enabled = true;
+                                }
+                                build_int = build_int & 0xFFFFF;
+                                if(build_int > 1000000) build_int = 1000000;
+                                Can1.begin(build_int, 255);
+                                //Can1.set_baudrate(build_int);
+
+                                settings.CAN1Speed = build_int;
+                            } else{ //disable second canbus
+                                Can1.disable();
+                                settings.CAN1_Enabled = false;
+                            }
+                            state = IDLE;
+                            //now, write out the new canbus settings to EEPROM
+                            EEPROM.write(EEPROM_ADDR, settings);
+                            setPromiscuousMode();
+                            break;
+                        }
+                }
+                step++;
                 break;
             }
-            break;
-        case BUILD_CAN_FRAME:
-            buff[1 + step] = in_byte;
-            switch (step) {
-            case 0:
-                build_out_frame.id = in_byte;
-                break;
-            case 1:
-                build_out_frame.id |= in_byte << 8;
-                break;
-            case 2:
-                build_out_frame.id |= in_byte << 16;
-                break;
-            case 3:
-                build_out_frame.id |= in_byte << 24;
-                if (build_out_frame.id & 1 << 31) {
-                    build_out_frame.id &= 0x7FFFFFFF;
-                    build_out_frame.extended = true;
-                } else build_out_frame.extended = false;
-                break;
-            case 4:
-                out_bus = in_byte & 3;
-                break;
-            case 5:
-                build_out_frame.length = in_byte & 0xF;
-                if (build_out_frame.length > 8) build_out_frame.length = 8;
-                break;
-            default:
-                if (step < build_out_frame.length + 6) {
-                    build_out_frame.data.bytes[step - 6] = in_byte;
-                } else {
+            case GET_CANBUS_PARAMS:{
+                    // nothing to do
+                    break;
+                }
+            case GET_DEVICE_INFO:{
+                    // nothing to do
+                    break;
+                }
+            case SET_SINGLEWIRE_MODE:{
+                    if(in_byte == 0x10){
+                    } else{
+                    }
+                    EEPROM.write(EEPROM_ADDR, settings);
                     state = IDLE;
-                    //this would be the checksum byte. Compute and compare.
-                    temp8 = checksumCalc(buff, step);
-                    //if (temp8 == in_byte)
-                    //{
-                    /*
-                    if (settings.singleWireMode == 1)
-                    {
-                       if (build_out_frame.id == 0x100)
-                       {
-                    	   if (out_bus == 1)
-                    	   {
-                    		   setSWCANWakeup();
-                    		   delay(5);
-                    	   }
-                       }
+                    break;
+                }
+            case SET_SYSTYPE:{
+                    settings.sysType = in_byte;
+                    EEPROM.write(EEPROM_ADDR, settings);
+                    loadSettings();
+                    state = IDLE;
+                    break;
+                }
+            case ECHO_CAN_FRAME:{
+                    buff[1 + step] = in_byte;
+                    switch(step){
+                        case 0:{
+                                build_out_frame.id = in_byte;
+                                break;
+                            }
+                        case 1:{
+                                build_out_frame.id |= in_byte << 8;
+                                break;
+                            }
+                        case 2:{
+                                build_out_frame.id |= in_byte << 16;
+                                break;
+                            }
+                        case 3:{
+                                build_out_frame.id |= in_byte << 24;
+                                if(build_out_frame.id & 1 << 31){
+                                    build_out_frame.id &= 0x7FFFFFFF;
+                                    build_out_frame.extended = true;
+                                } else build_out_frame.extended = false;
+                                break;
+                            }
+                        case 4:{
+                                out_bus = in_byte & 1;
+                                break;
+                            }
+                        case 5:{
+                                build_out_frame.length = in_byte & 0xF;
+                                if(build_out_frame.length > 8) build_out_frame.length = 8;
+                                break;
+                            }
+                        default:{
+                                if(step < build_out_frame.length + 6){
+                                    build_out_frame.data.bytes[step - 6] = in_byte;
+                                } else{
+                                    state = IDLE;
+                                    //this would be the checksum byte. Compute and compare.
+                                    temp8 = checksumCalc(buff, step);
+                                    //if (temp8 == in_byte)
+                                    //{
+                                    toggleRXLED();
+                                    if(isConnected) sendFrameToUSB(build_out_frame, 0);
+                                    //}
+                                }
+                                break;
+                            }
                     }
-                    */
-                    build_out_frame.rtr = 0;
-                    if (out_bus == 0) sendFrame(&Can0, build_out_frame);
-                    if (out_bus == 1) sendFrame(&Can1, build_out_frame);
-                    if (out_bus == 2) sendFrame(&SWCAN, build_out_frame);
-                    /*
-                    if (settings.singleWireMode == 1)
-                    		   {
-                    			   if (build_out_frame.id == 0x100)
-                    			   {
-                    				   if (out_bus == 1)
-                    				   {
-                    					   delay(5);
-                    					   setSWCANEnabled();
-                    				   }
-                    			   }
-                    		   } */
-                    //}
+                    step++;
+                    break;
                 }
-                break;
+            case SETUP_EXT_BUSES:{ //setup enable/listenonly/speed for SWCAN, Enable/Speed for LIN1, LIN2
+                    switch(step){
+                        case 0:{
+                                build_int = in_byte;
+                                break;
+                            }
+                        case 1:{
+                                build_int |= in_byte << 8;
+                                break;
+                            }
+                        case 2:{
+                                build_int |= in_byte << 16;
+                                break;
+                            }
+                        case 3:{
+                                build_int |= in_byte << 24;
+                                if(build_int > 0){
+                                    if(build_int & 0x80000000){ //signals that enabled and listen only status are also being passed
+                                        if(build_int & 0x40000000){
+                                            settings.SWCAN_Enabled = true;
+                                            SWCAN.mode(3);
+                                        } else{
+                                            settings.SWCAN_Enabled = false;
+                                            SWCAN.mode(0);
+                                        }
+                                        if(build_int & 0x20000000){
+                                            settings.SWCANListenOnly = true;
+                                            //SWCAN.enable_autobaud_listen_mode();
+                                        } else{
+                                            settings.SWCANListenOnly = false;
+                                            //SWCAN.disable_autobaud_listen_mode();
+                                        }
+                                    } else{
+                                        SWCAN.mode(3);
+                                        settings.SWCAN_Enabled = true;
+                                    }
+                                    build_int = build_int & 0xFFFFF;
+                                    if(build_int > 100000) build_int = 100000;
+                                    SWCAN.setupSW(build_int);
+                                    delay(20);
+                                    SWCAN.mode(3); // Go to normal mode. 0 - Sleep, 1 - High Speed, 2 - High Voltage Wake-Up, 3 - Normal
+                                    attachInterrupt(SWC_INT, CANHandler, FALLING); //enable interrupt for SWCAN
+                                    settings.SWCANSpeed = build_int;
+                                } else{ //disable first canbus
+                                    SWCAN.mode(0);
+                                    settings.SWCAN_Enabled = false;
+                                }
+                                break;
+                            }
+                        case 4:{
+                                build_int = in_byte;
+                                break;
+                            }
+                        case 5:{
+                                build_int |= in_byte << 8;
+                                break;
+                            }
+                        case 6:{
+                                build_int |= in_byte << 16;
+                                break;
+                            }
+                        case 7:{
+                                build_int |= in_byte << 24;
+                                /* FIX THIS UP TO INITIALIZE LIN1
+                                if (build_int > 0) {
+                                    if (build_int & 0x80000000) { //signals that enabled and listen only status are also being passed
+                                        if (build_int & 0x40000000) {
+                                            settings.CAN1_Enabled = true;
+                                            Can1.enable();
+                                        } else {
+                                            settings.CAN1_Enabled = false;
+                                            Can1.disable();
+                                        }
+                                    } else {
+                                        Can1.enable(); //if not using extended status mode then just default to enabling - this was old behavior
+                                        settings.CAN1_Enabled = true;
+                                    }
+                                    build_int = build_int & 0xFFFFF;
+                                    if (build_int > 1000000) build_int = 1000000;
+                                    Can1.begin(build_int, 255);
+                                    //Can1.set_baudrate(build_int);
+                                    settings.CAN1Speed = build_int;
+                                } else { //disable second canbus
+                                    Can1.disable();
+                                    settings.CAN1_Enabled = false;
+                                }*/
+                                break;
+                            }
+                        case 8:{
+                                build_int = in_byte;
+                                break;
+                            }
+                        case 9:{
+                                build_int |= in_byte << 8;
+                                break;
+                            }
+                        case 10:{
+                                build_int |= in_byte << 16;
+                                break;
+                            }
+                        case 11:{
+                                build_int |= in_byte << 24;
+                                /* FIX THIS UP TO INITIALIZE LIN2
+                                if (build_int > 0) {
+                                    if (build_int & 0x80000000) { //signals that enabled and listen only status are also being passed
+                                        if (build_int & 0x40000000) {
+                                            settings.CAN1_Enabled = true;
+                                            Can1.enable();
+                                        } else {
+                                            settings.CAN1_Enabled = false;
+                                            Can1.disable();
+                                        }
+                                    } else {
+                                        Can1.enable(); //if not using extended status mode then just default to enabling - this was old behavior
+                                        settings.CAN1_Enabled = true;
+                                    }
+                                    build_int = build_int & 0xFFFFF;
+                                    if (build_int > 1000000) build_int = 1000000;
+                                    Can1.begin(build_int, 255);
+                                    //Can1.set_baudrate(build_int);
+                                    settings.CAN1Speed = build_int;
+                                } else { //disable second canbus
+                                    Can1.disable();
+                                    settings.CAN1_Enabled = false;
+                                } */
+                                state = IDLE;
+                                //now, write out the new canbus settings to EEPROM
+                                EEPROM.write(EEPROM_ADDR, settings);
+                                //setPromiscuousMode();
+                                break;
+                            }
+                    }
+                    step++;
+                    break;
+                }
             }
-            step++;
-            break;
-        case TIME_SYNC:
-            state = IDLE;
-            break;
-        case SET_DIG_OUTPUTS: //todo: validate the XOR byte
-            buff[1] = in_byte;
-            //temp8 = checksumCalc(buff, 2);
-            for (int c = 0; c < 8; c++) {
-                if (in_byte & (1 << c)) setOutput(c, true);
-                else setOutput(c, false);
-            }
-            state = IDLE;
-            break;
-        case SETUP_CANBUS: //todo: validate checksum
-            switch (step) {
-            case 0:
-                build_int = in_byte;
-                break;
-            case 1:
-                build_int |= in_byte << 8;
-                break;
-            case 2:
-                build_int |= in_byte << 16;
-                break;
-            case 3:
-                build_int |= in_byte << 24;
-                if (build_int > 0) {
-                    if (build_int & 0x80000000) { //signals that enabled and listen only status are also being passed
-                        if (build_int & 0x40000000) {
-                            settings.CAN0_Enabled = true;
-                            Can0.enable();
-                        } else {
-                            settings.CAN0_Enabled = false;
-                            Can0.disable();
-                        }
-                        if (build_int & 0x20000000) {
-                            settings.CAN0ListenOnly = true;
-                            Can0.enable_autobaud_listen_mode();
-                        } else {
-                            settings.CAN0ListenOnly = false;
-                            Can0.disable_autobaud_listen_mode();
-                        }
-                    } else {
-                        Can0.enable(); //if not using extended status mode then just default to enabling - this was old behavior
-                        settings.CAN0_Enabled = true;
-                    }
-                    build_int = build_int & 0xFFFFF;
-                    if (build_int > 1000000) build_int = 1000000;
-                    Can0.begin(build_int, 255);
-                    //Can0.set_baudrate(build_int);
-                    settings.CAN0Speed = build_int;
-                } else { //disable first canbus
-                    Can0.disable();
-                    settings.CAN0_Enabled = false;
-                }
-                break;
-            case 4:
-                build_int = in_byte;
-                break;
-            case 5:
-                build_int |= in_byte << 8;
-                break;
-            case 6:
-                build_int |= in_byte << 16;
-                break;
-            case 7:
-                build_int |= in_byte << 24;
-                if (build_int > 0) {
-                    if (build_int & 0x80000000) { //signals that enabled and listen only status are also being passed
-                        if (build_int & 0x40000000) {
-                            settings.CAN1_Enabled = true;
-                            Can1.enable();
-                        } else {
-                            settings.CAN1_Enabled = false;
-                            Can1.disable();
-                        }
-                        if (build_int & 0x20000000) {
-                            settings.CAN1ListenOnly = true;
-                            Can1.enable_autobaud_listen_mode();
-                        } else {
-                            settings.CAN1ListenOnly = false;
-                            Can1.disable_autobaud_listen_mode();
-                        }
-                    } else {
-                        Can1.enable(); //if not using extended status mode then just default to enabling - this was old behavior
-                        settings.CAN1_Enabled = true;
-                    }
-                    build_int = build_int & 0xFFFFF;
-                    if (build_int > 1000000) build_int = 1000000;
-                    Can1.begin(build_int, 255);
-                    //Can1.set_baudrate(build_int);
-
-                    settings.CAN1Speed = build_int;
-                } else { //disable second canbus
-                    Can1.disable();
-                    settings.CAN1_Enabled = false;
-                }
-                state = IDLE;
-                //now, write out the new canbus settings to EEPROM
-                EEPROM.write(EEPROM_ADDR, settings);
-                setPromiscuousMode();
-                break;
-            }
-            step++;
-            break;
-        case SET_SINGLEWIRE_MODE:
-            if (in_byte == 0x10) {
-            } else {
-            }
-            EEPROM.write(EEPROM_ADDR, settings);
-            state = IDLE;
-            break;
-        case SET_SYSTYPE:
-            settings.sysType = in_byte;
-            EEPROM.write(EEPROM_ADDR, settings);
-            loadSettings();
-            state = IDLE;
-            break;
-        case ECHO_CAN_FRAME:
-            buff[1 + step] = in_byte;
-            switch (step) {
-            case 0:
-                build_out_frame.id = in_byte;
-                break;
-            case 1:
-                build_out_frame.id |= in_byte << 8;
-                break;
-            case 2:
-                build_out_frame.id |= in_byte << 16;
-                break;
-            case 3:
-                build_out_frame.id |= in_byte << 24;
-                if (build_out_frame.id & 1 << 31) {
-                    build_out_frame.id &= 0x7FFFFFFF;
-                    build_out_frame.extended = true;
-                } else build_out_frame.extended = false;
-                break;
-            case 4:
-                out_bus = in_byte & 1;
-                break;
-            case 5:
-                build_out_frame.length = in_byte & 0xF;
-                if (build_out_frame.length > 8) build_out_frame.length = 8;
-                break;
-            default:
-                if (step < build_out_frame.length + 6) {
-                    build_out_frame.data.bytes[step - 6] = in_byte;
-                } else {
-                    state = IDLE;
-                    //this would be the checksum byte. Compute and compare.
-                    temp8 = checksumCalc(buff, step);
-                    //if (temp8 == in_byte)
-                    //{
-                    toggleRXLED();
-                    if (isConnected) sendFrameToUSB(build_out_frame, 0);
-                    //}
-                }
-                break;
-            }
-            step++;
-            break;
-        case SETUP_EXT_BUSES: //setup enable/listenonly/speed for SWCAN, Enable/Speed for LIN1, LIN2
-            switch (step) {
-            case 0:
-                build_int = in_byte;
-                break;
-            case 1:
-                build_int |= in_byte << 8;
-                break;
-            case 2:
-                build_int |= in_byte << 16;
-                break;
-            case 3:
-                build_int |= in_byte << 24;
-                if (build_int > 0) {
-                    if (build_int & 0x80000000) { //signals that enabled and listen only status are also being passed
-                        if (build_int & 0x40000000) {
-                            settings.SWCAN_Enabled = true;
-                            SWCAN.mode(3);
-                        } else {
-                            settings.SWCAN_Enabled = false;
-                            SWCAN.mode(0);
-                        }
-                        if (build_int & 0x20000000) {
-                            settings.SWCANListenOnly = true;
-                            //SWCAN.enable_autobaud_listen_mode();
-                        } else {
-                            settings.SWCANListenOnly = false;
-                            //SWCAN.disable_autobaud_listen_mode();
-                        }
-                    } else {
-                        SWCAN.mode(3);
-                        settings.SWCAN_Enabled = true;
-                    }
-                    build_int = build_int & 0xFFFFF;
-                    if (build_int > 100000) build_int = 100000;
-                    SWCAN.setupSW(build_int);
-                    delay(20);
-                    SWCAN.mode(3); // Go to normal mode. 0 - Sleep, 1 - High Speed, 2 - High Voltage Wake-Up, 3 - Normal
-                    attachInterrupt(SWC_INT, CANHandler, FALLING); //enable interrupt for SWCAN
-                    settings.SWCANSpeed = build_int;
-                } else { //disable first canbus
-                    SWCAN.mode(0);
-                    settings.SWCAN_Enabled = false;
-                }
-                break;
-            case 4:
-                build_int = in_byte;
-                break;
-            case 5:
-                build_int |= in_byte << 8;
-                break;
-            case 6:
-                build_int |= in_byte << 16;
-                break;
-            case 7:
-                build_int |= in_byte << 24;
-                /* FIX THIS UP TO INITIALIZE LIN1
-                if (build_int > 0) {
-                    if (build_int & 0x80000000) { //signals that enabled and listen only status are also being passed
-                        if (build_int & 0x40000000) {
-                            settings.CAN1_Enabled = true;
-                            Can1.enable();
-                        } else {
-                            settings.CAN1_Enabled = false;
-                            Can1.disable();
-                        }
-                    } else {
-                        Can1.enable(); //if not using extended status mode then just default to enabling - this was old behavior
-                        settings.CAN1_Enabled = true;
-                    }
-                    build_int = build_int & 0xFFFFF;
-                    if (build_int > 1000000) build_int = 1000000;
-                    Can1.begin(build_int, 255);
-                    //Can1.set_baudrate(build_int);
-                    settings.CAN1Speed = build_int;
-                } else { //disable second canbus
-                    Can1.disable();
-                    settings.CAN1_Enabled = false;
-                }*/
-                break;
-            case 8:
-                build_int = in_byte;
-                break;
-            case 9:
-                build_int |= in_byte << 8;
-                break;
-            case 10:
-                build_int |= in_byte << 16;
-                break;
-            case 11:
-                build_int |= in_byte << 24;
-                /* FIX THIS UP TO INITIALIZE LIN2
-                if (build_int > 0) {
-                    if (build_int & 0x80000000) { //signals that enabled and listen only status are also being passed
-                        if (build_int & 0x40000000) {
-                            settings.CAN1_Enabled = true;
-                            Can1.enable();
-                        } else {
-                            settings.CAN1_Enabled = false;
-                            Can1.disable();
-                        }
-                    } else {
-                        Can1.enable(); //if not using extended status mode then just default to enabling - this was old behavior
-                        settings.CAN1_Enabled = true;
-                    }
-                    build_int = build_int & 0xFFFFF;
-                    if (build_int > 1000000) build_int = 1000000;
-                    Can1.begin(build_int, 255);
-                    //Can1.set_baudrate(build_int);
-                    settings.CAN1Speed = build_int;
-                } else { //disable second canbus
-                    Can1.disable();
-                    settings.CAN1_Enabled = false;
-                } */
-                state = IDLE;
-                //now, write out the new canbus settings to EEPROM
-                EEPROM.write(EEPROM_ADDR, settings);
-                //setPromiscuousMode();
-                break;
-            }
-            step++;
-            break;
-        }
     }
     Logger::loop();
     elmEmulator.loop();
-}
-
+
+#ifdef _M2IO
+    #ifdef _M2IO_Demo
+        // !!!! M2_12VIO demonstration with M2RET !!!!
+    if(millis() > (Display_Time + SER_BUFF_FLUSH_INTERVAL)){   //Debugging sys_io
+        Display_Time = millis();
+
+        SerialUSB.print("\nTemp ");
+        SerialUSB.print(M2IO.Temperature());
+        SerialUSB.print("C");
+
+        SerialUSB.print("   Vehicle Volts ");
+        SerialUSB.print(((float)M2IO.Supply_Volts()) / 1000,2);
+        SerialUSB.print("V");
+
+        SerialUSB.print("   Analogue_1 ");
+        SerialUSB.print(((float) M2IO.Read_12VIO(1)) / 1000, 2);
+        SerialUSB.print("V");
+
+        SerialUSB.print("   Load Amps ");
+        SerialUSB.print(((float) M2IO.Load_Amps()) / 100, 2);
+        SerialUSB.print("A");
+
+        SerialUSB.print("\n");
+    }
+    #endif
+#endif
+}
+


not using this example

not using this example

--- html/examples/03.Analog/AnalogWriteMega/AnalogWriteMega.ino
+++ html/examples/03.Analog/AnalogWriteMega/AnalogWriteMega.ino
@@ -1,45 +0,0 @@
-/*
-  Mega analogWrite() test
-
-  This sketch fades LEDs up and down one at a time on digital pins 2 through 13.
-  This sketch was written for the Arduino Mega, and will not work on previous boards.
-
-  The circuit:
-  * LEDs attached from pins 2 through 13 to ground.
-
-  created 8 Feb 2009
-  by Tom Igoe
-
-  This example code is in the public domain.
-
- */
-// These constants won't change.  They're used to give names
-// to the pins used:
-const int lowestPin = 2;
-const int highestPin = 13;
-
-
-void setup() {
-  // set pins 2 through 13 as outputs:
-  for (int thisPin =lowestPin; thisPin <= highestPin; thisPin++) {
-    pinMode(thisPin, OUTPUT);
-  }
-}
-
-void loop() {
-  // iterate over the pins:
-  for (int thisPin =lowestPin; thisPin <= highestPin; thisPin++) {
-    // fade the LED on thisPin from off to brightest:
-    for (int brightness = 0; brightness < 255; brightness++) {
-      analogWrite(thisPin, brightness);
-      delay(2);
-    }
-    // fade the LED on thisPin from brithstest to off:
-    for (int brightness = 255; brightness >= 0; brightness--) {
-      analogWrite(thisPin, brightness);
-      delay(2);
-    }
-    // pause between LEDs:
-    delay(100);
-  }
-}


Initial game skeleton straw man.

Initial game skeleton straw man.

--- arduboy-game/arduboy-game.ino
+++ arduboy-game/arduboy-game.ino
@@ -1,106 +1,183 @@
 /*
-Buttons example
-June 11, 2015
-Copyright (C) 2015 David Martinez
-All rights reserved.
-This code is the most basic barebones code for showing how to use buttons in
-Arduboy.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
+ * arduboy-game, Modus Create 2016
 */

 #include "Arduboy.h"

-// Make an instance of arduboy used for many functions
-Arduboy arduboy;
-
-// Variables for your game go here.
-char text[] = "Press Buttons!";
-byte x;
-byte y;
-
-// Width of each charcter including inter-character space
-#define CHAR_WIDTH 6
-
-// Height of each charater
-#define CHAR_HEIGHT 8
-
-// To get the number of characters, we subtract 1 from the length of
-// the array because there will be a NULL terminator at the end.
-#define NUM_CHARS (sizeof(text) - 1)
-
-// This is the highest value that x can be without the end of the text
-// going farther than the right side of the screen. We add one because
-// there will be a 1 pixel space at the end of the last character.
-// WIDTH and HEIGHT are defined in the Arduboy library.
-#define X_MAX (WIDTH - (NUM_CHARS * CHAR_WIDTH) + 1)
-
-// This is the highest value that y can be without the text going below
-// the bottom of the screen.
-#define Y_MAX (HEIGHT - CHAR_HEIGHT)
+// Define limits that ship movement is bounded by
+#define MIN_SHIP_X 2
+#define MAX_SHIP_X 75
+#define MIN_SHIP_Y 10
+#define MAX_SHIP_Y 57

-// This function runs once in your game.
-// use it for anything that needs to be set only once in your game.
+// Time before title screen flips to high score screen
+#define ATTRACT_MODE_TIMEOUT 10000
+
+// Title screen outcomes
+#define TITLE_CREDITS 0
+#define TITLE_PLAY_GAME 1
+#define TITLE_TIMEOUT 2
+
+// Global variables
+Arduboy arduboy;
+// TODO highScore should be replaced with table in EEPROM
+unsigned int score, highScore = 0;
+byte livesRemaining = 4;
+
+// General purpose text buffer for string concatenations etc
+char textBuf[15];
+
+void printText(char *message, int x, int y, int textSize) {
+  arduboy.setCursor(x, y);
+  arduboy.setTextSize(textSize);
+  arduboy.print(message);
+}
+
+void introScreen() {
+  arduboy.clear();
+  printText("INTRO", 10, 20, 2);
+  arduboy.display();
+  delay(3000);
+}
+
+byte titleScreen() {
+  byte result = TITLE_PLAY_GAME;
+  unsigned short totalDelay = 0;
+
+  arduboy.clear();
+  printText("TITLE", 25, 20, 2);
+  arduboy.drawRect(2, 47, 31, 13, 1);
+  printText("PLAY", 5, 50, 1);
+  printText("CREDITS", 45, 50, 1);
+  arduboy.display();
+
+  while(totalDelay < ATTRACT_MODE_TIMEOUT) {
+    if (arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON)) {
+      break;
+    } else if (arduboy.pressed(LEFT_BUTTON)) {
+      // Highlight play option
+      result = TITLE_PLAY_GAME;
+      arduboy.drawRect(42, 47, 48, 13, 0);
+      arduboy.drawRect(2, 47, 31, 13, 1);
+      arduboy.display();
+    } else if (arduboy.pressed(RIGHT_BUTTON)) {
+      // Highlight credits option
+      result = TITLE_CREDITS;
+      arduboy.drawRect(2, 47, 31, 13, 0);
+      arduboy.drawRect(42, 47, 48, 13, 1);
+      arduboy.display();
+    }
+
+    delay(15);
+    totalDelay += 15;
+  }
+
+  if (totalDelay >= ATTRACT_MODE_TIMEOUT) {
+    // User didn't press a button so title screen just timed out
+    result = TITLE_TIMEOUT;
+  }
+
+  return(result);
+}
+
+void highScoreScreen() {
+  // TODO, this is placeholder
+  arduboy.clear();
+  printText("HI SCORES", 3, 15, 2);
+  arduboy.display();
+  delay(3000);
+}
+
+void creditsScreen() {
+  // TODO, this is placeholder
+  arduboy.clear();
+  printText("CREDITS", 20, 25, 2);
+  arduboy.display();
+  delay(5000);
+}
+
+void playGame() {
+  // TODO, this is placeholder, should also use livesRemaining
+  // to count down user lives
+  unsigned short shipX = 2, shipY = 32;
+  score = 0;
+
+  // Random test to set score
+  unsigned int randomScore = random(4000, 15000);
+
+  // Loop to simulate a game that ends with score being
+  // close to value of randomScore
+  while (score < randomScore) {
+    arduboy.clear();
+    arduboy.fillRect(shipX, shipY, 6, 4, 1);
+    sprintf(textBuf, "SCORE %u", score);
+    printText(textBuf, 0, 0, 1);
+    score += random(0, 50);
+    arduboy.display();
+
+    if (arduboy.pressed(UP_BUTTON) && shipY > MIN_SHIP_Y) {
+      shipY--;
+    } else if (arduboy.pressed(DOWN_BUTTON) && shipY < MAX_SHIP_Y) {
+      shipY++;
+    } else if (arduboy.pressed(LEFT_BUTTON) && shipX > MIN_SHIP_X) {
+      shipX--;
+    } else if (arduboy.pressed(RIGHT_BUTTON) && shipX < MAX_SHIP_X) {
+      shipX++;
+    }
+  }
+}
+
+void gameOverScreen() {
+  // TODO, this is placeholder
+  arduboy.clear();
+  printText("GAME OVER", 15, 30, 2);
+  arduboy.display();
+  delay(3000);
+}
+
+void newHighScoreScreen() {
+  // TODO, this is placeholder
+  arduboy.clear();
+  printText("NEW HI", 4, 25, 2);
+  arduboy.display();
+  delay(3000);
+}
+
+// Initialization runs once only
 void setup() {
-  //initiate arduboy instance
-  arduboy.begin();
-
-  // here we set the framerate to 30, we do not need to run at default 60 and
-  // it saves us battery life.
-  arduboy.setFrameRate(30);
-
-  // set x and y to the middle of the screen
-  x = (WIDTH / 2) - (NUM_CHARS * CHAR_WIDTH / 2);
-  y = (HEIGHT / 2) - (CHAR_HEIGHT / 2);
+  arduboy.beginNoLogo();
+  introScreen();
 }

-// our main game loop, this runs once every cycle/frame.
-// this is where our game logic goes.
+// Main program loop
 void loop() {
-  // pause render until it's time for the next frame
-  if (!(arduboy.nextFrame()))
-    return;
+  byte result;
+
+  // TODO alternate between titleScreen and highScoreScreen on a timer
+  // until user pressed a button
+  result = titleScreen();

-  // the next couple of lines will deal with checking if the D-pad buttons
-  // are pressed and move our text accordingly.
-  // We check to make sure that x and y stay within a range that keeps the
-  // text on the screen.
-
-  // if the right button is pressed move 1 pixel to the right every frame
-  if(arduboy.pressed(RIGHT_BUTTON) && (x < X_MAX)) {
-    x++;
+  switch(result) {
+    case TITLE_CREDITS:
+      creditsScreen();
+      break;
+    case TITLE_PLAY_GAME:
+      playGame();
+      gameOverScreen();
+      // TODO high score should be checked against a set of high scores
+      // in the EEPROM
+      if (score > highScore) {
+        newHighScoreScreen();
+        highScore = score;
+      }
+
+      highScoreScreen();
+      break;
+    case TITLE_TIMEOUT:
+      // No button pressed on title, alternate with high score
+      highScoreScreen();
+      break;
   }
-
-  // if the left button is pressed move 1 pixel to the left every frame
-  if(arduboy.pressed(LEFT_BUTTON) && (x > 0)) {
-    x--;
-  }
-
-  // if the up button or B button is pressed move 1 pixel up every frame
-  if((arduboy.pressed(UP_BUTTON) || arduboy.pressed(B_BUTTON)) && (y > 0)) {
-    y--;
-  }
-
-  // if the down button or A button is pressed move 1 pixel down every frame
-  if((arduboy.pressed(DOWN_BUTTON) || arduboy.pressed(A_BUTTON)) && (y < Y_MAX)) {
-    y++;
-  }
-
-
-  // we clear our screen to black
-  arduboy.clear();
-
-  // we set our cursor x pixels to the right and y down from the top
-  arduboy.setCursor(x, y);
-
-  // then we print to screen what is stored in our text variable we declared earlier
-  arduboy.print(text);
-
-  // then we finaly we tell the arduboy to display what we just wrote to the display.
-  arduboy.display();
 }


FIX: falsche Anzeige zwischen halb sechs und sechs Uhr morgens

--- arduino/src/myletterclock.ino
+++ arduino/src/myletterclock.ino
@@ -276,7 +276,7 @@
         lightMittag(cForeground);
     }
     if((Hour ==  19  && Minute >= 23) ||
-            (Hour >= 20 || Hour <= 5) ||
+            (Hour >= 20 || Hour <= 4) ||
             (Hour ==  5  && Minute <= 22))
     {
         lightNachts(cForeground);


combined stepper type constants into one variable. Added support for both normally closed and normally open stop switches.

--- starsynctrackers.ino
+++ starsynctrackers.ino
@@ -1,39 +1,39 @@
-// ConstantSpeed.pde
-// -*- mode: C++ -*-
 //
 // If using Motorshield requires the Adafruit_Motorshield v2 library
 //   https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library
-// And AccelStepper with AFMotor support
+// And you need AccelStepper fork with AFMotor support with library
 //   https://github.com/adafruit/AccelStepper
-
-// This tutorial is for Adafruit Motorshield v2 only!
-// Will not work with v1 shields
+// The latest version of AccellStepper should have AFMotor support already.
+// http://www.airspayce.com/mikem/arduino/AccelStepper/

 #include <AccelStepper.h>
 #include <Wire.h>

-#define MOTORSHIELD 0 // Set to 1 if using Adafruit Motorshield
-#define EASYDRIVER 1  // Set to 1 if using Easydriver
+// STEPPER_DRIVER
+// 0 - Adafruit Motorshield https://www.adafruit.com/products/1438
+// 1 - Easy Driver https://www.sparkfun.com/products/12779
+#define STEPPER_DRIVER 0

-#if MOTORSHIELD == 1
+#if STEPPER_DRIVER == 0
 #include <Adafruit_MotorShield.h>
 #include "utility/Adafruit_PWMServoDriver.h"
 #endif

 //Constants
 static const float STEPS_PER_ROTATION = 200.0; // Steps per rotation, just steps not microsteps.
-static const float THREADS_PER_INCH = 20;  //Threads per inch or unit of measurement
+static const float THREADS_PER_INCH = 20;  // Threads per inch or unit of measurement
 static const float R_I = 7.28;     // Distance from plate pivot to rod when rod is perp from plate
 static const float D_S = 0.00591;   // Distance from rod pivot to plate
 static const float D_F = 0.252; // Distiance along rod from plate to starting position
-static const float RECALC_INTERVAL_S = 15; //Time in seconds between recalculating
+static const float RECALC_INTERVAL_S = 15; // Time in seconds between recalculating

-static const int STOP_BUTTON_PIN = 0;  //The pin the stop push switch is on
-static const float RESET_SPEED = -1000.0;  //The speed to go back to initial position at
+static const int STOP_BUTTON_PIN = 0;      // The pin the stop push switch is on
+static const int STOP_BUTTON_TYPE = 0;     // The type of switch 0 - Normally Closed; 1 - Normally Open
+static const float RESET_SPEED = -1000.0;  // The speed to go back to initial position at

-#if MOTORSHIELD == 1
+#if STEPPER_DRIVER == 0
 // Create the motor shield object with the default I2C address
 Adafruit_MotorShield AFMS = Adafruit_MotorShield();
 // Or, create it with a different I2C address (say for stacking)
@@ -58,7 +58,7 @@

 #endif

-#if EASYDRIVER == 1
+#if STEPPER_DRIVER == 1

 AccelStepper Astepper1(1, 9, 8);
 #define MICROSTEPS 8
@@ -71,7 +71,7 @@
   Serial.println("Star Tracker v0.01");

   pinMode(STOP_BUTTON_PIN, INPUT_PULLUP);
-#if MOTORSHIELD == 1
+#if STEPPER_DRIVER == 0
   AFMS.begin();  // create with the default frequency 1.6KHz
 #endif

@@ -83,13 +83,11 @@
 void goInitialPosition()
 {
   Serial.println("goInitialPosition");
+  boolean started = false;
   delay(250);
   int buttonV = digitalRead(STOP_BUTTON_PIN);
-  boolean started = false;
   Serial.println(buttonV);
-  buttonV = digitalRead(STOP_BUTTON_PIN);
-  Serial.println(buttonV);
-  while (buttonV == HIGH)
+  while (buttonV == STOP_BUTTON_TYPE)
   {
     if (!started) {
       Serial.println("Set reset speed.");


fix travis compile on esp32

fix travis compile on esp32

--- examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino
+++ examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino
@@ -68,7 +68,9 @@
 //gets called when WiFiManager enters configuration mode
 void configModeCallback (WiFiManager *myWiFiManager) {
   Serial.println("[CALLBACK] configModeCallback fired");
-  print_oled("WiFiManager Waiting\nIP: " + WiFi.softAPIP().toString() + "\nSSID: " + WiFi.softAPSSID(),1);
+  #ifdef ESP8266
+    print_oled("WiFiManager Waiting\nIP: " + WiFi.softAPIP().toString() + "\nSSID: " + WiFi.softAPSSID(),1);
+  #endif
   // myWiFiManager->setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
   // Serial.println(WiFi.softAPIP());
   //if you used auto generated SSID, print it


v0.0.9 fix 6

v0.0.9 fix 6

remove voltage multiplier check as it is not needed and increased buffer size of the calibration json

--- src/WiFiSensor/loadconfig.ino
+++ src/WiFiSensor/loadconfig.ino
@@ -50,7 +50,7 @@
   mqtt["humiditytopic"] = "humidity";
   root["mqtt-settings"] = mqtt;

-  StaticJsonBuffer<128> calbuffer;
+  StaticJsonBuffer<256> calbuffer;
   JsonObject &calib = calbuffer.createObject();
   calib["temperature-offset"] = "0";
   calib["humidity-offset"] = "0";
@@ -140,11 +140,6 @@
     Serial.println("Error: Config does not contain 'update_rates'");
     return (1);
   }
-  if(!root.containsKey("voltage-multiplier")){
-    //String not found error case
-    Serial.println("Error: Config does not contain 'voltage-multiplier'");
-    return (1);
-  }

   // Use the JSON root object to assign the values to the global variables
   wifissid = root["wifi"]["ssid"].asString();


Prove that reset doesn't clobber hooks

Prove that reset doesn't clobber hooks

--- examples/rwccert-otaa-halconfig-us915/rwccert-otaa-halconfig-us915.ino
+++ examples/rwccert-otaa-halconfig-us915/rwccert-otaa-halconfig-us915.ino
@@ -326,14 +326,14 @@
     // now that we have a pinmap, initalize the low levels accordingly.
     os_init_ex(pPinMap);

-    // Reset the MAC state. Session and pending data transfers will be discarded.
-    LMIC_reset();
-
-    // Reset resets *everything*, so we need to register after the LMIC_reset().
+    // LMIC_reset() doesn't affect callbacks, so we can do this first.
     if (! (LMIC_registerRxMessageCb(myRxMessageCb, /* userData */ nullptr) &&
            LMIC_registerEventCb(myEventCb, /* userData */ nullptr))) {
         myFail("couldn't register callbacks");
     }
+
+    // Reset the MAC state. Session and pending data transfers will be discarded.
+    LMIC_reset();

     // do the network-specific setup.
     setupForNetwork();


Extend-o-Hand recognizes 'snappy' gestures with 70ms accuracy

--- extendo-hand/src/main/arduino/extendo_hand/extendo_hand.ino
+++ extendo-hand/src/main/arduino/extendo_hand/extendo_hand.ino
@@ -1,8 +1,4 @@
-/*
-  Sends sensor data to Android
-  (needs SensorGraph and Amarino app installed and running on Android)
-*/
-
+
 #include <MeetAndroid.h>

 MeetAndroid meetAndroid;
@@ -11,6 +7,8 @@
 const int pinX = A0;
 const int pinY = A1;
 const int pinZ = A2;
+
+
 ////////////////////////////////////////
 // 1.5g constants

@@ -51,15 +49,80 @@
 const double zmid = (zmin + zmax) / 2.0;

+const double lowerBound = 1.25;
+const double upperBound = 1.75;
+const int STATE_ONE = 1;
+const int STATE_TWO = 2;
+const int STATE_THREE = 3;
+const int STATE_FOUR = 4;
+
+int state;
+double amax;
+double ax_max, ay_max, az_max;
+
 void setup()
 {
   // use the baud rate your bluetooth module is configured to
-  // not all baud rates are working well, i.e. ATMEGA168 works best with 57600
+  // not all baud rates work well, i.e. ATMEGA168 works best with 57600
   Serial.begin(115200);
+
+  state = STATE_ONE;
 }

 void loop()
 {
+    double ax, ay, az;
+    double a;
+
+    ax = 2 * (analogRead(pinX) - xmid) / xrange;
+    ay = 2 * (analogRead(pinY) - ymid) / yrange;
+    az = 2 * (analogRead(pinZ) - zmid) / zrange;
+
+    a = sqrt(ax*ax + ay*ay + az*az);
+
+    switch (state) {
+      case STATE_ONE:
+        if (a >= lowerBound) {
+          state = STATE_TWO;
+        }
+        break;
+      case STATE_TWO:
+        if (a >= upperBound) {
+          state = STATE_THREE;
+          amax = 0;
+        } else if (a < lowerBound) {
+          state = STATE_ONE;
+        }
+        break;
+      case STATE_THREE:
+        if (a > amax) {
+           amax = a;
+           ax_max = ax;
+           ay_max = ay;
+           az_max = az;
+        }
+
+        if (a < upperBound) {
+           state = STATE_FOUR;
+        }
+        break;
+      case STATE_FOUR:
+        if (a >= upperBound) {
+          state = STATE_THREE;
+        } else if (a < lowerBound) {
+          state = STATE_ONE;
+
+          // gesture event
+          Serial.print(micros()); Serial.print(","); Serial.print(amax);
+          Serial.print(": ("); Serial.print(ax_max);
+          Serial.print(","); Serial.print(ay_max);
+          Serial.print(","); Serial.print(az_max);
+          Serial.println(")");
+        }
+        break;
+    }
+
+    /*
     int xraw = analogRead(pinX);
     int yraw = analogRead(pinY);
     int zraw = analogRead(pinZ);
@@ -69,16 +132,13 @@
     Serial.print(","); Serial.print(yraw);
     Serial.print(","); Serial.print(zraw);
     Serial.println("");
-
-    //delay(500);

+    meetAndroid.receive(); // you need to keep this in your loop() to receive events

-  meetAndroid.receive(); // you need to keep this in your loop() to receive events
+    meetAndroid.send(xraw);

-  // read input pin and send result to Android
-  meetAndroid.send(pinX);
-
-  // add a little delay otherwise the phone is pretty busy
-  delay(100);
+    // add a little delay otherwise the phone is pretty busy
+    delay(100);
+    //*/
 }


Maker mapFloat inline.

Maker mapFloat inline.

--- aquacontrol32.ino
+++ aquacontrol32.ino
@@ -182,7 +182,7 @@
 void wifiTask( void * pvParameters );

 /* global functions */
-float mapFloat( const float &x, const float &in_min, const float &in_max, const float &out_min, const float &out_max) {
+inline float mapFloat( const float &x, const float &in_min, const float &in_max, const float &out_min, const float &out_max) {
   return ( x - in_min ) * ( out_max - out_min ) / ( in_max - in_min ) + out_min;
 }


Delete C_CDETPO-Industruino.ino

Delete C_CDETPO-Industruino.ino

--- Examples/C_CDETPO-Industruino/C_CDETPO-Industruino.ino
+++ Examples/C_CDETPO-Industruino/C_CDETPO-Industruino.ino
@@ -1,221 +0,0 @@
-/*-------------------------------------------------------------------------------------------------------------------------------------------*
-* SE2R : C_CDETPO - Fonction de temporisation de commande à l'action et à l'arrêt                                                03/06/2015 *
- *-------------------------------------------------------------------------------------------------------------------------------------------*
- *        C_CDETPO(boolean CDE, boolean DFT, float CPT[], int RES[], int CFG)                                                     03/06/2015 *
- *                CDE : Demande calculée ou donnée par l'utilisateur (peut être le résultat d'une fonction appelée plus haut)                *
- *                DFT : Défaut de l'équipement commandé. True signale un équipement en état normal. Un false signale un défaut               *
- *                CPT : [00] Compteur de temporisation                                                                                *
- *                      [01] Tempo entre le front montant de la demande CDE avant l'action sur la commande                                   *
- *                      [02] Tempo entre le front descendant de la demande CDE avant la désactivation de la commande                         *
- *                      [03] Temps de cycle automate calculé par la fonction                                                                 *
- *                      [04] Mémorisation de la variable système Millis pour le calcul du temps de cycle                                     *
- *                RES : [00] Commande de l'équipement - forcément un tableau de taille au moins 1                                            *
- *                CFG : Commande de forçage.                                                                                *
- *                      <0 : RES maintenu à false                                                                                *
- *                      0  : RES figée dans son dernier état connu                                                                           *
- *                      1  : RES soumise à CDE (à TMA et TAR près) et à DFT                                                                  *
- *                      2  : RES soumise seulement à DFT (comme si CDE était true en permanence)                                             *
- *                      3  : RES  maintenu à true indépendamment de DFT et CDE                                                               *
- *                      >3 : RES maintenu à false                                                                                *
- *-------------------------------------------------------------------------------------------------------------------------------------------*
- * Copyright SE2R under the APACHE Licence                                                                                *
- *-------------------------------------------------------------------------------------------------------------------------------------------*
- * Plate-formes testées : Industruino 32U8 et 1286                                                                                *
- *-------------------------------------------------------------------------------------------------------------------------------------------*
- * 27/05/2015 : DD, SE2R : Testée et validée sur banc                                                                                *
- * 27/05/2015 : DD, SE2R : Cette fonction nécessite l'utilisation de S_SCANTS pour accéder à la valeur du cycle automate                     *
- * 03/06/2015 : DD, SE2R : Intégration du calcul de temps de cycle, passage de la commande en boolean et simplification du code              *
- * 03/06/2015 : DD, SE2R : Passage en mode void et ajout des commentaires d'appartenance à C_CDETPO                                          *
- *-------------------------------------------------------------------------------------------------------------------------------------------*/
-
-// Déclaration des bibliothèques nécessaires à l'exécution du programme ---------------------------------------------------------------------*
-#include <DIS.h>                        // Biblio   - SE2R - Fonctions de dialogue et d'affichage sur l'écran UC1701 Industruino
-static DIS DIS;                         // Biblio   - Activation du constructeur de la bibliothèque de fonctions d'affichage
-static UC1701 lcd;
-#include <BMS.h>                        // Biblio   - SE2R - Fonctions de contrôle et régulation
-static BMS BMS;                         // Biblio   - Activation du constructeur de la bibliothèque de fonctions d'affichage
-
-// Déclaration des variables nécessaires à l'exécution de la fonction -----------------------------------------------------------------------*
-boolean FCO_XXXX[1];                    // C_CDELEM - [00] Commande de marche depuis l'extérieur
-boolean EDx_TEL_XXXX[9];                // Système  - [00] Inutilisée
-                                        //            [01] Etat de la lecture de la voie digitale 1 si elle est une entrée
-                                        //            [02] Etat de la lecture de la voie digitale 2 si elle est une entrée
-                                        //            [03] Etat de la lecture de la voie digitale 3 si elle est une entrée
-                                        //            [04] Etat de la lecture de la voie digitale 4 si elle est une entrée
-                                        //            [05] Etat de la lecture de la voie digitale 5 si elle est une entrée
-                                        //            [06] Etat de la lecture de la voie digitale 6 si elle est une entrée
-                                        //            [07] Etat de la lecture de la voie digitale 7 si elle est une entrée
-                                        //            [08] Etat de la lecture de la voie digitale 8 si elle est une entrée
-boolean SDx_TSL_XXXX[9];                // Système  - [00] Mémoire temporaire utilisée pour les calculs
-                                        //            [01] Etat de la commande de la voie digitale 1 si elle est une sortie
-                                        //            [02] Etat de la commande de la voie digitale 1 si elle est une sortie
-                                        //            [04] Etat de la commande de la voie digitale 1 si elle est une sortie
-                                        //            [05] Etat de la commande de la voie digitale 1 si elle est une sortie
-                                        //            [07] Etat de la commande de la voie digitale 1 si elle est une sortie
-                                        //            [08] Etat de la commande de la voie digitale 1 si elle est une sortie
-float VTT_XXXX[5];                      // C_CDETPO - [00] Compteur des temporisations
-                                        //            [01] Tempo entre le front montant de la demande CDE avant l'action sur la commande
-                                        //            [02] Tempo entre le front descendant de la demande CDE avant la désactivation de la commande
-                                        //            [03] Temps de cycle automate calculé par la fonction
-                                        //            [04] Mémorisation de la variable système Millis pour le calcul du temps de cycle
-int VCO_XXXX[1];                        // C_CDETPO - [00] Commande de forçage par l'extérieur
-
-// Déclaration des variables nécessaires au fonctionnement de l'écran -----------------------------------------------------------------------*
-String TCM_PRES[21] = {                 // EcranLCD - Table de chaînes de caractères de présentation
-  "                     ",  // 00
-  "-  Menu  Principal  -",
-  "Retour Accueil      ",
-  "Demande             ",
-  "forcage             ",
-  "Chrono              ",
-  "Defaut               ",
-  "Cde M/A              ",
-  "- Selection + Enter -",
-  "- Commande  Mar/Arr -",
-  "-      Forcage      -",  // 10
-  "- Tempo a la marche -",
-  "-  Tempo a l'arret  -",
-  " ",
-  " ",
-  " ",
-  " ",
-  " ",
-  " ",
-  " ",
-  " "};                      // 20
-
-
-String TCM_UNIT[21] = {                 // EcranLCD - Table de chaînes de caractères d'unités standard
-  "        ",  // 00
-  "oC      ",
-  "%       ",
-  "s       ",
-  "V       ",
-  "mV      ",  // 05
-  "",
-  "",
-  "",
-  "",
-  "",          // 10
-  "   Arret ",
-  "  Marche ",
-  " F.Arret ",
-  " Debraye ",
-  "    Auto ", // 15
-  "F.Marche ",
-  "V.Marche ",
-  "  Defaut ",
-  "  Normal ",
-  "  " };      // 20
-
-boolean FCO_PRUP[5];                    // EcranLCD - Information de touche "Up" appuyée
-boolean FCO_PREN[5];                    // EcranLCD - Information de touche "Enter" appuyée
-boolean FCO_PRDN[5];                    // EcranLCD - Information de touche "Down" appuyée
-int VNT_MENU[2];                        // EcranLCD - Table d'adressage des menus
-int VNC_MENU[10];                       // EcranLCD - Table des numéros de menus
-int VNC_PRUP[11];                       // EcranLCD - Table des numéros de menus de destination par la touche "Up"
-int VNC_PREN[10];                       // EcranLCD - Table des numéros de menus de destination par la touche "Enter"
-int VNC_PRDN[10];                       // EcranLCD - Table des numéros de menus de destination par la touche "Down"
-float VTT_SCRN[10];                     // EcranLCD - Table des temporisations
-int VNX_MN02[12];                       // EcranLCD - Table des menus de destimation et des index du menu 02 - Principal
-boolean FCM_XXXX[1];                    // G_MODV1B - Mémoire de la demande de marche
-int VTM_XXXX[7];                        // G_MODV1M - Mémoire de calcul de la commande de la fonction pour VCO_XXXX - Forçage
-float VTM_TPAM[11];                     // G_MODV1F - Mémoire de calcul de la commande de la fonction pour VTT_XXXX[1] - Tempo à la marche
-float VTM_TPMA[11];                     // G_MODV1F - Mémoire de calcul de la commande de la fonction pour VTT_XXXX[2] - Tempo à l'arrêt
-
-void setup() {                          // Initialisation -----------------------------------------------------------------------------------*
-Indio.digitalMode(1,INPUT);             // Système  - Affectation de la voie Dx1 en tant qu'entrée digitale
-Indio.digitalMode(5,OUTPUT);            // Système  - Affectation de la voie Dx5 en tant que sortie digitale
-VCO_XXXX[0] = 1;                        // C_CDELEM - Passage du forçage en position auto
-
-VTT_SCRN[1] = 180;                      // G_TOUCHx - Temporisation d'inactivité sur le rétroéclairage
-VTT_SCRN[2] = 240;                      // G_TOUCHx - Temporisation d'inactivité de retour à l'écran principal
-VTT_SCRN[3] = 20;                       // G_TOUCHx - Temporisation d'antirebond de la touche "Enter"
-VTT_SCRN[4] = 15;                       // G_TOUCHx - Temporisation d'antiredond des touches "Up" et "Down"
-VNT_MENU[0] = 6;                        // G_NAVIGM - Taille des tables d'index et de destinations
-VNT_MENU[1] = 1;                        // G_NAVIGM - Initialisation du pointeur de destinations
-
-//                                      // G_NAVIGM - Tables d'adressage de l'écran LCD
-VNC_MENU[0] = 1;
-VNC_MENU[1] = 1;
-VNC_MENU[2] = 2;
-VNC_MENU[3] = 3;
-VNC_MENU[4] = 4;
-VNC_MENU[5] = 5;
-VNC_MENU[6] = 6;
-VNC_PRUP[1] =   1; VNC_PREN[1] =   2; VNC_PRDN[1] =   2;
-VNC_PRUP[2] =   2; VNC_PREN[2] =   2; VNC_PRDN[2] =   2;
-VNC_PRUP[3] =   3; VNC_PREN[3] =   2; VNC_PRDN[3] =   3;
-VNC_PRUP[4] =   4; VNC_PREN[4] =   2; VNC_PRDN[4] =   4;
-VNC_PRUP[5] =   5; VNC_PREN[5] =   6; VNC_PRDN[5] =   5;
-VNC_PRUP[6] =   6; VNC_PREN[6] =   2; VNC_PRDN[6] =   6;
-VNC_PRUP[7] =   2;
-
-VNX_MN02[0] = 0;						// G_CHOIX8 - Table des menus de destination et des index du menu 11 - Initialisation index
-VNX_MN02[1] = 1;
-VNX_MN02[2] = 3;
-VNX_MN02[3] = 4;
-VNX_MN02[4] = 5;
-VNX_MN02[5] = 0;
-VNX_MN02[6] = 0;
-VNX_MN02[7] = 0;
-VNX_MN02[8] = 1;
-VNX_MN02[9] = 4;
-VNX_MN02[10] = 1;
-
-VTM_XXXX[1] = 0; VTM_XXXX[2] = 2; VTM_XXXX[3] = 1; VTM_XXXX[4] = VCO_XXXX;
-VTM_TPAM[1] = 0; VTM_TPAM[2] = 600; VTM_TPAM[3] = 1;  VTM_TPAM[4] = VTT_XXXX[1];  VTM_TPAM[8] = 100;
-VTM_TPMA[1] = 0; VTM_TPMA[2] = 600; VTM_TPMA[3] = 1;  VTM_TPMA[4] = VTT_XXXX[2];  VTM_TPMA[8] = 100;
-
-//                                      // EcranLCD - Paramétrage spécifique Industruino 1286
-pinMode(23, INPUT);                     // EcranLCD - Spécifique 1286 - Touche flèche basse
-pinMode(24, INPUT);                     // EcranLCD - Spécifique 1286 - Touche entrée
-pinMode(25, INPUT);                     // EcranLCD - Spécifique 1286 - Touche flèche haute
-pinMode(26, OUTPUT);                    // EcranLCD - Spécifique 1286 - Sortie de commande du rétroéclairage
-
-/*                                      // EcranLCD - Paramétrage spécifique Industruino 32U8
-pinMode(13, OUTPUT);                    // EcranLCD - Spécifique 32U8 - Sortie de commande du rétroéclairage
-*/
-lcd.begin();                            // EcranLCD - Initialisation de l'écran LCD
-lcd.clear();                            // EcranLCD - Effacement de l'écran LCD
-}
-
-void loop() {                            // Exécution ---------------------------------------------------------------------------------------*
-if (Indio.digitalRead(1) == HIGH) { EDx_TEL_XXXX[1] = false; } else { EDx_TEL_XXXX[1] = true; }
-BMS.C_CDETPO(FCO_XXXX[0], EDx_TEL_XXXX[1], VTT_XXXX, SDx_TSL_XXXX, VCO_XXXX[0]);
-if (SDx_TSL_XXXX[0] == true ) { SDx_TSL_XXXX[5] = true; } else  { SDx_TSL_XXXX[5] = false; }
-if (SDx_TSL_XXXX[5] == true ) { Indio.digitalWrite(5,HIGH); } else {Indio.digitalWrite(5,LOW); }
-
-//                                      // EcranLCD - Gestion des touches spécifique Industruino 1286
-DIS.G_TOUCH2(VNC_MENU, VTT_SCRN, FCO_PRUP, FCO_PREN, FCO_PRDN);
-/*                                      // EcranLCD - Gestion des touches spécifique Industruino 32U8
-DIS.G_TOUCH1(VNC_MENU, VTT_SCRN, FCO_PRUP, FCO_PREN, FCO_PRDN);
-*/
-
-if (VNC_MENU[0] ==  1) { lcd.setCursor(0, 0); lcd.clearLine(); }
-DIS.G_MESS1L(VNC_MENU, 1, 1, 0, "   www.eControls.eu  ");
-DIS.G_MESS1L(VNC_MENU, 1, 2, 0, "    SE2R Softwares   ");
-DIS.G_MESS1L(VNC_MENU, 1, 3, 0, "  Industruino  1286  ");
-// DIS.G_MESS1L(VNC_MENU, 1, 3, 0, "  Industruino  32U8  ");
-if (VNC_MENU[0] ==  1) { lcd.setCursor(0, 4); lcd.clearLine(); }
-DIS.G_MESS1L(VNC_MENU, 1, 5, 0, "Fonction BMS.C_CDETPO");
-DIS.G_MESS1L(VNC_MENU, 1, 6, 0, "A# TESTS     C# 00001");
-DIS.G_MESS1L(VNC_MENU, 1, 7, 0, "V.1.01     03/06/2015");
-
-DIS.G_CHOIX8(VNC_MENU, 2, FCO_PRUP, FCO_PREN, FCO_PRDN, VNX_MN02);
-DIS.G_MESS1L(VNC_MENU, 2, 0, 0, TCM_PRES[1]);
-DIS.G_MESS1L(VNC_MENU, 2, 1, 6, TCM_PRES[2]);
-DIS.G_VISV1B(VNC_MENU, 2, 2, 6, FCO_XXXX[0], TCM_PRES[3], TCM_UNIT[11], TCM_UNIT[12]);
-DIS.G_VISV1M(VNC_MENU, 2, 3, 6, VCO_XXXX[0], TCM_PRES[4], TCM_UNIT[14]);
-DIS.G_VISV1F(VNC_MENU, 2, 4, 6, VTT_XXXX[0], TCM_PRES[4], TCM_UNIT[3]);
-DIS.G_VISV1B(VNC_MENU, 2, 5, 0, EM1_MII_MPLX[4], TCM_PRES[6], TCM_UNIT[18], TCM_UNIT[19]);
-DIS.G_VISV1B(VNC_MENU, 2, 6, 0, SDx_MPL_XXXX[5], TCM_PRES[7], TCM_UNIT[11], TCM_UNIT[12]);
-DIS.G_MESS1L(VNC_MENU, 2, 7, 0, TCM_PRES[8]);
-
-DIS.G_MODV1B(VNC_MENU, 3, FCO_PRUP, FCO_PREN, FCO_PRDN, FCO_XXXX, 0, FCM_XXXX, TCM_PRES[9] , " Commande operateur ", TCM_UNIT[13], TCM_UNIT[14], true);
-DIS.G_MODV1M(VNC_MENU, 4, FCO_PRUP, FCO_PREN, FCO_PRDN, VCO_XXXX, 0, VTM_XXXX, TCM_PRES[10], "Arr/Deb/Auto/Mar/VMa", TCM_UNIT, 14, true, 0);
-DIS.G_MODV1F(VNC_MENU, 5, FCO_PRUP, FCO_PREN, FCO_PRDN, VTT_XXXX, 1, VTM_TPAM, TCM_PRES[11], "de Demande a  Marche", TCM_UNIT[3], true, 0);
-DIS.G_MODV1F(VNC_MENU, 6, FCO_PRUP, FCO_PREN, FCO_PRDN, VTT_XXXX, 2, VTM_TPMA, TCM_PRES[12], "de Demande a   Arret", TCM_UNIT[3], true, 0);
-
-DIS.G_NAVIGM(VNC_MENU, VNT_MENU, FCO_PRUP, FCO_PREN, FCO_PRDN , VNC_PRUP, VNC_PREN, VNC_PRDN);
-}


some higher decimal numbers for rain reporting

--- mwsLRWHFv2/mwsLRWHFv2.ino
+++ mwsLRWHFv2/mwsLRWHFv2.ino
@@ -167,9 +167,9 @@

 //Calibrate rain bucket here
 //Rectangle raingauge from Sparkfun.com weather sensors
-float rain_bucket_mm = 0.011*25.4;//Each dump is 0.011" of water
+//float rain_bucket_mm = 0.011*25.4;//Each dump is 0.011" of water
 //DAVISNET Rain Collector 2
-//float rain_bucket_mm = 0.01*25.4;//Each dump is 0.01" of water
+float rain_bucket_mm = 0.01*25.4;//Each dump is 0.01" of water

 // volatiles are subject to modification by IRQs
 volatile unsigned long raintime, rainlast, raininterval, rain, Rainindtime, Rainindlast;
@@ -570,13 +570,13 @@
   Serial.print(",");
   Serial.print(tempf, 1);//[15] Celsius
   Serial.print(",");
-  Serial.print(rainin, 2);//[16] hourly
-  Serial.print(",");
-  Serial.print(dailyrainin, 2);//[17]
+  Serial.print(rainin, 3);//[16] hourly
+  Serial.print(",");
+  Serial.print(dailyrainin, 3);//[17]
   Serial.print(",");
   Serial.print(Rainindi,1);//[18] 5min indicatior (flag 0/1)
   Serial.print(",");
-  Serial.print(rainin5min,1);//[19] 5min rain (mm/5min)
+  Serial.print(rainin5min,3);//[19] 5min rain (mm/5min)
   Serial.print(",");
   Serial.print(pressure, 2);//[20]
   Serial.print(",");
@@ -628,7 +628,7 @@

   lcd.clear();
   lcd.print("R:");
-  lcd.print(dailyrainin);
+  lcd.print(dailyrainin,2);
   lcd.print("(mm/d)");
   lcd.setCursor(0, 2);
   lcd.print(F("P:"));


fixed max speed

fixed max speed

--- Braking_Ultrasonic/Braking_Ultrasonic.ino
+++ Braking_Ultrasonic/Braking_Ultrasonic.ino
@@ -56,8 +56,8 @@
     analogWrite(leftMotorPins[2], 70); // slow down, we are getting close to the wall.
     analogWrite(rightMotorPins[2], 70);
   } else {
-    analogWrite(leftMotorPins[2], 200); // go fast we are far from the object.
-    analogWrite(rightMotorPins[2], 200);
+    analogWrite(leftMotorPins[2], 120); // go fast we are far from the object.
+    analogWrite(rightMotorPins[2], 120);
   }
   delay(40); // necessary delay to allow the sensor to get the data.
 }