ble_bandwidth_test done

ble_bandwidth_test done

--- libraries/BLE/examples/ble_bandwidth_test/ble_bandwidth_test.ino
+++ libraries/BLE/examples/ble_bandwidth_test/ble_bandwidth_test.ino
@@ -56,7 +56,6 @@
  *
  */
 #include <SPI.h>
-#include <avr/pgmspace.h>
 #include <ble_system.h>
 #include <lib_aci.h>
 #include <aci_setup.h>
@@ -213,7 +212,7 @@

   //We reset the nRF8001 here by toggling the RESET line connected to the nRF8001
   //and initialize the data structures required to setup the nRF8001
-  lib_aci_init(&aci_state);
+  lib_aci_init(&aci_state,true);
 }

 bool data_tx_send()
@@ -241,11 +240,12 @@

 void aci_loop()
 {
+  static bool setup_required = false;
+
   // We enter the if statement only when there is a ACI event available to be processed
   if (lib_aci_event_get(&aci_state, &aci_data))
   {
     aci_evt_t * aci_evt;
-
     aci_evt = &aci_data.evt;
     switch(aci_evt->evt_opcode)
     {
@@ -262,10 +262,7 @@
             When the device is in the setup mode
             */
             Serial.println(F("Evt Device Started: Setup"));
-            if (ACI_STATUS_TRANSACTION_COMPLETE != do_aci_setup(&aci_state))
-            {
-              Serial.println(F("Error in ACI Setup"));
-            }
+            setup_required = true;
             break;

             case ACI_DEVICE_STANDBY:
@@ -411,6 +408,18 @@
     // Arduino can go to sleep now
     // Wakeup from sleep from the RDYN line
   }
+
+  /* setup_required is set to true when the device starts up and enters setup mode.
+   * It indicates that do_aci_setup() should be called. The flag should be cleared if
+   * do_aci_setup() returns ACI_STATUS_TRANSACTION_COMPLETE.
+   */
+  if(setup_required)
+  {
+    if (SETUP_SUCCESS == do_aci_setup(&aci_state))
+    {
+      setup_required = false;
+    }
+  }
 }

 void loop()


[enhancement] changed a variable name

[enhancement] changed a variable name

--- AutoCooker_Uno_V0.ino
+++ AutoCooker_Uno_V0.ino
@@ -64,7 +64,7 @@

 // variables to limit temperature read frequency
 #define TEMPERATURE_READ_COUNT 2
-int i = 0;
+int loopCount = 0;
 float temperatureC;

 // The display
@@ -142,14 +142,14 @@
   // read the temperature and update the current step
   // every (TEMPERATURE_READ_COUNT+1) rounds (each round being 100 ms
   // + the duration of I2C operations)
-  if (i++ == TEMPERATURE_READ_COUNT) {
+  if (loopCount++ == TEMPERATURE_READ_COUNT) {
     temperatureC = thermocouple.readCelsius();
     if (!isnan(temperatureC)) {
       Serial.print("C = ");
       Serial.println(temperatureC);
       steps.setCurrentTemperature(temperatureC);
     }
-    i = 0;
+    loopCount = 0;
   }

   // update the internale state of the step holder with regards to the current time


Cleaned unnessary code. Added more documentation to make code clearer. Also added socket disconnect once data has been transmitted to server


Added snake function muahaha.

Added snake function muahaha.

--- BareTest/BareTest.ino
+++ BareTest/BareTest.ino
@@ -62,7 +62,7 @@
 void loop() {
   // put your main code here, to run repeatedly:

-
+  /*

   for(int i=0;i<200;i++){
     strobe();
@@ -86,10 +86,108 @@
   for(int l=0;l<3;l++){
     cubeHorizPlaneShift();
   }
-
-
-
-}
+  */
+
+  bug(1000);
+
+}
+
+void bug(int num) {
+  int proposedX = 0;
+  int proposedY = 0;
+  int proposedZ = 0;
+  int currentX = 0;
+  int currentY = 0;
+  int currentZ = 0;
+  int previousX1 = 0;
+  int previousY1 = 0;
+  int previousZ1 = 0;
+  int previousX2 = 0;
+  int previousY2 = 0;
+  int previousZ2 = 0;
+  int previousX3 = 0;
+  int previousY3 = 0;
+  int previousZ3 = 0;
+  int rand = 0;
+
+  for(int i = 0;i<num;i++) {
+    rand = random(1,12);
+    if(rand == 1) {
+      proposedY++;
+      proposedZ--;
+    } else if(rand == 2) {
+      proposedY++;
+      proposedZ++;
+    } else if(rand == 3) {
+      proposedX--;
+      proposedY++;
+    } else if(rand == 4) {
+      proposedX++;
+      proposedY++;
+    } else if(rand == 5) {
+      proposedX++;
+      proposedZ++;
+    } else if(rand == 6) {
+      proposedX--;
+      proposedZ--;
+    } else if(rand == 7) {
+      proposedX++;
+      proposedZ--;
+    } else if(rand == 8) {
+      proposedX--;
+      proposedZ++;
+    } else if(rand == 9) {
+      proposedY--;
+      proposedZ--;
+    } else if(rand == 10) {
+      proposedY--;
+      proposedZ++;
+    } else if(rand == 11) {
+      proposedY--;
+      proposedX--;
+    } else {
+      proposedX++;
+      proposedY--;
+    }
+
+    String compareNew = String(String(proposedX) + String(proposedY) + String(proposedZ));
+    String compare1 = String(String(previousX1) + String(previousY1) + String(previousZ1));
+    String compare2 = String(String(previousX2) + String(previousY2) + String(previousZ2));
+    String compare3 = String(String(previousX3) + String(previousY3) + String(previousZ3));
+
+    if(proposedX<=3 && proposedX>=0 && proposedY<=3 && proposedY>=0 && proposedZ<=3 && proposedZ>=0 && compareNew!=compare1 && compareNew!=compare2 && compareNew!=compare3) {
+
+      changePix(cube[previousX3][previousY3][previousZ3], 0, 25);
+
+      previousX3 = previousX2;
+      previousY3 = previousY2;
+      previousZ3 = previousZ2;
+      previousX2 = previousX1;
+      previousY2 = previousY1;
+      previousZ2 = previousZ1;
+      previousX1 = currentX;
+      previousY1 = currentY;
+      previousZ1 = currentZ;
+      currentX = proposedX;
+      currentY = proposedY;
+      currentZ = proposedZ;
+
+      changePix(cube[currentX][currentY][currentZ], 1);
+      changePix(cube[previousX1][previousY1][previousZ1], 1, 18);
+      changePix(cube[previousX2][previousY2][previousZ2], 1, 11);
+      changePix(cube[previousX3][previousY3][previousZ3], 1, 4);
+
+      refresh();
+      delay(100);
+
+    } else {
+      proposedX = currentX;
+      proposedY = currentY;
+      proposedZ = currentZ;
+    }
+  }
+}
+

 void cubeHorizPlaneShift() {
   for(int i=0;i<4;i++) {
@@ -280,3 +378,16 @@
   if(color==6) pixels[index].turnTeal();
   if(color==7) pixels[index].turnWhite();
 }
+
+void changePix(int index, int color, int brightness) //0-off 1-red 2-green 3-blue 4-yellow 5-pink 6-teal 7-white
+{
+  if(color==0) pixels[index].turnOff();
+  if(color==1) pixels[index].turnRed();
+  if(color==2) pixels[index].turnGreen();
+  if(color==3) pixels[index].turnBlue();
+  if(color==4) pixels[index].turnYellow();
+  if(color==5) pixels[index].turnPink();
+  if(color==6) pixels[index].turnTeal();
+  if(color==7) pixels[index].turnWhite();
+  pixels[index].setBrightness(brightness);
+}


unit test fix

unit test fix

--- unit_tests/unit_tests_interrupts/unit_tests_interrupts.ino
+++ unit_tests/unit_tests_interrupts/unit_tests_interrupts.ino
@@ -18,6 +18,9 @@
  * - POZYX_INT_CONFIG
  *
  */
+void test_pin(int pinnum, int arduino_pinnum);
+void test_pinlatch(int pinnum, int arduino_pinnum);
+void trigger_interrupt();

 void setup()
 {
@@ -239,4 +242,3 @@

 }
 */
-


Fixed incorrect flash macro in transmit method

--- examples/Transmit/Transmit.ino
+++ examples/Transmit/Transmit.ino
@@ -58,7 +58,7 @@
   // NOTE: transmit() is a blocking method!
   //       See example TransmitInterrupt for details
   //       on non-blocking transmission method.
-  int state = lora.transmit(F("Hello World!"));
+  int state = lora.transmit("Hello World!");

   // you can also transmit byte array up to 256 bytes long
   /*


remove twi_setClock(200000)

remove twi_setClock(200000)

--- _56-gopro-control/a-91-config-on-rtc/a-91-config-on-rtc.ino
+++ _56-gopro-control/a-91-config-on-rtc/a-91-config-on-rtc.ino
@@ -662,8 +662,8 @@
   rtc_config_read();

   Wire.begin(0, 2);
-  twi_setClock(200000);
-  delay(100);
+  //twi_setClock(200000);
+  //delay(100);

   clientName += "esp8266-";
   uint8_t mac[6];


More logger fixes

More logger fixes

--- KISS_OSD/KISS_OSD.ino
+++ KISS_OSD/KISS_OSD.ino
@@ -323,11 +323,11 @@
     if(recBytes == 2)
     {
       minBytes = serialBuf[1]+STARTCOUNT+1; // got the transmission length
-      /*if (minBytes<150 || minBytes>180)
+      if (minBytes<150 || minBytes>180)
       {
          recBytes = 0;
          minBytes = 100;
-      }*/
+      }
     }
     if(recBytes == minBytes)
     {
@@ -465,8 +465,7 @@
               motorCurrent[i] < 0 || motorCurrent[i] > 10000 ||
               motorKERPM[i] < 0 || motorKERPM[i] > 500 ||
               ESCVoltage[i] < 0 || ESCVoltage[i] > 10000 ||
-              ESCmAh[i] < 0 ||
-              AuxChanVals[i] < 0)
+              ESCmAh[i] < 0)
            {
              return false;
            }
@@ -538,7 +537,7 @@
       }
     }
   }
-  if(recBytes < minBytes)
+  if(recBytes != minBytes)
   {
     return false;
   }


Update DumpInfo.ino

Update DumpInfo.ino

--- examples/DumpInfo/DumpInfo.ino
+++ examples/DumpInfo/DumpInfo.ino
@@ -9,15 +9,20 @@
  * Released into the public domain.
  *
  * Sample program showing how to read data from a PICC using a MFRC522 reader on the Arduino SPI interface.
+ *----------------------------------------------------------------------------- empty_skull
+ * Aggiunti pin per arduino Mega
+ * add pin configuration for arduino mega
+ * http://mac86project.altervista.org/
+ ----------------------------------------------------------------------------- Nicola Coppola
  * Pin layout should be as follows:
- * Signal     Pin              Pin
- *            Arduino Uno      MFRC522 board
- * -----------------------------------------
- * Reset      9                RST
- * SPI SS     10               SDA
- * SPI MOSI   11               MOSI
- * SPI MISO   12               MISO
- * SPI SCK    13               SCK
+ * Signal     Pin              Pin               Pin
+ *            Arduino Uno      Arduino Mega      MFRC522 board
+ * ------------------------------------------------------------
+ * Reset      9                5                 RST
+ * SPI SS     10               53                SDA
+ * SPI MOSI   11               52                MOSI
+ * SPI MISO   12               51                MISO
+ * SPI SCK    13               50                SCK
  *
  * The reader can be found on eBay for around 5 dollars. Search for "mf-rc522" on ebay.com.
  */


- fan full/min debug output

- fan full/min debug output

--- GeheimTuer.ino
+++ GeheimTuer.ino
@@ -449,6 +449,7 @@
         dsCount = scan1Wire(dsAddrs, dsMax);
         break;
       case 'l':
+        debug(currentMillis, F("Fan full\r\n"));
         digitalWrite(fanPWMPin, HIGH);
         fanOverride = true;
         fanPWM = 255;
@@ -526,7 +527,7 @@
         doorState = doorOpen;
         break;
       }
-      // fall-through to next case
+      // fall-through to doorClosing

     case doorClosing:
       if (doorState == doorClosing && swFront == LOW) {
@@ -840,7 +841,8 @@
             Serial.print(maxTemp);
             Serial.print(F(")\r\n"));
           }
