Incomplete bug fixes to compare

Incomplete bug fixes to compare

--- Elcano_C2_LowLevel/Elcano_C2_LowLevel.ino
+++ Elcano_C2_LowLevel/Elcano_C2_LowLevel.ino
@@ -39,9 +39,9 @@
 #define LEFT_DEGx1000pCOUNT  333
 // A correct sensor will produce a reading between these values
 int Left_Min_Count = 850; // Real values are in setup().
-int Left_Max_Count = 980;
-int Right_Min_Count = 698;
-int Right_Max_Count = 808;
+int Left_Max_Count = 980;
+int Right_Min_Count = 698;
+int Right_Max_Count = 808;

 // RC_rise contains the time value collected in the rising edge interrupts.
 // RC_elapsed contains the width of the pulse. The rise and fall interrupts
@@ -59,7 +59,7 @@
 volatile unsigned long RC_elapsed[7];
 volatile boolean synced = false;
 volatile unsigned long last_fallingedge_time = 4294967295; // max long
-volatile bool RC_Done[7] = {0,0,0,0,0,0,0};
+volatile bool RC_Done[7] = {0, 0, 0, 0, 0, 0, 0};

 long speed_errors[ERROR_HISTORY];
 long old_turn_degx1000;
@@ -77,18 +77,18 @@
 int max_rc = MAX_RC;
 int mid = MIDDLE;
 int min_rc = MIN_RC;
-#define LED_PIN_OUT
+#define LED_PIN_OUT
 //==========================================================================================
 void ISR_TURN_rise() {
   noInterrupts();
   ProcessRiseOfINT(RC_TURN);
-  attachInterrupt(IRPT_TURN, ISR_TURN_fall, FALLING);
+  attachInterrupt(digitalPinToInterrupt(IRPT_TURN), ISR_TURN_fall, FALLING);
   interrupts();
 }
 /*---------------------------------------------------------------------------------------*/
 // RDR (rudder) is currently not used.
 void ISR_RDR_rise() {
-// RDR (rudder) is not used. Instead, use this interrupt for the motor phase feedback, which gives speed.
+  // RDR (rudder) is not used. Instead, use this interrupt for the motor phase feedback, which gives speed.
   noInterrupts();
   unsigned long old_phase_rise = RC_rise[RC_RDR];
   ProcessRiseOfINT(RC_RDR);
@@ -97,37 +97,39 @@
   // An e-bike hub is powered by giving it 3 phased 36 V lines
   // The e-bike controller needs feeback from the hub.
   // The hub supplies 3 Hall Phase sensors; each is a 5V square wave and tells how fast the wheel rotates.
-  // The square wave feedback has sone noise, which is cleaned up by an RC low pass filter
-  //  with R = 1K, C = 100 nF
+  // The square wave feedback has sone noise, which is cleaned up by an RC low pass filter
+  //  with R = 1K, C = 100 nF
+  Serial.println("RDR");
   interrupts();
 }
 /*---------------------------------------------------------------------------------------*/
 void ISR_GO_rise() {
   noInterrupts();
   ProcessRiseOfINT(RC_GO);
-  attachInterrupt(IRPT_GO, ISR_GO_fall, FALLING);
+  attachInterrupt(digitalPinToInterrupt(IRPT_GO), ISR_GO_fall, FALLING);
   interrupts();
 }
 /*---------------------------------------------------------------------------------------*/
 void ISR_ESTOP_rise() {
   noInterrupts();
   ProcessRiseOfINT(RC_ESTP);
-  attachInterrupt(IRPT_ESTOP, ISR_ESTOP_fall, FALLING);
+  attachInterrupt(digitalPinToInterrupt(IRPT_ESTOP), ISR_ESTOP_fall, FALLING);
   interrupts();
 }
 /*---------------------------------------------------------------------------------------*/
 void ISR_RVS_rise() {
   noInterrupts();
   ProcessRiseOfINT(RC_RVS);
-  attachInterrupt(IRPT_RVS, ISR_RVS_fall, FALLING);
+  attachInterrupt(digitalPinToInterrupt(IRPT_RVS), ISR_RVS_fall, FALLING);
   interrupts();
 }
 /*---------------------------------------------------------------------------------------*/
-void ISR_TURN_fall() {
+void ISR_TURN_fall() {
   noInterrupts();
   ProcessFallOfINT(RC_TURN);
   RC_Done[RC_TURN] = 1;
-  attachInterrupt(IRPT_TURN, ISR_TURN_rise, RISING);
+  Serial.println("TURN");
+  attachInterrupt(digitalPinToInterrupt(IRPT_TURN), ISR_TURN_rise, RISING);
   interrupts();
 }
 /*---------------------------------------------------------------------------------------*/
@@ -135,17 +137,19 @@
   noInterrupts();
   ProcessFallOfINT(RC_GO);
   RC_Done[RC_GO] = 1;
-  attachInterrupt(IRPT_GO, ISR_GO_rise, RISING);
+  Serial.println("GO");
+  attachInterrupt(digitalPinToInterrupt(IRPT_GO), ISR_GO_rise, RISING);
   interrupts();
 }
 /*---------------------------------------------------------------------------------------*/
-void ISR_ESTOP_fall() {
+void ISR_ESTOP_fall() {
   noInterrupts();
   ProcessFallOfINT(RC_ESTP);
   RC_Done[RC_ESTP] = 1;
-//  if (RC_elapsed[RC_ESTP] > MIDDLE)
-//     E_Stop();
-  attachInterrupt(IRPT_ESTOP, ISR_ESTOP_rise, RISING);
+  //  if (RC_elapsed[RC_ESTP] > MIDDLE)
+  //     E_Stop();
+  Serial.println("ESTOP");
+  attachInterrupt(digitalPinToInterrupt(IRPT_ESTOP), ISR_ESTOP_rise, RISING);
   interrupts();
 }
 /*---------------------------------------------------------------------------------------*/
@@ -153,7 +157,7 @@
   noInterrupts();
   ProcessFallOfINT(RC_RVS);
   RC_Done[RC_RVS] = 1;
-  attachInterrupt(IRPT_RVS, ISR_RVS_rise, RISING);
+  attachInterrupt(digitalPinToInterrupt(IRPT_RVS), ISR_RVS_rise, RISING);
   interrupts();
 }

@@ -197,119 +201,121 @@
   unsigned long old_phase_rise = RC_rise[RC_MOTOR_FEEDBACK];
   ProcessRiseOfINT(RC_MOTOR_FEEDBACK);
   RC_elapsed[RC_MOTOR_FEEDBACK] = RC_rise[RC_MOTOR_FEEDBACK] - old_phase_rise;
+  Serial.println("MOTOR");
   interrupts();
 }
 /*---------------------------------------------------------------------------------------*/
 //----------------------------------------------------------------------------
 void setup()
 { //Set up pins
-      STEER_SERVO.attach(STEER_OUT_PIN);
-      pinMode(BRAKE_OUT_PIN, OUTPUT);
-
-      // SPI: set the slaveSelectPin as an output:
-      pinMode (SelectAB, OUTPUT);
-      pinMode (SelectCD, OUTPUT);
-      pinMode (10, OUTPUT);
-      SPI.setDataMode( SPI_MODE0);
-      SPI.setBitOrder( MSBFIRST);
-      // initialize SPI:
-      // The following line should not be neccessary. It uses a system library.
-      PRR0 &= ~4; // turn off PRR0.PRSPI bit so power isn't off
-      SPI.begin();
-      for (int channel = 0; channel < 4; channel++)
-          DAC_Write (channel, 0); // reset did not clear previous states
-      // put vehicle in initial state
-      steer(STRAIGHT_TURN_OUT);
-      brake(MAX_BRAKE_OUT);
-      moveVehicle(MIN_ACC_OUT);
-      setup7seg();    // Initialize 7 segment display for speedometer
-      delay(500);   // let vehicle stabilize
-
-      Serial.begin(9600);
-      rc_index = 0;
-      for (int i = 0; i < 8; i++)
-      {
-          RC_rise[i] = INVALID_DATA;
-          RC_elapsed[i] = INVALID_DATA;
-      }
-      for (int i = 0; i < ERROR_HISTORY; i++)
-      {
-          speed_errors[i] = 0;
-      }
-      setupWheelRev(); // WheelRev4 addition
-      CalibrateTurnAngle(32, 20);
-      calibrationTime_ms = millis();
-      attachInterrupt(IRPT_TURN,  ISR_TURN_rise,  RISING);
-      attachInterrupt(IRPT_RDR,   ISR_RDR_rise,   RISING);
-      attachInterrupt(IRPT_GO,    ISR_GO_rise,    RISING);
-      attachInterrupt(IRPT_ESTOP, ISR_ESTOP_rise, RISING);
-      //attachInterrupt(IRPT_RVS,   ISR_RVS_rise,   RISING);
-      attachInterrupt(digitalPinToInterrupt(IRPT_SWITCH), ISR_SWITCH_rise, RISING);
-      attachInterrupt(IRPT_MOTOR_FEEDBACK, ISR_MOTOR_FEEDBACK_rise, RISING);
-      //Print7headers(false);
-      //PrintHeaders();
+  STEER_SERVO.attach(STEER_OUT_PIN);
+  pinMode(BRAKE_OUT_PIN, OUTPUT);
+
+  // SPI: set the slaveSelectPin as an output:
+  pinMode (SelectAB, OUTPUT);
+  pinMode (SelectCD, OUTPUT);
+  pinMode (10, OUTPUT);
+  SPI.setDataMode( SPI_MODE0);
+  SPI.setBitOrder( MSBFIRST);
+  // initialize SPI:
+  // The following line should not be neccessary. It uses a system library.
+  PRR0 &= ~4; // turn off PRR0.PRSPI bit so power isn't off
+  SPI.begin();
+  for (int channel = 0; channel < 4; channel++){
+    DAC_Write (channel, 0); // reset did not clear previous states
+  }
+  // put vehicle in initial state
+  steer(STRAIGHT_TURN_OUT);
+  brake(MAX_BRAKE_OUT);
+  moveVehicle(MIN_ACC_OUT);
+  //setup7seg();    // Initialize 7 segment display for speedometer
+  delay(500);   // let vehicle stabilize
+  //brake(MIN_BRAKE_OUT);
+  Serial.begin(9600);
+  rc_index = 0;
+  for (int i = 0; i < 8; i++)
+  {
+    RC_rise[i] = INVALID_DATA;
+    RC_elapsed[i] = INVALID_DATA;
+  }
+  for (int i = 0; i < ERROR_HISTORY; i++)
+  {
+    speed_errors[i] = 0;
+  }
+  setupWheelRev(); // WheelRev4 addition
+  CalibrateTurnAngle(32, 20);
+  calibrationTime_ms = millis();
+        attachInterrupt(digitalPinToInterrupt(IRPT_TURN),  ISR_TURN_rise,  RISING);
+        //attachInterrupt(digitalPinToInterrupt(IRPT_RDR),   ISR_RDR_rise,   RISING);
+        attachInterrupt(digitalPinToInterrupt(IRPT_GO),    ISR_GO_rise,    RISING);
+        attachInterrupt(digitalPinToInterrupt(IRPT_ESTOP), ISR_ESTOP_rise, RISING);
+        //attachInterrupt(digitalPinToInterrupt(IRPT_RVS),   ISR_RVS_rise,   RISING);
+        attachInterrupt(digitalPinToInterrupt(IRPT_SWITCH), ISR_SWITCH_rise, RISING);
+        attachInterrupt(digitalPinToInterrupt(IRPT_MOTOR_FEEDBACK), ISR_MOTOR_FEEDBACK_rise, RISING);
+        //Print7headers(false);
+  //PrintHeaders();
 }
 /*---------------------------------------------------------------------------------------*/
 void loop() {
-    SerialData Results;
-
-    // Save start time for performance report.
-    unsigned long startTime = micros();
-    // Get the next loop start time.
-    unsigned long nextTime = startTime + LOOP_TIME_MS;
-
-    startCapturingRCState();
-
-    unsigned long local_results[7];
-//  PrintDone();
+  SerialData Results;
+
+  // Save start time for performance report.
+  unsigned long startTime = micros();
+  // Get the next loop start time.
+  unsigned long nextTime = startTime + LOOP_TIME_MS;
+
+  startCapturingRCState();
+
+  unsigned long local_results[7];
+  //  PrintDone();

   while (micros() < nextTime &&
-    ~((RC_Done[RC_ESTP] == 1) && (RC_Done[RC_GO] == 1) && (RC_Done[RC_TURN] == 1) ))
+         ~((RC_Done[RC_ESTP] == 1) && (RC_Done[RC_GO] == 1) && (RC_Done[RC_TURN] == 1) ))
     ;  //wait
