new features; bug fixes

new features; bug fixes

--- loom.ino
+++ loom.ino
@@ -14,8 +14,10 @@
     - 1 Teensy 3.5 microprocessor, with 512KB flash, 192KB RAM, 4KB EEPROM, and 40 I/O pins

    The software allows you to graphically configure the treadle tie-ups and the treadle sequence,
-   and then weave by throwing the shuttle and just pushing the single foot pedeal to get the
+   and then weave by throwing the shuttle and just pushing the single foot pedal to get the
    next configuration of the shafts.  The warping, though, must still be done manually!
+
+   See https://github.com/LenShustek/loom for more information about this project.

    ------------------------------------------------------------------------------------------------------
    Copyright (c) 2017, Len Shustek
@@ -58,30 +60,42 @@
                                   - temporarily disable motors during weaving if there is no activity for a few minutes.
    27 Mar 2017, L. Shustek, V1.6  - display filename on top-level screen, or "unsaved" if pgmg changes are made
                                   - default to current file in load/save menu
+                                  - exit from program mode if any other button is pushed
+   15 Jun 2017, L. Shustek, V1.7  - fix bug: exiting weaving mode after motors had timed out didn't return
+                                    the shafts to the neutral position
+    8 Jan 2018, L. Shustek, V1.8  - change "zero" button to "backup" button in weave mode
+                                  - display frame numbers instead of X in tieup screen
+                                  - display treadle numbers instead of X in treadle sequence screen
+                                  - fix bug: backing up weave at the first treadle position failed
+   28 Oct 2018, L. Shustek, V1.9  - add the option to do "Tabby" between each step of a treadle sequence
+    3 Jan 2019, L. Shustek, V1.10 - during calibration, show the distance the frame moves
+
 */
-#define VERSION "1.6"
-
-/* TODO:
+#define VERSION "1.10"
+
+/***** Enhancement ideas:
+
     - Invent a more programmatic way to configure treadle sequences with repeat loops.
       Since weaving is limited to one treadle at a time we can use decimal rather than unary
       notation on the narrow display. It doesn't match weaving books, though, so weavers would
-      consider that sacriligious!
+      consider that sacrilegious!

       Idea #1: a programming mode for "treadle loops", in addition to the traditional sequence.
       The notation might be like this, using "Irish Meadows blanket" as an example:
           4x: 5 6
           6x: 6 5
           8x: 5 6
-          xx: 1 2 3 4
+          ?x: 1 2 3 4
           8x: 5 6
           6x: 6 5
           4x: 5 6
-      When weaving, the "xx" line would be repeated indefinitely until a button is pushed to advance.
+      When weaving, the "?x" line would be repeated indefinitely until a button is pushed to advance.
       Either this "treadle loop" notation or a reconstructed "treadle sequence" notation could be displayed.
-      The big-digit display could show how far along in a repeat sequence we are.
-      The file format would have to be elaborated to be able to save and load these looped treadle sequences.
+      The 3rd and 4th numbers on the big-digit display could show how far along in a repeat sequence we are.
+      The file format would have to be elaborated to save and load these looped treadle sequences.

     - Save space by making the tieup[][] matrix be a true bitmap. That would allow more files in the EEPROM.
+      Or instead: use an SD card for files, and to hell with optimizing the size to fit in the 4K EEPROM!
 */

 #define DEBUG true
@@ -95,6 +109,7 @@

 //**** global parameters

+// All stored files will break if NUM_TREADLES, NUM_SHAFTS, or MAX_SEQUENCE is changed!
 #define NUM_TREADLES 16 // max 17 will fit on the display currently
 #define NUM_SHAFTS 8
 #define MAX_SEQUENCE 99
@@ -102,6 +117,7 @@
 #define MSEC_PER_ROTATION 1000      // how long we should take for one rotation
 #define uSTEPS_PER_STEP 4           // how many microsteps per step the drivers are configured for (MODE1 high)
 #define STEPS_PER_ROTATION (200 * uSTEPS_PER_STEP)  // the stepper motors have 1.8 degree "full" steps; 360/1.8=200
+#define HUNDRETHINCHES_PER_ROTATION ((int)(0.75*3.14*100.0+0.5))  // we use a 3/4" drive gear
 #define MIN_STEP_uSEC (1000UL * MSEC_PER_ROTATION / STEPS_PER_ROTATION)
 #define DEBOUNCE_MSEC 50
 #define ROTATION_PERCENT (112/2) // what part of a full rotation goes from CENTER to UP or DOWN, nominally
@@ -212,7 +228,8 @@
    // initialization: a line is all treadles connected to a particular shaft
    {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // initialized to basic weave
    {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-   /* everything else is 0 */ };
+   /* everything else is 0 */
+};
 static byte treadle_sequence[MAX_SEQUENCE]; // treadle sequence for this pattern; values are 0..NUM_TREADLES-1
 #define UNUSED_SEQ 0xff                     // or 0xff signifying "this position is unused"
 static int sequence_size;
@@ -220,10 +237,10 @@
 //**** EEPROM format for persistent data

 #define EEPROM_SIZE 4096
-/* layout is:
+/* layout in the EEPROM is:
      config_hdr
      shaft_status []
-     repeat {
+     repeat for each file {
         file_hdr
         tieup []
         treadle_sequence []
@@ -237,7 +254,8 @@
    byte maxsequence;
    byte lastfilenum;  // the last file we loaded or saved
    byte tr_seq_pos;   // the current index into the treadle sequence for that file
-   byte unused[15];
+   byte tr_treadle;   // the current treadle (could be 0/1 for "alternate tabby" mode)
+   byte unused[14];
    // after this we write the "shaft_status" array, which contains the current shaft configuration data
 } config_hdr = {0 };
 #define CONFIG_SIZE ((int)sizeof(config_hdr) + (int)sizeof(shaft_status))
@@ -245,7 +263,10 @@
 #define MAX_FILENAME 14
 struct {
    char id[4]; // "fil" for identification
-   int size;   // size of the whole file, including this header
+   int16_t size;   // size of the whole file, including this header
+   byte flags;
+#define FILE_TABBY 0x01  // use Tabby 1/2 between each treadle step
+   byte unused;
    byte checksum;
    char filename[MAX_FILENAME + 1]; // null-terminated string
    // after this we write the tieup array, followed by the treadle_sequence vector
@@ -255,7 +276,7 @@
 // The current implementation assumes all files are padded to the fixed maximum size.
 // All stored files will break if NUM_SHAFTS, NUM_TREADLES, or MAX_SEQUENCE is changed!

-//**** global variables
+//    other global variables

 LiquidCrystalFast lcd (LCD_RS, LCD_RW, LCD_ENB, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
 Encoder H_ENC (H_ENC_A, H_ENC_B);
@@ -265,16 +286,15 @@
 char last_filename[MAX_FILENAME + 1] = {0};
 bool unsaved_file = false;

-//**** utility routines
+//***********************************************************************
+//    utility routines
+//***********************************************************************

 void assert (boolean test, const char *msg) {
    if (!test) {
-      lcd.clear();
-      lcd.print("** INTERNAL ERROR **");
-      lcd.setCursor(0, 1);
-      lcd.print("Assertion failed:");
-      lcd.setCursor(0, 2);
-      lcd.print(msg);
+      lcd.clear(); lcd.print("** INTERNAL ERROR **");
+      lcd.setCursor(0, 1); lcd.print("Assertion failed:");
+      lcd.setCursor(0, 2); lcd.print(msg);
       while (true) ; } }

 void center_message (byte row, const char *msg) {
@@ -289,8 +309,7 @@
    for (byte i = 0; i < nblanks; ++i) lcd.print(" "); }

 void info_message(const char *msg1, char *msg2) {
-   lcd.clear();
-   center_message(1, msg1);
+   lcd.clear(); center_message(1, msg1);
    if (msg2) center_message(2, msg2);
    delay(3000);
    lcd.clear(); }
@@ -318,7 +337,9 @@
    digitalWrite(V_ENC_GREEN, led == V_ENC_GREEN ? LED_ON : LED_OFF);
    digitalWrite(V_ENC_BLUE, led == V_ENC_BLUE ? LED_ON : LED_OFF); }

-//**** big 7-sgement LED display routines
+//***********************************************************************
+//     big 7-sgement LED display routines
+//***********************************************************************

 static const uint8_t numbertable[] = {
    0x3F, /* 0 */  0x06, /* 1 */  0x5B, /* 2 */  0x4F, /* 3 */  0x66, /* 4 */
@@ -439,8 +460,7 @@
       if (event == ePBV) {
          answer =  false;
          break; } }
-   H_LED(0);
-   V_LED(0);
+   H_LED(0); V_LED(0);
    lcd.clear();
    return answer; }

@@ -477,8 +497,7 @@
             if (event != eNone) answer = 0;  // any other button aborts
             break; } }
    lcd.noBlink();
-   V_LED(0);
-   H_LED(0);
+   V_LED(0); H_LED(0);
    return answer; }

 void lcd_write_dd (int number) {
@@ -486,8 +505,9 @@
    lcd.write('0' + number % 10);
    lcd.write(':'); }

-
-//**** loom programming routines
+//***********************************************************************
+//    loom programming routines
+//***********************************************************************

 void display_tieups(int /*starting*/ shaft, bool title) {
    int row = 3; // start from bottom to match weaving pattern books
@@ -501,9 +521,12 @@
       lcd.write('1' + shaft);
       lcd.write(':');
       for (int treadle = 0; treadle < NUM_TREADLES; ++treadle)
-         lcd.write(tieup[shaft] [treadle] ? 'X' : ' '); } }
+         lcd.write(tieup[shaft] [treadle] ? '1' + shaft : ' '); } }

 void display_treadle_sequence(int /*starting*/ sequence_pos, bool title) {
+   static char treadle_name[] = { // treadles are numbered 0..NUM_TREADLES-1
+      '1', '2', '3', '4', '5', '6', '7', '8', '9',
+      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' };
    int row = 0; // start from top to match weaving pattern books
    lcd.clear();
    if (title) {
@@ -515,10 +538,15 @@
       lcd.setCursor(0, row);
       lcd_write_dd(sequence_pos + 1);
       if (treadle != UNUSED_SEQ) {
+         if (file_hdr.flags & FILE_TABBY) { // show tabby in addition to real treadle
+            int tabby_posn = sequence_pos & 1 ? 1 : 0;  // alternate even/odd
+            lcd.setCursor(tabby_posn + 3, row);
+            lcd.write(treadle_name[tabby_posn]); }
          lcd.setCursor(treadle + 3, row);
-         lcd.write('X'); } } }
-
-void program_tieups(void) {
+         lcd.write(treadle_name[treadle]); } } }
+
+enum events program_tieups(void) {
+   // program the treadle-lamm tieups, and return the button push that caused us to stop
    int shaft_num_on_bottom = 0;
    int shaft_num = 0, treadle_num = 0;
    bool show_title = true;
@@ -563,12 +591,25 @@
             unsaved_file = true;
             tieup[shaft_num][treadle_num] = false;
             goto move_right;
-         case ePB1:  // top button: stop programming
+         default:  // any button: stop programming
             H_LED(0);
             V_LED(0);
             lcd.noCursor();
-            return;
-         default:; } } }
+            return event; } } }
+
+bool using_shaft(int shaft) {  // does any used treadle tie up to this shaft?
+   if ((file_hdr.flags & FILE_TABBY) &&
+         (shaft == 0 || shaft == 1)) return true;  // use the first two in "alternate tabby 1/2" mode
+   for (int pos = 0; pos < sequence_size; ++pos)
+      if (treadle_sequence[pos] != UNUSED_SEQ && tieup[shaft][treadle_sequence[pos]])
+         return true;
+   return false; }
+
+bool using_treadle(int treadle) { // is this treadle used in this program?
+   for (int pos = 0; pos < sequence_size; ++pos)
+      if (treadle_sequence[pos] != UNUSED_SEQ && treadle_sequence[pos] == treadle)
+         return true;
+   return false; }

 void cleanup_treadle_sequence(void) {
    // compact the treadle sequence by removing unused lines,
@@ -579,6 +620,8 @@
       if (treadle_sequence[rpos] != UNUSED_SEQ) {
          treadle_sequence[wpos++] = treadle_sequence[rpos];
          ++sequence_size; }
+   if (!(file_hdr.flags & FILE_TABBY))
+      config_hdr.tr_treadle = treadle_sequence[config_hdr.tr_seq_pos];
    if (DEBUG) {
       Serial.print("sequence size: "); Serial.println(sequence_size); } }

@@ -596,11 +639,13 @@
    treadle_sequence[position] = UNUSED_SEQ; // new last row is "unused"
 }

-void program_treadle_sequence(void) {
+enum events  program_treadle_sequence(void) {
+   // program the treadle sequence, and return the button push that caused us to stop
    int sequence_pos_on_top = 0;
    int sequence_pos = 0, treadle_num = 0;
    bool show_title = true;
    bool row_select = false;  // are we selecting the whole row by having the cursor on the far left?
+   bool did_something = false;
    enum events event;
    H_LED(H_ENC_GREEN);
    V_LED(V_ENC_RED);
@@ -609,11 +654,9 @@
       lcd.setCursor(row_select ? 0 : treadle_num + 3,
                     sequence_pos - sequence_pos_on_top + (show_title ? 1 : 0));
       if (row_select) {
-         lcd.noCursor();
-         lcd.blink(); }
+         lcd.noCursor(); lcd.blink(); }
       else {
-         lcd.noBlink();
-         lcd.cursor(); }
+         lcd.noBlink(); lcd.cursor(); }
       do {
          event = check_event(); }
       while (event == eNone);
