Delete AirSolarController.ino

Delete AirSolarController.ino

--- AirSolarController.ino
+++ AirSolarController.ino
@@ -1,900 +0,0 @@
-/*
-   Arduino Solar Controller - Kit
-
-   by karldm, March 2016
-
-
-   The MIT License (MIT)
-
-   Copyright (c) 2016 www.renergia.fr
-
-   Permission is hereby granted, free of charge, to any person obtaining a copy
-   of this software and associated documentation files (the "Software"), to deal
-   in the Software without restriction, including without limitation the rights
-   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-   copies of the Software, and to permit persons to whom the Software is
-   furnished to do so, subject to the following conditions:
-
-   The above copyright notice and this permission notice shall be included in all
-   copies or substantial portions of the Software.
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-   SOFTWARE.
-*/
-
-/*
- * v0.0a
- * =====
- * 2016/9/19
- *
- * - PINs definition according to the shield design
- * - added OW3 and OW4 (TUSR1, TUSR2)
- * - added SWUSR
- *
- * 2016/9/26 - v0.0b
- *
- * - PINs allocation according to ASC-Kit shield design
- * - delete the SAFE mode (idem STOP)
- * - add MODEMH mngt in StateEngineMH()
- * - change access parameters ('pgs')
- * - check updated data 'g' from datastore to update EEPROM
- * - add requests: stop-run-default-setdefault-rst_indsh-rst_tcmh-rst_tcsh
- *
- * First verison for tests with ASC-Kit hardware => v1.0 prod
- * - sketch 92% - ram 48% /w console
- * - sketch 83% - ram 43% /w console
- *
- * test on new hardware -- wait
- * for 'prod', remove the --dev features (console?)
- *
- * v0.0c
- * =====
- * 2016/10/1
- * - add the parameter value in EEPROM_put EEPROM_get to access
- * value=0 saved values
- * value=1 default values (defined in the prog)
- * - remove the while in console start => keep def CONSOLE
- * - add error comments to CONSOLE
- * - remove EEPROM options
- *
- * TODO: clean the Info messages -- eg the sensors errors OW & the state transitions on SH and SM
- */
-
-//-------1---------2---------3---------4---------5---------6---------7---------8
-#define VERSION "0.0c"            // Software version
-#define TAG10   "ASCKit...."      // Tag for EEPROM data structure check -- unused
-
-//
-// SOLAR HEATER STATES
-// modes  : OFF - HEAT
-// states : OFF - ON
-//
-// MAIN HEATER
-// modes  : OFF - HEAT - ECO - FP
-// states : ON - OFF
-
-#define OFF     0                  // OFF mode or state
-#define ON      1                  // ON state
-#define HEAT    1                  // main heater & solar heater HEAT mode
-#define ECO     2                  // Main heater ECO mode
-#define FP      3                  // Main heater freeze protection
-
-//
-// CONTROLLER
-// states : STOP - RUN - INIT - FAIL1 - FAIL2
-//
-#define STOP      0                // Controller STOP state or mode
-#define RUN       1                // Controller RUN state or mode
-#define INIT      2                // Controller INIT state -- power onP
-#define FAIL1     3                // Controller FAIL1 -- solar heater OFF due to TCOL measurement error
-#define FAIL2     4                // Controller FAIL2 state -- sh and mh OFF due to TAMB measurements error
-
-// Hardware configuration
-#define PINDHT    2                // DHT sensor bus
-#define PINLED1   3                // GREEN LED pin number
-#define PINOW1    4                // OW1 Bus pin number (single sensor TCOL)
-#define PINOW2    5                // OW2 Bus pin number (single sensor TEXT)
-#define PINOW3    6                // OW1 Bus pin number (single sensor TUSR1)
-#define PINOW4    7                // OW2 Bus pin number (single sensor TUSR2)
-#define PINSWMH   8                // SWMH pin number
-#define PINSWSH   9                // SWSH pin number
-#define PINSWUSR 12                // SWUSR pin number
-
-// sensors
-// masks for the ERRSENSOR parameter (use for error diagnostic)
-#define MASKTAMB   0b00000001
-#define MASKHAMB   0b00000010
-#define MASKTCOL   0b00000100
-#define MASKTEXT   0b00001000
-#define MASKTUSR1  0b00010000
-#define MASKTUSR2  0b00100000
-
-#define TEMPERATURE_RESOLUTION 12  // nb bits for DS18B20 sensors
-
-//=== DHT SENSOR MODEL ===
-#define DHTTYPE DHT11              // DHT 11
-//#define DHTTYPE DHT22            // DHT 22  (AM2302), AM2321
-
-// includes
-#include <avr/pgmspace.h>
-
-#include <Console.h>
-#include <Bridge.h>
-
-#include <DHT.h>
-#include <OneWire.h>
-#include <DallasTemperature.h>
-
-#include "ascutil.h"
-#include "ascdata.h"
-
-//-------1---------2---------3---------4---------5---------6---------7---------8
-// Ascdata objet - global access -- needed?
-Ascdata ascdata;
-
-/************************************************************/
-/***    PARAMETERS TYPE DECLARATION AND DEFAULT VALUES    ***/
-/************************************************************/
-
-// available types are :
-//   byte
-//   int            => TEMP
-//   unsigned long  => ULONG
-
-/*
- * Sensors
- */
-TEMP   TAMB;               // ambiant temperature (.01 degC)
-int    HAMB;               // humidity (0.01%)
-TEMP   TCOL;               // collector temperature (.01 degC)
-TEMP   TEXT;               // external temperature (.01 degC)
-TEMP   TUSR1;              // temperature user#1 (.01 degC)
-TEMP   TUSR2;              // temperature user#2 (.01 degC)
-
-/*
- * Calculated
- */
-int    NLOOPS = 0;         // number of loops per sec
-int    PSOLTH = 0;         // heating solar power (W)
-byte   SWSH = OFF;         // Solar heater switch (FAN)
-byte   SWMH = OFF;         // Main heater switch
-byte   SWUSR = OFF;        // user switch
-byte   STATESH = OFF;      // begin with the OFF state
-byte   STATEMH = OFF;      // begin with OFF state
-byte   STATECTRL = INIT;   // controller INIT state at power on
-byte   ERRSENSOR = 255;    // error status on sensor -- begin with error
-byte   ERRCTRL = 0;        // internal error id# -- go to STOP mode if != 0
-ULONG  INDSH = 0;          // Cumulative index of solar energy (Wh)
-ULONG  TCSH = 0;           // Cumulated time of SH usage (h)
-ULONG  TCMH = 0;           // Cumulated time of MH usage (h)
-
-/*
- * Controller parameters
- */
-TEMP   TSET = 2500;        // set point (.01 degC)
-TEMP   DTECO = 350;        // delta T eco (.01 degC)
-byte   MODESH = ON;        // mode solar heater
-byte   MODEMH = ON;        // mode main heater
-byte   TMHON = 5;          // min time main heater in ON state(s)
-byte   TMHOFF = 5;         // min time main heater in OFF state(s)
-byte   TSHON = 5;          // min time Fan in ON state (s)
-byte   TSHOFF = 5;         // min time Fan in OFF state (s)
-TEMP   DTSHON = 600;       // delta T Fan ON (.01 deg.C)
-TEMP   DTSHOFF = 300;      // delta T Fan OFF (.01 deg.C)
-TEMP   AUG1 = 200;         // Solar heater set point delta (.01 deg.C)
-TEMP   AUG2 =   0;         // Main heater set point delta (.01 deg.C)
-TEMP   TFP = 500;          // Freeze protection set point (.01 deg.C)
-TEMP   HYST = 100;         // Hysteresis parameter (.01 deg.C)
-int    VFAN = 200;         // Fan flow (cub.m/h)
-int    ASOLT = 4;          // Thermal collectors total area (sq.m)
-byte   CONF1 = 1;          // Air circulation configuration (1=External, 2=Recirculated) -- for INDSH calculation
-
-/************************************************************/
-/********** END PARAMETERS DEFAULT VALUES *******************/
-/************************************************************/
-
-// Define the x.hour counters
-Counterh counterhTCMH( TCMH );   // time usage main heater (h)
-Counterh counterhTCSH( TCSH );   // time usage solar heater (h)
-Counterh counterhINDSH( INDSH ); // estimated usefull solar energy (Wh)
-
-// Various timers - see usage in util.cpp
-// declare delays in millis
-Timer  timerOW( 750 / (1 << (12 - TEMPERATURE_RESOLUTION)) ); // min delay for DS18B20 convertion
-Timer  timerDHT( 2000 );          // DHT readout delay, may be reduced...
-Timer  timerMH( 0 );              // main heater time-in-state, begin with OFF state
-Timer  timerSH( 0 );              // solar heater time-in-state, begin with OFF state
-Timer  timerEEPROM( ONEHOURMS );  // update period of EEPROM data
-Timer  timerLED( 3456 );          // flash the LED
-Timer  timerBridge( 2000 );       // synchronize bridge data (i.e. commands responsivity...)
-
-// DHT sensor bus
-DHT dht(PINDHT, DHTTYPE);
-
-// 1-Wire buses & sensors
-OneWire ow1(PINOW1);    // for TCOL
-OneWire ow2(PINOW2);    // for TAMB
-OneWire ow3(PINOW3);    // for TUSR1
-OneWire ow4(PINOW4);    // for TUSR2
-
-DallasTemperature sensor1(&ow1);
-DallasTemperature sensor2(&ow2);
-DallasTemperature sensor3(&ow3);
-DallasTemperature sensor4(&ow4);
-
-/*
- * === setup() ===
- */
-void setup() {
-  // Set PinMode
-  pinMode( PINLED1, OUTPUT );
-  pinMode( PINDHT, OUTPUT ); // done after
-  pinMode( PINOW1, OUTPUT ); // done after
-  pinMode( PINOW2, OUTPUT ); // done after
-  pinMode( PINSWMH, OUTPUT );
-  pinMode( PINSWSH, OUTPUT );
-  pinMode( PINSWUSR, OUTPUT );
-
-  // setoutputs -- check STATECTRL = INIT
-  // done azap -- set switches in OFF position
-  STATECTRL = INIT; // force the INIT state
-  StateEngine();    // calculate the heaters states
-  SetOutputs();     // set the outputs
-
-  // bridge
-  Bridge.begin();   // start the script /usr/bin/run-bridge on the MPU side
-
-  // infos to the console by PrintInfo()
-  // only for debug purpose! It's waiting for the console for ever
-  BeginInfo();      // start the Console if CONSOLE if defined in util.h -- dev
-  PrintInfo('i', "Arduino Solar Controller - Kit, v%s", VERSION);
-
-  /************************************************************
-     WARNING:
-     THE DECLARATION ORDER DEFINES THE DATA STORAGE IN EEPROM
-     ANY CHANGE WILL PREVENT TO RETRIEVE THE STORED DATAS
-   ************************************************************/
-  //
-  // Parameters declaration
-  // ( pointer, label, options)
-  // options = "<access> <format>" (! only one space)
-  //   where <access> = {pgs}
-  //                  p: put the value to datastore
-  //                  g: get the value from datastore
-  //                  s: save the value into the EEPROM
-  //         <format> = f4.2 (xxxx.xx) i -- ipv4 (x.x.x.x)
-  //
-
-  // usr : user parameters
-  ascdata.par_F( &TSET,     F("tset"),     F("gs f4.2"));
-  ascdata.par_F( &DTECO,    F("dteco"),    F("gs f4.2"));
-  ascdata.par_F( &MODESH,   F("modesh"),   F("gs i"));
-  ascdata.par_F( &MODEMH,   F("modemh"),   F("gs i"));
-
-  // dev : device parameters
-  ascdata.par_F( &TMHON,    F("tmhon"),    F("gs i"));
-  ascdata.par_F( &TMHOFF,   F("tmhoff"),   F("gs i"));
-  ascdata.par_F( &TSHON,    F("tshon"),    F("gs i"));
-  ascdata.par_F( &TSHOFF,   F("tshoff"),   F("gs i"));
-  ascdata.par_F( &DTSHON,   F("dtshon"),   F("gs f4.2"));
-  ascdata.par_F( &DTSHOFF,  F("dtshoff"),  F("gs f4.2"));
-  ascdata.par_F( &AUG1,     F("aug1"),     F("gs f4.2"));
-  ascdata.par_F( &AUG2,     F("aug2"),     F("gs f4.2"));
-  ascdata.par_F( &TFP,      F("tfp"),      F("gs f4.2"));
-  ascdata.par_F( &HYST,     F("hyst"),     F("gs f4.2"));
-  ascdata.par_F( &VFAN,     F("vfan"),     F("gs i"));
-  ascdata.par_F( &ASOLT,    F("asolt"),    F("gs i"));
-  ascdata.par_F( &CONF1,    F("conf1"),    F("gs i"));
-
-  // Calculated
-  ascdata.par_F( &NLOOPS,   F("nloops"),   F("p i"));
-  ascdata.par_F( &PSOLTH,   F("psolth"),   F("p i"));
-  ascdata.par_F( &INDSH,    F("indsh"),    F("ps i"));     // update period tbd
-  ascdata.par_F( &TCMH,     F("tcmh"),     F("ps i"));     // update period tbd
-  ascdata.par_F( &TCSH,     F("tcsh"),     F("ps i"));     // update period tbd
-
-  // sensors & switches
-  ascdata.par_F( &TAMB,     F("tamb"),     F("p f4.2"));
-  ascdata.par_F( &HAMB,     F("hamb"),     F("p f4.2"));
-  ascdata.par_F( &TCOL,     F("tcol"),     F("p f4.2"));
-  ascdata.par_F( &TEXT,     F("text"),     F("p f4.2"));
-  ascdata.par_F( &TUSR1,    F("tusr1"),    F("p f4.2"));
-  ascdata.par_F( &TUSR2,    F("tusr2"),    F("p f4.2"));
-  ascdata.par_F( &SWSH,     F("swsh"),     F("p i"));
-  ascdata.par_F( &SWMH,     F("swmh"),     F("p i"));
-  ascdata.par_F( &SWUSR,    F("swusr"),    F("gs i"));     // user switch -- saved?
-
-  // states
-  ascdata.par_F( &STATEMH,  F("statemh"),  F("p i"));
-  ascdata.par_F( &STATESH,  F("statesh"),  F("p i"));
-  ascdata.par_F( &STATECTRL, F("statectrl"), F("p i"));
-
-  // errors
-  ascdata.par_F( &ERRSENSOR, F("errsensor"), F("p i"));
-  ascdata.par_F( &ERRCTRL,   F("errctrl"),   F("p i"));
-
-  /************************************************************/
-  /***************  END OF DECLARATION   **********************/
-  /************************************************************/
-  ascdata.getNpar(); // info on data usage if console activated -- dev
-
-  //
-  // Get configuration from EEPROM (if available and consistent with the present version (TAG10)
-  //
-  PrintInfo( 'i', F("Get EEPROM saves data..."));
-
-  if ( ascdata.EEPROM_get( TAG10, 0 ) != 0 ) {
-    // data structure not compatible
-    // Note: EEPROM is reset after a schetch upload => we write the default values
-    PrintInfo( 'w', F("EEPROM TAG error."));
-    // then update the EEPROM with the defaults values defined in the sketch
-    // counters values are reset
-    PrintInfo( 'i', F("Update EEPROM data with the sketch default values..."));
-    ascdata.EEPROM_put( TAG10, 0 );
-    // write the default values into EEPROM as well
-    ascdata.EEPROM_put( TAG10, 1 );
-  }
-  else {
-    // Data retrieved from the EEPROM are ok
-    // Update counters values
-    counterhTCMH.set( TCMH );
-    counterhTCSH.set( TCSH );
-    counterhINDSH.set( INDSH );
-  }
-
-  //
-  // 1-Wire Initialization
-  //
-  // Start up the library and define the resolution
-  // Define the Async mode
-  // Start a conversion
-  //
-  OWsensorBegin( sensor1 );
-  OWsensorBegin( sensor2 );
-  OWsensorBegin( sensor3 );
-  OWsensorBegin( sensor4 );
-
-  // Keys generation in datastore
-  //
-  // put all the data to create the keys
-  ascdata.bridgePut('*'); // create all the keys in datastore
-
-  // add the 'version' data
-  ascdata.bridgePutVersion( VERSION );
-
-  // add the 'request' data
-  ascdata.bridgePutRequest("none");
-
-  // start the controller
-  LedBlinkingN( PINLED1, 200, 4 ); // indicate that the INIT phase is finished
-  STATECTRL = RUN; // go into RUN state after power on
-
-  // setup() finished
-  PrintInfo( 'i', F("Starting loop()..."));
-}
-
-/*
- * === loop() ===
- */
-void loop() {
-  //
-  static int nloops = 0;
-  static Timer timerLoops( 1000 );
-  int index;
-
-  ReadSensors();
-  CalcParameters();
-  StateEngine();
-  SetOutputs();
-
-  // loop performance calculation
-  nloops++;
-  if ( timerLoops.check() ) {
-    NLOOPS = nloops; // nb loops per sec
-    nloops = 0;
-  }
-
-  if ( timerBridge.check() ) {
-    // Bridge synchronization
-    // do it only at low rate (~500ms), but may be optimized
-    //
-    // Retrieve data from datastore (bridge)
-    // We get only the 'g' access values
-    if ( ascdata.bridgeGet('g') != 0 ) {
-      ascdata.EEPROM_put( TAG10, 0 ); // update EEPROM data if some modifications in saved data
-      PrintInfo( 'i', F("EEPROM update due to datastore change"));
-    }
-
-    // Update the data into datastore (bridge)
-    // we only put the 'p' access values
-    // you should not have both 'p' and 'g' access for the same data...
-    ascdata.bridgePut('p');
-
-    // request handle
-    // see RequestHandle()
-    if (ascdata.bridgeGetRequest()) {
-      ascdata.bridgePutRequest("none"); // reset request into datastore
-      RequestHandle();                  // execute the request
-    }
-  }
-
-  if ( timerEEPROM.check() ) {
-    ascdata.EEPROM_put( TAG10, 0 ); // periodic update of EEPROM saved data (counters)
-    PrintInfo( 'i', F("timerEEPROM update."));
-  }
-}
-
-/*
- * === ReadSensors() ===
- */
-void ReadSensors() {
-  // read the sensors
-  // what if an error occur?
-  // no check for time serie (i.e. glitches)
-  float dhtval;
-
-  /////////////////////
-  // Read DHT sensor //
-  // TAMB & HAMB     //
-  /////////////////////
-  if ( timerDHT.check() ) {
-
-    dhtval = dht.readTemperature(); // default is Celsius
-    if (isnan(dhtval)) {
-      // FAIL
-      if ( IsSensorValid( MASKTAMB ) ) PrintInfo( 'w', F("Failed to read from DHT sensor TAMB!...")); // only once
-      ErrSensorRaise( MASKTAMB );
-    }
-    else {
-      if ( !IsSensorValid( MASKTAMB ) ) PrintInfo( 'i', F("DHT sensor TAMB ok...")); // only once
-      TAMB = int(100 * dhtval);
-      ErrSensorClear( MASKTAMB );
-    }
-
-    dhtval = dht.readHumidity();
-    if (isnan(dhtval)) {
-      // soft FAIL
-      if ( IsSensorValid( MASKHAMB ) ) PrintInfo( 'w', F("Failed to read from DHT sensor HAMB!...")); // only once
-      ErrSensorRaise( MASKHAMB );
-    }
-    else {
-      if ( !IsSensorValid( MASKHAMB ) ) PrintInfo( 'i', F("DHT sensor HAMB ok...")); // only once
-      HAMB = int(100 * dhtval);
-      ErrSensorClear( MASKHAMB );
-    }
-  }
-
-  ///////////////////////////
-  // Read OW1 Bus => TCOL  //
-  // Read OW2 Bus => TEXT  //
-  // Read OW3 Bus => TUSR1 //
-  // Read OW4 Bus => TUSR2 //
-  ///////////////////////////
-  if ( timerOW.check() ) {
-    //
-    // to do -- should add error messages
-    //
-    TCOL  = ReadOWbus( sensor1, MASKTCOL );
-    TEXT  = ReadOWbus( sensor2, MASKTEXT );
-    TUSR1 = ReadOWbus( sensor3, MASKTUSR1 );
-    TUSR2 = ReadOWbus( sensor4, MASKTUSR2 );
-  }
-}
-
-/*
- * === CalcParameters() ===
- */
-void CalcParameters() {
-  // Parameters calculation
-  PSOLTH = 0; // default value
-  if ( STATESH == ON ) {
-    // PSOLTH (W) -- check positive value
-    if ( CONF1 == 1 && TCOL > TEXT ) PSOLTH = int( 0.335 * VFAN * (TCOL - TEXT) / 100 ); // external air
-    if ( CONF1 == 2 && TCOL > TAMB ) PSOLTH = int( 0.335 * VFAN * (TCOL - TAMB) / 100 ); // recirculated
-  }
-
-  // counters calls for cumulative quantities
-  TCMH = int(counterhTCMH.add(1)); // time integration (h)
-  TCSH = int(counterhTCSH.add(1)); // time integration (h)
-  INDSH = int(counterhINDSH.add((unsigned long) PSOLTH)); // power integration (Wh)
-}
-
-/*
- * === StateEngine() ===
- */
-void StateEngine() {
-  //
-  // Define the controller state STATECTRL ( INTI - STOP - RUN - FAIL1 - FAIL2 ) -- INIT defined during setup()
-  // Define the heaters states: STATEMH & STATESH
-  // See SetOutputs()
-  //
-  // TO BE CHECKED -- correction FAIL2???
-  //
-  if ( STATECTRL == INIT ) {
-    STATEMH = OFF;
-    STATESH = OFF;
-  }
-  else if ( STATECTRL == STOP ) {
-    STATEMH = OFF;
-    STATESH = OFF;
-  }
-  else { // i.e. RUN, FAIL1 or FAIL2
-    if ( IsSensorValid(MASKTAMB)&& IsSensorValid(MASKTCOL) ) {
-      STATECTRL = RUN;
-      StateEngineMH();
-      StateEngineSH();
-    }
-    else if ( IsSensorValid(MASKTAMB)&& !IsSensorValid(MASKTCOL) ) {
-      STATECTRL = FAIL1;
-      StateEngineMH();
-      STATESH = OFF;
-    }
-    else {
-      STATECTRL = FAIL2; // ok?
-      STATEMH = OFF;
-      STATESH = OFF;
-    }
-  }
-
-  if ( ERRCTRL != 0 ) { // catch internal error => STOP
-    STATECTRL = STOP;
-    STATEMH = OFF;
-    STATESH = OFF;
-    // the only way to quit this mode is to reset the board or to send /data/put/request/run
-  }
-}
-
-/*
- * === StateEngineMH() ===
- */
-void StateEngineMH() {
-  // Main heater
-  boolean c1, c2, c3, c4;     // conditions
-  TEMP tsetmh;                // internal setpoint -- depends on MODEMH
-
-  // define tsetmh -- depends on MODEMH
-  switch ( MODEMH ) {
-    case HEAT:
-      tsetmh = TSET;
-      break;
-
-    case ECO:
-      tsetmh = TSET - DTECO;
-      break;
-
-    case FP:
-      tsetmh = TFP;
-      break;
-
-    default:
-      tsetmh = TSET;
-  }
-
-  switch ( STATEMH ) {
-    case OFF:
-      // compute the conditions to go ON
-      c1 = (MODEMH != OFF);
-      c2 = timerMH.check( 1000*TMHOFF );               // is minimum time in the OFF state?
-      c3 = (TAMB < tsetmh) && (STATESH == OFF);          // condition if STATESH = OFF
-      c4 = (TAMB < tsetmh - AUG2) && (STATESH == ON);    // condition if STATESH = ON
-
-      if ( c1 && c2 && (c3 || c4) ) {
-        PrintInfo('i', F("Main heater switched to ON"));
-        STATEMH = ON;
-        timerMH.start();                               // restart timer
-        counterhTCMH.run();                            // run time counter
-      }
-      break;
-
-    case ON:
-      // compute the conditions to go OFF
-      c1 = (MODEMH == OFF);
-      c2 = timerMH.check( 1000*TMHON );                      // is minimum time in the ON state?
-      c3 = (TAMB > tsetmh + HYST) && (STATESH == OFF);       // condition if STATESH = OFF
-      c4 = (TAMB > tsetmh + HYST - AUG2) && (STATESH == ON); // condition if STATESH = ON
-
-      if ( c1 || (c2 && (c3 || c4)) ) {
-        PrintInfo('i', F("Main heater switched to OFF"));
-        STATEMH = OFF;
-        timerMH.start();                              // restart timer
-        counterhTCMH.stop();                          // stop time counter
-      }
-      break;
-
-    default:
-      // error in software
-      ERRCTRL = 91; // at least... call the vendor! -- ERRCTRL = ???
-      PrintInfo('w', F("Internal error ERRCTRL=91"));
-  }
-}
-/*
- * ===stateEngineSH() ===
- */
-void StateEngineSH() {
-  // Solar heater
-  boolean c1, c2, c3, c4;     // conditions
-
-  switch ( STATESH ) {
-    case OFF:
-      // compute the conditions to go ON
-      c1 = (MODESH == ON);
-      c2 = timerSH.check( 1000*TSHOFF );               // is minimum time in the OFF state?
-      c3 = (TCOL > TAMB + DTSHON);                     // solar collector temp condition
-      c4 = (TAMB < TSET + AUG1);                       // ambiant condition
-
-      if ( c1 && c2 && c3 && c4 ) {
-        PrintInfo('i', F("Solar heater switched to HEAT"));
-        STATESH = ON;
-        timerSH.start();                               // restart timer
-        counterhINDSH.run();                           // run energy counter
-        counterhTCSH.run();                            // run time counter
-      }
-      break;
-
-    case ON:
-      // compute the conditions to go OFF
-      c1 = (MODESH == OFF);
-      c2 = timerSH.check( 1000*TSHON );                // is minimum time in the ON state?
-      c3 = (TCOL < TAMB + DTSHOFF);                    // solar collector temp condition
-      c4 = (TAMB > TSET + HYST + AUG1);                // ambiant condition
-
-      if ( c1 || (c2 && (c3 || c4)) ) {
-        PrintInfo('i', F("Solar heater switched to OFF"));
-        STATESH = OFF;
-        timerSH.start();                               // restart timer
-        counterhINDSH.stop();                          // stop energy counter
-        counterhTCSH.stop();                           // stop time counter
-      }
-      break;
-
-    default:
-      // error in software
-      ERRCTRL = 92; // at least... call the vendor!
-      PrintInfo('w', F("Internal error ERRCTRL=92"));
-  }
-}
-
-/*
- * SetOutputs()
- */
-void SetOutputs() {
-  //
-  // Set the outputs regarding to the controller state
-  // the controller state is defined in StateEngine()
-  //
-  // Set the heaters switches -- defined by STATEMH and STATESH
-
-  // main heater
-  if (STATEMH == ON) {
-    SWMH = ON;
-    digitalWrite( PINSWMH, HIGH );
-  }
-  else {
-    SWMH = OFF;
-    digitalWrite( PINSWMH, LOW );
-  }
-
-  // solar heater
-  if (STATESH == ON) {
-    SWSH = ON;
-    digitalWrite( PINSWSH, HIGH );
-  }
-  else {
-    SWSH = OFF;
-    digitalWrite( PINSWSH, LOW );
-  }
-
-  // switch user -- no error catch, simply copy the SWUSR value
-  if (SWUSR == HIGH) {
-    digitalWrite( PINSWUSR, HIGH );
-  }
-  else {
-    digitalWrite( PINSWUSR, LOW );
-  }
-  //
-  // set the LED1
-  switch ( STATECTRL ) {
-
-    case INIT:
-      // show LED1
-      LedBlinkingN( PINLED1, 100, 4 ); // 4 short pulses
-      digitalWrite( PINLED1, HIGH );   // lighted during INIT phase
-      break;
-
-    case STOP:
-      LedBlinkingN( PINLED1, 100, 5 ); // 5 pulses
-      break;
-
-    case RUN:
-      // run phase: switches controlled by the states
-      //LedBlinking( PINLED1, 100, &timerLED ); // RUN => short flash
-      LedGlowing( PINLED1, 6740, 20, 100 );
-      break;
-
-    case FAIL1:
-      LedBlinkingN( PINLED1, 100, 1 ); // one pulse
-      break;
-
-    case FAIL2:
-      LedBlinkingN( PINLED1, 100, 2 ); // two pulses
-      break;
-  }
-}
-
-/*
- *  === RequestHandle() ===
- */
-void RequestHandle() {
-  //
-  // Requests from datastore: data/put/request/request_type
-  //
-  // stop:          set STATECTRL to STOP
-  //+run:           set STATECTRL to RUN
-  // default:       retrieve the EEPROM values
-  //+setdefault:    copy the current values into the EEPROM (default values)
-  // rst_indsh:     reset the solar ventilation energy counter
-  // rst_tcsh:      reset the solar ventilation time counter
-  // rst_tcsh:      reset the main heater time counter
-  //
-
-  if ( ascdata.isRequest("stop") ) {
-    PrintInfo( 'i', F("request = stop"));
-    STATECTRL = STOP;
-  }
-
-  else if ( ascdata.isRequest("run") ) {
-    PrintInfo( 'i', F("request = run"));
-    STATECTRL = RUN;
-  }
-
-  else if ( ascdata.isRequest("default") ) {
-    PrintInfo( 'i', F("request = default"));
-
-    // get default data from EEPROM
-    // no need to check the TAG
-    ascdata.EEPROM_get( TAG10, 1 );
-    // update saved values
-     ascdata.EEPROM_put( TAG10, 0 );
-
-    // Update current counters values -- reset!
-    counterhTCMH.set( TCMH );
-    counterhTCSH.set( TCSH );
-    counterhINDSH.set( INDSH );
-    // update datastore -- otherwise, current datastore data will be retrieved!
-    ascdata.bridgePut('s'); // only the saved data are modified
-  }
-
-  else if ( ascdata.isRequest("setdefault") ) {
-    PrintInfo( 'i', F("request = setdefault"));
-    PrintInfo( 'i', F("EEPROM default data update with current values."));
-
-    // save current data into EEPROM default data
-    ascdata.EEPROM_put( TAG10, 1 );
-  }
-
-  else if ( ascdata.isRequest("rst_indsh") ) {
-    PrintInfo( 'i', F("request = rst_indsh"));
-
-    INDSH = 0;
-    counterhINDSH.set( INDSH );  // set the counter value
-
-    // save the values
-    PrintInfo( 'i', F("EEPROM update with current values."));
-    // update EEPROM data with current values
-    ascdata.EEPROM_put( TAG10, 0 );
-
-    // update datastore -- to be sure!
-    ascdata.bridgePut('s'); // only the saved data are modified
-  }
-
-  else if ( ascdata.isRequest("rst_tcmh") ) {
-    PrintInfo( 'i', F("request = rst_tcmh"));
-
-    TCMH = 0;
-    counterhTCMH.set( TCMH );  // set the counter value
-
-    // save the values
-    PrintInfo( 'i', F("EEPROM update with current values."));
-    // update EEPROM data with current values
-    ascdata.EEPROM_put( TAG10, 0 );
-
-    // update datastore -- to be sure!
-    ascdata.bridgePut('s'); // only the saved data are modified
-  }
-
-  else if ( ascdata.isRequest("rst_tcsh") ) {
-    PrintInfo( 'i', F("request = rst_tcsh"));
-
-    TCSH = 0;
-    counterhTCSH.set( TCSH );  // set the counter value
-
-    // save the values
-    PrintInfo( 'i', F("EEPROM update with current values."));
-    // update EEPROM data with current values
-    ascdata.EEPROM_put( TAG10, 0 );
-
-    // update datastore -- to be sure!
-    ascdata.bridgePut('s'); // only the saved data are modified
-  }
-
-  else {
-    PrintInfo('w', F("Undefined request"));
-  }
-
-/*
- * === end request handle ===
- */
-}
-
-// #############################
-// utilities for ERRSENSOR usage
-// #############################
-
-/*
- * IsSensorValid()
- */
-bool IsSensorValid( byte mask ) {
-  // Return true if the sensor is ok
-  return( (ERRSENSOR & mask) == 0 );
-}
-
-/*
- * ErrSensorRaise()
- */
-void ErrSensorRaise( byte mask ) {
-  // Raise an error on sensor
-  ERRSENSOR = ERRSENSOR | mask;
-}
-
-/*
- * ErrSensorClear()
- */
-void ErrSensorClear( byte mask ) {
-  // Clear error on sensor
-  ERRSENSOR = ERRSENSOR & ~mask;
-}
-
-// ################
-// 1-Wire utilities
-// ################
-
-/*
- * OWsensorBegin()
- */
-void OWsensorBegin(DallasTemperature sensor) {
-  // OW begin
-  // variable to get the device address of a 1-wire sensor
-  DeviceAddress deviceAddress;
-  //
-  sensor.begin();
-  if (sensor.getAddress(deviceAddress, 0)) {
-    sensor.setResolution(deviceAddress, TEMPERATURE_RESOLUTION);
-    sensor.setWaitForConversion(false);
-    sensor.requestTemperatures(); // start conversion
-  }
-}
-
-/*
- * ReadOWbus()
- */
-TEMP ReadOWbus( DallasTemperature sensor, byte masksensor ) {
-  // Get OW temperature data -- single device connected
-  TEMP temp;
-  //
-  temp = int(100 * sensor.getTempCByIndex(0));  // the unique sensor has index 0
-  sensor.requestTemperatures();                 // restart a conversion
-  // test for bad reading
-  if ( (TCOL > -5000) && (TCOL < 12500) ) {
-    ErrSensorClear( masksensor );
-  }
-  else {
-    ErrSensorRaise( masksensor );
-  }
-  return( temp );
-}
-