-
-    // got data;
-    for (int i = 0; i < 8; i++)
-        local_results[i] = RC_elapsed[i];
-    //Print7(false, local_results);
-    byte automate = processRC(local_results);
-    if(automate = 0x01)
-        processHighLevel();
-//    Print7( true, local_results);
-
-    Results.Clear();
-    Results.kind = MSG_SENSOR;
-    Results.angle_deg = TurnAngle_degx10() / 10;
-    show_speed (&Results);
-
-    // Report how long the loop took.
-    unsigned long endTime = micros();
-    unsigned long elapsedTime = endTime - startTime;
-    //Serial.print("loop elapsed time = ");
-    //Serial.println(elapsedTime);
-
-    //LogData(local_results, &Results);  // data for spreadsheet
-
-    calibrationTime_ms += LOOP_TIME_MS;
-    straightTime_ms = (steer_control == STRAIGHT_TURN_OUT)? straightTime_ms + LOOP_TIME_MS: 0;
-    stoppedTime_ms = (throttle_control == MIN_ACC_OUT)? stoppedTime_ms + LOOP_TIME_MS: 0;
-    if (calibrationTime_ms > 40000 && straightTime_ms > 3000 && stoppedTime_ms > 3000)
-    {
-//       int oldBrake = brake_control;
-//       brake(MAX_BRAKE_OUT);  // put on brakes
-         CalibrateTurnAngle(16, 10);  // WARNING: No response to controls while calibrating
-//       brake(oldBrake);       // restore brake state
-         calibrationTime_ms = 0;
-    }
-
-    // Did we spend long enough in the loop that we should immediately
-    // start the next pass?
-    if (nextTime > endTime) {
-        // No, pause til the next loop start time.
-        delay(nextTime - endTime);
-    } else {
-        // Yes, we overran the expected loop interval. Extend the time.
-        nextTime = endTime + 1000 * LOOP_TIME_MS;
-    }
+
+  // got data;
+  for (int i = 0; i < 8; i++)
+    local_results[i] = RC_elapsed[i];
+  //Print7(false, local_results);
+  byte automate = processRC(local_results);
+  if (automate == 0x01) //remember to tell Pat to fix this, was = instead of ==
+    processHighLevel();
+  //    Print7( true, local_results);
+
+  Results.Clear();
+  Results.kind = MSG_SENSOR;
+  Results.angle_deg = TurnAngle_degx10() / 10;
+  show_speed (&Results);
+
+  // Report how long the loop took.
+  unsigned long endTime = micros();
+  unsigned long elapsedTime = endTime - startTime;
+  Serial.print("loop elapsed time = ");
+  Serial.println(elapsedTime);
+
+  //LogData(local_results, &Results);  // data for spreadsheet
+
+  calibrationTime_ms += LOOP_TIME_MS;
+  straightTime_ms = (steer_control == STRAIGHT_TURN_OUT) ? straightTime_ms + LOOP_TIME_MS : 0;
+  stoppedTime_ms = (throttle_control == MIN_ACC_OUT) ? stoppedTime_ms + LOOP_TIME_MS : 0;
+  if (calibrationTime_ms > 40000 && straightTime_ms > 3000 && stoppedTime_ms > 3000)
+  {
+    //       int oldBrake = brake_control;
+    //       brake(MAX_BRAKE_OUT);  // put on brakes
+    CalibrateTurnAngle(16, 10);  // WARNING: No response to controls while calibrating
+    //       brake(oldBrake);       // restore brake state
+    calibrationTime_ms = 0;
+  }
+
+  // Did we spend long enough in the loop that we should immediately
+  // start the next pass?
+  if (nextTime > endTime) {
+    // No, pause til the next loop start time.
+    delay(nextTime - endTime);
+  } else {
+    // Yes, we overran the expected loop interval. Extend the time.
+    nextTime = endTime + 1000 * LOOP_TIME_MS;
+  }
 }
 /*---------------------------------------------------------------------------------------*/
 void PrintDone()