@@ -621,19 +664,15 @@
          case eHrotL:  // move left
             if (treadle_num == 0) {
                row_select = true;
-               lcd.noCursor();
-               lcd.blink();
-               H_LED(H_ENC_BLUE);
-               V_LED(V_ENC_RED); }
+               lcd.noCursor(); lcd.blink();
+               H_LED(H_ENC_BLUE); V_LED(V_ENC_RED); }
             else --treadle_num;
             break;
          case eHrotR:   // move right
             if (row_select) {
                row_select = false;
-               lcd.noBlink();
-               lcd.cursor();
-               H_LED(H_ENC_GREEN);
-               V_LED(V_ENC_RED); }
+               lcd.noBlink(); lcd.cursor();
+               H_LED(H_ENC_GREEN); V_LED(V_ENC_RED); }
             else if (treadle_num < NUM_TREADLES - 1) ++treadle_num;
             break;
          case eVrotR:  // move down
@@ -651,36 +690,43 @@
                   --sequence_pos_on_top; } }
             break;
          case ePBH: // green or blue (left, horizontal) button
-            unsaved_file = true;
+            unsaved_file = did_something = true;
             if (row_select) insert_treadle_sequence(sequence_pos);
             else {
                treadle_sequence[sequence_pos] = treadle_num;  // assign the treadle to this position
                goto move_down; }
             break;
          case ePBV:  // red (right, vertical) button
-            unsaved_file = true;
+            unsaved_file = did_something = true;
             if (row_select) delete_treadle_sequence(sequence_pos);
             else {
                if (treadle_sequence[sequence_pos] == treadle_num)  // if we're on this treadle
                   treadle_sequence[sequence_pos] = UNUSED_SEQ; // remove it
             }
             break;
-         case ePB1:  // program button: stop programming
+         default:  // program button: stop programming
             H_LED(0);
             V_LED(0);
             lcd.noBlink();
             lcd.noCursor();
             cleanup_treadle_sequence();
-            return;
-         default:; } } }
-
+            // If the new or modified program doesn't use the first two treadles at all, see if
+            // the weaver wants us to alternate using them between all the other treadle steps
+            if (did_something && ((file_hdr.flags & FILE_TABBY) || (!using_treadle(0) && !using_treadle(1)))
+                  && wait_yesno(0, "Alternate 1/2 Tabby?"))
+               file_hdr.flags |= FILE_TABBY;
+            return event; } } }
+
+//***********************************************************************
 // file routines
+//***********************************************************************

 void dump_file (const char *msg) {
    Serial.println(msg);
    Serial.print(file_hdr.id); Serial.print(", ");
-   Serial.print(file_hdr.size); Serial.print(" bytes, checksum "); Serial.println(" checksum");
+   Serial.print(file_hdr.size); Serial.print(" bytes, checksum "); Serial.println(file_hdr.checksum, HEX);
    Serial.print("name:"); Serial.println(file_hdr.filename);
+   Serial.print("flags:"); Serial.println(file_hdr.flags, HEX);
    Serial.println("tieups:");
    for (int sh = 0; sh < NUM_SHAFTS; ++sh) {
       for (int tr = 0; tr < NUM_TREADLES; ++tr) {
@@ -783,7 +829,7 @@
          checksum += ((char *)&file_hdr) [ i];
       assert(checksum == 0, "bad file checksum");
       cleanup_filename(file_hdr.filename); }
-   else { // damaged or never-used header: make it look good
+   else {   // damaged or never-used header: make it look good
       strcpy (file_hdr.id, "fil");
       memset(file_hdr.filename, '\0', MAX_FILENAME + 1);
       file_hdr.size = FILE_SIZE; } }
@@ -793,6 +839,7 @@
    assert (filenum < MAX_FILES, "bad read_file_data");
    read_EEPROM(&fromloc, (char*) tieup, sizeof(tieup));
    read_EEPROM(&fromloc, (char*) treadle_sequence, sizeof(treadle_sequence));
+   config_hdr.tr_seq_pos = 0; // start the treadle sequence from the beginning
    cleanup_treadle_sequence();
    config_hdr.lastfilenum = filenum;
    strcpy(last_filename, file_hdr.filename);
@@ -816,7 +863,7 @@
       ndx = letterptr - filenamechars; }
    if (forward) { // forwards in lexical order
       if (++ndx >= (int)sizeof(filenamechars) - 1) ndx = 0; }
-   else { // backwards in lexical order
+   else {   // backwards in lexical order
       if (--ndx < 0) ndx = (int)sizeof(filenamechars) - 2; }
    return filenamechars[ndx]; }

@@ -834,6 +881,8 @@
       erase_EEPROM();
       return; }
    save = choice == 2;  // choice is either 1 for load, or 2 for save
+   byte flags = file_hdr.flags; // Save the current flags in case we save a file,
+   // because just listing files destroys it. We need multiple file header buffers.

    // highlight the last file we loaded or saved on line 2, maybe
    filenum = config_hdr.lastfilenum < MAX_FILES ? config_hdr.lastfilenum : 0;
@@ -847,11 +896,9 @@
       V_LED(save ? (row_select ? V_ENC_RED : V_ENC_BLUE) : V_ENC_GREEN);
       lcd.setCursor(row_select ? 0 : 3 + charnum, filenum - filenum_on_top);
       if (row_select) {
-         lcd.noCursor();
-         lcd.blink(); }
+         lcd.noCursor(); lcd.blink(); }
       else {
-         lcd.noBlink();
-         lcd.cursor(); }
+         lcd.noBlink(); lcd.cursor(); }
       do {
          event = check_event(); }
       while (event == eNone);