-        } else if (fanPWM > 0) {
+        } else if (fanPWM > fanMin) {
+          debug(currentMillis, F("Fan min\r\n"));
           fanPWM = fanMin;
         }
       } else {


Another pin fixed

Another pin fixed

--- examples/sos1/sos1.ino
+++ examples/sos1/sos1.ino
@@ -11,7 +11,7 @@
 const int longerwaitTime = 1000;

 void setup() {
-  led.begin( 3 );
+  led.begin( pin );
 }

 void loop() {


removed debug print statements in gyro test

--- examples/APM_GyroTest/APM_GyroTest.ino
+++ examples/APM_GyroTest/APM_GyroTest.ino
@@ -30,31 +30,11 @@

 void loop(){
     Quaternion attitude = orientation.getAttitude();
-
-    uint8_t oldSREG = SREG;
-    cli();
-    uint32_t p = -micros();
     float pitch = attitude.getPitch();
-    float roll  = attitude.getRoll();
-    p += micros();
-
-    uint32_t q = -micros();
-    Vec3 ref(0,0,-1);
-    ref.rotateBy(attitude);
-    float vPitch = asin(ref[0]);
-    float vRoll  = asin(-ref[1]);
-    q += micros();
-    SREG = oldSREG;
-
-    Serial.print(p);
+    Serial.print(pitch);
     Serial.print("\t");
-    Serial.print(q);
-    Serial.print("\t");
-    Serial.print(pitch);
-    Serial.print(roll);
-    Serial.print(vPitch);
+    Serial.print(integral);
     Serial.print("\n");
-

     integral += I*pitch;
     integral = constrain(integral, -90, 90);


lcd: hello world

lcd: hello world

--- src/src.ino
+++ src/src.ino
@@ -1,4 +1,12 @@
+#include "ILI9341_t3.h"
+#include "SPI.h"
 #include <math.h>
+
+// Hardware
+// TFT LCD
+const int TFT_DC = 9;
+const int TFT_CS = 10;
+ILI9341_t3 lcd = ILI9341_t3(TFT_CS, TFT_DC);

 // A physical location
 typedef struct Location {
@@ -118,6 +126,12 @@
 // Start serial
 void setup() {
   Serial.begin(9600);
+
+  lcd.begin();
+  lcd.fillScreen(ILI9341_BLACK);
+  lcd.setTextColor(ILI9341_YELLOW);
+  lcd.setTextSize(2);
+  lcd.println("Hello world!");
 }

 // Fake GPS data and print calculated values


Missing #include

Missing #include

--- Firmware/Source/v1.2/grove_pi_v1_2_6/grove_pi_v1_2_6.ino
+++ Firmware/Source/v1.2/grove_pi_v1_2_6/grove_pi_v1_2_6.ino
@@ -8,6 +8,7 @@
 #include "IRSendRev.h"
 #include "Encoder.h"
 #include "TimerOne.h"
+#include "VirtualWire.h"

 MMA7660 acc;
 DS1307 clock;


integrating changes into module

integrating changes into module

--- module/module.wifi.ino
+++ module/module.wifi.ino
@@ -14,7 +14,7 @@
 }
 void updateACM(unsigned int ID, unsigned long elapsedTime, unsigned long existingTime) {
     String beginConnection = "AT+CIPSTART=\"TCP\",\"192.168.0.200\",5000";
-    String getStr = "GET /laserLog/";
+    String getStr = "GET /laserLog/A/";
     String cmd = "AT+CIPSEND=";
     String closeConnection = "AT+CIPCLOSE";


comments

comments

--- Sensorizer.ino
+++ Sensorizer.ino
@@ -91,6 +91,7 @@
   int newPos = myEnc.read() / 4;

   if (buttonMode == HIGH) {
+    // no button, change bank
     if (newPos != position) {
       DEBUG_PRINT_NUM("encoder: ", newPos);
       int newInst = newPos % 129;
@@ -118,7 +119,8 @@
     }
   }
   else { //button is depressed. cheer up, button!
-     if (newPos != positionKey) {
+    // change scale
+    if (newPos != positionKey) {
       positionKey = newPos;
       DEBUG_PRINT_NUM("encoder key: ", positionKey);


Send last position and place hash to support Node.js

--- WhereDial.ino
+++ WhereDial.ino
@@ -109,6 +109,8 @@

 void loop()
 {
+  digitalWrite(ledRed,LOW);
+
   for(int i=0;i<5;i++)
   {
     delay(50);
@@ -178,7 +180,6 @@
     if ((err >= 200) && (err < 300))
     {

-      digitalWrite(ledRed,LOW);
       /* OK - TURN DOWN LED  03 */
       digitalWrite(errorLeds[2],LOW);

@@ -286,8 +287,37 @@
   Serial.println("end-ip");
   int err =0;

-  Serial.println("Requesting new angle...");
-  err = http.get(ip, apiHostname,apiPort, apiPath, userAgent);
+  Serial.println("Requesting new angle...");
+  // We need to add &position=DDD&placeHash=40CHARS
+  int apiPathSize = strlen(apiPath);
+  int pathSize = apiPathSize+64;
+  char path[pathSize];
+  char *pathPointer = path;
+  strncpy(path,apiPath,apiPathSize);
+  char* queryString = strstr(apiPath,"?");
+  pathPointer += apiPathSize;
+  *pathPointer = '?';
+  if (queryString) {
+    *pathPointer = '&';
+  }
+  ++pathPointer;
+
+  strcpy(pathPointer,"position=");
+  pathPointer+=9;
+  char pos[4];
+  sprintf(pos,"%d",actual);
+  strcpy(pathPointer,pos);
+  pathPointer += strlen(pos);
+
+  strcpy(pathPointer,"&placeHash=");
+  pathPointer+=11;
+  strcpy(pathPointer,lastPlaceHash);
+  pathPointer+=strlen(lastPlaceHash);
+
+  Serial.print("Calculated path=");
+  Serial.println(path);
+
+  err = http.get(ip, apiHostname,apiPort, path, userAgent);
   if (err == 0)
   {

@@ -299,11 +329,10 @@
     if ((err >= 200) && (err < 300))
     {

-      digitalWrite(ledRed,LOW);
       /* OK - TURN DOWN LED  03 */
       digitalWrite(errorLeds[2],LOW);

-      delay(1000);
+      delay(100);
       processPage();

       /* OK - TURN DOWN LED  04 */
@@ -342,9 +371,9 @@
   Serial.println(prev);
   Serial.println(actual);

-  Serial.print("read=");
-  char c =http.read();
-  Serial.println(c);
+//  Serial.print("read=");
+//  char c =http.read();
+//  Serial.println(c);

   char placeHash[41];
   charCount = http.readBytesUntil(',', placeHash, sizeof(placeHash)-1);


removed blink sketch

removed blink sketch

Removed blink sketch. It was added accidentally (it’s just the basic
Arduino Blink sketch)

--- IOT2020_Blinktest/IOT2020_Blinktest.ino
+++ IOT2020_Blinktest/IOT2020_Blinktest.ino
@@ -1,29 +0,0 @@
-/*
-  Blink
-  Turns on an LED on for one second, then off for one second, repeatedly.
-
-  Most Arduinos have an on-board LED you can control. On the Uno and
-  Leonardo, it is attached to digital pin 13. If you're unsure what
-  pin the on-board LED is connected to on your Arduino model, check
-  the documentation at http://www.arduino.cc
-
-  This example code is in the public domain.
-
-  modified 8 May 2014
-  by Scott Fitzgerald
- */
-
-
-// the setup function runs once when you press reset or power the board
-void setup() {
-  // initialize digital pin 13 as an output.
-  pinMode(13, OUTPUT);
-}
-
-// the loop function runs over and over again forever
-void loop() {
-  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
-  delay(1000);              // wait for a second
-  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
-  delay(1000);              // wait for a second
-}


tuning values

tuning values

--- examples/CaroloCar/CaroloCar.ino
+++ examples/CaroloCar/CaroloCar.ino
@@ -35,7 +35,7 @@
 unsigned long prevCheck = 0; //for the LEDs
 const unsigned short LEDrefreshRate = 200;

-const unsigned short OVERRIDE_TIMEOUT = 300;
+const unsigned short OVERRIDE_TIMEOUT = 500;
 unsigned long overrideRelease = 0; //variable to hold WHEN the override should be lifted
 volatile boolean overrideTriggered = false; //volatile since we are accessing it inside an ISR

@@ -73,7 +73,7 @@
   setupChangeInterrupt(OVERRIDE_SERVO_PIN);
   gyro.attach();
   gyro.begin(); //default 80ms
-  delay(1000);
+  delay(500); //wait a bit for the esc
   car.enableCruiseControl(encoderLeft);
   car.setSpeed(0);
   Serial.begin(115200); //to HLB
@@ -95,7 +95,7 @@
   if (qualityCheck) { //good quality, means that the RC controller is turned on, therefore we should go on override mode
     overrideTriggered = true;
     overrideRelease = millis() + OVERRIDE_TIMEOUT; //specify the moment in the future to re-enable Serial communication
-  } else { //this means that at least one of the last 8 measurements was not valid, therefore we consider the signal not to be of good quality (RC controller is turned off)
+  } else { //this means that at least one of the last 16 measurements was not valid, therefore we consider the signal not to be of good quality (RC controller is turned off)
     throttleSignalPending = false; //indicate that loop() has processed/disregarded the throttle signal
     steeringSignalPending = false; //indicate that loop() has read/disregarded the servo signal
   }


Keep temperature in F if user has tapped in top right

--- examples/ReflowWizard/Touch.ino
+++ examples/ReflowWizard/Touch.ino
@@ -291,7 +291,6 @@
   touchCallbackInterval = 0;
   touchCallbackTemperatureUnitChange = 0;
   touchScreenshotTaps = 0;
-  touchDisplayInCelsius = true;
 }


removed switching analogReference

removed switching analogReference

--- src/ard_sketch.ino
+++ src/ard_sketch.ino
@@ -45,8 +45,6 @@
     //lcd setup
     lcdSetup();

-    // for current sensor
-    analogReference(INTERNAL);
     pinMode(RELAY_PIN, OUTPUT);
     digitalWrite(RELAY_PIN, HIGH);
     Serial.begin(9600);
@@ -198,7 +196,6 @@

             // current sensor
         case 86:
-            analogReference(INTERNAL);
             send_int(analogRead(CURRENT_SENSOR_PIN));
             break;

@@ -240,7 +237,6 @@
                 digitalWrite(MAX7219_CS, HIGH);
                 break;
         case 88:
-                analogReference(DEFAULT);
                 send_int(analogRead(PHOTO_RESISTOR));
                 break;


fixing renaming error

fixing renaming error

--- src/main.ino
+++ src/main.ino
@@ -1,44 +0,0 @@
-/*
-This code takes input from two pushbuttons and i2c serial communications, and
-outputs a PWM squarewave to control two LED MINIPUCK constant current drivers.
-
-this board is primarily a slave device on i2c and will accept control signals
-from an i2c master. In addition, it can respond to the master with certain
-values
-
-This code is written for a destination board of a digispark V4. Hence pin
-references and other libraries may be used in a unusual manner from normal
-arduino coding .
-*/
-
-#include <wire.h>
-
-const byte frontLED 1 //digital pin 1 (PWM) - Output
-const byte backLED  4 //digital pin 4 (PWM) - Output
-const byte frontSwitch 3 //digital pin 3 - Input
-const byte backSwitch 5 //digital pin 5 - Input
-const byte slaveAddress 8
-//SDA = pin D0
-//SCL = pin D2
-
-int frontLEDpulse = 0;
-int backLEDpulse = 0;
-
-
-void setup() {
-  pinMode(frontLED, OUTPUT);
-  pinMode(backLED, OUTPUT);
-  pinMode(frontSwitch, INPUT);
-  digitalWrite(frontSwitch, HIGH); //turn on internal pullup resistor
-  wire.begin(slaveAddress);
-  wire.onReceive(receiveEvent);
-}
-
-void loop() {
-
-}
-
-void receiveEvent(int quantity){
-  frontLEDpulse = wire.read()
-  backLEDpulse = wire.read()
-}


Added temp sensor and I/O expander

Added temp sensor and I/O expander

--- ASC_Alexa_Sprinkler_Controller/ASC_Alexa_Sprinkler_Controller.ino
+++ ASC_Alexa_Sprinkler_Controller/ASC_Alexa_Sprinkler_Controller.ino
@@ -20,7 +20,7 @@
 #include <ESP8266mDNS.h>
 #include "SSD1306.h" // SSD1306
 #include "Adafruit_MCP23017.h" //Adafruit-MCP23017-Arduino-Library
-#include "SparkFunTMP102.h" // Used to send and recieve specific information from our sensor
+#include "SparkFunTMP102.h" // Used to send and recieve specific information from temp sensor

  //CONSTANTS/VARIABLES/GLOBALS-------------------------------------------------------------
 const int ALERT_PIN = 5; //TMP102 alert pin
@@ -93,6 +93,7 @@
   mcp.pinMode(5, OUTPUT);
   mcp.pinMode(6, OUTPUT);
   mcp.pinMode(7, OUTPUT);
+  mcp.pinMode(8, OUTPUT);

 // ensure that each pin defaults to HIGH (relay off)
 // these cheap blue relay modules use active low logic.
@@ -104,12 +105,10 @@
   mcp.digitalWrite(5, HIGH); //K6
   mcp.digitalWrite(6, HIGH); //K7
   mcp.digitalWrite(7, HIGH); //K8
+  //mcp.digitalWrite(8, HIGH); MCP23017 GPB0 test

 //Webpage Heading
   webPage += "
ASC - Alexa Sprinkler Controller
";
-// Temp object
-webPage += "
Temp " ; //name of button
-
 //All on objects
   webPage += "
ALL RELAYS "; //name of button
   webPage += "<button>ON</button> "; //on button object
@@ -171,8 +170,7 @@
     Serial.println("MDNS responder started");

     server.on("/", [](){
-    server.send(200, "text/html", webPage);
-  });
+    server.send(200, "text
   //RELAY 1 ------------------------------------
     server.on("/relay1On", [](){
     server.send(200, "text/html", webPage);


Version 4.0a - 9th July 2021

Version 4.0a - 9th July 2021

Couple of minor bug fixes.

--- ulisp.ino
+++ ulisp.ino
@@ -1,5 +1,5 @@
-/* uLisp AVR Version 4.0 - www.ulisp.com
-   David Johnson-Davies - www.technoblogy.com - 7th July 2021
+/* uLisp AVR Version 4.0a - www.ulisp.com
+   David Johnson-Davies - www.technoblogy.com - 9th July 2021

    Licensed under the MIT license: https://opensource.org/licenses/MIT
 */
@@ -1179,7 +1179,7 @@
   return tf_progn(function, *env);
 }

-object *apply (symbol_t name, object *function, object *args, object *env) {
+object *apply (builtin_t name, object *function, object *args, object *env) {
   if (symbolp(function)) {
     builtin_t fname = builtin(function->name);
     if ((fname > FUNCTIONS) && (fname < KEYWORDS)) {
@@ -1188,15 +1188,15 @@
     } else function = eval(function, env);
   }
   if (consp(function) && isbuiltin(car(function), LAMBDA)) {
-    object *result = closure(0, name, function, args, &env);
+    object *result = closure(0, sym(name), function, args, &env);
     return eval(result, env);
   }
   if (consp(function) && isbuiltin(car(function), CLOSURE)) {
     function = cdr(function);
-    object *result = closure(0, name, function, args, &env);
+    object *result = closure(0, sym(name), function, args, &env);
     return eval(result, env);
   }
-  errorsym(name, PSTR("illegal function"), function);
+  error(name, PSTR("illegal function"), function);
   return NULL;
 }

@@ -4357,8 +4357,9 @@
   uint16_t x = untwist(name);
   for (int d=1600; d>0; d = d/40) {
     uint16_t j = x/d;
-    pfun(fromradix40(j));
-    x = x - j*d;
+    char c = fromradix40(j);
+    if (c == 0) return;
+    pfun(c); x = x - j*d;
   }
 }


Update base2clock.ino

Update base2clock.ino

Better way to handle initial mins on time set.

--- base2clock.ino
+++ base2clock.ino
@@ -34,16 +34,15 @@
 int p1,p2,p3,p4,p5,p6,p7,p8 = 0;

 //booleans for time setting purposes.
-boolean time_set,add_2_mins,subtract_1_min,reset_slow,reset_fast = false;
+boolean time_set,reset_slow,reset_fast = false;

 //call this function if a time set button is pressed.
 void reset_init(){
-  add_2_mins = true;
   reset_mills = mil;

   //use current time setting as new initial values.
   hr_init = 0;
-  min_init = 0;
+  min_init = 2;
   if(p1 == 1) hr_init = 4;
   if(p2 == 1) hr_init += 2;
   if(p3 == 1) hr_init += 1;
@@ -54,7 +53,7 @@
   if(p8 == 1) min_init += 2;

   if(p6 == 1 && p7 == 1 && p8 == 1)
-    subtract_1_min = true;
+    min_init -= 1;
 }

 void setup(){
@@ -78,13 +77,11 @@
   //reinitialize time setting booleans to false.
   reset_fast = false;
   reset_slow = false;
-  add_2_mins = false;
-  subtract_1_min = false;

   //get the time that the program has been running, to calculate time.
   mil = millis();

-  //add this to determine if mil has counted 46 days and has reset.
+  //add this to determine if mil has counted 50 days and has reset.
   if(prev_mils != 0){
     if(prev_mils > mil){
       time_set = false;
@@ -155,10 +152,6 @@

     //calculate values for hours and minutes.
     mins = sec/60;
-    if(add_2_mins)
-      min_init += 2;
-    if(subtract_1_min)
-      min_init -= 1;
     mins += min_init;
     hr = mins/60;
     mins -= (hr*60);


Delete blank arduino file

Delete blank arduino file

--- toy/toy.ino
+++ toy/toy.ino
@@ -1,7 +0,0 @@
-/*** Code for the Furby ***/
-
-void setup() {}
-
-void loop() {}
-
-


improved example

improved example

--- examples/joystickRotaryEncoder/joystickRotaryEncoder.ino
+++ examples/joystickRotaryEncoder/joystickRotaryEncoder.ino
@@ -9,7 +9,7 @@
 #include <IoAbstraction.h>
 #include <JoystickSwitchInput.h>

-#define ANALOG_INPUT_PIN A1
+#define ANALOG_INPUT_PIN A0

 // we need to create an analog device that the joystick encoder will use to get readings.
 // In this case on arduino analog pins.
@@ -26,8 +26,11 @@
 }

 void setup() {
-    while(!Serial);
     Serial.begin(115200);
+
+    // MKR boards require the line below to wait for the serial port, uncomment if needed
+    // However, it doesn't work on some other boards and locks them up.
+    //while(!Serial);

     Serial.println("Starting joystick rotary encoder example");


- Example sketch

- Example sketch

--- examples/LightBlueBean/01.Basics/AccelerometerEvent/AccelerometerEvent.ino
+++ examples/LightBlueBean/01.Basics/AccelerometerEvent/AccelerometerEvent.ino
@@ -1,23 +1,69 @@
+/*
+  This sketch demonstrates the Bean's ability to detect motion events.
+
+  In this demo we assign motions with corresponding LED colors.
+  The Bean's LED color shows what motion event it's waiting to detect.
+  After detecting the event, it will cycle to the next color and wait for the next event.
+
+  We start by waiting for "double tap" indicated by a red LED color
+
+  - Double tap          (Red)
+  - Single tap          (Green)
+  - Any motion detected (Blue)
+  - Orientation change  (Orange)
+  - High-g motion       (Purple)
+  - Low-g (freefall)    (Turquoise)
+  - Flat orientation    (Off)
+
+  Notes:
+    - This is not a low-power sketch because we are using the LED extensively.
+      Without LED use, this sketch is considered low-power.
+    - Bean.sleep() is interrupted by the action of an enabled event.
+    - Calling checkMotionEvent(someEvent) will return 'true' only if "someEvent" was
+      detected in the time since checkMotionEvent(someEvent) was last called.
+
+  This example code is in the public domain.
+*/
+
+typedef struct{
+  uint8_t event;
+  uint8_t red;
+  uint8_t green;
+  uint8_t blue;
+}MotionEventState;
+
+int index = 0;
+MotionEventState states[] = {
+  {DOUBLE_TAP_EVENT, 128,    0,    0 },          // Red
+  {SINGLE_TAP_EVENT,   0,  128,    0 },          // Green
+  {ANY_MOTION_EVENT,   0,    0,  128 },          // Blue
+  {ORIENT_EVENT,      64,   64,    0 },          // Orange
+  {HIGH_G_EVENT,      64,    0,   64 },          // Purple
+  {LOW_G_EVENT,        0,   64,   64 },          // Turquoise
+  {FLAT_EVENT,         0,    0,    0 }           // Off
+};
+
+
 void setup() {
-  // put your setup code here, to run once:
-
-  Bean.enableAccelEvent( SINGLE_TAP_EVENT | HIGH_G_EVENT );
 }

 void loop() {
-  // put your main code here, to run repeatedly:
+  // Listen for this event
+  Bean.enableMotionEvent( states[index].event );

-  if ( Bean.checkAccelEvent( SINGLE_TAP_EVENT ) )
+  // Set the LED state to indicate which event the Bean is waiting for
+  Bean.setLed(states[index].red, states[index].green, states[index].blue);
+
+  // Wait for the motion event in a low-power mode
+  while( Bean.checkMotionEvent( states[index].event ) == false )
   {
-    // Turn on the LED
-    Bean.setLed( 0xff, 0x00, 0x00 );
+    // Bean.sleep is interrupted by an enabled acclerometer event
+    Bean.sleep(10000);
   }
+
+  // Disable this event
+  Bean.disableMotionEvents();

-  if ( Bean.checkAccelEvent( HIGH_G_EVENT ) )
-  {
-    // Turn off the LED
-    Bean.setLed( 0x00, 0x00, 0x00 );
-  }
-
-  Bean.sleep(10000);
+  // Move on to the next event
+  index = (index + 1) % 7;
 }


clean up example

clean up example

--- examples/walkingwizard/walkingwizard.ino
+++ examples/walkingwizard/walkingwizard.ino
@@ -14,34 +14,31 @@

 Arduboy arduboy;
 Sprites sprites (arduboy);
-byte frameCount = 0;
-byte wizard_X = 51;
-byte wizard_Y = 19;
-
-unsigned long next_frame = 0;
+byte spriteFrame = 0;
+const byte wizard_X = 51;
+const byte wizard_Y = 19;

 void setup() {
   arduboy.start();
   arduboy.setFrameRate(60);
-  arduboy.clearDisplay();
-  arduboy.display();
 }

 void loop() {
   if (!(arduboy.nextFrame()))
     return;
+
   arduboy.clearDisplay();
+  // animate every 180ms or so
+  if (arduboy.everyXFrames(11)) {
+    spriteFrame++;
+    if (spriteFrame > 3)
+      spriteFrame = 0;
+  }
   drawWizard();
   arduboy.display();
 }

 void drawWizard()
 {
-  sprites.draw(wizard_X, wizard_Y, wizard_bitmaps, frameCount);
-  if (millis() >= next_frame)
-  {
-    frameCount++;
-    if (frameCount > 3) frameCount = 0;
-     next_frame = millis() + PAUSE_BETWEEN_FRAMES;
-  }
+  sprites.draw(wizard_X, wizard_Y, wizard_bitmaps, spriteFrame);
 }


Update Sparkfun_ADJD-S311.ino

Update Sparkfun_ADJD-S311.ino

--- firmware/examples/Sparkfun_ADJD-S311.ino
+++ firmware/examples/Sparkfun_ADJD-S311.ino
@@ -1,4 +1,4 @@
-#include <ADJDS311.h>
+#include <Sparkfun_ADJD-S311/Sparkfun_ADJD-S311.h>
 #include <Wire.h>

 int sensorLed_pin = 2; //LED on the ADJDS-311


better servo spinning

better servo spinning

--- testing/arduino/self-driving-v6.ino
+++ testing/arduino/self-driving-v6.ino
@@ -12,7 +12,7 @@
 const uint8_t rangeLimit_Warning3 = 25;
 const uint8_t rangeLimit_Stop = 15;

-const uint16_t rangeLimit_RotateFor = 500;
+const uint16_t rangeLimit_RotateFor = 1000;
 unsigned long rangeLimit_Timestamp = 0;
 bool wheelSpinCompleted = true;

@@ -107,6 +107,7 @@
 {
     ServoMotor.write(angle);
     delay(20);
+    servoPos = angle;
 }

@@ -166,27 +167,47 @@
 void loop()
 {

+    uint32_t uptime = millis();
     GetRange()

+    if(uptime % 5000 == 0)
+    {
+        SetServoAngle(servoTiltRight)
+    }
+
+    if(uptime % 5500 == 0)
+    {
+        SetServoAngle(servoCenter)
+    }
+
+
+    if(uptime % 9000 == 0)
+    {
+        SetServoAngle(servoTiltLeft)
+    }
+
+    if(uptime % 9500 == 0)
+    {
+        SetServoAngle(servoCenter)
+    }
+
     // Wait for initial scans before performing any actions
-    if(millis() < initialDelay)
+    if(uptime < initialDelay)
     {
         SetLightErrorState();
         return;
     }

-    long range = rangeCenter;
-
-    SetLightByRange(range);
+    SetLightByRange(rangeCenter);

     // obstacle is further away than X cm
-    if(wheelSpinCompleted && range > rangeLimit_Stop)
+    if(wheelSpinCompleted && rangeCenter > rangeLimit_Stop)
     {
         // drive
         SetMotor(motorPin1_1, motorPin1_2, 255);
         SetMotor(motorPin2_1, motorPin2_2, 255);

-        rangeLimit_Timestamp = millis();
+        rangeLimit_Timestamp = uptime;
     }

     // TODO - slightly turn if side better than center
@@ -206,7 +227,7 @@

         wheelSpinCompleted = false;

-        if(range > rangeLimit_Warning3 && (rangeLimit_Timestamp + rangeLimit_RotateFor) <= millis())
+        if(rangeCenter > rangeLimit_Warning3 && (rangeLimit_Timestamp + rangeLimit_RotateFor) <= uptime)
         {
             wheelSpinCompleted = true;
         }


update positionFunctions

update positionFunctions

--- SensorShirt/PositionFunctions.ino
+++ SensorShirt/PositionFunctions.ino
@@ -4,49 +4,133 @@
 */

 boolean armAtSideRight() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean armFwdRight45() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean armFwdRight90() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean armFwdRight135() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean armFwdRight180() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean armSideRight45() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean armSideRight90() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean armSideRight135() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean armSideRight180() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean backStraight() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean backBentFwd() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }

 boolean backBentBack() {
-
+  if(backValue > 0 && backValue < 0) {
+    if(shoulderValue > 0 && shoulderValue < 0) {
+      if(underarmValue > 0 && underarmValue < 0) {
+        return true;
+      }
+    }
+  }
+  return false;
 }


Better contrast control

Better contrast control

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -2261,7 +2261,9 @@
       // adjust display brightness so we can see the results
       LcdBrightness = index * 16 - 1;
       analogWrite(mc_Brightness, LcdBrightness);
+#if (DEBUG & DEBUG_ACT)
       Serial.printf(F("brightness_action: brightness set to %d\n"), LcdBrightness);
+#endif

       // show brightness value in row 1
       draw_row1_bar(index);
@@ -2276,7 +2278,7 @@
 // We show immediately what the changes mean, but only update the
 // actual contrast if we do a vfo_Click action.
 //
-// We limit the allowed range for LcdContrast to [0, 128].
+// We limit the allowed range for LcdContrast to [0, 255].
 //----------------------------------------

 void contrast_action(struct Menu *menu, int item_num)
@@ -2285,7 +2287,7 @@
   int old_contrast = LcdContrast;

   // convert contrast value to a display value in [0, 15]
-  int index = LcdContrast / 10;
+  int index = LcdContrast / 16;

   if (index > 15)   // ensure in range
     index = 15;
@@ -2338,9 +2340,11 @@
       }

       // adjust display contrast so we can see the results
-      LcdContrast = index * 10;
+      LcdContrast = index * 16;
       analogWrite(mc_Contrast, LcdContrast);
+#if (DEBUG & DEBUG_ACT)
       Serial.printf(F("contrast_action: contrast set to %d\n"), LcdContrast);
+#endif

       // show brightness value in row 1
       // Contrast voltage works opposite to brightness
@@ -2383,10 +2387,6 @@

 void holdclick_action(struct Menu *menu, int item_num)
 {
-#if (DEBUG & DEBUG_ACT)
-  Serial.printf(F("holdclick_action: entered\n"));
-#endif
-
   UINT holdtime = ReHoldClickTime;      // the value we change
   const UINT hold_step = 100;           // step adjustment +/-

@@ -2455,10 +2455,6 @@

 void doubleclick_action(struct Menu *menu, int item_num)
 {
-#if (DEBUG & DEBUG_ACT)
-  Serial.printf(F("doubleclick_action: entered, ReDClickTime=%dmsec\n"), ReDClickTime);
-#endif
-
   int dctime = ReDClickTime;      // the value we adjust
   UINT dclick_step = 100;         // step adjustment +/-

@@ -2530,10 +2526,6 @@

 void calibrate_action(struct Menu *menu, int item_num)
 {
-#if (DEBUG & DEBUG_ACT)
-  Serial.printf(F("calibrate_action: entered, VfoClockOffset=%dmsec\n"), VfoClockOffset);
-#endif
-
   int save_offset = VfoClockOffset; // save the existing offset
   int seldig = 0;                   // the selected digit in the display
   bool was_standby = false;         // true if we have to set standby when finished
@@ -2775,14 +2767,10 @@
     {
       Serial.printf(F("actual volts=%f, percent=%d, batt_bucket=%d\n"),
                       MeasuredVoltage, percent, batt_bucket);
+    batt_report_count = -ReportVoltageDelay;
     }
 #endif
   }
-
-#if (DEBUG & DEBUG_BATT)
-  if (batt_report_count > 0)
-    batt_report_count = -ReportVoltageDelay;
-#endif
 }

 //----------------------------------------


File structure got messed up. Fixed

File structure got messed up. Fixed

--- AutoREQ2.ino
+++ AutoREQ2.ino
@@ -1,183 +0,0 @@
-#include <stdio.h>
-#include <SPI.h> //from wifly library
-#include <WiFly.h> //from wifly library
-#include <MFRC522.h>
-//contains server address as well as SSID
-//credentials
-#include "Credentials.h"
-
-/*
- * Pin layout used:
- * -----------------------------------------------------------------------------------------
- *             MFRC522      Arduino
- *             Reader/PCD   Uno
- * Signal      Pin          Pin
- * -----------------------------------------------------------------------------------------
- * RST/Reset   RST          9
- * SPI SS      SDA(SS)      7
- * SPI MOSI    MOSI         11 / ICSP-4
- * SPI MISO    MISO         12 / ICSP-1
- * SPI SCK     SCK          13 / ICSP-3
- *
- * This program will allow the arduino to read an RFID card
- * and send data to a listening port on a server.
- *
- * Thanks to SparkFun's wifly shield library and Miguel Balboa's MFRC522 library
- * https://github.com/sparkfun/WiFly-Shield/ https://github.com/miguelbalboa/rfid
- *
- * Definitions
- * PICC  = This is the RFID card or key fob
- *
- */
-
-
-
-#define RST_PIN         9           // Configurable, see typical pin layout above
-#define SS_PIN          7          // Configurable, see typical pin layout above
-#define MIN_BUFFER_SIZE 18         // Minimum buffer size for read function
-MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
-MFRC522::MIFARE_Key key;
-
-void setup() {
-
-   Serial.begin(9600);
-
-  //start up wifly
-  WiFly.begin();
-
-  //Connect to network
-  if (!WiFly.join(ssid, passphrase)) {
-    Serial.println("Association failed.");
-    while (1) {
-      // Hang on failure.
-    }
-  }
-
-  //print out wifly IP
-  Serial.println(WiFly.ip());
-
-  SPI.begin();        // Init SPI bus
-  mfrc522.PCD_Init(); // Init MFRC522 card
-
- // Prepare the key (used both as key A and as key B)
- // using FFFFFFFFFFFFh which is the default at chip delivery from the factory
-  for (int i = 0; i < 6; i++) {
-      key.keyByte[i] = 0xFF;
-  }
-
-}
-
-void loop() {
-
-    // Look for new cards
-    if ( ! mfrc522.PICC_IsNewCardPresent())
-        return;
-
-    // Select one of the cards
-    if ( ! mfrc522.PICC_ReadCardSerial())
-        return;
-
-    byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
-    // Check for compatibility
-    if (    piccType != MFRC522::PICC_TYPE_MIFARE_MINI
-        &&  piccType != MFRC522::PICC_TYPE_MIFARE_1K
-        &&  piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
-        Serial.println(F("This sample only works with MIFARE Classic cards."));
-        return;
-    }
-
-    // In this sample we use the second sector,
-    // that is: sector #1, covering block #4 up to and including block #7
-    byte sector         = 1;
-    byte blockAddr      = 4;
-    //will need to get rid of this. This is the
-    //actual value in the block of data I'm reading
-    byte dataBlock[] = "DYND12345";
-    byte trailerBlock   = 7;
-    byte status;
-    byte buffer[MIN_BUFFER_SIZE];
-    byte size = sizeof(buffer);
-
-    // In order to read or write data to a PICC, the card must first be
-    //authenticated using a key. Below, the PICC is being authenticated using
-    //key A so we can read data from card
-    Serial.println(F("Authenticating using key A..."));
-    status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
-
-    //check if authenticated
-    if (status != MFRC522::STATUS_OK) {
-        Serial.print(F("PCD_Authenticate() failed: "));
-        Serial.println(mfrc522.GetStatusCodeName(status));
-        return;
-    }
-
-    // Read data from the block
-    Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
-    Serial.println(F(" ..."));
-
-    //reads data from the specified block address and puts
-    //it into the buffer
-    status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
-
-    //If read status is ok, call sendMessage function
-    if (status == MFRC522::STATUS_OK) {
-        sendMessage(buffer,sizeof(dataBlock));
-    }
-    else{
-        Serial.print(F("MIFARE_Read() failed: "));
-        Serial.println(mfrc522.GetStatusCodeName(status));
-    }
-
-
-
-    // Halt PICC
-    mfrc522.PICC_HaltA();
-    // Stop encryption on PCD
-    mfrc522.PCD_StopCrypto1();
-
-}
-
-/*  Function sendMessage
- *  Description: Function sends data over to the server. Data is passed in the
- *  buffer variable with the size of the data as the int. In the beginning of
- *  the function, the Wifly connects to the server via port 5000. Port 5000
- *  can be configured to another port if needed. Once the Wifly client has
- *  been connected, the buffer is iterated through and passed as chars to
- *  the server using client.print(). Once the data size cap is reached, the wifly
- *  disconnects from the socket.
- *  Inputs: pointer to a byte and an int
- *  Outputs: None.
- */
- void sendMessage(byte *buffer,int dataSize)
- {
-  //Creates WiFly client attached to the server through port 5000
-   WiFlyClient client(server, 5000);
-     if(client.connect())
-    {
-
-      Serial.println("Connected!");
-      char c; //char variable for buffer value
-
-      //converts decimals in buffer to chars and sends across to server
-      for (int i=0; i < dataSize; i++)
-      {
-         client.print(c = buffer[i]);
-      }
-
-      //disconnects from socket
-      client.println();
-      client.stop();
-    }
-    else
-    {
-      Serial.println("Connection failed. Is port open?");
-
-    }
-    // If we're disconnected, stop the client:
-    if (!client.connected())
-    {
-      Serial.println(F("Disconnecting."));
-      client.stop();
-    }
- }
-


removed 2 way communication

removed 2 way communication

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -63,7 +63,7 @@

   char charBuf[send_length+5];
   send_message.toCharArray(charBuf, send_length+5);
-  Serial.write(charBuf);
+  //Serial.write(charBuf);
 }

 void recieve_data() {


lower sensitivity

lower sensitivity

--- sketch/CurieDice/CurieDice.ino
+++ sketch/CurieDice/CurieDice.ino
@@ -132,7 +132,7 @@
   movement = 0;

   for (int i=0; i<6; i++) {
-    int m = (abs(vprev[i]-vraw[i])) >> 8;
+    int m = (abs(vprev[i]-vraw[i])) >> 9;
     if (m>movement) movement = m;
     if (maxMove[i]==0 && m>MOVE_THRESHOLD) { maxMove[i]=m; moves++;}
   }


rewire

rewire

--- sketchbook/printer/printer.ino
+++ sketchbook/printer/printer.ino
@@ -1,8 +1,8 @@
 #include <Motor.h>

-Motor motorX(8, 9, 10, 11);
-Motor motorY(8, 9, 10, 11);
-Motor motorZ(2, 3, 4, 5);
+Motor motorX(2, 3, 4, 5);
+Motor motorY(6, 7, 8, 9);
+Motor motorZ(12, 12, 12, 12);

 void setup() {
     Serial.begin(9600);


Automatic motor driver power control.

Automatic motor driver power control.

--- RobotBase.ino
+++ RobotBase.ino
@@ -20,8 +20,7 @@

 // common vars //
 unsigned long lastCommandTime;
-unsigned long commandTime;
-unsigned long cmdTimeout = 2500;
+unsigned long commandTimeout = 2500;
 boolean IsConnected = false;

 // RoboClaw //
@@ -30,6 +29,8 @@
 #define RC_TX_PIN 11
 RoboClaw roboclaw(RC_RX_PIN, RC_TX_PIN);
 boolean driveEnabled = false;
+unsigned long lastDriveCommandTime;
+unsigned long driveCommandTimeout = 60000;

 // propulsion vars
 #define MOTOR_VELOCITY_0 64
@@ -83,6 +84,7 @@
   // serial input
   ReadSerial();
   if (IsConnected) CheckCommandTimeout();
+  if (driveEnabled) CheckDriveCommandTimeout();

   // motors
   if (motor_counter > 0) motor_counter--;
@@ -141,10 +143,10 @@

 void CheckCommandTimeout()
 {
-  if (cmdTimeout == 0) return;
-  commandTime = millis();
+  if (commandTimeout == 0) return;
+  unsigned long commandTime = millis();
   if (commandTime >= lastCommandTime) commandTime -= lastCommandTime; else lastCommandTime = 0;
-  if (commandTime > cmdTimeout) OnDisconnected();
+  if (commandTime > commandTimeout) OnDisconnected();
 }

 void OnDisconnected()
@@ -266,7 +268,8 @@
 // update motor velocities
 void updateMotors()
 {
-  if (!driveEnabled) return;
+  if (motor1 == motor1_target && motor2 == motor2_target) return;
+  if (!driveEnabled) { driveEnable(true); delay(20); }

   // M1
   if (motor1 != motor1_target)
@@ -284,6 +287,7 @@
       else motor1 = motor1_target;
     }
     roboclaw.ForwardBackwardM1(RC_ADDR, motor1);
+    lastDriveCommandTime = millis();
   }
   // M2
   if (motor2 != motor2_target)
@@ -301,6 +305,7 @@
       else motor2 = motor2_target;
     }
     roboclaw.ForwardBackwardM2(RC_ADDR, motor2);
+    lastDriveCommandTime = millis();
   }
 }

@@ -314,6 +319,7 @@
   motor2 = MOTOR_VELOCITY_0;
   roboclaw.ForwardBackwardM1(RC_ADDR, motor1);
   roboclaw.ForwardBackwardM2(RC_ADDR, motor2);
+  lastDriveCommandTime = millis();
 }

 // enable/disable motor driver communication and power
@@ -323,6 +329,7 @@
   {
     pulsePin(MOTORS_PIN, 20);
     driveUART(true);
+    lastDriveCommandTime = millis();
   }
   else
   {
@@ -337,6 +344,14 @@
   if (action) roboclaw.begin(38400);
   else roboclaw.end();
   driveEnabled = action;
+}
+
+void CheckDriveCommandTimeout()
+{
+  if (driveCommandTimeout == 0) return;
+  unsigned long driveCommandTime = millis();
+  if (driveCommandTime >= lastDriveCommandTime) driveCommandTime -= lastDriveCommandTime; else lastDriveCommandTime = 0;
+  if (driveCommandTime > driveCommandTimeout) driveEnable(false);
 }

 //=======================================
@@ -381,7 +396,7 @@
 {
   cmd = buf[1];
   // command timeout
-  if (cmd == 'T' || cmd == 't') cmdTimeout = bctoi(2, 2) * 100;
+  if (cmd == 'T' || cmd == 't') commandTimeout = bctoi(2, 2) * 100;
   else
   if (cmd == 'C' || cmd == 'c') doCRC = buf[2] == '1';
   else
@@ -394,7 +409,7 @@
 void battery()
 {
   digitalWrite(BATTERY_PIN, HIGH);
-  analogRead(0);
+  delay(20);
   unsigned long voltage = (unsigned long)analogRead(0) * 625 >> 7;
   digitalWrite(BATTERY_PIN, LOW);
   Serial.write('B');


Fix the new lengths here since I reduce their size in a previous commit.

--- SimpleCSV.ino
+++ SimpleCSV.ino
@@ -13,14 +13,13 @@
 Fat16 file;

 #define FORM_BOUNDARY_BASE       F("KSFile")
-#define FORM_BOUNDARY            F("--KSFile")
 #define FORM_BOUNDARY_END        F("--KSFile--\r\n")
-#define FORM_BOUNDARY_END_SIZE   22
+#define FORM_BOUNDARY_END_SIZE   12
 #define FORM_BOUNDARY_START      F("--KSFile\r\n")
-#define FORM_BOUNDARY_START_SIZE 20
+#define FORM_BOUNDARY_START_SIZE 10

 #define FILE_HEADER              F("Content-Disposition: form-data; name=\"file\"; filename=\"f.csv\"\r\nContent-Type: text/csv\r\n\r\n")
-#define FILE_HEADER_SIZE         96
+#define FILE_HEADER_SIZE         89 //       '         '         '          '          '          '            '         '            9

 #define SUCCESS_RESPONSE_SIZE    17


Unnecessary update

Unnecessary update

--- Garduino.ino
+++ Garduino.ino
@@ -42,7 +42,7 @@
 int soilsensor = 0; // Soil humidity sensor integer, Arduino A0
 int nem; // Humidity integer

-int INTERNAL; // for ESP8266
+

 void setup() {
@@ -53,7 +53,7 @@
  // Join the Wi-Fi network with ESP8266 Module
  Serial.println("AT"); //ESP modülümüz ile bağlantı kurulup kurulmadığını kontrol ediyoruz.
  delay(3000); //ESP ile iletişim için 3 saniye bekliyoruz.
- analogReference(INTERNAL);
+
  if(Serial.find("OK")){         //esp modülü ile bağlantıyı kurabilmişsek modül "AT" komutuna "OK" komutu ile geri dönüş yapıyor.
     Serial.println("AT+CWMODE=1"); //esp modülümüzün WiFi modunu STA şekline getiriyoruz. Bu mod ile modülümüz başka ağlara bağlanabilecek.
     delay(2000);


Start 1.6 version - cleanup

Start 1.6 version - cleanup

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -40,14 +40,14 @@
 #define DEBUG_BATT    (1 << 8)  // battery

 // DEBUG word for debugging program - bitmask values
-//#define DEBUG         (DEBUG_BATT + DEBUG_ACT)
-#define DEBUG         0
+#define DEBUG         (DEBUG_BATT + DEBUG_ACT)
+//#define DEBUG         0
 //#define DEBUG         0xff

 // Digital VFO program name & version
 const char *ProgramName = "DigitalVFO";
-const char *Version = "1.5";
-const char *MinorVersion = ".2";
+const char *Version = "1.6";
+const char *MinorVersion = ".0";
 const char *Callsign = "ac3dn";

 // display constants - below is for ubiquitous small HD44780 16x2 display
@@ -326,7 +326,7 @@
 /* restart the Teensy, without invoking bootloader. */
 void restart(void)
 {
-  Serial.printf(F("Restarting ...\n"));
+  Serial.print(F("Restarting ..."));
   delay(500);
   WRITE_RESTART(0x5FA0004);
 }
@@ -334,7 +334,7 @@
 /* reboot the Teensy, invoking bootloader. */
 void reboot(void)
 {
-  Serial.printf(F("Rebooting ...\n"));
+  Serial.print(F("Rebooting ..."));
   delay(500);
   _reboot_Teensyduino_();
 }
@@ -434,23 +434,23 @@
 void decode_debug_levels(int debug)
 {
   if (debug & DEBUG_DDS)
-    Serial.println(F("    DEBUG_DDS\tbit is set"));
+    Serial.print(F("    DEBUG_DDS\tbit is set\n"));
   if (debug & DEBUG_FREQ)
-    Serial.println(F("    DEBUG_FREQ\tbit is set"));
+    Serial.print(F("    DEBUG_FREQ\tbit is set\n"));
   if (debug & DEBUG_MENU)
-    Serial.println(F("    DEBUG_MENU\tbit is set"));
+    Serial.print(F("    DEBUG_MENU\tbit is set\n"));
   if (debug & DEBUG_EVENT)
-    Serial.println(F("    DEBUG_EVENT\tbit is set"));
+    Serial.print(F("    DEBUG_EVENT\tbit is set\n"));
   if (debug & DEBUG_ACT)
-    Serial.println(F("    DEBUG_ACT\tbit is set"));
+    Serial.print(F("    DEBUG_ACT\tbit is set\n"));
   if (debug & DEBUG_RE)
-    Serial.println(F("    DEBUG_RE\tbit is set"));
+    Serial.print(F("    DEBUG_RE\tbit is set\n"));
   if (debug & DEBUG_INT)
-    Serial.println(F("    DEBUG_INT\tbit is set"));
+    Serial.print(F("    DEBUG_INT\tbit is set\n"));
   if (debug & DEBUG_DISP)
-    Serial.println(F("    DEBUG_DISP\tbit is set"));
+    Serial.print(F("    DEBUG_DISP\tbit is set\n"));
   if (debug & DEBUG_BATT)
-    Serial.println(F("    DEBUG_BATT\tbit is set"));
+    Serial.print(F("    DEBUG_BATT\tbit is set\n"));
 }

 //----------------------------------------
@@ -500,16 +500,16 @@
 void banner(void)
 {
   show_credits(false);
-  delay(800);    // wait a bit
+  delay(500);    // wait a bit

   // do a fade out, clear screen then normal brightness
   for (int i = LcdBrightness; i; --i)
   {
     analogWrite(mc_Brightness, i);
-    delay(20);
+    delay(10);
   }
   lcd.clear();
-  delay(200);
+  delay(100);
   analogWrite(mc_Brightness, LcdBrightness);
 }

@@ -1960,7 +1960,7 @@
   Serial.begin(19200);

 #if INIT_EEPROM
-  Serial.printf(F("Erasing EVERYTHING in EEPROM!\n"));
+  Serial.print(F("Erasing EVERYTHING in EEPROM!\n"));
   initialize_eeprom();  // WARNING! Destroys the EEPROM stored values
 #endif

@@ -1977,15 +1977,15 @@
   pinMode(mc_Brightness, OUTPUT);
   pinMode(mc_Contrast, OUTPUT);

+  // initialize the display
+  lcd.begin(NumCols, NumRows);      // define display size
+  lcd.noCursor();
+  lcd.clear();
+
   // get state back from EEPROM, set display brightness/contrast
   restore_from_eeprom();
   analogWrite(mc_Brightness, 0);    // display off while initializing
   analogWrite(mc_Contrast, LcdContrast);
-
-  // initialize the display
-  lcd.begin(NumCols, NumRows);      // define display size
-  lcd.noCursor();
-  lcd.clear();

   // create underlined space for frequency display
   lcd.createChar(SpaceChar, sel_digits[SpaceIndex]);
@@ -2012,7 +2012,7 @@

     Serial.printf(F("Resetting brightness to %d, contrast to %d and hold/dclick times\n"),
                   LcdBrightness, LcdContrast);
-    Serial.printf(F("Click the RE button to continue...\n"));
+    Serial.print(F("Click the RE button to continue..."));

     // show user we were reset
     lcd.clear();
@@ -2031,16 +2031,7 @@
     delay(500);
   }

-#if (DEBUG != 0)
-  Serial.printf(F("\n"));
-  Serial.printf(F("*************************************************\n"));
-  Serial.printf(F("*            %s %s%s (%s)           *\n"),
-                ProgramName, Version, MinorVersion, Callsign);
-  Serial.printf(F("*************************************************\n"));
-  Serial.printf(F("\n"));
-#else
   Serial.printf(F("%s %s%s (%s)\n"), ProgramName, Version, MinorVersion, Callsign);
-#endif

 #if (DEBUG != 0)
   Serial.printf(F("DEBUG is defined as %06X:\n"), DEBUG);
@@ -2068,7 +2059,7 @@

   // show the main screen and continue in loop()
   show_main_screen();
-  Serial.printf(F("\nReady!\n"));
+  Serial.print(F("Ready!\n"));
 }

 //----------------------------------------


temf response in JSON

temf response in JSON

--- weather_station/dashboard/arduino/weather_station_02.ino
+++ weather_station/dashboard/arduino/weather_station_02.ino
@@ -56,11 +56,27 @@
     // read the command
     String request  = client.readString();
     request.trim();   //kill whitespace
-     if (request == "tempf") {
-      //client.print("
Current Temperature: ");
-      client.print(f);
-      //client.print(" degrees F");
-     }
+
+      if (request == "tempf") {
+        client.println("HTTP/1.1 200 OK");
+        client.println("Content-type: text/javascript");
+        client.println("Access-Control-Allow-Origin: *");
+
+        // JSON response
+        client.print("{\"type\":\"temperature\",\"scale\":\"fahrenheit\",\"title\":\"Fahrenheit\", \"value\":\"");
+        client.print(f);
+        client.print("\"}");
+      }
+
+      if (request == "tempc") {
+        client.println("HTTP/1.1 200 OK");
+        client.println("Content-type: text/javascript");
+        client.println("Access-Control-Allow-Origin: *");
+
+        client.print("{\"type\":\"tempature!\"}");
+        client.print("{\"title\":\"Celsius\"}");
+        client.print("{\"value\":\"f\"}");
+      }
      if (request == "tempc") {
       //client.print("
Current Temperature: ");
       client.print(c);
@@ -121,4 +137,4 @@
   double T = log(VP/0.61078); // temp var

   return (241.88 * T) / (17.558-T);
-}+}


send sensible pixel data

send sensible pixel data

--- arduino/led_matrix/led_matrix.ino
+++ arduino/led_matrix/led_matrix.ino
@@ -31,6 +31,5 @@
   }
   FastLED.show();
   Serial.println("END");
-  delay(1000);
 }


Fix turning off voice 4, increase audio library memory

--- roto2.ino
+++ roto2.ino
@@ -72,7 +72,7 @@
 void setup() {
   Serial.begin(115200);

-  AudioMemory(8);
+  AudioMemory(20);
   audioShield.enable();
   audioShield.volume(0.5);

@@ -237,7 +237,7 @@
       sine14.frequency(fund * 0.5);
       sine15.frequency(fund * 1.5);
       sine16.frequency(fund * 2.0);
-      envelope3.noteOn();
+      envelope4.noteOn();
       break;
   }
 }


Improved the comments for clearer usage info

--- scripts/McbController.ino
+++ scripts/McbController.ino
@@ -1,22 +1,23 @@
 /*
   MCB Controller That Runs On The Arduino Platform for debug or very very simple controllers

-  Some basic MCB speed control for the Ubiquity Robotics Magni Robot is implemented
-  This code is meant for the Arduino Nano model.
+  A basic MCB speed control for the Ubiquity Robotics Magni Robot is implemented
+  This code is meant for the Arduino Nano model but because of how IDE works can easily be used
+  on other processors as supported by the Arduino IDE board support packages. .

-  This code could be used to build upon a far more complex robot based on the Arduino platform
-  or other platform supported by the Arduino IDE libraries.
+  This is meant as a debug tool for board bringup as well as example code showing how to send
+  Magni commands with the way we do checksum and transmission over serial.

-  As a minimum the Arduino 5V level TX signal goes to MCB board P508  RX pin and Arduino Ground goes to P508 ground.
-  Optionally you can power the Arduino all from P508 because there is 5V VCC on P508 as well.
+  User needs to power up his Arduino Nano from a usb power source or directly from Magni P508  GND and VCC
+  The Arduino 5V level TX pin goes to the P508 5V RX pin and Arduino Ground goes to P508 ground.
+  Optionally you can power the Arduino all from P508 because there is 5V VCC on P508 as well to go to Nano +5 line.
   (Note that to do that you must tie MCB Vcc on P508 to Arduino 5V power because the spec for VIN is for 6V or more)

   Usage Instructions
-  - Ground the ENABLE_SPEED_PIN
-  - Connect tow 1k to 20k pots with each of the ends on GND and Vcc.
-    Center tap of one pot to A1, center tap of other pot to A2.
-    Default with no jumpers is for each pot to separately control a single wheel.
-  - Optionally ground the ENABLE_JOYSTICK pin to interprit two pots as joystick
+  - Connect two 1k to 20k linear taper pots with each of the ends on GND and Vcc.
+    Center tap of one pot to Arduino A1 and the center tap of the other pot to Arduino A2.
+  - Default with no jumpers is for each pot to separately control a single wheel.
+  - Optionally ground the ENABLE_JOYSTICK pin to interprit two pots as a simple joystick
   - Optionally a normaly closed switch from ground to ENABLE_SPEED_PIN for switch that must close to run motors
     When the ENABLE_SPEED_PIN is floating motors are enabled. When it goes to ground motors stop


added pressure proto

added pressure proto

--- sketches/hive_monitor/hive_monitor.ino
+++ sketches/hive_monitor/hive_monitor.ino
@@ -42,6 +42,7 @@
 float get_ext_humidity(void);
 float get_volts(void);
 float get_amps(void);
+float get_pressure(void);

 /* --- Objects --- */
 DHT int_dht(DHT_INTERNAL_PIN, DHT_TYPE);


constrain to values outside range

constrain to values outside range

--- servometer/servometer.ino
+++ servometer/servometer.ino
@@ -197,7 +197,7 @@
 */
 int findServoAngle(String value)
 {
-  return (180 - map(value.toInt(), 0, 2000, SERVO_MIN, SERVO_MAX));
+  return constrain((180 - map(value.toInt(), 0, 2000, SERVO_MIN, SERVO_MAX)), SERVO_MIN, SERVO_MAX);
 }

 /*


Added voltage calibration

Added voltage calibration

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -154,7 +154,8 @@
 byte batt80[8]    = {0x0e,0x1b,0x11,0x1f,0x1f,0x1f,0x1f,0x1f};
 byte batt100[8]   = {0x0e,0x1b,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f};
 byte battover[8]  = {0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f};
-byte battnone[8]  = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+//byte battnone[8]  = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+byte battnone[8]  = {0x04,0x06,0x0d,0x15,0x14,0x10,0x00,0x00}; // a USB log (sort of)

 // array of references to the 9 'battery symbol' characters
 byte *batt_syms[] = {battunder, batt00, batt20, batt40, batt60, batt80, batt100, battover, battnone};
@@ -517,6 +518,139 @@
   lcd.write(BlankRow);
   lcd.setCursor(0, 1);
   lcd.write(mode2display(VfoMode));
+}
+
+
+//----------------------------------------
+// Toggle the VFO mode: vfo_Online or vfo_Standby.
+//
+// Note that DDS-60 only updates if VfoMode is vfo_Online.
+// So we must be sure to set mode to vfo_Standby after dds_standby()
+// and set mode to vfo_Online before dds_online().
+//----------------------------------------
+void vfo_toggle_mode(void)
+{
+  if (VfoMode == vfo_Online)
+  {
+    // DDS goes into standby, change mode
+    dds_standby();
+    VfoMode = vfo_Standby;
+  }
+  else
+  {
+    // DDS goes online, change mode
+    VfoMode = vfo_Online;
+    dds_online();
+  }
+
+  // update display
+  vfo_display_mode();
+}
+
+//----------------------------------------
+// Measure the battery voltage.
+// We measure every "MeasureVoltageDelay" milliseconds, update the battery symbol.
+// If DEBUG reporting is turned on, we report every "ReportVoltageDelay" measurements.
+//----------------------------------------
+
+#if (DEBUG & DEBUG_BATT)
+  int batt_report_count = 0;
+#endif
+
+float get_volts(void)
+{
+  // measure the raw volts and adjust
+  // the "measured" voltage read is in range [0..1023] over 3.3 volts
+  // the VDIV_RATIO is the voltage divide ratio, R12 and R13
+  // VoltsCalibrate is the calibration value, a float
+  UINT measured = analogRead(mc_BattVolts);
+  float voltage = 3.3 * measured / 1023;   // this is the raw, unadjusted voltage
+
+  return voltage * (VDIV_RATIO * VoltsCalibrate/VCALIBBASE);
+}
+
+void measure_battery(void)
+{
+  // get the time since the last measurement
+  static long last_volts_time = -MeasureVoltageDelay;    // millis() value last time we measured
+  long now_milli = millis();
+
+  if (now_milli < last_volts_time)
+    last_volts_time = -MeasureVoltageDelay;    // handle wraparound of millis()
+
+  // if not time yet, return
+  if (now_milli < last_volts_time + MeasureVoltageDelay)
+    return;
+
+  // measuring, set measurement time to "now"
+  last_volts_time = now_milli;
+
+  // measure voltage, we will get a value of 1023 for 3.3 volts
+  // adjust the divider to calibrate
+  // with my crappy multimeter:  (32.11/9.90)
+  float volts = get_volts();
+  AverageVoltage = moving_average(volts);
+
+  int percent = (int) ((AverageVoltage - MinVoltage) / (MaxVoltage - MinVoltage) * 100.0);
+
+#if (DEBUG & DEBUG_BATT)
+  if (++batt_report_count > 0)
+  {
+//    Serial.printf(F("volts: %.2fv, value=%d%%, "), AverageVoltage, percent);
+    Serial.printf(F("volts: %.2fv, "), AverageVoltage);
+  }
+#endif
+
+  // figure out which battery symbol to use
+  if (AverageVoltage < NoBattVoltage)
+  {
+    BatterySymbol = battnone;
+#if (DEBUG & DEBUG_BATT)
+    if (batt_report_count > 0)
+    {
+      Serial.printf(F("no battery\n"));
+    }
+#endif
+  }
+  else if (AverageVoltage < MinVoltage)
+  {
+    BatterySymbol = battunder;
+#if (DEBUG & DEBUG_BATT)
+    if (batt_report_count > 0)
+    {
+      Serial.printf(F("battery under voltage\n"));
+    }
+#endif
+  }
+  else if (AverageVoltage > OverVoltage)
+  {
+    BatterySymbol = battover;
+#if (DEBUG & DEBUG_BATT)
+    if (batt_report_count > 0)
+    {
+      Serial.printf(F("OVER VOLTAGE\n"));
+    }
+#endif
+  }
+  else
+  {
+    // calculate the battery symbol depending on %full
+    int batt_bucket = min((int) (percent/(100/6)), 5);
+    BatterySymbol = batt_syms[batt_bucket + 1];
+#if (DEBUG & DEBUG_BATT)
+    if (batt_report_count > 0)
+    {
+      Serial.printf(F("batt_bucket=%d\n"), batt_bucket+1);
+    }
+#endif
+  }
+
+#if (DEBUG & DEBUG_BATT)
+  if (batt_report_count > 0)
+  {
+    batt_report_count = -ReportVoltageDelay;
+  }
+#endif
 }

@@ -1563,7 +1697,7 @@
 const int EepromDClickTime = NEXT_FREE;
 #define NEXT_FREE   (EepromDClickTime + sizeof(ReDClickTime))

-// address for float 'voltage calibrate'
+// address for int 'voltage calibrate'
 const int EepromVoltsCalibrate = NEXT_FREE;
 #define NEXT_FREE   (EepromVoltsCalibrate + sizeof(VoltsCalibrate))

@@ -1594,12 +1728,6 @@
   EEPROM.put(EepromHoldClickTime, ReHoldClickTime);
   EEPROM.put(EepromDClickTime, ReDClickTime);
   EEPROM.put(EepromVoltsCalibrate, VoltsCalibrate);
-
-  Serial.printf(F("save_to_eeprom: VfoClockOffset=%ld\n"), VfoClockOffset);
-  Serial.printf(F("save_to_eeprom: VoltsCalibrate=%ld\n"), VoltsCalibrate);
-  Serial.printf(F("save_to_eeprom: EepromVfoClockOffset=%d\n"), EepromVfoClockOffset);
-  Serial.printf(F("save_to_eeprom: EepromVoltsCalibrate=%d\n"), EepromVoltsCalibrate);
-  Serial.printf(F("save_to_eeprom: EepromSaveFreqBase=%d\n"), EepromSaveFreqBase);
 }

 //----------------------------------------
@@ -1616,13 +1744,7 @@
   EEPROM.get(EepromContrast, LcdContrast);
   EEPROM.get(EepromHoldClickTime, ReHoldClickTime);
   EEPROM.get(EepromDClickTime, ReDClickTime);
-  EEPROM.put(EepromVoltsCalibrate, VoltsCalibrate);
-
-  Serial.printf(F("restore_from_eeprom: VfoClockOffset=%ld\n"), VfoClockOffset);
-  Serial.printf(F("restore_from_eeprom: VoltsCalibrate=%ld\n"), VoltsCalibrate);
-  Serial.printf(F("restore_from_eeprom: EepromVfoClockOffset=%d\n"), EepromVfoClockOffset);
-  Serial.printf(F("restore_from_eeprom: EepromVoltsCalibrate=%d\n"), EepromVoltsCalibrate);
-  Serial.printf(F("restore_from_eeprom: EepromSaveFreqBase=%d\n"), EepromSaveFreqBase);
+  EEPROM.get(EepromVoltsCalibrate, VoltsCalibrate);
 }

 //----------------------------------------
@@ -1661,7 +1783,7 @@

 #if (DEBUG != 0)

-#define DELAY_MS 200
+#define DELAY_MS 20

 void dump_eeprom(void)
 {
@@ -1845,7 +1967,9 @@
 void setup(void)
 {
   // initialize the serial console
-  Serial.begin(115200);
+  Serial.begin(19200);
+
+//  initialize_eeprom();  // DEBUG

   // initialize the BlankRow global to a blank string length of a display row
   BlankRow = (char *) malloc(NumCols + 1);
@@ -2692,10 +2816,13 @@
 // a 'click' action only.
 //----------------------------------------

+#define VOLTS_DELAY_MS   500
+
 void volts_calibrate_action(struct Menu *menu, int item_num)
 {
-  UINT save_calibrate = VoltsCalibrate;  // save the existing value
-  int seldig = 0;                        // the selected digit in the display
+  UINT save_calibrate = VoltsCalibrate; // save the existing value
+  int seldig = 0;                       // the selected digit in the display
+  ULONG delay_time = 0;                 // show voltage every whenever

   // get rid of any stray events to this point
   event_flush();
@@ -2773,37 +2900,24 @@
           // ignored events we don't handle
           break;
       }
-
-      // show voltage calibrate value
+
+      // show new voltage calibrate value
       display_sel_offset(VoltsCalibrate, seldig, 5, 10, 1);
     }
-  }
-}
-
-//----------------------------------------
-// Toggle the VFO mode: vfo_Online or vfo_Standby.
-//
-// Note that DDS-60 only updates if VfoMode is vfo_Online.
-// So we must be sure to set mode to vfo_Standby after dds_standby()
-// and set mode to vfo_Online before dds_online().
-//----------------------------------------
-void vfo_toggle_mode(void)
-{
-  if (VfoMode == vfo_Online)
-  {
-    // DDS goes into standby, change mode
-    dds_standby();
-    VfoMode = vfo_Standby;
-  }
-  else
-  {
-    // DDS goes online, change mode
-    VfoMode = vfo_Online;
-    dds_online();
-  }
-
-  // update display
-  vfo_display_mode();
+
+    // show instantaneous voltage, every short period
+    // we must not display voltage every time through loop, too fast!
+    if (millis() > delay_time)
+    {
+      float volts = get_volts();
+
+      sprintf(FreqBuffer, "%.2fv", volts);
+      lcd.setCursor(0, 1);
+      lcd.print(FreqBuffer);
+
+      delay_time = millis() + VOLTS_DELAY_MS;
+    }
+  }
 }

 //----------------------------------------
@@ -2849,112 +2963,6 @@
 struct MenuItem mi_credits = {"Credits", NULL, &credits_action};
 struct MenuItem *mia_main[] = {&mi_slots, &mi_settings, &mi_reset, &mi_credits};
 struct Menu menu_main = {"Menu", ALEN(mia_main), mia_main};
-
-//----------------------------------------
-// Measure the battery voltage.
-// We measure every "MeasureVoltageDelay" milliseconds, update the battery symbol.
-// If DEBUG reporting is turned on, we report every "ReportVoltageDelay" measurements.
-//----------------------------------------
-
-#if (DEBUG & DEBUG_BATT)
-  int batt_report_count = 0;
-#endif
-
-float get_volts(void)
-{
-  // measure the raw volts and adjust
-  // the UINT read is in range [0..1023] over 3.3 volts
-  // the VDIV_RATIO is the voltage divide ratio, R12 and R13
-  // VoltsCalibrate is the calibration value, a float
-  UINT measured = analogRead(mc_BattVolts);
-  float voltage = 3.3 * measured / 1023;
-
-  return voltage * (VDIV_RATIO * VoltsCalibrate/VCALIBBASE);
-}
-
-void measure_battery(void)
-{
-  // get the time since the last measurement
-  static long last_volts_time = -MeasureVoltageDelay;    // millis() value last time we measured
-  long now_milli = millis();
-
-  if (now_milli < last_volts_time)
-    last_volts_time = -MeasureVoltageDelay;    // handle wraparound of millis()
-
-  // if not time yet, return
-  if (now_milli < last_volts_time + MeasureVoltageDelay)
-    return;
-
-  // measuring, set measurement time to "now"
-  last_volts_time = now_milli;
-
-  // measure voltage, we will get a value of 1023 for 3.3 volts
-  // adjust the divider to calibrate
-  // with my crappy multimeter:  (32.11/9.90)
-  float volts = get_volts();
-  AverageVoltage = moving_average(volts);
-
-  int percent = (int) ((AverageVoltage - MinVoltage) / (MaxVoltage - MinVoltage) * 100.0);
-
-#if (DEBUG & DEBUG_BATT)
-  if (++batt_report_count > 0)
-  {
-//    Serial.printf(F("volts: %.2fv, value=%d%%, "), AverageVoltage, percent);
-    Serial.printf(F("volts: %.2fv, "), AverageVoltage);
-  }
-#endif
-
-  // figure out which battery symbol to use
-  if (AverageVoltage < NoBattVoltage)
-  {
-    BatterySymbol = battnone;
-#if (DEBUG & DEBUG_BATT)
-    if (batt_report_count > 0)
-    {
-      Serial.printf(F("no battery\n"));
-    }
-#endif
-  }
-  else if (AverageVoltage < MinVoltage)
-  {
-    BatterySymbol = battunder;
-#if (DEBUG & DEBUG_BATT)
-    if (batt_report_count > 0)
-    {
-      Serial.printf(F("battery under voltage\n"));
-    }
-#endif
-  }
-  else if (AverageVoltage > OverVoltage)
-  {
-    BatterySymbol = battover;
-#if (DEBUG & DEBUG_BATT)
-    if (batt_report_count > 0)
-    {
-      Serial.printf(F("OVER VOLTAGE\n"));
-    }
-#endif
-  }
-  else
-  {
-    // calculate the battery symbol depending on %full
-    int batt_bucket = min((int) (percent/(100/6)), 5);
-    BatterySymbol = batt_syms[batt_bucket + 1];
-#if (DEBUG & DEBUG_BATT)
-    if (batt_report_count > 0)
-    {
-      Serial.printf(F("batt_bucket=%d\n"), batt_bucket+1);
-    }
-#endif
-  }
-
-#if (DEBUG & DEBUG_BATT)
-  if (batt_report_count > 0)
-  {
-    batt_report_count = -ReportVoltageDelay;
-  }
-#endif
-}

 //----------------------------------------
 // Do any commands from the external controller.
@@ -2991,7 +2999,7 @@
 // Handle events from the rotary encoder.
 //----------------------------------------

-void handle_RE_events()
+void handle_RE_events(void)
 {
   while (event_pending() > 0)
   {


Add giant explanation of Timers and bit concepts, fix GUI strings

--- Dremelfuge.ino
+++ Dremelfuge.ino
@@ -10,7 +10,7 @@
 #include "LEDButton.h"                                  // include custom library which is in the same directory as this file
                                                         // because it's a relative path, use "" LITERAL PATHNAME
 #include "karina_utility.cpp"                           // for void printfSecs(unsigned long seconds, T& t)
-
+#include <avr/interrupt.h>
 //============================GLOBAL VARIABLES=================================//
 /* *** These variables MUST be global because they're being used by multiple
   totally separate functions--static local won't do
@@ -79,7 +79,121 @@
   lcd.setCursor(0, 2);
   lcd.print(F("Set speed: ___"));
   lcd.setCursor(0, 3);
-  lcd.print(F("   Push to Start!"));
+  lcd.print(F("   Push to "));
+
+  /* Explanation of timer interrupts and applications of bit operations:
+    An interrupt is a special type of user-defined event; interrupts occur either
+    when a timer reaches a certain value (timer interrupts), or when a pin
+    changes state (external interrupts). This block will focus on timer
+    interrupts. Note that the terms "interrupt" as an event and
+    "Interrupt Service Routine (ISR)," which is the function that is run when an
+    interrupt occurs, are used almost interchangeably.
+
+    "n" = timer number; Timer0, Timer1, ...
+    "x" = A or B, in the context of named regisers.
+    Registers are a small but very quickly-accessed memory location that reside
+    on the processor itself. Registers store special values that need to be read
+    and/or written very quickly.
+    ----------
+
+    MCUs have built-in timers. Timers are just modules used to measure time,
+    physically via the oscillation of Voltage storage in a capacitor-inductor
+    circuit, like an electric pendulum. To utilize this physical process in a
+    MCU, the timer circuit has many additional components: a counter register
+    whose value increments with each tick, a output comparison register whose
+    value is compared with the counter on every tick to let the programmer time
+    events, prescalers to change the frequency of the timer ticks, and a wave
+    generation module that can use the timer to produce various waveforms through
+    PWM, to name some main ones.
+
+    Timers have 2 primary modes of operation: 1) increment from 0 until a TOP
+    value is reached, and then reset to 0; 2) increment from 0 until a TOP value
+    is reached, and then decrement back down to 0. These are the main attributes
+    of the non-PWM and PWM modes, respectively. Generally, the latter should be
+    used for timing events, while the former should be used for PWM.
+    We shall pay special attention to the non-PWM modes for this project. There
+    are two non-PWM modes: Normal and CTC (Clear Timer on Compare match). In
+    Normal mode, *TCNTn (the register that holds the Timer CouNT) *keeps
+    incrementing until it overflows.** On the same tick (clock cycle) that
+    overflow occurs, the Timer/Counter Overflow flag (TOVn) is raised. In CTC
+    mode, TCNTn increments until a specific, user-set value is reached, at which
+    point TCNTn is cleared (set to 0). This user-set value is stored in OCRnx
+    (Output Compare Register nA or nB). Every single clock cycle, the value of
+    TCNTn is compared with OCRnx. On the clock cycle after the comparison returns
+    true, the corresponding OCFnx (Output Compare Flag) is raised. However, an
+    additional clock cycle must be spent clearing TCNTn, unlike Normal mode--this
+    represents a one-tick delay that must be taken into account in timing
+    calculations.
+    You _could_ use interrupts through Output Comparison on Normal mode just like
+    in CTC mode, but the calculation is comparatively not straightforward, so
+    using CTC mode is easier in most cases.
+
+    What determines the frequency of each tick? The clock cycle does! While AVRs
+    have a builtin system clock, whose processor speed determines its system
+    clock frequency, you can use "prescalers" to change the clock speed/tick
+    frequency of individual timers. Using a timer without prescalers would mean
+    using the system clock speed, which is way too fast for many practical
+    purposes. Prescalers effectively give individual timers slower clocks.
+    These prescaled clocks will be slower than the system clock by factors of 2--
+    that is, [frequency of prescaled clock = system clock frequency/pow(2, n)].
+    You can select between different prescalers in the TCCRnB bit string.
+
+    There are two Timer/Counter Control Registers, TCCRnA and TCCRnB, which
+    are bit strings whose different bit values correspond to the different Timer
+    settings: mode (set by WGMy Waveform Generation Mode bits in TCCRnA and
+    TCCRnB), whether/how to change the outputs of external pins (OCnx) when OCFnx
+    flags are raised (set by COMnxy COMpare match output mode bits in TCCRnA),
+    and what if any prescaler value to use (CSny bits in TCCRnB). All
+    combinations of modes and prescalers and output comparisons are valid.
+    Additionally, you can have up to 2 Output Control Registers, i.e. up to 2
+    values that the Timer is checked against every tick and that can ultimately
+    cause ISRs. These are OCRnA and OCRnB; "x" denotes a bit corresponding to
+    either OCR.
+    See the appropriate Atmel AVR datasheet for details on bit string layout.
+
+    Details of implementation:
+    An interrupt service routine (ISR) is a function that runs when an interrupt
+    flag is raised, i.e. ISRs are run when "interrupts" occur.
+    An interrupt flag is a bit that keeps track of whether a timer event has
+    occurred (1) or not (0). A timer event is either overflow (w/ flag TOVn) or
+    a successful comparison of the timer with the value in the output compare
+    register (when TCNTn == OCRnx, OCFnx is raised).
+    Interrupt flags are stored in interrupt flag registers. One interrupt flag
+    register is used for each timer. The value of/in an interrupt flag register
+    is a bit string whose bits correspond to which flags have been raised.
+
+    A timer mask (TIMSKn) is a string of bits that determines *which timer events
+    to pay attention to*, i.e. *which flags can trigger ISRs*, i.e. "which
+    interrupts are activated/attached." A bit set to 1 in TIMSKn means that that
+    associated flag will not be masked off, so that if that flag is raised, its
+    corresponding ISR will run automatically.
+    The bit masking is done behind the scenes, probably taken care of through
+    the configuration of the Timer circuit itself.
+
+    Bit concepts:
+    Generally, a bit mask is a string of *bits used to extract bit values of
+    interest from other bit strings,* usually by binary AND (&) in a process
+    called "masking off" the other bits outside the mask, or sometimes by binary
+    OR (|) in a process called "masking on" the other bits outside the mask.
+    When we set the bits in TIMSKn, we're "building a bit mask," determining
+    which bit values are of interest.
+
+    A bit value is meaningless without the context of where that bit value lies
+    in a bit string. This is especially true of bits inside registers used for
+    special purposes: "You have a 1? THAT'S GREAT. But where is it? What does
+    that 1 MEAN? How am I supposed to know what this 1 means when I don't know
+    where it is?"
+    When we talk of the "foo bit," we're talking about the bit value AT POSITION
+    FOO--we're talking about the state of foo. For bits, location = meaning
+    = what state the 1 or 0 alludes to.
+    That's why constants like OCIE1A are actually the values of indexes. In the
+    datasheet, the bit _AT_ OCIE1A represents the STATE _OF_ OCIE1A.
+
+    Reference for knowledge but incorrect datasheet:
+    http://www.atmel.com/Images/doc8025.pdf
+    */
+
+  TIMSK1 = (1 << OCIE1A);

   Serial.begin(9600);
 } // void setup()
@@ -171,8 +285,8 @@
       {
         lcd.setCursor(0, 1);
         lcd.print(F("Set time: <"));
-        lcd.setCursor(0, 3);
-        lcd.print(F("   Push to Start!"));
+        lcd.setCursor(11, 3);
+        lcd.print(F("Start!"));
         changedUIString = true;
         /* This block becomes unreachable after this, because this true value is
           remembered; therefore block only done once, when case first entered
@@ -256,8 +370,8 @@

         lcd.setCursor(0, 1);
         lcd.print(F("Finished in: "));
-        lcd.setCursor(0, 3);
-        lcd.print(F("    Push to Stop!"));
+        lcd.setCursor(11, 3);
+        lcd.print(F("Stop!"));

         changedUIString = true;
       } // if(!changedIUIString)


more comments and fix for Arduino IDE 1.x, thx Paul

--- examples/Ports/memory_demo/memory_demo.ino
+++ examples/Ports/memory_demo/memory_demo.ino
@@ -4,8 +4,16 @@

 #include <JeeLib.h>

-// pressing button 1 replays the collected data
-// pressing button 2 clears the data
+// Requires a JeeLabs Memory Plug on port 4 and a Blink Plug on port 3
+//
+// To use the demo:
+//    Open the Serial Monitor in Arduino
+//    Type some text into the serial monitor, then hit return
+//      to save the text to the memory plug
+//
+// Press button 1 on the Blink Plug  to print out your text
+// Press button 2 on the Blink Plug to erase the text, and reset the counter
+
 BlinkPlug buttons (3);

 PortI2C i2cBus (4);
@@ -40,7 +48,7 @@
         stream.reset();
         Serial.println();
         while (--pos >= 0 && !Serial.available())
-            Serial.print(stream.get());
+            Serial.print((char) stream.get());
         Serial.println();
         stream.reset();
     }


Use TimedProbe to show reduction of control complexity.

--- examples/UML/CosaCapsules/CosaCapsules.ino
+++ examples/UML/CosaCapsules/CosaCapsules.ino
@@ -38,13 +38,13 @@
  *                         |        |
  *                 +------>|        |
  *                 |       +--------+
- *    Button       |         Probe
+ *    Button       |       TimedProbe
  *  +--------+     |       +--------+
  *  |   b1   |     |       |   p2   |
  *  |        |---[onoff]-->|        |
  *  |        |             |        |
  *  +--------+             +--------+
- *     [64 ms]
+ *     [64 ms]              [2048 ms]
  *
  * This file is part of the Arduino Che Cosa project.
  */
@@ -58,6 +58,7 @@
 #include "Cosa/UML/Button.hh"
 #include "Cosa/UML/LED.hh"
 #include "Cosa/UML/Probe.hh"
+#include "Cosa/UML/TimedProbe.hh"
 #include "Cosa/UML/Controller.hh"

 using namespace UML;
@@ -76,7 +77,7 @@
 Probe<Clock::Tick> p1((str_P) p1_name, tick);

 const char p2_name[] __PROGMEM = "onoff";
-Probe<Signal> p2((str_P) p2_name, onoff);
+TimedProbe<Signal> p2((str_P) p2_name, onoff, 2048);

 // The wiring; control dependencies
 Capsule* const tick_listeners[] __PROGMEM = { &p1, &l1, NULL };
@@ -97,6 +98,7 @@
   // Start the Timed Capsules
   c1.begin();
   b1.begin();
+  p2.begin();
 }

 void loop()


improve temperature compensation command by sending only two decimals

--- firmware/src/PoolBuddy.ino
+++ firmware/src/PoolBuddy.ino
@@ -150,7 +150,7 @@

 void compensate_temp_ph() {
   String commandString = String("T,");
-  commandString.concat(temp);
+  commandString.concat(String(temp, 2));
   executeRequest(PH_ADDRESS,commandString);
 }


mi-test: changed timer

mi-test: changed timer

--- prototype/mi-test/mi-test.ino
+++ prototype/mi-test/mi-test.ino
@@ -28,9 +28,10 @@

 void loop()
 {
-    int32_t test_dist = distance_sensor_double_take(); //distance_sensor_measure_distance(&distance_sensor);
+    //int32_t test_dist = distance_sensor_double_take(); //distance_sensor_measure_distance(&distance_sensor);
     //Serial.println(test_dist);

+/*
     if(test_dist + 10 < distance_to_wall)
     {
         Serial.print("Log: ");
@@ -45,9 +46,11 @@
     }

     return;
+    */
+
     uint32_t pos = motor_get_degrees(&motor_conveyor);
     // Change TARGET1 for delay before requesting image
-    while(pos + 225 > motor_get_degrees(&motor_conveyor)) {}
+    while(pos + 270 > motor_get_degrees(&motor_conveyor)) {}
     Serial.print("Command:");
     Serial.print(2);
     Serial.println("end");


- quick linear accel works better than slow exponential increase - remote-control debugging - output currentMillis over Serial - changed line endings to \r\n

--- GeheimTuer.ino
+++ GeheimTuer.ino
@@ -66,6 +66,7 @@
 const int motorPWMPin = 9;

 // ad-hoc acceleration profile
+// TODO: self-calibration by means of driveTotalMillis
 struct accelProfile {
   unsigned long maxMillis; // time until next step, 0 == end of profile
   unsigned long stepMillis; // modify PWM value every stepMillis ms
@@ -100,6 +101,57 @@
 // try accelerating as fast as possible without skipping belt teeth
 // TODO: install less stiff spring between belt and door to dampen the initial pull
 const struct accelProfile accelProfileHigh[] = {
+  { // slow start
+    maxMillis: 260,
+    stepMillis: 10,
+    factor: 1,
+    add: 1,
+    minPWM: 0,
+    maxPWM: 25,
+    startPWM: 0,
+    useStartPWM: true, // first element always sets initial PWM value
+    brake: false
+  },
+  { // accelerate to full-ish speed and keep running
+    maxMillis: 2300,
+    stepMillis: 5,
+    factor: 1,
+    add: 1,
+    minPWM: 0,
+    maxPWM: 255,
+    startPWM: 0,
+    useStartPWM: false,
+    brake: false
+  },
+  { // slow down before end-stop
+    maxMillis: 1300,
+    stepMillis: 100,
+    factor: 0.9,
+    add: 0,
+    minPWM: 32,
+    maxPWM: 255,
+    startPWM: 0,
+    useStartPWM: false,
+    brake: false
+  },
+  { // seek end-stop
+    maxMillis: 4000,
+    stepMillis: 100,
+    factor: 1,
+    add: -1,
+    minPWM: 32,
+    maxPWM: 64,
+    startPWM: 64,
+    useStartPWM: false,
+    brake: false
+  },
+  {
+    maxMillis: 0
+  }
+};
+
+/*
+const struct accelProfile accelProfileHigh[] = {
 { // slow start
     maxMillis: 350,
     stepMillis: 50,
@@ -122,7 +174,7 @@
     useStartPWM: false,
     brake: false
   },
-/*
+/+
   { // coast
     maxMillis: 1000,
     stepMillis: 50,
@@ -145,7 +197,7 @@
     useStartPWM: true,
     brake: true
   },
-*/
++/
   { // slow down before end-stop
     maxMillis: 1000,
     stepMillis: 100,
@@ -172,6 +224,7 @@
     maxMillis: 0
   }
 };
+*/

 const struct accelProfile *accelProfile; // pointer to current profile
 int accelProfileIdx = 0;
@@ -201,6 +254,7 @@

 unsigned long driveMillis = 0;
 unsigned long driveStepMillis = 0;
+unsigned long driveTotalMillis = 0;

 const unsigned long openInterval = 3000; // ms before the door closes again, unless blocked by button
 unsigned long openMillis = 0;
@@ -221,7 +275,7 @@

 void setup() {
   Serial.begin(115200);
-  Serial.print(F("\nDoor control init\n"));
+  Serial.print(F("\r\nDoor control init\r\n"));

   // disable driver bridges until setup complete
   motorDisable();
@@ -259,16 +313,16 @@

   if (swTrigger == LOW || (swFront == LOW && swBack == LOW)) {
     doorState = doorError;
-    Serial.print(F("ERROR\n"));
+    Serial.print(F("ERROR\r\n"));
   } else if (swFront == LOW) {
     doorState = doorClosed;
-    Serial.print(F("closed\n"));
+    Serial.print(F("closed\r\n"));
   } else if (swBack == LOW) {
     doorState = doorOpen;
-    Serial.print(F("open\n"));
+    Serial.print(F("open\r\n"));
   } else {
     doorState = doorBlocked;
-    Serial.print(F("blocked\n"));
+    Serial.print(F("blocked\r\n"));
   }

   if (doorState != doorError) {
@@ -325,6 +379,7 @@
     debounce(switchBack, &swBack, &swBackDebounce);
   }

+
   // fast debounce driver error signals to filter short glitches
   debounce(motorDiagAPin, &motorDiagA, &motorDiagADebounce);
   debounce(motorDiagBPin, &motorDiagB, &motorDiagBDebounce);
@@ -332,22 +387,50 @@
   // The WAM's overheating!
   if ((motorDiagA == LOW || motorDiagB == LOW) && doorState != doorError) {
     motorFree();
-    Serial.print(F("Motor driver error condition - door disabled\n"));
+    Serial.print(currentMillis);
+    Serial.print(F(" Motor driver error condition - door disabled\r\n"));
     setLeds1(red, ledFade);
     doorState = doorError;
   }
+
+// remote debugging aid
+// TODO: formalize the commands
+if (Serial.available()) {
+  char c;
+  if ((c = Serial.read()) == 'x') {
+    swTrigger = LOW;
+  } else if (c == 'X') {
+    swTrigger = HIGH;
+  } else if (c == 'b') {
+    swBack = LOW;
+  } else if (c == 'B') {
+    swBack = HIGH;
+  } else if (c == 'f') {
+    swFront = LOW;
+  } else if (c == 'F') {
+    swFront = HIGH;
+  } else if (c == 'r') {
+//    motorEnable();
+    doorState = doorBlocked;
+  } else if (c == 'm') {
+    Serial.println(currentMillis);
+  } else if (c == '\n') {
+    Serial.print(F("\r\n"));
+  }
+}

   switch(doorState) {
     case doorClosed:
       // wait until a button is pressed or the front switch opens
       if (swFront == HIGH || swTrigger == LOW) {
+        Serial.print(currentMillis);
         if (swFront == HIGH) {
           // maybe someone tried to pull the door open
           // TODO: or the door slams too fast into the end-stop and rebounds. align profile & inertial reality
-          Serial.print(F("Front switch triggered - opening door\n"));
+          Serial.print(F(" Front switch triggered - opening door\r\n"));
           initDrive(backward, accelProfileLow);
         } else {
-          Serial.print(F("Button switch triggered - opening door\n"));
+          Serial.print(F(" Button switch triggered - opening door\r\n"));
           initDrive(backward, accelProfileHigh);
 // TODO: think again. re-arming swTrigger disables deglitching
 // any short HIGH pulse resets swTrigger to LOW
@@ -361,7 +444,8 @@
     case doorOpen:
       // hold the door open if button pressed during openInterval
       if (swTrigger == LOW) {
-        Serial.print(F("Button switch triggered - door blocked\n"));
+        Serial.print(currentMillis);
+        Serial.print(F(" Button switch triggered - door blocked\r\n"));
         motorFree();
         setLeds1(red, ledSolid);
         doorState = doorBlocked;
@@ -371,13 +455,14 @@

       openMillis += elapsedMillis;
       if (openMillis >= openInterval || swBack == HIGH) {
+        Serial.print(currentMillis);
         if (swBack == HIGH) {
           // maybe someone tried to pull the door close
           // TODO: or the door slams too fast into the end-stop and rebounds. align profile & inertial reality
-          Serial.print(F("Back switch triggered - closing door\n"));
+          Serial.print(F(" Back switch triggered - closing door\r\n"));
           initDrive(forward, accelProfileLow);
         } else {
-          Serial.print(F("openInterval timeout - closing door\n"));
+          Serial.print(F(" openInterval timeout - closing door\r\n"));
           initDrive(forward, accelProfileHigh);
         }
         setLeds2(white, black, 3, ledForward);
@@ -389,7 +474,10 @@
       // are we there yet?
       if (swBack == LOW) {
         motorBrake();
-        Serial.print(F("Back switch triggered - door open\n"));
+        Serial.print(currentMillis);
+        Serial.print(F(" Back switch triggered - door open\r\n"));
+        Serial.print(F("Total ms: "));
+        Serial.println(driveTotalMillis);
         openMillis = 0;
         setLeds1(green, ledFade);
         doorState = doorOpen;
@@ -400,7 +488,10 @@
     case doorClosing:
       if (doorState == doorClosing && swFront == LOW) {
         motorBrake();
-        Serial.print(F("Front switch triggered - door closed\n"));
+        Serial.print(currentMillis);
+        Serial.print(F(" Front switch triggered - door closed\r\n"));
+        Serial.print(F("Total ms: "));
+        Serial.println(driveTotalMillis);
         setLeds1(green, ledFade);
         doorState = doorClosed;
         break;
@@ -409,7 +500,8 @@
       // stop if button pressed while in motion
       if (swTrigger == LOW) {
         motorFree(); // TODO: motorBrake() might be better for an emergency stop. doesn't make much different in our case, the belt skips and the door stops in both cases
-        Serial.print(F("Button switch triggered - door blocked\n"));
+        Serial.print(currentMillis);
+        Serial.print(F(" Button switch triggered - door blocked\r\n"));
         setLeds1(red, ledSolid);
         doorState = doorBlocked;
 swTrigger = HIGH;
@@ -417,6 +509,7 @@
       }

       driveStepMillis += elapsedMillis;
+      driveTotalMillis += elapsedMillis;
       if (driveStepMillis >= accelProfile[accelProfileIdx].stepMillis) {
         driveMillis += driveStepMillis;
         driveStepMillis = 0;
@@ -428,7 +521,10 @@
           // end-stop not reached at end of profile, someone might be in the way
           if (accelProfile[++accelProfileIdx].maxMillis == 0) {
             motorFree();
-            Serial.print(F("End of profile - door blocked\n"));
+            Serial.print(currentMillis);
+            Serial.print(F(" End of profile - door blocked\r\n"));
+            Serial.print(F("Total ms: "));
+            Serial.println(driveTotalMillis);
             setLeds1(red, ledBlink);
             doorState = doorBlocked;
             break;
@@ -451,7 +547,8 @@
             drivePWM = accelProfile[accelProfileIdx].startPWM;
           }

-          Serial.print(F("accelProfileIdx: "));
+          Serial.print(currentMillis);
+          Serial.print(F(" accelProfileIdx: "));
           Serial.println(accelProfileIdx);
         }

@@ -459,7 +556,8 @@
         drivePWM = min(accelProfile[accelProfileIdx].maxPWM, max(accelProfile[accelProfileIdx].minPWM,
                         (drivePWM + accelProfile[accelProfileIdx].add) * accelProfile[accelProfileIdx].factor));

-        Serial.print(F("Drive PWM: "));
+        Serial.print(currentMillis);
+        Serial.print(F(" Drive PWM: "));
         Serial.println(drivePWM);

         analogWrite(motorPWMPin, round(drivePWM*drivePWMscale));
@@ -469,14 +567,16 @@
     case doorBlocked:
       // wait until a button is pressed
       if (swTrigger == LOW) {
+        Serial.print(currentMillis);
         // close door only if end-stop is active
         if (swBack == LOW) {
-          Serial.print(F("Button switch triggered - closing door\n"));
-          initDrive(forward, accelProfileLow);
+          Serial.print(F(" Button switch triggered - closing door\r\n"));
+//          initDrive(forward, accelProfileLow);
+          initDrive(forward, accelProfileHigh);
           ledMode = ledForward;
           doorState = doorClosing;
         } else {
-          Serial.print(F("Button switch triggered - opening door\n"));
+          Serial.print(F(" Button switch triggered - opening door\r\n"));
           initDrive(backward, accelProfileLow);
           ledMode = ledBackward;
           doorState = doorOpening;
@@ -489,15 +589,13 @@
     case doorError:
       // wait for reset by qualified service technician
       // TODO: make it user-resettable
-/*
 // wait until driver cools down
 // TODO: this won't work now because motorDisable() pulls the pins low
 if (motorDiagA == HIGH && motorDiagB == HIGH) {
-  motorEnable();
   setLeds1(red, ledSolid);
   doorState = doorBlocked;
-}
-*/
+digitalWrite(13, LOW);
+}
 digitalWrite(13, HIGH);
       break;
   }
@@ -613,12 +711,15 @@
   accelProfile = profile;
   accelProfileIdx = 0;
   drivePWM = accelProfile[0].startPWM;
-
-  driveMillis = driveStepMillis = 0;
+  driveMillis = driveStepMillis = driveTotalMillis = 0;

   switch(dir) {
     case forward:
       motorForward(); break;
+/*
+  digitalWrite(motorInAPin, LOW);
+  digitalWrite(motorInBPin, LOW);
+*/
     case backward:
       motorBackward(); break;
   }
@@ -641,70 +742,51 @@
   digitalWrite(motorDiagBPin, LOW);
   pinMode(motorDiagBPin, OUTPUT);

-  Serial.print(F("Motor driver disabled\n"));
+  Serial.print(F("Motor driver disabled\r\n"));
 }

 void motorEnable() {
-  // return control to pull-ups on the BB-VNH3SP30 board
+  // return control to pull-ups on the driver2 board
   pinMode(motorDiagAPin, INPUT);
   pinMode(motorDiagBPin, INPUT);
-  Serial.print(F("Motor driver enabled\n"));
+  Serial.print(F("Motor driver enabled\r\n"));
 }

 void motorBrake() {
   _motorBrake();
-  Serial.print(F("Brake engaged\n"));
+  Serial.print(F("Brake engaged\r\n"));
 }

 void _motorBrake() {
   setMotorBits(0x00);
-/*
-  digitalWrite(motorInAPin, LOW);
-  digitalWrite(motorInBPin, LOW);
-*/
   digitalWrite(motorPWMPin, HIGH);
 }

 void motorFree() {
   _motorFree();
-  Serial.print(F("Brake disengaged\n"));
+  Serial.print(F("Brake disengaged\r\n"));
 }

 void _motorFree() {
   setMotorBits(0x00);
-/*
-  digitalWrite(motorPWMPin, LOW);
-  digitalWrite(motorInAPin, LOW);
-  digitalWrite(motorInBPin, LOW);
-*/
 }

 void motorForward() {
   _motorForward();
-  Serial.print(F("Forward\n"));
+  Serial.print(F("Forward\r\n"));
 }

 void _motorForward() {
   setMotorBits(0x02);
-/*
-  digitalWrite(motorPWMPin, LOW);
-  digitalWrite(motorInAPin, HIGH);
-  digitalWrite(motorInBPin, LOW);
-*/
 }

 void motorBackward() {
   _motorBackward();
-  Serial.print(F("Backward\n"));
+  Serial.print(F("Backward\r\n"));
 }

 void _motorBackward() {
   setMotorBits(0x01);
-/*
-  digitalWrite(motorPWMPin, LOW);
-  digitalWrite(motorInAPin, LOW);
-  digitalWrite(motorInBPin, HIGH);
-*/
 }

@@ -754,9 +836,9 @@
       default: return;
     }
     if(pin == 5 || pin == 6) {
-      TCCR0B = TCCR0B & 0b11111000 | mode;
+      TCCR0B = (TCCR0B & 0b11111000) | mode;
     } else {
-      TCCR1B = TCCR1B & 0b11111000 | mode;
+      TCCR1B = (TCCR1B & 0b11111000) | mode;
     }
   } else if(pin == 3 || pin == 11) {
     switch(divisor) {
@@ -769,7 +851,7 @@
       case 1024: mode = 0x7; break;
       default: return;
     }
-    TCCR2B = TCCR2B & 0b11111000 | mode;
-  }
-}
-
+    TCCR2B = (TCCR2B & 0b11111000) | mode;
+  }
+}
+