@@ -324,74 +330,45 @@
 /*---------------------------------------------------------------------------------------*/
 void Print7headers (bool processed)
 {
-    processed? Serial.print("processed data \t") : Serial.print("received data \t");
- #ifdef RC_SPEKTRUM
-    Serial.print("Time\t");
-    Serial.print("TURN\t");
-    Serial.print("AUTO\t");
-    Serial.print("GO\t");
-    Serial.print("Rudder\t");
-    Serial.print("E-Stop\t");
-    Serial.println("Reverse\t");
+  processed ? Serial.print("processed data \t") : Serial.print("received data \t");
+#ifdef RC_SPEKTRUM
+  Serial.print("Time\t");
+  Serial.print("TURN\t");
+  Serial.print("AUTO\t");
+  Serial.print("GO\t");
+  Serial.print("Rudder\t");
+  Serial.print("E-Stop\t");
+  Serial.println("Reverse\t");
 #endif

 #ifdef RC_HITEC
-    Serial.print("Time\t");
-    Serial.print("TURN\t");
-    Serial.print("AUTO\t");
-    Serial.print("GO\t");
-    Serial.print("E-Stop\t");
-    Serial.print("Rudder\t");
-    Serial.println("Reverse\t");
+  Serial.print("Time\t");
+  Serial.print("TURN\t");
+  Serial.print("AUTO\t");
+  Serial.print("GO\t");
+  Serial.print("E-Stop\t");
+  Serial.print("Rudder\t");
+  Serial.println("Reverse\t");
 #endif
 }
 /*---------------------------------------------------------------------------------------*/
 void Print7 (bool processed, unsigned long results[7])
 {
-
-    processed? Serial.print("processed data \t") : Serial.print("received data \t");
-    Serial.print(results[0]); Serial.print("\t");
-    Serial.print(results[1]); Serial.print("\t");
-    Serial.print(results[2]); Serial.print("\t");
-    Serial.print(results[3]); Serial.print("\t");
-    Serial.print(results[4]); Serial.print("\t");
-    Serial.print(results[5]); Serial.print("\t");
-    Serial.println(results[6]);
+
+  processed ? Serial.print("processed data \t") : Serial.print("received data \t");
+  Serial.print(results[0]); Serial.print("\t");
+  Serial.print(results[1]); Serial.print("\t");
+  Serial.print(results[2]); Serial.print("\t");
+  Serial.print(results[3]); Serial.print("\t");
+  Serial.print(results[4]); Serial.print("\t");
+  Serial.print(results[5]); Serial.print("\t");
+  Serial.println(results[6]);
 }
 /*---------------------------------------------------------------------------------------*/
 void LogData(unsigned long commands[7], SerialData *sensors)  // data for spreadsheet
 {
-     show7seg(HubSpeed_kmPh);
-     /*Serial.print("(ms) Time\t");
-     Serial.print("(cm/s) Speed\t");
-     Serial.print("(km/h) Speed\t");
-     Serial.print("(km/h) Hub Speed\t");
-     Serial.print("(deg) Angle\t");
-     Serial.print("Right\t");
-     Serial.print("Left\t");
-     Serial.print("Throttle\t");
-     Serial.print("Brake\t");
-     Serial.print("Steer\t");
-     Serial.println("(m) Distance");*/
-     Serial.print(millis()); Serial.print("\t");                        //(ms) Time
-     Serial.print(sensors->speed_cmPs); Serial.print("\t");             //(cm/s) Speed
-     Serial.print(sensors->speed_cmPs*36.0/1000.); Serial.print("\t");  //(km/h) Speed
-     Serial.print(HubSpeed_kmPh); Serial.print("\t");                   //(km/h) Hub Speed
-     Serial.print(sensors->angle_deg); Serial.print("\t");              //(deg) Angle
-     int right = analogRead(A3);
-     int left = analogRead(A2);
-     Serial.print(right); Serial.print("\t");                           //Right turn sensor
-     Serial.print(left); Serial.print("\t");                            //Left turn sensor
-     Serial.print(throttle_control); Serial.print("\t");                //Throttle
-     Serial.print(brake_control); Serial.print("\t");                   //Brake
-     Serial.print(steer_control); Serial.print("\t");                   //Steer
-     Serial.println(Odometer_m);                                        //(m) Distance
-//     Print7 (true, commands);
-}
-/*---------------------------------------------------------------------------------------*/
-void PrintHeaders (void)
-{
-    Serial.print("(ms) Time\t");
+  show7seg(HubSpeed_kmPh);
+  /*Serial.print("(ms) Time\t");
     Serial.print("(cm/s) Speed\t");
     Serial.print("(km/h) Speed\t");
     Serial.print("(km/h) Hub Speed\t");
@@ -401,368 +378,401 @@
     Serial.print("Throttle\t");
     Serial.print("Brake\t");
     Serial.print("Steer\t");
-    Serial.println("(m) Distance");
-}
-
-/*---------------------------------------------------------------------------------------*/
-//circleRoutine
-void circleRoutine(unsigned long seconds){
+    Serial.println("(m) Distance");*/
+  Serial.print(millis()); Serial.print("\t");                        //(ms) Time
+  Serial.print(sensors->speed_cmPs); Serial.print("\t");             //(cm/s) Speed
+  Serial.print(sensors->speed_cmPs * 36.0 / 1000.); Serial.print("\t"); //(km/h) Speed
+  Serial.print(HubSpeed_kmPh); Serial.print("\t");                   //(km/h) Hub Speed
+  Serial.print(sensors->angle_deg); Serial.print("\t");              //(deg) Angle
+  int right = analogRead(A3);
+  int left = analogRead(A2);
+  Serial.print(right); Serial.print("\t");                           //Right turn sensor
+  Serial.print(left); Serial.print("\t");                            //Left turn sensor
+  Serial.print(throttle_control); Serial.print("\t");                //Throttle
+  Serial.print(brake_control); Serial.print("\t");                   //Brake
+  Serial.print(steer_control); Serial.print("\t");                   //Steer
+  Serial.println(Odometer_m);                                        //(m) Distance
+  //     Print7 (true, commands);
+}
+/*---------------------------------------------------------------------------------------*/
+void PrintHeaders (void)
+{
+  Serial.print("(ms) Time\t");
+  Serial.print("(cm/s) Speed\t");
+  Serial.print("(km/h) Speed\t");
+  Serial.print("(km/h) Hub Speed\t");
+  Serial.print("(deg) Angle\t");
+  Serial.print("Right\t");
+  Serial.print("Left\t");
+  Serial.print("Throttle\t");
+  Serial.print("Brake\t");
+  Serial.print("Steer\t");
+  Serial.println("(m) Distance");
+}
+
+/*---------------------------------------------------------------------------------------*/
+//circleRoutine
+void circleRoutine(unsigned long seconds) {
   steer(LEFT_TURN_OUT);
   delay(1000);
   seconds = seconds * 1000;
   unsigned long loopTime = millis();
-  while(millis() < (loopTime + seconds)){
+  while (millis() < (loopTime + seconds)) {
     moveVehicle(128);
-  }
-}
-/*---------------------------------------------------------------------------------------*/
-void startCapturingRCState()
-{
+  }
+}
+/*---------------------------------------------------------------------------------------*/
+void startCapturingRCState(){
   for (int i = 1; i < 7; i++) {
     RC_Done[i] = 0;
   }
 }

-/*---------------------------------------------------------------------------------------*/
-//done in setup, calibrate RC values for MIDDLE, MIN_RC, and MAX_RC at startup
-void calibrateRC(unsigned long mic){
-
-    Serial.print(mic);
-    Serial.println("Calibration Started");
-    //Step 1: Wait for controller to turn on, and leave joysticks in neutral
-//    while (micros() < TEN_SECONDS_IN_MICROS ||
-//    ~((RC_Done[RC_ESTP]) && (RC_Done[RC_GO]) && (RC_Done[RC_TURN]) ))
-//    digitalWrite(LED_PIN_OUT, HIGH); //wait for 10 seconds to receive radio signal to Calibrate Neutral Positions on RC controller, otherwise proceed
-
-    //Step 2: Calibrate MIDDLE
-    Serial.println(RC_elapsed[RC_GO]);
-    mid = RC_elapsed[RC_GO];
-    Serial.print("MIDDLE \t");
-    Serial.println(mid);
-    mic = micros();
-
-    //Step 3: Turn on LED and wait for Right joystick DOWN
-    //digitalWrite(LED_PIN_OUT, HIGH);
-    while(micros() < (mic + (TEN_SECONDS_IN_MICROS/4)))
-    //digitalWrite(LED_PIN_OUT, HIGH);//wait
-    //if
-    //digitalWrite(LED_PIN_OUT, LOW);
-    //Set MIN_RC
-    min_rc = RC_elapsed[RC_GO];
-    Serial.print("MIN_RC \t");
-    Serial.println(min_rc);
-    mic = micros();
-
-    //Step 4:Turn on LED again and wait for Right joystick UP
-    //digitalWrite(LED_PIN_OUT, HIGH);
-    while(micros() < (mic + (TEN_SECONDS_IN_MICROS/4)))
-    //digitalWrite(LED_PIN_OUT, HIGH);//wait
-
-    max_rc = RC_elapsed[RC_GO];
-    Serial.print("MAX_RC \t");
-    Serial.println(max_rc);
-    //digitalWrite(LED_PIN_OUT, LOW);
-}
-
-/*---------------------------------------------------------------------------------------*/
-byte processRC (unsigned long *results)
-{
-    // 1st pulse is aileron (position 5 on receiver; controlled by Right left/right joystick on transmitter)
-    //     used for Steering
-    int aileron = results[RC_TURN];
-//    Serial.print("\tTurn input "); Serial.print(aileron);
-    results[RC_TURN] = convertTurn(aileron);
-//    Serial.print("\tTurn Cmd "); Serial.println(results[RC_TURN]);
-    /* 2nd pulse is aux (position 1 on receiver; controlled by flap/gyro toggle on transmitter)
-       will be used for selecting remote control or autonomous control. */
-//    Serial.print("In processRC, received results[RC_AUTO] = "); Serial.println(results[RC_AUTO]);
-    if (NUMBER_CHANNELS > 5)
-        results[RC_AUTO] = (results[RC_AUTO] > MIDDLE? HIGH: LOW);
-//    Serial.print("processed results[RC_AUTO] = "); Serial.println(results[RC_AUTO]);
-
-    /* 4th pulse is gear (position 2 on receiver; controlled by gear/mode toggle on transmitter)
+///*---------------------------------------------------------------------------------------*/
+////done in setup, calibrate RC values for MIDDLE, MIN_RC, and MAX_RC at startup
+//void calibrateRC(unsigned long mic) {
+//
+//  Serial.print(mic);
+//  Serial.println("Calibration Started");
+//  //Step 1: Wait for controller to turn on, and leave joysticks in neutral
+//  //    while (micros() < TEN_SECONDS_IN_MICROS ||
+//  //    ~((RC_Done[RC_ESTP]) && (RC_Done[RC_GO]) && (RC_Done[RC_TURN]) ))
+//  //    digitalWrite(LED_PIN_OUT, HIGH); //wait for 10 seconds to receive radio signal to Calibrate Neutral Positions on RC controller, otherwise proceed
+//
+//  //Step 2: Calibrate MIDDLE
+//  Serial.println(RC_elapsed[RC_GO]);
+//  mid = RC_elapsed[RC_GO];
+//  Serial.print("MIDDLE \t");
+//  Serial.println(mid);
+//  mic = micros();
+//
+//  //Step 3: Turn on LED and wait for Right joystick DOWN
+//  //digitalWrite(LED_PIN_OUT, HIGH);
+//  while (micros() < (mic + (TEN_SECONDS_IN_MICROS / 4)))
+//    //digitalWrite(LED_PIN_OUT, HIGH);//wait
+//    //if
+//    //digitalWrite(LED_PIN_OUT, LOW);
+//    //Set MIN_RC
+//    min_rc = RC_elapsed[RC_GO];
+//  Serial.print("MIN_RC \t");
+//  Serial.println(min_rc);
+//  mic = micros();
+//
+//  //Step 4:Turn on LED again and wait for Right joystick UP
+//  //digitalWrite(LED_PIN_OUT, HIGH);
+//  while (micros() < (mic + (TEN_SECONDS_IN_MICROS / 4)))
+//    //digitalWrite(LED_PIN_OUT, HIGH);//wait
+//
+//    max_rc = RC_elapsed[RC_GO];
+//  Serial.print("MAX_RC \t");
+//  Serial.println(max_rc);
+//  //digitalWrite(LED_PIN_OUT, LOW);
+//}
+
+/*---------------------------------------------------------------------------------------*/
+byte processRC (unsigned long *results){
+  // 1st pulse is aileron (position 5 on receiver; controlled by Right left/right joystick on transmitter)
+  //     used for Steering
+    //    Serial.print("\tTurn Cmd "); Serial.println(results[RC_TURN]);
+  /* 2nd pulse is aux (position 1 on receiver; controlled by flap/gyro toggle on transmitter)
+     will be used for selecting remote control or autonomous control. */
+  //    Serial.print("In processRC, received results[RC_AUTO] = "); Serial.println(results[RC_AUTO]);
+  if (NUMBER_CHANNELS > 5)
+    results[RC_AUTO] = (results[RC_AUTO] > MIDDLE ? HIGH : LOW);
+  //    Serial.print("processed results[RC_AUTO] = "); Serial.println(results[RC_AUTO]);
+
+  /* 4th pulse is gear (position 2 on receiver; controlled by gear/mode toggle on transmitter)
     will be used for emergency stop. D38 */
-    results[RC_ESTP] = (results[RC_ESTP] > MIDDLE? HIGH: LOW);
-
-    if (results[RC_ESTP] == HIGH)
-    {
-        E_Stop();  // already done at interrupt level
-        if ((results[RC_AUTO] == LOW)  && (NUMBER_CHANNELS > 5)) // under RC control
-            ;//steer(results[RC_TURN]);
-        //Serial.println("Exiting processRC due to E-stop.");
-        return 0x00;
-    }
-
-
-    if ((results[RC_AUTO] == HIGH)  && (NUMBER_CHANNELS > 5))
-    {
-//        Serial.println("Calling processHighLevel.");
-        return 0x01;  // not under RC control
-    } else {
-//        Serial.println("Continuing processRC as under RC control.");
-    }
-    /*  6th pulse is marked throttle (position 6 on receiver; controlled by Left up/down joystick on transmitter).
+  results[RC_ESTP] = (results[RC_ESTP] > MIDDLE ? HIGH : LOW);
+
+  if (results[RC_ESTP] == HIGH)
+  {
+    Serial.println("XXX");
+    E_Stop();  // already done at interrupt level
+    if ((results[RC_AUTO] == LOW)  && (NUMBER_CHANNELS > 5)) // under RC control
+      ;//steer(results[RC_TURN]);
+    Serial.println("Exiting processRC due to E-stop.");
+    return 0x00;
+  }
+
+
+  if ((results[RC_AUTO] == HIGH)  && (NUMBER_CHANNELS > 5))
+  {
+    //        Serial.println("Calling processHighLevel.");
+    return 0x01;  // not under RC control
+  } else {
+         //Serial.println("Continuing processRC as under RC control.");
+  }
+
+  /*  6th pulse is marked throttle (position 6 on receiver; controlled by Left up/down joystick on transmitter).
     It will be used for shifting from Drive to Reverse . D40
-    */
-    //results[RC_RVS] = (results[RC_RVS] > MIDDLE? HIGH: LOW);
-
-// TO DO: Select Forward / reverse based on results[RC_RVS]
-
-    /*   3rd pulse is elevator (position 4 on receiver; controlled by Right up/down.
-       will be used for throttle/brake: RC_Throttle
-    */
-    // Braking or Throttle
-    if (liveBrake(results[RC_GO]))
-         convertBrake (&(results[RC_GO]));
-
-    //Accelerating
-    if(liveThrottle(results[RC_RDR]))
-    {
-        int going = convertThrottle(results[RC_RDR]);
-        moveVehicle(going);
-    }
-    else
-    {
-        moveVehicle(MIN_ACC_OUT);
-    }
-
-    steer(results[RC_TURN]);
-
-    /* 5th pulse is rudder (position 3 on receiver; controlled by Left left/right joystick on transmitter)
+  */
+  //results[RC_RVS] = (results[RC_RVS] > MIDDLE? HIGH: LOW);
+
+  // TO DO: Select Forward / reverse based on results[RC_RVS]
+
+  /*   3rd pulse is elevator (position 4 on receiver; controlled by Right up/down.
+     will be used for throttle/brake: RC_Throttle
+  */
+  int aileron = results[RC_TURN];
+  //    Serial.print("\tTurn input "); Serial.print(aileron);
+  results[RC_TURN] = convertTurn(aileron);
+
+
+  // Braking or Throttle
+  if (liveBrake(results[RC_GO])){
+    Serial.print("Braking: "); Serial.println(results[RC_GO]);
+    convertBrake ((results[RC_GO]));
+  }
+
+  //Accelerating
+  if (liveThrottle(results[RC_RDR])){
+    int going = convertThrottle(results[RC_RDR]);
+    moveVehicle(going);
+  }
+  else {
+    moveVehicle(MIN_ACC_OUT);
+  }
+
+  steer(results[RC_TURN]);
+
+  /* 5th pulse is rudder (position 3 on receiver; controlled by Left left/right joystick on transmitter)
     Not used */
-//    results[RC_RDR] = (results[RC_RDR] > MIDDLE? HIGH: LOW);  // could be analog
-//    Serial.println(results[RC_RDR]);
-//    if (results[RC_RDR] >= HubAtZero)
-//        HubSpeed_kmPh = 0;
-//    else
-//        HubSpeed_kmPh = HubSpeed2kmPh / results[RC_RDR];
-
-//  Serial.println("");  // New line
-    return 0x00;
+  //    results[RC_RDR] = (results[RC_RDR] > MIDDLE? HIGH: LOW);  // could be analog
+  //    Serial.println(results[RC_RDR]);
+  //    if (results[RC_RDR] >= HubAtZero)
+  //        HubSpeed_kmPh = 0;
+  //    else
+  //        HubSpeed_kmPh = HubSpeed2kmPh / results[RC_RDR];
+
+  //  Serial.println("");  // New line
+  return 0x00;
 }
 /*---------------------------------------------------------------------------------------*/
 void processHighLevel()
 {
-    SerialData Results;
-    readSerial(&Serial3, &Results);
-    //Throttle
-
-    //End Throttle
-    //Brake
-
-    //End Brake
-    //Steer
-    int turn_signal = convertDeg(Results.angle_deg);
-    steer(turn_signal);
-    //End Steer
-    writeSerial(&Serial3, &Results);
+  SerialData Results;
+  readSerial(&Serial3, &Results);
+  //Throttle
+
+  //End Throttle
+  //Brake
+
+  //End Brake
+  //Steer
+  int turn_signal = convertDeg(Results.angle_deg);
+  steer(turn_signal);
+  //End Steer
+  writeSerial(&Serial3, &Results);
 }
 /*---------------------------------------------------------------------------------------*/
 //Converts RC values to corresponding values for the PWM output
 int convertTurn(int input)
 {
-     long int steerRange, rcRange;
-     long output;
-     int trueOut;
-//     Serial.print("\tconvertTurn: input = \t"); Serial.print(input);
-     //  Check if Input is in steer dead zone
-     if ((input <= MIDDLE + DEAD_ZONE) && (input >= MIDDLE - DEAD_ZONE))
-       return STRAIGHT_TURN_OUT;
-       // On SPEKTRUM, MIN_RC = 1 msec = stick right; MAX_RC = 2 msec = stick left
-       // On HI_TEC, MIN_RC = 1 msec = stick left; MAX_RC = 2 msec = stick right
-      // LEFT_TURN_OUT > RIGHT_TURN_OUT
-      else
-          return input;
-
-// @ToDo: Fix this so it is correct in any case.
-// If a controller requires some value to be reversed, then specify that
-// requirement in Settings.h, and use the setting here.
+  long int steerRange, rcRange;
+  long output;
+  int trueOut;
+  //     Serial.print("\tconvertTurn: input = \t"); Serial.print(input);
+  //  Check if Input is in steer dead zone
+  if ((input <= MIDDLE + DEAD_ZONE) && (input >= MIDDLE - DEAD_ZONE))
+    return STRAIGHT_TURN_OUT;
+  // On SPEKTRUM, MIN_RC = 1 msec = stick right; MAX_RC = 2 msec = stick left
+  // On HI_TEC, MIN_RC = 1 msec = stick left; MAX_RC = 2 msec = stick right
+  // LEFT_TURN_OUT > RIGHT_TURN_OUT
+  else
+    return input;
+
+  // @ToDo: Fix this so it is correct in any case.
+  // If a controller requires some value to be reversed, then specify that
+  // requirement in Settings.h, and use the setting here.
 #ifdef RC_HITEC
   input = MAX_RC - (input - MIN_RC);
 #endif
-
-//      if (input > MIDDLE + DEAD_ZONE)
-//      {  // left turn
-//         steerRange = LEFT_TURN_OUT - STRAIGHT_TURN_OUT;
-//         rcRange = MAX_RC - (MIDDLE + DEAD_ZONE);
-//        input = input - MIDDLE - DEAD_ZONE; // originally input = middle + dead_zone
-//        output = STRAIGHT_TURN_OUT + input * steerRange / rcRange;
-//        //set max and min values if out of range
-//        trueOut = (int)output;
-//        if(trueOut > LEFT_TURN_OUT)
-//            trueOut = LEFT_TURN_OUT;
-//        if(trueOut < STRAIGHT_TURN_OUT)
-//            trueOut = STRAIGHT_TURN_OUT;
-//        return trueOut;
-//    }
-//      if (input < MIDDLE - DEAD_ZONE)
-//      {  // right turn
-//         steerRange = STRAIGHT_TURN_OUT - RIGHT_TURN_OUT;
-//         rcRange = MIDDLE - DEAD_ZONE - MIN_RC;
-//        input = input - DEAD_ZONE - MIDDLE;  // input is negative
-//        output = STRAIGHT_TURN_OUT + input * steerRange / rcRange;
-//        //set max and min values if out of range
-//        trueOut = (int)output;
-//        if(trueOut < RIGHT_TURN_OUT)
-//            trueOut = RIGHT_TURN_OUT;
-//        if(trueOut > STRAIGHT_TURN_OUT)
-//            trueOut = STRAIGHT_TURN_OUT;
-//        return trueOut;
-//    }
+
+  //      if (input > MIDDLE + DEAD_ZONE)
+  //      {  // left turn
+  //         steerRange = LEFT_TURN_OUT - STRAIGHT_TURN_OUT;
+  //         rcRange = MAX_RC - (MIDDLE + DEAD_ZONE);
+  //        input = input - MIDDLE - DEAD_ZONE; // originally input = middle + dead_zone
+  //        output = STRAIGHT_TURN_OUT + input * steerRange / rcRange;
+  //        //set max and min values if out of range
+  //        trueOut = (int)output;
+  //        if(trueOut > LEFT_TURN_OUT)
+  //            trueOut = LEFT_TURN_OUT;
+  //        if(trueOut < STRAIGHT_TURN_OUT)
+  //            trueOut = STRAIGHT_TURN_OUT;
+  //        return trueOut;
+  //    }
+  //      if (input < MIDDLE - DEAD_ZONE)
+  //      {  // right turn
+  //         steerRange = STRAIGHT_TURN_OUT - RIGHT_TURN_OUT;
+  //         rcRange = MIDDLE - DEAD_ZONE - MIN_RC;
+  //        input = input - DEAD_ZONE - MIDDLE;  // input is negative
+  //        output = STRAIGHT_TURN_OUT + input * steerRange / rcRange;
+  //        //set max and min values if out of range
+  //        trueOut = (int)output;
+  //        if(trueOut < RIGHT_TURN_OUT)
+  //            trueOut = RIGHT_TURN_OUT;
+  //        if(trueOut > STRAIGHT_TURN_OUT)
+  //            trueOut = STRAIGHT_TURN_OUT;
+  //        return trueOut;
+  //    }
 }
 /*---------------------------------------------------------------------------------------*/
 int convertDeg(int deg)
 {
-    int result = STRAIGHT_TURN_OUT;
-    result += (deg * 2.25);
-    return result;
+  int result = STRAIGHT_TURN_OUT;
+  result += (deg * 2.25);//magic numbers bad
+  return result;
 }
 /*---------------------------------------------------------------------------------------*/
 int convertThrottle(int input)
 {
-    //full throttle = 227, min = 40
-    const int dacRange = MAX_ACC_OUT - MIN_ACC_OUT;
-    const int rcRange = MAX_RC - (MIDDLE + DEAD_ZONE);
-    input -= (MIDDLE + DEAD_ZONE);
-    double output = (double)input /(double)rcRange;
-    output *= dacRange;
-    output += MIN_ACC_OUT;
-    //set max values if out of range
-    int trueOut = (int)output;
-    if(trueOut > MAX_ACC_OUT)
-        trueOut = MAX_ACC_OUT;
-    return trueOut;
+  //full throttle = 227, min = 40
+  const int dacRange = MAX_ACC_OUT - MIN_ACC_OUT;
+  const int rcRange = MAX_RC - (MIDDLE + DEAD_ZONE);
+  input -= (MIDDLE + DEAD_ZONE);
+  double output = (double)input / (double)rcRange;
+  output *= dacRange;
+  output += MIN_ACC_OUT;
+  //set max values if out of range
+  int trueOut = (int)output;
+  if (trueOut > MAX_ACC_OUT)
+    trueOut = MAX_ACC_OUT;
+  return trueOut;
 }
 /*---------------------------------------------------------------------------------------*/
 //Tests for inputs
 // Input not in throttle dead zone
 boolean liveThrottle(int acc)
 {
-      return (acc > MIDDLE + DEAD_ZONE);
+  return (acc > MIDDLE + DEAD_ZONE);
 }
 /*---------------------------------------------------------------------------------------*/
 // Input is not in brake dead zone
-boolean liveBrake(int brake)
-{
-      return (brake < MIDDLE - DEAD_ZONE);
+boolean liveBrake(int b)
+{
+  Serial.println("Checking Brake RC");
+  if (b < 500) return false;
+  return (b < (MIDDLE - DEAD_ZONE));
 }
 /*---------------------------------------------------------------------------------------*/
 // Emergency stop
 void E_Stop()
 {
-    brake(MAX_BRAKE_OUT);
-    moveVehicle(MIN_ACC_OUT);
-    delay (2000);   // inhibit output
-    // TO DO: disable 36V power
+  brake(MAX_BRAKE_OUT);
+  moveVehicle(MIN_ACC_OUT);
+  delay (2000);   // inhibit output
+  // TO DO: disable 36V power
 }
 /*---------------------------------------------------------------------------------------*/
 //Send values to output pin
 void steer(int pos)
 {
-      STEER_SERVO.writeMicroseconds(pos);
-//      Serial.print("\tSteering to: \t"); Serial.print(pos);
-     steer_control = pos;
-}
-/*---------------------------------------------------------------------------------------*/
-void convertBrake(long unsigned *amount)
-{
-      if (*amount < (MIDDLE + MIN_RC)/2)
-          *amount = MAX_BRAKE_OUT;
-      else
-           *amount = MIN_BRAKE_OUT;
-      brake (*amount);
+  STEER_SERVO.writeMicroseconds(pos);
+  //      Serial.print("\tSteering to: \t"); Serial.print(pos);
+  steer_control = pos;
+}
+/*---------------------------------------------------------------------------------------*/
+void convertBrake(unsigned long amount)
+{
+  if(amount < (MIDDLE + MIN_RC) / 2)
+    amount = MAX_BRAKE_OUT;
+  else if (amount > (MAX_RC - DEAD_ZONE))
+    amount = MIN_BRAKE_OUT;
+  brake (amount);
 }
 /*---------------------------------------------------------------------------------------*/
 void brake (int amount)
 {
-      analogWrite(BRAKE_OUT_PIN, amount);
- //     Serial.print("\tBraking to: \t"); Serial.print(*amount);
-      brake_control = amount;
+  analogWrite(BRAKE_OUT_PIN, amount);
+  //     Serial.print("\tBraking to: \t"); Serial.print(*amount);
+  brake_control = amount;
 }
 /*---------------------------------------------------------------------------------------*/
 /* DAC_Write applies value to address, producing an analog voltage.
-// address: 0 for chan A; 1 for chan B; 2 for chan C; 3 for chan D
-// value: digital value converted to analog voltage
-// Output goes to mcp 4802 Digital-Analog Converter Chip via SPI
-// There is no input back from the chip.
+  // address: 0 for chan A; 1 for chan B; 2 for chan C; 3 for chan D
+  // value: digital value converted to analog voltage
+  // Output goes to mcp 4802 Digital-Analog Converter Chip via SPI
+  // There is no input back from the chip.
 */
 void DAC_Write(int address, int value)
 /*
-REGISTER 5-3: WRITE COMMAND REGISTER FOR MCP4802 (8-BIT DAC)
-A/B — GA SHDN D7 D6 D5 D4 D3 D2 D1 D0 x x x x
-bit 15 bit 0
-bit 15 A/B: DACA or DACB Selection bit
-1 = Write to DACB
-0 = Write to DACA
-bit 14 — Don’t Care
-bit 13 GA: Output Gain Selection bit
-1 = 1x (VOUT = VREF * D/4096)
-0 = 2x (VOUT = 2 * VREF * D/4096), where internal VREF = 2.048V.
-bit 12 SHDN: Output Shutdown Control bit
-1 = Active mode operation. VOUT is available.
-0 = Shutdown the selected DAC channel. Analog output is not available at the channel that was shut down.
-VOUT pin is connected to 500 k (typical)
-bit 11-0 D11:D0: DAC Input Data bits. Bit x is ignored.
-With 4.95 V on Vcc, observed output for 255 is 4.08V.
-This is as documented; with gain of 2, maximum output is 2 * Vref
+  REGISTER 5-3: WRITE COMMAND REGISTER FOR MCP4802 (8-BIT DAC)
+  A/B — GA SHDN D7 D6 D5 D4 D3 D2 D1 D0 x x x x
+  bit 15 bit 0
+  bit 15 A/B: DACA or DACB Selection bit
+  1 = Write to DACB
+  0 = Write to DACA
+  bit 14 — Don’t Care
+  bit 13 GA: Output Gain Selection bit
+  1 = 1x (VOUT = VREF * D/4096)
+  0 = 2x (VOUT = 2 * VREF * D/4096), where internal VREF = 2.048V.
+  bit 12 SHDN: Output Shutdown Control bit
+  1 = Active mode operation. VOUT is available.
+  0 = Shutdown the selected DAC channel. Analog output is not available at the channel that was shut down.
+  VOUT pin is connected to 500 k (typical)
+  bit 11-0 D11:D0: DAC Input Data bits. Bit x is ignored.
+  With 4.95 V on Vcc, observed output for 255 is 4.08V.
+  This is as documented; with gain of 2, maximum output is 2 * Vref
 */
 {
-      int byte1 = ((value & 0xF0)>>4) | 0x10; // acitve mode, bits D7-D4
-      int byte2 = (value & 0x0F)<<4; // D3-D0
-      if (address < 2)
-      {
-          // take the SS pin low to select the chip:
-          digitalWrite(SelectAB,LOW);
-          if (address >= 0)
-          {
-              if (address == 1)
-                  byte1 |= 0x80; // second channnel
-              SPI.transfer(byte1);
-              SPI.transfer(byte2);
-          }
-          // take the SS pin high to de-select the chip:
-          digitalWrite(SelectAB,HIGH);
-      }
-      else
-      {
-          // take the SS pin low to select the chip:
-          digitalWrite(SelectCD,LOW);
-          if (address <= 3)
-          {
-              if (address == 3)
-                  byte1 |= 0x80; // second channnel
-              SPI.transfer(byte1);
-              SPI.transfer(byte2);
-          }
-          // take the SS pin high to de-select the chip:
-          digitalWrite(SelectCD,HIGH);
-      }
+  int byte1 = ((value & 0xF0) >> 4) | 0x10; // acitve mode, bits D7-D4
+  int byte2 = (value & 0x0F) << 4; // D3-D0
+  if (address < 2)
+  {
+    // take the SS pin low to select the chip:
+    digitalWrite(SelectAB, LOW);
+    if (address >= 0)
+    {
+      if (address == 1)
+        byte1 |= 0x80; // second channnel
+      SPI.transfer(byte1);
+      SPI.transfer(byte2);
+    }
+    // take the SS pin high to de-select the chip:
+    digitalWrite(SelectAB, HIGH);
+  }
+  else
+  {
+    // take the SS pin low to select the chip:
+    digitalWrite(SelectCD, LOW);
+    if (address <= 3)
+    {
+      if (address == 3)
+        byte1 |= 0x80; // second channnel
+      SPI.transfer(byte1);
+      SPI.transfer(byte2);
+    }
+    // take the SS pin high to de-select the chip:
+    digitalWrite(SelectCD, HIGH);
+  }
 }
 /*---------------------------------------------------------------------------------------*/
 void moveVehicle(int acc)
 {
-      /* Observed behavior on ElCano #1 E-bike no load (May 10, 2013, TCF)
-      0.831 V at rest 52 counts
-      1.20 V: nothing 75
-      1.27 V: just starting 79
-      1.40 V: slow, steady 87
-      1.50 V: brisker 94
-      3.63 V: max 227 counts
-      255 counts = 4.08 V
-      */
-      DAC_Write(DAC_CHANNEL, acc);
-      throttle_control = acc;    // post most recent throttle.
+  /* Observed behavior on ElCano #1 E-bike no load (May 10, 2013, TCF)
+    0.831 V at rest 52 counts
+    1.20 V: nothing 75
+    1.27 V: just starting 79
+    1.40 V: slow, steady 87
+    1.50 V: brisker 94
+    3.63 V: max 227 counts
+    255 counts = 4.08 V
+  */
+  DAC_Write(DAC_CHANNEL, acc);
+  throttle_control = acc;    // post most recent throttle.
 }

 /*========================================================================/
- *============================WheelRev4 code==============================/
- *=======================================================================*/
-
+  ============================WheelRev4 code==============================/
+  =======================================================================*/
+
 /* Wheel Revolution Interrupt routine
    Ben Spencer 10/21/13
    Modified by Tyler Folsom 3/16/14; 3/3/16
-
-   A cyclometer gives a click once per revolution.
+
+   A cyclometer gives a click once per revolution.
    This routine computes the speed.
 */

@@ -796,219 +806,219 @@
 volatile unsigned long TickTime = 0;  // Time from one wheel rotation to the next gives speed.
 volatile unsigned long OldTick = 0;

-   static struct hist {
-     long olderSpeed_mmPs;  // older data
-     unsigned long olderTime_ms;   // time stamp of older speed
-
-     long oldSpeed_mmPs;  // last data from the interrupt
-     byte oldClickNumber;
-     unsigned long oldTime_ms;  // time stamp of old speed
-
-     byte nowClickNumber;  // situation when we want to display the speed
-     byte InterruptState;
-     unsigned long nowTime_ms;
-     unsigned long TickTime_ms;  // Tick times are used to compute speeds
-     unsigned long OldTick_ms;   // Tick times may not match time stamps if we don't process
-                                 // results of every interrupt
-   } history;
-
-/*---------------------------------------------------------------------------------------*/
+static struct hist {
+  long olderSpeed_mmPs;  // older data
+  unsigned long olderTime_ms;   // time stamp of older speed
+
+  long oldSpeed_mmPs;  // last data from the interrupt
+  byte oldClickNumber;
+  unsigned long oldTime_ms;  // time stamp of old speed
+
+  byte nowClickNumber;  // situation when we want to display the speed
+  byte InterruptState;
+  unsigned long nowTime_ms;
+  unsigned long TickTime_ms;  // Tick times are used to compute speeds
+  unsigned long OldTick_ms;   // Tick times may not match time stamps if we don't process
+  // results of every interrupt
+} history;
+
+/*---------------------------------------------------------------------------------------*/
 // WheelRev is called by an interrupt.
 void WheelRev()
 {
-    static int flip = 0;
-    unsigned long tick;
-    noInterrupts();
-    tick = millis();
-    if (InterruptState != IRQ_RUNNING)
+  static int flip = 0;
+  unsigned long tick;
+  noInterrupts();
+  tick = millis();
+  if (InterruptState != IRQ_RUNNING)
     // Need to process 1st two interrupts before results are meaningful.
-        InterruptState++;
-
-    if (tick - TickTime > MinTickTime_ms)
-    {
-        OldTick = TickTime;
-        TickTime = tick;
-        ++ClickNumber;
+    InterruptState++;
+
+  if (tick - TickTime > MinTickTime_ms)
+  {
+    OldTick = TickTime;
+    TickTime = tick;
+    ++ClickNumber;
+  }
+  if (flip)
+    digitalWrite(13, LOW);
+  else
+    digitalWrite(13, HIGH);
+  flip = !flip;
+
+  interrupts();
+}
+/*---------------------------------------------------------------------------------------*/
+
+void setupWheelRev()
+{
+
+  //    SerialOdoOut.begin(115200); // C6 to C4
+  //    pinMode(13, OUTPUT); //led
+  //    digitalWrite(13, LOW);//turn LED off
+  //
+  pinMode(3, INPUT);//pulls input HIGH
+  float MinTick = WHEEL_DIAMETER_MM * PI;
+  //    SerialMonitor.print (" MinTick = ");
+  //    SerialMonitor.println (MinTick);
+  MinTick *= 1000.0;
+  MinTick /= MAX_SPEED_mmPs;
+  //    SerialMonitor.print (MinTick);
+  MinTickTime_ms = MinTick;
+  //    SerialMonitor.print (" MinTickTime_ms = ");
+  //    SerialMonitor.println (MinTickTime_ms);
+
+  //    SerialMonitor.print (" MIN_SPEED_mPh = ");
+  //    SerialMonitor.print (MIN_SPEED_mPh);
+  float MIN_SPEED_mmPs =  ((MIN_SPEED_mPh * 1000.0) / 3600.0);
+  // MIN_SPEED_mmPs = 135 mm/s
+  //    SerialMonitor.print (" MIN_SPEED_mmPs = ");
+  //    SerialMonitor.print (MIN_SPEED_mmPs);
+  float MaxTick = (WHEEL_DIAMETER_MM * PI * 1000.0) / MIN_SPEED_mmPs;
+  //    SerialMonitor.print (" MaxTick = ");
+  //    SerialMonitor.print (MaxTick);
+  MaxTickTime_ms = MaxTick;
+  //    SerialMonitor.print (" MaxTickTime = ");
+  //    SerialMonitor.println (MaxTickTime_ms);
+  TickTime = millis();
+  // OldTick will normally be less than TickTime.
+  // When it is greater, TickTime - OldTick is a large positive number,
+  // indicating that we have not moved.
+  // TickTime would overflow after days of continuous operation, causing a glitch of
+  // a display of zero speed.  It is unlikely that we have enough battery power to ever see this.
+  OldTick = TickTime;
+  InterruptState = IRQ_NONE;
+  ClickNumber = 0;
+  history.oldSpeed_mmPs = history.olderSpeed_mmPs = NO_DATA;
+
+  attachInterrupt (1, WheelRev, RISING);//pin 3 on Mega
+  //    SerialMonitor.print("TickTime: ");
+  //    SerialMonitor.print(TickTime);
+  //    SerialMonitor.print(" OldTick: ");
+  //    SerialMonitor.println(OldTick);
+
+  //    SerialMonitor.println("WheelRev setup complete");
+
+}
+/*---------------------------------------------------------------------------------------*/
+void ComputeSpeed( struct hist *data)
+{
+  if (data->InterruptState == IRQ_NONE || data->InterruptState == IRQ_FIRST)
+  { // No data
+    SpeedCyclometer_mmPs = 0;
+    SpeedCyclometer_revPs = 0;
+    return;
+  }
+  float Circum_mm = (WHEEL_DIAMETER_MM * PI);
+  long WheelRev_ms = data->TickTime_ms - data->OldTick_ms;
+  if (data->InterruptState >= IRQ_SECOND && data->oldSpeed_mmPs == NO_DATA && WheelRev_ms > 0)
+  { //  first computed speed
+    SpeedCyclometer_revPs = 1000.0 / WheelRev_ms;
+    SpeedCyclometer_mmPs  =
+      data->oldSpeed_mmPs = Circum_mm * SpeedCyclometer_revPs;
+    data->oldTime_ms = data->TickTime_ms;  // time stamp for oldSpeed_mmPs
+    data->oldClickNumber = data->nowClickNumber;
+    return;
+  }
+  if (data->InterruptState == IRQ_RUNNING && data->olderSpeed_mmPs == NO_DATA && WheelRev_ms > 0
+      && data->nowClickNumber != data->oldClickNumber)
+  { //  new data for second computed speed
+    data->olderSpeed_mmPs = data->oldSpeed_mmPs;
+    data->olderTime_ms = data->oldTime_ms;
+
+    SpeedCyclometer_revPs = 1000.0 / WheelRev_ms;
+    SpeedCyclometer_mmPs  =
+      data->oldSpeed_mmPs = Circum_mm * SpeedCyclometer_revPs;
+    data->oldTime_ms = data->TickTime_ms;  // time stamp for oldSpeed_mmPs
+    data->oldClickNumber = data->nowClickNumber;
+    return;
+  }
+  if (data->InterruptState == IRQ_RUNNING && data->olderSpeed_mmPs != NO_DATA && WheelRev_ms > 0)
+  { // Normal situation after initialization
+    if (data->nowClickNumber == data->oldClickNumber)
+    { // No new information; extrapolate the speed if decelerating; else keep old speed
+      if (data->olderSpeed_mmPs > data->oldSpeed_mmPs)
+      { // decelerrating
+        float deceleration = (float) (data->olderSpeed_mmPs - data->oldSpeed_mmPs) /
+                             (data->oldTime_ms - data->olderTime_ms);
+        SpeedCyclometer_mmPs = data->oldSpeed_mmPs - deceleration *
+                               (data->nowTime_ms - data->oldTime_ms);
+        if (SpeedCyclometer_mmPs < 0)
+          SpeedCyclometer_mmPs = 0;
+        SpeedCyclometer_revPs = SpeedCyclometer_mmPs / Circum_mm;
+      }
+      else
+      { // accelerating; should get new data soon
+
+      }
+      if (data->nowTime_ms - data->oldTime_ms > MaxTickTime_ms)
+      { // too long without getting a tick
+        SpeedCyclometer_mmPs = 0;
+        SpeedCyclometer_revPs = 0;
+        if (data->nowTime_ms - data->oldTime_ms > 2 * MaxTickTime_ms)
+        {
+          InterruptState = IRQ_FIRST;  //  Invalidate old data
+          data->oldSpeed_mmPs = NO_DATA;
+          data->olderSpeed_mmPs = NO_DATA;
+        }
+      }
     }
-    if (flip)
-        digitalWrite(13, LOW);
     else
-        digitalWrite(13, HIGH);
-    flip =!flip;
-
-    interrupts();
-}
-/*---------------------------------------------------------------------------------------*/
-
-void setupWheelRev()
-{
-
-//    SerialOdoOut.begin(115200); // C6 to C4
-//    pinMode(13, OUTPUT); //led
-//    digitalWrite(13, LOW);//turn LED off
-//
-    pinMode(3, INPUT);//pulls input HIGH
-    float MinTick = WHEEL_DIAMETER_MM * PI;
-//    SerialMonitor.print (" MinTick = ");
-//    SerialMonitor.println (MinTick);
-    MinTick *= 1000.0;
-    MinTick /= MAX_SPEED_mmPs;
-//    SerialMonitor.print (MinTick);
-    MinTickTime_ms = MinTick;
-//    SerialMonitor.print (" MinTickTime_ms = ");
-//    SerialMonitor.println (MinTickTime_ms);
-
-//    SerialMonitor.print (" MIN_SPEED_mPh = ");
-//    SerialMonitor.print (MIN_SPEED_mPh);
-    float MIN_SPEED_mmPs =  ((MIN_SPEED_mPh * 1000.0) / 3600.0);
-    // MIN_SPEED_mmPs = 135 mm/s
-//    SerialMonitor.print (" MIN_SPEED_mmPs = ");
-//    SerialMonitor.print (MIN_SPEED_mmPs);
-    float MaxTick = (WHEEL_DIAMETER_MM * PI * 1000.0) / MIN_SPEED_mmPs;
-//    SerialMonitor.print (" MaxTick = ");
-//    SerialMonitor.print (MaxTick);
-    MaxTickTime_ms = MaxTick;
-//    SerialMonitor.print (" MaxTickTime = ");
-//    SerialMonitor.println (MaxTickTime_ms);
-    TickTime = millis();
-    // OldTick will normally be less than TickTime.
-    // When it is greater, TickTime - OldTick is a large positive number,
-    // indicating that we have not moved.
-    // TickTime would overflow after days of continuous operation, causing a glitch of
-    // a display of zero speed.  It is unlikely that we have enough battery power to ever see this.
-    OldTick = TickTime;
-    InterruptState = IRQ_NONE;
-    ClickNumber = 0;
-    history.oldSpeed_mmPs = history.olderSpeed_mmPs = NO_DATA;
-
-    attachInterrupt (1, WheelRev, RISING);//pin 3 on Mega
-//    SerialMonitor.print("TickTime: ");
-//    SerialMonitor.print(TickTime);
-//    SerialMonitor.print(" OldTick: ");
-//    SerialMonitor.println(OldTick);
-
-//    SerialMonitor.println("WheelRev setup complete");
-
-}
-/*---------------------------------------------------------------------------------------*/
-void ComputeSpeed( struct hist *data)
-{
-    if (data->InterruptState == IRQ_NONE || data->InterruptState == IRQ_FIRST)
-    {  // No data
-       SpeedCyclometer_mmPs = 0;
-       SpeedCyclometer_revPs = 0;
-       return;
+    { // moving; use new data to compute speed
+      data->olderSpeed_mmPs = data->oldSpeed_mmPs;
+      data->olderTime_ms = data->oldTime_ms;
+
+      SpeedCyclometer_revPs = 1000.0 / WheelRev_ms;
+      SpeedCyclometer_mmPs  =
+        data->oldSpeed_mmPs = Circum_mm * SpeedCyclometer_revPs;
+      data->oldTime_ms = data->TickTime_ms;  // time stamp for oldSpeed_mmPs
+      data->oldClickNumber = data->nowClickNumber;
     }
-    float Circum_mm = (WHEEL_DIAMETER_MM * PI);
-    long WheelRev_ms = data->TickTime_ms - data->OldTick_ms;
-    if (data->InterruptState >= IRQ_SECOND && data->oldSpeed_mmPs == NO_DATA && WheelRev_ms > 0)
-    {   //  first computed speed
-        SpeedCyclometer_revPs = 1000.0 / WheelRev_ms;
-        SpeedCyclometer_mmPs  =
-        data->oldSpeed_mmPs = Circum_mm * SpeedCyclometer_revPs;
-        data->oldTime_ms = data->TickTime_ms;  // time stamp for oldSpeed_mmPs
-        data->oldClickNumber = data->nowClickNumber;
-        return;
-    }
-    if (data->InterruptState == IRQ_RUNNING && data->olderSpeed_mmPs == NO_DATA && WheelRev_ms > 0
-       && data->nowClickNumber != data->oldClickNumber)
-    {   //  new data for second computed speed
-        data->olderSpeed_mmPs = data->oldSpeed_mmPs;
-        data->olderTime_ms = data->oldTime_ms;
-
-        SpeedCyclometer_revPs = 1000.0 / WheelRev_ms;
-        SpeedCyclometer_mmPs  =
-        data->oldSpeed_mmPs = Circum_mm * SpeedCyclometer_revPs;
-        data->oldTime_ms = data->TickTime_ms;  // time stamp for oldSpeed_mmPs
-        data->oldClickNumber = data->nowClickNumber;
-        return;
-    }
-    if (data->InterruptState == IRQ_RUNNING && data->olderSpeed_mmPs != NO_DATA && WheelRev_ms > 0)
-    {  // Normal situation after initialization
-        if (data->nowClickNumber == data->oldClickNumber)
-        {  // No new information; extrapolate the speed if decelerating; else keep old speed
-            if (data->olderSpeed_mmPs > data->oldSpeed_mmPs)
-            {   // decelerrating
-                float deceleration = (float) (data->olderSpeed_mmPs - data->oldSpeed_mmPs) /
-                (data->oldTime_ms - data->olderTime_ms);
-                SpeedCyclometer_mmPs = data->oldSpeed_mmPs - deceleration *
-                (data->nowTime_ms - data->oldTime_ms);
-                if (SpeedCyclometer_mmPs < 0)
-                    SpeedCyclometer_mmPs = 0;
-                SpeedCyclometer_revPs = SpeedCyclometer_mmPs / Circum_mm;
-            }
-            else
-            {  // accelerating; should get new data soon
-
-            }
-            if(data->nowTime_ms - data->oldTime_ms > MaxTickTime_ms)
-            {  // too long without getting a tick
-                SpeedCyclometer_mmPs = 0;
-                SpeedCyclometer_revPs = 0;
-                if(data->nowTime_ms - data->oldTime_ms > 2 * MaxTickTime_ms)
-                {
-                    InterruptState = IRQ_FIRST;  //  Invalidate old data
-                    data->oldSpeed_mmPs = NO_DATA;
-                    data->olderSpeed_mmPs = NO_DATA;
-                }
-            }
-        }
-        else
-        {  // moving; use new data to compute speed
-            data->olderSpeed_mmPs = data->oldSpeed_mmPs;
-            data->olderTime_ms = data->oldTime_ms;
-
-            SpeedCyclometer_revPs = 1000.0 / WheelRev_ms;
-            SpeedCyclometer_mmPs  =
-          data->oldSpeed_mmPs = Circum_mm * SpeedCyclometer_revPs;
-            data->oldTime_ms = data->TickTime_ms;  // time stamp for oldSpeed_mmPs
-            data->oldClickNumber = data->nowClickNumber;
-        }
-    }
-    if(data->nowTime_ms - data->TickTime_ms > WheelRev_ms)
-    {  // at this speed, should have already gotten a tick?; If so, we are slowing.
-        float SpeedSlowing_revPs = 1000.0 / (data->nowTime_ms - data->TickTime_ms);
-        long SpeedSlowing_mmPs  = Circum_mm * SpeedCyclometer_revPs;
-        SpeedCyclometer_revPs = min(SpeedCyclometer_revPs, SpeedSlowing_revPs);
-        SpeedCyclometer_mmPs  = min(SpeedCyclometer_mmPs, SpeedSlowing_mmPs);
-   }
-    return;
-}
-/*---------------------------------------------------------------------------------------*/
+  }
+  if (data->nowTime_ms - data->TickTime_ms > WheelRev_ms)
+  { // at this speed, should have already gotten a tick?; If so, we are slowing.
+    float SpeedSlowing_revPs = 1000.0 / (data->nowTime_ms - data->TickTime_ms);
+    long SpeedSlowing_mmPs  = Circum_mm * SpeedCyclometer_revPs;
+    SpeedCyclometer_revPs = min(SpeedCyclometer_revPs, SpeedSlowing_revPs);
+    SpeedCyclometer_mmPs  = min(SpeedCyclometer_mmPs, SpeedSlowing_mmPs);
+  }
+  return;
+}
+/*---------------------------------------------------------------------------------------*/
 void PrintSpeed( struct hist *data)
 {
-      Serial.print(SpeedCyclometer_mmPs); Serial.print("\t");
-      Serial.print(data->InterruptState); Serial.print("\t");
-      Serial.print(data->oldSpeed_mmPs); Serial.print("\t");
-      Serial.print(data->olderSpeed_mmPs); Serial.print("\t");
-      Serial.print(data->oldClickNumber); Serial.print("\t");
-      Serial.print(data->nowClickNumber); Serial.print("\t");
-      Serial.print(data->olderTime_ms); Serial.print("\t");
-      Serial.print(data->oldTime_ms); Serial.print("\t");
-      Serial.print(data->nowTime_ms); Serial.print("\t");
-      Serial.print(data->TickTime_ms); Serial.print("\t");
-      Serial.println(data->OldTick_ms);
-}
-/*---------------------------------------------------------------------------------------*/
+  Serial.print(SpeedCyclometer_mmPs); Serial.print("\t");
+  Serial.print(data->InterruptState); Serial.print("\t");
+  Serial.print(data->oldSpeed_mmPs); Serial.print("\t");
+  Serial.print(data->olderSpeed_mmPs); Serial.print("\t");
+  Serial.print(data->oldClickNumber); Serial.print("\t");
+  Serial.print(data->nowClickNumber); Serial.print("\t");
+  Serial.print(data->olderTime_ms); Serial.print("\t");
+  Serial.print(data->oldTime_ms); Serial.print("\t");
+  Serial.print(data->nowTime_ms); Serial.print("\t");
+  Serial.print(data->TickTime_ms); Serial.print("\t");
+  Serial.println(data->OldTick_ms);
+}
+/*---------------------------------------------------------------------------------------*/
 void show_speed(SerialData *Results)
 {
-   history.nowTime_ms = millis();
-   noInterrupts();
-   history.TickTime_ms = TickTime;
-   history.OldTick_ms = OldTick;
-   history.nowClickNumber = ClickNumber;
-   history.InterruptState = InterruptState;
-   interrupts();
-
-   ComputeSpeed (&history);
-//   PrintSpeed(&history);
-
-    Odometer_m += (float)(LOOP_TIME_MS * SpeedCyclometer_mmPs) / MEG;
-// Since Results have not been cleared, angle information will also be sent.
-    Results->speed_cmPs = SpeedCyclometer_mmPs / 10;
-    writeSerial(&Serial3, Results);  // Send speed to C6
-
-    show7seg( SpeedCyclometer_mmPs);   // Show speed on 7 segment LEDs
+  history.nowTime_ms = millis();
+  noInterrupts();
+  history.TickTime_ms = TickTime;
+  history.OldTick_ms = OldTick;
+  history.nowClickNumber = ClickNumber;
+  history.InterruptState = InterruptState;
+  interrupts();
+
+  ComputeSpeed (&history);
+  //   PrintSpeed(&history);
+
+  Odometer_m += (float)(LOOP_TIME_MS * SpeedCyclometer_mmPs) / MEG;
+  // Since Results have not been cleared, angle information will also be sent.
+  Results->speed_cmPs = SpeedCyclometer_mmPs / 10;
+  writeSerial(&Serial3, Results);  // Send speed to C6
+
+  show7seg( SpeedCyclometer_mmPs);   // Show speed on 7 segment LEDs

 }
 /*---------------------------------------------------------------------------------------*/
@@ -1017,112 +1027,112 @@
           - Wheels are pointed straight ahead, and have been for a while.
           - Trike is not moving, and is stable.
     Calibration will block any response to controls; there will be no turning or movemnet during calibration.
-    Angle sensors can drift, and should periodically be zeroed.
+    Angle sensors can drift, and should periodically be zeroed.
 */
 void CalibrateTurnAngle(int count, int pause)
 {
-    int totalRight = 0;
-    int totalLeft = 0;
-    int i, left, right;
-    for (i = 0; i < count; i++)
+  int totalRight = 0;
+  int totalLeft = 0;
+  int i, left, right;
+  for (i = 0; i < count; i++)
+  {
+    totalRight += analogRead(A2);
+    totalLeft += analogRead(A3);
+    delay(pause);
+  }
+  right = totalRight / count;
+  left  = totalLeft  / count;
+  // Only recalibrate when instruments are reasonable
+  // Do not make garbage readings the new normal.
+  if (RIGHT_MIN_COUNT <= right && right <= RIGHT_MAX_COUNT)
+  {
+    RightStraight_A2 = right;
+    Right_Min_Count = RightStraight_A2 - 60;   // 60 counts is 20 degrees
+    Right_Max_Count = RightStraight_A2 + 60;
+  }
+  else
+  {
+    RightStraight_A2 = RIGHT_MIN_COUNT + (RIGHT_MAX_COUNT - RIGHT_MIN_COUNT) / 2 ;
+    Right_Min_Count = RIGHT_MIN_COUNT;
+    Right_Max_Count = RIGHT_MAX_COUNT;
+  }
+  if  (LEFT_MIN_COUNT  <= left  && left  <= LEFT_MAX_COUNT)
+  {
+    LeftStraight_A3  = left;
+    Left_Min_Count  = LeftStraight_A3  - 60;
+    Left_Max_Count  = LeftStraight_A3  + 60;
+  }
+  else
+  {
+    LeftStraight_A3  = LEFT_MIN_COUNT + (LEFT_MAX_COUNT - LEFT_MIN_COUNT) / 2 ;
+    Left_Min_Count = LEFT_MIN_COUNT;
+    Left_Max_Count = LEFT_MAX_COUNT;
+  }
+  //    Serial.print("\tCALIBRATE: Left Straight\t"); Serial.print(LeftStraight_A3);
+  //    Serial.print("\tRight Straight\t"); Serial.println(RightStraight_A2);
+  old_turn_degx1000 = 0; // straight
+}
+/*---------------------------------------------------------------------------------------*/
+/*======================ReadTurnAngle======================*/
+int TurnAngle_degx10()
+{
+  long new_turn_degx1000;
+  long expected_turn_degx1000;
+  int new_turn_degx10;
+  long min_ang, max_ang;
+  bool OK_right = false;
+  bool OK_left = false;
+  int right = analogRead(A2);
+  int left = analogRead(A3);
+  //    Serial.print("Left"); Serial.print("\t"); Serial.print(left);
+  //    Serial.print("\tRight"); Serial.print("\t"); Serial.print(right);
+  //    Serial.print("LeftStraight_A3"); Serial.print("\t"); Serial.print(LeftStraight_A3);
+  //    Serial.print("\tRightStraight_A2"); Serial.print("\t"); Serial.print(RightStraight_A2);
+  if ((Right_Min_Count <= right) && (right <= Right_Max_Count))
+    OK_right = true;
+  if ((Left_Min_Count <= left) && (left <= Left_Max_Count))
+    OK_left = true;
+  long right_degx1000 = (right - RightStraight_A2) * RIGHT_DEGx1000pCOUNT;
+  long left_degx1000  = (left -  LeftStraight_A3) *  LEFT_DEGx1000pCOUNT;
+  //    Serial.print("Left"); Serial.print("\t"); Serial.print(left_degx1000);
+  //    Serial.print("\tRight"); Serial.print("\t"); Serial.print(right_degx1000);
+
+  expected_turn_degx1000 = old_turn_degx1000;
+  if (OK_left && OK_right)
+  { // use the median
+    if (right_degx1000 < left_degx1000)
     {
-          totalRight += analogRead(A2);
-          totalLeft += analogRead(A3);
-          delay(pause);
-    }
-    right = totalRight / count;
-    left  = totalLeft  / count;
-    // Only recalibrate when instruments are reasonable
-    // Do not make garbage readings the new normal.
-    if(RIGHT_MIN_COUNT <= right && right <= RIGHT_MAX_COUNT)
-    {
-         RightStraight_A2 = right;
-         Right_Min_Count = RightStraight_A2 - 60;   // 60 counts is 20 degrees
-         Right_Max_Count = RightStraight_A2 + 60;
-     }
-    else
-    {
-         RightStraight_A2 = RIGHT_MIN_COUNT + (RIGHT_MAX_COUNT - RIGHT_MIN_COUNT)/2 ;
-         Right_Min_Count = RIGHT_MIN_COUNT;
-         Right_Max_Count = RIGHT_MAX_COUNT;
-    }
-    if  (LEFT_MIN_COUNT  <= left  && left  <= LEFT_MAX_COUNT)
-    {
-        LeftStraight_A3  = left;
-        Left_Min_Count  = LeftStraight_A3  - 60;
-        Left_Max_Count  = LeftStraight_A3  + 60;
+      min_ang = right_degx1000;
+      max_ang = left_degx1000;
     }
     else
     {
-        LeftStraight_A3  = LEFT_MIN_COUNT + (LEFT_MAX_COUNT - LEFT_MIN_COUNT)/2 ;
-        Left_Min_Count = LEFT_MIN_COUNT;
-        Left_Max_Count = LEFT_MAX_COUNT;
+      min_ang = left_degx1000;
+      max_ang = right_degx1000;
     }
-//    Serial.print("\tCALIBRATE: Left Straight\t"); Serial.print(LeftStraight_A3);
-//    Serial.print("\tRight Straight\t"); Serial.println(RightStraight_A2);
-    old_turn_degx1000 = 0; // straight
-}
-/*---------------------------------------------------------------------------------------*/
-/*======================ReadTurnAngle======================*/
-int TurnAngle_degx10()
-{
-    long new_turn_degx1000;
-    long expected_turn_degx1000;
-    int new_turn_degx10;
-    long min_ang, max_ang;
-    bool OK_right = false;
-    bool OK_left = false;
-    int right = analogRead(A2);
-    int left = analogRead(A3);
-//    Serial.print("Left"); Serial.print("\t"); Serial.print(left);
-//    Serial.print("\tRight"); Serial.print("\t"); Serial.print(right);
-//    Serial.print("LeftStraight_A3"); Serial.print("\t"); Serial.print(LeftStraight_A3);
-//    Serial.print("\tRightStraight_A2"); Serial.print("\t"); Serial.print(RightStraight_A2);
-    if ((Right_Min_Count <= right) && (right <= Right_Max_Count))
-       OK_right = true;
-    if ((Left_Min_Count <= left) && (left <= Left_Max_Count))
-       OK_left = true;
-    long right_degx1000 = (right - RightStraight_A2) * RIGHT_DEGx1000pCOUNT;
-    long left_degx1000  = (left -  LeftStraight_A3) *  LEFT_DEGx1000pCOUNT;
-//    Serial.print("Left"); Serial.print("\t"); Serial.print(left_degx1000);
-//    Serial.print("\tRight"); Serial.print("\t"); Serial.print(right_degx1000);
-
-    expected_turn_degx1000 = old_turn_degx1000;
-    if (OK_left && OK_right)
-    {  // use the median
-        if (right_degx1000 < left_degx1000)
-        {
-            min_ang = right_degx1000;
-            max_ang = left_degx1000;
-        }
-        else
-        {
-            min_ang = left_degx1000;
-            max_ang = right_degx1000;
-        }
-        if (expected_turn_degx1000 < min_ang)
-            new_turn_degx1000 = min_ang;
-        else if (expected_turn_degx1000 > max_ang)
-            new_turn_degx1000 = max_ang;
-        else
-            new_turn_degx1000 = expected_turn_degx1000;
-    }
-    else if (OK_left)
-    {
-        new_turn_degx1000 = (left_degx1000 + expected_turn_degx1000)/2;
-    }
-    else if (OK_right)
-    {
-        new_turn_degx1000 = (right_degx1000 + expected_turn_degx1000)/2;
-    }
+    if (expected_turn_degx1000 < min_ang)
+      new_turn_degx1000 = min_ang;
+    else if (expected_turn_degx1000 > max_ang)
+      new_turn_degx1000 = max_ang;
     else
-    {   // No sensors; use last valid measurement
-        new_turn_degx1000 = old_turn_degx1000;
-    }
-    new_turn_degx10 = (int) (new_turn_degx1000 / 100);
-    old_turn_degx1000 = new_turn_degx1000;
-//  Serial.print("\tnew_turn_degx10"); Serial.print("\t"); Serial.println(new_turn_degx10);
-    return new_turn_degx10;
+      new_turn_degx1000 = expected_turn_degx1000;
+  }
+  else if (OK_left)
+  {
+    new_turn_degx1000 = (left_degx1000 + expected_turn_degx1000) / 2;
+  }
+  else if (OK_right)
+  {
+    new_turn_degx1000 = (right_degx1000 + expected_turn_degx1000) / 2;
+  }
+  else
+  { // No sensors; use last valid measurement
+    new_turn_degx1000 = old_turn_degx1000;
+  }
+  new_turn_degx10 = (int) (new_turn_degx1000 / 100);
+  old_turn_degx1000 = new_turn_degx1000;
+  //  Serial.print("\tnew_turn_degx10"); Serial.print("\t"); Serial.println(new_turn_degx10);
+  return new_turn_degx10;
 }
 /*---------------------------------------------------------------------------------------*/
 void Throttle_PID(long error_speed_mmPs)
@@ -1133,15 +1143,15 @@
    I = integra;  change based on recent sum of errors
    D = derivative: change based on how error is changing.
    The controller needs to avoid problems of being too sluggish or too skittery.
-   A sluggish control (overdamped) takes too long to reach the set-point.
-   A skitterish control (underdamped) can overshoot, then undershoot, producing
+   A sluggish control (overdamped) takes too long to reach the set-point.
+   A skitterish control (underdamped) can overshoot, then undershoot, producing
    oscillations and jerky motion.
    Getting the right control is a matter of tuning right parts of P, I, and D,
    which is something of a black art.
    For more information, search for:
    VanDoren Proportional Integral Derivative Control
 */
-{
+{
   static int  throttle_control = MIN_ACC_OUT;
   static int  brake_control = MAX_BRAKE_OUT;
   static int error_index = 0;
@@ -1158,57 +1168,57 @@
   // setting the max_error affacts control: anything bigger gets maximum response
   const long max_error_mmPs = 2500; // about 5.6 mph

-//lets look through this
+  //lets look through this
   error_sum -= speed_errors[error_index];
   speed_errors[error_index] = error_speed_mmPs;
   error_sum += error_speed_mmPs;
   mean_speed_error = error_sum / ERROR_HISTORY;
-  i = (error_index -1) % ERROR_HISTORY;
+  i = (error_index - 1) % ERROR_HISTORY;
   if (++error_index >= ERROR_HISTORY)
-      error_index = 0;
+    error_index = 0;
   extrapolated_error = 2 * error_speed_mmPs - speed_errors[i];
-    PID_error = P_tune * error_speed_mmPs
-            + I_tune * mean_speed_error
-            + D_tune * extrapolated_error;
+  PID_error = P_tune * error_speed_mmPs
+              + I_tune * mean_speed_error
+              + D_tune * extrapolated_error;
   if (PID_error > speed_tolerance_mmPs)
-  {  // too fast
+  { // too fast
     long throttle_decrease = (MAX_ACC_OUT - MIN_ACC_OUT) * PID_error / max_error_mmPs;
     throttle_control -= throttle_decrease;
     if (throttle_control < MIN_ACC_OUT)
-        throttle_control = MIN_ACC_OUT;
+      throttle_control = MIN_ACC_OUT;
     moveVehicle(throttle_control);
-
+
     long brake_increase = (MAX_BRAKE_OUT - MIN_BRAKE_OUT) * PID_error / max_error_mmPs;
-    // MIN_BRAKE_OUT = 180; MAX_BRAKE_OUT = 250;
+    // MIN_BRAKE_OUT = 180; MAX_BRAKE_OUT = 250;
     brake_control -= brake_increase;
     if (brake_control > MAX_BRAKE_OUT)
-        brake_control = MAX_BRAKE_OUT;
+      brake_control = MAX_BRAKE_OUT;
     brake(brake_control);
   }
   else if (PID_error < speed_tolerance_mmPs)
-  {  // too slow
+  { // too slow
     long throttle_increase = (MAX_ACC_OUT - MIN_ACC_OUT) * PID_error / max_error_mmPs;
     throttle_control += throttle_increase;
     if (throttle_control > MAX_ACC_OUT)
-        throttle_control = MAX_ACC_OUT;
+      throttle_control = MAX_ACC_OUT;
     moveVehicle(throttle_control);
-
+
     // release brakes
     long brake_decrease = (MAX_BRAKE_OUT - MIN_BRAKE_OUT) * PID_error / max_error_mmPs;
-    // MIN_BRAKE_OUT = 180; MAX_BRAKE_OUT = 250;
+    // MIN_BRAKE_OUT = 180; MAX_BRAKE_OUT = 250;
     brake_control += brake_decrease;
     if (brake_control < MIN_BRAKE_OUT)
-        brake_control = MIN_BRAKE_OUT;
+      brake_control = MIN_BRAKE_OUT;
     brake(brake_control);
   }
   // else maintain current speed
-//  Serial.print("\tThrottle Brake \t");  // csv for spreadsheet
-//  Serial.print(throttle_control);
-//  Serial.print("\t");
-//  Serial.print(brake_control);
-//  Serial.print("\t");
-//  Serial.print(drive_speed_mmPs);  Serial.print("\t");
-//  Serial.println(sensor_speed_mmPs);
+  //  Serial.print("\tThrottle Brake \t");  // csv for spreadsheet
+  //  Serial.print(throttle_control);
+  //  Serial.print("\t");
+  //  Serial.print(brake_control);
+  //  Serial.print("\t");
+  //  Serial.print(drive_speed_mmPs);  Serial.print("\t");
+  //  Serial.println(sensor_speed_mmPs);
 }

 /*---------------------------------------------------------------------------------------*/
@@ -1243,7 +1253,7 @@

   // Clear the display, and then turn on all segments and decimals
   clearDisplay();  // Clears display, resets cursor
-//  setBrightness(127);  // Medium brightness
+  //  setBrightness(127);  // Medium brightness
   setBrightness(255);  // High brightness
 }
 /*---------------------------------------------------------------------------------------*/
@@ -1251,12 +1261,12 @@
 {
   char tempString[4];  // Will be used with sprintf to create strings
   // convert mm/s to km/h
-  int speed_kmPhx10 = (speed_mmPs*.036);
+  int speed_kmPhx10 = (speed_mmPs * .036);
   // Magical sprintf creates a string for us to send to the s7s.
   //  The %4d option creates a 4-digit integer.
   sprintf(tempString, "%4d", speed_kmPhx10);
   String temp3 = (String)tempString;
-//  Serial.println(temp3);
+  //  Serial.println(temp3);

   // This will output the tempString to the S7S
   s7s.print(temp3);
@@ -1283,7 +1293,7 @@
 }
 /*---------------------------------------------------------------------------------------*/
 // Turn on any, none, or all of the decimals.
-//  The six lowest bits in the decimals parameter sets a decimal
+//  The six lowest bits in the decimals parameter sets a decimal
 //  (or colon, or apostrophe) on or off. A 1 indicates on, 0 off.
 //  [MSB] (X)(X)(Apos)(Colon)(Digit 4)(Digit 3)(Digit2)(Digit1)
 void setDecimals(byte decimals)


Update base2clock.ino

Update base2clock.ino

Moved delay code.

--- base2clock.ino
+++ base2clock.ino
@@ -90,19 +90,15 @@
       if(!setIncrementFlag())
         doIncrement();
     }
-  } else { // time has never been set so just blink the lights.
+    delay(interval_time);
+ } else { // time has never been set so just blink the lights.
     if(p8 == 0)
       p8 = p7 = p6 = p5 = p4 = p3 = p2 = p1 = 1;
     else
       p8 = p7 = p6 = p5 = p4 = p3 = p2 = p1 = 0;
     lightLights();
-  }
-
-  // figure out the loop delay, typically 10 seconds, 1 second if the time has never been set
-  // and we are blinking the lights
-  if(!time_set)
-    delay(1000 * BLINK_DELAY);
-  else delay(interval_time);
+    delay(1000 * BLINK_DELAY);
+ }
 } // end loop()

 void setTimeSlow(){


one byte hex led display

one byte hex led display

--- dummycomm.ino
+++ dummycomm.ino
@@ -60,6 +60,14 @@
 			bytebits[i++] = 0;
 		value = value >> 1;
 	}
+}
+
+void bytesbufHexled() {
+	byte high= bytesbuf[1] / 16;
+	byte low = bytesbuf[1] % 16;
+	bytesbuf[0] = 2;
+	bytesbuf[1] = hexled[high];
+	bytesbuf[2] = ((hexled[low] & 0x0f) << 4 ) | ((hexled[low] & 0xf0) >> 4 );
 }

 int readFrame(int cyclecount0, int cyclecount1)