@@ -860,16 +907,14 @@
             if (save) {
                if (charnum == 0) {
                   row_select = true;
-                  lcd.noBlink();
-                  lcd.cursor(); }
+                  lcd.noBlink();  lcd.cursor(); }
                else --charnum; }
             break;
          case eHrotR:   // move right
             if (save) {
                if (row_select) {
                   row_select = false;
-                  lcd.noCursor();
-                  lcd.blink(); }
+                  lcd.noCursor(); lcd.blink(); }
                else if (charnum < MAX_FILENAME) {
                   ++charnum;
                   if (file_hdr.filename[charnum] == '\0') { // if we're going beyond the end
@@ -880,26 +925,24 @@
          case eVrotR:  // move down
             if (!save || row_select) {
                if (filenum < MAX_FILES - 1) {
-                  ++filenum;
-                  if (filenum - filenum_on_top > 3)  // scroll up
+                  if (++filenum - filenum_on_top > 3)  // scroll up
                      ++filenum_on_top;
                   display_files(filenum_on_top);
                   read_file_hdr(filenum);
                   charnum = 0; } }
-            else {  // save, in name: change filename char
+            else {   // save, in name: change filename char
                file_hdr.filename[charnum] = changeletter(file_hdr.filename[charnum], true);
                goto update_letter; }
             break;
          case eVrotL:  // move up
             if (!save || row_select) {
                if (filenum > 0) {
-                  --filenum;
-                  if (filenum < filenum_on_top) // scroll down
+                  if (--filenum < filenum_on_top) // scroll down
                      --filenum_on_top;
                   display_files(filenum_on_top);
                   read_file_hdr(filenum);
                   charnum = 0; } }
-            else { // save, in name: change filename char
+            else {   // save, in name: change filename char
                file_hdr.filename[charnum] = changeletter(file_hdr.filename[charnum], false);
 update_letter:
                lcd.write(file_hdr.filename[charnum]);
@@ -910,6 +953,7 @@
             if (save) {
                if (row_select) { // write this file
                   cleanup_filename(file_hdr.filename);
+                  file_hdr.flags = flags; // use the current flags
                   write_file(filenum);
                   sprintf (string, "file %d saved", filenum + 1);
                   info_message(string, file_hdr.filename);
@@ -920,11 +964,11 @@
             if (save) {
                if (!row_select) { // name entry: go to next char
                   if (charnum < MAX_FILENAME) ++charnum; }
-               else { // abort writing
+               else {   // abort writing
                   cleanup_filename(file_hdr.filename);
                   info_message("file save aborted", 0);
                   goto exit_loadsave; } }
-            else { // load file
+            else {   // load file
                read_file_data(filenum);
                sprintf (string, "file %d loaded", filenum + 1);
                info_message(string, file_hdr.filename);
@@ -936,20 +980,14 @@
          case ePB3:
          case ePB4:
 exit_loadsave:
-            H_LED(0);
-            V_LED(0);
-            lcd.noBlink();
-            lcd.noCursor();
+            H_LED(0); V_LED(0);
+            lcd.noBlink(); lcd.noCursor();
             return;
          default:; } } }

-//**** weaving routines
-
-bool using_shaft(int shaft) {  // does any used treadle tie up to this shaft?
-   for (int pos = 0; pos < sequence_size; ++pos)
-      if (treadle_sequence[pos] != UNUSED_SEQ && tieup[shaft][treadle_sequence[pos]])
-         return true;
-   return false; }
+//***********************************************************************
+//     weaving routines
+//***********************************************************************

 void do_steps() {  // do queued-up steps for all motors
    bool step_done;
@@ -982,8 +1020,7 @@
          delayMicroseconds(MIN_STEP_uSEC);
          assert(digitalRead(MOTOR_FAULT) == HIGH, "motor failure"); } }
    while (step_done);
-   H_LED(0);
-   V_LED(0); }
+   H_LED(0); V_LED(0); }

 void do_treadle(int treadle) { // queue up and then do the shaft motion for a treadle push
    #if DEBUG
@@ -1000,11 +1037,11 @@
                shaft_status[shaft].steps_to_move = -shaft_status[shaft].steps_to_down - shaft_status[shaft].steps_to_up;
             if (shaft_status[shaft].shaft_position == SHAFT_CENTER)
                shaft_status[shaft].steps_to_move = -shaft_status[shaft].steps_to_down; }
-         else { // this shaft should go up
+         else {   // this shaft should go up
             if (shaft_status[shaft].shaft_position == SHAFT_DOWN)
                shaft_status[shaft].steps_to_move = shaft_status[shaft].steps_to_down + shaft_status[shaft].steps_to_up;
             if (shaft_status[shaft].shaft_position == SHAFT_CENTER)
-               shaft_status[shaft].steps_to_move = shaft_status[shaft].steps_to_up;  }
+               shaft_status[shaft].steps_to_move = shaft_status[shaft].steps_to_up; }
          if (DEBUG) {
             Serial.print("shaft "); Serial.print(shaft);
             Serial.print(" moves "); Serial.println(shaft_status[shaft].steps_to_move); } } }
@@ -1042,14 +1079,18 @@
             delayMicroseconds(5);
             digitalWrite(shaft_hardware[shaft].pin_step, LOW);
             delayMicroseconds(MIN_STEP_uSEC);
-            steps += stepadj; } }
+            steps += stepadj; }
+         int hundredthinches = (int)(((long)steps * HUNDRETHINCHES_PER_ROTATION) / STEPS_PER_ROTATION);
+         if (hundredthinches < 0) // show the distance the frame moved up or down, in inches
+            sprintf(str, "-%d.%02d\"", (-hundredthinches) / 100, -hundredthinches % 100);
+         else sprintf(str, "+%d.%02d\"", hundredthinches / 100, hundredthinches % 100);
+         center_message(2, str); }
       if (allow_abort && event == ePBH) {
          steps = 999;
          goto do_exit; }
       if (event == ePBV) {
 do_exit:
-         V_LED(0);
-         H_LED(0);
+         V_LED(0); H_LED(0);
          if (DEBUG) {
             Serial.print("shaft "); Serial.print(shaft); Serial.print(' ');
             Serial.print(msg); Serial.print(", steps:"); Serial.println(steps); }
@@ -1062,8 +1103,8 @@
       shaft_status[shaft].steps_to_down = shaft_status[shaft].steps_to_up = NOMINAL_STEPS;
       shaft_status[shaft].steps_to_move = 0; }
    for (shaft = 0; shaft < NUM_SHAFTS; ++shaft) {  // now ask to recalibrate
-      if (using_shaft(shaft)) {                    //  the shafts in use for this pattern
-         if (get_calibration(shaft, "center", true) != 999) { // not calibrating this shaft
+      if (using_shaft(shaft)) {                    //  the shaft is in use for this pattern
+         if (get_calibration(shaft, "center", true) != 999) { // calibrating this shaft
             shaft_status[shaft].steps_to_down = -get_calibration(shaft, "down", false);
             shaft_status[shaft].steps_to_move = shaft_status[shaft].steps_to_down; // return it to the center
             do_steps();  // (it will be the only motor to move)
@@ -1089,6 +1130,32 @@
       shaft_status[shaft].shaft_position = SHAFT_CENTER; }
    do_steps(); }

+// If this file uses the FILE_TABBY "alternate with tabby" option, we assume
+// none of the treadles in the treadle sequence are either 0 or 1.
+// These routines go forward and backward in the treadle seqeunce by
+// updating tr_seq_pos and/or tr_treadle.
+
+void next_treadle(void) {
+   if (file_hdr.flags & FILE_TABBY && config_hdr.tr_treadle < 2) {
+      // we just did the tabby alternation, so now do the real treadle
+      config_hdr.tr_treadle = treadle_sequence[config_hdr.tr_seq_pos]; }
+   else { // advance to the next in the treadle sequence
+      if (++config_hdr.tr_seq_pos >= sequence_size) config_hdr.tr_seq_pos = 0;
+      if (file_hdr.flags & FILE_TABBY) // first do tabby alternation
+         config_hdr.tr_treadle = config_hdr.tr_seq_pos & 1 ? 1 : 0;
+      else // go right to the real treadle
+         config_hdr.tr_treadle = treadle_sequence[config_hdr.tr_seq_pos]; } }
+
+void previous_treadle(void) {
+   if (file_hdr.flags & FILE_TABBY && config_hdr.tr_treadle >= 2) {
+      // we just did the real treadle, so simply back up to the tabby alternative
+      config_hdr.tr_treadle = config_hdr.tr_seq_pos & 1 ? 1 : 0; }
+   else { // go to the previous in the treadle sequence
+      config_hdr.tr_seq_pos = config_hdr.tr_seq_pos == 0 ? sequence_size - 1
+                              : config_hdr.tr_seq_pos - 1;
+      // and go right to the real treadle, even if we're alternating with tabby
+      config_hdr.tr_treadle = treadle_sequence[config_hdr.tr_seq_pos]; } }
+
 void weave (void) {  // enter weaving mode
    int shuttle_count = 0;
    enum events event;
@@ -1103,16 +1170,20 @@
    if (wait_yesno("shed must be closed", "do calibration?"))
       do_calibration();
    Serial.println("weaving");
-   lcd.clear();
-   lcd.blink();
+   lcd.clear(); lcd.blink();
    display_treadle_sequence(config_hdr.tr_seq_pos, false);  // show the position we are about to move to
    lcd.setCursor(0, 0);  // indicate that by putting the cursor before the sequence number
    led7_shownum(shuttle_count, true);
+
    while (1) {// do the treadle sequence forever
       V_LED(V_ENC_BLUE); // signal "ok to change rows"
-      event = check_event();
+      event = check_event();  // get a button push or something
+      if (event != eNone && !motors_on) { // if we're about to do something and the motors are off,
+         digitalWrite(MOTOR_ENB, LOW);  // enable the motors again
+         delay(500);  // delay for power supply ramp
+         motors_on = true; }
       switch (event) {
-         case ePB1:  // any other button stops the weaving
+         case ePB1:  // any random button stops the weaving
          case ePB2:
          case ePB3:
             lcd.noBlink();
@@ -1124,39 +1195,31 @@
             return;
          case ePEDAL:  // next in treadle sequence
 do_pedal:
-            if (!motors_on) {
-               digitalWrite(MOTOR_ENB, LOW);  // enable the motors again
-               delay(500);  // delay for power supply ramp
-               motors_on = true; }
             last_weave_time = millis();
             if (!before_movement) {  // we need to move to a new position
-               if (++config_hdr.tr_seq_pos >= sequence_size) config_hdr.tr_seq_pos = 0;
+               next_treadle();
                display_treadle_sequence(config_hdr.tr_seq_pos, false);
                led7_shownum(++shuttle_count, true); }
             if (treadle_sequence[config_hdr.tr_seq_pos] != UNUSED_SEQ) {
-               lcd.setCursor(3 + treadle_sequence[config_hdr.tr_seq_pos], 0); // indicate that we will have moved to that position
+               lcd.setCursor(3 + config_hdr.tr_treadle, 0); // indicate that we will have moved to that position
                // by highlighting the treadle itself
-               do_treadle(treadle_sequence[config_hdr.tr_seq_pos]); }
+               do_treadle(config_hdr.tr_treadle); }
             before_movement = false;
             break;
-         case ePB4: // clear shuttle counter
-            shuttle_count = 0;
-            led7_shownum(shuttle_count, true);
-            break;
-         case ePBV:
+         case ePB4:     // (black button)
          case eVrotL:   // go up (backward) in treadle sequence
-            if (--config_hdr.tr_seq_pos < 0) config_hdr.tr_seq_pos = sequence_size - 1;
+            previous_treadle();
             if (shuttle_count > 0) --shuttle_count;
             goto new_position;
          case eVrotR:  // go down (forward) in treadle sequence
-            if (++config_hdr.tr_seq_pos >= sequence_size) config_hdr.tr_seq_pos = 0;
+            next_treadle();
             ++shuttle_count;
 new_position:
             before_movement = true;
             display_treadle_sequence(config_hdr.tr_seq_pos, false);
             lcd.setCursor(0, 0); // indicate that we are displaying a position we aren't at
             led7_shownum(shuttle_count, true);
-            if (event == ePBV) goto do_pedal;
+            if (event == ePB4) goto do_pedal; // black button goes up and pedals
             break;
          default:
             if (motors_on && (millis() - last_weave_time) > MINS_BEFORE_MOTOR_DISABLE * 1000L * 60L) {
@@ -1233,8 +1296,8 @@
    while (event == eNone);
    switch (event) {
       case ePB1:
-         program_tieups();
-         program_treadle_sequence();
+         event = program_tieups();
+         if (event == ePB1) program_treadle_sequence();
          break;
       case ePB2:
          weave();


Delete main.ino

Delete main.ino

--- main.ino
+++ main.ino
@@ -1,70 +0,0 @@
-/*
-
-    created by Mr.Chen
-
-*/
-
-#include "config.h"
-#include "myfunctions.h"
-
-
-
-
-void setup()
-{
-  pinMode(backlightPin, OUTPUT);
-  Backlight("ON");
-  /* 控制按键初始化 */
-  keyObj.Initialise();
-
-  /* 菜单之间的关联性设置 */
-  main_menu[2].next = set_winter_delay;
-  set_winter_delay[0].prev = main_menu;
-  main_menu[3].next = set_summer_delay;
-  set_summer_delay[0].prev = main_menu;
-  main_menu[4].next = set_param_values;
-  set_param_values[0].prev = main_menu;
-  main_menu[5].next = set_work_mode;
-  set_work_mode[0].prev = main_menu;
-  main_menu[6].next = set_PID_values;
-  set_PID_values[0].prev = main_menu;
-
-  // 初始化当前菜单为第一集
-  cur_item = main_menu;
-  prev_item = NULL;
-  // 当前选择菜单内第一项
-  cur_item_index = 0;
-  // 从第一项开始显示菜单
-  disp_start_index = 0;
-  // 为了初始化过程看清楚，按时3秒
-  delay(1000);
-  // 初始化完成，清屏并关闭LCD背光
-  Backlight("OFF");
-
-  menu_draw_required = 1;
-
-#ifdef DEBUG
-  Serial.begin(9600);
-  while (!Serial) {
-    ; // wait for serial port to connect. Needed for native USB port only
-  }
-  Serial.println("menu start");
-#endif
-
-}
-
-void loop()
-{
-  // picture loop
-  if (  menu_draw_required != 0 ) {
-    u8g.firstPage();
-    do  {
-      drawMenu();
-    } while ( u8g.nextPage() );
-    menu_draw_required = 0;
-  }
-
-  updateMenu();
-
-}
-


added do_move command

added do_move command

--- tictactoe/tictactoe.ino
+++ tictactoe/tictactoe.ino
@@ -291,10 +291,12 @@
  **********************************************/

 void registerPlayer(){
+  Serial.println("Registering player...");
   sendMsg(MSG_REGISTER + player_id + END_CHAR);
 }

 void findPlayer(){
+  Serial.println("Finding other player...");
   boolean notFound = true;
   while(notFound){
     String res = sendAndWait(MSG_FIND_GAME + player_id + END_CHAR);
@@ -304,10 +306,13 @@
     // if not_registered -> register
     // if rival -> set start_turn, set rival_id, notFound = false
     if (command == CMD_WAIT_FOR_RIVAL){
+      Serial.println("Waiting for rivals...");
       delay(1000);
     } else if (command == CMD_NOT_REGISTERED){ // This shouldn't happen
+      Serial.println("Not registered");
       registerPlayer();
     } else if (command == CMD_RIVAL){
+      Serial.println("Rival found");
       String parameters = getParameters(res);
       rival_id = getParameter(parameters, 1);
       start_turn = getParameter(parameters, 2);
@@ -325,14 +330,30 @@
 }

 void sendMove(int player_move){
+  Serial.println("Sending move...");
+  boolean notReceived = true;
+
+  //If ack -> notReceived = false
+  //If wait_for_rival -> delay 1000
+  while(notReceived){}
+    String res = sendAndWait(MSG_REGISTER + player_id + player_move +  END_CHAR);
+    String command = getCommand(res);
+    if (command = CMD_ACK){
+      Serial.println("Sent");
+      notReceived = false;
+    } else if (command == CMD_WAIT_FOR_RIVAL){
+      Serial.println("Waiting for the rival to retrieve previous move...");
+      delay(1000);
+    }
+}
+
+void sendMsg(String msg){
   //TODO
-  // send ("MOVE " + player_move + player_id)
-  // MOVE # ####
-  Serial.println("sending move");
-}
-
-void sendMsg(String msg){}
-String sendAndWait(String msg){ return "foo"; }
+}
+String sendAndWait(String msg){
+  //TODO
+  return "foo";
+}

 /**********************************************


Switching to sprintf for URL composition

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -29,10 +29,10 @@
 #define TRIGGER_INT 0

 // TIMEFRAME defines the datastorages time segmenting (256 hits in that time frame max)
-#define TIMEFRAME 15
+#define TIMEFRAME 60

 // STORAGE_MINUTES defines how many minutes of detailed information are stored in RAM
-#define STORAGE_MINUTES 10
+#define STORAGE_MINUTES 30

 #define SERVER_PORT 80
 //#define LOCAL
@@ -70,8 +70,9 @@
 // Set up the corresponding network device
 #ifdef USE_ETHERNET_SHIELD
   #define USE_NETWORK
-  EthernetClient client;
-  EthernetClient connection;
+  EthernetClient
+    client,
+    connection;
   EthernetServer server = EthernetServer(SERVER_PORT);
   #ifdef USE_STROMBEWUSST_SERVER
     EthernetUDP udp;
@@ -81,8 +82,9 @@

 #ifdef USE_WIFI_SHIELD
   #define USE_NETWORK
-  WiFiClient client;
-  WiFiClient connection;
+  WiFiClient
+    client,
+    connection;
   WiFiServer server = WiFiServer(SERVER_PORT);
   int connectionStatus = WL_IDLE_STATUS;
   #ifdef USE_STROMBEWUSST_SERVER
@@ -91,9 +93,10 @@
 #endif

 #ifdef USE_NETWORK
-  char readBuffer[13];
-  char headerBuffer[10];
-  char sendBuffer[160];
+  char
+    readBuffer[13],
+    headerBuffer[10],
+    sendBuffer[128];
 #endif

 #ifdef USE_STROMBEWUSST_SERVER
@@ -115,8 +118,7 @@
   lastHour = 0xFF;

 unsigned long
-  storageRuntime = 0,
-  lastTrigger = 0;
+  storageRuntime = 0;

 unsigned int
   storagePointer = 0,
@@ -373,8 +375,8 @@
 void xs1Push()
 {
   IPAddress ip XS1_IP;
-  String url = XS1_URL;
-  url += calculateWatt(XS1_TIMEFRAME);
+  char url[100];
+  sprintf(url, "%s%i", F(XS1_URL), calculateWatt(XS1_TIMEFRAME));

   if (networkRequestIP(ip, url))
   {
@@ -387,16 +389,16 @@
 #endif

 #ifdef USE_NETWORK
-bool networkRequestIP(IPAddress ip, String url)
+bool networkRequestIP(IPAddress ip, char* url)
 {
   Serial.print(F("[network] HTTP request "));
   Serial.println(url);

-
   if (client.connect(ip, 80))
   {
-    String request = "GET "+url+" HTTP/1.0\r\nConnection: close\r\n\r\n";
-    client.print(request);
+    sprintf(sendBuffer, "GET %s HTTP/1.0", url);
+    client.println(sendBuffer);
+    client.println(F("Connection: close\r\n"));
     return true;
   } else
   {


Add main func to stop build from breaking on akira

--- interduino/src/sketch.ino
+++ interduino/src/sketch.ino
@@ -22,3 +22,12 @@
 		}
 	}
 }
+
+int main()
+{
+  setup();
+  while(true) {
+    loop();
+  }
+  return 0;
+}


Remove useless delay.

Remove useless delay.

--- linefollow/linefollow.ino
+++ linefollow/linefollow.ino
@@ -92,8 +92,6 @@
   driveRightForward(rightSpeed);
   driveLeftForward(leftSpeed);

-  delay(0);  // add a delay to decrease sensitivity.
-
   Serial.print(leftReading);
   Serial.print("\t");  // tab character
   Serial.print(centerReading);


Bugfix in sensor detection if sensor is not present

--- esp32LightServerRGB.ino
+++ esp32LightServerRGB.ino
@@ -246,7 +246,7 @@
   Serial.println(attendF);
   Serial.print("Fois - ");
   Serial.println(flashfois / 2);
-  if (attendF == 0){
+  if (attendF == 0) {
     flashfois = 0;
   }
   if (testteu != 0) {
@@ -1142,7 +1142,7 @@
   resetpass = preferences.getString("resetpass", "admin");
   thingkey = preferences.getString("thingkey", "none");
   thingchanel = preferences.getString("thingchanel", "none");
-  xTaskCreatePinnedToCore(loop1, "loop1", 4096, NULL, 10, NULL, 0);
+  xTaskCreatePinnedToCore(loop1, "loop1", 4096, NULL, 3, NULL, 0);
   lesliens();
   WiFiManager wifiManager;
   wifiManager.setTimeout(240);
@@ -1153,7 +1153,24 @@
     ESP.restart();
     delay(5000);
   }
-  delay(3000);
+  if (!sensors.getAddress(insideThermometer, 0)) {
+    int ereur = 0;
+    int marchetu = 1;
+    do { // 5 retry
+      ereur++;
+      Serial.print("Erreur senseur 0 essai #");
+      Serial.println(ereur);
+      delay(200);
+      if (sensors.getAddress(insideThermometer, 0)) {
+        ereur = 5;
+        marchetu = 0;
+      }
+    } while (ereur <= 5);
+    if (marchetu != 0) {
+      Serial.println("Erreure senseurs 0 non fonctionnel !");
+    }
+  }
+  sensors.setResolution(insideThermometer, 12);// 9 ou 12 9 plus rapide mais moin préçis
   MDNS.begin("lumiere");
   server.on("/", handleRoot);
   server.on("/setup", handleSetup);
@@ -1200,7 +1217,7 @@
                 "Added User-Agernt information in logging and serial output of / and 404 not found page\n
"
                 "Fixed Bonjour service support you can now use ( http://lumiere.local ) if you have Bonjour V3 installed\n

"
                 "Moved fading to it's own core and loop
\n"
-                "Cleaned CSS and changed color selector to match buttons" + liens);
+                "Cleaned CSS and changed color selector to match buttons
\n" + liens);
     Serial.println("");
     Serial.println(addy);
     Serial.println("Page de Version");
@@ -1214,29 +1231,7 @@
   server.collectHeaders(headerkeys, headerkeyssize );
   server.begin();
   Serial.println("Serveur web démaré");
-  delay(500);
   MDNS.addService("_http", "_tcp", 80);
-  if (!sensors.getAddress(insideThermometer, 0)) {
-    int ereur;
-    int marchetu;
-    while (ereur != 5) { // 5 retry
-      ereur++;
-      Serial.print("Erreur senseur 0 essai #");
-      Serial.println(ereur);
-      delay(200);
-      if (!sensors.getAddress(insideThermometer, 0)) {
-        marchetu = 1;
-      } else {
-        ereur = 5;
-        marchetu = 0;
-      }
-    }
-    if (marchetu != 0) {
-      Serial.println("Erreure senseurs 0 non fonctionnel !");
-    } else {
-      sensors.setResolution(insideThermometer, 12);// 9 ou 12 9 plus rapide mais moin préçis
-    }
-  }
 }

 void loop() {


Add compiler directives

Add compiler directives

Chop out lots of code to fit into T84
I have been ruthless - perhaps gone too far.

--- examples/RF12/RF12demo/RF12demo.ino
+++ examples/RF12/RF12demo/RF12demo.ino
@@ -6,18 +6,19 @@
 // Adding frequency features. 2013-09-05 JohnOH
 #include <JeeLib.h>
 #include <util/crc16.h>
-#include <util/parity.h>
 #include <avr/eeprom.h>
 #include <avr/pgmspace.h>
+#include <util/parity.h>

 // ATtiny's only support outbound serial @ 38400 baud, and no DataFlash logging

-#if defined(__AVR_ATtiny84__) ||defined(__AVR_ATtiny44__)
+#if defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny44__)
 #define SERIAL_BAUD 38400
 #else
 #define SERIAL_BAUD 57600

-#define DATAFLASH 1 // check for presence of DataFlash memory on JeeLink
+#define DATAFLASH 0          // Enabling flash for none flash equipped nodes causes odd problems - particularly non-Jee kit
+// check for presence of DataFlash memory on JeeLink
 #define FLASH_MBIT  16  // support for various dataflash sizes: 4/8/16 Mbit

 #define LED_PIN   9 // activity LED, comment out to disable
@@ -127,6 +128,7 @@
    return band == 4 ? RF12_433MHZ : band == 8 ? RF12_868MHZ : band == 9 ? RF12_915MHZ : 0;
 }

+#if not defined(__AVR_ATtiny84__) || not defined(__AVR_ATtiny44__)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // OOK transmit code

@@ -179,7 +181,7 @@
     delay(11); // approximate
   }
 }
-
+#endif
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 // DataFlash code

@@ -549,8 +551,9 @@
 #define df_replay(x,y)
 #define df_erase(x)

-#endif
-
+#endif
+
+#if not defined(__AVR_ATtiny84__) || not defined(__AVR_ATtiny44__)
 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

 const char helpText1[] PROGMEM =
@@ -558,8 +561,8 @@
   "Available commands:" "\n"
   "  <nn> i     - set node ID (standard node ids are 1..30)" "\n"
   "  <n> b      - set MHz band (4 = 433, 8 = 868, 9 = 915)" "\n"
-  "  <nnn> o    - Change frequency offset within the frequency band above" "\n"
-  "               values above 99 are sticky for reuse, 255 changes direction" "\n"
+  "  <nnn> o    - Change frequency offset within the band above" "\n"
+  "               values > 99 are sticky, 255 changes direction" "\n"
   "  <nnn> g    - set network group (RFM12 only allows 212, 0 = any)" "\n"
   "  <n> c      - set collect mode (advanced, normally 0)" "\n"
   "  t          - broadcast max-size test packet, request ack" "\n"
@@ -573,6 +576,9 @@
   "  <hchi>,<hclo>,<addr>,<cmd> f     - FS20 command (868 MHz)" "\n"
   "  <addr>,<dev>,<on> k              - KAKU command (433 MHz)" "\n"
 ;
+#endif
+
+#if DATAFLASH
 const char helpText2[] PROGMEM =
   "Flash storage (JeeLink only):" "\n"
   "  d                                - dump all log markers" "\n"
@@ -580,7 +586,8 @@
   "  123,<bhi>,<blo> e                - erase 4K block" "\n"
   "  12,34 w                          - wipe entire flash memory" "\n"
 ;
-
+#endif
+#if not defined(__AVR_ATtiny84__) || not defined(__AVR_ATtiny44__)
 static void showString (PGM_P s) {
   for (;;) {
     char c = pgm_read_byte(s++);
@@ -591,14 +598,19 @@
     Serial.print(c);
   }
 }
-
+#endif
+
+#if not defined(__AVR_ATtiny84__) || not defined(__AVR_ATtiny44__)
 static void showHelp () {
-  if (!quiet) {
     showString(helpText1);
+#endif
+#if DATAFLASH
     if (df_present())
       showString(helpText2);
+#endif
+#if not defined(__AVR_ATtiny84__) || not defined(__AVR_ATtiny44__)
     Serial.println("Current configuration:");
-  }
+#endif
     rf12_config();
 }

@@ -673,7 +685,11 @@
         break;
       case 't': // broadcast a maximum size test packet, request an ack
         cmd = 'a';
+#if not defined(__AVR_ATtiny84__) || not defined(__AVR_ATtiny44__)
         sendLen = RF12_MAXDATA;
+#else
+        sendLen = 16;    // Conserve RAM
+#endif
         dest = 0;
         for (byte i = 0; i < RF12_MAXDATA; ++i)
           testbuf[i] = i + testCounter;
@@ -691,6 +707,7 @@
       case 'l': // turn activity LED on or off
         activityLed(value);
         break;
+#if not defined(__AVR_ATtiny84__) || not defined(__AVR_ATtiny44__)
       case 'f': // send FS20 command: <hchi>,<hclo>,<addr>,<cmd>f
         rf12_initialize(0, RF12_868MHZ, 0);
         activityLed(1);
@@ -729,9 +746,6 @@
           Serial.println("erased");
         }
         break;
-      case 'q': // turn quiet mode on or off (don't report bad packets)
-        quiet = value;
-        break;
       case 'z': // put the ATmega in ultra-low power mode (reset needed)
         if (value == 123) {
           delay(10);
@@ -739,6 +753,10 @@
           cli();
           Sleepy::powerDown();
         }
+        break;
+#endif
+        case 'q': // turn quiet mode on or off (don't report bad packets)
+        quiet = value;
         break;
       case 'x': // set reporting mode to hex (1) or decimal (0)
         useHex = value;
@@ -764,7 +782,7 @@
 }

 void displayVersion(uint8_t newline ) {
-  Serial.print("\n[RF12demo.11]");
+  Serial.print("\n[RF12demo.11] ");  // Extra space on the end to replace byte pinched from EEProm byte 0
   if(newline!=0)  Serial.println();

 }
@@ -787,9 +805,12 @@
     saveConfig();
   }

+#if DATAFLASH
   df_initialize();
-
+#endif
+#if not defined(__AVR_ATtiny84__) || not defined(__AVR_ATtiny44__)
   showHelp();
+#endif
 }

 void loop() {
@@ -830,10 +851,10 @@

     if (rf12_crc == 0) {
       activityLed(1);
-
+#if not defined(__AVR_ATtiny84__) || not defined(__AVR_ATtiny44__)
       if (df_present())
         df_append((const char*) rf12_data - 2, rf12_len + 2);
-
+#endif
       if (RF12_WANTS_ACK && (config.nodeId & COLLECT) == 0) {
         Serial.println(" -> ack");
         rf12_sendStart(RF12_ACK_REPLY, 0, 0);


Update Mimic_LED_Controller.ino

Update Mimic_LED_Controller.ino

Commenting Neopixel control code for IEA status LEDs, Closes #277

--- Arduino/Mimic_LED_Controller/Mimic_LED_Controller.ino
+++ Arduino/Mimic_LED_Controller/Mimic_LED_Controller.ino
@@ -153,8 +153,12 @@
     allSet_module(moduleLED.Color(0,0,0),0);
   }
   moduleLED.show();
+
+  //if array voltage is under 151.5V, assume batteries are discharging and set LEDs to Red - note, the 151.5V value is not fixed and varies depending on array. might need tweaking
+  //if array voltage is 160V, assume batteries are fully charged and set LEDs to White
+  //if array voltage is between those values, assume batteries are being charged by the arrays and set LEDs to Blue

-  if(V2A < 151.5)
+  if(V2A < 151.5)
   {
     portIEA.setPixelColor(0, portIEA.Color(255,0,0));
     portIEA.setPixelColor(1, portIEA.Color(255,0,0));


Have push button reading, and have RGB LED color setting working

--- oven.ino
+++ oven.ino
@@ -1,40 +1,36 @@
-/* Serial 7-Segment Display Example Code
-    I2C 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 the Arduino Wire
-   library to interface with a Serial 7-Segment Display.
-
-   There are example functions for setting the display's
-   brightness, decimals, clearing the display, and sending a
-   series of bytes via I2C.
-
-   Each I2C transfer begins with a Wire.beginTransmission(address)
-   where address is the 7-bit address of the device set to
-   receive the data. Wire.write() sends a byte of data. I2C
-   communication is closed with Wire.endTransmission().
-
-   Circuit:
-   Arduino -------------- Serial 7-Segment
-     5V   --------------------  VCC
-     GND  --------------------  GND
-     SDA  --------------------  SDA (A4 on older 'duino's)
-     SCL  --------------------  SCL (A5 on older 'duino's)
-*/
+/* Matthew's Microwave Oven
+ */
 #include <Wire.h> // Include the Arduino SPI library

-// Here we'll define the I2C address of our S7S. By default it
-//  should be 0x71. This can be changed, though.
+// I2C address of our S7S
 const byte s7sAddress = 0x71;
+
+// Pin number the push button is connected to
+const int buttonPin = 2;
+
+// Somewhere to store the state of the button
+int buttonState = 0;
+
+// Pin numbers for the RGB LEB
+const int ledRedPin = 9;
+const int ledGreenPin = 10;
+const int ledBluePin = 11;

 unsigned int counter = 9900;  // This variable will count up to 65k
 char tempString[10];  // Will be used with sprintf to create strings

 void setup()
 {
+  Serial.begin(9600);
+
+  // Enable push button
+  pinMode(buttonPin, INPUT);
+
+  // Set the RGB LEB pins as output
+  pinMode(ledRedPin, OUTPUT);
+  pinMode(ledGreenPin, OUTPUT);
+  pinMode(ledBluePin, OUTPUT);
+
   Wire.begin();  // Initialize hardware I2C pins

   // Clear the display, and then turn on all segments and decimals
@@ -44,8 +40,12 @@
   //  The I2C.write function only allows sending of a single
   //  byte at a time.
   s7sSendStringI2C("-HI-");
+  delay(1500);
+  s7sSendStringI2C("HELO");
+  delay(1500);
   setDecimalsI2C(0b111111);  // Turn on all decimals, colon, apos

+  delay(1500);
   // Flash brightness values at the beginning
   setBrightnessI2C(0);  // Lowest brightness
   delay(1500);
@@ -58,6 +58,15 @@

 void loop()
 {
+  // Read the state of the button
+  buttonState = digitalRead(buttonPin);
+  if (buttonState == LOW) {
+    Serial.println("Button pushed ON");
+    setColor(255, 0, 0);
+  } else {
+    setColor(0, 255, 0);
+  }
+
   // Magical sprintf creates a string for us to send to the s7s.
   //  The %4d option creates a 4-digit integer.
   sprintf(tempString, "%4d", counter);
@@ -73,6 +82,14 @@

   counter++;  // Increment the counter
   delay(100);  // This will make the display update at 10Hz.*/
+}
+
+// Sets the color of the RGB LEB
+void setColor(int red, int green, int blue)
+{
+  analogWrite(ledRedPin, red);
+  analogWrite(ledGreenPin, green);
+  analogWrite(ledBluePin, blue);
 }

 // This custom function works somewhat like a serial.print.


Chassis_Control.ino i2C address change

Chassis_Control.ino i2C address change

Changed the i2C address of the Chassis arduino so that it is
compatible with our computer's i2C bus.

--- tests/drive-test/Chassis_Control/Chassis_Control.ino
+++ tests/drive-test/Chassis_Control/Chassis_Control.ino
@@ -7,7 +7,7 @@
 #include "C:\Users\Taylor\Documents\Arduino\libraries\ChassisData.h"

 #ifndef I2C_ADDRESS
-#define I2C_ADDRESS  1
+#define I2C_ADDRESS  5
 #endif

 //Packet size of ChassisData object in bytes


Update Bridge.ino

Update Bridge.ino

--- examples/Widgets/Bridge/Bridge.ino
+++ examples/Widgets/Bridge/Bridge.ino
@@ -14,9 +14,12 @@
  *
  **************************************************************
  * Control another device using Bridge widget!
- *
- * App dashboard setup:
- *   Bridge widget on V1
+ *
+ * Bridge is initialized with the token of any (Blynk-enabled) device.
+ * After that, use the familiar functions to control it:
+ *   bridge.digitalWrite(8, HIGH)
+ *   bridge.analogWrite(3, 123)
+ *   bridge.virtualWrite(1, "hello")
  *
  **************************************************************/


Flight time numbers moved to constants

Flight time numbers moved to constants

--- examples/quadcopter/quadcopter.ino
+++ examples/quadcopter/quadcopter.ino
@@ -8,6 +8,11 @@
                    RADIO_YAW   = 3, RADIO_GEAR = 4, RADIO_AUX      = 5 };
 const uint8_t CHANNEL_TRIGGER_MIN = 32;
 const uint8_t CHANNEL_TRIGGER_MAX = 148;
+
+// Time constants in milliseconds
+const uint32_t ARMING_TIME = 2000;
+const uint32_t CALIBRATING_TIME = 2000;
+const uint32_t DISARMING_TIME = 750;

 // State timer used to detect ARMING
 StateTimer radioDownRight([](){
@@ -31,7 +36,7 @@
 // Flight State variables
 boolean altHold = false;
 float yawTarget = 0.0;
-uint32_t calStartTime;
+auto calibrateEndTimer = Interval::elapsed(0);

 // Temporary test variables
 uint32_t loopstart;
@@ -55,16 +60,15 @@
     //always running updates
     loopQuad();
     sendTelemetry();
-
     //flight mode state machine
     switch(state){
         /*#DISARMED Hold Down and to the right on
          * the Throttle stick for two seconds to begin the arming process
         **/
         case DISARMED:
-            if(radioDownRight.trueFor(2000)) {
+            if(radioDownRight.trueFor(ARMING_TIME)) {
                 if(safe()){
-                    calStartTime = millis();
+                    calibrateEndTimer = Interval::elapsed(CALIBRATING_TIME);
                     setState(CALIBRATE);
                 } else {
                     /*#NOFLY Flight aborted due to error status */
@@ -77,7 +81,7 @@
         **/
         case CALIBRATE:
             orientation.calibrate(true);
-            if(calStartTime + 2000 < millis()) {
+            if(calibrateEndTimer()) {
                 orientation.calibrate(false);
                 yawTarget = orientation.getYaw();
                 altitudeCalcInit();
@@ -90,7 +94,7 @@
         **/
         case FLYING:
             fly();
-            if(radioDownLeft.trueFor(750)) {
+            if(radioDownLeft.trueFor(DISARMING_TIME)) {
                 output.disable();
                 setState(DISARMED);
             }


config safety for termtype entries

config safety for termtype entries

git-svn-id: d8bfcd070c2c81762cca1b3912331324182919ba@19309 0d6f1817-ed0e-0410-87c9-987e46238f29

--- zimodem/zcommand.ino
+++ zimodem/zcommand.ino
@@ -2536,6 +2536,7 @@
                     else
                     {
                       termType = eq;
+                      termType.replace(',','.');
                       result=ZOK;
                     }
                     break;


fixed writing to sd card

fixed writing to sd card

--- sensebox/sensebox.ino
+++ sensebox/sensebox.ino
@@ -15,7 +15,6 @@
 //Barometer variables
 float pressure;
 float atm;
-float altitude;
 Barometer myBarometer;

 //Accelerometer variables
@@ -57,7 +56,7 @@
   Wire.begin();
   //Initialize Accelerometer
   accelgyro.initialize();
-  Serial.println(accelgyro.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
+  //Serial.println(accelgyro.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

   delay(1000);

@@ -67,7 +66,6 @@
   //Init barometer
   myBarometer.init();

-
   // Initalize SD card:
   //Serial.print("init sd card...");

@@ -89,7 +87,7 @@
   // If the file opened okay, write to it:
   if (dataFile) {
     //Serial.print("Writing to test.txt...");
-    dataFile.println("Logging: row, lat, lon, time, sound, brightness, vibration, pressure.");
+    dataFile.println("Logging: row, lat, lon, time, sound, brightness, vibration, altitude.");
     // close the file:
     dataFile.close();
     //Serial.println("done.");
@@ -111,7 +109,6 @@
       //Serial.print(buttonPushCounter);

     } else {
-      Serial.println(F("OFF"));
     }
     delay(50);
   }
@@ -220,21 +217,23 @@
         dataFile.print(seperator);
         dataFile.print((abs(Axyz[0]) + abs(Axyz[1]) + abs(Axyz[2])), 2);
         dataFile.print(seperator);
-        dataFile.print(myBarometer.calcAltitude(myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP())));
+        dataFile.println(myBarometer.calcAltitude(myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP())));

         // close the file:
         dataFile.close();

         rowCounter = rowCounter + 1;
-        //Serial.println(F("done writing."));
+        Serial.println(F("done writing."));
       } else {
         // if the file didn't open, print an error:
-        //Serial.println(F("error opening file"));
+        Serial.println(F("error opening file"));
       }

     }
   } else {
     digitalWrite(LED, LOW);   // turn the LED on (HIGH is the voltage level)
+    Serial.println(F("OFF"));
+
   }

 }


Fix typo (#317)

Fix typo (#317)

* fix typo

--- examples/IRrecvDump/IRrecvDump.ino
+++ examples/IRrecvDump/IRrecvDump.ino
@@ -92,7 +92,7 @@
       Serial.print((uint32_t) results->rawbuf[i] * RAWTICK, DEC);
     }
   }
-  Serial.println("};")
+  Serial.println("};");
 }

 void loop() {


Removed Atm_teensywav example as well

Removed Atm_teensywav example as well

--- examples/teensywave/teensywave.ino
+++ examples/teensywave/teensywave.ino
@@ -1,33 +0,0 @@
-#include <Automaton.h>
-#include <Atm_teensywave.h>
-#include <Atm_button.h>
-
-// A state machine generates simple waveforms on Teensy 3.1/LC (which has true analog out)
-// Attach a button to pin 11 to cycle thru SINE (SN) > SAW (SW) > SAW REVERSE (SR) > TRIANGLE (TR) > SQUARE (SQ)
-
-int pinOut = A14; // Teensy 3.1 analog output pin (LC uses A12)
-int pinIn = 11;   // Button attached to pin 11 (pullup)
-
-Atm_teensywave wave;
-Atm_button btn;
-Factory factory;
-
-void btnHandler( int press ) {
-  if ( press ) {
-    wave.trigger( wave.EVT_TOGGLE );
-  }
-}
-
-void setup()
-{
-  // 314 steps, 50 usec period, start machine in SN (Sine Wave) state
-  wave.begin( pinOut, 314, 50 );
-  btn.begin( pinIn, btnHandler ).autoPress( 10000, 1 );
-  factory.add( wave ).add( btn );
-  wave.trigger( wave.EVT_TOGGLE );
-}
-
-void loop()
-{
-  factory.cycle();
-}


Delete BitBeacon.ino

Delete BitBeacon.ino

--- BitBeacon/BitBeacon.ino
+++ BitBeacon/BitBeacon.ino
@@ -1,186 +0,0 @@
-const uint8_t north = A0;
-const uint8_t east = A1;
-const uint8_t south = A2;
-const uint8_t west = A3;
-
-int nVal = 0;
-int eVal = 0;
-int sVal = 0;
-int wVal = 0;
-
-int n = 0;
-int e = 1;
-int s = 2;
-int w = 3;
-const int arr_size = 4;
-
-int sensorVals[arr_size] = {0};
-
-int n_base = 0;
-int e_base = 0;
-int s_base = 0;
-int w_base = 0;
-
-uint8_t interrupt = 2;
-
-void setup()
-{
-  //analogReference(EXTERNAL);
-  Serial.begin(115200);
-
-  delay(1000);
-
-  n_base = analogRead(north) - 50;
-  e_base = analogRead(east) - 50;
-  s_base = analogRead(south) - 50;
-  w_base = analogRead(west) - 50;
-
-  Serial.println(n_base);
-  Serial.println(e_base);
-  Serial.println(s_base);
-  Serial.println(w_base);
-}
-
-
-void readSensors()
-{
-  int north_intensity = analogRead(north);
-  int east_intensity = analogRead(east);
-  int south_intensity = analogRead(south);
-  int west_intensity = analogRead(west);
-
-  nVal = north_intensity - n_base;
-  eVal = east_intensity - e_base;
-  sVal = south_intensity - s_base;
-  wVal = west_intensity - w_base;
-
-  //sensorVals[0] = {nVal, eVal, sVal, wVal};
-  sensorVals[n] = nVal;
-  sensorVals[e] = eVal;
-  sensorVals[s] = sVal;
-  sensorVals[w] = wVal;
-}
-
-
-void printSensors()
-{
-  Serial.print("north: ");
-  Serial.print(nVal);
-  Serial.print(", ");
-
-  Serial.print("east: ");
-  Serial.print(eVal);
-  Serial.print(", ");
-
-  Serial.print("south: ");
-  Serial.print(sVal);
-  Serial.print(", ");
-
-  Serial.print("west: ");
-  Serial.println(wVal);
-}
-
-
-void loop()
-{
-  readSensors();
-  printSensors();
-  determineDirection();
-  Serial.println();
-  delay(500);
-}
-
-
-
-void determineDirection()
-{
-  //check to see which direction has highest value
-  //check to see which direction is second
-  //check to see which direction is third
-
-  if ((sensorVals[n]*.6) > sensorVals[w] && (sensorVals[n]*.6) > sensorVals[e])
-  {
-    if (abs(sensorVals[w]-sensorVals[e]) < 50)
-    {
-      Serial.println("head north");
-    }
-    else if (sensorVals[w]*1.2 >= sensorVals[e]*1.2)
-    {
-      Serial.println("head north-west");
-    }
-    else if (sensorVals[e]*1.2 >= sensorVals[w]*1.2)
-    {
-      Serial.println("head north-east");
-    }
-    else
-    {
-      Serial.println("no direction or continue moving along last direction");
-      //some error
-    }
-  }
-  else if ((sensorVals[e]*.6) > sensorVals[n] && (sensorVals[e]*.6) > sensorVals[s])
-  {
-    if (abs(sensorVals[n]-sensorVals[s]) < 50)
-    {
-      Serial.println("head east");
-    }
-    else if (sensorVals[n]*1.2 >= sensorVals[s]*1.2)
-    {
-      Serial.println("head east-north-east");
-    }
-    else if (sensorVals[s]*1.2 >= sensorVals[n]*1.2)
-    {
-      Serial.println("head east-south-east");
-    }
-    else
-    {
-      Serial.println("no direction or continue moving along last direction");
-      //some error
-    }
-  }
-  else if ((sensorVals[w]*.6) > sensorVals[n] && (sensorVals[w]*.6) > sensorVals[s])
-  {
-    if (abs(sensorVals[n]-sensorVals[s]) < 50)
-    {
-      Serial.println("head west");
-    }
-    else if (sensorVals[n]*1.2 >= sensorVals[s]*1.2)
-    {
-      Serial.println("head west-north-west");
-    }
-    else if (sensorVals[s]*1.2 >= sensorVals[n]*1.2)
-    {
-      Serial.println("head west-south-west");
-    }
-    else
-    {
-      Serial.println("no direction or continue moving along last direction");
-      //some error
-    }
-  }
-  else if ((sensorVals[s]*.6) > sensorVals[w] && (sensorVals[s]*.6) > sensorVals[e])
-  {
-    if (abs(sensorVals[w]-sensorVals[e]) < 50)
-    {
-      Serial.println("head south");
-    }
-    else if (sensorVals[w]*1.2 >= sensorVals[e]*1.2)
-    {
-      Serial.println("head south-west");
-    }
-    else if (sensorVals[e]*1.2 >= sensorVals[w]*1.2)
-    {
-      Serial.println("head south-east");
-    }
-    else
-    {
-      Serial.println("no direction or continue moving along last direction");
-      //some error
-    }
-  }
-  else
-  {
-    Serial.println("got no where");
-  }
-}
-


Modified test sketch to test full range of options

--- L9110_hbridge/L9110_libtest/L9110_libtest.ino
+++ L9110_hbridge/L9110_libtest/L9110_libtest.ino
@@ -10,7 +10,20 @@

 void loop()
 {
-  L9110.motorA(1,255);
+  L9110.motorA(1,255); //run both motors forward at full speed
   L9110.motorB(1,255);
+  delay(5000);
+  L9110.motorA(0,255); //run both motors backward at full speed
+  L9110.motorB(0,255);
+  delay(5000);
+  L9110.motorA(1,127); //run both motors forward at half speed
+  L9110.motorB(1,127);
+  delay(5000);
+  L9110.motorA(1,127); //run motors at half speed in opposite directions
+  L9110.motorB(0,127);
+  delay(5000);
+  L9110.motorA(0,0); //full stop on both motors
+  L9110.motorB(0,0);
+  delay(3000);
 }


Fixed an ifdef-bug in NOKO_EEPROM_Disk0

Fixed an ifdef-bug in NOKO_EEPROM_Disk0

--- src/NOKO_EEPROM_Disk0/NOKO_EEPROM_Disk0.ino
+++ src/NOKO_EEPROM_Disk0/NOKO_EEPROM_Disk0.ino
@@ -194,7 +194,7 @@
     // delay(30);
     addr++;
   #else
-    while(1)
+    while(1);
   #endif
 }


git-svn-id: svn://192.168.1.10/public/Zimodem@14521 0d6f1817-ed0e-0410-87c9-987e46238f29

--- zimodem/zcommand.ino
+++ zimodem/zcommand.ino
@@ -277,7 +277,6 @@

 ZResult ZCommand::doDialStreamCommand(int vval, uint8_t *vbuf, int vlen, bool isNumber,const char *dmodifiers)
 {
-Serial.printf("Stream %d %s %d %d %s\n\r",vval,vbuf,vlen,isNumber,dmodifiers);
   bool doPETSCII = (strchr(dmodifiers,'P')!=null)||(strchr(dmodifiers,'p')!=null);
   bool doTelnet = (strchr(dmodifiers,'T')!=null)||(strchr(dmodifiers,'t')!=null);
   if(vlen == 0)
@@ -293,13 +292,11 @@
   else
   if((vval >= 0)&&(isNumber))
   {
-Serial.printf("VVal %d %d\n\r",vval,isNumber);
     WiFiClientNode *c=conns;
     while((c!=null)&&(c->id != vval))
       c=c->next;
     if((c!=null)&&(c->id == vval)&&(c->isConnected()))
     {
-Serial.printf("Switching to serial mode on %d\n\r",c->id);
       streamMode.reset(c,false,doPETSCII,doTelnet);
       currMode=&streamMode;
     }


added serial communication

added serial communication

--- DeskChair/desk/desk.ino
+++ DeskChair/desk/desk.ino
@@ -1,3 +1,5 @@
+#include <motor.h>
+

@@ -6,6 +8,8 @@
   Memorise one position
   There's 4 different motors on the chair and each one has one position
  */
+
+

 //-------------------Motors-------------------

@@ -40,6 +44,7 @@
 //-------------------Misc-------------------

+const int baudrate = 9600;
 const int MARGIN_MOTOR = 20 ;

 int position_pot = 0 ;
@@ -58,8 +63,25 @@
 Motor motor4(MOTOR4_BACK,MOTOR4_FORWARD,POTENTIOMETER4,MARGIN_MOTOR) ;

-// the setup routine runs once when you press reset:
-void setup() {
+
+//-------------------Help functions-------------------
+
+boolean is_a_number(int n)
+{
+  return n >= 48 && n <= 57;
+}
+
+int ascii2int(int n, int byte_read)
+{
+  return n*10 + (byte_read - 48);
+}
+
+
+//-------------------Setup routine-------------------
+
+void setup() {
+
+  Serial.begin(baudrate);
   // // initialize the digital pin as an output.
   // pinMode(MOTOR_BACK, OUTPUT);
   // pinMode(MOTOR_FORWARD, OUTPUT);
@@ -69,23 +91,60 @@

 }

-// the loop routine runs over and over again forever:
+//-------------------Loop-------------------
+
 void loop() {

-  if (digitalRead(BUTTON_MEM) == HIGH) {
-    memory_state1 = analogRead(POTENTIOMETER1) ;
-    memory_state2 = analogRead(POTENTIOMETER2) ;
-    memory_state3 = analogRead(POTENTIOMETER3) ;
-    memory_state4 = analogRead(POTENTIOMETER4) ;
-  }
-
-  if (digitalRead(BUTTON_SET) == HIGH) {
-
-    motor1.move_to(memory_state1);
-    motor2.move_to(memory_state2);
-    motor3.move_to(memory_state3);
-    motor4.move_to(memory_state4);
-
+  //while ( !Serial.available() );
+  while (Serial.available() > 0) {
+    int serial_read = Serial.parseInt();
+    if(serial_read==1){
+
+   // if (digitalRead(BUTTON_MEM) == HIGH) {
+      memory_state1 = analogRead(POTENTIOMETER1) ;
+      memory_state2 = analogRead(POTENTIOMETER2) ;
+      memory_state3 = analogRead(POTENTIOMETER3) ;
+      memory_state4 = analogRead(POTENTIOMETER4) ;
+
+      Serial.println("memory_state1");
+      Serial.println(memory_state1);
+      Serial.println("memory_state2");
+      Serial.println(memory_state2);
+      Serial.println("memory_state3");
+      Serial.println(memory_state3);
+      Serial.println("memory_state4");
+      Serial.println(memory_state4);
+
+      delay(500);
+    }
+    else if(serial_read==2){
+
+   // if (digitalRead(BUTTON_SET) == HIGH) {
+
+     Serial.println("Moving to selected position : ");
+    while (Serial.available() < 1) ;
+      memory_state1 = Serial.parseInt();
+      memory_state2 = Serial.parseInt();
+      memory_state3 = Serial.parseInt();
+      memory_state4 = Serial.parseInt();
+     // motor1.move_to(memory_state1);
+     // motor2.move_to(memory_state2);
+     // motor3.move_to(memory_state3);
+     // motor4.move_to(memory_state4);
+
+     Serial.println("Moving to selected position : ");
+
+     Serial.println("memory_state1");
+      Serial.println(memory_state1);
+      Serial.println("memory_state2");
+      Serial.println(memory_state2);
+      Serial.println("memory_state3");
+      Serial.println(memory_state3);
+      Serial.println("memory_state4");
+      Serial.println(memory_state4);
+
+
+    }
   }
 }


pid_update

--- drone_control/drone_control.ino
+++ drone_control/drone_control.ino
@@ -3,6 +3,7 @@
  */
 #include <Adafruit_L3GD20.h>
 #include <Servo.h>
+#include <PID_v1.h>
 #include "drone_common.h"

 typedef unsigned long ulong;
@@ -23,6 +24,17 @@
 ulong TimeSinceStart;
 ulong TimeDelta;
 bool ManualControl;
+
+double SetYaw, IputYaw, OputYaw;
+double SetRoll, IputRoll, OputRoll;
+double SetPitch, IputPitch, OputPitch;
+double SetThro, IputThro, OputThro;
+
+PID YawPid(&IputYaw, &OputYaw, &SetYaw,5,10,10,DIRECT);
+PID RollPid(&IputRoll, &OputRoll, &SetRoll,5,10,10,DIRECT);
+PID PitchPid(&IputPitch, &OputPitch, &SetPitch,5,10,10,DIRECT);
+PID ThroPid(&IputThro, &OputThro, &SetThro,5,10,10,DIRECT);
+

 Adafruit_L3GD20 gyro;

@@ -68,6 +80,14 @@

 void setup() {
   Serial.begin(9600);
+
+  /*set up PID */
+  YawPid.SetOutputLimits(0,360);// return in degree
+  PitchPid.SetOutputLimits(0,360);
+  RollPid.SetOutputLimits(0,360);
+  ThroPid.SetOutputLimits(1000,2000);//limit max thro output to
+  /*end set up PID*/
+
 #ifdef TEST_CONTROLS
   ManualControl = true;
 #else
@@ -115,10 +135,20 @@
     const int CONTROLLER_MIN = 0;

     ControllerInput Input = GetControllerInput();
-    int Throttle = Input.Throttle;
-    int Roll     = Input.Roll;
-    int Pitch    = Input.Pitch;
-    int Yaw      = Input.Yaw;
+    IputThro = Input.Throttle;
+    IputRoll = Input.Roll;
+    IputPitch    = Input.Pitch;
+    IputYaw      = Input.Yaw;
+
+    YawPid.Compute();
+    PitchPid.Compute();
+    RollPid.Compute();
+    ThroPid.Compute();
+
+    int Yaw=OputYaw;
+    int Roll=OputRoll;
+    int Pitch=OputPitch;
+    int Throttle=OputThro;

     Throttle = map(Throttle, CONTROLLER_MIN, CONTROLLER_MAX, SERVO_OFF, SERVO_FULL);
     Roll     = map(Roll,     CONTROLLER_MIN, CONTROLLER_MAX, SERVO_OFF, SERVO_FULL);


Removed comments, changed startcolor and fadeup time

--- RGB_lamps/RGB_lamps.ino
+++ RGB_lamps/RGB_lamps.ino
@@ -30,7 +30,7 @@
   setColors();

   for (int lamp = 0; lamp < 4; lamp++) {
-    lamps[lamp].fade(3000, dayCols[10]);
+    lamps[lamp].fade(2000, dayCols[10]);
   }
 }

@@ -56,7 +56,6 @@
 void controller() {
   // Read controll data from the serial port to decide what to do with the lamps
   if(Serial.available() > 0) {
-    delay(100);

     // Setup variables for control
     unsigned char ctrl = Serial.read();
@@ -71,7 +70,7 @@

     if (ctrl == 0) {
       // Set color for lamp(s)
-      Serial.println("Set Color");
+      //Serial.println("Set Color");
       char cols[3];
       Serial.readBytes(cols,3);

@@ -96,12 +95,12 @@
       for(int i = 0; i < 3; i++) {
         col[i] = col[i] < 0 ? col[i] + 256 : col[i];
       }
-      Serial.print("Fade Color:");
+      /*Serial.print("Fade Color:");
       Serial.print(col[0]);
       Serial.print("-");
       Serial.print(col[1]);
       Serial.print("-");
-      Serial.println(col[2]);
+      Serial.println(col[2]);*/
       int fade_time = cols[3];

       if (selected_lamp < 4) {
@@ -189,8 +188,8 @@

   // Candle
   dayCols[10][0] = 255;
-  dayCols[10][1] = 147;
-  dayCols[10][2] = 41;
+  dayCols[10][1] = 175;
+  dayCols[10][2] = 50;

   // Tungsten 40W
   dayCols[11][0] = 255;


Go command

Go command

--- _4DSystemDispalyBare/_4DSystemDispalyBare.ino
+++ _4DSystemDispalyBare/_4DSystemDispalyBare.ino
@@ -5,16 +5,18 @@
 //  Display.touch_DetectRegion(100,100, 200, 200) ;
  //Display.gfx_MoveTo(30, 30);

+#include <stdio.h>

 #define DisplaySerial Serial1
 #define HWLOGGING Serial // Serial port for debugging
 #define RESETLINE 4
-#define TEXTWIDTH 3
-#define TEXTHEIGHT 2
-#define BUTTON_H 44
-#define BUTTON_W 160
-#define BUTTON_SMALL_W 36
-#define PADDING 10
+#define TEXTWIDTH 5
+#define TEXTHEIGHT 5
+#define BUTTON_H 70
+#define BUTTON_W 230
+#define BUTTON_SMALL_W 55
+#define PADDING 12
+#define OK_BUTTON_ROW 6

 #include "Picaso_Serial_4DLib.h"
 #include "Picaso_Const4D.h"
@@ -25,10 +27,14 @@
 int y;
 char cstr[20];
 String str;
-int rowadd = 3;
-int coladd = 1;
+int rowadd = 0;
+int coladd = 0;
 unsigned int num = 0;

+int commands[100];
+int duration[100];
+
+int index;
 void setup()
 {

@@ -49,6 +55,11 @@

 #define INIT_STATE 0
 #define MOVE_STATE 1
+#define ROTATE_STATE 2
+#define GO_STATE 3
+#define ERASE_STATE 4
+
+#define MOVE 1

 int state = INIT_STATE;
 void loop()
@@ -56,7 +67,9 @@
   Display.touch_Set(TOUCH_ENABLE) ;
   Display.touch_Set(TOUCH_REGIONDEFAULT) ;
   drawInitialScreen();
-
+// Draw a button as a List Box (sunken)
+//   Display.gfx_Selection(3, RED, YELLOW); // pre-select "Item3"
+//  Display.gfx_Button(DOWN, 30, 30, GREEN, WHITE, FONT3, 1, 1, "Item1\nItem2\nItem3\nItem4");

   while(1)
@@ -73,7 +86,6 @@
     switch(state)
     {
       case INIT_STATE:
-
         if(insideRegion(0, 1, x, y, BUTTON_W)) // MOVE
         {
           HWLOGGING.print("MOVE");
@@ -83,15 +95,26 @@
         }else if (insideRegion(0, 2, x, y, BUTTON_W)) // ROTATE
         {
            HWLOGGING.print("ROTATE");
-           drawButton("ROTATE", 0, 2, BUTTON_DOWN);
+           state = ROTATE_STATE;
+           //drawButton("ROTATE", 0, 2, BUTTON_DOWN);
+           drawRotateScreen();
         }else if (insideRegion(0, 3, x, y, BUTTON_W)) // SHOOT
         {
-           HWLOGGING.print("SHOOT");
+          HWLOGGING.print("SHOOT");
           drawButton("SHOOT", 0, 3, BUTTON_DOWN);
-        }else if (insideRegion(0, 5, x, y, BUTTON_W)) // ERACE
-        {
-           HWLOGGING.print("ERACE");
-          drawButton("ERACE", 0, 5, BUTTON_DOWN);
+        }else if (insideRegion(0, 5, x, y, BUTTON_W)) // GO
+        {
+          state = GO_STATE;
+          HWLOGGING.print("GO");
+          go();
+          drawButton("GO", 0, 5, BUTTON_DOWN);
+        }else if (insideRegion(0, 6, x, y, BUTTON_W)) // ERASE
+        {
+          //state = ERASE_STATE;
+          state = INIT_STATE;
+          HWLOGGING.print("ERASE");
+          drawButton("ERASE", 0, 6, BUTTON_DOWN);
+          index = 0;
         }
         break;

@@ -128,17 +151,38 @@
         {
           add(0);
         }
-        else if(insideRegion(0, 10, x, y, BUTTON_W)) // BACK
-        {
+        else if(insideRegion(0, OK_BUTTON_ROW, x, y, BUTTON_W)) // OK
+        {
+          addCommand(MOVE);
           state = INIT_STATE;
           drawInitialScreen();
-        } else if(insideRegion(1, 10, x, y, BUTTON_W)) // OK
-        {
-          //TODO: Save
+        }
+//        } else if(insideRegion(1, 10, x, y, BUTTON_W)) // OK
+//        {
+//          //TODO: Save
+//          state = INIT_STATE;
+//          drawInitialScreen();
+//        }
+      break;
+      case ROTATE_STATE:
+      if(insideRegion(0, 1, x, y, BUTTON_W)) // LEFT
+        {
+           HWLOGGING.print("Left");
+        }else if (insideRegion(0, 2, x, y, BUTTON_W)) // RIGHT
+        {
+           HWLOGGING.print("Right");
+
+        }else if(insideRegion(0, OK_BUTTON_ROW, x, y, BUTTON_W)) // OK
+        {
           state = INIT_STATE;
           drawInitialScreen();
         }
-
+//        } else if(insideRegion(1, 10, x, y, BUTTON_W)) // OK
+//        {
+//          //TODO: Save
+//          state = INIT_STATE;
+//          drawInitialScreen();
+//        }
       break;
     }

@@ -148,9 +192,17 @@
 //    Display.touch_Set(TOUCH_REGIONDEFAULT) ;
 }

+void addCommand(int type)
+{
+  commands[index] = type;
+  duration[index] = num;
+  index++;
+}
+
 void add(int n)
 {
   HWLOGGING.print(num);
+  if( ((long)num * 10 + n) > 65535) return;
   num = num * 10 + n;
   drawNumber();
 }
@@ -175,8 +227,8 @@
 {
     str = String(num);
   str.toCharArray(cstr,16);
- Display.gfx_MoveTo(50,100);
-
+// Display.gfx_MoveTo(50,100);
+   Display.txt_MoveCursor(0,2);
 //  Display.txt_MoveCursor(1, 0);
 //  Display.txt_FontID(FONT1);
 //    Display.putstr(cstr) ;
@@ -184,6 +236,8 @@
 //  Display.txt_FontID(FONT2);
 //    Display.putstr(cstr) ;
 //  Display.txt_MoveCursor(3, 0);
+  Display.txt_Width(TEXTWIDTH);
+  Display.txt_Height(TEXTHEIGHT);
   Display.txt_FontID(FONT3);

   Display.putstr(cstr) ;
@@ -204,11 +258,14 @@
   drawButton("MOVE",   0, 1, BUTTON_UP);
   drawButton("ROTATE", 0, 2, BUTTON_UP);
   drawButton("SHOOT",  0, 3, BUTTON_UP);
-  drawButton("ERACE",  0, 5, BUTTON_UP);
+  drawButton("GO",     0, 5, BUTTON_UP);
+  drawButton("ERASE",  0, 6, BUTTON_UP);
 }

 void drawMoveScreen()
 {
+  num =0;
+  add(0);
   Display.gfx_Cls();
   drawSmallButton("1", 0+coladd, 1+rowadd, BUTTON_UP);
   drawSmallButton("2", 1+coladd, 1+rowadd, BUTTON_UP);
@@ -223,8 +280,22 @@
   drawSmallButton("9", 2+coladd, 3+rowadd, BUTTON_UP);

   drawSmallButton("0", 1+coladd, 4+rowadd, BUTTON_UP);
-  drawButton("BACK", 0, 10, BUTTON_UP);
-  drawButton("OK", 1, 10, BUTTON_UP);
+  okBackButtons();
+}
+
+void okBackButtons()
+{
+//  drawButton("BACK", 0, 6, BUTTON_UP);
+  drawButton("OK", 0, OK_BUTTON_ROW, BUTTON_UP);
+}
+void drawRotateScreen()
+{
+   Display.gfx_Cls();
+  drawButton("LEFT",  0, 1, BUTTON_UP);
+  drawButton("RIGHT", 0, 2, BUTTON_UP);
+//  drawButton("ROTATE 180 ",  0, 3, BUTTON_UP);
+//  drawButton("ERACE",  0, 5, BUTTON_UP);
+  okBackButtons();
 }

@@ -262,8 +333,35 @@

 void debugCoordinates()
 {
+  Display.txt_Width(1);
+  Display.txt_Height(1);
+  Display.txt_FontID(FONT1);
   Display.txt_MoveCursor(1,0);
   printint(x);
   Display.txt_MoveCursor(2,0);
   printint(y);
-}
+  Display.txt_Width(TEXTWIDTH);
+  Display.txt_Height(TEXTHEIGHT);
+}
+
+void go()
+{
+  //TODO:go
+  Display.gfx_Cls();
+  for (int i=0; i!= index;i++)
+  {
+    Display.txt_MoveCursor(i,0);
+    printCommand(i, commands[i], duration[i]);
+  }
+}
+
+void printCommand(int i, int command, int duration)
+{
+  Display.txt_Width(2);
+  Display.txt_Height(2);
+  Display.txt_FontID(FONT3);
+  String c = "Move";
+  c=i+" "+c+" "+duration;
+  c.toCharArray(cstr,16);
+  Display.putstr(cstr);
+}


added command S and A

added command S and A

--- jenny5-firmware/jenny5-firmware.ino
+++ jenny5-firmware/jenny5-firmware.ino
@@ -6,7 +6,7 @@

 char is_command_running;

-char firmware_version[] = "2015.11.11.4";
+char firmware_version[] = "2015.11.12.0";

 char current_buffer[65];


ListAccessPoints and keepalive are working correctly, however strange code for message length is still required.

--- ArduinoTestTool/ArduinoTestTool.ino
+++ ArduinoTestTool/ArduinoTestTool.ino
@@ -53,6 +53,52 @@
 }

 /**
+ *  Interrupt method used to get notified about messages of slave
+ */
+void incomingMessage() {
+  // Show led interrupt has been triggered
+  if(ledState == LOW) {
+    ledState = HIGH;
+  } else {
+    ledState = LOW;
+  }
+  digitalWrite(led, ledState);
+
+  // Receive message
+  digitalWrite(slaveSelectPin,LOW);
+
+  // Ignore 0 and read message type
+  byte messageType;
+  while(messageType == 0x00) {
+    messageType = transferByte(0x00);
+  }
+
+  // Read message length
+  int messageLength = SPI.transfer(0x00);
+  delayMicroseconds(1);
+
+  // Proccess message
+  if (messageType == KEEPALIVE) {
+    readKeepAlive(messageLength);
+  } else if(messageType == LISTACCESSPOINTS) {
+    readListAccesspoints(messageLength);
+  } else {
+    Serial.println("Unknown message type received");
+  }
+
+  digitalWrite(slaveSelectPin,HIGH);
+}
+
+byte transferByte(const byte c) {
+  byte receivedByte = SPI.transfer(c);
+  //delayMicroseconds(1);
+
+  return receivedByte;
+}
+
+//------------- Send message Functions -------------//
+
+/**
  *  Send Keep Alive to slave
  */
 void sendKeepAlive(void) {
@@ -87,43 +133,34 @@
   digitalWrite(slaveSelectPin,HIGH);
 }

-void incomingMessage() {
-  const char delay = 1;
-
-  // Show led interrupt has been triggered
-  if(ledState == LOW) {
-    ledState = HIGH;
-  } else {
-    ledState = LOW;
-  }
-  digitalWrite(led, ledState);
+//------------- Read message Functions -------------//

-  // Receive message
-  digitalWrite(slaveSelectPin,LOW);
-
-  char messageType;
-  while(messageType == 0x00) {
-    messageType = SPI.transfer(0x00);
-    delayMicroseconds(delay);
+/**
+ * Read received keep alive message
+ */
+void readKeepAlive(int messageLength) {
+  for(int i = 0; i < messageLength; i++) {
+    char c = transferByte(0x00);
+    Serial.print(c);
   }

-  if(messageType == 2) {
-    int messageLength = SPI.transfer(0x00);
-    delayMicroseconds(delay);
-    char message[messageLength];
+  Serial.println();
+}
+
+/**
+ * Read received list accesspoint message
+ */
+void readListAccesspoints(int messageLength) {
+  char message[messageLength];

-    for(int i = 0; i < messageLength; i++) {
-      char c = SPI.transfer(0x00);
-      delayMicroseconds(delay);
+  for(int i = 0; i < messageLength; i++) {
+    byte c = transferByte(0x00);

-      if(i > 1) {
-        message[i-2] = c;
-      }
+    if(i > 1) {
+      message[i-2] = c;
     }
-
-    Serial.println(message);
   }

-  digitalWrite(slaveSelectPin,HIGH);
+  Serial.println(message);
 }


src: add brightness command

src: add brightness command

--- MqttLEDs/MqttLEDs.ino
+++ MqttLEDs/MqttLEDs.ino
@@ -24,6 +24,7 @@
 const char* FADE = "fade";
 const char* CYCLE = "cycle";
 const char* FIRE = "fire";
+const char* BRIGHTNESS = "brightness";

 #define FADE_COMMAND 1
 #define FIRE_COMMAND 2
@@ -238,7 +239,7 @@
     } else {
       delete command;
     }
-  } else if (0 == strncmp(FIRE, messageBuffer.c_str(), strlen(FIRE)) {
+  } else if (0 == strncmp(FIRE, messageBuffer.c_str(), strlen(FIRE))) {
     CommandEntry* command = new CommandEntry;
     char* next = strtok((char*) messageBuffer.c_str()," ");

@@ -285,6 +286,15 @@
       strip.setPixelColor(i, strip.Color(0,0,0));
     }
     setCurrent(0, 0, 0);
+  } else if (0 == strncmp(BRIGHTNESS, messageBuffer.c_str(), strlen(BRIGHTNESS))) {
+    char* next = strtok((char*) messageBuffer.c_str()," ");
+    next = strtok(nullptr," ");
+    int brightness = atoi(next);
+    if ((brightness < 0) || (brightness > 100)) {
+      Serial.println("Invalid Brightness");
+      return;
+    }
+    strip.setBrightness(brightness);
   } else if ((0 == strncmp(RANGE, messageBuffer.c_str(), strlen(RANGE))) ||
              (0 == strncmp(CLEAR_AND_RANGE, messageBuffer.c_str(), strlen(CLEAR_AND_RANGE)))) {
     clearQueue();


Switch to alternate RTC library that supports time_t

(Actually, the other probably would have in a round abut way, but I only
found out my problem upon switching libraries, and by then it was too
late.)

--- NTPclock/NTPclock.ino
+++ NTPclock/NTPclock.ino
@@ -11,7 +11,7 @@
 //----------------------------------------------------------------------------------------------------------------

 #include <pgmspace.h>     // Used by RTC Library.  Specific for ESP8266
-#include <RtcDS3231.h>    // RTC Library
+#include <DS3232RTC.h>    // RTC Library
 #include <Wire.h>         // Incuded here so that Arduino library object file references work
 #include <LedControl.h>   // MAX7219 display control library
 #include <ESP8266WiFi.h>  // We need to use the wifi for NTP
@@ -25,7 +25,6 @@
 char pass[] = "";       // your network password           //
 //---------------------------------------------------------//

-RtcDS3231 RTC;
 LedControl lc1 = LedControl(D5,D6,D7,1); // Initialize MAX7219

 // Initial set up routines
@@ -37,15 +36,36 @@
   connectWifi(); //Then connect to wifi
   beginNTP();    //Start up NTP Client & time keeping

+  NTP.onNTPSyncEvent([](NTPSyncEvent_t ntpEvent) {
+    if (ntpEvent == 0) {
+      Serial.print("Got NTP time: ");
+      Serial.println(NTP.getTimeDateString(NTP.getLastNTPSync()));
+      RTC.set(now() );
+    }
+  });
+
   lc1.shutdown(0,false);
   lc1.setIntensity(0, 10);     //TODO: Needs moved out to seperate function.  Plus controls to raise / lower.
 }

 // Main program loop
 void loop() {
-  updateDigits();
-  updateMisc();
-  delay(1000);         //TODO:   REMOVE DELAY FOR A COUNTER..............................PLEASE!!!!......../////////////////////////
+  updateDigits(); //
+  updateMisc();   //
+  delay(1000);    //
+
+  Serial.print( month() );
+  Serial.print(" ");
+  Serial.print( day() );
+  Serial.print(" ");
+  Serial.print( year() );
+  Serial.print(" ");
+  Serial.print( hour() );
+  Serial.print(" ");
+  Serial.print( minute() );
+  Serial.print(" ");
+  Serial.print( second() );
+  Serial.println();
 }

 //
@@ -93,23 +113,12 @@
   Serial.println("  Done.");
 }

-// Set up the RTC.  Also loads RTC time to get time faster.
+// Set up the RTC.  Also loads RTC time to get time faster
 void RTCSetup() {
-  RTC.Begin();
-
-  //If RTC is still valid, set it as current time
-  if (RTC.IsDateTimeValid()) {
-    RtcDateTime now = RTC.GetDateTime();
-    setTime(now.Hour(), now.Minute(), now.Second(), now.Day(), now.Month(), now.Year() );
-  }
-
-  //Make sure RTC is actually running...
-  if (!RTC.GetIsRunning()){
-    RTC.SetIsRunning(true);
-  }
-
-  //Never assume the Rtc was last configured by you, so just clear them to your needed state
-  RTC.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
+  time_t RTCTime = RTC.get();  //Get RTC time
+  setTime(RTCTime);            //Set it as current time
+  RTC.squareWave(SQWAVE_NONE); //Never assume the Rtc was last configured by you, so just clear them to your needed state
+  updateDigits();  //Force update of display while loop() not running
 }

 // Initial set up of NTP


Verify reserved pins aren't being used in addSensor()

--- arduino/autogarten_probe/autogarten_probe.ino
+++ arduino/autogarten_probe/autogarten_probe.ino
@@ -51,9 +51,9 @@
 const int ERROR_VALUE = -1000;

 const int oneWirePin = 9;
-const int maxOneWireDevices = 3;
+const int maxOneWireDevices = 2;  // Adjust to number of 1-Wire devices
 int oneWireDeviceCount = 0;
-OneWire oneWire(9);
+OneWire oneWire(oneWirePin);

 /* WiFi variables */
 const int wifiConnectionWait = 10000;  // In ms
@@ -296,7 +296,11 @@
  */
 boolean addSensor(char *sensorId, int pin, int sensorType) {

-  // TODO: Verify a reserved PIN isn't being used...
+  // Verify a reserved PIN isn't being used...
+  if (pin == 7 || pin == 10 || pin == 11 || pin == 12 || pin ==13) {
+    Serial.println("ERROR 100");
+    return false;
+  }

   switch (sensorType) {


Added a delay in ds loop

Added a delay in ds loop

--- src/WiFiSensor/WiFiSensor.ino
+++ src/WiFiSensor/WiFiSensor.ino
@@ -194,7 +194,7 @@
 			httpServer.handleClient();
 			// This will reset every 2000 milliseconds a.k.a every 2 seconds
 			long dstimer = (millis() % 2000);
-			if ( dstimer <= 10 ){
+			if ( dstimer <= 100 ){
 				dsOverrideCycleCount++;
 			}
 			if ( dstimer <= 1000 ){
@@ -205,8 +205,8 @@
 				digitalWrite(GREENLED, LOW);
 				digitalWrite(REDLED, LOW);
 			}
-
-			if( dsOverrideCycleCount > 30){
+			delay(200);
+			if( dsOverrideCycleCount >= 30){
 				dsWebOverride = false;
 				Serial.println("Deep Sleep Web Override Finished, sleep for 10s");
 				digitalWrite(GREENLED, LOW);


fix the boundary check

fix the boundary check

..so that changing fadeAmount (to, say, 7) doesn't break the algorithm making an infinit loop (see https://github.com/arduino/Arduino/issues/5115)

--- build/shared/examples/01.Basics/Fade/Fade.ino
+++ build/shared/examples/01.Basics/Fade/Fade.ino
@@ -32,8 +32,8 @@
   brightness = brightness + fadeAmount;

   // reverse the direction of the fading at the ends of the fade:
-  if (brightness == 0 || brightness == 255) {
-    fadeAmount = -fadeAmount ;
+  if (brightness <= 0 || brightness >= 255) {
+    fadeAmount = -fadeAmount;
   }
   // wait for 30 milliseconds to see the dimming effect
   delay(30);


minor fixes

minor fixes

--- projects/YunHub/YunHub_1.05_MQTT/YunHub_1.05_MQTT.ino
+++ projects/YunHub/YunHub_1.05_MQTT/YunHub_1.05_MQTT.ino
@@ -7,7 +7,7 @@
 //
 // Blink LED #13 for each package received
 //
-// 150725 YunHub 1.05
+// 150726 YunHub 1.05
 //

 #include <Bridge.h>
@@ -17,7 +17,7 @@

 byte rf12_group, rf12_nodeid;
 String timeStamp, dataStr, rawdataStr;
-char message_buff[255];
+char message_buff[128];

 // Update these with values suitable for your network.
 byte server[] = { 192, 168, 178, 27 };
@@ -35,7 +35,7 @@
 } TNodeData;

-// Temperature node data structure. Timestamp created locally, at time of receival.
+// RadioBlip2 data structure. Timestamp created locally, at time of receival.
 struct
 {
     String timeStamp;   // "+%Y-%m-%d %T": format "YYYY-MM-DD hh:mm:ss"
@@ -53,7 +53,7 @@
     // counter
     int i = 0;
     // buffer for payload-to-string conversion
-    char message_buff[255];
+    char message_buff[128];

     // copy payload to buffer, append \0
     for (i = 0; i < length; i++)
@@ -74,7 +74,7 @@

     Serial.begin(57600);
     Serial.println("***");
-    Serial.println("*** 150725 YunHub 1.05");
+    Serial.println("*** 150726 YunHub 1.05");
     Serial.println("***");

     // initialize digital pin 13 as an output.
@@ -119,7 +119,7 @@
         }

         // publish to MQTT server
-        rawdataStr.toCharArray(message_buff, 255);
+        rawdataStr.toCharArray(message_buff, 128);
         client.publish("RF12_RawData", message_buff);

@@ -143,7 +143,7 @@
                       + String(TNodeData.T2);

             // publish interpreted TNode data to MQTT server
-            dataStr.toCharArray(message_buff, 255);
+            dataStr.toCharArray(message_buff, 128);
             client.publish("TNode", message_buff);
         }

@@ -163,7 +163,7 @@
                       + String(RadioBlip2Data.Vcc);

             // publish interpreted TNode data to MQTT server
-            dataStr.toCharArray(message_buff, 255);
+            dataStr.toCharArray(message_buff, 128);
             client.publish("RadioBlip2", message_buff);
         }


minor bugs fixed

minor bugs fixed

remove delay from ISR "door limit switch"
releaseBillDelay increased

--- arduino/medox/medox.ino
+++ arduino/medox/medox.ino
@@ -28,7 +28,7 @@
 #define    trayLimit    A5
 #define    upLimit      A4

-#define    releaseBillDelay 3000 //to wait untill bill released
+#define    releaseBillDelay 5000 //to wait untill bill released
 #define    getBillDelay     1000 //to wait until bill catched for sure
 #define    upStepperDelay   3    //to wait before up/down steps
 #define    roStepperDelay   15   //to wait before rotation steps
@@ -51,7 +51,7 @@
 float tempFloat       = 0;    //for saving sensor data temporary
 int billCount         = 0;    //for storing bill count added by ISR
 int selectedWarehouse = 0;    //to know what warehouse is above the door "0 is the empty one"
-
+bool closeDrawer = false;     //to close door from main loop
 /// using half step mode
 int seq[8][4]={ {1,0,0,0},
                 {1,1,0,0},
@@ -87,7 +87,7 @@
   Serial.begin(9600);

   //define drawer limit switch pin as interrupt pin to secure drawer automatically
-  attachInterrupt(digitalPinToInterrupt(doorSwitch), closeDoor, RISING);
+  attachInterrupt(digitalPinToInterrupt(doorSwitch), callCloseDoor, RISING);

   pinMode(  trayLimit,  INPUT);
   pinMode(  upLimit,    INPUT);
@@ -136,6 +136,10 @@
     else if(serialData == 'b')
       initialization();
   }
+  if(closeDrawer){
+    closeDoor();
+    closeDrawer = false;
+  }
 }

 //initialize motors "moves them to initial position"
@@ -184,6 +188,16 @@
   warehouseServo.write(WarehouseServoOpen);
   delay(servoPositionDelay); //waits servo to reach position
   warehouseServo.detach(); //detaches the warehouseServo
+}
+
+void callCloseDoor(){
+  //used as ISR can't have delay()
+  //and delay is needed to wait for servo
+  //to get to its position
+  //so a variable is used instead
+  //to call closeDoor() from main loop
+  closeDrawer = true;
+
 }

 void closeDoor(){


moved from local response processing to yahoo yql api to do the 'heavy lifting'. for arduino, this includes string parsing.

--- mood_fly/mood_fly.ino
+++ mood_fly/mood_fly.ino
@@ -8,8 +8,9 @@
 #define RGB_LED_BluePin 5

-Client client("data.tweetsentiments.com", 8080);
+Client client("query.yahooapis.com", 80);
 byte red = 0, blue= 0, green = 0;
+char led_red=0, led_green=0, led_blue=0;

 void setup() {
   Serial.begin(9600);
@@ -25,10 +26,34 @@
 }

 void loop() {
-  char sum=0, led_red=0, led_green=0, led_blue=0;
+  char sum=0;
+  boolean valueFound = false;
   if (client.available()) {

-    if(client.find("neutral\":")){
+    if(client.find("positive\":\""))
+    {
+      valueFound = true;
+      char buf[4];
+      client.readBytes(buf, 3);
+      green=atoi(buf);
+      Serial.println();
+      Serial.print("green: ");
+      Serial.println(green);
+    }
+
+    if(client.find("negative\":\""))
+    {
+      valueFound = true;
+      char buf[4];
+      client.readBytes(buf, 3);
+      red = atoi(buf);
+      Serial.println();
+      Serial.print("red: ");
+      Serial.println(red);
+    }
+
+    if(client.find("neutral\":\"")){
+      valueFound = true;
       char buf[4];
       client.readBytes(buf, 3);
       blue = atoi(buf);
@@ -37,33 +62,15 @@
       Serial.println(blue);
     }

-    if(client.find("positive\":"))
-    {
-      char buf[4];
-      client.readBytes(buf, 3);
-      green=atoi(buf);
-      Serial.println();
-      Serial.print("green: ");
-      Serial.println(green);
-    }
-
-    if(client.find("negative\":"))
-    {
-      char buf[4];
-      client.readBytes(buf, 3);
-      red = atoi(buf);
-      Serial.println();
-      Serial.print("red: ");
-      Serial.println(red);
-    }
-
     client.stop();

+    if(valueFound){
     sum = red+green+blue;
     if (sum != 0){
       led_red = (255*(red*1.0/sum));
       led_green = (255*(green*1.0/sum));
       led_blue = (255*(blue*1.0/sum));
+    }
     }

      // set the brightness of the LED:
@@ -89,9 +96,20 @@

   if (client.connect()) {
     Serial.println("connected");
-    client.println("GET /api/search.json?topic=fail HTTP/1.0");
+
+    char topicToAnalyze[] = "fail";
+
+    String request = "GET ";
+    //use yahoo yql web api to do the numbercrunching - arduino is too slow to process tweet sentiments results locally (70s+)
+    request += "http://query.yahooapis.com/v1/public/yql?q=SELECT%20positive,%20negative,%20neutral%20FROM%20json%20WHERE%20url%20%3D%20%22http://data.tweetsentiments.com:8080/api/search.json%3Ftopic%3D";
+    request += topicToAnalyze;
+    request += "%22&format=json";
+    request += " HTTP/1.0";
+    Serial.println( request );
+    // do the HTTP GET request
+    client.println( request );
     client.println();
-    delay(1000);
+
   } else {
     Serial.println("connection failed");
   }


Read detector value to A0

Read detector value to A0

--- src/zapper/zapper.ino
+++ src/zapper/zapper.ino
@@ -1,8 +1,9 @@
 const int outPinLed = 2;
 const int inPinTrigger = 7;
-const int inPinDetector = 4;
+const int inPinDetector = A0;

 int triggerPressed = 0;
+int detectorValue = 1023;

 void setup() {
   // put your setup code here, to run once:
@@ -11,9 +12,7 @@
   pinMode(outPinLed, OUTPUT);
   digitalWrite(outPinLed, LOW);

-  pinMode(inPinTrigger, INPUT);
-  pinMode(inPinDetector, INPUT);
-
+  pinMode(inPinTrigger, INPUT_PULLUP);
 }

 void loop() {
@@ -22,14 +21,22 @@
   if (triggerPressed != triggerPrev) {
     Serial.print("Trigger state changed: ");
     Serial.println(triggerPressed);
-    if (triggerPressed) {
-      int detectorValue = digitalRead(inPinDetector);
+    /*if (triggerPressed) {
+      int detectorValue = analogRead(inPinDetector);

       Serial.print("Detector: ");
       Serial.println(detectorValue);
-    }
+    }*/
   }
-
+  if (triggerPressed) {
+    int detectorPrev = detectorValue;
+    detectorValue = analogRead(inPinDetector);
+    Serial.print("     Detector: ");
+    Serial.print(detectorValue);
+    Serial.print("   diff=");
+    Serial.println(detectorValue - detectorPrev);
+  }
+
   int ledState = triggerPressed ? HIGH : LOW;
   digitalWrite(outPinLed, ledState);


minor comment

minor comment

--- IMUtest.ino
+++ IMUtest.ino
@@ -88,7 +88,7 @@

 void setup() {
   Serial.begin(baud);
-  //Wire.begin();  // arduino as master
+  //Wire.begin();  // arduino as I2C master

   // arduino I2C slave address: 0x44; no conflict with LSM303 or L3G addresses
   Wire.begin(0x44);


Add files via upload

Add files via upload

Add v7.0

--- gpslcd.ino
+++ gpslcd.ino
@@ -144,7 +144,7 @@
     GPSData.second     = gps.time.second();
 #else // #ifndef DATA_VALID_OVERRIDE
     // Store the fake GPS data (for debugging)
-    GPSData.satellites = 5; // Invalid satellites
+    GPSData.satellites = 5;
     GPSData.lat        = 40.71d;  // East coast (NYC)
     GPSData.lon        = -74.00d; //   "
     GPSData.speed      = 5.0d;
@@ -371,7 +371,10 @@
       lcd.print("Data Not");
       lcd.setCursor(7, 3); // Go to 4th line
       lcd.print("Valid");
-      lcd.setCursor(19, 3);
+      lcd.setCursor(0, 3);
+      lcd.print("SV:"); // Desplay the number of satellites
+      lcd.print(gps.satellites.value());
+      lcd.setCursor(19, 3); // Display the initializing counter
       if (++initializingCounter > 9) initializingCounter = 1; // Limit 1 - 9
       lcd.print(initializingCounter);
       leftInitialization = false;


Clean up getChipName

Clean up getChipName

--- temperature-relay.ino
+++ temperature-relay.ino
@@ -114,20 +114,17 @@
   return type_s;
 }

-void chipName(byte a, char* name) {
-  switch (a) {
-    case 0:
-      strcpy(name, "DS18S20 or DS1822");
-      break;
-    case 1:
-      strcpy(name, "DS18S20");
-      break;
-    case 2:
-      strcpy(name, "DS2438");
-      break;
-    default:
-      strcpy(name, "Unknown");
-  }
+const char* CHIP_NAME[] = { "DS18S20 or DS1822", "DS18S20", "DS2438", "Unknown" };
+
+const char* getChipName(byte val) {
+  int index = (int)val;
+  const char* chipName;
+  if( index < 0 || index > 2 ) {
+    chipName = CHIP_NAME[3];
+  }  else {
+    chipName = CHIP_NAME[index];
+  }
+  return chipName;
 }

 float parseTempValue(byte data[12], byte type_s) {
@@ -219,8 +216,7 @@
     sensors[sensor_id].type = type_s;
     memcpy(&sensors[sensor_id].addr, &addr, sizeof(addr));

-    char name[18];
-    chipName(sensors[sensor_id].type, name);
+    const char* name = getChipName(sensors[sensor_id].type);
     char sensorMessage[75];
     sprintf(
       sensorMessage,


update board detail.

update board detail.

--- examples/mqtt/mqtt_super_simple/mqtt_super_simple.ino
+++ examples/mqtt/mqtt_super_simple/mqtt_super_simple.ino
@@ -11,20 +11,20 @@
 WiFiConnector *wifi;

 /* MQTT INFO */
-#define MQTT_HOST        "rabbit.cmmc.ninja"
+#define MQTT_HOST        "iot.eclipse.org"
 #define MQTT_PORT        1883
-#define PUBLISH_EVERY    1 *1000 // every 15 seconds
+#define PUBLISH_EVERY    2 *1000 // every 15 seconds

 /* comment ทิ้งถ้าไม่ส่ username/password */
-#define MQTT_USERNAME    "free:test"
-#define MQTT_PASSWORD    "test"
+#define MQTT_USERNAME    "nat:cmmc"
+#define MQTT_PASSWORD    "cmmc"

 /* SENSOR INFO */
-#define DEVICE_NAME "-RED-"
+#define DEVICE_NAME "EXPERIMENT-003"
 #define AUTHOR      "Nat Weerawan"
-#define BOARD       "dw.mini-esp.v2"
-#define PROJECT     "POC"
-#define SENSOR      "DHT22"
+#define BOARD       "espresso"
+#define PROJECT     "test"
+#define SENSOR      "-"

 /* WIFI INFO */
 #define SSID        "WIFI SSID"
@@ -53,4 +53,4 @@
 void loop()
 {
   mqtt->loop(wifi);
-}
+}