switch dont work with oled libs

switch dont work with oled libs

--- src/gps-oled-temp-controller.ino
+++ src/gps-oled-temp-controller.ino
@@ -2,194 +2,74 @@
 #include <SFE_MicroOLED.h>  // Include the SFE_MicroOLED library
 #include <DHT.h>
 #include <Adafruit_MLX90614.h>
+#include "Switch.h"

-#define PIN_RESET 255  //
+#define PIN_RESET 255  // MicroOLED
 #define DC_JUMPER 0  // I2C Addres: 0 - 0x3C, 1 - 0x3D - OLED Display

 #define DHTPIN D4
 #define DHTTYPE DHT22

+const byte buttonPin = D3; // Button Shield
+const int ledPin = BUILTIN_LED; // Wemos D1 Built-in LED
+
+int i =0;
+
+/////////////////////////////////////////////////////////////
+// Hardware Initialization
 Adafruit_MLX90614 mlx = Adafruit_MLX90614();
+DHT dht(DHTPIN, DHTTYPE);
+MicroOLED oled(PIN_RESET, DC_JUMPER);
+Switch button = Switch(buttonPin);
+/////////////////////////////////////////////////////////////

-DHT dht(DHTPIN, DHTTYPE);
-
-//////////////////////////////////
-// MicroOLED Object Declaration //
-//////////////////////////////////
-
-MicroOLED oled(PIN_RESET, DC_JUMPER);  // I2C Example
-
-// Use these variables to set the initial time
-int hours = 11;
-int minutes = 50;
-int seconds = 30;
-
-// How fast do you want the clock to spin? Set this to 1 for fun.
-// Set this to 1000 to get _about_ 1 second timing.
-const int CLOCK_SPEED = 1000;
-
-// Global variables to help draw the clock face:
-const int MIDDLE_Y = oled.getLCDHeight() / 2;
-const int MIDDLE_X = oled.getLCDWidth() / 2;
-
-int CLOCK_RADIUS;
-int POS_12_X, POS_12_Y;
-int POS_3_X, POS_3_Y;
-int POS_6_X, POS_6_Y;
-int POS_9_X, POS_9_Y;
-int S_LENGTH;
-int M_LENGTH;
-int H_LENGTH;
-
-unsigned long lastDraw = 0;
-
-void initClockVariables()
-{
-  // Calculate constants for clock face component positions:
-  oled.setFontType(0);
-  CLOCK_RADIUS = min(MIDDLE_X, MIDDLE_Y) - 1;
-  POS_12_X = MIDDLE_X - oled.getFontWidth();
-  POS_12_Y = MIDDLE_Y - CLOCK_RADIUS + 2;
-  POS_3_X  = MIDDLE_X + CLOCK_RADIUS - oled.getFontWidth() - 1;
-  POS_3_Y  = MIDDLE_Y - oled.getFontHeight()/2;
-  POS_6_X  = MIDDLE_X - oled.getFontWidth()/2;
-  POS_6_Y  = MIDDLE_Y + CLOCK_RADIUS - oled.getFontHeight() - 1;
-  POS_9_X  = MIDDLE_X - CLOCK_RADIUS + oled.getFontWidth() - 2;
-  POS_9_Y  = MIDDLE_Y - oled.getFontHeight()/2;
+void setup() {
+  Serial.begin(9600);
+  Wire.begin();
+  mlx.begin();
+  dht.begin();
+  // oled.begin();     // Initialize the OLED

-  // Calculate clock arm lengths
-  S_LENGTH = CLOCK_RADIUS - 2;
-  M_LENGTH = S_LENGTH * 0.7;
-  H_LENGTH = S_LENGTH * 0.5;
+  // oled.clear(PAGE); // Clear the display's internal memory
+  // oled.clear(ALL);  // Clear the library's display buffer
+  // oled.display();   // Display what's in the buffer (splashscreen)
+  pinMode(ledPin, OUTPUT);
+  digitalWrite(ledPin, LOW);
 }

-void setup()
-{
-  Wire.begin();
-
-  mlx.begin();
-
-  Serial.begin(9600);
-
-  Serial.println("\nI2C Scanner");
-  Serial.println("DHT22 Test!");
-
-  dht.begin();
-
-  oled.begin();     // Initialize the OLED
-  oled.clear(PAGE); // Clear the display's internal memory
-  oled.clear(ALL);  // Clear the library's display buffer
-  oled.display();   // Display what's in the buffer (splashscreen)
-
-  initClockVariables();
-
-  oled.clear(ALL);
-  drawFace();
-  drawArms(hours, minutes, seconds);
-  oled.display(); // display the memory buffer drawn
-}
-
-void loop()
-{
-  getTemp();
-
+void loop() {
+  button.poll();
+  // textExamples();  // Finally the text example
+  // printInitialScreen();
   // scanI2CDevices();

-  getTempMLX();
+  if(button.switched()) {
+    Serial.print("SWITHCED");
+    digitalWrite(ledPin, HIGH);
+  }
+  if (button.pushed()) {
+    Serial.print("pushed ");
+    Serial.print(++i);
+    Serial.print(" ");
+  }

-  // Check if we need to update seconds, minutes, hours:
-  if (lastDraw + CLOCK_SPEED < millis())
-  {
-    lastDraw = millis();
-    // Add a second, update minutes/hours if necessary:
-    updateTime();
-
-    // Draw the clock:
-    oled.clear(PAGE);  // Clear the buffer
-    drawFace();  // Draw the face to the buffer
-    drawArms(hours, minutes, seconds);  // Draw arms to the buffer
-    oled.display(); // Draw the memory buffer
+  if (button.longPress()) {
+    Serial.print("longPress ");
+    digitalWrite(ledPin, HIGH);
+    getTemp();
+    getTempMLX();
+   // printInitialScreen();
   }
-}

-// Simple function to increment seconds and then increment minutes
-// and hours if necessary.
-void updateTime()
-{
-  seconds++;  // Increment seconds
-  if (seconds >= 60)  // If seconds overflows (>=60)
-  {
-    seconds = 0;  // Set seconds back to 0
-    minutes++;    // Increment minutes
-    if (minutes >= 60)  // If minutes overflows (>=60)
-    {
-      minutes = 0;  // Set minutes back to 0
-      hours++;      // Increment hours
-      if (hours >= 12)  // If hours overflows (>=12)
-      {
-        hours = 0;  // Set hours back to 0
-      }
-    }
+  if (button.doubleClick()) {
+    Serial.print("doubleClick ");
+    // getTemp();
   }
-}

-// Draw the clock's three arms: seconds, minutes, hours.
-void drawArms(int h, int m, int s)
-{
-  double midHours;  // this will be used to slightly adjust the hour hand
-  static int hx, hy, mx, my, sx, sy;
-
-  // Adjust time to shift display 90 degrees ccw
-  // this will turn the clock the same direction as text:
-  h -= 3;
-  m -= 15;
-  s -= 15;
-  if (h <= 0)
-    h += 12;
-  if (m < 0)
-    m += 60;
-  if (s < 0)
-    s += 60;
-
-  // Calculate and draw new lines:
-  s = map(s, 0, 60, 0, 360);  // map the 0-60, to "360 degrees"
-  sx = S_LENGTH * cos(PI * ((float)s) / 180);  // woo trig!
-  sy = S_LENGTH * sin(PI * ((float)s) / 180);  // woo trig!
-  // draw the second hand:
-  oled.line(MIDDLE_X, MIDDLE_Y, MIDDLE_X + sx, MIDDLE_Y + sy);
-
-  m = map(m, 0, 60, 0, 360);  // map the 0-60, to "360 degrees"
-  mx = M_LENGTH * cos(PI * ((float)m) / 180);  // woo trig!
-  my = M_LENGTH * sin(PI * ((float)m) / 180);  // woo trig!
-  // draw the minute hand
-  oled.line(MIDDLE_X, MIDDLE_Y, MIDDLE_X + mx, MIDDLE_Y + my);
-
-  midHours = minutes/12;  // midHours is used to set the hours hand to middling levels between whole hours
-  h *= 5;  // Get hours and midhours to the same scale
-  h += midHours;  // add hours and midhours
-  h = map(h, 0, 60, 0, 360);  // map the 0-60, to "360 degrees"
-  hx = H_LENGTH * cos(PI * ((float)h) / 180);  // woo trig!
-  hy = H_LENGTH * sin(PI * ((float)h) / 180);  // woo trig!
-  // draw the hour hand:
-  oled.line(MIDDLE_X, MIDDLE_Y, MIDDLE_X + hx, MIDDLE_Y + hy);
-}
-
-// Draw an analog clock face
-void drawFace()
-{
-  // Draw the clock border
-  oled.circle(MIDDLE_X, MIDDLE_Y, CLOCK_RADIUS);
-
-  // Draw the clock numbers
-  oled.setFontType(0); // set font type 0, please see declaration in SFE_MicroOLED.cpp
-  oled.setCursor(POS_12_X, POS_12_Y); // points cursor to x=27 y=0
-  oled.print(12);
-  oled.setCursor(POS_6_X, POS_6_Y);
-  oled.print(6);
-  oled.setCursor(POS_9_X, POS_9_Y);
-  oled.print(9);
-  oled.setCursor(POS_3_X, POS_3_Y);
-  oled.print(3);
+  if (button.released()) {
+    Serial.print("released\n");
+    digitalWrite(ledPin, LOW);
+  }
 }

 void getTemp() {
@@ -237,16 +117,14 @@
   Serial.println("Scanning...");

   nDevices = 0;
-  for(address = 1; address < 127; address++ )
-  {
+  for(address = 1; address < 127; address++ ) {
     // The i2c_scanner uses the return value of
     // the Write.endTransmisstion to see if
     // a device did acknowledge to the address.
     Wire.beginTransmission(address);
     error = Wire.endTransmission();

-    if (error == 0)
-    {
+    if (error == 0) {
       Serial.print("I2C device found at address 0x");
       if (address<16)
         Serial.print("0");
@@ -255,8 +133,7 @@

       nDevices++;
     }
-    else if (error==4)
-    {
+    else if (error == 4) {
       Serial.print("Unknow error at address 0x");
       if (address<16)
         Serial.print("0");
@@ -272,7 +149,6 @@
 }

 void getTempMLX() {
-  {
   Serial.print("MLX Ambient = ");
   Serial.print(mlx.readAmbientTempC());
   Serial.print("*C\tMLX Object = ");
@@ -285,6 +161,22 @@
   Serial.println("*F");

   Serial.println();
-  delay(1000);
+  delay(2000);
 }
+
+void printInitialScreen()
+{
+  String title = "PPSmart";
+
+  int middleX = oled.getLCDWidth() / 2;
+  int middleY = oled.getLCDHeight() / 2;
+
+  oled.clear(PAGE);
+  oled.setFontType(1);
+  // oled.setCursor(middleX - (oled.getFontWidth() * (title.length() / 2)), middleY - (oled.getFontWidth() / 2));
+  oled.setCursor(0, middleY - (oled.getFontWidth() / 2));
+  oled.print(title);
+  oled.display();
+
+
 }


update comments

update comments

--- Arduino/Neutrino_Wand/Neutrino_Wand.ino
+++ Arduino/Neutrino_Wand/Neutrino_Wand.ino
@@ -20,10 +20,14 @@
 #define NEO_WAND 4 // for nose of wand
 Adafruit_NeoPixel wandLights = Adafruit_NeoPixel(4, NEO_WAND, NEO_GRB + NEO_KHZ800);

-// LED indexes into the neopixel powerstick chain for the cyclotron
+// LED indexes into the neopixel powerstick chain for the cyclotron. Each stick has 8 neopixels for a total of
+// 16 with an index starting at 0. These offsets are because my powercell window only shows 13 leds. If you can show more
+// change the offset index and powercell count to get more or less lit.
 const int powercellLedCount = 14;                                         // total number of led's in the animation
 const int powercellIndexOffset = 1;                                       // first led offset into the led chain for the animation

+// These are the indexes for the led's on the chain. Each jewel has 7 LEDs. If you are using a single neopixel or
+// some other neopixel configuration you will need to update these indexes to match where things are in the chain
 const int c1Start = 16;
 const int c1End = 22;
 const int c2Start = 23;


Use enum instead of number

Use enum instead of number

--- ArduinoMazeSolver/ArduinoMazeSolver.ino
+++ ArduinoMazeSolver/ArduinoMazeSolver.ino
@@ -277,7 +277,7 @@
 	path[pathLength + 1] = none;
 	pathPositionInLaterRun = 0;
 	isFirstRun = false;
-	if (path[pathPositionInLaterRun] == (unsigned char)3)
+	if (path[pathPositionInLaterRun] == backward)
 	{
 		direction = backward;
 		pathPositionInLaterRun++;


Add basic support for send and receive commands

--- arduino/rflink/rflink.ino
+++ arduino/rflink/rflink.ino
@@ -31,7 +31,7 @@

 typedef struct {
     uint8_t len;
-    uint8_t data[64];
+    uint8_t data[63];
 } buffer_t;

 static buffer_t buffers[9];
@@ -105,10 +105,97 @@
     return 0;
 }

+static uint8_t hexdigit(char c)
+{
+    if (c >= 'a') {
+        return c - 'a' + 10;
+    } else if (c >= 'A') {
+        return c - 'A' + 10;
+    } else {
+        return c - '0';
+    }
+}
+
+static int decode_hex(char *s, uint8_t *buf, int size)
+{
+    int len = strlen(s);
+    if ((len % 2) != 0) {
+        return 0;
+    }
+    if ((len / 2) > size) {
+        return 0;
+    }
+    for (int i = 0; i < len; i +=2) {
+        uint8_t b = (hexdigit(s[i]) << 4) + hexdigit(s[i + 1]);
+        *buf++ = b;
+    }
+    return len / 2;
+}
+
+static int do_send(int argc, char *argv[])
+{
+    if (argc != 4) {
+        return -1;
+    }
+    uint8_t node = atoi(argv[1]);
+    uint8_t type = atoi(argv[2]);
+    uint8_t buf[64];
+    int len = decode_hex(argv[3], buf, sizeof(buf));
+    if (len < 0) {
+        Serial.println("invalid hex");
+        return -1;  // TODO BSI sensible error code
+    }
+
+    fill_buffer(node, type, len, buf);
+
+    Serial.print(argv[0]);
+    Serial.println(" 00");
+    return 0;
+}
+
+static void printhex(uint8_t *rcv, int len)
+{
+    for (int i = 0; i < len; i++) {
+        uint8_t b = rcv[i];
+        Serial.print((b >> 4) & 0xF, HEX);
+        Serial.print((b >> 0) & 0xF, HEX);
+    }
+}
+
+static int do_recv(int argc, char *argv[])
+{
+    if (argc != 2) {
+        return -1;
+    }
+    uint8_t node = atoi(argv[1]);
+    buffer_t *buf = &buffers[node];
+    if (buf->len == 0) {
+        // nothing to read
+        Serial.println("no data");
+        return -1;
+    }
+
+    uint8_t dest = buf->data[0];
+    uint8_t type = buf->data[2];
+
+    Serial.print(argv[0]);
+    Serial.print(" ");
+    Serial.print(dest, HEX);
+    Serial.print(" ");
+    Serial.print(type, HEX);
+    Serial.print(" ");
+    printhex(buf->data, buf->len);
+    Serial.println("");
+
+    return 0;
+}
+
 static const cmd_t commands[] = {
     {"help",    do_help,    "lists all commands"},
     {"id",      do_id,      "[id] gets/sets the node id"},
     {"ping",    do_ping,    "[node] sends a ping to node"},
+    {"s",       do_send,    "[node] [type] [data] sends data"},
+    {"r",       do_recv,    "[node] returns data from buffer"},
     {"", NULL, ""}
 };

@@ -217,19 +304,18 @@
         default:
             // copy data into buffer and indicate reception
             buffer_t *buf = &buffers[node];  // TODO BSI check node in range
-            memcpy(&buf->data, buf, len);
+            memcpy(&buf->data, rcv, len);
+            buf->len = len;

             Serial.print("!r ");
             Serial.print(node, HEX);
             Serial.print(" ");
+            Serial.print(flags, HEX);
+            Serial.print(" ");
             Serial.println(len);

             Serial.print("Got:");
-            for (int i = 0; i < len; i++) {
-                uint8_t b = rcv[i];
-                Serial.print((b >> 4) & 0xF);
-                Serial.print((b >> 0) & 0xF);
-            }
+            printhex(rcv, len);
             Serial.println(".");
             break;
         }


Added some default behavior and notes

Added some default behavior and notes

--- arduino/semSim/semSim.ino
+++ arduino/semSim/semSim.ino
@@ -2,6 +2,21 @@
   Forked frin Serial Event example

   http://www.arduino.cc/en/Tutorial/SerialEvent
+
+  (Line feed, '\n', 0x0A, 10 in decimal <----
+  CR (Carriage return, '\r', 0x0D, 13 in decimal)
+  (CR+LF, '\r\n', 0x0D0A)
+
+  **************
+  Command Format
+  **************
+  <LF>OP[_arg1,]<CR>
+    <LF>:   Line Feed
+    OP:     Operation
+    arg1...: Argument for command
+    <CR>: Carriage return code; a terminator signifying the end of a command
+    _: Space code: used to separate between the command and argument or between arguments
+

  */

@@ -34,7 +49,7 @@
     //Serial.println(inputCommand);
     //Serial.println(inputValue);

-    switch (var) {
+    switch (res) {
       case 0:
         // No Error
         break;
@@ -54,6 +69,7 @@
         break;
       default:
         // statements
+        Serial.print("!3 "+ inputString);
     }

     // clear the string:


Multiple LEDs

Multiple LEDs

--- map/map.ino
+++ map/map.ino
@@ -8,11 +8,10 @@
 IPAddress gateway(192,168,0,255); // network gateway address
 IPAddress subnet(255,255,255,0); // network subnet mask

-const int led = 13;
-
-const int LED01 = D5;
-const int LED02 = D6;
-const int LED03 = D7;
+const int LED01 = D1;
+const int LED02 = D2;
+const int LED03 = D3;
+const int LED04 = D4;

 void handleRoot() {
     digitalWrite(LED01, 1);
@@ -62,22 +61,52 @@
                 message = "At location3";
                 led = LED03;
                 break;
+            case 4:
+                message = "At location4";
+                led = LED04;
+                break;
             default:
                 message = "location Argument = ";
                 message += server.arg("location");
         }

     }
-    digitalWrite(led, LOW);
+    light_led(led);
     server.send(200, "text/plain", message);     //Returns the HTTP response

     delay(1000);
     digitalWrite(LED01, HIGH);
 }

+void light_led(int led){
+    digitalWrite(LED01, LOW);
+    digitalWrite(LED02, LOW);
+    digitalWrite(LED03, LOW);
+    digitalWrite(LED04, LOW);
+
+    digitalWrite(led, HIGH);
+}
+
+void flashAll(){
+    digitalWrite(LED01, HIGH);
+    digitalWrite(LED02, HIGH);
+    digitalWrite(LED03, HIGH);
+    digitalWrite(LED04, HIGH);
+
+    delay(100);
+
+    digitalWrite(LED01, LOW);
+    digitalWrite(LED02, LOW);
+    digitalWrite(LED03, LOW);
+    digitalWrite(LED04, LOW);
+}
+
 void setup(void){
     pinMode(LED01, OUTPUT);
-    digitalWrite(LED01, HIGH);
+    pinMode(LED02, OUTPUT);
+    pinMode(LED03, OUTPUT);
+    pinMode(LED04, OUTPUT);
+
     Serial.begin(115200);
     WiFi.begin(ssid, password);
     Serial.println("");
@@ -92,6 +121,8 @@
     Serial.println(ssid);
     Serial.print("IP address: ");
     Serial.println(WiFi.localIP());
+
+    flashAll();

 //    if (MDNS.begin("esp8266")) {
 //        Serial.println("MDNS responder started");


Z axis support

Z axis support

--- src/miscr.ino
+++ src/miscr.ino
@@ -206,7 +206,9 @@
     Serial.print(globalPos.x);
     Serial.print(" Y: ");
     Serial.print(globalPos.y);
-    Serial.print(" Z: N/A E: N/A");
+    Serial.print(" Z: ");
+    Serial.print(globalPos.z);
+    Serial.print(" E: N/A");
     Serial.print(" // ");
     Serial.println(info);
     //Serial.println("");
@@ -438,29 +440,61 @@
     if(yindex != INT_MIN)
       in = trim(in);

+    int zindex = getIndex('Z', in);
+
+    if(zindex != INT_MIN)
+      in = trim(in);
+
     int findex = getIndex('F', in);

     if(findex != INT_MIN) {
-      if(xindex != INT_MIN && yindex == INT_MIN) {
+      /*
+       * Just to keep myself right...
+       * Checked:
+       * When only X is specified *
+       * When only Y is specified *
+       * When only Z is specified *
+       * When only X and Y are specified *
+       * When only Y and Z are specified *
+       * When only X and Z are specified *
+       * When X, Y and Z are specified *
+       */
+      if(xindex != INT_MIN && yindex == INT_MIN && zindex == INT_MIN) {
         // Temporarily replace globalDelay value and calculate distance for X
         globalDelay.val = calc1DFeedrate(findex, xindex);
-      } else if(xindex == INT_MIN && yindex != INT_MIN) {
+      } else if(xindex == INT_MIN && yindex != INT_MIN && zindex == INT_MIN) {
         // Temporarily replace globalDelay value and calculate distance for X
         globalDelay.val = calc1DFeedrate(findex, yindex);
-      } else if(xindex != INT_MIN && yindex != INT_MIN) {
-        // Temporarily replace globalDelay value and calculate distanc
+      } else if(xindex == INT_MIN && yindex == INT_MIN && zindex != INT_MIN) {
+        // When only Z is specified
+        globalDelay.val = calc1DFeedrate(findex, zindex);
+      } else if(xindex != INT_MIN && yindex != INT_MIN && zindex == INT_MIN) {
+        // Temporarily replace globalDelay value and calculate distance
         // from the current position to the position specified
         globalDelay.val = calc2DFeedrate(findex, xindex, yindex);
-      } else if(xindex == INT_MIN && yindex == INT_MIN) {
+      } else if(xindex == INT_MIN && yindex != INT_MIN && zindex != INT_MIN) {
+        // When only Y and Z are specified
+        globalDelay.val = calc2DFeedrate(findex, yindex, zindex);
+      } else if(xindex != INT_MIN && yindex == INT_MIN && zindex != INT_MIN) {
+        // When only X and Z are specified
+        globalDelay.val = calc2DFeedrate(findex, xindex, zindex);
+      } else if(xindex != INT_MIN && yindex != INT_MIN && zindex != INT_MIN) {
+        // When X, Y and Z are specified
+        globalDelay.val = calc3DFeedrate(findex, xindex, yindex, zindex);
+      } else if(xindex == INT_MIN && yindex == INT_MIN && zindex == INT_MIN) {
         // TODO Permanently replace globalDelay default value
         // globalDelay.defaultVal = findex;
+      } else {
+        out.msg(1, "Invalid Syntax for Feedrate Parameter");
+        return false;
       }
     }

     if(xindex != INT_MIN) sX.testSpin(xindex);
     if(yindex != INT_MIN) sY.testSpin(yindex);
-
-    if(xindex == INT_MIN && yindex == INT_MIN) {
+    if(zindex != INT_MIN) sZ.testSpin(zindex);
+
+    if(xindex == INT_MIN && yindex == INT_MIN && zindex == INT_MIN && findex == INT_MIN) {
       out.msg(1, "No parameters/Invalid values for G0/G1");
       return false;
     }
@@ -469,16 +503,21 @@
   } else if(gindex == 28) {
     int xindex = in.indexOf("X");
     int yindex = in.indexOf("Y");
-
-    if(xindex == -1 && yindex == -1) {
+    int zindex = in.indexOf("Z");
+
+    if(xindex == -1 && yindex == -1 && zindex == -1) {
       if(globalPos.x != 0)
         sX.testSpin(globalPos.x - (globalPos.x * 2));
       if(globalPos.y != 0)
         sY.testSpin(globalPos.y - (globalPos.y * 2));
+      if(globalPos.z != 0)
+        sZ.testSpin(globalPos.z - (globalPos.z * 2));
     } else if(xindex != -1 && globalPos.x != 0) {
       sX.testSpin(globalPos.x - (globalPos.x * 2));
     } else if(yindex != -1 && globalPos.y != 0) {
       sY.testSpin(globalPos.y - (globalPos.y * 2));
+    } else if(zindex != -1 && globalPos.z != 0) {
+      sZ.testSpin(globalPos.z - (globalPos.z * 2));
     }

     return true;
@@ -501,7 +540,12 @@
     if(yindex != INT_MIN)
       sY.pos = yindex;

-    if(xindex == INT_MIN && yindex == INT_MIN) {
+    float zindex = getIndex('Z', in);
+
+    if(zindex != INT_MIN)
+      sZ.pos = zindex;
+
+    if(xindex == INT_MIN && yindex == INT_MIN && zindex == INT_MIN) {
       sX.pos = 0;
       sY.pos = 0;
       sZ.pos = 0;
@@ -561,11 +605,13 @@
     // Disable all stepper motors
     sX.disable();
     sY.disable();
+    sZ.disable();
     // TODO add more motors
   } else if(mindex == 18) {
     // Enable all stepper motors
     sX.enable();
     sY.enable();
+    sZ.enable();
     // TODO add more motors
   } else if(mindex == 300) {
     // Beep sound
@@ -681,14 +727,19 @@
   lcd.print("X: ");
   lcd.print(globalPos.x);

-  lcd.setCursor(0, 1);
+  lcd.print(" ");

   lcd.print("Y: ");
   lcd.print(globalPos.y);
+
+  lcd.setCursor(0, 1);
+
+  lcd.print("Z: ");
+  lcd.print(globalPos.z);
 }

 int updateLCD() {
-  if(sX.prevpos == globalPos.x || sY.prevpos == globalPos.y) {
+  if(sX.prevpos == globalPos.x || sY.prevpos == globalPos.y || sZ.prevpos == globalPos.z) {
     return -1;
   }

@@ -709,6 +760,7 @@
 void updatePos() {
   globalPos.x = sX.pos;
   globalPos.y = sY.pos;
+  globalPos.z = sZ.pos;

   //updateLCD();
 }
@@ -729,6 +781,7 @@
   // Initialise motors
   sX.begin();
   sY.begin();
+  sZ.begin();
 }

 void loop() {
@@ -736,6 +789,7 @@
     getSerialInput();
     sX.updateLoop();
     sY.updateLoop();
+    sZ.updateLoop();
     fanOn(temperature.operation);
     updatePos();
   } else {


Nevermind, just disconnect. It should send the control message first anyway.

--- rp6control/rp6control.ino
+++ rp6control/rp6control.ino
@@ -190,6 +190,7 @@
           SendMessage(client[j], "CONTROL:GRANTED");
         } else { // message was wrong (not CONTROL:)
           SendMessage(client[j], "ACCESS:DENIED");
+          client[j].stop();
         }
       } else { // if client is not the controller and the controller is already set
         SendMessage(client[j], "ACCESS:DENIED");


1.0 fixes reverted to previous gps.encode reading style seperated out  gps check , to check at fixed interval (30 seconds) created variables for possible "miles per hour" checking

--- LART1.ino
+++ LART1.ino
@@ -35,7 +35,7 @@
 #include "Log.h"
 #include "SD.h"

-#define VERSION "Beta-0.999m"
+#define VERSION "Beta-0.999n"
 #define ADC_REFERENCE REF_5V
 #define DEBUG_APRS_SETTINGS false

@@ -370,22 +370,23 @@
    pinMode(LED_GPS,OUTPUT) ;

    digitalWrite(LED_TX,HIGH) ;
+   digitalWrite(LED_RX,LOW);
+   digitalWrite(LED_GPS,LOW) ;
+   delay(800) ;
+   digitalWrite(LED_TX,LOW);
    digitalWrite(LED_RX,HIGH) ;
+   digitalWrite(LED_GPS,LOW);
+   delay(800) ;
+   digitalWrite(LED_TX,LOW) ;
+   digitalWrite(LED_RX,LOW) ;
    digitalWrite(LED_GPS,HIGH) ;
-   delay(750) ;
-   digitalWrite(LED_TX,LOW);
-   digitalWrite(LED_RX,LOW);
-   digitalWrite(LED_GPS,LOW);
-   delay(750) ;
-   digitalWrite(LED_TX,HIGH) ;
-   digitalWrite(LED_RX,HIGH) ;
-   digitalWrite(LED_GPS,HIGH) ;
-   delay(750) ;
+   delay(800) ;
    digitalWrite(LED_TX,LOW) ;
    digitalWrite(LED_RX,LOW) ;
    digitalWrite(LED_GPS,LOW) ;

 }
+

 void setup()
@@ -528,63 +529,54 @@

 char  lat[] =  "0000.00N" ;
 char  lon[] = "00000.00W" ;
+double latd = 0.0 ;
+double lond = 0.0 ;
+
+char  prevlat[] =  "0000.00N" ;
+char  prevlon[] = "00000.00W" ;
+double prevlatd = 0.0 ;
+double prevlond = 0.0 ;
+
 int alt = 0 ;
+
 bool position_changed = false ;
 bool lastpositionsent = false ;
-char  prevlat[] =  "0000.00N" ;
-char  prevlon[] = "00000.00W" ;

 void loop()
 {

-   // process the gps packets
-   while(serialgps->available() > 0 ) gps.encode(serialgps->read()) ;
-
-   // check location every 3 seconds
-
-   if ( (millis() - lastgpsupdate) > 3000 ) {
-
-       lastgpsupdate = millis() ;
-
+// process the gps packets
+while(serialgps->available() > 0 ) {
+
+   if ( gps.encode( serialgps->read() ) )

        if( gps.location.isValid() ) {
           double dmh ;
+           latd = gps.location.lat() ;
+           lond = gps.location.lng() ;
            // latitude
            if ( gps.location.rawLat().negative ) {
-               dmh = ddtodmh( -gps.location.lat() )  ;
+               dmh = ddtodmh( -latd )  ;
                dtostrf(dmh,7,2,lat) ;
                lat[7] = 'S';
            } else {
-               dmh = ddtodmh( gps.location.lat() )  ;
+               dmh = ddtodmh( latd )  ;
                dtostrf(dmh,7,2,lat) ;
                lat[7] = 'N';
            }
            // longitude
            if ( gps.location.rawLng().negative ) {
-               dmh = ddtodmh( -gps.location.lng() )  ;
+               dmh = ddtodmh( -lond )  ;
                dtostrf(dmh,8,2,lon) ;
                lon[8] = 'W';
            } else {
-               dmh = ddtodmh(gps.location.lng() )  ;
+               dmh = ddtodmh(lond )  ;
                dtostrf(dmh,8,2,lon) ;
                lon[8] = 'E';
            }
-
-
-           // position change
-           //  1 100th-second = 60 feet @ 38 lat
-           //  1 100th-second = 48 feet @  lon (fairly constant)
-           // set a precision value to compare
-           if ( strncmp(lat, prevlat, POSITION_CHANGE_PRECISION) != 0 ) {
-               strcpy(prevlat,lat) ;
-               position_changed = true ;
-           }
-           if ( strncmp(lon, prevlon, POSITION_CHANGE_PRECISION + 1 ) != 0 ) {
-               strcpy(prevlon,lon) ;
-               position_changed = true ;
-           }
+
        } // end lat lon update

            // altitude
@@ -592,7 +584,43 @@
            alt = (int) gps.altitude.feet() ;
        } // end altitude update

-    } // end gps check
+} // end readgps
+
+   // check if position has changed
+   if ( ( millis() - lastgpsupdate )   >   30000  ) {
+           lastgpsupdate = millis() ;
+           // position change
+           //  1 100th-second = 60 feet @ 38 lat
+           //  1 100th-second = 48 feet @  lon (fairly constant)
+           // for precision "6" , 13 miles per hour
+           /*
+           // calculate distance (in miles)
+           double distM  = TinyGPSPlus.distanceBetween(latd,lond, prevlatd, prevlond) * 0.6214 ;
+
+           // convert to MPH
+           double mph = ( distM / 15 ) * 3600 ;
+
+           if ( mph > 8.0 ) {
+
+           }
+           */
+
+
+           if ( strncmp(lat, prevlat, POSITION_CHANGE_PRECISION) != 0 ) {
+               strcpy(prevlat,lat) ;
+               prevlatd = latd ;
+               position_changed = true ;
+           }
+
+
+           if ( strncmp(lon, prevlon, POSITION_CHANGE_PRECISION + 1 ) != 0 ) {
+               strcpy(prevlon,lon) ;
+               prevlond = lond ;
+               position_changed = true ;
+           }
+   }
+
+

    // outer update check loop


Finish StanBox.ino

Finish StanBox.ino

--- examples/StanBox/StanBox.ino
+++ examples/StanBox/StanBox.ino
@@ -1,7 +1,7 @@
 //
-// LED7Seg Demo Example
+// Robotics PWM Motor Controller
 //
-// Copyright (C) 2016 Lennie Araki. All rights reserved
+// Copyright (C) 2016-2020 Lennie Araki. All rights reserved
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -17,44 +17,63 @@
 //
 // This example demonstrates the functionality of the LED7Seg library
 // optimized for a 3 or 4 digit display.
-//
-// It cycles through 4 different modes based on time "counter":
-//
-//  0-19.9   Shows graphic segment test (A-F,DP) digit-by-digit
-//  20-39.9  Shows scrolling text message
-//  40-59.9  Shows encoder as signed X.YY number
-//  60-79.9  Shows counter as unsigned hexadecimal number
-//  80-99.9  Shows time in as XX.Y seconds
+//
+// It creates a PWM output on pins D10,D11 compatible with Talon, TalonSRX
+// and SparkMax FRC motor controllers
+//
+// It monitors the battery voltage on A7:
+//            2.2K             1.0K
+//  VIN  ----/\/\/\-----o-----/\/\/\-------|>
+//                      |
+//                      A7
+// User input is set using a quadrature rotary encoder on D2-D3
+// Power is -1.00..+1.00 corresponding to:
+//     1.0 msec (full rev)
+//     1.5 msec (stop)
+//     2.0 msec (full fwd)
 //
 #include "LED7Seg.h"
+#include <Servo.h>

 #define LEDFONT

-using namespace LED;
+#define MODE_PIN        0     // RXD
+#define ENC_PIN         2     // Pins D2 & D3
+#define PWM_OUT         10
+
+#define MIN_POWER       -100  // -100%
+#define MAX_POWER       +100  // +100%

 SevSeg led7seg;        //Instantiate LED7Seg object
 #define LED_DIGITS      4

-// Arduino UNO
-//const byte ledPins[] = { /*segA-F+DP=*/ 2, 3, 4, 5, 6, 7, 8, 9, /*dig1-4=*/ 10, 11, 12, 13};
+Servo pwmOut;

-//		  D1  A  F D2 D3  B
-//      +--o--o--o--o--o--o--+
-//		| D4 D5 D6 D7 D8 D9  |
-//		|    Arduino Nano    |
-//      | A5 A4 A3 A2 A1 A0  |
-//      +--o--o--o--o--o--o--+
-//         E  D DP  C  G D4
+//           MOD         ENA ENB D1   A   F  D2  D3   B
+//      +-o---o---o---o---o---o---o---o---o---o---o---o---o---o---o-+
+//	    |TX0 RX1 RST GND D2  D3| D4  D5  D6  D7  D8  D9| D10 D11 D12|
+//	    |                      |     Arduino Nano      |            |
+//      |VIN GND RST 5V  A7  A6| A5  A4  A3  A2  A1  A0|REF 3V3 D13 |
+//      +-o---o---o---o---o---o---o---o---o---o---o---o---o---o---o-+
+//                       AIN BAT  E   D  DP   C   G  D4
 const byte ledPins[] = { /*segA-F+DP=*/ 5, 9, A2, A4, A5, 6, A1, A3, /*dig1-4=*/ 4, 7, 8, A0};

 void setup()
 {
+    Serial.begin(57600);
+    pinMode(MODE_PIN, INPUT_PULLUP);
+
+    analogReference(DEFAULT);
     led7seg.begin(COMMON_CATHODE, LED_DIGITS, ledPins);
-
-    pinMode(A6, INPUT);
-    pinMode(A7, INPUT);
-    digitalWrite(A6, HIGH);		// Turn on pullup for A6
-    digitalWrite(A7, HIGH);		// Turn on pullup for A7
+	  pinMode(LED_BUILTIN, OUTPUT);
+    pinMode(A6, INPUT_PULLUP);
+    pinMode(A7, INPUT_PULLUP);
+    pinMode(2, INPUT);
+    pinMode(3, INPUT);
+    digitalWrite(2, HIGH);    // Turn on pullup for D2
+    digitalWrite(3, HIGH);    // Turn on pullup for D3
+
+    pwmOut.attach(PWM_OUT);
 }

 uint8_t old_AB;
@@ -63,64 +82,91 @@
 /* returns change in encoder state (-1,0,1) */
 int8_t read_encoder()
 {
-	// remember previou state and ORin new state
-	old_AB = (old_AB << 2) | (PINC & 0x03); //remember previous state
+	// remember previous state and ORin new state
+  uint8_t enc_bits = (PIND >> ENC_PIN) & 0x03;
+	old_AB = (old_AB << 2) | enc_bits; //remember previous state
 	return enc_states[old_AB & 0x0f];
 }

+int counter = 0;
+int16_t analogin = 0;
+
+static unsigned long ten_msec = millis();
+
+void splash()
+{
+    int8_t segment = counter & 7;
+    int8_t digit = (counter / 8) % LED_DIGITS;
+    for (uint8_t d = 0; d < LED_DIGITS; ++d)
+    {
+        enum led_seg raw[LED_DIGITS];
+        raw[d] = (enum led_seg)((d == digit) ?
+            ((SEG_B << segment) - 1) : SEG_NONE);
+        led7seg.showRaw(raw);
+    }
+}
+
+uint8_t dispMode = 0;
+
 void loop()
 {
-	static unsigned long ten_msec = millis();
-	static int counter = 0;
 	static int encoder = 0;

-//	int pot = analogRead(0);
 	encoder += read_encoder();
+  // Cap value to -100..+100 (logical range)
+  if (encoder < MIN_POWER * 4) {
+    encoder = MIN_POWER * 4;
+  } else if (encoder > MAX_POWER * 4) {
+    encoder = MAX_POWER * 4;
+  }
+
+  // Blink LED to show activity
+  if (counter % 10 < 5) {
+    digitalWrite(LED_BUILTIN, HIGH);
+  } else {
+    digitalWrite(LED_BUILTIN, LOW);
+  }

 	if (millis() >= ten_msec) {
 		ten_msec += 100;
-		++counter;
-		if (counter < 200)
-		{
-			int segment = counter & 7;
-			int digit = (counter / 8) % LED_DIGITS;
-			for (byte d = 0; d < LED_DIGITS; ++d)
-			{
-				byte raw[LED_DIGITS];
-				raw[d] = (d == digit) ?
-					((SEG_B << segment) - 1) : SEG_NONE;
-				led7seg.showRaw(raw);
-			}
-		}
-#ifdef LEDFONT
-		else if (counter < 400)
-		{
-			static const char banner[] = "The Quick Brown Fox Jumped Over The Lazy Dogs 0123456789.";
-			const int scroll = ((counter - 200) >> 1) %  (sizeof(banner) - LED_DIGITS);
-			led7seg.showText(banner + scroll);
-		}
-#endif
-		else if (counter < 600)
-		{
-			// Display encoder value as signed -x.yy
-			led7seg.showDecimal(encoder >> 2, 2);
-		}
-		else if (counter < 800)
-		{
-			// Display counter in hex dddd
-			led7seg.showHex(counter);
-		}
-		else if (counter < 1000)
-		{
-			// Display counter as unsigned xxx.y
-			led7seg.showNumber(counter, 1);
-		}
-		else
-		{
-			// Reset to 0 after 100 seconds
-			counter = 0;
-		}
+		counter = (counter + 1) % 1000;
+    analogin = analogRead(7);
+
+    static int8_t oldMode = 1;
+    int8_t mode_pin = digitalRead(MODE_PIN) ? 1 : 0;
+    // Detect falling edge on MODE_PIN
+    if ((oldMode ^ mode_pin) && !mode_pin)
+    {
+       Serial.print("mode=");
+       dispMode = (dispMode + 1) % 3;
+       Serial.println(dispMode);
+       counter = 0;
+    }
+    oldMode = mode_pin;
+
+
+    if (dispMode == 0) {
+      // Display encoder value as signed -x.yy
+      int16_t power = encoder >> 2;
+//      int16_t power = counter * 2 - 100;
+      led7seg.showDecimal(power, 2);
+      //               _______
+      // FullRev  ____}       |_________________________|
+      //                _______________
+      // Stop      ____|               |________________|
+      //                 _______________________
+      // FullFwd    ____|                       |_______|
+      //
+      int16_t usec = power * 5 + 1500;
+      pwmOut.writeMicroseconds(usec);
+    } else if (dispMode == 1) {
+      // Display analog input as decimal
+      Serial.print("in=");
+      Serial.println(analogin);
+      led7seg.showDecimal(analogin, 0);
+    } else {
+      splash();
+    }
 	}
-//	led7seg.refreshDigits(); // Refresh/multiplex display
 	led7seg.refreshSegments(); // Refresh/multiplex display
 }


BUG: Fixed additional , in getall reply

BUG: Fixed additional , in getall reply

--- arduino/brew_kettle/brew_kettle.ino
+++ arduino/brew_kettle/brew_kettle.ino
@@ -105,7 +105,7 @@
 }

 void setPIDonoff_msg() {
-  Serial << STATMSG << "Set PID on off msg received" << ENDMSG;
+  /* Serial << STATMSG << "Set PID on off msg received" << ENDMSG; */
   while (cmdMessenger.available()) {
     char buf[350] = {'\0'};
     cmdMessenger.copyString(buf, 350);
@@ -119,10 +119,10 @@
 }

 void getall_msg() {
-  Serial << STATMSG << "All parameters requested" << ENDMSG;
+  /* Serial << STATMSG << "All parameters requested" << ENDMSG; */
   Serial << GETALLMSG << temperature << "," << dutyCycle << "," \
 	 << setpoint << "," << temperaturePID.GetMode() \
-	 << "," << pumpIsOn << "," << pValue << "," << iValue  << "," << ENDMSG;
+	 << "," << pumpIsOn << "," << pValue << "," << iValue << ENDMSG;
 }

 void changeSET_msg() {
@@ -187,7 +187,7 @@

 void setSetPoint(int value) {
   setpoint = double(value) / 10;
-  Serial << STATMSG << "Set setpoint to " << setpoint << ENDMSG;
+  /* Serial << STATMSG << "Set setpoint to " << setpoint << ENDMSG; */
 }

 void setDutyCycle(int value) {
@@ -198,26 +198,26 @@
   if (value < 0) {
     value = 0;
   }
-  Serial << STATMSG << "Set duty cycle to " << value << ENDMSG;
+  /* Serial << STATMSG << "Set duty cycle to " << value << ENDMSG; */
   dutyCycle = double(value);
 }

 void setPValue(int value) {
   pValue = double(value) / 1000;
-  Serial << STATMSG << "Set P value to " << pValue << ENDMSG;
+  /* Serial << STATMSG << "Set P value to " << pValue << ENDMSG; */
   temperaturePID.SetTunings(pValue, iValue, 0);
 }

 void setIValue(int value) {
   iValue = double(value) / 1000;
-  Serial << STATMSG << "Set P value to " << iValue << ENDMSG;
+  /* Serial << STATMSG << "Set I value to " << iValue << ENDMSG; */
   temperaturePID.SetTunings(pValue, iValue, 0);
 }

 void heaterOn() {
   if (!heaterIsOn) {
     digitalWrite(heaterPin, HIGH);
-    Serial << STATMSG << "Turned heater on" << dutyCycle << ENDMSG;
+    /* Serial << STATMSG << "Turned heater on" << dutyCycle << ENDMSG; */
   }
   heaterIsOn = HIGH;
 }
@@ -225,7 +225,7 @@
 void heaterOff() {
   if (heaterIsOn) {
     digitalWrite(heaterPin, LOW);
-    Serial << STATMSG << "Turned heater off" << dutyCycle << ENDMSG;
+    /* Serial << STATMSG << "Turned heater off" << dutyCycle << ENDMSG; */
   }
   heaterIsOn = LOW;
 }
@@ -233,7 +233,7 @@
 void pumpOn() {
   if (!pumpIsOn) {
     digitalWrite(pumpPin, HIGH);
-    Serial << STATMSG << "Turned pump on" << ENDMSG;
+    /* Serial << STATMSG << "Turned pump on" << ENDMSG; */
   }
   pumpIsOn = HIGH;
 }
@@ -241,7 +241,7 @@
 void pumpOff() {
   if (pumpIsOn) {
     digitalWrite(pumpPin, LOW);
-    Serial << STATMSG << "Turned pump off" << ENDMSG;
+    /* Serial << STATMSG << "Turned pump off" << ENDMSG; */
   }
   pumpIsOn = LOW;
 }


adds leucht-protocol spec :3, fmt

adds leucht-protocol spec :3, fmt

--- lableuchtung.ino
+++ lableuchtung.ino
@@ -14,7 +14,8 @@
  *    You should have received a copy of the GNU Affero General Public License
  *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
- *    Authors: Stefan Luecke <glaxx@glaxx.net>
+ *    Authors:  Stefan Luecke <glaxx@glaxx.net>
+ *              Michael Wendland <michael@michiwend.com>
  */
 #include "ledstripe.h"
 #include "beacon.h"
@@ -22,29 +23,51 @@
 Beacon beac;
 LedStripe leds;

+/*
+ * WIE LEUCHTEST DU!?
+ *     a simple binary leucht-protocol
+ *
+ * you can send 1 or 4 bytes as follows:
+ * the first byte is the command or time byte. Use 251-255 to invoke
+ * different commands otherwise it is interpreted as time in 10ms. See table
+ *
+ * |commands / time in 10ms |R        |G        |B        |Result
+ * +------------------------+---------+---------+---------+-----------------
+ * |11111011   251          |         |         |         |Enable automode
+ * |11111100   252          |         |         |         |Enable beacon
+ * |11111101   253          |         |         |         |Disable beacon
+ * |11111110   254          |         |         |         |
+ * |11111111   255          |         |         |         |
+ * +------------------------+---------+---------+---------+-----------------
+ * |00000000     0          |00000000 |00000000 |00000000 |turn all LEDs off
+ * |00000000     0          |11111111 |11111111 |11111111 |flash to full white
+ * |01100100   100          |11111111 |00000000 |00000000 |fade to full red in 1 sec
+ *
+ */
+
 void serialEvent() {
-  byte index = 0;
-  byte serial_buffer [4] = {0, 0, 0, 0};
-  while (Serial.available() > 0 && index < 4) {
-    serial_buffer[index] = Serial.read();
-    index++;
-    delay(5); // Needed to read all variables
-  }
-  Serial.println(serial_buffer[0]);
-  Serial.println(serial_buffer[1]);
-  Serial.println(serial_buffer[2]);
-  Serial.println(serial_buffer[3]);
-  if (index > 0) {
-    (serial_buffer[0] > 64) ? beac.setMode(serial_buffer) : leds.setMode(serial_buffer);
-  }
+    byte index = 0;
+    byte serial_buffer [4] = {0, 0, 0, 0};
+    while (Serial.available() > 0 && index < 4) {
+        serial_buffer[index] = Serial.read();
+        index++;
+        delay(5); // Needed to read all variables
+    }
+    Serial.println(serial_buffer[0]);
+    Serial.println(serial_buffer[1]);
+    Serial.println(serial_buffer[2]);
+    Serial.println(serial_buffer[3]);
+    if (index > 0) {
+        (serial_buffer[0] > 64) ? beac.setMode(serial_buffer) : leds.setMode(serial_buffer);
+    }
 }

 void setup() {
-  pinMode(REDLEDPIN, OUTPUT);
-  pinMode(GREENLEDPIN, OUTPUT);
-  pinMode(BLUELEDPIN, OUTPUT);
-  pinMode(BEACONPIN, OUTPUT);
-  Serial.begin(9600);
+    pinMode(REDLEDPIN, OUTPUT);
+    pinMode(GREENLEDPIN, OUTPUT);
+    pinMode(BLUELEDPIN, OUTPUT);
+    pinMode(BEACONPIN, OUTPUT);
+    Serial.begin(9600);
 }

 void loop() {


Update to latest API

Update to latest API

--- examples/BasicExample/BasicExample.ino
+++ examples/BasicExample/BasicExample.ino
@@ -37,11 +37,11 @@

 #include <ELModule.h>
 #include <ELDigitalIO.h>
-#include <ELSerial.h>
+#include <ELCommand.h>
 #include <ELRealTime.h>
 #include <ELAssert.h>

-class CExampleModule : public CModule, public IDigitalIOEventHandler, public ISerialCmdHandler, public IRealTimeHandler
+class CExampleModule : public CModule, public IDigitalIOEventHandler, public ICmdHandler, public IRealTimeHandler
 {
 	CExampleModule(
 		)
@@ -63,7 +63,7 @@
 		Serial.printf("In Setup\n");

 		// Register a serial port command.
-		gSerialCmd->RegisterCommand("hello", this, static_cast<TSerialCmdMethod>(&CExampleModule::SerialCmdHello));
+		gCmd->RegisterCommand("hello", this, static_cast<TCmdHandlerMethod>(&CExampleModule::SerialCmdHello));

 		// Register a digital io event handler on pin 1
 		gDigitalIO->RegisterEventHandler(1, false, this, static_cast<TDigitalIOEventMethod>(&CExampleModule::PinActivated), NULL);
@@ -84,12 +84,13 @@

 	bool
 	SerialCmdHello(
-		int			inArgC,
-		char const*	inArgv[])
+		IOutputDirector*	inOutput,
+		int					inArgC,
+		char const*			inArgv[])
 	{
-		Serial.printf("Hello World\n");
+		inOutput->printf("Hello World\n");

-		return true;	// Returning true means command was processed successfully, returning false will print an error to serial out
+		return true;	// Returning true means command was processed successfully, returning false will print an error to the proper output
 	}

 	void
@@ -120,7 +121,7 @@
 setup(
 	void)
 {
-	CModule::SetupAll("v0.2", true);	// Passing in true blinks the led
+	CModule::SetupAll("v0.2", true);	// Passing in true blinks the led when the blink_led config var is set to one
 }

 void


Update GPRS_ReadSMS.ino

Update GPRS_ReadSMS.ino

--- examples/GPRS_ReadSMS/GPRS_ReadSMS.ino
+++ examples/GPRS_ReadSMS/GPRS_ReadSMS.ino
@@ -18,9 +18,9 @@
 // дата отправки сообщения
 char datetime[24];

-// создаём объект класса GPRS и передаём ему скорость 9600 бод
-// с помощью него будем давать команды GPRS-шилду
-GPRS gprs(9600);
+// создаём объект класса GPRS. По умолчанию скорость общения с ним 9600 бод
+// с помощью него будем давать команды GPRS шилду
+GPRS gprs();

 void setup()
 {


Compiler options are back

Compiler options are back

--- src/Deutsch/NOKO/NOKO.ino
+++ src/Deutsch/NOKO/NOKO.ino
@@ -5,7 +5,7 @@
  * The main loop controls the timing events and gets interrupted by the taste()-funtion.
  * Otherwise NOKO falls asleep with powerdowndelay() for 120ms. This saves a lot of power.
  *
- * Flash-Usage: 29.036 (1.8.2 | AVR Core 1.6.18 | Linux x86_64, Windows 10 | No compiler options)
+ * Flash-Usage: 28.356 (1.8.2 | AVR Core 1.6.18 | Linux x86_64, Windows 10 |Compiler options)
  *
  * Optional:
  * Compiler Options:   -funsafe-math-optimizations -mcall-prologues -maccumulate-args


Fixed a bug in the arduino sensor software

--- aidu_vision/Arduino_files/sensor_to_ros/sensor_to_ros.ino
+++ aidu_vision/Arduino_files/sensor_to_ros/sensor_to_ros.ino
@@ -10,7 +10,7 @@
  * Call the topic with: rostopic echo sensors
  */

-
+
 #include <ros.h>
 #include <aidu_vision/DistanceSensors.h>
 #include <math.h>
@@ -42,23 +42,79 @@
   pinMode(echoPin_clean, INPUT);
   pinMode(trigPin_duct, OUTPUT);
   pinMode(echoPin_duct, INPUT);
-
 }

 void loop()
 {
-  // Sharp 041SK
-  // Range: 3 to 30 cm
-  // Value: 30 to 300 (mm)
-  // Attached to analog input 0
-  //double sensor_value_ir_41 = analogRead(sensorpin_ir_41);
-  //int dis_ir_41 = 27205.2633 * pow(sensor_value_ir_41, -1.0183);
-  //distance.Back = dis_ir_41;

-  // Sharp GP2D12
-  // Range: 10 to 80 cm
-  // Value: 100 to 800 (mm)
-  // Attached to analog input 1
+  // HC-SR04 ultrasonic clean
+  // Range: 2 to 400 cm
+  // Value: 20 to 4000 (mm)
+  // Attached to digital 7 (echo, blue) and digital 8 (Trig, red)
+  distance.Frontright = ultrasonic(trigPin_clean, echoPin_clean);
+
+
+  // HC-SR04 ultrasonic duct
+  // Range: 2 to 400 cm
+  // Value: 20 to 4000 (mm)
+  // Attached to digital 12 (Echo, blue) and digital 13 (Trigger, red)
+  distance.Frontleft = ultrasonic(trigPin_duct, echoPin_duct);
+
+
+
+  // Publisher
+  sensor_publisher.publish( &distance );
+  nh.spinOnce();
+  delay(50);
+}
+
+/**
+ * Measures distance from an ultrasonic sensor
+ */
+float ultrasonic(int triggerPin, int echoPin) {
+  float duration[5], distance;
+  for(int i = 0; i < 4; i++){
+    digitalWrite(triggerPin, LOW);
+    delayMicroseconds(2);
+
+    digitalWrite(triggerPin, HIGH);
+    delayMicroseconds(10);
+
+    digitalWrite(triggerPin, LOW);
+    duration[i] = pulseIn(echoPin, HIGH);
+    delayMicroseconds(60000);
+  }
+  duration[4] = (((duration[0] + duration[1] + duration[2] + duration[3])/4));
+  distance = (duration[4] / 5.82 ) - 0.2979052982*(duration[4] / 5.82 ) + 4.0456059645;
+  distance = distance + 0.1*distance - 10;
+  return distance;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Sharp 041SK
+// Range: 3 to 30 cm
+// Value: 30 to 300 (mm)
+// Attached to analog input 0
+//double sensor_value_ir_41 = analogRead(sensorpin_ir_41);
+//int dis_ir_41 = 27205.2633 * pow(sensor_value_ir_41, -1.0183);
+//distance.Back = dis_ir_41;
+
+// Sharp GP2D12
+// Range: 10 to 80 cm
+// Value: 100 to 800 (mm)
+// Attached to analog input 1
 //  double sensor_value_ir_12 = analogRead(sensorpin_ir_12);
 //  int dis_ir_12 = 38161.1739 * pow(sensor_value_ir_12, -0.9298) - 2936752.6632 * pow(sensor_value_ir_12,-2.2758995196);
 //  distance.Frontmiddle = dis_ir_12;
@@ -92,56 +148,3 @@
 // int dir_ir_022 = dir_ir_022 + 0.11999*dir_ir_022 /*- 18.91585*/;
 // distance.Right = dis_ir_022;
 //
-
-
-  // HC-SR04 ultrasonic clean
-  // Range: 2 to 400 cm
-  // Value: 20 to 4000 (mm)
-  // Attached to digital 7 (echo, blue) and digital 8 (Trig, red)
-
-  float duration_clean[5], dis_us_clean;
-  for(int i = 0; i < 4; i++){
-    digitalWrite(trigPin_clean, LOW);
-    delayMicroseconds(2);
-
-    digitalWrite(trigPin_clean, HIGH);
-    delayMicroseconds(10);
-
-    digitalWrite(trigPin_clean, LOW);
-    duration_clean[i] = pulseIn(echoPin_clean, HIGH);
-    delayMicroseconds(60000);
-  }
-  duration_clean[4] = (((duration_clean[0] + duration_clean[1] + duration_clean[2]+duration_clean[3])/4));
-  dis_us_clean = (duration_clean[4] / 5.82 ) - 0.2979052982*(duration_clean[4] / 5.82 ) + 4.0456059645;
-  dis_us_clean = dis_us_clean + 0.1*dis_us_clean - 10;
-  distance.Frontright = dis_us_clean;
-
-  // HC-SR04 ultrasonic duct
-  // Range: 2 to 400 cm
-  // Value: 20 to 4000 (mm)
-  // Attached to digital 12 (Echo, blue) and digital 13 (Trigger, red)
-  float duration_duct[5], dis_us_duct;
-  for(int i = 0; i < 4; i++){
-    digitalWrite(trigPin_duct, LOW);
-    delayMicroseconds(2);
-
-    digitalWrite(trigPin_duct, HIGH);
-    delayMicroseconds(10);
-
-    digitalWrite(trigPin_duct, LOW);
-    duration_duct[i] = pulseIn(echoPin_duct, HIGH);
-    delayMicroseconds(60000);
-  }
-  duration_duct[4] = (((duration_duct[0] + duration_duct[1] + duration_duct[2]+duration_clean[3])/4));
-  dis_us_duct = (duration_duct[4] / 5.82 ) - 0.2979052982*(duration_duct[4] / 5.82 ) + 4.0456059645;
-  dis_us_duct = dis_us_duct + 0.1*dis_us_duct - 10;
-  distance.Frontleft = dis_us_duct;
-
-
-
-  // Publisher
-  sensor_publisher.publish( &distance );
-  nh.spinOnce();
-  delay(50);
-}
-


Update sketch_aug08b.ino

Update sketch_aug08b.ino

--- plane/RECEIVER/sketch_aug08b/sketch_aug08b.ino
+++ plane/RECEIVER/sketch_aug08b/sketch_aug08b.ino
@@ -47,11 +47,11 @@

       angleV = myData1.angleV;
       myServo.write( myData1.angleV);
-      int angleV1 = 0;//variable reserved for further valor tests or adaptations if needed
+      int angleV1 = 0;//variable reserved for further value tests or adaptations if needed

       angleV1= myData1.angleV1;
       myServo1.write( myData1.angleV1);
-      int angleV2 =  0;//variable reserved for further valor tests or adaptations if needed
+      int angleV2 =  0;//variable reserved for further value tests or adaptations if needed

      angleV1= myData1.angleV1;


Update Disconnect Callback Type

Update Disconnect Callback Type

Update the Callback type for disconnect to
reflect recent API changes in RBLs SDK.

--- nRF51822-BLEMIDI/nRF51822-BLEMIDI.ino
+++ nRF51822-BLEMIDI/nRF51822-BLEMIDI.ino
@@ -206,8 +206,7 @@
 * Callback for Bluetooth disconnection
 * Restart advertising and stop the timers.
 *******************************************************************************/
-void disconnectionCallback(Gap::Handle_t handle,
-  Gap::DisconnectionReason_t reason)
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t*)
 {
     Serial.println("Disconnected ");
     Serial.println("Restart advertising ");


compiles

compiles

--- arudino/uno_distance_light_led/uno_distance_light_led.ino
+++ arudino/uno_distance_light_led/uno_distance_light_led.ino
@@ -18,4 +18,5 @@
   }
   else {
     digitalWrite(lightPin, LOW); // set it to low if greater than 24
+  }
 }


added description

added description

--- tank_water_level.ino
+++ tank_water_level.ino
@@ -1,3 +1,15 @@
+/*
+Using this sketch you can calculate water volume in cylinder.
+Based on ultrasonic sensor and NewPing library(which provides output smoothing).
+tH = Total Height (tank height)
+distance = Difference between ultrasonic sensor and water surface. (automaticaly calculated)
+f= Fill height calculated by: tH - distance
+v= volume calculated by: V(tank) = (πr2*f/1000)
+bubblestack - 2016
+by
+Nika Chkhikvishvili & Davit Gokadze
+http://bubblestack.io
+*/

 #include <NewPing.h>

@@ -27,10 +39,6 @@
    distance=(uS / US_ROUNDTRIP_CM); // calculate distance
    f=(tH-distance); //  calculate fill height of tank
    volume=(Pi*sqr_R*f/1000); // calculate volume of liquid
-  Serial.println(volume);
-
-
-
-
+    Serial.println(volume);

  }


Fix Serial1

Fix Serial1

--- Segment16Sign.ino
+++ Segment16Sign.ino
@@ -7,32 +7,33 @@
 void setup(){
   Serial.begin(9600);
   Serial1.begin(9600);
-  while (!Serial || !Serial1) {}  // wait for Leonard
+  //while (!Serial || !Serial1) {}  // wait for Leonard

   String prompt = "Type any character to start";
   Serial.println(prompt);
   Serial1.println(prompt);

-  while (Serial.read() <= 0 || Serial1.read() <= 0) {}
+  while (Serial.read() <= 0 && !Serial1.available() ) {}
+  Serial1.println("WOOT");
   delay(200);  // Catch Due reset problem
   display.init();
   // assume the user typed a valid character and no reset happened
 }

 void loop(){
-  if(Serial.available() > 0 || Serial1.available() > 0){
+  if(Serial.available() > 0 || Serial1.available()){
     input = 0;
     while(Serial.available() > 0){
       incomingByte = Serial.read();
       input = (input << 8) | incomingByte;
     }
-    while(Serial1.available() > 0){
-      incomingByte = Serial.read();
+    while(Serial1.available()){
+      incomingByte = Serial1.read();
       input = (input << 8) | incomingByte;
     }
     display.pushChar(input);
-    Serial.println(input, HEX);
-    Serial1.println(input, HEX);
+    //Serial.println(input, HEX);
+    //Serial1.println(input, HEX);
     //incomingByte = Serial.read();
   }
   display.show();


Output temperatures once per minute, not second, for production.

--- Temps5/Temps5.ino
+++ Temps5/Temps5.ino
@@ -66,6 +66,6 @@
   // Turn off LED
   digitalWrite(13, LOW);

-  delay(1000);
+  delay(60000L);
 }


work without spark cloud

work without spark cloud

--- Relay.ino
+++ Relay.ino
@@ -4,6 +4,8 @@

 #define PREFIX ""
 WebServer webserver(PREFIX, 80);
+
+SYSTEM_MODE(SEMI_AUTOMATIC);

 void helloCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
 {
@@ -147,6 +149,8 @@
   switchPin(D2, LOW);
   switchPin(D3, LOW);

+  WiFi.connect();
+
   webserver.setDefaultCommand(&helloCmd);

   webserver.addCommand("index.html", &helloCmd);
@@ -172,8 +176,11 @@

 void loop()
 {
-  char buff[64];
-  int len = 64;
+  if (WiFi.ready())
+  {
+    char buff[64];
+    int len = 64;

-  webserver.processConnection(buff, &len);
+    webserver.processConnection(buff, &len);
+  }
 }


Update sketch.ino

Update sketch.ino

--- dragino/sketch.ino
+++ dragino/sketch.ino
@@ -25,6 +25,7 @@
 #define IOTID USERNAME"/"IOTDEVICE

 IPAddress server(190, 97, 169, 126);
+long lastReconnectAttempt = 0;

 void callback(char* topic, byte* payload, unsigned int length);
@@ -71,7 +72,24 @@

 }

+boolean reconnect() {
+  if (client.connect("arduinoClient")) {
+    // Once connected, publish an announcement...
+    client.publish("outTopic","hello world");
+    // ... and resubscribe
+    client.subscribe("inTopic");
+  }
+  return client.connected();
+}

+boolean reconnect() {
+  if (client.connect(IOTID, IOTUSERNAME, IOTPASSWORD)) {
+  client.publish(STATUS,"hello world - authenticated!!");
+  client.subscribe(TOPIC);
+  }
+
+  return client.connected();
+}

 void setup()
 {
@@ -81,12 +99,13 @@
   pinMode(out4, OUTPUT);
   pinMode(out6, OUTPUT);

+  lastReconnectAttempt = 0;

-  if (client.connect(IOTID, IOTUSERNAME, IOTPASSWORD)) {
-   client.publish(STATUS,"hello world - authenticated!!");
-   client.subscribe(TOPIC);
-  }
-  lastReconnectAttempt = 0;
+//if (client.connect(IOTID, IOTUSERNAME, IOTPASSWORD)) {
+//  client.publish(STATUS,"hello world - authenticated!!");
+//  client.subscribe(TOPIC);
+//  }
+
 }


Update example

Update example

--- examples/Widgets/Menu/Menu.ino
+++ examples/Widgets/Menu/Menu.ino
@@ -25,7 +25,7 @@
 #include <Ethernet.h>
 #include <BlynkSimpleEthernet.h> // This part is for Ethernet stuff

-char auth[] = "YourAuthToken"; // Put your Auth Token here. (see Step 3 above)
+char auth[] = "YourAuthToken"; // Put your Auth Token here.

 void setup()
 {
@@ -44,6 +44,14 @@
       break;
     case 3: // Item 3
       Serial.println("Item 3 selected");
+
+      // If item 3 is selected, change menu items...
+      BlynkParamAllocated items(128); // list length, in bytes
+      items.add("New item 1");
+      items.add("New item 2");
+      items.add("New item 3");
+      Blynk.setProperty(V1, "labels", items);
+
       break;
     default:
       Serial.println("Unknown item selected");


TW-10: Rendering date now.  Prepend 0 to hours, minutes, and seconds when each value is < 10.

--- tinywatch.ino
+++ tinywatch.ino
@@ -1,3 +1,4 @@
+#include <TinyScreen.h>
 #include <TimeLib.h>
 #include <SPI.h>
 #include <BLEPeripheral.h>
@@ -7,7 +8,7 @@
 //Determines which version of TinyScreen we are using.
 TinyScreen display = TinyScreen(TinyScreenPlus);
 //Buffer used for drawing.
-RenderBuffer<uint8_t,20> buffer;
+RenderBuffer<uint16_t,20> buffer;
 char isTimeSet = 0;

 //Pinouts for TinyShield BLE.
@@ -57,14 +58,14 @@
 void loop() {
   blePeripheral.poll();
   BLECentral central = blePeripheral.central();
-  if(central){
-    while(central.connected()){
-      blePeripheral.poll();
+  if(central && central.connected()){
+    if(isTimeSet){
       renderTime();
-      refreshScreen();
+      renderDate();
     }
+  } else{
+    messageWithSecondDelay("searching...");
   }
-  buffer.drawText("searching...",15,8,buffer.rgb(255,0,0), &virtualDJ_5ptFontInfo);
   refreshScreen();
 }

@@ -82,7 +83,7 @@
 }

 void messageWithSecondDelay(String msg){
-  buffer.drawText(msg.c_str(),15,8,buffer.rgb(255,0,0), &virtualDJ_5ptFontInfo);
+  buffer.drawText(stringBuffer.start().put(msg.c_str()).get(),15,8,buffer.rgb(255,255,255), &liberationSans_8ptFontInfo);
   refreshScreen();
   delay(1000);
 }
@@ -93,15 +94,12 @@
 }

 void renderTime(){
-  if(isTimeSet){
-    buffer.drawText(((String)hour() + ":" + (String)minute() + ":" + (String)second()).c_str(),15,8,buffer.rgb(255,0,0), &virtualDJ_5ptFontInfo);
-  }
+  buffer.drawText(stringBuffer.start().put(hour() < 10 ? "0" : "").putDec(hour()).put(":").put(minute() < 10 ? "0" : "").putDec(minute()).put(":").put(second() < 10 ? "0" : "").putDec(second()).get(),20,16,buffer.rgb(255,255,255), &liberationSans_12ptFontInfo);
 }

-//TODO: Method to render date.
-/*void renderDate(){
-  buffer.drawText(stringBuffer.start().putDec(month()).put("-").putDec(day()).put("-").putDec(year()).get(),15,16,buffer.rgb(255,0,0), &virtualDJ_5ptFontInfo);
-}*/
+void renderDate(){
+  buffer.drawText(stringBuffer.start().putDec(month()).put("-").putDec(day()).put("-").putDec(year()).get(),24,34,buffer.rgb(255,255,255), &liberationSans_8ptFontInfo);
+}

 //TODO: Method to render background.


updated pin out

updated pin out

--- demos/ble_my_project_template/ble_my_project_template.ino
+++ demos/ble_my_project_template/ble_my_project_template.ino
@@ -118,7 +118,7 @@
   Tell the ACI library, the MCU to nRF8001 pin connections.
   The Active pin is optional and can be marked UNUSED
   */
-  aci_state.aci_pins.board_name = BOARD_DEFAULT; //See board.h for details
+  aci_state.aci_pins.board_name = REDBEARLAB_V1_1; //See board.h for details
   aci_state.aci_pins.reqn_pin   = 9;
   aci_state.aci_pins.rdyn_pin   = 8;
   aci_state.aci_pins.mosi_pin   = MOSI;
@@ -127,7 +127,7 @@

   aci_state.aci_pins.spi_clock_divider     = SPI_CLOCK_DIV8;

-  aci_state.aci_pins.reset_pin             = 4;
+  aci_state.aci_pins.reset_pin             = UNUSED;
   aci_state.aci_pins.active_pin            = UNUSED;
   aci_state.aci_pins.optional_chip_sel_pin = UNUSED;


Changed postingInterval

Changed postingInterval

--- files/template.ino
+++ files/template.ino
@@ -51,7 +51,7 @@
 DHT dht(DHTPIN, DHT11);

 //Variables for time sync and upload intervall
-const unsigned long postingInterval = 10*1000; //10 seconds
+const unsigned long postingInterval = 10*1000*60; //1 minute
 unsigned long lastConnectionTime = 0;
 boolean lastConnected = false;
 boolean uploadSuccess = false;


Update ControlViaSerial.ino

Update ControlViaSerial.ino

ControlViaSerial changed input to INPUT_JACK_AS_MIC

--- examples/02-Utility/ControlViaSerial/ControlViaSerial.ino
+++ examples/02-Utility/ControlViaSerial/ControlViaSerial.ino
@@ -69,8 +69,8 @@
   audioHardware.enable(); // activate AIC

   //Choose the desired input
-  audioHardware.inputSelect(TYMPAN_INPUT_ON_BOARD_MIC); // use the on board microphones
-  // audioHardware.inputSelect(TYMPAN_INPUT_JACK_AS_MIC); // use the microphone jack - defaults to mic bias 2.5V
+  //audioHardware.inputSelect(TYMPAN_INPUT_ON_BOARD_MIC); // use the on board microphones
+  audioHardware.inputSelect(TYMPAN_INPUT_JACK_AS_MIC); // use the microphone jack - defaults to mic bias 2.5V
   // audioHardware.inputSelect(TYMPAN_INPUT_JACK_AS_LINEIN); // use the microphone jack - defaults to mic bias OFF

   //Set the desired volume levels


Added proportional PWM control

Added proportional PWM control

--- ppt/ppt.ino
+++ ppt/ppt.ino
@@ -368,14 +368,10 @@
 void adjust_pwm(int target_difference) {

   int current_pwm = power_status.pwm_duty;
-  int target_difference = target_watts - power_status.sol_watts;
-
-  // if target difference is large, use big steps
-  int pwm_delta = 1;
-  if (abs(target_difference) > 100) {
-    pwm_delta = 16;
-  }
-
+
+  // proportional delta control
+  int pwm_delta = 1 + (abs(target_difference) / 25);
+
   // adjust pwm either up or down based on difference sign
   if (target_difference < 0) {
     current_pwm -= pwm_delta;


- minor corrections (some typos)

- minor corrections (some typos)

--- Device_LinkItOne/LASS/LASS.ino
+++ Device_LinkItOne/LASS/LASS.ino
@@ -183,7 +183,7 @@
   #define SENSOR_ID_HUMIDITY_BLYNK 6
   #define SENSOR_ID_LIGHT_BLYNK 7
 #endif
-XSWZA
+
 enum pinSensorConfig{
   DUST_SENSOR_PIN = 8,
   SOUND_SENSOR_PIN = A1,


Added defines defines for threeDigitPercentage()

Changed logic for OLED detection.

--- aquacontrol32.ino
+++ aquacontrol32.ino
@@ -89,6 +89,12 @@

 /**************************************************************************
+       defines for threeDigitPercentage()
+**************************************************************************/
+#define SHOW_PERCENTSIGN                    true
+#define NO_PERCENTSIGN                      false
+
+/**************************************************************************
       Setup included libraries
  *************************************************************************/
 XPT2046_Touchscreen touch( TOUCH_CS_PIN, TOUCH_IRQ_PIN );
@@ -257,8 +263,12 @@
   Wire.begin( I2C_SDA_PIN, I2C_SCL_PIN, 400000 );

   Wire.beginTransmission( OLED_ADDRESS );
-  uint8_t err = Wire.endTransmission();
-  if ( err == 0 )
+  uint8_t error = Wire.endTransmission();
+  if ( error )
+  {
+    ESP_LOGI( TAG, "No I2C device found." );
+  }
+  else
   {
     ESP_LOGI( TAG, "Found I2C device at address 0x%x.", OLED_ADDRESS );
     xTaskCreatePinnedToCore(
@@ -270,10 +280,6 @@
       &xOledTaskHandle,               /* Task handle. */
       1);                             /* Core where the task should run */
   }
-  else
-  {
-    ESP_LOGI( TAG, "No I2C device found." );
-  }

   xTaskCreatePinnedToCore(
     wifiTask,                       /* Function to implement the task */


ajuste no Sequencial.ino

ajuste no Sequencial.ino

--- arduino/Sequencial.ino
+++ arduino/Sequencial.ino
@@ -8,19 +8,19 @@
   Este exemplo está em domínio público.
  */

-const int PRIMEIRO = 7; // segmento A
+const int PRIMEIRO = 8; // segmento A
 const int ULTIMO = 13;  // segmento F

 void setup() {
   for (int i=PRIMEIRO; i<=ULTIMO; i++) {
-    pinMode(display[i], OUTPUT);
+    pinMode(i, OUTPUT);
   }
 }

 void loop() {
   for (int i=PRIMEIRO; i<=ULTIMO; i++) {
-    digitalWrite(display[i], HIGH);
+    digitalWrite(i, HIGH);
     delay(analogRead(A0));
-    digitalWrite(display[i], LOW);
+    digitalWrite(i, LOW);
   }
 }


tweak octo mode, gauge limits

tweak octo mode, gauge limits

--- main/main.ino
+++ main/main.ino
@@ -72,6 +72,17 @@
   B11111
 };

+byte fillMiddle[8] = {
+  B00100,
+  B00100,
+  B00100,
+  B00100,
+  B00100,
+  B00100,
+  B00100,
+  B00100
+};
+
 // BUILD ENGINE VARIABLES ///////////////////////////////////////

 struct EngineVariable
@@ -94,15 +105,15 @@
 EngineVariable engine_rpm   = {"RPM", 0.0, 0.0, 0.0, 6500.0, 0, 0, 0, 0};     //engine rpm
 EngineVariable engine_clt   = {"CLT", 0.0, 0.0, 20.0, 240.0, 0, 0, 0, 0};     //coolant temp
 EngineVariable engine_tps   = {"TPS", 0.0, 0.0, 0.0, 100.0, 0, 0, 0, 0};      //throttle position
-EngineVariable engine_pw1   = {"PW1", 0.0, 0.0, 0.0, 20.0, 3, 0, 0, 0};       //injector pulse width bank 1
-EngineVariable engine_pw2   = {"PW2", 0.0, 0.0, 0.0, 20.0, 3, 0, 0, 0};       //injector pulse width bank 2
+EngineVariable engine_pw1   = {"PW1", 0.0, 0.0, 0.0, 20.0, 2, 0, 0, 0};       //injector pulse width bank 1
+EngineVariable engine_pw2   = {"PW2", 0.0, 0.0, 0.0, 20.0, 2, 0, 0, 0};       //injector pulse width bank 2
 EngineVariable engine_iat   = {"IAT", 0.0, 0.0, 40.0, 150.0, 0, 0, 0, 0};     //intake air temp aka 'mat'
 EngineVariable engine_adv   = {"ADV", 0.0, 0.0, 10.0, 40.0, 1, 0, 0, 0};      //ignition advance
 EngineVariable engine_tgt   = {"TGT", 0.0, 0.0, 10.0, 20.0, 1, 0, 0, 0};      //afr target
 EngineVariable engine_afr   = {"AFR", 0.0, 0.0, 10.0, 20.0, 1, 0, 0, 0};      //air fuel ratio
 EngineVariable engine_ego   = {"EGO", 0.0, 0.0, 70.0, 130.0, 0, 0, 0, 0};     //ego correction %
 EngineVariable engine_egt   = {"EGT", 0.0, 0.0, 0.0, 2000.0, 0, 0, 0, 0};     //exhaust gas temp
-EngineVariable engine_pws   = {"PWS", 0.0, 0.0, 0.0, 20.0, 3, 0, 0, 0};       //injector pulse width sequential
+EngineVariable engine_pws   = {"PWS", 0.0, 0.0, 0.0, 20.0, 2, 0, 0, 0};       //injector pulse width sequential
 EngineVariable engine_bat   = {"BAT", 0.0, 0.0, 8.0, 18.0, 1, 0, 0, 0};       //battery voltage
 EngineVariable engine_sr1   = {"SR1", 0.0, 0.0, 0.0, 999.0, 1, 0, 0, 0};      //generic sensor 1
 EngineVariable engine_sr2   = {"SR2", 0.0, 0.0, 0.0, 999.0, 1, 0, 0, 0};      //generic sensor 2
@@ -160,6 +171,7 @@
   lcd.createChar(2, fill3);
   lcd.createChar(3, fill4);
   lcd.createChar(4, fill5);
+  lcd.createChar(5, fillMiddle);

   octoModeGauges[0][0] = &engine_rpm;
   octoModeGauges[0][1] = &engine_map;
@@ -358,13 +370,13 @@

     //draw dividing line
     lcd.setCursor(9, 0);
-    lcd.write(byte(4));
+    lcd.write(byte(5));
     lcd.setCursor(9, 1);
-    lcd.write(byte(4));
+    lcd.write(byte(5));
     lcd.setCursor(9, 2);
-    lcd.write(byte(4));
+    lcd.write(byte(5));
     lcd.setCursor(9, 3);
-    lcd.write(byte(4));
+    lcd.write(byte(5));

     //right column of labels
     lcd.setCursor(11, 0);


Moved the JSON sending code to the pooling loop and added a serial command capability to choose between old code and new code.

--- ServerSketch/ServerSketch.ino
+++ ServerSketch/ServerSketch.ino
@@ -30,6 +30,9 @@
 int sensor1 = 0;
 int sensor1Pin = A0;    // select the input pin for the potentiometer

+// JSON specifics
+aJsonStream serial_stream(&Serial);
+
 // HW declaration
 #define TOTAL_NUM_Dx 14
 #define TOTAL_NUM_Px 12
@@ -432,10 +435,11 @@

   getSerialCommand();
-  if( g_iNewCode )
+  if( !g_iNewCode )
   {

     // OLD CODE
+    Serial.println("OLD CODE");

     // Send HW status to website
     n = sprintf((char *)p, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
@@ -469,6 +473,11 @@
     ////// NEW JSON CODE /////
     updateBoardState();
     aJsonObject *msg = getJsonBoardState();
+
+    aJson.print(msg, &serial_stream);
+    Serial.println("");
+    aJson.deleteItem(msg);
+
     /*
     // Creating buffer for WebSockets
      int n;
@@ -862,7 +871,7 @@
 //char g_acMessage[] = "{\"status\":OK,\"pins\":{\"13\":{\"label\":\"LED ON 13\",\"is_analog\":\"false\",\"is_input\":\"false\",\"value\":\"0.0\",\"connections\":[]}},\"connections\":[]}\"";

 unsigned long last_print = 0;
-aJsonStream serial_stream(&Serial);
+//aJsonStream serial_stream(&Serial);

 /* Generate message like: { "analog": [0, 200, 400, 600, 800, 1000] } */