@@ -136,9 +144,7 @@
 		bytesbuf[++i]=Serial.parseInt();
 	}
 	if (bytesbuf[0] == 1) {
-		bytesbuf[1] = hexled[bytesbuf[1]];
-		bytesbuf[2] = 0;
-		bytesbuf[0] = bytesbuf[0] + 1;
+		bytesbufHexled();
 	}
 	digitalWrite(LED, LOW);
 	digitalWrite(BTX, LOW);


Fix Arduino sketch for test board

Fix Arduino sketch for test board

--- TestRig/TestProgram_Arduino/TestProgram_Arduino.ino
+++ TestRig/TestProgram_Arduino/TestProgram_Arduino.ino
@@ -313,12 +313,12 @@
   data);
 }
 void commit(int addr) {
-  if (PROG_FLICKER) prog_lamp(LOW);
+//  if (PROG_FLICKER) prog_lamp(LOW);
   spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
-  if (PROG_FLICKER) {
-    delay(PTIME);
-    prog_lamp(HIGH);
-  }
+//  if (PROG_FLICKER) {
+//    delay(PTIME);
+//    prog_lamp(HIGH);
+//  }
 }

 //#define _current_page(x) (here & 0xFFFFE0)
@@ -383,13 +383,13 @@
   // this writes byte-by-byte,
   // page writing may be faster (4 bytes at a time)
   fill(length);
