Better reset option during startup, close #6

--- DigitalVFO.ino
+++ DigitalVFO.ino
@@ -68,7 +68,7 @@
 // address in display CGRAM for definable characters
 #define SELECT_CHAR     0     // shows 'underlined' decimal digits (dynamic, 0 to 9)
 #define SPACE_CHAR      1     // shows an 'underlined' space character
-#define ALLSET_CHAR     0xff  // shows an 'all bits set' character, used for 'bar' display
+#define ALLSET_CHAR     0xff  // the 'all bits set' char in display RAM, used for 'bar' display

 // define the numeric digits and space with selection underline
 byte sel0[8] = {0xe,0x11,0x13,0x15,0x19,0x11,0xe,0x1f};
@@ -113,7 +113,7 @@
 #define vfo_Click     5
 #define vfo_HoldClick 6

-// the "in use" display character
+// the "in use" display character, ">"
 #define IN_USE_CHAR   0x7e

 // default LCD contrast & brightness
@@ -145,34 +145,36 @@
 // Abort the program.
 // Tries to tell the world what went wrong, then just loops.
 //     msg  address of error string
-// Only first 32 chars of message is displayed.
+// Only first NUM_ROWS*NUM_COLS chars of message is displayed on LCD.
 //----------------------------------------

 void abort(const char *msg)
 {
-  char buf[NUM_COLS*2+1];
+  char buf[NUM_COLS*NUM_ROWS+1];
   char *ptr = buf;

   // print error on console (maybe)
   Serial.printf(F("message=%s\nTeensy is paused!\n"), msg);

-  // truncate/pad message to 32 chars
-  for (int i = 0; i < NUM_COLS*2; ++i)
+  // truncate/pad message to NUM_ROWS * NUM_COLS chars
+  for (int i = 0; i < NUM_COLS*NUM_ROWS; ++i)
     *ptr++ = ' ';
   *ptr = '\0';

-  strncpy(buf, msg, NUM_COLS*2);
-  if (strlen(msg) < NUM_COLS*2)
-    strncpy(buf + strlen(msg), "                                ", NUM_COLS*2 - strlen(msg));
+  strncpy(buf, msg, NUM_COLS*NUM_ROWS);
+  if (strlen(msg) < NUM_COLS*NUM_ROWS)
+    strncpy(buf + strlen(msg), "                                ",
+            NUM_COLS*NUM_ROWS - strlen(msg));

   // show what we can on the display, forever
   while (1)
   {
     lcd.clear();
-    lcd.setCursor(0, 0);
-    lcd.print(buf);
-    lcd.setCursor(0, 1);
-    lcd.print(buf + NUM_COLS);
+    for (int i = 0; i < NUM_ROWS; ++i)
+    {
+      lcd.setCursor(0, i);
+      lcd.print(buf + i*NUM_COLS);
+    }
     delay(2000);

     lcd.clear();
@@ -191,7 +193,7 @@
 // Convert an event number to a display string
 //----------------------------------------

-const char * event2display(VFOEvent event)
+const char *event2display(VFOEvent event)
 {
   switch (event)
   {
@@ -202,15 +204,15 @@
     case vfo_DnRRight:  return "vfo_DnRRight";
     case vfo_Click:     return "vfo_Click";
     case vfo_HoldClick: return "vfo_HoldClick";
-    default:            return "UNKNOWN!";
-  }
+  }
+
+  return "UNKNOWN!";
 }

 //----------------------------------------
 // display a simple banner on the LCD
 //----------------------------------------

-#ifndef VFO_DEBUG
 void banner(void)
 {
   Serial.printf(F("%s %s (%s)\n"), ProgramName, Version, Callsign);
@@ -222,23 +224,18 @@
   lcd.print(Version);
   lcd.setCursor(0, 1);
   lcd.print(Callsign);
-  delay(2000);    // wait a bit
-
-  for (int i = 0; i <= NUM_COLS; ++i)
-  {
-    lcd.clear();
-    lcd.setCursor(i, 0);
-    lcd.print(ProgramName);
-    lcd.print(" ");
-    lcd.print(Version);
-    lcd.setCursor(0, 1);
-    lcd.print(Callsign16 + i);
-    delay(200);
-  }
-
-  delay(500);
-}
-#endif
+  delay(1000);    // wait a bit
+
+  // do a fade out
+  for (int i = LcdBrightness; i; --i)
+  {
+    analogWrite(mc_Brightness, i);
+    delay(10);
+  }
+  lcd.clear();
+  delay(300);
+  analogWrite(mc_Brightness, LcdBrightness);
+}

 //----------------------------------------
 // Function to convert an unsigned long into an array of byte digit values.
@@ -256,8 +253,6 @@

 void ulong2buff(char *buf, int bufsize, unsigned long value)
 {
-  Serial.printf(F("ulong2buff: bufsize=%d, value=%ld\n"), bufsize, value);
-
   char *ptr = buf + bufsize - 1;    // rightmost char in 'buf'

   for (int i = 0; i < bufsize; ++i)
@@ -266,8 +261,6 @@

     value = value / 10;
     *ptr-- = char(rem);
-
-    Serial.printf(F("long2buff: stored byte %d, i=%d\n"), rem, i);
   }
 }

@@ -330,7 +323,7 @@

 //----------------------------------------
 // Draw the menu on the screen
-//     menu      pointer to a Menu structure
+//     menu  pointer to a Menu structure
 //----------------------------------------

 void menu_draw(struct Menu *menu)
@@ -342,7 +335,7 @@
 }

 //----------------------------------------
-// Draw a standard or custom menuitem on the screen.
+// Draw a standard menuitem on the screen.
 //     menu      pointer to a Menu structure
 //     item_num  the item number to show
 //----------------------------------------
@@ -378,10 +371,6 @@
 void menu_show(struct Menu *menu, int unused)
 {
   int item_num = 0;     // index of the menuitem to show
-
-#ifdef VFO_DEBUG
-  dump_menu("menu_show, menu:", menu);
-#endif

   // draw the menu page
   menu_draw(menu);
@@ -453,7 +442,7 @@
 // flashes the menu page in a possibly eye-catching way
 //----------------------------------------

-void menu_flash(void)
+void display_flash(void)
 {
   lcd.noDisplay();
   delay(100);
@@ -535,8 +524,13 @@

 void event_flush(void)
 {
+  // Must protect from RE code fiddling with queue
+  noInterrupts();
+
   queue_fore = 0;
   queue_aft = 0;
+
+  interrupts();
 }

 void event_dump_queue(const char *msg)
@@ -566,70 +560,12 @@
 ////////////////////////////////////////////////////////////////////////////////

 //----------------------------------------
-// Print the frequency on the display with selected colum underlined.
-//     freq     the frequency to display
-//     sel_col  the selection offset of digit to underline
-//              (0 is rightmost digit, increasing to the left)
-//     row      the row to use, 0 is at top
-// The row and columns used to show frequency digits are defined elsewhere.
-//----------------------------------------
-
-void print_freq(Frequency freq, int sel_col, int row)
-{
-  char buf [MAX_FREQ_CHARS];
-  int index = MAX_FREQ_CHARS - sel_col - 1;
-  bool lead_zero = true;
-
-  Serial.printf(F("print_freq: freq=%ld, row=%d\n"), freq, row);
-
-  ulong2buff(buf, MAX_FREQ_CHARS, freq);
-
-  lcd.createChar(SELECT_CHAR, sel_digits[int(buf[index])]);
-  lcd.setCursor(NUM_COLS - MAX_FREQ_CHARS - 2, row);
-  for (int i = 0; i < MAX_FREQ_CHARS; ++i)
-  {
-    int char_val = buf[i];
-
-    if (char_val != 0)
-        lead_zero = false;
-
-    if (lead_zero)
-    {
-      if (index == i)
-      {
-        lcd.write(byte(SPACE_CHAR));
-        Serial.printf(F("print_freq: wrote selected space\n"));
-      }
-      else
-      {
-        lcd.write(" ");
-        Serial.printf(F("print_freq: wrote space\n"));
-      }
-    }
-    else
-    {
-      if (index == i)
-      {
-        lcd.write(byte(SELECT_CHAR));
-        Serial.printf(F("print_freq: wrote selected char\n"));
-      }
-      else
-      {
-        lcd.write(char_val + '0');
-        Serial.printf("print_freq: wrote char %d\n", char_val);
-      }
-    }
-  }
-}
-
-//----------------------------------------
-// Display an unsigned long on the display with selected colum underlined.
+// Display an unsigned long on the display with selected column underlined.
 //     value       the number to display
 //     sel_col     the selection offset of digit to underline
 //                 (0 is rightmost digit, increasing to the left)
 //     num_digits  the number of digits to show on the display
 //     col, row    position to display left-most digit at
-// The LCD cursor position is assumed set before this function is called.
 // If the value is too long it will be truncated at the left.
 //----------------------------------------

@@ -639,8 +575,6 @@
   int index = num_digits - sel_col - 1;
   bool lead_zero = true;

-  Serial.printf(F("display_sel_value: value=%ld, num_digits=%d\n"), value, num_digits);
-
   ulong2buff(buf, num_digits, value);

   lcd.createChar(SELECT_CHAR, sel_digits[int(buf[index])]);
@@ -657,12 +591,10 @@
       if (index == i)
       {
         lcd.write(byte(SPACE_CHAR));
-        Serial.printf(F("display_sel_value: wrote selected space\n"));
       }
       else
       {
         lcd.write(" ");
-        Serial.printf(F("display_sel_value: wrote space\n"));
       }
     }
     else
@@ -670,12 +602,10 @@
       if (index == i)
       {
         lcd.write(byte(SELECT_CHAR));
-        Serial.printf(F("display_sel_value: wrote selected char\n"));
       }
       else
       {
         lcd.write(char_val + '0');
-        Serial.printf("display_sel_value: wrote char %d\n", char_val);
       }
     }
   }
@@ -710,7 +640,12 @@
 // Setup the encoder stuff, pins, etc.
 //----------------------------------------