-  prog_lamp(LOW);
+//  prog_lamp(LOW);
   for (int x = 0; x < length; x++) {
     int addr = start+x;
     spi_transaction(0xC0, (addr>>8) & 0xFF, addr & 0xFF, buff[x]);
     delay(45);
   }
-  prog_lamp(HIGH);
+//  prog_lamp(HIGH);
   return STK_OK;
 }

@@ -681,3 +681,4 @@

+


Added circle to server

Added circle to server


Since the buzzer on the air conditioning set was removed, repeat IR sending is no more annoyed.

--- QmoteRHTlogger_w_Daikin/QmoteRHTlogger_w_Daikin.ino
+++ QmoteRHTlogger_w_Daikin/QmoteRHTlogger_w_Daikin.ino
@@ -23,7 +23,6 @@
 // for AltSoftSerial, TX/RX pins are hard coded: RX = digital pin 8, TX = digital pin 9 on Arduino Uno
 AltSoftSerial portOne;
 String recvLine = "";
-bool qmoteDisconnected = false;
 int resend = 0;

 // Daikin Control
@@ -32,37 +31,28 @@

 //  ambient environmental parameters
 #define TEMP_SETTING          24          // cooling setting to this temperature
-#define HEAT_INDEX_HIGH       27.8        // restart cooling if temperature reaches this measurement
-#define HEAT_INDEX_TOO_HIGH   29          // use Heat Index to check if the ambient condition needs to be changed, if so, KEEP_OFF_TIMER will be ignored
+#define HEAT_INDEX_HIGH       28          // restart cooling if temperature reaches this measurement
+#define HEAT_INDEX_TOO_HIGH   30          // use Heat Index to check if the ambient condition needs to be changed, if so, KEEP_OFF_TIMER will be ignored
+#define TEMP_HIGH             26.5        // Highheat index may be caused by Rh, set High limitation to determine cooling or dehumidifier
 #define TEMP_LOW              25          // stop cooling or switch to humidifier if temerature reaches this measurement
 #define TEMP_TOO_LOW          23          // if temperature reaches this value means humidifier goes too much, turn off everything
-#define RH_HIGH               68          // restart humidifier if Rh reaches to this measurement
+#define RH_HIGH               69          // restart humidifier if Rh reaches to this measurement
 #define RH_LOW                60          // stop humidifier if Rh reaches to this measurement

 // avoid frequent ON-OFF mode switch
-#define KEEP_ONOFF_TIMER      90
-
-// when Qmote is disconnected, a timer counts the time before it is reconnected back
-// if the disconnected time is longer than this value, a permanent disconnection is considered and the air conditioning will be off
-#define DISCONNECT_OFF_TIMER  20
+#define KEEP_ONOFF_TIMER      45
+#define RESEND_ATTEMPS        3

 #define MODE_OFF              0
 #define MODE_COOLING          1
 #define MODE_DEHUMIDIFIER     2

-// Resending Control
-unsigned int resend_attempts = 1;
-
-// Flag for startup calibration
-bool startup_calibration = true;
-
 // Elapsed Time Control
 elapsedMillis timeElapsed;

-// Auto Shutoff Control
-elapsedMillis disconnectDurationCheck;
-bool disconnecting = false;
-
+/**
+ *  Setup
+ */
 void setup() {
   // Setup SHT3x
   sht3x.setAddress(SHT3X::I2C_ADDRESS_44);
@@ -77,7 +67,6 @@

   // reset the air conditioning control
   isOn = MODE_OFF;
-  disconnecting = false;

   // needs no UART echo
   String qmoteCmd = "ATE0\r\n";
@@ -93,11 +82,11 @@

   // delay extra 10 seconds so the first RhT information can be sent to Qmote
   delay(10000);
-
-  // when startup, issue more IR firing for direction califbration
-  startup_calibration = true;
-}
-
+}
+
+/**
+ *  Flash Qmote LED
+ */
 void flash_LED()
 {
   String qmoteCmd;
@@ -113,6 +102,9 @@
   portOne.write(qmoteCmd.c_str());
 }