-void re_setup(int position)
+//----------------------------------------
+// Initialize the rotary encoder stuff
+// Return 'true' if button was pressed down
+//----------------------------------------
+
+bool re_setup(void)
 {
   // set RE data pins as pullup inputs
   pinMode(re_pinA, INPUT_PULLUP);
@@ -721,11 +656,18 @@
   attachInterrupt(digitalPinToInterrupt(re_pinA), pinA_isr, RISING);
   attachInterrupt(digitalPinToInterrupt(re_pinB), pinB_isr, RISING);
   attachInterrupt(digitalPinToInterrupt(re_pinPush), pinPush_isr, CHANGE);
+
+  // look at RE button, if DOWN this function returns 'true'
+  return ! (PIND & 0x10);
+
+//  if (re_down)
+//  return false;
 }

 void pinPush_isr(void)
 {
   re_down = ! (PIND & 0x10);
+
   if (re_down)
   {
     // button pushed down
@@ -1006,10 +948,6 @@
 // Main VFO code
 ////////////////////////////////////////////////////////////////////////////////

-//----------------------------------------
-// The standard Arduino setup() function.
-//----------------------------------------
-
 #ifdef VFO_RESET
 void zero_eeprom(void)
 {
@@ -1033,21 +971,21 @@
 }
 #endif

+//----------------------------------------
+// The standard Arduino setup() function.
+//----------------------------------------
+
 void setup(void)
 {
+  // initialize the serial console
   Serial.begin(115200);

-#ifdef VFO_RESET
-  zero_eeprom();
-  Serial.printf(F("All EEPROM data reset\n"));
-#endif
-
   // initialize the display
-  lcd.begin(NUM_COLS, NUM_COLS);      // define display size
+  lcd.begin(NUM_COLS, NUM_ROWS);      // define display size
   lcd.clear();
   lcd.noCursor();
-  lcd.createChar(SPACE_CHAR, sel_digits[SPACE_INDEX]);
-
+
+  // set brightness/contrast pin state
   pinMode(mc_Brightness, OUTPUT);
   pinMode(mc_Contrast, OUTPUT);

@@ -1056,45 +994,30 @@
   analogWrite(mc_Brightness, LcdBrightness);
   analogWrite(mc_Contrast, LcdContrast);

+  // create underlined space for frequency display
+  lcd.createChar(SPACE_CHAR, sel_digits[SPACE_INDEX]);
+
   // set up the DDS device
   dds_setup();
-
-  // set up the rotary encoder
-  re_setup(VfoSelectDigit);
-
-  // show program name and version number
-#ifndef VFO_DEBUG
-  banner();
-
-  // we might have got a 'reset' HoldClick during banner presentation
-  if (event_pop() == vfo_HoldClick)
-  {
-    // if holdClick during banner, reset all "Settings" values
+
+  // set up the rotary encoder, reset a few things if RE button down
+  if (re_setup())
+  {
     LcdBrightness = DefaultLcdBrightness;
     analogWrite(mc_Brightness, LcdBrightness);
     LcdContrast = DefaultLcdContrast;
     analogWrite(mc_Contrast, LcdContrast);
-    ReHoldClickTime = DefaultHoldClickTime;
-
-    // tell what happened on LCD
-    lcd.clear();
-    lcd.print("Reset all values");
-    lcd.setCursor(0, 1);
-    lcd.print("in Settings menu");
-
-    // and Serial console
-    Serial.printf(F("Reset brightness to %d, contrast to %d and hold time to %d\n"),
+    ReHoldClickTime = DefaultHoldClickTime;
+
+    Serial.printf(F("Resetting brightness to %d, contrast to %d and hold time to %d\n"),
                   LcdBrightness, LcdContrast, ReHoldClickTime);
-    Serial.printf(F("Select or rotate the rotary encoder to continue\n"));
-
-    // wait here until there is some input action
-    event_flush();
-    while (! event_pending())
-      delay(100);
-    event_flush();
-    delay(500);
-  }
-#endif
+  }
+
+  // we sometimes see random events on powerup, flush them here
+  event_flush();
+
+  // show program name and version number
+  banner();

   // we sometimes see random events on powerup, flush them here
   event_flush();
@@ -1106,9 +1029,6 @@

   // get going
   show_main_screen();
-
-  // we sometimes see random events on powerup, flush them here
-  event_flush();
 }

 //----------------------------------------
@@ -1120,7 +1040,6 @@
   lcd.setCursor(0, 0);
   lcd.print("Freq:");
   display_sel_value(VfoFrequency, VfoSelectDigit, MAX_FREQ_CHARS, NUM_COLS - MAX_FREQ_CHARS - 2, 0);
-//  print_freq(VfoFrequency, VfoSelectDigit, 0);
   lcd.print("Hz");
 }

@@ -1144,7 +1063,7 @@
   lcd.setCursor(4, 1);
   lcd.write(slot_num + '0');
   lcd.print(":");
-  print_freq(freq, -1, 1);
+  display_sel_value(freq, -1, MAX_FREQ_CHARS, NUM_COLS - MAX_FREQ_CHARS - 2, 1);
   lcd.print("Hz");
 }

@@ -1189,7 +1108,7 @@
         case vfo_Click:
           put_slot(slot_num, VfoFrequency, VfoSelectDigit);
           show_slot_frequency(slot_num);
-          menu_flash();
+          display_flash();
           break;
         case vfo_HoldClick:
           event_flush();
@@ -1245,7 +1164,7 @@
           break;
         case vfo_Click:
           get_slot(slot_num, VfoFrequency, VfoSelectDigit);
-          menu_flash();
+          display_flash();
           break;
         case vfo_HoldClick:
           event_flush();
@@ -1303,7 +1222,7 @@
           break;
         case vfo_Click:
           put_slot(slot_num, zero_freq, zero_offset);
-          menu_flash();
+          display_flash();
           break;
         case vfo_HoldClick:
           event_flush();
@@ -1374,7 +1293,7 @@
           break;
         case vfo_Click:
           save_to_eeprom();
-          menu_flash();
+          display_flash();
           break;
         case vfo_HoldClick:
           event_flush();
@@ -1435,7 +1354,7 @@
           break;
         case vfo_Click:
           save_to_eeprom();
-          menu_flash();
+          display_flash();
           break;
         case vfo_HoldClick:
           event_flush();
@@ -1532,7 +1451,7 @@
         case vfo_Click:
           ReHoldClickTime = holdtime;
           save_to_eeprom();
-          menu_flash();
+          display_flash();
           break;
         case vfo_HoldClick:
           event_flush();
@@ -1635,7 +1554,6 @@
     if (old_freq != VfoFrequency || old_position != VfoSelectDigit)
     {
       display_sel_value(VfoFrequency, VfoSelectDigit, MAX_FREQ_CHARS, NUM_COLS - MAX_FREQ_CHARS - 2, 0);
-//      print_freq(VfoFrequency, VfoSelectDigit, 0);
       old_freq = VfoFrequency;
       old_position = VfoSelectDigit;


fill small

fill small

--- coni/arduino/main/small/small.ino
+++ coni/arduino/main/small/small.ino
@@ -0,0 +1,149 @@
+#include <SoftwareSerial.h>
+#include <AccelStepper.h>
+#include <MultiStepper.h>
+
+#define pinRX 11
+#define pinTX 12
+
+//MOTORE STRETTO -
+#define pinStep_A 4     //bianco
+#define pinDirection_A 5   //giallo
+#define pinSens_A A2
+
+//MOTORE LARGO
+#define pinStep_B 9     //bianco
+#define pinDirection_B 10   //giallop
+#define pinSens_B A0
+
+#define RE 6
+#define DE 7
+
+#define MAXSPEED 3000
+#define MAXACC 1500
+
+SoftwareSerial mySerial(pinRX, pinTX);
+AccelStepper stepper_A(1, pinStep_A, pinDirection_A);
+AccelStepper stepper_B(1, pinStep_B, pinDirection_B);
+MultiStepper steppers;
+
+void setup() {
+  mySerial.begin(4800);
+
+  stepper_A.setMaxSpeed(MAXSPEED);
+  stepper_B.setMaxSpeed(MAXSPEED);
+  stepper_A.setAcceleration(MAXACC);
+  stepper_B.setAcceleration(MAXACC);
+
+  steppers.addStepper(stepper_A);
+  steppers.addStepper(stepperB);
+
+  //200 step per rev
+  //
+  pinMode(pinSens_A, INPUT_PULLUP);
+  pinMode(pinSens_B, INPUT_PULLUP);
+
+  pinMode(RE, OUTPUT);
+  pinMode(DE, OUTPUT);
+  digitalWrite(RE, LOW);
+  digitalWrite(DE, LOW);
+
+  //Serial.begin(9600);
+
+  //azzeraA();
+  //azzeraB();
+}
+
+uint32_t velA = 1000;
+uint32_t velB = 1000;
+uint32_t dataIn = 0;
+long positions[2] = {0,0};
+
+void loop() {
+  if (mySerial.available()) {
+    dataIn = mySerial.parseInt();
+    if (dataIn < 1000000) {
+      positions[0] += dataIn - 500000;
+      //Serial.print("posA");
+      //Serial.println(posA);
+    }
+    else if ((dataIn >= 1000000) && (dataIn < 2000000)) {
+      velA = dataIn - 1500000;
+      stepper_A.setMaxSpeed(velA);
+      stepper_A.setAcceleration(velA - velA / 4);
+      //Serial.print("velA");
+      //Serial.println(velA);
+    }
+    else if ((dataIn >= 2000000) && (dataIn < 3000000)) {
+      positions[1] += dataIn - 2500000;
+      //Serial.print("posB");
+      //Serial.println(posB);
+    }
+    else if ((dataIn >= 3000000) && (dataIn < 4000000)) {
+      velB = dataIn - 3500000;
+      stepper_B.setMaxSpeed(velB);
+      stepper_B.setAcceleration(velB - velB / 4);
+      //Serial.print("velB");
+      //Serial.println(velB);
+    }
+    else if ((dataIn >= 4000000) && (dataIn < 5000000)) {
+      zeros_A();
+    }
+    else if ((dataIn >= 5000000) && (dataIn < 6000000)) {
+      zeros_B();
+    }
+    else if ((dataIn >= 15000000) && (dataIn < 16000000)) {
+      stepper_A.setCurrentPosition(positions[0]);
+      stepper_B.setCurrentPosition(positions[1]);
+    }
+    else if ((dataIn >= 16000000) && (dataIn < 17000000)) {
+      positions[0] = dataIn - 16500000;
+    }
+    else if ((dataIn >= 17000000) && (dataIn < 18000000)) {
+      positions[1] = dataIn - 17500000;
+    }
+
+    steppers.moveTo(positions);
+  }
+  stepper_A.run();
+  stepper_B.run();
+}
+
+void zeros_A() {
+
+  long valPos = 0;
+
+  stepper_A.setMaxSpeed(6000);
+  stepper_A.setAcceleration(2000);
+  posA += 100800;
+  stepper_A.moveTo(posA);
+  while (stepper_A.distanceToGo() > 0) {
+    if (!digitalRead(pinSens_A)) {
+      stepper_A.setCurrentPosition(posA);
+    }
+    stepper_A.run();
+  }
+  stepper_A.setCurrentPosition(0);
+  posA = 0;
+
+
+}
+
+void zeros_B() {
+
+  long valPos = 0;
+
+  stepper_B.setMaxSpeed(6000);
+  stepper_B.setAcceleration(2000);
+  posB += 100800;
+  stepper_B.moveTo(posB);
+  while (stepper_B.distanceToGo() > 0) {
+    if (!digitalRead(pinSens_B)) {
+      stepper_B.setCurrentPosition(posB);
+    }
+    stepper_B.run();
+  }
+  stepper_B.setCurrentPosition(47600);
+  posB = 47600;
+
+}
+


Tested examples

Tested examples

--- LIDARduino.ino
+++ LIDARduino.ino
@@ -14,12 +14,13 @@
   Serial.println( l.getHWversion() );
   Serial.print(F("Software Version: 0x"));
   Serial.println( l.getHWversion() );
-
+  l.enableVelocity( LL_10_MS );

 }

 void loop(){

+
 Serial.println(l.getVelocity());
 delay(500);


Rename boolean IsDST to isDST.

Rename boolean IsDST to isDST.

Make isDST function more readable.

--- routines.ino
+++ routines.ino
@@ -34,18 +34,24 @@
 time_t localTime() {
   time_t t = now() + ( timeZone * 3600 );
   //if ( dstSet ) {
-  if ( IsDST( month(t), day(t), dayOfWeek(t) ) ) {
+  if ( isDST( month(t), day(t), dayOfWeek(t) ) ) {
     t += 3600;
   }
   return t;
 }

 // IsDST(): returns true if during DST, false otherwise
-boolean IsDST(int mo, int dy, int dw) {
-  if (mo < 3 || mo > 11) { return false; } // January, February, and December are out.
-  if (mo > 3 && mo < 11) { return true; } // April to October are in
-  int previousSunday = dy - dw;
-  if (mo == 3) { return previousSunday >= 8; } // In March, we are DST if our previous Sunday was on or after the 8th.
+boolean isDST( int mo, int dy, int dw ) {
+  if ( mo < 3 || mo > 11 ) {
+    return false;  // January, February, and December are out.
+  }
+  if ( mo > 3 && mo < 11 ) {
+    return true;  // April to October are in
+  }
+  int previousSunday = dy - dw;
+  if ( mo == 3 ) {
+    return previousSunday >= 8;  // In March, we are DST if our previous Sunday was on or after the 8th.
+  }
   return previousSunday <= 0; // In November we must be before the first Sunday to be DST. That means the previous Sunday must be before the 1st.
 }


Delete C_CDELEM-Industruino.ino

Delete C_CDELEM-Industruino.ino

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


Use runtime IQ inversion control in raw.ino

--- examples/raw/raw.ino
+++ examples/raw/raw.ino
@@ -1,5 +1,6 @@
 /*******************************************************************************
  * Copyright (c) 2015 Matthijs Kooijman
+ * Copyright (c) 2018 Terry Moore, MCCI Corporation
  *
  * Permission is hereby granted, free of charge, to anyone
  * obtaining a copy of this document and accompanying files,
@@ -16,10 +17,16 @@
 #include <hal/hal.h>
 #include <SPI.h>

-#if !defined(DISABLE_INVERT_IQ_ON_RX)
-#error This example requires DISABLE_INVERT_IQ_ON_RX to be set. Update \
-       config.h in the lmic library to set it.
-#endif
+// we formerly would check this configuration; but now there is a flag,
+// in the LMIC, LMIC.noRXIQinversion;
+// if we set that during init, we get the same effect.  If
+// DISABLE_INVERT_IQ_ON_RX is defined, it means that LMIC.noRXIQinversion is
+// treated as always set.
+//
+// #if !defined(DISABLE_INVERT_IQ_ON_RX)
+// #error This example requires DISABLE_INVERT_IQ_ON_RX to be set. Update \
+//        lmic_project_config.h in arduino-lmic/project_config to set it.
+// #endif

 // How often to send a packet. Note that this sketch bypasses the normal
 // LMIC duty cycle limiting, so when you change anything in this sketch
@@ -40,7 +47,8 @@

 // These callbacks are only used in over-the-air activation, so they are
 // left empty here (we cannot leave them out completely unless
-// DISABLE_JOIN is set in config.h, otherwise the linker will complain).
+// DISABLE_JOIN is set in arduino-lmoc/project_config/lmic_project_config.h,
+// otherwise the linker will complain).
 void os_getArtEui (u1_t* buf) { }
 void os_getDevEui (u1_t* buf) { }
 void os_getDevKey (u1_t* buf) { }
@@ -149,6 +157,9 @@
   // This sets CR 4/5, BW125 (except for DR_SF7B, which uses BW250)
   LMIC.rps = updr2rps(LMIC.datarate);

+  // disable RX IQ inversion
+  LMIC.noRXIQinversion = true;
+
   Serial.println("Started");
   Serial.flush();


added a switch case and delays for presets

--- src/main.ino
+++ src/main.ino
@@ -29,21 +29,39 @@
   switch (emg) {
     case 70:
       pinch();
+      break;
     case 81:
       thumbsUp();
+      break;
     case 60:
       middleFinger();
+      break;
+    default:
+      allfingers(0);
+      break;
   }
 }

 // FUNCTIONS //
+void allfingers(int pos) {
+  // get all fingers in same position.
+  // 0 for open hand, 180 for fully closed hand
+  m1.write(pos);
+  m2.write(pos);
+  m3.write(pos);
+  m4.write(pos);
+  m5.write(pos);
+  delay(100);
+}
+
 void pinch() {
   m1.write(90);
   m2.write(90);
   m3.write(180);
   m4.write(180);
   m5.write(180);
+  delay(100);
 }

 void thumbsUp() {
@@ -52,6 +70,7 @@
   m3.write(180);
   m4.write(180);
   m5.write(180);
+  delay(100);
 }

 void middleFinger() {
@@ -60,4 +79,5 @@
   m3.write(0);
   m4.write(180);
   m5.write(180);
+  delay(100);
 }


Version 3.1.5 - Fixes for temperature compensation

New version fixes temperature compensation bug.

--- OxFloodNet_Sensor/OxFloodNet_Sensor.ino
+++ OxFloodNet_Sensor/OxFloodNet_Sensor.ino
@@ -18,7 +18,7 @@
  * for next 10 minutes the sleep is every 1 minutes, after this sleep interval
  * becomes value set on jumpers (5, 10 or 15 mins)
  *
- * NOTE: For initial testing, wakeup time set to 5mins and battery interval to 4 cycles
+
  * (c) 2014 Andrew D Lindsay & Ben Ward
  */

@@ -26,8 +26,8 @@
 #include <OneWire.h>
 #include <DallasTemperature.h>

-// Used in START msg to indicate firmware version, 314 = 3.1.4
-#define VERSION_ID 314
+// Used in START msg to indicate firmware version, 315 = 3.1.5
+#define VERSION_ID 315

 // Set RFu hardware pins (not board jumpers)
 // Enable SRF
@@ -41,7 +41,9 @@
 // Using Sleep Mode 3, SLEEP must be LOW to run, uses interrupt to wakeup
 #define SRF_SLEEP 4
 #define WAKE_INT 2
+
 // Temperature sensor data line connects to pin 5 on the Arduino
+// OneWire bus pin for temperature sensor pin
 #define ONE_WIRE_BUS 5

 // Software configuration defines
@@ -72,6 +74,7 @@
 #define MED_POLL 1
 #define FAST_POLL 2

+// Counts for the startup polling modes
 #define FAST_POLL_COUNT 30
 #define MED_POLL_COUNT 10

@@ -80,15 +83,18 @@
 // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
 OneWire oneWire(ONE_WIRE_BUS);

-// Pass our oneWire reference to Dallas Temperature.
+// Pass our oneWire reference to Dallas Temperature library.
 DallasTemperature sensors(&oneWire);

 // arrays to hold device address
 DeviceAddress temperatureSensor;

-// Define pins that are not used and are to be made inputs
+// Define pins that are not used and are to be made inputs for power saving
+// TODO: Check usage of all pins
 #define PIN_COUNT 5
-uint8_t inPin[] = { 9, 10, 11, 12, 13 };
+
+uint8_t inPin[] = {
+  9, 10, 11, 12, 13 };

 // Other global variables
 boolean tempSensorFound = false;
@@ -98,17 +104,18 @@
 int startupCounter = FAST_POLL_COUNT;

 // Node ID, default 00, set by input pins
-// Stricly speaking this should only be digits, according to the Ciseco LLAP spec.
-char nodeId[2] = { '0', '0' };
-
-// Forward reference
-uint8_t enterCommandMode();
+// Strictly speaking this should only be digits, according to the Ciseco LLAP spec.
+// but since the spec is inefficient we've ignored the format.
+char nodeId[2] = {  '0', '0' };
+

 // Some functions to get the configured node address and polling
+/** readJumpers - determine node ID and polling interval for this sensor
+ */
 void readJumpers() {
   // Set analog input pins to read digital values, set internal pullup
   uint8_t jumperPins[] = {
-    A0, A1, A2, A3, A4, A5, 9, 10, 12, 13 };
+    A0, A1, A2, A3, A4, A5, 9, 10, 12, 13   };
   for( int n = 0; n < 10; n++ ) {
     pinMode( jumperPins[n], INPUT );
     digitalWrite( jumperPins[n], HIGH);
@@ -134,28 +141,17 @@
   for( int n = 0; n < 10; n++ ) {
     digitalWrite( jumperPins[n], LOW);
   }
-
-  // DEBUG to serial port on startup
-  // Print the values of Port B & Port C
-  Serial.println("Debug: ");
-  Serial.print("Port B: ");
-  Serial.println(PINB,HEX);
-  Serial.print("Port C: ");
-  Serial.println(PINC,HEX);
-
-  Serial.print("Polling Interval: ");
-  Serial.println(pollingInterval,DEC);
-
-  Serial.print("Node ID Digits: ");
-  Serial.print(digit1,DEC);
-  Serial.print(" ");
-  Serial.println(digit2,DEC);
-
-}
-
-// **************************************
+
+}
+
 // Functions used in processing readings
-// Sorting function (Author: Bill Gentles, Nov. 12, 2010)
+
+/* isort - Simple sort function for the set of readings
+ * Sorting function (Author: Bill Gentles, Nov. 12, 2010)
+ * The sorted array is returned in the original array
+ * @param a - Array of unsigned 16 bit values to sort
+ * @param n - Number of values in array
+ */
 void isort(uint16_t *a, int8_t n){
   for (int i = 1; i < n; ++i)  {
     uint16_t j = a[i];
@@ -167,7 +163,12 @@
   }
 }

-// Mode function, returning the mode or median.
+
+/** mode - Mode function, returning the mode or median.
+ * @param x - Array of unsigned 16 bit values to sort
+ * @param n - Number of values in array
+ * @return mode or median of the passed data.
+ */
 uint16_t mode(uint16_t *x,int n){
   int i = 0;
   int count = 0;
@@ -201,14 +202,19 @@
 }

 // Start of Ultrasonic sensor code
+
+/** getrange - Get the range in cm. Need to enable sensor first, waiting briefly for it to power up.
+ * Request temperature sensor, if previously detected, to take a reading.
+ * Disable ultrasonic sensor after use for power saving.
+ * Returns compensated, uncompensated and temperature values by reference.
+ * Calling function can still do checks to determine whether to use reading or not.
+ *
+ * @param outRawDistance - Raw uncompensated distance
+ * @param outDistance - Compensated distance if temperature available, otherwise raw distance
+ * @param outTemperature - Temperature reading
+ * @return boolean true returned form function for valid reading. false for <23cm or out of range
+ */
 boolean getRange( int *outRawDistance, int *outDistance, float *outTemperature ) {
-
-  // Get the range in cm. Need to enable sensor first then wait briefly for it to power up
-  // Also request temperture sensor, if previously detected, to take a reading.
-  // Disable sensor after use.
-  // Returns compensated, uncompensated and temperature values as reference params
-  // boolean true returned form function for valid reading. false for <23cm or out of range
-  // Calling function can still do checks to determine whether to use reading or not.

   int16_t pulse;  // number of pulses from sensor
   int i=0;
@@ -216,8 +222,9 @@
   // suggested by Maxbotix instead of a mathematical average
   int8_t arraysize = 9; // quantity of values to find the median (sample size). Needs to be an odd number
   //declare an array to store the samples. not necessary to zero the array values here, it just makes the code clearer
-  uint16_t rangevalue[] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0           };
+  //  uint16_t rangevalue[] = {
+  //    0, 0, 0, 0, 0, 0, 0, 0, 0 };
+  uint16_t pulsevalue[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0   };

   float temperature = 0.0;
   digitalWrite(SENSOR_ENABLE, HIGH);
@@ -226,27 +233,38 @@
   while( i < arraysize ) {
     pulse = pulseIn(SENSOR_PIN, HIGH);  // read in time for pin to transition
     if( pulse == 0 ) return 0;
-    rangevalue[i]=pulse/58;         // pulses to centimeters (use 147 for inches)
-    if( rangevalue[i] < 645 && rangevalue[i] >= 15 ) i++;  // ensure no values out of range
+    //    rangevalue[i]=pulse/58;         // pulses to centimeters (use 147 for inches)
+    pulsevalue[i]=pulse;              // raw pulses to centimeters (use 147 for inches)
+    //    if( rangevalue[i] < 645 && rangevalue[i] >= 15 ) i++;  // ensure no values out of range
+    if( pulsevalue[i] < 37410 && pulsevalue[i] >= 870 ) i++;  // ensure no values out of range
     delay(10);                      // wait between samples
   }

   // Turn off sensor as no longer needed
   digitalWrite(SENSOR_ENABLE, LOW);

-  isort(rangevalue,arraysize);        // sort samples
-  uint16_t distance = mode(rangevalue,arraysize);  // get median
-
-  *outRawDistance = distance;
+  //  isort(rangevalue,arraysize);        // sort samples
+  //  uint16_t distance = mode(rangevalue,arraysize);  // get median
+  isort(pulsevalue,arraysize);        // sort samples
+  uint16_t rawtof = mode(pulsevalue,arraysize);  // get median
+
+  //  *outRawDistance = distance;
+  *outRawDistance = rawtof/58;      // time of flight / 58uS for both there and back
   // Use temperature compensation if temp sensor found
   if( tempSensorFound ) {
     sensors.requestTemperatures();
     temperature = sensors.getTempCByIndex(0);
     *outTemperature = temperature;
-    float tof = distance * 0.0058;
-    uint16_t newDist = tof * (( 20.05 * sqrt( temperature + 273.15))/2);
+    //    float tof = distance * 0.58;
+    //    uint16_t newDist = tof * (( 20.05 * sqrt( temperature + 273.15))/200);
+    uint16_t newDist = (rawtof * (331.3 + 0.606 * temperature)) / 20000;
+
     *outDistance = newDist;
-  }
+  } else {
+    // No temperature sensor, just return same distance for both
+    *outDistance = rawtof/58;
+  }
+
   // Add check for validity of reading
   if( *outRawDistance <= 23 ) {    // 23cm seems to be the minimum value
     return false;
@@ -254,19 +272,25 @@

   return true;
 }
+
+
 // End of ultrasonic sensor code
-
+// **************************************

 // Battery monitoring
+
+/** readVcc - Read the current battery voltage
+ * @return Vcc in millivolts
+ */
 int readVcc() {
   // Read 1.1V reference against AVcc
   // set the reference to Vcc and the measurement to the internal 1.1V reference
 #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
-  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
+//  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
 #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
-  ADMUX = _BV(MUX5) | _BV(MUX0);
+//  ADMUX = _BV(MUX5) | _BV(MUX0);
 #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
-  ADMUX = _BV(MUX3) | _BV(MUX2);
+//  ADMUX = _BV(MUX3) | _BV(MUX2);
 #else
   ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
 #endif
@@ -285,15 +309,20 @@
 }
 // end of battery monitoring code

+
+
+
 // Start of SRF Sleep Code
-uint8_t setSRFSleep( int inPolling ) {
-
-/*
- Set the sleep mode on the SRF, this requires AT commands to set sleep interval
- This is not written to permanent store as this resets back to no sleep on power cycle.
- */
-
-  //  int selectedPollingInterval = TENMINS;    // Set a default
+/** setSRFSleep - Set the sleep mode on the SRF, this requires AT commands to set sleep interval
+ * This is not written to permanent store as this resets back to no sleep on power cycle.
+ * Set sleep based on current startup sequence and polling interval
+ * @param inPolling - The Polling parameter
+ * @return success code, 5 for success, other values indicate where failure occured
+ */
+
+
+uint8_t setSRFSleep( int inPolling )
+{
   if (!enterCommandMode())	// if failed once then try again
   {
     if (!enterCommandMode())
@@ -303,14 +332,20 @@

   // setup the selected polling interval
   if (!sendCommand( pollingIntervalCmds[inPolling]) ) return 2;
-  //  if (!sendCommand( pollingIntervalCmds[selectedPollingInterval]) ) return 2;
+
   if (!sendCommand("ATSM3")) return 3;
   if (!sendCommand("ATDN")) return 4;
   return 5; // success
 }
+
 // end of SRF sleep code

 // Start of SRF command functions
+
+/** enterCommandMode - Enter command mode on the SRF radio module. From here
+ * AT commands can be sent to reconfigure it.
+ * @return status to indicate if the SRF is in command mode now
+ */
 uint8_t enterCommandMode()
 {
   delay(1200);
@@ -321,6 +356,10 @@
   return checkOK(500);
 }

+/** sendCommand - Send the AT command to the SRD module.
+ * @param lpszCommand - Char pointer to the command string
+ * @return status to indicate command was sent.
+ */
 uint8_t sendCommand(char* lpszCommand)
 {
   Serial.print(lpszCommand);
@@ -328,6 +367,11 @@
   return checkOK(100);
 }

+/** checkOK - wait a specified time for the OK prompt to be returned after sending a
+ * command to the SRF module.
+ * @param  timeout - The timeout in milliseconds to wait before giving up
+ * @return 1 for successfully seen the OK, 0 for timeout
+ */
 uint8_t checkOK(uint32_t timeout)
 {
   uint32_t time = millis();
@@ -345,8 +389,11 @@
 }
 // End of SRF command functions

+/** setup - Regular Arduino setup function.
+ * We setup the I/O pins, read jumpers and start the sensor
+ */
 void setup() {
-  // initialise serial interface for debugging/SRF communication:
+  // initialise serial interface for SRF communication:
   Serial.begin(115200);

   // Get device ID
@@ -354,9 +401,10 @@

   // Initialise the LLAPSerial library
   LLAP.init( nodeId );
+  // ?
+  analogReference(DEFAULT);

   // Set unused digital pins to input and turn on pull-up resistor
-  analogReference(DEFAULT);
   for(int i = 0; i< PIN_COUNT; i++ ) {
     pinMode(inPin[i], INPUT);
     digitalWrite(inPin[i], HIGH);
@@ -375,11 +423,11 @@

   // start OneWire sensors
   sensors.begin();
-  tempSensorFound = false; //clear flag for sensor discovery
+  tempSensorFound = false;				//clear flag for sensor discovery
   // Discover OneWire temperature sensor
   if (sensors.getAddress(temperatureSensor, 0)) {
-    // If we find a sensor set the resolution to 9 bit
-    // (Each Dallas/Maxim device is capable of several different resolutions)
+    // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
+
     sensors.setResolution(temperatureSensor, 9);
     tempSensorFound = true; // set discovery flag
   }
@@ -396,8 +444,9 @@
     LLAP.sendInt("ERR",val); // Diagnostic
     delay(5000);	// try again in 5 seconds
   }
-
-  // Send START message + Version ID 5 times
+
+
+  // Send "START" message and Firmware version 5 times
   for(int i = 0; i<5; i++) {
     LLAP.sendInt("START", VERSION_ID);
     // TODO: Wait 100mS for ACK, if received continue, otherwise send next STARTED
@@ -405,42 +454,52 @@
   }
 }

-// The main loop, we basically wake up the SRF, take a reading, transmit reading then go back to sleep
+/** loop - where the sensor code runs.
+ * we wake up the SRF, take a reading, transmit reading then go back to sleep
+ */
 void loop() {
   float temperature = 0.0;
   int rawDistance = 0;
   int distance = 0;

-  // Determine if we need to send a battery voltage reading yet
+  // Determine if we need to send a battery voltage reading or a distance reading
   if( --batteryCountDown <= 0 ) {
     int mV = readVcc();
     LLAP.sendIntWithDP("B", mV, 3 );
     batteryCountDown = BATTERY_READ_INTERVAL;
+    delay(20);
   }

-    // Distance reading
-    boolean rangeValid = getRange( &rawDistance, &distance, &temperature);
-    // Send temperature reading
-    if( tempSensorFound ) {
-      int latestTemp = (int)(temperature * 100);
-      LLAP.sendIntWithDP( "T", latestTemp, 2);
-    }
-    // Uncompensated distance
-    LLAP.sendInt( "U", rawDistance);
-    // Send reading 3 times to make sure it gets through
-    //    for(int n = 0; n<1; n++ ) {
-
-    if( rangeValid ) {
-      //if( rawDistance > 23 )     // 23cm seems to be the minimum value
-      LLAP.sendInt( "D", distance );
-    } else {
-      if( rawDistance == 0 ) {
-        LLAP.sendMessage( "UMax" );
-      } else {
-        LLAP.sendMessage( "UErr" );
-      }
-    }
+  // Distance reading
+  boolean rangeValid = getRange( &rawDistance, &distance, &temperature);
+  // Send temperature reading
+  if( tempSensorFound ) {
+    int latestTemp = (int)(temperature * 100);
+    LLAP.sendIntWithDP( "T", latestTemp, 2);
+
+    delay(20);
+  }
+  // Uncompensated distance
+  LLAP.sendInt( "U", rawDistance);
+  delay(20);

+  // TODO: Send reading 3 times to make sure it gets through
+
+
+  if( rangeValid ) {
+    //if( rawDistance > 23 ) {    // 23cm seems to be the minimum value
+    LLAP.sendInt( "D", distance );
+  }
+  else {
+    if( rawDistance == 0 ) {
+      LLAP.sendMessage( "UMax" );
+    }
+    else {
+      LLAP.sendMessage( "UErr" );
+
+    }
+
+  }

   // Determine if we are still in startup sequence, if so, do we need to
   // adjust polling interval.
@@ -452,10 +511,11 @@
       int selectedPollingInterval = TENMINS;
       // Setup for next polling sequence
       switch( startupSequence ) {
-// removed as would never use this code
-//      case FAST_POLL:
-//        selectedPollingInterval = TWENTYSEC;
-//        break;
+        // removed as we would never use this code
+
+        //      case FAST_POLL:
+        //        selectedPollingInterval = TWENTYSEC;
+        //        break;
       case MED_POLL:
         selectedPollingInterval = ONEMIN;
         startupCounter = MED_POLL_COUNT;


Changes

Changes

--- acelaso.ino/acelaso.ino.ino
+++ acelaso.ino/acelaso.ino.ino
@@ -1,3 +1,5 @@
+
+

 #include <SI114.h>
 #include <Si114_defs.h>
@@ -43,7 +45,7 @@
     while (1);
   }

-  //Check
+  //Check to ensure that FRAM device is found
   if (fram.begin()) {  // you can stick the new i2c addr in here, e.g. begin(0x51);
     Serial.println("Found I2C FRAM");
   } else {


modify comments

modify comments

--- arduino/control_power/control_power.ino
+++ arduino/control_power/control_power.ino
@@ -96,20 +96,20 @@
       break;
     case RPI_STAT_BOOT:
       Serial.println("ignore");
-      //起動中はボタンおしても無反応
+      //button is ignored when it's booting
       break;
     case RPI_STAT_RUNNING:
-      //動作中にボタン押すとシャットダウンシーケンススタート
+      //shutdown will start when it's running
       Serial.println("start shutdown process");
       digitalWrite(pin_shutdown,LOW);
       raspi_stat = RPI_STAT_WAIT_SHUTDOWN;
       break;
     case RPI_STAT_WAIT_SHUTDOWN:
-      //シャットダウン中破はボタンおしても無反応
+      //button is ignored when it's shutting down
       Serial.println("ignore");
       break;
     case RPI_STAT_UNKNOWN:
-      //異常状態になったら、長押しで電源OFF
+      //power can be off by long press when status is UNKNOWN
       if(press_duration > 20*3){ //3sec (50*20*3 msec)
         Serial.println("*** Emergency turn off ***");
         turn_off();
@@ -131,13 +131,13 @@

   switch(raspi_stat){
     case RPI_STAT_SHUTDOWN:
-      //何もしない
+      //do nothing
       timeout_counter1=0;
       timeout_counter2=0;
       break;
     case RPI_STAT_BOOT:
-      //RasPiのGPIOの監視
-      //GPIOがLOWに落とされたら > 監視スクリプトが起動した
+      //Check RasPi's GPIO
+      //GPIO is LOW: "shutdown_checker.py" gets started
       timeout_counter1++;
       if(timeout_counter1 > 20*60*2 ){//50*20 * 60 * 2 (2min)
         Serial.println("*** BOOT error ***");
@@ -174,12 +174,12 @@
           int stat = digitalRead(pin_rpistat);
           //Serial.println(stat);
           if(stat == 1){
-            shtdwn_delay_count=1; // 電源OFFまでのカウントアップスタート
+            shtdwn_delay_count=1; // start couting up until power off
             Serial.println("start TURN OFF power count down");
             digitalWrite(pin_shutdown,HIGH);
           }
         }else{
-          if(shtdwn_delay_count>20*50){ //50*20 * 50 msec (70sec)
+          if(shtdwn_delay_count>20*50){ //50*20 * 50 msec (50sec)
             raspi_stat = RPI_STAT_SHUTDOWN;
             Serial.println("*** TURN OFF power successfully ***");
             turn_off();
@@ -189,7 +189,7 @@
       }
       break;
     case RPI_STAT_UNKNOWN:
-      //何もしない
+      //do nothing
       break;
    }
 }
@@ -200,7 +200,7 @@
 void loop() {
   static int press_duration=0;
   static int loop_count = 0;
-  static int button_stat = 1; // 0:押している状態 1:離している状態
+  static int button_stat = 1; // 0:pressed 1:not pressed

   delay(50);
   loop_count++;


IRSeeker tweaks to make it move more smoothly

--- software/firmware/LogoBotIRSeeker/LogoBotIRSeeker.ino
+++ software/firmware/LogoBotIRSeeker/LogoBotIRSeeker.ino
@@ -3,13 +3,22 @@
 #include <Bot.h>
 #include <Servo.h>

-#define SCAN_SPEED 25
-int lookAng = 90; // 0 -> right, 180 -> left, 90 -> straight ahead
-int scanDir = 1;
-long lastScanMove = 0;
+enum Activity
+{
+  Idle,
+  Seek,
+  Turn,
+  Advance,
+  Retreat
+};

-#define DIST_CLOSE 140
-#define DIST_TOO_CLOSE 70
+#define SCAN_SPEED 25 // speed eyes turn, lower is faster.  (delay in ms between moves)
+#define DIST_CLOSE 140 // distance in mm for an object to warrant investigation
+#define DIST_TOO_CLOSE 70 // distance in mm that bot is too close and should back off
+static int lookAng = 90; // current angle bot is looking 0 -> right, 180 -> left, 90 -> straight ahead
+static int scanDir = 1; // direction we are panning the servo in - 1 or -1.
+static long lastScanMove = 0; // last time we moved the servo
+static Activity action = Idle; // current activity the bot is doing

 Bot bot(MOTOR_L_PIN_1, MOTOR_L_PIN_2, MOTOR_L_PIN_3, MOTOR_L_PIN_4, MOTOR_R_PIN_1, MOTOR_R_PIN_2, MOTOR_R_PIN_3, MOTOR_R_PIN_4);
 Servo lidServo;
@@ -45,34 +54,63 @@
       if (dist < DIST_CLOSE) {
         // object close, turn to face or drive towards if already facing
         if (lookAng < 90) {
-          setLEDColour(0, 1, 0);
+          action = Turn;
           bot.turn(-1);
           lookAng += 1;
+
         } else if (lookAng > 90) {
-          setLEDColour(0, 1, 0);
+          action = Turn;
           bot.turn(1);
           lookAng -= 1;
-        } else if (lookAng == 90 && !bot.isBusy()) {
+
+        } else if (lookAng == 90) {
+          // bot is facing the object
           if (dist < DIST_TOO_CLOSE) {
             // too close!  back off
-            setLEDColour(1, 0, 0);
-            bot.buzz(40);
+            if (action != Retreat) bot.stop();
+            action = Retreat;
+            bot.buzz(10);
             bot.drive(-10);
+
           } else {
-            setLEDColour(0, 1, 0);
             // head for object
+            if (action != Advance) bot.stop();
+            action = Advance;
             bot.drive(10);
           }
         }
       } else {
         // keep scanning for objects
-        setLEDColour(0, 0, 1); // blue, seeking
+        if (action != Seek) bot.stop();
+        action = Seek;
         lookAng += scanDir;
+
+        // switch scan direction if end of servo travel reached
         if (lookAng > 180) scanDir = -1;
         if (lookAng < 0) scanDir = 1;
       }
-      lookAt(lookAng);
+
       lastScanMove = millis() + SCAN_SPEED;
+    }
+
+    // Update Servo position
+    lookAt(lookAng);
+
+    // Update LED
+    switch(action) {
+      case Idle:
+        setLEDColour(0, 0, 0);
+        break;
+      case Seek:
+        setLEDColour(0, 0, 1);
+        break;
+      case Turn:
+      case Advance:
+        setLEDColour(0, 1, 0);
+        break;
+      case Retreat:
+        setLEDColour(1, 0, 0);
+        break;
     }
 }

@@ -86,7 +124,8 @@
 {
     if (collisionData != 0) {
         // Just hit something, so stop, buzz and backoff
-        setLEDColour(1,0,0);  // Red, because we hit something
+        action = Retreat;
+        lastScanMove += 2000;
         Serial.println("Ouch!");
         bot.emergencyStop();
         bot.buzz(250);


Added lcd bitbang setup

Added lcd bitbang setup


fix for Arduino 1.0

fix for Arduino 1.0

--- examples/Ports/bmp085demo/bmp085demo.ino
+++ examples/Ports/bmp085demo/bmp085demo.ino
@@ -104,6 +104,7 @@
     Serial.print(payload.temp);
     Serial.print(' ');
     Serial.print(payload.pres);
+    Serial.flush();

     rf12_sleep(RF12_WAKEUP);         // turn radio back on at the last moment


changed command  letter size

changed command  letter size


compiles now on Teensy and UNO

compiles now on Teensy and UNO

--- IcomTest/IcomTest.ino
+++ IcomTest/IcomTest.ino
@@ -20,6 +20,7 @@
 #include <CATutil.h>
 #include <IcomCAT.h>

+#if defined (__AVR__)
 /**
  * From SoftwareSerialExample:

@@ -35,13 +36,18 @@
 */
 #include <SoftwareSerial.h>

-SoftwareSerial Serial1(10, 11); // RX, TX
-
-
-IcomCAT Icom706(Serial1,IC706MK2G_ADDR);
+SoftwareSerial rxSerial(10, 11); // RX, TX for the RX
+#else
+ // use RX1,TX1 on the Teensy 3.1/3.2 board
+ #define rxSerial  Serial1;
+#endif // (__AVR__)
+
+IcomCAT Icom706(rxSerial,IC706MK2G_ADDR);

 // local prototypes
+#if defined (__AVR__)
 static int availableMemory();
+#endif // (__AVR__)

 // code for setup and initialisation
 void setup() {
@@ -51,13 +57,15 @@
   Serial.begin(UART_BAUD_RATE);
   Serial << F("CATtransv: starting ...") << endl;

+ #if defined (__AVR__)
   Serial << F("Free SRAM: ");
   Serial.println(availableMemory());
+ #endif // (__AVR__)
 #endif // DEBUG

   // set the data rate for the SoftwareSerial port(s)
-  Serial1.begin(9600);
-  //Serial2.begin(9600);
+  rxSerial.begin(9600);
+  //txSerial.begin(9600);
 }

 /** Return true if the frequency is in the desired range. */
@@ -174,10 +182,10 @@
     default: ;
   }

-  Serial1.listen();
+  rxSerial.listen();

   // check if 'Serial1' has data to receive
-  if (Serial1.available()) {
+  if (rxSerial.available()) {

     Icom706.read();

@@ -185,7 +193,7 @@
       Icom706.parseMessage();
     }

-  } // Serial1.available()
+  } // rxSerial.available()

   // check if 'Serial2' has data to receive
   // ...
@@ -206,6 +214,7 @@
 /**
  * Try to inquire max. available memory by allocating until heap is exhausted.
  */
+#if defined (__AVR__)
 static int availableMemory() {

 #if 0
@@ -224,3 +233,9 @@
   return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
 #endif
 }
+#endif // (__AVR__)
+
+// code snippet for XXX specific code fragment
+#if defined(CORE_TEENSY) || defined(__AVR__) || defined(__ARM__)
+// ...
+#endif


edited mearm .ino

edited mearm .ino

--- MeArm/MeArm/MeArm.ino
+++ MeArm/MeArm/MeArm.ino
@@ -8,9 +8,9 @@
 Servo rot;

 const int griperControlPin = 3;  // pint for grip from joystick
-const int xPosControlPin = 0;  // pint for grip from joystick
-const int rotationControlPin = 1;  // pint for grip from joystick
-const int yPosControlPin = 2;  // pint for grip from joystick
+//const int xPosControlPin = 0;  // pint for grip from joystick
+//const int rotationControlPin = 1;  // pint for grip from joystick
+//const int yPosControlPin = 2;  // pint for grip from joystick

 const int leftVRx = 2;   // yellow
 const int leftVRy = 3;   // white


Disabled MQTT

Disabled MQTT

--- Receiver/rx_monitor/rx_monitor.ino
+++ Receiver/rx_monitor/rx_monitor.ino
@@ -194,7 +194,7 @@
     ping_last = currentMillis;
     udpBroadcast();
     websocketBroadcast();
-    mqttBroadcast();
+    //mqttBroadcast();
     serialPrintPayload();

     current_payload = 0;
@@ -238,6 +238,7 @@

     // No display when dark.
     int ldr = analogRead(A0);
+    //Serial.print("LDR: "); Serial.println(ldr);
     if (display_status == 1 && ldr < 10) {
       display_status = 0;
     } else if (display_status == 0 && ldr > 20) {
@@ -312,6 +313,7 @@
  * Send the signal data.
  */
 void websocketBroadcastSignal() {
+  String str;
   str = "{\"signal\":{";
   str += "\"msg_type\":" + String(signal_payload.getMsgType()) + ",";
   str += "\"msg_id\":" + String(signal_payload.getMsgId()) + ",";
@@ -326,6 +328,7 @@
  * Send the garden data as json
  */
 void websocketBroadcastGarden() {
+  String str;
   str = "{\"garden\":{";
   str += "\"msg_type\":" + String(rx_payload.getMsgType()) + ", ";
   str += "\"msg_id\":" + String(rx_payload.getMsgId()) + ",";
@@ -340,7 +343,6 @@
 }

 void websocketBroadcast() {
-  String str;
   switch (current_payload) {
     case theapi::Payload::SIGNAL:
       websocketBroadcastSignal();


Improved turn sensor computation & added calibration; add 7 segment displays; made E-stop happen at interrupt level; better integration of data for PID.

--- Elcano_C2_LowLevel/Elcano_C2_LowLevel.ino
+++ Elcano_C2_LowLevel/Elcano_C2_LowLevel.ino
@@ -1,6 +1,13 @@

 #include <SPI.h>
 #include <Elcano_Serial.h>
+
+#include <SoftwareSerial.h>
+// On Mega, TX must use d10-15, d50-53, or a8-a15 (62-69)
+const int softwareTx = 10;  // to 7 segment LED display
+const int softwareRx = 7;   // not used
+SoftwareSerial s7s(softwareRx, softwareTx);
+
 #define LOOP_TIME_MS 400
 #define ERROR_HISTORY 20

@@ -8,6 +15,7 @@
 //#define VEHICLE_NUMBER 1
 //#define RC_SPEKTRUM
 //#undef  RC_HITEC
+
 // Yellow Trike
 #define VEHICLE_NUMBER 2
 #undef RC_SPEKTRUM
@@ -22,28 +30,14 @@
 #define RIGHT_TURN_OUT 146
 #define LEFT_TURN_OUT 230
 #define STRAIGHT_TURN_OUT 180
-#define DAC_CHANNEL 0
+// Turn sensors are believed if they are in this range while wheels are straight
+#define RIGHT_MIN_COUNT 80
+#define RIGHT_MAX_COUNT 284
+#define LEFT_MIN_COUNT  80
+#define LEFT_MAX_COUNT  284
+#define DAC_CHANNEL 0    // output to motor actuator
 #define STEER_OUT_PIN 7 // Output to steer actuator
 #define BRAKE_OUT_PIN 6  // output to brake actuator
-
-/*================ReadTurnAngle 1================*/
-// Value measured at analog input A3 from right steering column when wheels pointed straight ahead.
-// An analog voltage can be 0 to 5V, which correspond to angles from 0 to 360 degrees.
-// Analog input reads this as a value form 0 to 1024.
-// We may want to mount the sensors so that straight is close to 500.
-// This number is not critical, since actual wheel turn range is much less than 360
-#define RIGHT_STRAIGHT_A3 181
-// Value measured at analog input A2 from left steering column when wheels pointed straight ahead.
-#define LEFT_STRAIGHT_A2  181
-// Calibration constants
-// Aangle (degrees) = (Value - RIGHT_STRAIGHT_A3) * RIGHT_DEGx1000pCOUNT / 1000
-#define RIGHT_DEGx1000pCOUNT  3333
-#define LEFT_DEGx1000pCOUNT  3333
-// A correct sensor will produce a reading between these values
-#define RIGHT_MIN_COUNT  80
-#define RIGHT_MAX_COUNT 284
-#define LEFT_MIN_COUNT   80
-#define LEFT_MAX_COUNT  284

 #endif

@@ -57,23 +51,35 @@
 #define RIGHT_TURN_OUT 146 // Original value 146
 #define LEFT_TURN_OUT 223 // Original value 230
 #define STRAIGHT_TURN_OUT 182 // Original value 187
-
+// Turn sensors are believed if they are in this range while wheels are straight
+#define RIGHT_MIN_COUNT 725
+#define RIGHT_MAX_COUNT 785
+#define LEFT_MIN_COUNT  880
+#define LEFT_MAX_COUNT  940
 #define DAC_CHANNEL 3
 #define STEER_OUT_PIN 7 // Output to steer actuator
 #define BRAKE_OUT_PIN 9  // output to brake actuator

-/*================ReadTurnAngle 2================*/
-#define RIGHT_STRAIGHT_A3 515 // Original value 181
-#define LEFT_STRAIGHT_A2  522 // Original value 181
+#endif
+
+/*================ReadTurnAngle ================*/
+// Value measured at analog input A3 from right steering column when wheels pointed straight ahead.
+// An analog voltage can be 0 to 5V, which correspond to angles from 0 to 360 degrees.
+// Analog input reads this as a value form 0 to 1024.
+// We may want to mount the sensors so that straight is close to 500.
+// This number is not critical, since actual wheel turn range is much less than 360
+int RightStraight_A3 = 914; // Original value 181
+// Value measured at analog input A2 from left steering column when wheels pointed straight ahead.
+int LeftStraight_A2  = 750; // Original value 181
+// Calibration constants
+// Aangle (degrees) = (Value - RightStraight_A3) * RIGHT_DEGx1000pCOUNT / 1000
 #define RIGHT_DEGx1000pCOUNT  3333
 #define LEFT_DEGx1000pCOUNT  3333
-#define RIGHT_MIN_COUNT 466 // Original value 80
-#define RIGHT_MAX_COUNT 557 // Original value 284
-#define LEFT_MIN_COUNT 465  // Original value 80
-#define LEFT_MAX_COUNT 559  // Original value 284
-
-#endif
-// End new section
+// A correct sensor will produce a reading between these values
+int Right_Min_Count = 850; // Real values are in setup().
+int Right_Max_Count = 980;
+int Left_Min_Count = 698;
+int Left_Max_Count = 808;

 // Channel order differs for differernt vehicles
 // Indices for information stored in arrays RC_rise, RC_elapsed, local_results,...
@@ -97,23 +103,12 @@
 #define ProcessFallOfINT(Index)  RC_elapsed[Index]=(micros()-RC_rise[Index])
 #define ProcessRiseOfINT(Index) RC_rise[Index]=micros()

-// TO DO: Throttle and brake values should be in a header file and depend on vehicle number.
-// Values to send over DAC
-const int FullThrottle =  227;   // 3.63 V
-const int MinimumThrottle = 70;  // Throttle has no effect until 1.2 V
-// Values to send on PWM to get response of actuators
-const int FullBrake = 167;  // start with a conservative value; could go as high as 255;
-const int NoBrake = 207; // start with a conservative value; could go as low as 127;
-
 //RC input values - pulse widths in microseconds
-const int LONG_DEADZONE_THRESHOLD = 10000; // used for syncing to determine if the last down time was the long down zone
 const int DEAD_ZONE = 75;
 const int MIDDLE = 1500;  // was 1322; new stable value = 1510
 // extremes of RC pulse width
 const int MIN_RC = 1090;  // was 911;
 const int MAX_RC = 1930; // was 1730;
-const int CYCLE_MAX = 25000;  // Pulses come at 42.27 Hz, every 21155 us
-const int MAX_PULSE = 4000; // Next pulse should be no longer than this time from last.

 const int SelectCD = 49; // Select IC 3 DAC (channels C and D)
 const int SelectAB = 53; // Select IC 2 DAC (channels A and B)
@@ -145,19 +140,16 @@
 #endif
 //  D3 = Int 1  Wheel Click

-// globals
-long sensor_speed_mmPs = 0;
-long drive_speed_mmPs = 0;
-char IncomingMessage[BUFFER_SIZE];
-int  InIndex=0;
-int  throttle_control = MinimumThrottle;
-int  brake_control = FullBrake;
-// int  steer_control = Straight;
 long speed_errors[ERROR_HISTORY];
-/*================Read Turn Angle=================*/
-long old_turn_degx1000, older_turn_degx1000;
-long expected_turn_degx1000;
-
+long old_turn_degx1000;
+unsigned long calibrationTime_ms;
+unsigned long stoppedTime_ms;
+unsigned long straightTime_ms;
+int  throttle_control = MIN_ACC_OUT;
+int  brake_control = MAX_BRAKE_OUT;
+int  steer_control = STRAIGHT_TURN_OUT;
+
+//==========================================================================================
 void ISR_TURN_rise() {
   noInterrupts();
   ProcessRiseOfINT(RC_TURN);
@@ -220,6 +212,8 @@
   noInterrupts();
   ProcessFallOfINT(RC_ESTP);
   RC_Done[RC_ESTP] = 1;
+  if (RC_elapsed[RC_ESTP] > MIDDLE)
+      E_Stop();
   attachInterrupt(IRPT_ESTOP, ISR_ESTOP_rise, RISING);
   interrupts();
 }
@@ -231,15 +225,7 @@
   attachInterrupt(IRPT_RVS, ISR_RVS_rise, RISING);
   interrupts();
 }
-
-void initialize()
-{
-  for (int i = 0; i < ERROR_HISTORY; i++)
-  {
-      speed_errors[i] = 0;
-  }
-
-}
+//----------------------------------------------------------------------------
 void setup()
 { //Set up pins
       pinMode(BRAKE_OUT_PIN, OUTPUT);
@@ -256,6 +242,13 @@
       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++)
@@ -263,28 +256,28 @@
           RC_rise[i] = INVALID_DATA;
           RC_elapsed[i] = INVALID_DATA;
       }
-      initialize();
-
+      for (int i = 0; i < ERROR_HISTORY; i++)
+      {
+          speed_errors[i] = 0;
+      }
       setupWheelRev(); // WheelRev4 addition
-
-    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);
-
-    old_turn_degx1000 = older_turn_degx1000 = expected_turn_degx1000 = 0; // ReadTurnAngle addition
-    Print7headers(false);
-}
-
-unsigned long nextTime = micros();
+      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);
+      Print7headers(false);
+}
+
 void loop() {
     SerialData Results;

     // Save start time for performance report.
     unsigned long startTime = micros();
     // Get the next loop start time.
-    unsigned long nextTime = nextTime + LOOP_TIME_MS;
+    unsigned long nextTime = startTime + LOOP_TIME_MS;

     startCapturingRCState();

@@ -313,7 +306,19 @@
     //Serial.print("loop elapsed time = ");
     //Serial.println(elapsedTime);

-//    LogData(local_results, &Results);  // data for spreadsheet
+    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?
@@ -322,7 +327,7 @@
         delay(nextTime - endTime);
     } else {
         // Yes, we overran the expected loop interval. Extend the time.
-        nextTime = endTime + LOOP_TIME_MS;
+        nextTime = endTime + 1000 * LOOP_TIME_MS;
     }
 }
 void PrintDone()
@@ -375,6 +380,10 @@
      Serial.print(sensors->speed_cmPs); Serial.print("\t");
      Serial.print(sensors->speed_cmPs*36.0/1000.); Serial.print("\t"); // km/hr
      Serial.print(sensors->angle_deg); Serial.print("\t");
+     int right = analogRead(A2);
+     int left = analogRead(A3);
+     Serial.print(right); Serial.print("\t");
+     Serial.print(left); Serial.print("\t");
      Print7 (true, commands);
 }

@@ -406,7 +415,7 @@

     if (results[RC_ESTP] == HIGH)
     {
-        E_Stop();
+        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.");
@@ -537,6 +546,7 @@
 {
       analogWrite(STEER_OUT_PIN, pos);
 //      Serial.print("\tSteering to: \t"); Serial.print(pos);
+     steer_control = pos;
 }
 void convertBrake(long unsigned *amount)
 {
@@ -550,6 +560,7 @@
 {
       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.
@@ -622,6 +633,7 @@
       255 counts = 4.08 V
       */
       DAC_Write(DAC_CHANNEL, acc);
+      throttle_control = acc;    // post most recent throttle.
 }

 /*========================================================================/
@@ -764,7 +776,7 @@
     SerialMonitor.print(" OldTick: ");
     SerialMonitor.println(OldTick);

-    SerialMonitor.println("setup complete");
+    SerialMonitor.println("WheelRev setup complete");

 }
 /*---------------------------------------------------------------------------------------*/
@@ -878,25 +890,70 @@
    interrupts();

    ComputeSpeed (&history);
-   PrintSpeed(&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
-
-    // Show on monitor
-/*  SerialMonitor.print(" SENSOR ");
-    SerialMonitor.print("{Speed ");
-    SerialMonitor.print(SpeedCyclometer_revPs);
-    SerialMonitor.println("}\0");
- */
-}
-
+
+    show7seg( SpeedCyclometer_mmPs);   // Show speed on 7 segment LEDs
+
+}
+/*========================CalibrateTurnAngle======================*/
+/*  This routine should only be called when
+          - 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.
+*/
+void CalibrateTurnAngle(int count, int pause)
+{
+    int totalRight = 0;
+    int totalLeft = 0;
+    int i, left, right;
+    for (i = 0; i < count; i++)
+    {
+          totalRight += analogRead(A3);
+          totalLeft += analogRead(A2);
+          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_A3 = right;
+         Right_Min_Count = RightStraight_A3 - 60;   // 60 counts is 20 degrees
+         Right_Max_Count = RightStraight_A3 + 60;
+     }
+    else
+    {
+         RightStraight_A3 = (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_A2  = left;
+        Left_Min_Count  = LeftStraight_A2  - 60;
+        Left_Max_Count  = LeftStraight_A2  + 60;
+    }
+    else
+    {
+        LeftStraight_A2  = (LEFT_MAX_COUNT - LEFT_MIN_COUNT)/2 ;
+        Left_Min_Count = LEFT_MIN_COUNT;
+        Left_Max_Count = LEFT_MAX_COUNT;
+    }
+
+    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;
@@ -905,14 +962,14 @@
     int left = analogRead(A2);
     //Serial.print("Left"); Serial.print("\t"); Serial.println(left);
     //Serial.print("Right"); Serial.print("\t"); Serial.println(right);
-    if ((RIGHT_MIN_COUNT <= right) && (right <= RIGHT_MAX_COUNT))
+    if ((Right_Min_Count <= right) && (right <= Right_Max_Count))
        OK_right = true;
-    if ((LEFT_MIN_COUNT <= left) && (left <= LEFT_MAX_COUNT))
+    if ((Left_Min_Count <= left) && (left <= Left_Max_Count))
        OK_left = true;
-    long right_degx1000 = (right - RIGHT_STRAIGHT_A3) * RIGHT_DEGx1000pCOUNT;
-    long left_degx1000  = (left -  LEFT_STRAIGHT_A2) *  LEFT_DEGx1000pCOUNT;
+    long right_degx1000 = (right - RightStraight_A3) * RIGHT_DEGx1000pCOUNT;
+    long left_degx1000  = (left -  LeftStraight_A2) *  LEFT_DEGx1000pCOUNT;

-    expected_turn_degx1000 = 2 * old_turn_degx1000 - (older_turn_degx1000);
+    expected_turn_degx1000 = old_turn_degx1000;
     if (OK_left && OK_right)
     {  // use the median
         if (right_degx1000 < left_degx1000)
@@ -929,23 +986,22 @@
             new_turn_degx1000 = min_ang;
         else if (expected_turn_degx1000 > max_ang)
             new_turn_degx1000 = max_ang;
-        else  // TO DO; limit this value to keep it bounded when both sensors fail
+        else
             new_turn_degx1000 = expected_turn_degx1000;
     }
     else if (OK_left)
     {
-        new_turn_degx1000 = left_degx1000;
+        new_turn_degx1000 = (left_degx1000 + expected_turn_degx1000)/2;
     }
     else if (OK_right)
     {
-        new_turn_degx1000 = right_degx1000;
+        new_turn_degx1000 = (right_degx1000 + expected_turn_degx1000)/2;
     }
     else
-    {
-        new_turn_degx1000 = expected_turn_degx1000;
+    {   // No sensors; use last valid measurement
+        new_turn_degx1000 = old_turn_degx1000;
     }
     new_turn_degx10 = (int) (new_turn_degx1000 / 100);
-    older_turn_degx1000 = old_turn_degx1000;
     old_turn_degx1000 = new_turn_degx1000;
     return new_turn_degx10;
 }
@@ -967,7 +1023,8 @@
    VanDoren Proportional Integral Derivative Control
 */
 {
-  static long speed_errors[ERROR_HISTORY];
+  static int  throttle_control = MIN_ACC_OUT;
+  static int  brake_control = MAX_BRAKE_OUT;
   static int error_index = 0;
   int i;
   static long error_sum = 0;
@@ -994,44 +1051,118 @@
             + D_tune * extrapolated_error;
   if (PID_error > speed_tolerance_mmPs)
   {  // too fast
-    long throttle_decrease = (FullThrottle - MinimumThrottle) * PID_error / max_error_mmPs;
+    long throttle_decrease = (MAX_ACC_OUT - MIN_ACC_OUT) * PID_error / max_error_mmPs;
     throttle_control -= throttle_decrease;
-    if (throttle_control < MinimumThrottle)
-        throttle_control = MinimumThrottle;
+    if (throttle_control < MIN_ACC_OUT)
+        throttle_control = MIN_ACC_OUT;
     moveVehicle(throttle_control);

-    long brake_increase = (NoBrake - FullBrake) * PID_error / max_error_mmPs;
-    // NoBrake = 207; FullBrake = 167;
+    long brake_increase = (MAX_BRAKE_OUT - MIN_BRAKE_OUT) * PID_error / max_error_mmPs;
+    // MIN_BRAKE_OUT = 180; MAX_BRAKE_OUT = 250;
     brake_control -= brake_increase;
-    if (brake_control < FullBrake)
-        brake_control = FullBrake;
+    if (brake_control > MAX_BRAKE_OUT)
+        brake_control = MAX_BRAKE_OUT;
     brake(brake_control);
   }
   else if (PID_error < speed_tolerance_mmPs)
   {  // too slow
-    long throttle_increase = (FullThrottle - MinimumThrottle) * PID_error / max_error_mmPs;
+    long throttle_increase = (MAX_ACC_OUT - MIN_ACC_OUT) * PID_error / max_error_mmPs;
     throttle_control += throttle_increase;
-    if (throttle_control > FullThrottle)
-        throttle_control = FullThrottle;
+    if (throttle_control > MAX_ACC_OUT)
+        throttle_control = MAX_ACC_OUT;
     moveVehicle(throttle_control);

     // release brakes
-    long brake_decrease = (NoBrake - FullBrake) * PID_error / max_error_mmPs;
-    // NoBrake = 207; FullBrake = 167;
+    long brake_decrease = (MAX_BRAKE_OUT - MIN_BRAKE_OUT) * PID_error / max_error_mmPs;
+    // MIN_BRAKE_OUT = 180; MAX_BRAKE_OUT = 250;
     brake_control += brake_decrease;
-    if (brake_control > NoBrake)
-        brake_control = NoBrake;
+    if (brake_control < MIN_BRAKE_OUT)
+        brake_control = MIN_BRAKE_OUT;
     brake(brake_control);
   }
   // else maintain current speed
-  Serial.print("\tThottle Brake \t");  // csv for spreadsheet
+  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(drive_speed_mmPs);  Serial.print("\t");
+//  Serial.println(sensor_speed_mmPs);
 }

 /*---------------------------------------------------------------------------------------*/
-
+/* Serial 7-Segment Display Example Code
+    Serial Mode Stopwatch
+   by: Jim Lindblom
+     SparkFun Electronics
+   date: November 27, 2012
+   license: This code is public domain.
+
+   This example code shows how you could use software serial
+   Arduino library to interface with a Serial 7-Segment Display.
+
+   There are example functions for setting the display's
+   brightness, decimals and clearing the display.
+
+   The print function is used with the SoftwareSerial library
+   to send display data to the S7S.
+
+   Circuit:
+   Arduino -------------- Serial 7-Segment
+     3.3V   --------------------  VCC
+     GND  --------------------  GND
+      10   --------------------  RX
+*/
+
+void setup7seg()
+{
+  // Must begin s7s software serial at the correct baud rate.
+  //  The default of the s7s is 9600.
+  s7s.begin(9600);
+
+  // Clear the display, and then turn on all segments and decimals
+  clearDisplay();  // Clears display, resets cursor
+  setBrightness(127);  // Medium brightness
+//  setBrightness(255);  // High brightness
+}
+
+void show7seg(int speed_mmPs)
+{
+  char tempString[10];  // Will be used with sprintf to create strings
+  // convert mm/s to km/h
+  int speed_kmPhx10 = (speed_mmPs*36)/10;
+  // 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);
+
+  // This will output the tempString to the S7S
+  s7s.print(tempString);
+  setDecimals(0b00000100);  // Sets digit 3 decimal on
+}
+
+// Send the clear display command (0x76)
+//  This will clear the display and reset the cursor
+void clearDisplay()
+{
+  s7s.write(0x76);  // Clear display command
+}
+
+// Set the displays brightness. Should receive byte with the value
+//  to set the brightness to
+//  dimmest------------->brightest
+//     0--------127--------255
+void setBrightness(byte value)
+{
+  s7s.write(0x7A);  // Set brightness command byte
+  s7s.write(value);  // brightness data byte
+}
+
+// Turn on any, none, or all of the decimals.
+//  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)
+{
+  s7s.write(0x77);
+  s7s.write(decimals);
+}


Added print statements

Added print statements

--- Elcano_C2_LowLevel/Elcano_C2_LowLevel.ino
+++ Elcano_C2_LowLevel/Elcano_C2_LowLevel.ino
@@ -503,11 +503,12 @@
 void steer(int pos)
 {
       analogWrite(STEER_OUT_PIN, pos);
+      Serial.print("Steering to: "); Serial.println(pos);
 }
 void brake(int amount)
 {
       analogWrite(BRAKE_OUT_PIN, amount);
-      Serial.println(amount);
+      Serial.print("Braking to: "); Serial.println(amount);
 }
 /*---------------------------------------------------------------------------------------*/
 /* DAC_Write applies value to address, producing an analog voltage.


Found issue int the code theat the MQTT topic names were not set. Corrected this and uploaded.

--- src/WiFiSensor/WiFiSensor.ino
+++ src/WiFiSensor/WiFiSensor.ino
@@ -154,6 +154,8 @@
         String topicname("sensors/");
         topicname += String(sensorname);
         topicname += String("/");
+		mqtttemperaturetopic = "temp";
+		mqtthumiditytopic = "humidity";
         snprintf(msg, 25, "%s", String(lastmeasurement.temperature).c_str());
         if(client.publish( (topicname + mqtttemperaturetopic).c_str(), msg)){
 			Serial.println( "Successful MQTT Update 1");


implementado o pré-ciclo, resolves #7

implementado o pré-ciclo, resolves #7

--- EMP-B-Due.ino
+++ EMP-B-Due.ino
@@ -10,6 +10,7 @@
     const byte bt_geral = 22; // Entrada do botão de Liga/Desliga Geral
     const byte bt_dosador = 24; // Entrada do botão de Liga/Desliga do Dosador
     const byte bt_datador = 26; // Entrada do botão de Liga/Desliga do Datador
+    const byte sensor_reset = 28; // Entrada do Sensor de Reset de Ciclo
     const byte sensor_porta = 32; // Sensor de Segurança da Porta Frontal
     const byte sensor_painel = 34; // Sensor de Segurança da Porta do Painel
     const byte sensor_maquina = 36; // Sensor de Segurança da Porta da Máquina
@@ -23,6 +24,9 @@
     const byte solda_vertical = 33; // Saída da Solda Vertical
     const byte solda_horizontal = 35; // Saída da Solda Horizontal
     const byte solda_datador = 37; // Saída da Solda do Datador
+    const byte led_teste_1 = 23;
+    const byte led_teste_2 = 25;
+    const byte led_teste_3 = 27;

 // Variáveis
@@ -65,6 +69,32 @@
     boolean dosador_ligado = FALSO;
     boolean datador_ligado = FALSO;
     boolean alarme_ativo = FALSO;
+    unsigned long inicio_ciclo = millis();
+    bool fotocelula_liberada = FALSO;
+    bool fotocelula_cortou = FALSO;
+    bool ciclo_resetado = FALSO;
+    unsigned long conta_ciclo = 0;
+  // Tempos do Ciclo
+    // Mandibula
+    unsigned long inicio_mandibula = 550;
+    unsigned long fim_mandibula = 1500;
+    // Fotocélula
+    unsigned long inicio_fotocelula = 1250;
+    unsigned long fim_fotocelula = 1400;
+    // Faca
+    unsigned long inicio_faca = 600;
+    unsigned long fim_faca = 800;
+    // Refrigeração
+    unsigned long inicio_refrigeracao = 800;
+    unsigned long fim_refrigeracao = 1450;
+    // Datador
+    unsigned long inicio_datador = 0;
+    unsigned long fim_datador = 400;
+    // Solda Vertical
+    unsigned long inicio_soldas = 0;
+    unsigned long fim_soldas = 400;
+    // Atraso entre resets consecutivos
+    unsigned long atraso_resets = 500;

 void setup() {
@@ -73,6 +103,7 @@
   pinMode(bt_geral, BOTAO);
   pinMode(bt_dosador, BOTAO);
   pinMode(bt_datador, BOTAO);
+  pinMode(sensor_reset, BOTAO); // Mudar para Sensor após os testes.
   // Potenciômetros das Soldas
   pinMode(pot_solda_vertical, SENSOR);
   pinMode(pot_solda_horizontal, SENSOR);
@@ -90,6 +121,9 @@
   pinMode(geral, SAIDA);
   pinMode(dosador, SAIDA);
   pinMode(datador, SAIDA);
+  pinMode(led_teste_1, SAIDA);
+  pinMode(led_teste_2, SAIDA);
+  pinMode(led_teste_3, SAIDA);

   // Define estado inicial das saídas
   resetCompleto();
@@ -130,7 +164,11 @@
 }

 void iniciaTrabalho(){
-
+  if (conta_ciclo >= 3){
+    ligaFuncao(led_teste_1, "Led Teste 1"); // Exemplo para teste.
+    // ciclo de trabalho
+  }
+  funcaoReset();
 }

 void modoAlarme(){
@@ -147,6 +185,14 @@

 // FUNÇÕES ADICIONAIS

+void bloqueioPorAlarme(String texto){
+  alarme_ativo = VERDADEIRO;
+  stand_by = FALSO;
+  escreveSerial("\n<< Alarme! >>\n");
+  reiniciaSaidas();
+  escreveSerial(texto + " detectou uma falha!");
+}
+
 void acionaGeral(){
   btUmClique(bt_geral, &estbt_geral, &estbta_geral, &atr_geral, &maquina_ligada);
 }
@@ -159,6 +205,24 @@
   if (maquina_ligada and !alarme_ativo){
     btUmClique(bt_datador, &estbt_datador, &estbta_datador, &atr_datador, &datador_ligado);
   }
+}
+
+void funcaoReset() {
+  unsigned long tempo_atual = (millis()-inicio_ciclo);
+  if (!ciclo_resetado and ativo(sensor_reset)) {
+    ciclo_resetado = true;
+    conta_ciclo++;
+    escreveSerial((String) conta_ciclo);
+    reiniciaCiclo();
+  } else if (ciclo_resetado and tempo_atual > atraso_resets) {
+    ciclo_resetado = false;
+  }
+}
+
+void reiniciaCiclo(){
+  inicio_ciclo = millis();
+  fotocelula_liberada = FALSO;
+  fotocelula_cortou = FALSO;
 }

 void geraPWM(byte pot, unsigned long *inicio, byte saida, String nome){
@@ -177,89 +241,82 @@
   }
 }

-void bloqueioPorAlarme(String texto){
-  alarme_ativo = VERDADEIRO;
-  stand_by = FALSO;
-  escreveSerial("\n<< Alarme! >>\n");
-  reiniciaSaidas();
-  escreveSerial(texto + " detectou uma falha!");
+
+// FERRAMENTAS AUXILIARES
+
+byte leEntrada(byte pino){
+  return digitalRead(pino);
+}
+
+void liga(byte saida){
+  digitalWrite(saida, LIGA);
+}
+
+void ligaFuncao(byte saida, String texto){
+  if (desligado(saida)){
+    liga(saida);
+    escreveSerial(texto + " Ligado.");
+  }
+}
+
+void desliga(byte saida){
+  digitalWrite(saida, DESLIGA);
+}
+
+void desligaFuncao(byte saida, String texto){
+  if (ligado(saida)){
+    desliga(saida);
+    escreveSerial(texto + " Desligado.");
+  }
+}
+
+boolean ligado(byte saida){
+  if (digitalRead(saida) == LIGA){
+    return VERDADEIRO;
+  } else {
+    return FALSO;
+  }
+}
+
+boolean desligado(byte saida){
+  if (digitalRead(saida) == DESLIGA){
+    return VERDADEIRO;
+  } else {
+    return FALSO;
+  }
+}
+
+boolean ativo(byte entrada){
+  if (digitalRead(entrada) == ALTO){
+    return VERDADEIRO;
+  } else {
+    return FALSO;
+  }
+}
+
+boolean inativo(byte entrada){
+  if (digitalRead(entrada) == BAIXO){
+    return VERDADEIRO;
+  } else {
+    return FALSO;
+  }
 }

 void btUmClique(byte botao, int *estado, int *est_ant, unsigned long *atr_ant, boolean *funcao){
-  byte leitura = leEntrada(botao);
-  if (leitura != *est_ant) {
+  byte estado_atual = leEntrada(botao);
+  if (estado_atual != *est_ant) {
     *atr_ant = millis();
   }

   if ((millis() - *atr_ant) > atraso) {
-    if (leitura != *estado) {
-      *estado = leitura;
+    if (estado_atual != *estado) {
+      *estado = estado_atual;
       if (*estado == ALTO) {
         *funcao = !*funcao;
       }
     }
   }
-  *est_ant = leitura;
-}
-
-// FERRAMENTAS AUXILIARES
-
-byte leEntrada(byte pino){
-  return digitalRead(pino);
-}
-
-void liga(byte saida){
-  digitalWrite(saida, LIGA);
-}
-
-void ligaFuncao(byte saida, String texto){
-  if (desligado(saida)){
-    liga(saida);
-    escreveSerial(texto + " Ligado.");
-  }
-}
-
-void desliga(byte saida){
-  digitalWrite(saida, DESLIGA);
-}
-
-void desligaFuncao(byte saida, String texto){
-  if (ligado(saida)){
-    desliga(saida);
-    escreveSerial(texto + " Desligado.");
-  }
-}
-
-boolean ligado(byte saida){
-  if (digitalRead(saida) == LIGA){
-    return VERDADEIRO;
-  } else {
-    return FALSO;
-  }
-}
-
-boolean desligado(byte saida){
-  if (digitalRead(saida) == DESLIGA){
-    return VERDADEIRO;
-  } else {
-    return FALSO;
-  }
-}
-
-boolean ativo(byte entrada){
-  if (digitalRead(entrada) == ALTO){
-    return VERDADEIRO;
-  } else {
-    return FALSO;
-  }
-}
-
-boolean inativo(byte entrada){
-  if (digitalRead(entrada) == BAIXO){
-    return VERDADEIRO;
-  } else {
-    return FALSO;
-  }
+  *est_ant = estado_atual;
 }

 void escreveSerial(String texto){
@@ -271,10 +328,15 @@
 void reiniciaSaidas(){
   dosador_ligado = FALSO;
   datador_ligado = FALSO;
+  conta_ciclo = 0;

   desligaFuncao(geral, NomeGeral);
   desligaFuncao(dosador, NomeDosador);
   desligaFuncao(datador, NomeDatador);
+
+  desliga(led_teste_1); // Para testes
+  desliga(led_teste_2); // Para testes
+  desliga(led_teste_3); // Para testes
 }

 void resetCompleto(){
@@ -285,6 +347,10 @@
   desliga(solda_vertical);
   desliga(solda_horizontal);
   desliga(solda_datador);
+
+  desliga(led_teste_1); // Para testes
+  desliga(led_teste_2); // Para testes
+  desliga(led_teste_3); // Para testes
 }