+/**
+ *  WeMo ON
+ */
 void wemo_fan_on()
 {
   String qmoteCmd;
@@ -125,6 +117,9 @@
   }
 }

+/**
+ *  WeMo OFF
+ */
 void wemo_fan_off()
 {
   String qmoteCmd;
@@ -137,6 +132,9 @@
   }
 }

+/**
+ *  Switch to cooling mode
+ */
 void daikin_cooling_on()
 {
   String qmoteCmd;
@@ -162,6 +160,9 @@
   wemo_fan_off();
 }

+/**
+ *  Switch to dehumidifier mode
+ */
 void daikin_dehumidifier_on()
 {
   String qmoteCmd;
@@ -187,6 +188,9 @@
   wemo_fan_off();
 }

+/**
+ *  Air conditioning OFF
+ */
 void daikin_all_off()
 {
   String qmoteCmd;
@@ -200,7 +204,6 @@
   isOn = MODE_OFF;
   resend++;
   timeElapsed = 0;            // reset mode-switch timer
-  // don't put just_off here to avoid startup calibration off

   // report this state change
   qmoteCmd = "ATBN=0x0A,\"air cond OFF\"\r\n";    // using click combination code 0x0A, --..
@@ -209,20 +212,9 @@
   // flash Qmote LED as indicator
   flash_LED();

-  if(!qmoteDisconnected)
-  {
-    // turn on FAN through WeMo Switch
-    wemo_fan_on();
-  }
-  else
-  {
-    // turn off FAN through WeMo Switch
-    // Note: this control is tricky. If Qmote is disconnected, this command never goes to WeMo.
-    //       the ultimate solution will be a disconnected trigger of Qmote on IFTTT.
-    wemo_fan_off();
-  }
-}
-
+  // turn on FAN through WeMo Switch
+  wemo_fan_on();
+}

 /**
  * Heat Index Calculator
@@ -244,7 +236,9 @@
  return ((float) rvC);
 }

-
+/**
+ *  Main loop
+ */
 void loop() {
   String qmoteCmd;
   float currentTemp;
@@ -258,6 +252,10 @@
   currentTemp = sht3x.getTemperature();
   currentRh = sht3x.getHumidity();

+  // ---------------------------------------------------------------------------------------------------------------------------------
+  // Sending reports
+  // ---------------------------------------------------------------------------------------------------------------------------------
+
   // filter out incorrect SHT3x reading
   if(currentTemp > -100 && currentRh >= 0)
   {
@@ -265,21 +263,19 @@
     unsigned int currentRhInt = (unsigned int) currentRh;
     float currentHeatIndex = heatIndex((double) currentTemp, (double) currentRh);

-
-
-//debug
-unsigned int teim = timeElapsed / (long) 60000;
-qmoteCmd = "ATBN=0x0A,\"";      // using click combination code 0x0A
-qmoteCmd += isOn;
-qmoteCmd += qmoteDisconnected;
-qmoteCmd += ",";
-qmoteCmd += teim;
-qmoteCmd += "\"\r\n";
-portOne.write(qmoteCmd.c_str());
-delay(3000);
-
-
-
+    /*
+    //debug output
+    unsigned int teim = timeElapsed / (long) 60000;
+    qmoteCmd = "ATBN=0x0A,\"";        // using click combination code 0x0A, --..
+    qmoteCmd += isOn;
+    qmoteCmd += ",";
+    qmoteCmd += teim;
+    qmoteCmd += "\"\r\n";
+    portOne.write(qmoteCmd.c_str());
+    delay(3000);
+    */
+
+    // RhT logging in text file
     qmoteCmd = "ATBN=0x0A,\"RH";      // using click combination code 0x0A, --..
     qmoteCmd += currentRhInt;
     qmoteCmd += ",T";
@@ -301,7 +297,11 @@
     portOne.write(qmoteCmd.c_str());
   }

-  // check Qmote Status
+  // ---------------------------------------------------------------------------------------------------------------------------------
+  // Processing incoming commands
+  // ---------------------------------------------------------------------------------------------------------------------------------
+
+  // check if Qmote has incoming notifications or commands
   while (portOne.available() > 0)
   {
     char c = portOne.read();
@@ -310,29 +310,8 @@
     {
       // null terminated
       recvLine += 0x00;
-
-      // process this line if Qmote never gets disconnected
-      if(!qmoteDisconnected)
-      {
-        if(recvLine.indexOf("ST: 0") >= 0)
-        {
-          // received "DISCONNECTED" status message
-
-          // set the flag
-          disconnecting = true;
-
-          // restart the timer the timer
-          disconnectDurationCheck = 0;
-        }
-
-        if(recvLine.indexOf("ST: 1") >= 0)
-        {
-          // received "CONNECTED" status message
-
-          // uncheck the flag
-          disconnecting = false;
-        }
-      } // end if(!qmoteDisconnected)
+
+      // reserved for the future command processing use

       // clear the line
       recvLine = "";
@@ -344,143 +323,100 @@
     // ignore 0x0A
   }

-  // check disconnecting status
-  unsigned int durationCheckInMin = disconnectDurationCheck / (long) 60000;
-  if(!qmoteDisconnected && disconnecting && durationCheckInMin > DISCONNECT_OFF_TIMER)
-  {
-    // status remained on disconnected over 3 minutes
+  // =================================================================================================================================
+  // PROCEED THE ENVIRONMENT CONTROL
+  // =================================================================================================================================
+
+  // delay before next command and sample the data again
+  sht3x.readSample();
+  delay(2000);
+
+  // read SHT3x again
+  currentTemp = sht3x.getTemperature();
+  currentRh = sht3x.getHumidity();
+
+  // filter out incorrect SHT3x reading
+  if(currentTemp > -100 && currentRh >= 0)
+  {
+    // Calculate Heat Index
+    float curHeatIndex = heatIndex((double) currentTemp, (double) currentRh);

-    // set the flag, do not operate the air conditioning any more
-    qmoteDisconnected = true;
-
-    // reset the flag to avoid short delay at the end of loop
-    disconnecting = false;
-
-    // turn off air conditioning
-    resend = 0;
-    resend_attempts = 3;  // perform disconnection IR firing 3 times
-    daikin_all_off();
-  }
-
-  // this is to prevent unattended air conditioning control
-  // once the Qmote is disconnected, no more auto air conditioning control
-  // until the next power cycle
-  if(!qmoteDisconnected)
-  {
-    // delay before next command and sample the data again
-    sht3x.readSample();
-    delay(2000);
-
-    // read SHT3x again
-    currentTemp = sht3x.getTemperature();
-    currentRh = sht3x.getHumidity();
-
-    // filter out incorrect SHT3x reading
-    if(currentTemp > -100 && currentRh >= 0)
+    // the following conditions will ignore the ON-OFF timer
+    if(
+       (isOn == MODE_OFF && ((float) curHeatIndex) >= ((float) HEAT_INDEX_TOO_HIGH)) ||                   // heat index too high
+       (isOn != MODE_OFF && ((float) currentTemp) <= ((float) TEMP_TOO_LOW)) ||                           // temperature too low
+       (isOn == MODE_COOLING && ((float) currentTemp) < ((float) TEMP_LOW) && currentRh > RH_LOW) ||      // cooling -> dehumidifier
+       (isOn == MODE_DEHUMIDIFIER &&                                                                      // dehumidifier -> cooling
+        ((((float) currentTemp) > ((float) TEMP_LOW) && currentRh < RH_LOW) ||
+         ((float) curHeatIndex >= (float) HEAT_INDEX_HIGH)))
+      )
     {
-      // Calculate Heat Index
-      float curHeatIndex = heatIndex((double) currentTemp, (double) currentRh);
+      // ambient condition exceeds the limit, skip the KEEP_ONOFF_TIMER
+      timeElapsed = (long) KEEP_ONOFF_TIMER * (long) 60000;
+    }
+
+    // once the air conditioning mode is switched, keep the state for a certain amount of time
+    // otherwise, it will be annoyed
+    unsigned int timeElaspedInMinutes = timeElapsed / (long) 60000;
+    if(timeElaspedInMinutes >= KEEP_ONOFF_TIMER)
+    {
+      // Since there is no beep now (I took off the buzzer on the air conditioning set), resend the same command every KEEP_ONOFF_TIMER in case the previous IR is missed
+      resend = RESEND_ATTEMPS - 1;

-      // the following conditions will ignore the ON-OFF timer
-      if(
-         (isOn == MODE_OFF && ((float) curHeatIndex) >= ((float) HEAT_INDEX_TOO_HIGH)) ||                   // heat index too high
-         (isOn != MODE_OFF && ((float) currentTemp) <= ((float) TEMP_TOO_LOW)) ||                           // temperature too low
-         (isOn == MODE_COOLING && ((float) currentTemp) < ((float) TEMP_LOW) && currentRh > RH_LOW) ||      // cooling -> dehumidifier
-         (isOn == MODE_DEHUMIDIFIER &&                                                                      // dehumidifier -> cooling
-          ((((float) currentTemp) > ((float) TEMP_LOW) && currentRh < RH_LOW) ||
-           ((float) curHeatIndex >= (float) HEAT_INDEX_HIGH)))
-        )
+      // determine the air conditioning state
+      if(isOn == MODE_OFF)
       {
-        // ambient condition exceeds the limit, skip the KEEP_ONOFF_TIMER
-        timeElapsed = (long) KEEP_ONOFF_TIMER * (long) 60000;
-      }
-
-      // once the air conditioning mode is switched, keep the state for a certain amount of time
-      // otherwise, it will be annoyed
-      unsigned int timeElaspedInMinutes = timeElapsed / (long) 60000;
-      if(timeElaspedInMinutes >= KEEP_ONOFF_TIMER)
-      {
-        // determine the air conditioning state
-        if(isOn == MODE_OFF)
+        // assume current air conditioning is OFF
+        // heat index (temperature) priority
+        if((float) curHeatIndex >= (float) HEAT_INDEX_HIGH)
         {
-          // assume current air conditioning is OFF
-          // heat index (temperature) priority
-          if((float) curHeatIndex >= (float) HEAT_INDEX_HIGH)
+          // I guess this is a Winter Mode
+          if(((float) currentTemp) > ((float) TEMP_HIGH))
           {
-            resend = 0;
-            resend_attempts = 1;
             daikin_cooling_on();
           }
-          else if(currentRh >= RH_HIGH)
+          else
           {
-            resend = 0;
-            resend_attempts = 1;
             daikin_dehumidifier_on();
           }
         }
-        else if(isOn == MODE_COOLING)
+      }
+      else if(isOn == MODE_COOLING)
+      {
+        // assume current air condition in running cooling
+        if(((float) currentTemp) < ((float) TEMP_LOW) && currentRh <= RH_LOW)
         {
-          // assume current air condition in running cooling
-          if(((float) currentTemp) < ((float) TEMP_LOW) && currentRh <= RH_LOW)
-          {
-            resend = 0;
-            resend_attempts = 2;
-            daikin_all_off();
-          }
-          else if(((float) currentTemp) < ((float) TEMP_LOW) && currentRh > RH_LOW)
-          {
-            resend = 0;
-            resend_attempts = 1;
-            daikin_dehumidifier_on();
-          }
+          daikin_all_off();
         }
-        else // MODE_DEHUMIDIFIER
+        else if(((float) currentTemp) < ((float) TEMP_LOW) && currentRh > RH_LOW)
         {
-          // assume current air conditioning is running dehumidifier
-          if((((float) currentTemp) <= ((float) TEMP_LOW) && currentRh < RH_LOW) ||       // meet both criterias
-             (((float) currentTemp) <= ((float) TEMP_TOO_LOW)))                           // humidifier goes too far, stop the air conditioning temperarily
-          {
-            resend = 0;
-            resend_attempts = 2;
-            daikin_all_off();
-          }
-          else if((((float) currentTemp) > ((float) TEMP_LOW) && currentRh < RH_LOW) ||   // humidity reaches low but temperature is higher than low
-                  ((float) curHeatIndex >= (float) HEAT_INDEX_HIGH))                      // heat index reaches high no matter how much humidity is
-          {
-            resend = 0;
-            resend_attempts = 1;
-            daikin_cooling_on();
-          }
+          daikin_dehumidifier_on();
         }
-      } // end if(timeElaspedInMinutes >= KEEP_ONOFF_TIMER)
-    } // end if(currentTemp > -100 ...)
-  } // end if(!qmoteDisconnected)
-
-  // delay a minutes until next reading unless the Qmote status in in the disconnecting state
-  if(!disconnecting && !startup_calibration)
-  {
-    delay(60000);
-  }
-  else
-  {
-    delay(3000);
-  }
-
-  // if this is the first time get here,
-  // issue more IR attempts for the IR direction calibration
-  if(startup_calibration)
-  {
-    resend_attempts = 3;
-
-    // calibration window time is up
-    if(resend >= 2)
-    {
-      startup_calibration = false;
-    }
-  }
+      }
+      else // MODE_DEHUMIDIFIER
+      {
+        // assume current air conditioning is running dehumidifier
+        if((((float) currentTemp) <= ((float) TEMP_LOW) && currentRh < RH_LOW) ||       // meet both criterias
+           (((float) currentTemp) <= ((float) TEMP_TOO_LOW)))                           // humidifier goes too far, stop the air conditioning temperarily
+        {
+          daikin_all_off();
+        }
+        else if((((float) currentTemp) > ((float) TEMP_LOW) && currentRh < RH_LOW) ||   // humidity reaches low but temperature is higher than low
+                ((float) currentTemp > (float) TEMP_HIGH))                              // if high temp reached, switch to cooling
+        {
+          daikin_cooling_on();
+        }
+      }
+    } // end if(timeElaspedInMinutes >= KEEP_ONOFF_TIMER)
+  } // end if(currentTemp > -100 ...)
+
+  // =================================================================================================================================
+
+  // delay a minutes until next reading
+  delay(60000);

   // Since IR has no feedback, multiple sends to ensure the command was received
-  if(resend < resend_attempts)
+  if(resend < RESEND_ATTEMPS)
   {
     switch(isOn)
     {
@@ -501,3 +437,4 @@
     delay(5000);
   }
 }
+


implement bluetooth

implement bluetooth

--- hook___dail/hook___dail.ino
+++ hook___dail/hook___dail.ino
@@ -45,6 +45,18 @@
  * \ref Error_Codes
  */
   char buffer[6]; // 0-35K+null
+
+
+//////////////// BLUETOOTH
+#define bt_power 7
+#define bt_key_power 8
+#define indication_led 13
+
+#include <SoftwareSerial.h>
+SoftwareSerial BT(3, 2); // RX | TX
+
+char c = ' ';
+//////////////// END BLUETOOTH

 // constants
@@ -75,6 +87,51 @@
   Serial.println();
   Serial.println();

+
+  ///////////////////////////////////////////////////// SETUP BLUETOOTH
+  // set the pins to OUTPUT
+  pinMode(bt_power, OUTPUT);
+  pinMode(bt_key_power, OUTPUT);
+  pinMode(indication_led, OUTPUT);
+
+  // set the pins to LOW
+  digitalWrite(bt_power, LOW);
+  digitalWrite(bt_key_power, LOW);
+  digitalWrite(indication_led, LOW);
+
+  // make sure the key has been LOW for a bit
+  delay(100);
+
+  // set the key pin to High
+  digitalWrite(bt_key_power, HIGH);
+
+  // small delay
+  delay(100);
+
+  // now power on the BT
+  digitalWrite(bt_power, HIGH);
+
+  // start our serial so we can send and recieve
+  // information from the BT module
+  Serial.begin(9600);
+  // initiate the BT serial at 38400 which is the default
+  // speed at which the BT AT mode operates at
+  BT.begin(38400);
+  Serial.println("BT started at 38400");
+
+  // self explanatory
+  Serial.write("For a list of commands, visit: \n");
+  Serial.write("Type AT commands  \n\n");
+
+  // process complete turn on led 13
+  digitalWrite(indication_led, HIGH);
+
+  // Send an "AT" command to the AT (without quotes)
+  // if response is OK, then we are connected
+  // and ready to program the BT module
+
+  ///////////////////////////////////////////////////// END SETUP BLUETOOTH
+
   //Initialize the SdCard.
   if(!sd.begin(SD_SEL, SPI_FULL_SPEED)) sd.initErrorHalt();
   // depending upon your SdCard environment, SPI_HAVE_SPEED may work better.
@@ -85,72 +142,85 @@
   //check result, see readme for error codes.
   }

-#if (0)
+  #if (0)
   // Typically not used by most shields, hence commented out.
   //Serial.println(F("Applying ADMixer patch."));
   if(MP3player.ADMixerLoad("admxster.053") == 0) {
     //Serial.println(F("Setting ADMixer Volume."));
     MP3player.ADMixerVol(-3);
   }
-#endif
+  #endif

 void loop()
 {
+  ///////////////////////////////////////// BLUETOOTH
+  // listen for a response from the HC-05 and write it to the serial monitor
+  if (BT.available()){
+    c = BT.read();
+    Serial.write(c);
+  }
+  // listen for user input and send it to the HC-05
+  if (Serial.available()){
+    c = Serial.read();
+    Serial.write(c);
+    BT.write(c);
+  }
+  ///////////////////////////////////////// END BLUETOOTH
+
   if (digitalRead(A0)==HIGH)
-{
-  int reading = digitalRead(in);
-
-
-if ((millis() - lastStateChangeTime) > dialHasFinishedRotatingAfterMs) {
-// the dial isn't being dialed, or has just finished being dialed.
-if (needToPrint) {
-// if it's only just finished being dialed, we need to send the number down the serial
-// line and reset the count. We mod the count by 10 because '0' will send 10 pulses.
-
-if(count==1){
-  MP3player.stopTrack();
-  Serial.println("Dail 1-9 to select one track.");
-  Serial.println();
-}
-
-  else{
-   Serial.print("You select track: ");
-   Serial.println(count-1);
-   Serial.println("The music is playing");
-   MP3player.stopTrack();
-   MP3player.playTrack(count-1);
-   Serial.println();
-   Serial.println("Hey,you can add some sound effect!");
-   Serial.println();
-  }
-
-
-needToPrint = 0;
-count = 0;
-cleared = 0;
-}
+  {
+    int reading = digitalRead(in);
+
+
+    if ((millis() - lastStateChangeTime) > dialHasFinishedRotatingAfterMs) {
+    // the dial isn't being dialed, or has just finished being dialed.
+      if (needToPrint) {
+      // if it's only just finished being dialed, we need to send the number down the serial
+      // line and reset the count. We mod the count by 10 because '0' will send 10 pulses.
+
+      if(count==1){
+        MP3player.stopTrack();
+        Serial.println("Dail 1-9 to select one track.");
+        Serial.println();
+      }
+
+      else{
+        Serial.print("You select track: ");
+        Serial.println(count-1);
+        Serial.println("The music is playing");
+        MP3player.stopTrack();
+        MP3player.playTrack(count-1);
+        Serial.println();
+        Serial.println("Hey,you can add some sound effect!");
+        Serial.println();
+      }
+
+
+      needToPrint = 0;
+      count = 0;
+      cleared = 0;
+      }
+    }
+
+    if (reading != lastState) {
+      lastStateChangeTime = millis();
+    }
+      if ((millis() - lastStateChangeTime) > debounceDelay) {
+      // debounce - this happens once it's stablized
+        if (reading != trueState) {
+        // this means that the switch has either just gone from closed->open or vice versa.
+        trueState = reading;
+          if (trueState == HIGH) {
+          // increment the count of pulses if it's gone high.
+          count++;
+          needToPrint = 1; // we'll need to print this number (once the dial has finished rotating)
+          }
+        }
+      }
+      lastState = reading;
+  }
+  else {
+    MP3player.stopTrack();
+  }
 }

-if (reading != lastState) {
-lastStateChangeTime = millis();
-}
-if ((millis() - lastStateChangeTime) > debounceDelay) {
-// debounce - this happens once it's stablized
-if (reading != trueState) {
-// this means that the switch has either just gone from closed->open or vice versa.
-trueState = reading;
-if (trueState == HIGH) {
-// increment the count of pulses if it's gone high.
-count++;
-needToPrint = 1; // we'll need to print this number (once the dial has finished rotating)
-}
-}
-}
-lastState = reading;
-}
-else
-{
-MP3player.stopTrack();
-}
-}
-


Missing semicolon

Missing semicolon

--- examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino
+++ examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino
@@ -31,7 +31,7 @@

   // is configuration portal requested?
   if(digitalRead(TRIGGER_PIN) == LOW) {
-    delay(50)
+    delay(50);
     if(digitalRead(TRIGGER_PIN) == LOW) {
       if(!portalRunning){
         Serial.println("Button Pressed, Starting Portal");