minor enhancements and bug fixes

minor enhancements and bug fixes

--- loom.ino
+++ loom.ino
@@ -19,6 +19,10 @@

    See https://github.com/LenShustek/loom for more information about this project.

+   When you install a DRV8825 stepper motor driver, adjust the pot on the board so that
+   there is 0.75V at the body of the pot, which is for 1.5A drive current to the motor.
+   The motor doesn't have to be on when you that.
+
    ------------------------------------------------------------------------------------------------------
    Copyright (c) 2017, Len Shustek

@@ -42,11 +46,11 @@
 ******************************************************************************************************/
 /*
    23 Jan 2017, L. Shustek, V1.0, - first version
-   31 Jan 2017, L. Shustek, V1.1, - fix treadle sequence changes during weaving,
+   31 Jan 2017, L. Shustek, V1.1, - fix treadle sequence changes during weaving
                                   - clean up filename handling and display
     4 Feb 2017, L. Shustek, V1.2  - add motor fault detection
                                   - fix filename bug
-                                  - change schematic to match driver physical layout;
+                                  - change schematic to match driver physical layout
                                   - clean up compiler warnings
    10 Feb 2017, L. Shustek, V1.3  - separate motor hardware config, and don't write it to memory
                                   - better debugging output
@@ -57,21 +61,28 @@
                                   - allow abort from load/save/erase menu
    23 Mar 2017, L. Shustek, V1.5  - increase max treadle sequence to 99
                                   - fix bug when editing the filename extends its length
-                                  - temporarily disable motors during weaving if there is no activity for a few minutes.
+                                  - 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
+                                  - display frame numbers instead of X on the tieup screen
+                                  - display treadle numbers instead of X on the 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
+   28 Oct 2018, L. Shustek, V1.9  - add an option to do "Tabby" between each step of a treadle sequence
+                                    if the first two treadles are otherwise unused
     3 Jan 2019, L. Shustek, V1.10 - during calibration, show the distance the frame moves
+                                  - add a file option to reverse the fabric by inverting the tieups
+   13 Jun 2020, L. Shustek, V1.11 - fix bug: "alternate tabby" wasn't working for shafts other than 0 and 1
+                                  - fix bug: always set FILE_TABBY one way or the other when changing programming
+   10 Oct 2020, L. Shustek, V1.12 - allow "weave" button to abort the calibration process
+                                  - during calibration, show the previously set calibration point
+                                  - increase debounce delay because our switches are really noisy

 */
-#define VERSION "1.10"
+#define VERSION "1.12"

 /***** Enhancement ideas:

@@ -98,7 +109,7 @@
       Or instead: use an SD card for files, and to hell with optimizing the size to fit in the 4K EEPROM!
 */

-#define DEBUG true
+#define DEBUG false
 #define HW_TEST false

 #include <Encoder.h>
@@ -119,8 +130,8 @@
 #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
+#define DEBOUNCE_MSEC 100
+#define ROTATION_PERCENT (130/2) // what part of a full rotation goes from CENTER to UP or DOWN, nominally
 #define STEPS_PER_LIGHT_CHANGE 64
 #define MINS_BEFORE_MOTOR_DISABLE 10

@@ -163,7 +174,7 @@

 enum events { // input events
    eNone,
-   ePB1, ePB2, ePB3, ePB4,  // big pushbuttons
+   ePB1, ePB2, ePB3, ePB4,  // big pushbuttons: program, weave, load/save, unweave
    ePBH, ePBV,              // horizontal and vertical encoder pushbuttons
    ePEDAL,                  // foot pedal
    eHrotL, eHrotR,          // horizontal encoder rotation
@@ -265,7 +276,8 @@
    char id[4]; // "fil" for identification
    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
+#define FILE_TABBY 0x01         // use Tabby 1/2 between each treadle step
+#define FILE_INVERT_TIEUPS 0x02 // invert the top and bottom of the fabric
    byte unused;
    byte checksum;
    char filename[MAX_FILENAME + 1]; // null-terminated string
@@ -513,7 +525,8 @@
    int row = 3; // start from bottom to match weaving pattern books
    lcd.clear();
    if (title) {
-      center_message(row, "Treadle tie-ups");
+      center_message(row, file_hdr.flags & FILE_INVERT_TIEUPS ?
+                     "Treadle tie-ups, rev" : "Treadle tie-ups");
       --row; }
    for (; row >= 0 && shaft < NUM_SHAFTS; --row, ++shaft) {
       lcd.setCursor(0, row);
@@ -599,7 +612,7 @@

 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
+         (tieup[shaft][0] || tieup[shaft][1])) return true;  // used by treadle 0 or 1 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;
@@ -710,11 +723,15 @@
             lcd.noBlink();
             lcd.noCursor();
             cleanup_treadle_sequence();
-            // 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;
+            if (did_something) {
+               // 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 (!using_treadle(0) && !using_treadle(1) && wait_yesno(0, "Alternate 1/2 Tabby?"))
+                  file_hdr.flags |= FILE_TABBY;
+               else file_hdr.flags &= ~FILE_TABBY;
+               if (wait_yesno(0, "Reverse top/bottom?"))
+                  file_hdr.flags |= FILE_INVERT_TIEUPS;
+               else file_hdr.flags &= ~FILE_INVERT_TIEUPS; }
             return event; } } }

 //***********************************************************************
@@ -1032,7 +1049,7 @@
    #endif
    for (int shaft = 0; shaft < NUM_SHAFTS; ++shaft) {
       if (using_shaft(shaft)) {  // if we ever use this shaft in our pattern, then move it up or down
-         if ( tieup[shaft] [treadle]) { // this shaft should go down
+         if ( (file_hdr.flags & FILE_INVERT_TIEUPS ? 1 : 0) ^ tieup[shaft][treadle]) { // this shaft should go down
             if (shaft_status[shaft].shaft_position == SHAFT_UP)
                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)
@@ -1047,10 +1064,20 @@
             Serial.print(" moves "); Serial.println(shaft_status[shaft].steps_to_move); } } }
    do_steps();
    for (int shaft = 0; shaft < NUM_SHAFTS; ++shaft) // record the ending position of the shafts
-      shaft_status[shaft].shaft_position = tieup[shaft] [treadle] ? SHAFT_DOWN : SHAFT_UP; }
-
-int get_calibration(int shaft, const char *msg, bool allow_abort) {  // calibrate the center, bottom, or top position of a shaft
-   // returns the number of steps down (negative) or up (positive) we went, or 999 if aborted
+      shaft_status[shaft].shaft_position = ((file_hdr.flags & FILE_INVERT_TIEUPS ? 1 : 0) ^ tieup[shaft] [treadle]) ? SHAFT_DOWN : SHAFT_UP; }
+
+#define CALIB_SKIP 999
+#define CALIB_ABORT 998
+
+void format_distance (char *str, int steps) {
+   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); }
+
+int get_calibration(int shaft, const char *msg, int old_steps, bool centering) {  // calibrate the center, bottom, or top position of a shaft
+   // returns the number of steps down (negative) or up (positive) we went,
+   // or CALIB_SKIP (if centering) to skip this shaft, or CALIB_ABORT to abort calibration altogether
    enum events event;
    int steps = 0, stepadj;
    char str[25];
@@ -1059,12 +1086,16 @@
    center_message(0, str);
    sprintf(str, "%s, push green", msg);
    center_message(1, str);
-   if (allow_abort) {
-      center_message(3, "red button skips");
+   if (centering) {
+      center_message(2, "red button skips");
       H_LED(H_ENC_RED); }
+   center_message(3, "\"weave\" aborts");
    V_LED(V_ENC_GREEN);
    while (1) {
       event = check_event();
+      if (event == ePB2) {
+         steps = CALIB_ABORT;
+         goto do_exit; }
       if (event == eVrotR) {
          digitalWrite(MOTOR_DIR, 1 - shaft_hardware[shaft].clockwise);  // set direction to "down"
          stepadj = -1;
@@ -1080,13 +1111,14 @@
             digitalWrite(shaft_hardware[shaft].pin_step, LOW);
             delayMicroseconds(MIN_STEP_uSEC);
             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;
+         if (!centering) {
+            char old_distance[8], distance[8];
+            format_distance(old_distance, old_steps);
+            format_distance(distance, steps);
+            sprintf(str, "%s -> %s", old_distance, distance);
+            center_message(2, str); } }
+      if (centering && event == ePBH) {
+         steps = CALIB_SKIP;
          goto do_exit; }
       if (event == ePBV) {
 do_exit:
@@ -1097,23 +1129,33 @@
          return steps; } } }

 void do_calibration(void) {  // calibrate the center, bottom, and top positions of all shafts in use
-   int shaft;
-   for (shaft = 0; shaft < NUM_SHAFTS; ++shaft) {  // initialize all shafts as centered and nominal
-      shaft_status[shaft].shaft_position = SHAFT_CENTER;
-      shaft_status[shaft].steps_to_down = shaft_status[shaft].steps_to_up = NOMINAL_STEPS;
-      shaft_status[shaft].steps_to_move = 0; }
+   int shaft, steps;
    for (shaft = 0; shaft < NUM_SHAFTS; ++shaft) {  // now ask to recalibrate
       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);
+         steps = get_calibration(shaft, "center", 0, true);
+         shaft_status[shaft].shaft_position = SHAFT_CENTER;
+         if (steps == CALIB_ABORT) goto abort;
+         if (steps != CALIB_SKIP) { // calibrating this shaft
+            steps = get_calibration(shaft, "down", -shaft_status[shaft].steps_to_down, false);
+            if (steps == CALIB_ABORT) goto abort;
+            shaft_status[shaft].steps_to_down = -steps;
             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)
-            shaft_status[shaft].steps_to_up = get_calibration(shaft, "up", false);
+            steps = get_calibration(shaft, "up", shaft_status[shaft].steps_to_up, false);
+            if (steps == CALIB_ABORT) goto abort;
+            shaft_status[shaft].steps_to_up = steps;
             shaft_status[shaft].steps_to_move = -shaft_status[shaft].steps_to_up; // return it to the center
             do_steps(); // (it will be the only motor to move)
-         } } }
+         } }
+      else { // not using this shaft: assume centered, and leave the previous calibration
+         shaft_status[shaft].shaft_position = SHAFT_CENTER;
+         shaft_status[shaft].steps_to_move = 0; } }
    write_config(); // write the shaft calibration data
-   info_message("calibration saved", 0); }
+   info_message("calibration saved", 0);
+   return;
+abort:
+   read_config(); // reread the existing config
+   info_message("calibration aborted", 0); }

 void center_all_shafts(void) {
    for (int shaft = 0; shaft < NUM_SHAFTS; ++shaft) {
@@ -1307,5 +1349,3 @@
          break;
       default: ; } }
 //*
-
-


Remove T0

Remove T0

--- cmdMULTIsens/src/sketch.ino
+++ cmdMULTIsens/src/sketch.ino
@@ -56,9 +56,6 @@
 OneWire ds1w(DS18Pin);

 ChipTemp chipTemp(ATSamples);
-ChipTemp T0(1000);
-
-const float T0 = T0.readTemperature(); // Before anything else determine the chip temperature while it's still close to ambient. Kind of...

 float h;  // used for calculating dewpoint
 float t;  // used for calculating dewpoint
@@ -71,7 +68,6 @@
   digitalWrite(ActivityLED, HIGH);  // Turn the LED on during setup()
   Serial.begin(9600);               // Initialise serialport
   Serial.print("... ");
-  Serial.print(T0);
   tmp36.begin();                    // Initialise TMP36 sensor
   vbat.begin();                     // Initialise VBAT sensor
   dht.begin();                      // Initialise DHT22 sensor
@@ -187,10 +183,6 @@
         Serial.println("V | v : VBAT voltage");
         Serial.println("W | w : DS18B20 (1-wire) temperature");
         break;
-      case '0':
-        // ATMEGA T0 temperature
-        Serial.print(T0);
-        break;
       case 'C':
       case 'c':
         // ATMEGA temperature


Demonstrate TOTP

Demonstrate TOTP

--- totp/totp.ino
+++ totp/totp.ino
@@ -66,23 +66,17 @@
   return count;
 }

-void totp(const uint8_t* key, const size_t len, const long time, char token[TOKEN_LENGTH]) {
-  Serial.println("Starting totp");
-  long tc = time / INTERVAL;
-  Sha1.initHmac(key, len);
-  Serial.println("inited Hmac");
-  Sha1.write((uint8_t) (tc >> 24));
-  Sha1.write((uint8_t) (tc >> 16));
-  Sha1.write((uint8_t) (tc >> 8));
-  Sha1.write((uint8_t) tc);
-
-
-
+void totp(uint8_t* secret, const size_t len, const long time, char token[TOKEN_LENGTH]) {
+  long timestamp = time / INTERVAL;
+  uint8_t input[8] = { 0x00, 0x00, 0x00, 0x00 };
+  input[4] = (timestamp >> 24) & 0xff;
+  input[5] = (timestamp >> 16) & 0xff;
+  input[6] = (timestamp >> 8) & 0xff;
+  input[7] = timestamp & 0xff;

-  Serial.println("wrote");
-  uint8_t *hash = Sha1.resultHmac();
-
-  Serial.println("hashed");
+  Sha1.initHmac(secret, len);
+  Sha1.write(input, 8);
+  uint8_t* hash = Sha1.resultHmac();

   uint8_t offset = hash[19] & 0xf;

@@ -90,15 +84,11 @@
                       | ((hash[offset + 1] & 0xff) << 16)
                       | ((hash[offset + 2] & 0xff) << 8)
                       | ((hash[offset + 3] & 0xff));
-  Serial.println("thinged");
-  Serial.println(thing);

   for (int i = TOKEN_LENGTH - 1; i >= 0; i--) {
     token[i] = (thing % 10) + '0';
     thing /= 10;
   }
-
-  Serial.println("\ndone");
 }

 void setup() {
@@ -106,25 +96,19 @@
   Serial.begin(115200);
   rtc.begin();

-  uint8_t keyBase32[32];
-  String("salvdaxi3ipetshmxf54muq7q4k3cnrj").toCharArray((char *)keyBase32, 32);
+  uint8_t keyBase32[33];
+  String("salvdaxi3ipetshmxf54muq7q4k3cnrj").toCharArray((char *)keyBase32, 33);

   uint8_t key[20];
   base32_decode(keyBase32, key, 20);

   uint8_t correctKey[20] = { 0x90, 0x17, 0x51, 0x82, 0xe8, 0xda, 0x1e, 0x49, 0xc8, 0xec, 0xb9, 0x7b, 0xc6, 0x52, 0x1f, 0x87, 0x15, 0xb1, 0x36, 0x29 };

-  printHash(correctKey, 20);
-
-
   char token[TOKEN_LENGTH];

-  Serial.println("Trying to do work");
-
-  totp(key, 20, getTimestamp(), token);
+  totp(correctKey, 20, getTimestamp(), token);

   Serial.println(token);
-  Serial.println("All done with work.");

 }


move to 5feet

move to 5feet

--- shira-spider/shira-spider.ino
+++ shira-spider/shira-spider.ino
@@ -28,7 +28,7 @@
 SoftwareSerial mp3serial(serial_rx, serial_tx);
 DFRobotDFPlayerMini myDFPlayer;

-SPIDER spider(leds, NR_LEDS, &myDFPlayer, &sonar, 72);
+SPIDER spider(leds, NR_LEDS, &myDFPlayer, &sonar, 60);
 int i;

 void printDetail(uint8_t type, int value) {


more annonying beep

more annonying beep

--- src/basic/basic.ino
+++ src/basic/basic.ino
@@ -105,11 +105,13 @@
   return false;
 }

-void beep(unsigned char delayms) { //creating function
-  analogWrite(buzzerPin, 20); //Setting pin to high
-  delay(delayms); //Delaying
-  analogWrite(buzzerPin ,0); //Setting pin to LOW
-  delay(delayms); //Delaying
+void beep() { //creating function
+    for(int i=0; i<5; i++) {
+      tone(buzzerPin, 1410, 800);
+      delay(800);
+      tone(buzzerPin, 1000, 800);
+      delay(800);
+    }
 }

 void transmit_coords(double float_latitude, double float_longitude){


descriptive text changed

descriptive text changed

no little modifications needed according to https://github.com/somhi/ESP_SSD1306/issues/4

--- examples/ESP_ssd1306_128x64_I2C/ESP_ssd1306_128x64_I2C.ino
+++ examples/ESP_ssd1306_128x64_I2C/ESP_ssd1306_128x64_I2C.ino
@@ -12,8 +12,8 @@
  * This examples uses the ESP_SSD1306 library which is a copy of the default's Adafruit_SSD1306
  * library with some modifications in order to work in the ESP8266 board.
  * This library works in conjunction with the default's Adafruit_GFX library,  but it's needed
- * to do a little modification in that library in order to work (See README.txt file)
- *
+ * to do a little modification in that library in order to work (According to
+ * https://github.com/somhi/ESP_SSD1306/issues/4 this modifications is not needed anymore).
 */

 // Import required libraries


Fixed with shorten file name and correct line number

--- tests/TestStringRefs/TestStringRefs.ino
+++ tests/TestStringRefs/TestStringRefs.ino
@@ -1,3 +1,5 @@
+# 2 "TestStringRefs.ino"
+
 #include <Arduino.h>
 #include <ArduinoUnit.h>
 #include <Arduino_FreeRTOS.h>


Close the stream once the update is finished

--- examples/ESP8266-OTA/ESP8266-OTA.ino
+++ examples/ESP8266-OTA/ESP8266-OTA.ino
@@ -44,6 +44,7 @@

   Serial.setDebugOutput(true);
   if (ESP.updateSketch(*pub.payload_stream(), size, true, false)) {
+    pub.payload_stream()->stop();
     Serial.println("Clearing retained message.");
     client.publish(MQTT::Publish(pub.topic(), "")
                    .set_retain());


Add test logic for tempADC with one index point

--- arduino_sketches/PGA309/testPin_I2C/testPin_I2C.ino
+++ arduino_sketches/PGA309/testPin_I2C/testPin_I2C.ino
@@ -26,8 +26,8 @@
 int regToWriteTo[] = {0x01, 0x02};
 // int regToReadFrom[] = {0x01, 0x02};
 byte ADSData[3];
-int memData[] = {0x5449, 0x0000, 0x0000, REG3, REG4, 0x0000, REG6, (0xFFFF-((0x5449+REG3+REG4+REG6)&0xFFFF))};
-int memToWriteToReadFrom[] = {0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E};
+int memData[] = {0x5449, 0x0000, 0x0000, REG3, REG4, 0x0000, REG6, (0xFFFF-((0x5449+REG3+REG4+REG6)&0xFFFF)), 0x0280, REG1, REG2, 0x7FFF, 0x0000, (0xFFFF-((0x0280+REG1+REG2+0x7FFF)&0xFFFF))};
+int memToWriteToReadFrom[] = {0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A};

 void setup(){
 	Serial.begin(9600);
@@ -37,14 +37,14 @@
 	//Setting the test pin high enables direct writing of internal registers and stops transactions with External EEPROM
 	pga.enableTestPin();
 	delay(100);
-	//eeprom.clear();
-	// util::WriteToMultiEEPROM(&eeprom, memData, memToWriteToReadFrom,  (sizeof(memToWriteToReadFrom)/sizeof(int)));
-	// util::ReadFromMultEEPROM(&eeprom, memToWriteToReadFrom, (sizeof(memToWriteToReadFrom)/sizeof(int)));
+	eeprom.clear();
+	util::WriteToMultiEEPROM(&eeprom, memData, memToWriteToReadFrom,  (sizeof(memToWriteToReadFrom)/sizeof(int)));
+	util::ReadFromMultEEPROM(&eeprom, memToWriteToReadFrom, (sizeof(memToWriteToReadFrom)/sizeof(int)));
 	delay(1000);

-	util::WriteToMultiRegisters(&pga, regData, regToWriteTo, (sizeof(regData)/sizeof(int)));
+	// util::WriteToMultiRegisters(&pga, regData, regToWriteTo, (sizeof(regData)/sizeof(int)));
 	// util::ReadFromMultRegisters(&pga, regToReadFrom, (sizeof(regToReadFrom)/sizeof(int)));
 	Serial.print("Status of writing to the ADS internal register:");
 	Serial.println(ads.write(ADSREG));
@@ -56,6 +56,6 @@
 void loop(){
 	// util::printMenu();
 	util::ReadADSData(&ads, ADSData);
-	util::ReadErrorREG(&pga);
+	// util::ReadErrorREG(&pga);
 	util::ReadFromMultRegisters(&pga, regToReadFrom, (sizeof(regToReadFrom)/sizeof(int)));
 }


Implement custom BMP data structure in program

--- payload/payload.ino
+++ payload/payload.ino
@@ -11,11 +11,12 @@

 #include "Bmp180.h" // RCR header

+namespace rcr {
+namespace level1payload {
+
+Bmp180 bmp;
 File file; // file object
 //SdFatSdio sd_card; // MicroSD card
-
-namespace rcr {
-namespace level1payload {

 void setup() {
   // Start serial communication.
@@ -25,15 +26,15 @@
 void printBmpData(void) {

   Serial.print("Temperature = ");
-  Serial.print(bmp_data.temperature);
+  Serial.print(bmp.temperature());
   Serial.println(" °C");

   Serial.print("Ambient pressure = ");
-  Serial.print(bmp_data.ambient_pressure);
+  Serial.print(bmp.ambient_pressure());
   Serial.println(" Pa");

   Serial.print("Pressure altitude = ");
-  Serial.print(bmp_data.pressure_altitude);
+  Serial.print(bmp.pressure_altitude());
   Serial.println(" meters");
   Serial.println();
 }


full speed is more reliable, specially when -10F

Signed-off-by: Robert Nelson <d6c41255011d14bfa93d8562b946ca186cfa0c7b@gmail.com>

--- ws_bm_rtc.ino
+++ ws_bm_rtc.ino
@@ -12,17 +12,17 @@
 char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

 /* 16Mhz */
-//#define ws_baud 57600
-//#define ws_one_second 1000
-//#define ws_short_delay 200
+#define ws_baud 57600
+#define ws_one_second 1000
+#define ws_short_delay 200

 /* 8Mhz */
-#define ws_baud 115200
-#define ws_one_second 500
-#define ws_short_delay 100
+//#define ws_baud 115200
+//#define ws_one_second 500
+//#define ws_short_delay 100

 void setup () {
-	clock_prescale_set(clock_div_2);
+	//clock_prescale_set(clock_div_2);

 	Serial1.begin(ws_baud);
 	Serial1.println("Hello!");


need to debug sliderEvent

need to debug sliderEvent

--- glass/glass.ino
+++ glass/glass.ino
@@ -3,7 +3,6 @@

 #define DEBUG
 #include "utils.h"
-

 SoftwareSerial XBee(2, 4); // RX, TX

@@ -24,7 +23,7 @@
 #define gRELEASE 2

-unsigned long session_id = 0xA90;
+unsigned long session_id;// = 0xA90;
 int clicks;
 gesture_t g = gNONE;
 // An IR LED must be connected to Arduino PWM pin 3.
@@ -54,24 +53,10 @@
 bool pressed;
 unsigned long end_time;

-int readXBeeString (char *strArray) {
-  int i = 0;
-  if(!XBee.available()) {
-    return -1;
-  }
-  while (XBee.available()) {
-    strArray[i] = XBee.read();
-    i++;
-  }
-  strArray[i] = '\0';
-  return i;
-}
-
 void setup()
 {
   Serial.begin(9600);
   state = IDLE;
-  Serial.println('System Begins!');
   digitalWrite(softpotPin, HIGH); //enable pullup resistor
   randomSeed(analogRead(5));
   digitalWrite(ledPin, LOW);
@@ -80,31 +65,48 @@
   pressed = false;
   released = false;
   last_release_time = 0;
+  delay(300);
+  Serial.print("system begins");
+}
+
+int readXBeeString (char *strArray) {
+  int i = 0;
+  if(!XBee.available()) {
+    return -1;
+  }
+  while (XBee.available()) {
+    strArray[i] = XBee.read();
+    i++;
+  }
+  strArray[i] = '\0';
+  return i;
 }

 // should I abstract out the click event and then implement advanced ones?
 // well, so the question now is how you detect tap when you have fingers on the slider?
 // this is different from click, double click
-

 gesture_t sliderEvent(int *delta, int counts) {
   // all related events are detected here
   gesture_t returnV = gNONE;
   softpotReading = analogRead(softpotPin);
-  /* DEBUG_PRINT("   gStart_time: "); */
-  /* DEBUG_PRINT(gStart_time); */
-  /* DEBUG_PRINT("   clicks: "); */
-  /* DEBUG_PRINT(clicks); */
-  /* DEBUG_PRINT("   gState: "); */
-  /* DEBUG_PRINT(gState); */
-  /* DEBUG_PRINT("   Softpot Reading: "); */
-  /* DEBUG_PRINTLN(softpotReading); */
-
-  if (clicks > 0 && (millis() - gStart_time) > gResolution) {
+  DEBUG_PRINT("   gStart_time: ");
+  DEBUG_PRINT(gStart_time);
+  DEBUG_PRINT("   clicks: ");
+  DEBUG_PRINT(clicks);
+  DEBUG_PRINT("   gState: ");
+  DEBUG_PRINT(gState);
+  DEBUG_PRINT("   Softpot Reading: ");
+  DEBUG_PRINTLN(softpotReading);
+
+  if (gStart_time != 0 && (millis() - gStart_time) > gResolution) {
     gState = gIDLE;
     gStart_time = 0;
     if (softpotReading < SOFTPOT_THREASHOLD) {
-      if (clicks == 1) {
+      if (clicks == 0) {
+	returnV = gHOVER;
+      }
+      else if (clicks == 1) {
 	returnV = gTAP;
       }
       else if (clicks == 2) {
@@ -122,14 +124,12 @@
     clicks = 0;
     if (softpotReading < SOFTPOT_THREASHOLD) {
       gState = gPRESS;
+      gStart_time = millis();
       softpotInitV = softpotReading;
       return gHOVER;
     }
     break;
   case gPRESS:
-    if (clicks == 0) {
-      gStart_time = millis();
-    }
     if (softpotReading < SOFTPOT_THREASHOLD) {
       delta_threshold = SOFTPOT_DELTA_THREASHOLD;
       *delta = 0;
@@ -161,11 +161,13 @@
   // monitor the user input all the time
   // so everytime when loop executes, or at least in some states
   // we will see the results
-  if (state == IDLE) {
+  if (state == IDLE || state == CONNECTED) {
     g = sliderEvent(&changes, 0);
     if (g!= 0)
       DEBUG_PRINTLN(g);
   }
+  delay(10);
+  return;

   switch(state) {
   case IDLE:
@@ -324,17 +326,19 @@

     break;
   case CONNECTED:
-
     // based on gesture, define actions
-
-    // temporarily for debugging
-    delay(10000);
-
-    // disconnected
-    sendXBeePacketFromRaw(&XBee, XBeePacketArr[selectedXBee].id, "d", XBeePacketArr[selectedXBee].data);
-
-    state = IDLE;
-
+    if (g == gCLICK) {
+      sendXBeePacketFromRaw(&XBee, XBeePacketArr[selectedXBee].id, "i", "0001");
+      DEBUG_PRINTLN("[CONNECTED] commands 0001");
+      g = gNONE;
+    }
+    else if (g == gD_TAP) {
+      // disconnected
+      sendXBeePacketFromRaw(&XBee, XBeePacketArr[selectedXBee].id, "d", XBeePacketArr[selectedXBee].data);
+      DEBUG_PRINTLN("[DISCONNECTED] entering IDLE");
+      state = IDLE;
+      g = gNONE;
+    }
     break;
   default:
     break;


Uptime terminal tweaks

Uptime terminal tweaks

--- hvacMonitor.ino
+++ hvacMonitor.ino
@@ -142,8 +142,8 @@
   float secDur = millis() / 1000;
   float minDur = secDur / 60;
   float hourDur = minDur / 60;
-  terminal.println("--------------UPTIME  REPORT--------------");
-  terminal.println(String("HVAC uptime: ") + hourDur + " hours ");
+  terminal.println("------------ UPTIME REPORT ------------");
+  terminal.println(String("HVAC: ") + hourDur + " hours ");
   terminal.flush();
   }
 }


state machine should be ok, next is led test routine

--- piserverpanel/piserverpanel.ino
+++ piserverpanel/piserverpanel.ino
@@ -75,7 +75,8 @@
 void *server_hungup();            void animate_hungup();
 void *server_locked();            void animate_locked();
 void *system_reset();             void animate_reset();
-void *system_shutdown();  //async trigger in function detect_heartbeat();
+void *system_shutdown();          void animate_system_shutdown();
+//async trigger in function detect_heartbeat();

 //FSM
 typedef void *(*StateFunc)();
@@ -198,7 +199,6 @@
   delay(15);
 }

-<<<<<<< HEAD
 void signal_heartbeat_system_shutdown() {
   led_color(0,0,255);
   delay(10);
@@ -206,12 +206,6 @@
   delay(10);
   led_color(0,0,0);
   delay(15);
-=======
-//heartbeat detection
-long detect_heartbeat_any() {
-
->>>>>>> c774d8b760525d033ce5c35391565738e5727941
-}

 //heartbeat detection
 long detect_heartbeat_any() {
@@ -403,11 +397,15 @@
   delay(del);
 }

+void animate_locked() {
+
+}
+
 void animate_reset() {

 }

-void animate_locked() {
+void animate_system_shutdown() {

 }

@@ -612,7 +610,7 @@
       return system_reset;
     }

-    if (receivedHeartbeat > 0) {}
+    if (receivedHeartbeat > 0) {
       return server_running;
     } else {
       return server_hungup;
@@ -664,7 +662,7 @@
 }

 void *system_shutdown() {
-  animate_shutdown_active();
+  animate_system_shutdown();

   if (((millis()-track_uart) >= WAIT_TO_SEND)) {
     //send_();
@@ -673,19 +671,7 @@
   }

   if (digitalRead(SYSTEM_ON) == IS_ON) {
-
-    if ((digitalRead(BUTTON) == PUSHED) || (digitalRead(PUSHLOCK) == UNLOCKED)) {
-      delay(100);
-      send_abort_shutdown();
-    }
-
-    if (receivedHeartbeat > 0) {
-      send_ok();
-      return server_running;
-    } else {
-      return server_shutdown_active;
-    }
-
+    return system_shutdown;
   } else {
     if (digitalRead(PUSHLOCK) == LOCKED) {
       return server_locked;


add LED blinking

add LED blinking

--- examples/DIJN/test/test.ino
+++ examples/DIJN/test/test.ino
@@ -4,7 +4,14 @@

 #include <JeeLib.h>

+const byte LED = 9;
 byte counter;
+
+// turn the opn-bpard LED on or off
+static void led (bool on) {
+  pinMode(LED, OUTPUT);
+  digitalWrite(LED, on ? 0 : 1);
+}

 void setup () {
   // this is node 1 in net group 100 on the 868 MHz band
@@ -12,12 +19,16 @@
 }

 void loop () {
+  led(true);
+
   // standard idiom for waiting until we can send a new packet
   while (!rf12_canSend())
     rf12_recvDone();
   // actual packet send: broadcast to all, current counter, 1 byte long
   rf12_sendStart(0, &counter, 1);

+  led(false);
+
   // next time, the counter will be one higher (it'll wrap from 255 to 0)
   ++counter;
   // let one second pass before sending out the next packet


removed setPromiscuousMode()

removed setPromiscuousMode()

--- GVRET.ino
+++ GVRET.ino
@@ -728,7 +728,6 @@
 			   state = IDLE;
 			   //now, write out the new canbus settings to EEPROM
 			   EEPROM.write(EEPROM_PAGE, settings);
-			   setPromiscuousMode();
 			   break;
 		   }
 		   step++;


Stuck at 37mA sleep current with Arduino Pro (blue display, always on, and 4.7k ohm on interrupter)

--- fed-arduino/fed-arduino.ino
+++ fed-arduino/fed-arduino.ino
@@ -2,7 +2,6 @@
 #include <avr/power.h>
 #include <avr/wdt.h>
 #include <SdFat.h>                // SD and RTC libraries
-SdFat SD;
 #include "RTClib.h"
 #include <Wire.h>
 #include <Stepper.h>
@@ -14,11 +13,12 @@
 #include <SoftwareSerial.h>

-#define rxPin 255 // 255 because we don't need a receive pin
+#define DISPLAY_SERIAL_RX_PIN 255 // we don't need a receive pin, 255 indicates this
 // Connect the Arduino pin 3 to the rx pin on the 7 segment display
-#define txPin 9
-
-SoftwareSerial LEDserial = SoftwareSerial(rxPin, txPin);
+#define DISPLAY_SERIAL_TX_PIN 9
+
+SoftwareSerial LEDserial = SoftwareSerial(DISPLAY_SERIAL_RX_PIN, DISPLAY_SERIAL_TX_PIN);
+SdFat SD;

 long previousMillis = 0;
@@ -41,7 +41,7 @@
 const int steps = 64;
 const int MOTOR_STEPS_PER_REVOLUTION = 512;
 const int MOTOR_ENABLE12_PIN = 8;
-const int MOTOR_ENABLE34_PIN = 9;
+const int MOTOR_ENABLE34_PIN = 11;
 const int TTL = 3;

@@ -85,56 +85,55 @@
 }

 void setMotorToTurn() {
-    digitalWrite(MOTOR_ENABLE12_PIN, HIGH);
-    digitalWrite(MOTOR_ENABLE34_PIN, HIGH);
     pinMode(MOTOR_INPUT1_PIN, OUTPUT);
     pinMode(MOTOR_INPUT2_PIN, OUTPUT);
     pinMode(MOTOR_INPUT3_PIN, OUTPUT);
     pinMode(MOTOR_INPUT4_PIN, OUTPUT);
-}
-
-void setMotorToSleep() {
-    pinMode(MOTOR_INPUT1_PIN, INPUT);
-    pinMode(MOTOR_INPUT2_PIN, INPUT);
-    pinMode(MOTOR_INPUT3_PIN, INPUT);
-    pinMode(MOTOR_INPUT4_PIN, INPUT);
+
+    pinMode(MOTOR_ENABLE12_PIN, OUTPUT);
+    pinMode(MOTOR_ENABLE34_PIN, OUTPUT);
+    digitalWrite(MOTOR_ENABLE12_PIN, HIGH);
+    digitalWrite(MOTOR_ENABLE34_PIN, HIGH);
+}
+
+void setMotorToSleep()
+{
     digitalWrite(MOTOR_ENABLE12_PIN, LOW);
     digitalWrite(MOTOR_ENABLE34_PIN, LOW);
+
+    pinMode(MOTOR_INPUT1_PIN, INPUT_PULLUP);
+    pinMode(MOTOR_INPUT2_PIN, INPUT_PULLUP);
+    pinMode(MOTOR_INPUT3_PIN, INPUT_PULLUP);
+    pinMode(MOTOR_INPUT4_PIN, INPUT_PULLUP);
 }

 void setup()
 {
+  // make all unused pins inputs with pullups enabled by default, lowest power drain
+  // leave pins 0 & 1 (Arduino RX and TX) as they are
+  for (byte i=2; i <= 20; i++) {
+    pinMode(i, INPUT_PULLUP);
+  }
+  ADCSRA = 0;  // disable ADC as we won't be using it
+
   Serial.begin(9600);
   Serial.println(F("Starting up..."));

-  LEDserial.begin(9600); //Talk to the Serial7Segment at 9600 bps
-
-  DDRD &= B00000011;       // set Arduino pins 2 to 7 as inputs, leaves 0 & 1 (RX & TX) as is
-  DDRB = B00000000;        // set pins 8 to 13 as inputs
-  PORTD |= B11111100;      // enable pullups on pins 2 to 7M
-  PORTB |= B11111111;      // enable pullups on pins 8 to 13
-
-  pinMode(MOTOR_ENABLE12_PIN, OUTPUT);
-  pinMode(MOTOR_ENABLE34_PIN, OUTPUT);
-  digitalWrite(MOTOR_ENABLE12_PIN, HIGH);
-  digitalWrite(MOTOR_ENABLE34_PIN, HIGH);
-
-  pinMode(MOTOR_INPUT1_PIN, OUTPUT);
-  pinMode(MOTOR_INPUT2_PIN, OUTPUT);
-  pinMode(MOTOR_INPUT3_PIN, OUTPUT);
-  pinMode(MOTOR_INPUT4_PIN, OUTPUT);
+  // Display setup
+  LEDserial.begin(9600);
+  pinMode(DISPLAY_SERIAL_TX_PIN, OUTPUT);
+  setDisplayBrightness(64);
+  clearDisplay();
+  delay(1); // allow a very short delay for display response
+  setDisplayValues(pelletCount);
+
   pinMode(PIPin, INPUT);
   pinMode(TTL, OUTPUT);
   pinMode(CS_pin, OUTPUT);
   pinMode(SS, OUTPUT);
-  pinMode(9, OUTPUT);
-
-#ifdef AVR
+
   Wire.begin();
-#else
-  Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
-#endif
-  RTC.begin();
+  RTC.begin(); // RTC library needs Wire

   if (! RTC.isrunning()) {
     Serial.println(F("RTC is NOT running!"));
@@ -167,9 +166,6 @@
   }

   motor.setSpeed(35);
-
-
-
   delay (500);
 }

@@ -196,9 +192,9 @@
     logData();
     pelletCount ++;
     Serial.println(F("It did work"));
-    LEDserial.print("v"); // this is the reset display command
-    delay(5); // allow a very short delay for display response
-    LEDserial.print(pelletCount);
+    clearDisplay();
+    delay(1); // allow a very short delay for display response
+    setDisplayValues(pelletCount);
     lastState = PIState;

   }
@@ -226,17 +222,10 @@
     setMotorToSleep();
     enterSleep();
   }
-
-
-
-  delay(1000);
-
-  //  display.refresh();
-  //  updateCount();
-  //  pokeCount ++;
-  //  delay(1000);
-
-}
+
+  delay(100);
+}
+

 void timecounter(long timeNow) {

@@ -256,13 +245,12 @@

 }

+// utility function for digital clock display: prints colon and leading 0
 void printDigits(byte digits) {
-  // utility function for digital clock display: prints colon and leading 0
-  //Serial.print(":");
-  if (digits < 10)
+  if (digits < 10) {
     Serial.print('0');
+  }
   Serial.print(digits, DEC);
-  //time2 = String(digits);
 }

 void enterSleep()
@@ -278,8 +266,6 @@
   sleep_bod_disable();
   sei();
   sleep_cpu();
-
-
   sleep_disable();
 }

@@ -294,4 +280,27 @@
   power_all_enable();

 }
+
+// Send the clear display command (0x76)
+//  This will clear the display and reset the cursor
+void clearDisplay()
+{
+  LEDserial.write(0x76);  // Clear display command
+}
+
+// Set the displays brightness. Should receive byte with the value
+//  to set the brightness to
+//  dimmest------------->brightest
+//     0--------127--------255
+void setDisplayBrightness(byte value)
+{
+  LEDserial.write(0x7A);  // Set brightness command byte
+  LEDserial.write(value);  // brightness data byte
+}
+
+void setDisplayValues(int value)
+{
+  LEDserial.print(value);
+}
+


Almost done with inner loop support

Almost done with inner loop support

--- gcn_controller_v5/gcn_controller_v5.ino
+++ gcn_controller_v5/gcn_controller_v5.ino
@@ -182,12 +182,13 @@
 uint8_t current_macro_input[12];
 uint8_t old_macro_input[12];
 uint8_t macro_buffer[macroBufferSize][12];
-uint8_t macro_loop_metadata[macroMetadataSize][12]; // Contains informations such as how many times to repeat a portion of a macro, and where to start and end
+uint8_t inner_loop_metadata[macroMetadataSize][12]; // Contains informations such as how many times to repeat a portion of a macro, and where to start and end
 uint32_t controller = 0;

 void setup()
 {
   Serial.begin(baudRate);
+  Serial.println("Starting");

   pinMode(motorInput, INPUT);
   pinMode(turboLed, INPUT);
@@ -206,7 +207,7 @@
   }
   digitalWrite(latchPin, HIGH);

-  // Press the buttons X, Y and Start for 2 seconds to reset the controller,
+  // Press the buttons X, Y and Start for 3 seconds to reset the controller,
   // this is a built in controller feature to make it easier to reset analog sticks and
   // triggers without having to unplug the controller, thanks Nintendo, this feature is very useful!
   inputStatus[buttonX] = LOW;
@@ -222,9 +223,9 @@
   }
   digitalWrite(latchPin, HIGH);

-  delay(2000);
-
-  // Now we release the buttons X, Y and Start after 2 seconds have passed
+  delay(3000);
+
+  // Now we release the buttons X, Y and Start after 3 seconds have passed
   inputStatus[buttonX] = HIGH;
   inputStatus[buttonY] = HIGH;
   inputStatus[buttonStart] = HIGH;
@@ -284,7 +285,7 @@
   Serial.println(startingMacroMetadataIndex);
   Serial.println(endingMacroMetadataIndex);
   Serial.println(macroMetadataSize);
-
+  Serial.println("Ready to go");
 }

 void loop()
@@ -351,9 +352,26 @@
       macroInputsToRun = serial_rx_buffer[1];
       loopMacro = serial_rx_buffer[2];
       currentMacroIndexRunning = serial_rx_buffer[3];
-      timesToLoop = serial_rx_buffer[4]; // Times to repeat, if == 0, it'll not repeat, if != 0, it'll repeat n times, so in this case, gramatically speaking, timesToLoop and times to repeat are different things (does this make sense?), so the max amount of times it can loop is 256, the amount of times it can repeat is 255, the first iteration is not a repetition (Repeat input? Repeated input?) (Again, does this makes sense?)
+      timesToLoop = serial_rx_buffer[4]; // Times to repeat, if <=0, it'll not repeat, if >0, it'll repeat n times, so in this case, gramatically speaking, timesToLoop and times to repeat are different things (does this make sense?), so the max amount of times it can loop is 256, the amount of times it can repeat is 255, the first iteration is not a repetition (Repeat input? Repeated input?) (Again, does this makes sense?)
       loopCounter = serial_rx_buffer[5];
-      howManyInnerLoopsMacroHas = serial_rx_buffer[6]; // Different than 0 if there are, 0 if there aren't
+      howManyInnerLoopsMacroHas = serial_rx_buffer[6]; // >0 if there are, <=0 if there aren't
+      // The block below resets all inner loop metadata counters
+      if (howManyInnerLoopsMacroHas > 0) {
+        Serial.println("TEST ABC");
+        macroMetadataIndex = 0;
+        if (inner_loop_metadata[0][1] > 0 && inner_loop_metadata[0][3] > 0) {
+          Serial.println("TEST DEF");
+          macroMetadataIndex = 0;
+          for (uint8_t macroMetadataIndexInner = 0; macroMetadataIndexInner < howManyInnerLoopsMacroHas; macroMetadataIndexInner++) {
+            Serial.print("BEFORE macroMetadataIndexInner = ");
+            Serial.println(macroMetadataIndexInner);
+            inner_loop_metadata[macroMetadataIndexInner][2] = 0; // Reset current input index for inner loop
+            inner_loop_metadata[macroMetadataIndexInner][4] = 0; // Reset current repeat counter for inner loop
+            Serial.print("AFTER macroMetadataIndexInner = ");
+            Serial.println(macroMetadataIndexInner);
+          }
+        }
+      }
       //isInputting = true;
       //previousInputDelay = millis();
     }
@@ -374,26 +392,27 @@
           isInputtingDelayed = false;
           macroMetadataIndex = serial_rx_buffer[0] - startingMacroMetadataIndex;
           /*
-            macro_loop_metadata[macroMetadataIndex][0] = 0; // Preamble
-            macro_loop_metadata[macroMetadataIndex][1] = 0; // Inputs to execute (number of inputs that should be executed in this inner loop) (Use same logic as [5] here instead?)
-            macro_loop_metadata[macroMetadataIndex][2] = 0; // Current input index
-            macro_loop_metadata[macroMetadataIndex][3] = 0; // Times to repeat (number of times this inner loop should be executed, before going to the next inner loop, if any)
-            macro_loop_metadata[macroMetadataIndex][4] = 0; // Repeat counter (number of times this inner loop was executed)
-            macro_loop_metadata[macroMetadataIndex][5] = 0; // Where is the next inner loop's first input (index 0 input for the next inner loop, aka the index for the input in the macro_buffer array) (Continue normally if value is 0, or do nothing if there are no more inputs to be executed)
-            macro_loop_metadata[macroMetadataIndex][6] = 0; // Where to start (index of the starting input) (Inclusive)
-            macro_loop_metadata[macroMetadataIndex][7] = 0; // Where to end (index of the ending input) (Inclusive)
-            macro_loop_metadata[macroMetadataIndex][8] = 0; // How many inner loops that should be executed after this (if <=0, don't execute inner loops any inner loops after this, and move on as normal, if there are normal inputs to be exeucuted, execute those, if there's nothing else to do, go back to the beginning of the larger loop, if > 0, execute n inner loops after this)
-            macro_loop_metadata[macroMetadataIndex][9] = 0; // Unused?
-            macro_loop_metadata[macroMetadataIndex][10] = 0; // Unused?
-            macro_loop_metadata[macroMetadataIndex][11] = 0; // Postamble
+            inner_loop_metadata[macroMetadataIndex][0] = 0; // Preamble
+            inner_loop_metadata[macroMetadataIndex][1] = 0; // Inputs to execute (number of inputs that should be executed in this inner loop) (Use same logic as [5] here instead?)
+            inner_loop_metadata[macroMetadataIndex][2] = 0; // Current input index
+            inner_loop_metadata[macroMetadataIndex][3] = 0; // Times to repeat (number of times this inner loop should be executed, before going to the next inner loop, if any)
+            inner_loop_metadata[macroMetadataIndex][4] = 0; // Repeat counter (number of times this inner loop was executed)
+            inner_loop_metadata[macroMetadataIndex][5] = 0; // Where is the next inner loop's first input (index 0 input for the next inner loop, aka the index for the input in the macro_buffer array) (Continue normally if value is 0, or do nothing if there are no more inputs to be executed) // Current unused, apply logic to this
+            inner_loop_metadata[macroMetadataIndex][6] = 0; // Where to start (index of the starting input) (Inclusive)
+            inner_loop_metadata[macroMetadataIndex][7] = 0; // Where to end (index of the ending input) (Inclusive)
+            inner_loop_metadata[macroMetadataIndex][8] = 0; // How many inner loops that should be executed after this (if <=0, don't execute inner loops any inner loops after this, and move on as normal, if there are normal inputs to be exeucuted, execute those, if there's nothing else to do, go back to the beginning of the larger loop, if > 0, execute n inner loops after this) // Currently unused, apply logic to this
+            inner_loop_metadata[macroMetadataIndex][9] = 0; // Unused?
+            inner_loop_metadata[macroMetadataIndex][10] = 0; // Unused?
+            inner_loop_metadata[macroMetadataIndex][11] = 0; // Postamble
           */
           for (uint8_t macroInputMetadataIndex = 0; macroInputMetadataIndex < sizeof(serial_rx_buffer); macroInputMetadataIndex++) {
-            macro_loop_metadata[macroMetadataIndex][macroInputMetadataIndex] = serial_rx_buffer[macroInputMetadataIndex];
+            inner_loop_metadata[macroMetadataIndex][macroInputMetadataIndex] = serial_rx_buffer[macroInputMetadataIndex];
             //Serial.print("macroMetadataIndex = ");
             //Serial.println(macroMetadataIndex);
             //Serial.print("macroInputMetadataIndex = ");
             //Serial.println(macroInputMetadataIndex);
-            Serial.println(macro_loop_metadata[macroMetadataIndex][macroInputMetadataIndex]);
+            Serial.println("Toast");
+            Serial.println(inner_loop_metadata[macroMetadataIndex][macroInputMetadataIndex]);
           }
           //Serial.println("");
         }
@@ -444,12 +463,12 @@
             //Serial.println("\r\nTEST B");
             //
             currentMacroMetadataIndexRunning = currentMacroIndexRunning + startingMacroMetadataIndex;
-            if (macro_loop_metadata[currentMacroIndexRunning][2] == currentMacroMetadataIndexRunning) {
+            if (inner_loop_metadata[currentMacroIndexRunning][2] == currentMacroMetadataIndexRunning) {
               //Serial.println("");
               //Serial.println("YEAH 2");
               //Serial.println("");
             }
-            if (macro_loop_metadata[currentMacroIndexRunning][2] == currentMacroIndexRunning) {
+            if (inner_loop_metadata[currentMacroIndexRunning][2] == currentMacroIndexRunning) {
               //Serial.println("");
               //Serial.print("currentMacroMetadataIndexRunning = ");
               //Serial.println(currentMacroMetadataIndexRunning);
@@ -462,8 +481,8 @@
               Serial.println(startingMacroMetadataIndex);
               Serial.print("currentMacroIndexRunning = ");
               Serial.println(currentMacroIndexRunning);
-              Serial.print("macro_loop_metadata[currentMacroIndexRunning][2] = ");
-              Serial.println(macro_loop_metadata[currentMacroIndexRunning][2]);
+              Serial.print("inner_loop_metadata[currentMacroIndexRunning][2] = ");
+              Serial.println(inner_loop_metadata[currentMacroIndexRunning][2]);
               Serial.print("currentMacroMetadataIndexRunning = ");
               Serial.println(currentMacroMetadataIndexRunning);
             */
@@ -493,62 +512,73 @@
         if (howManyInnerLoopsMacroHas > 0) {
           // This is where inner loop logic goes (???)
           Serial.println("This macro has inner loops");
-          if (macro_loop_metadata[macroMetadataIndex][1] > 0 && macro_loop_metadata[macroMetadataIndex][3] > 0) {
+          if (inner_loop_metadata[macroMetadataIndex][1] > 0 && inner_loop_metadata[macroMetadataIndex][3] > 0) {
             // Do something
             Serial.println("This inner loop metadata is valid");
             Serial.print("A currentMacroIndexRunning  = ");
             Serial.println(currentMacroIndexRunning);
-            if (macro_loop_metadata[macroMetadataIndex][3] > 0 && macro_loop_metadata[macroMetadataIndex][4] <= macro_loop_metadata[macroMetadataIndex][3]) {
+            if (inner_loop_metadata[macroMetadataIndex][3] > 0 && inner_loop_metadata[macroMetadataIndex][4] <= inner_loop_metadata[macroMetadataIndex][3]) {
               Serial.println("TEST");
-              if (macro_loop_metadata[macroMetadataIndex][2] < macro_loop_metadata[macroMetadataIndex][6]) {
+              if (inner_loop_metadata[macroMetadataIndex][2] < inner_loop_metadata[macroMetadataIndex][6]) {
                 // Current input index is lower than starting index, fix this
+                // Write inner loop metadata back to PC here
                 Serial.println("Current input index for current inner loop is below what it is supposed to be, fix that!");
                 Serial.print("B currentMacroIndexRunning  = ");
                 Serial.println(currentMacroIndexRunning);
-                macro_loop_metadata[macroMetadataIndex][2] = macro_loop_metadata[macroMetadataIndex][6];
-                currentMacroIndexRunning = macro_loop_metadata[macroMetadataIndex][6];
+                inner_loop_metadata[macroMetadataIndex][2] = inner_loop_metadata[macroMetadataIndex][6];
+                currentMacroIndexRunning = inner_loop_metadata[macroMetadataIndex][6];
                 Serial.print("C currentMacroIndexRunning  = ");
                 Serial.println(currentMacroIndexRunning);
+                // Write inner loop metadata back to PC here
               }
-              if (macro_loop_metadata[macroMetadataIndex][2] >= macro_loop_metadata[macroMetadataIndex][6] && currentMacroIndexRunning <= macro_loop_metadata[macroMetadataIndex][7]) {
-                // Current input index is lower than starting index, fix this
+              if (inner_loop_metadata[macroMetadataIndex][2] >= inner_loop_metadata[macroMetadataIndex][6] && currentMacroIndexRunning <= inner_loop_metadata[macroMetadataIndex][7]) {
+                // Current input index is valid
+                // Write inner loop metadata back to PC here
                 Serial.println("Current input index for current inner loop is in the valid range!");
                 Serial.print("D currentMacroIndexRunning  = ");
                 Serial.println(currentMacroIndexRunning);
                 currentMacroIndexRunning++;
-                macro_loop_metadata[macroMetadataIndex][2]++;
+                inner_loop_metadata[macroMetadataIndex][2]++;
                 Serial.print("E currentMacroIndexRunning  = ");
                 Serial.println(currentMacroIndexRunning);
+                // Write inner loop metadata back to PC here
               }
-              if (macro_loop_metadata[macroMetadataIndex][2] > macro_loop_metadata[macroMetadataIndex][7]) {
+              if (inner_loop_metadata[macroMetadataIndex][2] > inner_loop_metadata[macroMetadataIndex][7]) {
                 // Inner loop ended?
+                // Write inner loop metadata back to PC here
                 Serial.println("Inner loop ended");
                 Serial.print("F currentMacroIndexRunning  = ");
                 Serial.println(currentMacroIndexRunning);
-                currentMacroIndexRunning = macro_loop_metadata[macroMetadataIndex][6];
-                macro_loop_metadata[macroMetadataIndex][2] = macro_loop_metadata[macroMetadataIndex][6];
-                macro_loop_metadata[macroMetadataIndex][4]++;
-                Serial.print("macro_loop_metadata[macroMetadataIndex][4] = ");
-                Serial.println(macro_loop_metadata[macroMetadataIndex][4]);
+                currentMacroIndexRunning = inner_loop_metadata[macroMetadataIndex][6];
+                inner_loop_metadata[macroMetadataIndex][2] = inner_loop_metadata[macroMetadataIndex][6];
+                inner_loop_metadata[macroMetadataIndex][4]++;
+                Serial.print("inner_loop_metadata[macroMetadataIndex][4] = ");
+                Serial.println(inner_loop_metadata[macroMetadataIndex][4]);
                 Serial.print("G currentMacroIndexRunning  = ");
                 Serial.println(currentMacroIndexRunning);
+                // Write inner loop metadata back to PC here
               }
             }
-            if (macro_loop_metadata[macroMetadataIndex][3] > 0 && macro_loop_metadata[macroMetadataIndex][4] > macro_loop_metadata[macroMetadataIndex][3]) {
-              Serial.println("Broke out from inner loop?");
+            if (inner_loop_metadata[macroMetadataIndex][3] > 0 && inner_loop_metadata[macroMetadataIndex][4] > inner_loop_metadata[macroMetadataIndex][3]) {
+              Serial.println("Broke out from inner loop?");
               Serial.print("H currentMacroIndexRunning  = ");
               Serial.println(currentMacroIndexRunning);
-              currentMacroIndexRunning = macro_loop_metadata[macroMetadataIndex][7] + 1;
+              //currentMacroIndexRunning = inner_loop_metadata[macroMetadataIndex][7] + 1;
+              macroMetadataIndex++;
               Serial.print("I currentMacroIndexRunning  = ");
               Serial.println(currentMacroIndexRunning);
             }
             Serial.print("J currentMacroIndexRunning  = ");
             Serial.println(currentMacroIndexRunning);
           }
-          if (macro_loop_metadata[macroMetadataIndex][1] <= 0 || macro_loop_metadata[macroMetadataIndex][3] <= 0) {
+          if (inner_loop_metadata[macroMetadataIndex][1] <= 0 || inner_loop_metadata[macroMetadataIndex][3] <= 0) {
             // Ignore this inner loop, it is not valid
             Serial.println("This inner loop metadata is not valid");
+            Serial.print("K currentMacroIndexRunning  = ");
+            Serial.println(currentMacroIndexRunning);
             currentMacroIndexRunning++;
+            Serial.print("L currentMacroIndexRunning  = ");
+            Serial.println(currentMacroIndexRunning);
           }
         }
         //Serial.print("B AFTER currentMacroIndexRunning = ");
@@ -566,9 +596,26 @@
             //
             }
           */
+          // The block below resets all inner loop metadata counters
+          if (howManyInnerLoopsMacroHas > 0) {
+            Serial.println("TEST ABC");
+            macroMetadataIndex = 0;
+            if (inner_loop_metadata[0][1] > 0 && inner_loop_metadata[0][3] > 0) {
+              Serial.println("TEST DEF");
+              macroMetadataIndex = 0;
+              for (uint8_t macroMetadataIndexInner = 0; macroMetadataIndexInner < howManyInnerLoopsMacroHas; macroMetadataIndexInner++) {
+                Serial.print("BEFORE macroMetadataIndexInner = ");
+                Serial.println(macroMetadataIndexInner);
+                inner_loop_metadata[macroMetadataIndexInner][2] = 0; // Reset current input index for inner loop
+                inner_loop_metadata[macroMetadataIndexInner][4] = 0; // Reset current repeat counter for inner loop
+                Serial.print("AFTER macroMetadataIndexInner = ");
+                Serial.println(macroMetadataIndexInner);
+              }
+            }
+          }
           if (timesToLoop > 0 && loopCounter <= timesToLoop) {
             // Sending this block for redundancy sake, will comment this block if something goes wrong (it shouldn't)
-            Serial.print("E BEFORE loopCounter = ");
+            Serial.print("M BEFORE loopCounter = ");
             Serial.println(loopCounter);
             Serial.write(endingMacroIndex);
             Serial.write(macroInputsToRun);
@@ -595,7 +642,7 @@
             Serial.write(0x00);
             Serial.write(0x00);
             Serial.write(endingMacroIndex);
-            Serial.print("F AFTER loopCounter = ");
+            Serial.print("N AFTER loopCounter = ");
             Serial.println(loopCounter);
           }
         }
@@ -644,7 +691,7 @@
         //Serial.println("TEST");
       }
       /*
-        if (current_macro_input[2] == macro_loop_metadata[currentMacroIndexRunning][2]) {
+        if (current_macro_input[2] == inner_loop_metadata[currentMacroIndexRunning][2]) {
         //
         //Serial.println("TEST");
         }


v 19.14 Remove test code

v 19.14 Remove test code

--- GPSLCD.ino
+++ GPSLCD.ino
@@ -677,13 +677,13 @@
   if (UTCOffset < 0) {
     // West of Greenwich, subtract
     UTCOffset = abs(UTCOffset); // Make offset positive
-//    if (DST) UTCOffset -= 1; // Compensate for DST
+    if (DST) UTCOffset -= 1; // Compensate for DST
     if (*hour <= UTCOffset) *hour += 24;
     *hour -= UTCOffset; // Subtract offset
   }
   else {
     // East of Greenwich, add
-//    if (DST) - UTCOffset; // Compensate for DST.
+    if (DST) - UTCOffset; // Compensate for DST.
     if (*hour <= UTCOffset) *hour += 24;
     *hour += UTCOffset; // Add offset
   }


working nunchuck control

working nunchuck control

--- uArm.ino
+++ uArm.ino
@@ -261,19 +261,15 @@
 // nunchuk
 ArduinoNunchuk nunchuk = ArduinoNunchuk();
 bool nunchukControlMode = false;
-bool nunchukControlJustEntered = false;
-bool nunchukControlJustExited = false;

 void nunchukControlModeToggle(void) {
 	nunchukControlMode = !nunchukControlMode;
 	if (nunchukControlMode) {
 		sendMsgF(MSG_NCM_ON);
 		messageScrollSet("NCM+");
-		nunchukControlJustEntered = true;
 	} else {
 		sendMsgF(MSG_NCM_OFF);
 		messageScrollSet("NCM-");
-		nunchukControlJustExited = true;
 	}
 	messageScrollUpdate(true);
 }
@@ -284,38 +280,51 @@
 		return true;
 	return false;
 }
-#define NUNCHUK_SWEEP_SCALE DEFAULT_SERVO_SWEEP_SPEED / 2
+#define NUNCHUK_SWEEP_SCALE DEFAULT_SERVO_SWEEP_SPEED * 2

 void nunchukControlModeUpdate() {
+	uint8_t pos;
+
 	nunchuk.update();
+
 	// the Z-Button disables nunchukcontrolmode
-	// but only if we didn't just enable it
-	//	i.e. it is still pressed from enabling the mode
 	if (nunchuk.zButton)
-		if (!nunchukControlJustEntered && !nunchukControlJustExited)
-			nunchukControlModeToggle();
+		nunchukControlModeToggle();
 	else  {
-		nunchukControlJustEntered = false;
-		nunchukControlJustExited = false;
-
-		Serial.print("update\n");
 		if (!nunchukControlMode)
 			return;
 		// if the stick is centered, hold the current position
 		if (nunchukControlIsDeadzone(nunchuk.analogX)) {
-			moveServo(servoRot, widgetRot, servoRot.read(), 10, false, true);
-			Serial.print("deadzone\n");
+			moveServo(servoRot, widgetRot, servoRot.read(), DEFAULT_SERVO_SWEEP_SPEED, false, true);
 		} else if (nunchuk.analogX < 127) {
 			// rotate
-			moveServo(servoRot, widgetRot, 0, (127 - nunchuk.analogX) / NUNCHUK_SWEEP_SCALE, false, true);
-			Serial.print("less\n");
+			pos = config.servoSafe[EEPROM_CONFIG_SERVO_ROT].min;
+			moveServo(servoRot, widgetRot, 30, map(nunchuk.analogX, 127, 0, 0, NUNCHUK_SWEEP_SCALE), false, true);
+			//moveServo(servoRot, widgetRot, 30, DEFAULT_SERVO_SWEEP_SPEED, false, true);
 		} else {
-			moveServo(servoRot, widgetRot, 180, (nunchuk.analogX - 127) / NUNCHUK_SWEEP_SCALE, false, true);
-			Serial.print("more\n");
+			pos = config.servoSafe[EEPROM_CONFIG_SERVO_ROT].max;
+			moveServo(servoRot, widgetRot, 120, map(nunchuk.analogX, 127, 255, 0, NUNCHUK_SWEEP_SCALE), false, true);
+			//moveServo(servoRot, widgetRot, 120, DEFAULT_SERVO_SWEEP_SPEED, false, true);
 		}
 		if (nunchukControlIsDeadzone(nunchuk.analogY)) {
-			moveServo(servoL, widgetL, servoL.read(), 10, true, true);
-			moveServo(servoR, widgetR, servoR.read(), 10, true, true);
+			moveServo(servoL, widgetL, servoL.read(), DEFAULT_SERVO_SWEEP_SPEED, true, true);
+			moveServo(servoR, widgetR, servoR.read(), DEFAULT_SERVO_SWEEP_SPEED, true, true);
+		} else if (nunchuk.analogY < 127) {
+			if (nunchuk.cButton) {
+				pos = config.servoSafe[EEPROM_CONFIG_SERVO_R].min;
+				moveServo(servoR, widgetR, pos, map(nunchuk.analogY, 127, 0, 0, NUNCHUK_SWEEP_SCALE), false, true);
+			} else {
+				pos = config.servoSafe[EEPROM_CONFIG_SERVO_L].min;
+				moveServo(servoL, widgetL, pos, map(nunchuk.analogY, 127, 0, 0, NUNCHUK_SWEEP_SCALE), false, true);
+			}
+		} else {
+			if (nunchuk.cButton) {
+				pos = config.servoSafe[EEPROM_CONFIG_SERVO_R].max;
+				moveServo(servoR, widgetR, pos, map(nunchuk.analogY, 127, 255, 0, NUNCHUK_SWEEP_SCALE), false, true);
+			} else {
+				pos = config.servoSafe[EEPROM_CONFIG_SERVO_L].max;
+				moveServo(servoL, widgetL, pos, map(nunchuk.analogY, 127, 255, 0, NUNCHUK_SWEEP_SCALE), false, true);
+			}
 		}
 	}
 }
@@ -942,9 +951,8 @@
 		if (cycles == CYCLES_RESET_COUNT)
 			cycles = 0;

-		// if we are in the nunchuk control mode
-		// or once per CYCLES_RESET_COUNT cycles check for a Z-button press
-		if (nunchukControlMode || cycles == 0)
+		// if we are in the nunchuk control mode run the update code
+		if (nunchukControlMode)
 			nunchukControlModeUpdate();
 	}
 }


戦車側の基本プログラムを作成した。

戦車側の基本プログラムを作成した。

--- tank/src/sketch.ino
+++ tank/src/sketch.ino
@@ -1,8 +1,152 @@
+/* Arduinoで戦車を動かすためのプログラム
+author:4869 */

-void setup()
-{
+#include<Servo.h>
+
+//定数宣言
+#define MAX 250
+#define NOM 100
+
+//上の回線部分
+const int Turn_A = 2;
+const int Turn_B = 3;
+
+//右モーター
+const int Right_A = 4;
+const int Right_B = 5;
+const int Right_PWM = 6; //速度調整用のアナログピン
+
+//左モーター
+const int Left_PWM = 11;
+const int Left_A = 12;
+const int Left_B = 13;
+
+//砲台の上下
+Servo myservo;
+
+//シリアル通信で使う文字の宣言
+char ch = 'R';
+
+//設定について記述
+void setup(){
+  //シリアルポートの設定
+  Serial.begin(9600);
+  //デジタルピンの設定
+  pinMode(Turn_A,OUTPUT);
+  pinMode(Turn_B,OUTPUT);
+  pinMode(Right_A,OUTPUT);
+  pinMode(Right_B,OUTPUT);
+  pinMode(Left_A,OUTPUT);
+  pinMode(Left_B,OUTPUT);
+  myservo.attach(9);
 }

-void loop()
-{
+/*   独自関数を記述します  */
+
+//砲台の回転に関する関数
+//砲台右回転
+void Turn_Right(void){
+  digitalWrite(Turn_A,HIGH);
+  digitalWrite(Turn_B,LOW);
 }
+
+//砲台左回転
+void Turn_Left(void){
+  digitalWrite(Turn_A,LOW);
+  digitalWrite(Turn_B,HIGH);
+}
+
+//砲台回転ストップ
+void Turn_Stop(void){
+  digitalWrite(Turn_A,LOW);
+  digitalWrite(Turn_B,LOW);
+}
+
+//右側モーターに関する関数
+//右のモーターを前に回転させる
+void Right_go(void){
+  digitalWrite(Right_A,HIGH);
+  digitalWrite(Right_B,LOW);
+  analogWrite(Right_PWM,MAX);
+}
+
+//右のモーターを後ろに回転させる
+void Right_back(void){
+  digitalWrite(Right_A,LOW);
+  digitalWrite(Right_B,HIGH);
+  analogWrite(Right_PWM,MAX);
+}
+
+//右のモーターを止める
+void Right_stop(void){
+  digitalWrite(Right_A,LOW);
+  digitalWrite(Right_B,LOW);
+}
+
+//左側のモーターに関する関数
+//左のモーターを前に回転させる
+void Left_go(void){
+  digitalWrite(Left_A,HIGH);
+  digitalWrite(Left_B,LOW);
+  analogWrite(Left_PWM,MAX);
+}
+
+//左のモーターを後ろに回転させる
+void Left_back(void){
+  digitalWrite(Left_A,LOW);
+  digitalWrite(Left_B,HIGH);
+  analogWrite(Left_PWM,MAX);
+}
+
+//左のモーターを止める
+void Left_stop(void){
+  digitalWrite(Left_A,LOW);
+  digitalWrite(Left_B,LOW);
+}
+
+//砲台の上下に関する関数
+
+
+/*メイン関数
+  (実際行う処理を書く関数。この関数はループするので終わることはない)*/
+
+void loop(){
+  //シリアルを受信している間
+  while(Serial.available()){
+	//シリアルの文字列をchに代入する
+	ch = Serial.read();
+	//chの文字によって処理を変える
+	switch(ch){
+	  case 's':{ //送られてきた文字がsの場合
+				 //左右のモーターをどちらもストップさせる→止める
+				 Right_stop();
+				 Left_stop();
+				 break; //これがないとそのまま下の処理に行ってしまう
+			   }
+	  case 'g':{ //gの場合
+				 //左右のモーターをどちらも進める→前に進める
+				 Right_go();
+				 Left_go();
+				 break;
+			   }
+	  case 'b':{ //bの場合
+				 //左右どちらのモーターも後ろに進める→バックさせる
+				 Right_back();
+				 Left_back();
+				 break;
+			   }
+	  case 'r':{
+				 Turn_Right();
+				 break;
+			   }
+	  case 'l':{
+				 Turn_Left();
+				 break;
+			   }
+	  case 'n':{
+				 Turn_Stop();
+				 break;
+			   }
+	}
+  }
+}


tweak fona button pin to match tutorial

tweak fona button pin to match tutorial

--- arduino-fona/digital-in/digital-in.ino
+++ arduino-fona/digital-in/digital-in.ino
@@ -24,7 +24,7 @@
 #include "Adafruit_MQTT_FONA.h"

 /****************************** Pins ****************************************/
-#define BUTTON      5
+#define BUTTON      8
 #define FONA_RX     2
 #define FONA_TX     3
 #define FONA_RST    4


added bridge for Yun

added bridge for Yun

--- mecosystem/mecosystem.ino
+++ mecosystem/mecosystem.ino
@@ -1,7 +1,25 @@
-// MIT License
-//Hannon
-// channon@hawk.iit.edu
-//support@mecosystemlabs.com
+#include <Bridge.h>
+#include <Console.h>
+#include <FileIO.h>
+#include <HttpClient.h>
+#include <Mailbox.h>
+#include <Process.h>
+#include <YunClient.h>
+#include <YunServer.h>
+
+/* MIT License
+ *Hannon
+ * channon@hawk.iit.edu
+ *support@mecosystemlabs.com
+ *
+ *
+ *
+ */
+
+#define YUN_SERVER_PORT 1993
+
+
+
 /* Data Pins*/
 #define lightT 3
 #define lightB  4
@@ -11,6 +29,8 @@
 #define other 8
 #define temp 9
 #define ph A0
+
+//global variables
 //data variables
 //min on
 int lightTmin = 0;
@@ -27,13 +47,22 @@
 int lightTdmin = 0;
 int lightBdmin = 0;
 int lightFdmin = 0;
+//pump
 int pumpFreq = 90; //min
 int pumpD = 210; // sec
+//temp
 int setTemp = 78;
+//time
 int s = 55;
 int m = 25;
 int h = 10;
+//flag
 int sched = 0;
+
+//server stuff
+YunServer server(YUN_SERVER_PORT);
+YunClient client;
+
 void setup() {
   // put your setup code here, to run once:
   pinMode(3, OUTPUT);
@@ -44,7 +73,7 @@
   pinMode(8, OUTPUT);
   pinMode(9, INPUT);
   pinMode(A0, INPUT);
-  Serial.begin(9600);
+  Serial.begin(115200);
   // initialize timer1
   noInterrupts();           // disable all interrupts
   TCCR1A = 0;
@@ -55,9 +84,16 @@
   TCCR1B |= (1 << CS12);    // 256 prescaler
   TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
   interrupts();             // enable all interrupts
-}
-ISR(TIMER1_COMPA_vect)          // timer compare interrupt service routine
-{
+
+//setup bridge
+  Bridge.begin();
+  server.listenOnLocalhost();
+  server.begin();
+
+}
+
+
+ISR(TIMER1_COMPA_vect) {          // timer compare interrupt service routine
   s++;
   if (s == 60) {
     //mina ++
@@ -131,6 +167,26 @@
     }
   }
   delay(500);
+
+  if(client.connected()) {
+     //handle client
+     String data = (String(lightTmin)+','+String(lightBmin)+','+String(lightFmin)+','+
+             String(lightThr)+','+String(lightBhr)+','+String(lightFhr)+','+
+             String(lightTdhr)+','+String(lightBdhr)+','+String(lightFdhr)+','+
+             String(lightTdmin)+','+String(lightBdmin)+','+String(lightFdmin)+','+
+             String(pumpFreq)+','+String(pumpD)+','+
+             String(setTemp)+','+
+             String(s)+','+String(m)+','+String(h)
+             );
+     client.println(data);
+  }
+  else {
+     client = server.accept();
+      if (client.connected()) {
+         Serial.println("User is connected!");
+      }
+  }
+
   Serial.print(h);
   Serial.print(":");
   Serial.print(m);


Update bumper reactions to hopefully stop it bumping into the same thing over and over

--- software/firmware/LogoBotIRSeeker/LogoBotIRSeeker.ino
+++ software/firmware/LogoBotIRSeeker/LogoBotIRSeeker.ino
@@ -150,7 +150,7 @@
         // Just hit something, so stop, buzz and backoff
         Serial.println("Ouch!");
         action = Retreat;
-        lastScanMove = millis() + 2000;
+        lastScanMove = millis() + 5000;
         bot.emergencyStop();
         bot.buzz(250);
     }
@@ -160,19 +160,19 @@
     if (collisionData == 1) { // Front Left
         lookAng=135;
         bot.drive(-20);
-        bot.turn(-30);
+        bot.turn(-175);
     } else if (collisionData == 2) { // Front Right
         lookAng=45;
         bot.drive(-20);
-        bot.turn(60);
+        bot.turn(165);
     } else if (collisionData == 4) { // Back left
         lookAng=180;
         bot.drive(20);
-        bot.turn(60);
+        bot.turn(150);
     } else if (collisionData == 8) { // Back right
         lookAng=0;
         bot.drive(20);
-        bot.turn(-25);
+        bot.turn(-165);
     } else if (collisionData != 0) {
         bot.turn(-90);
     }


Update RS485_UnoR3_Slave.ino

Update RS485_UnoR3_Slave.ino

--- rs485/RS485_UnoR3_Slave.ino
+++ rs485/RS485_UnoR3_Slave.ino
@@ -7,10 +7,6 @@
 const int colorR = 255;
 const int colorG = 0;
 const int colorB = 0;
-
-int sensorValue = 0;
-int outputValue = 0;
-

 #define  LED 8

@@ -41,7 +37,7 @@
 {

   modbus_update();
-  holdingRegs[ADC_VAL] = analogRead(A0);
+//  holdingRegs[ADC_VAL] = analogRead(A0);

  digitalWrite(LED, HIGH);
  delay(holdingRegs[PWM_VAL]);


Delete 4ledblink.ino

Delete 4ledblink.ino

--- sFDW/examples/4ledblink.ino
+++ sFDW/examples/4ledblink.ino
@@ -1,47 +0,0 @@
-/*
-  Blink sketch for sFDW library
-  Turns on an 4 LEDs on for one second in sequence,
-  then off all at once, then on all at once, after on all at once,
-  and turn off all 4 LEDs separately.
-  And all this actions repeatedly.
-  Functions of this library:
-	- sPin(pin №, pin HIGH/LOW status <1/0> )
-	- mPinsStateHigh(pins numbers for HIGH state switch, as array - separate by ",")
-	- mPinsStateLow(pins numbers for LOW state switch, as array - separate by ",")
-  Created by Dmitry Pogudo-Georgov, December 3, 2014.
-  This example code is in the public domain.
- */
-
-// Pins 6,7,8,9 has an LEDs connected on most Arduino boards.
-#include <sFDW.h>
-
-// the setup routine runs once when you press reset:
-void setup() {}
-
-// the loop routine runs over and over again forever:
-void loop() {
-  sFDW.sPin(6,1);   // turn the LED on (HIGH is the voltage level)
-  delay(1000);               // wait for a second
-  sFDW.sPin(7,1);
-  delay(1000);
-  sFDW.sPin(8,1);
-  delay(1000);
-  sFDW.sPin(9,1);
-  delay(1000);
-
-  sFDW.mPinsStateLow(6,7,8,9);  // turn the LED off by making the voltage LOW in all ours pins
-  delay(1000);                  // wait for a second
-
-  sFDW.mPinsStateHigh(6,7,8,9); // turn the LED on by making the voltage HIGH in all ours pins
-  delay(1000);                  // wait for a second
-
-  sFDW.sPin(6,0);   // turn the LED off (LOW is the voltage level)
-  delay(1000);               // wait for a second
-  sFDW.sPin(7,0);
-  delay(1000);
-  sFDW.sPin(8,0);
-  delay(1000);
-  sFDW.sPin(9,0);
-  delay(1000);
-
-}


Fix rows and columns of bricks

Fix rows and columns of bricks

The number of columns and rows was wrong which made it impossible to go
to level 2.

--- examples/ArduBreakout/ArduBreakout.ino
+++ examples/ArduBreakout/ArduBreakout.ino
@@ -17,6 +17,8 @@

 Arduboy arduboy;

+const unsigned int COLUMNS = 13; //Columns of bricks
+const unsigned int ROWS = 4;     //Rows of bricks
 int dx = -1;        //Initial movement of ball
 int dy = -1;        //Initial movement of ball
 int xb;           //Balls starting possition
@@ -24,7 +26,7 @@
 boolean released;     //If the ball has been released by the player
 boolean paused = false;   //If the game has been paused
 byte xPaddle;       //X position of paddle
-boolean isHit[5][12];   //Array of if bricks are hit or not
+boolean isHit[ROWS][COLUMNS];   //Array of if bricks are hit or not
 boolean bounced=false;  //Used to fix double bounce glitch
 byte lives = 3;       //Amount of lives
 byte level = 1;       //Current level
@@ -169,9 +171,9 @@
     }

     //Bounce off Bricks
-    for (byte row = 0; row < 4; row++)
-    {
-      for (byte column = 0; column < 14; column++)
+    for (byte row = 0; row < ROWS; row++)
+    {
+      for (byte column = 0; column < COLUMNS; column++)
       {
         if (!isHit[row][column])
         {
@@ -712,7 +714,7 @@
     oldpad=pad;
     drawBall();

-    if(brickCount==60)
+    if(brickCount == ROWS * COLUMNS)
     {
       level++;
       newLevel();


VIP: Correcting a conditionla where header not accepted and first zero is yet to be found.

--- DebugManchester.ino
+++ DebugManchester.ino
@@ -122,7 +122,7 @@
       }//end of dealing with ones
       else{  //bitState==0 could first error, first zero or packet
         // if it is header there must be no "zeroes" or errors
-        if(headerHits<headerBits){
+        if((headerHits<headerBits)&&(!firstZero)){
           //Still in header checking phase, more header hits required
           noErrors=false;//landing here means header is corrupted, so it is probably an error
         }//end of detecting a "zero" inside a header


added declination angle for sg

added declination angle for sg

--- arduino_motor/compass/HMC5883L_Example/HMC5883L_Example.ino
+++ arduino_motor/compass/HMC5883L_Example/HMC5883L_Example.ino
@@ -15,14 +15,14 @@
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

-//library to be found on edventure
+

 // Reference the I2C Library
-#include <Wire.h>
+#include <Wire.h>  // built-in library
 // Reference the HMC5883L Compass Library
-#include <HMC5883L.h>
+#include <HMC5883L.h> //library to be found on edventure

 // Store our compass as a variable.
 HMC5883L compass;
@@ -69,8 +69,8 @@
   // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
   // Find yours here: http://www.magnetic-declination.com/
   // Mine is: 2� 37' W, which is 2.617 Degrees, or (which we need) 0.0456752665 radians, I will use 0.0457
-  // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
-  float declinationAngle = 0.0457;
+  // float declinationAngle = 0.0457;
+  float declinationAngle = 0.003781546713
   heading += declinationAngle;

   // Correct for when signs are reversed.


added pulse

added pulse

--- quadsim/quadsim.ino
+++ quadsim/quadsim.ino
@@ -3,7 +3,8 @@
 int states[] = {0, 1, 1, 0};
 volatile int state = 0;
 volatile int dir = 1;
-volatile int enable = 1;
+volatile int enable = 0;
+volatile int count = 0;
 long rate = 1000;

 void setup() {
@@ -22,6 +23,9 @@
     digitalWrite(10, states[state]);
     digitalWrite(9, states[state + 1 & 0x3]);
     state = (state + dir) & 0x3;
+    count--;
+    if (count == 0)
+      enable = false;
   }
 }

@@ -44,6 +48,10 @@
         if (rate < 100) rate = 100;
         Timer1.setPeriod(rate);
         break;
+      case 'p':
+        enable = 1;
+        count = 20;
+        break;
     }

@@ -57,7 +65,7 @@
     else
       Serial.print("Disabled ");

-    Serial.print(rate * 2);
+    Serial.print(rate * 4);
     Serial.println("uS");

   }


20150406.1002

--- sensChipTemp/src/sketch.ino
+++ sensChipTemp/src/sketch.ino
@@ -32,6 +32,11 @@

   It is preferable, from a simplicity point-of-view, to always measure the raw
   values (CT_gain = 1 & CT_offset=0) and calculate the gain and offset from those.
+
+  Tip: consider using these (relatively) stable temperature sources:
+  * Refrigerator freezer (approx. -15degC)
+  * Refrigerator cooler  (approx. +5degC)
+  * Room                 (approx. +20degC)
 */

 static const float CT_gain   = 1;


Simplified example, removed timer, 1 min limit

--- examples/Widgets/Email/Email.ino
+++ examples/Widgets/Email/Email.ino
@@ -13,13 +13,15 @@
  * This example code is in public domain.
  *
  **************************************************************
- * Simple email example
+ * Simple e-mail example
  *
  * App dashboard setup:
- *   Email widget
+ *   E-mail Widget
  *
- * Connect a button to pin 2 and GND...
- * Pressing this button will also email a message! ;)
+ * Connect a button to digital pin 2 and GND
+ * Pressing this button will send an e-mail
+ *
+ * WARNING: You are limited to send ONLY ONE E-MAIL PER MINUTE!
  *
  **************************************************************/
 //#define BLYNK_DEBUG
@@ -27,13 +29,11 @@
 #include <SPI.h>
 #include <Ethernet.h>
 #include <BlynkSimpleEthernet.h>
-#include <SimpleTimer.h>

 // You should get Auth Token in the Blynk App.
 // Go to the Project Settings (nut icon).
 char auth[] = "YourAuthToken";

-SimpleTimer timer;

 void setup()
 {
@@ -43,44 +43,36 @@
   while (Blynk.connect() == false) {
     // Wait until connected
   }
+
+  // Send e-mail when your hardware gets connected to Blynk Server
+  // Just put the recepient's "e-mail address", "Subject" and the "message body"
+  Blynk.email("your_email@mail.com", "Subject", "My Blynk project is online.");

-  // Send email immediately on startup
-  Blynk.email("my_email@example.com", "Title", "Body");
-
-  // Setup a function to be called every 10 minutes
-  timer.setInterval(10L * 60000L, emailUptime);
-
-  // Setup email button on pin 2
+  // Setting the button
   pinMode(2, INPUT_PULLUP);
   // Attach pin 2 interrupt to our handler
   attachInterrupt(digitalPinToInterrupt(2), emailOnButtonPress, CHANGE);
 }

-void emailUptime()
-{
-  long uptime = millis() / 60000L;
-  BLYNK_LOG("Sending email every 10 minutes ;)");
-
-  // Actually send the message.
-  // Note:
-  //   We allow 1 email per minute for now.
-  Blynk.email("my_email@example.com", "Title", "Body");
-}
-
 void emailOnButtonPress()
 {
-  // Invert state, since button is "Active LOW"
-  int isButtonPressed = !digitalRead(2);
-  if (isButtonPressed) {
-    BLYNK_LOG("Button is pressed.");
-
-    Blynk.email("my_email@example.com", "Title", "Body");
+  // *** WARNING: You are limited to send ONLY ONE E-MAIL PER MINUTE! ***
+
+  // Let's send an e-mail when you press the button
+  // connected to digital pin 2 on your Arduino
+
+  int isButtonPressed = !digitalRead(2); // Invert state, since button is "Active LOW"
+
+  if (isButtonPressed) // You can write any condition to trigger e-mail sending
+  {
+    BLYNK_LOG("Button is pressed."); // This can be seen in the Serial Monitor
+    Blynk.email("your_email@mail.com", "Subject: Button Logger", "You just pushed the button...");
+
   }
 }

 void loop()
 {
   Blynk.run();
-  timer.run();
 }


fixed unit test

fixed unit test

--- Arduino/hardware/V0p2_Main_PCB_REV7_DORM1_and_REV8/testsuite/201702/REV7EncoderTest/REV7EncoderTest.ino
+++ Arduino/hardware/V0p2_Main_PCB_REV7_DORM1_and_REV8/testsuite/201702/REV7EncoderTest/REV7EncoderTest.ino
@@ -141,7 +141,7 @@
 static constexpr bool binaryOnlyValveControl = false;
 static constexpr uint8_t m1 = MOTOR_DRIVE_ML;
 static constexpr uint8_t m2 = MOTOR_DRIVE_MR;
-OTRadValve::ValveMotorDirectV1HardwareDriver<m1, m2, MOTOR_DRIVE_MI_AIN, MOTOR_DRIVE_MC_AIN> motorDriver;
+OTRadValve::ValveMotorDirectV1HardwareDriver<m1, m2, MOTOR_DRIVE_MI_AIN, MOTOR_DRIVE_MC_AIN, OTRadValve::MOTOR_DRIVE_NSLEEP_UNUSED> motorDriver;
 OTRadValve::TestValveMotor ValveDirect((OTRadValve::HardwareMotorDriverInterface *)(&motorDriver));

 static constexpr uint8_t adcSetting = (1 << 6) | (MOTOR_DRIVE_MC_AIN & 7);


add test for client connection

add test for client connection

--- sketch_test/sketch_test.ino
+++ sketch_test/sketch_test.ino
@@ -1,13 +1,16 @@
 #include <SoftwareSerial.h>
 #include <WIZ610.h>

-#define  PULL_UPS_OFF   bitSet(MCUCR,PUD)
-
-#define  txWifi         3
-#define  rxWifi         2
+#define   PULL_UPS_OFF     bitSet(MCUCR,PUD)
+#define   txWifi          3
+#define   rxWifi          2
+#define   LIB_DOMAIN      "192.168.0.2"
+#define   LIB_DOMAIN_PORT "8080"

 SoftwareSerial wifiPort(rxWifi, txWifi);
 WIZ610 modem(&wifiPort);
+
+char buff[BUF_LENGTH];

 void setup() {
   modem.pwrOn();
@@ -33,6 +36,7 @@

   modem.setWIRCfg(WIZ610_B_G, WIZ610_CLIENT, "Ninja", WIZ610_CH_AUTO);
   modem.setSecurity(WIZ610_WPA2_PSK, WIZ610_TKIP_AES, WIZ610_TKIP, WIZ610_ASCII, WIZ610_PASSPHRASE, "A2B4C6D8E0");
+  modem.serialClientCfg(WIZ610_TCP, LIB_DOMAIN, LIB_DOMAIN_PORT, "60");

   Serial.println("ready");
   Serial.print("exit config...");
@@ -46,7 +50,20 @@
 }

 void loop() {
+  getToken();
+  modem.receive(buff);
+
+  Serial.print("token: ");
+  Serial.println(buff);

+  delay(5000);
+}
+
+void getToken() {
+  modem.sendln("GET /getToken/h1h1h1 HTTP/1.1");
+  modem.sendln("Host: 192.168.0.2");
+  modem.sendln("Connection: close");
+  modem.sendln();
 }


Fixing tilt to different pin of the cape

--- OpenROV/OpenROV.ino
+++ OpenROV/OpenROV.ino
@@ -24,7 +24,7 @@

   pinMode(13, OUTPUT);

-  tilt.attach(12);
+  tilt.attach(3);
   light.attach(6);

   motors.reset();


Added smoothing function for all servor and ESCs. This shoudl reduce AMP spikes as the torque in not as high as the adjustment in force is spread over time

--- OpenROV/OpenROV.ino
+++ OpenROV/OpenROV.ino
@@ -21,14 +21,24 @@
 // the more the readings will be smoothed, but the slower the output will
 // respond to the input.  Using a constant rather than a normal variable lets
 // use this value to determine the size of the readings array.
-const int numReadings = 10;
+const int numReadings = 100;

 int readings[numReadings];      // the readings from the analog input
 int index = 0;                  // the index of the current reading
 int total = 0;                  // the running total
 int average = 0;                // the average
+int c_tilt = 90;
+int c_motorp = 90;
+int c_motors = 90;
+int c_motorv = 90;
+int tilt_val = 90;
+int p = 90;
+int v = 90;
+int s = 90;

 void setup(){
+
+  delay(5000); //wait 5 seconds before starting to give time for programming pin sets

   Serial.begin(115200);

@@ -56,15 +66,15 @@
     // do something with the command, what command is it?
     if (cmd.cmp("tilt")) {
       cmd.parse(array);
-      int tilt_val = array[1];
-      tilt.write(tilt_val);
+      tilt_val = array[1];
+      //tilt.write(tilt_val);
     }
     else if (cmd.cmp("go")) {
       cmd.parse(array);
-      int p = array[1];
-      int v = array[2];
-      int s = array[3];
-      motors.go(p, v, s);
+      p = array[1];
+      v = array[2];
+      s = array[3];
+      //motors.go(p, v, s);
     }
     else if (cmd.cmp("light")) {
       cmd.parse(array);
@@ -74,6 +84,20 @@
     else {
       motors.stop();
     }
+  }
+
+  //to reduce AMP spikes, smooth large power adjustments out
+  if (time.elapsed (100)) {
+    if (p<c_motorp) c_motorp--;
+    if (p>c_motorp) c_motorp++;
+    if (v<c_motorv) c_motorv--;
+    if (v>c_motorv) c_motorv++;
+    if (s<c_motors) c_motors--;
+    if (s>c_motors) c_motors++;
+    if (tilt_val<c_tilt) c_tilt--;
+    if (tilt_val>c_tilt) c_tilt++;
+    tilt.write(tilt_val);
+    motors.go(c_motorp, c_motorv, c_motors);
   }

   if (time.elapsed (100)) {


Fixed bitmap rotation in 8x8 example

Fixed bitmap rotation in 8x8 example


add sensor: ultrasonic

add sensor: ultrasonic

--- StandardFirmata.ino
+++ StandardFirmata.ino
@@ -402,6 +402,27 @@
   unsigned int delayTime;

   switch (command) {
+    case 1:
+      pinMode(argv[0] & 0x0f, OUTPUT);
+      pinMode(argv[1] & 0x0f, INPUT);
+      digitalWrite(argv[0] & 0x0f, LOW);
+      delayMicroseconds(2);
+      digitalWrite(argv[0] & 0x0f, HIGH);
+      delayMicroseconds(10);
+      digitalWrite(argv[0] & 0x0f, LOW);
+      Firmata.write(START_SYSEX);
+      Firmata.write(1);
+      Firmata.write(argv[0] & 0x0f);
+      Firmata.write(argv[1] & 0x0f);
+      {
+        String strData = String(pulseIn(argv[1] & 0x0f, HIGH) / 58);
+        data = strData.length();
+        for (int i = 0; i < data; i++) {
+          Firmata.write(strData.charAt(i));
+        }
+      }
+      Firmata.write(END_SYSEX);
+      break;
     case I2C_REQUEST:
       mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
       if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {


Nuke spaces at ends of lines

Nuke spaces at ends of lines

--- lcd_temperature_display.ino
+++ lcd_temperature_display.ino
@@ -49,7 +49,7 @@
   if (reading != lastButtonState) lastDebounceTime = millis();
   lastButtonState = reading;
   digitalWrite(LED_PIN, !reading);
-
+
   if ((reading != buttonState) && ((millis() - lastDebounceTime) > DEBOUNCE_DELAY))
   {
     buttonState = reading;
@@ -64,7 +64,7 @@
   int readval = analogRead(TEMPERATURE_PIN);
   byte readval_shifted;
   long bigsum = 0;
-
+
   if (currentVoltageBin < 0)
   {
     // special case: first time through.
@@ -80,7 +80,7 @@
   // Shift our readval by the voltageEpsilon, constrain to fit within a byte, then save to the array
   readval_shifted = (byte)constrain((readval - voltageEpsilon), 0, 255);
   voltageBins[currentVoltageBin] = readval_shifted;
-
+
   // Nudge voltageEpsilon as required to avoid overflow the next time around
   if (readval_shifted > 200)
   {
@@ -106,7 +106,7 @@
   {
     bigsum += voltageBins[i];
   }
-
+
   // re-add our voltageEpsilon across all slots
   bigsum += voltageEpsilon << AVERAGE_BINS_BITS;

@@ -138,13 +138,13 @@
   // old_val to target in a smooth timeframe.
   byte new_val = old_val;
   byte delta   = abs(old_val - target);
-
+
   // just return the new value if it's less than 2
   // otherwise, bump it up/down by the step shift value
   if      (delta < 2)        new_val = target;
   else if (old_val < target) new_val += (delta >> STEP_SHIFT);
   else                       new_val -= (delta >> STEP_SHIFT);
-
+
   #ifdef DEBUG
     if (old_val != new_val)
     {
@@ -159,7 +159,7 @@
       Serial.println("");
     }
   #endif
-
+
   return new_val;
 }

@@ -193,15 +193,15 @@
   pinMode(BUTTON_PIN,      INPUT_PULLUP);
   pinMode(TEMPERATURE_PIN, INPUT);

-  // set up the LCD's number of columns and rows:
+  // set up the LCD's number of columns and rows:
   lcd.begin(16, 2);
-
+
   // initialize voltageBins
   for (int i = 0; i < AVERAGE_BINS; i++)
   {
     voltageBins[i] = 127;
   }
-
+
   // serial for troubleshooting
   #ifdef DEBUG
     Serial.begin(9600);
@@ -214,31 +214,31 @@
   int timediff;
   unsigned char timespec;
   char outstr[17];
-
+
   // Get the current temperature.
   getTemperature(&current_temp);

   if (millis() > (3*1000))
   {
     // We are past the startup screen.
-
+
     // Check for button presses.
     processButton();

-    // Increment color if the button was pressed
+    // Increment color if the button was pressed
     if (buttonIsPressed)
     {
       incrementColor(&next_color);
       buttonIsPressed = FALSE;
     }
-
+
     // Check for records
     if (current_temp > high_temp.temperature)
     {
       high_temp.temperature = current_temp;
       high_temp.time = millis();
     }
-
+
     if (current_temp < low_temp.temperature)
     {
       low_temp.temperature = current_temp;
@@ -254,17 +254,17 @@
       timediff /= 60;
       timespec = 'h';
     }
-
+
     if (timediff > 23)
     {
       timediff /= 24;
       timespec = 'd';
     }
-
+
     lcd.setCursor(0, 0);
     snprintf(outstr, 17, "H%3d.%1d @%3d%c %3d", (int)high_temp.temperature, (int)(high_temp.temperature * 10) % 10, timediff, timespec, (int)current_temp);
     lcd.print(outstr);
-
+
     // Then do the low
     timediff = minutesAgo(low_temp.time);
     timespec = 'm';
@@ -273,38 +273,38 @@
       timediff /= 60;
       timespec = 'h';
     }
-
+
     if (timediff > 23)
     {
       timediff /= 24;
       timespec = 'd';
     }
-
+
     lcd.setCursor(0, 1);
     snprintf(outstr, 17, "L%3d.%1d @%3d%c %3c", (int)low_temp.temperature, (int)(low_temp.temperature * 10) % 10, timediff, timespec, 'C');
     lcd.print(outstr);

   } else {
-
+
     // Startup message and color test
     lcd.setCursor(0, 0);
     lcd.print(STARTUP_MESSAGE_0);
     lcd.setCursor(0, 1);
     lcd.print(STARTUP_MESSAGE_1);
-
+
     // read, but ignore, button presses
     processButton();
     buttonIsPressed = FALSE;
-
+
     next_color = VIOLET_COLOR;
-
-  }
-
+
+  }
+
   // Manage colors
   getColorByName(&new_color, next_color);
   fadeTowardsColor(&current_color, &new_color);
   setColor(&current_color);
-
+
   // Sleep for a bit
   delay(SLEEP_TIME);
 }


Clean up.

Clean up.

--- libraries/HCSR04/examples/CosaHCSR04/CosaHCSR04.ino
+++ libraries/HCSR04/examples/CosaHCSR04/CosaHCSR04.ino
@@ -68,7 +68,6 @@

   // Start the watchdog ticks
   Watchdog::begin();
-  Watchdog::job(&scheduler);

   // Schedule to read distance every 1/4 second
   ping.schedule(256);


config add and more

config add and more

--- nodmcu.ino
+++ nodmcu.ino
@@ -6,7 +6,7 @@
 #include <Servo.h>
 #include <SimpleTimer.h>
 #include <ESP8266HTTPClient.h>
-
+#include <MD5Builder.h>
 extern "C" {
   #include "user_interface.h"
 }
@@ -19,16 +19,19 @@
  * Flash button is convenient to use but if it is pressed it will stuff up the serial port device driver
  * until the computer is rebooted on windows machines.
  */
-String DEV_VERSION = "1.0";
-const int POWERCHECK_INTERVAL = 10000; // Check battery volage
-float VOLTAGE_THRESHOLD = 2710; // voltage threshold , mv
-const int REPOSITORY_INTERVAL = 5000; //Repository interval check, milisecond
-const char* HOST = "http://345.kiev.ua/1.php"; //Repository  full adress for remote job
-unsigned int UPDPORT = 28031;
-
 const int TRIGGER_PIN = D3; // D3 on NodeMCU and WeMos.
 const int LED_PIN = D7; //Diod pin
 const int MOTOR_PIN = D5; //Motor pin
+const String DEV_VERSION = "1.0";
+const int POWERCHECK_INTERVAL = 600000; // 10 min Check battery volage
+const float VOLTAGE_THRESHOLD = 2710; // voltage threshold , mv
+const int BROADCAST_INTERVAL = 5000; // 5 sec broadcastinterval, milisecond
+unsigned int UPDPORT = 28031;
+
+int REPOSITORY_INTERVAL = 120000; // 2 min Repository interval check, milisecond
+char* REPOSITORY_HOST = "http://345.kiev.ua/1.php"; //Repository  full adress for remote job
+String DID = ""; //device ID
+String DHEX = ""; //Device md5 hex id based

 /*
  * Alternative trigger pin. Needs to be connected to a button to use this pin. It must be a momentary connection
@@ -39,11 +42,14 @@
 bool initialConfig = false; // Indicates whether ESP has WiFi credentials saved from previous session
 ADC_MODE(ADC_VCC); //for voltage measuring
 std::unique_ptr<ESP8266WebServer> server;
+MD5Builder builder_md5;
 SimpleTimer timer_remote;
 SimpleTimer timer_vcc;
+SimpleTimer timer_broadcast;
 WiFiUDP udp;

 //-------------main functions----------------------------------------
+/* delete in prodaction
   void goFeed(String sval) {
         int ival = sval.toInt();
         servo.write(ival);
@@ -52,7 +58,8 @@
           strcat(msg, sval.c_str());
           server->send(200, "text/plain", msg);
   }
-  void goFeedSlow(String sval) {
+*/
+  void doFeed(String sval) {
         int ival = sval.toInt();
         for(int a=0; a<ival; a++){
               for(int i=0; i<180; i++){
@@ -66,13 +73,15 @@
                  delay(5);
                  }
                  delay(200); // for fill the bank))
-                 //servo.write(0); delay(500);  // replaced by for for noise reduce
         }
+        server->send(200, "text/plain", "OK");
+        /* delete in prodaction
           char msg[100];
           strcpy(msg, "Performed cycles : ");
           strcat(msg, sval.c_str());
-          server->send(200, "text/plain", msg);
+
           Serial.println("Eat and be quiet.");
+          */
   }
   void goblink(int i){
     if ((i%10) == 0){
@@ -89,30 +98,29 @@
   }
   void checkRepository(){
           HTTPClient http;
-          http.begin(HOST);
+          http.begin(REPOSITORY_HOST);
           http.addHeader("Content-Type", "application/x-www-form-urlencoded");
-          http.POST("id=" + getID(WiFi.macAddress()) + "&version=" + DEV_VERSION);
+          http.POST("id=" + getID() + "&version=" + DEV_VERSION);
           String response = http.getString();
           http.end();
           CheckRemoteFeedback(response);
-          // UPD broadcast also
-          broadcast();
  }
  void CheckRemoteFeedback(String json){
      StaticJsonBuffer<200> jsonBuffer;
      JsonObject& jobj = jsonBuffer.parseObject(json);
      if (!jobj.success()){
-         Serial.println("parseObject() failed");
+         Serial.println("parseObject() failed on CheckRemoteFeedback");
          return;
          }
          //check server answer here. We are here only if json has been parsed successfuly
-         String remote_job = jobj["remote_job"];
          String devise_id = jobj["devise_id"];
-         if(remote_job[0] != '\0'){
-          goFeedSlow(remote_job);
+         String portion = jobj["portion"];
+         if(devise_id[0] != '\0'){
+          doFeed(portion);
          }
  }
- String getID(String str){
+ String getID(){
+  String str = WiFi.macAddress();
   int j=0;
   String dev_id;
   for(int i=0; i <17; i++){
@@ -120,50 +128,103 @@
       }
       return dev_id;
 }
+String getHex(String did) {
+  String doubledid = did + did;
+  builder_md5.begin();
+  builder_md5.add(String(doubledid));
+  builder_md5.calculate();
+  return builder_md5.toString();
+}
 void batteryCheck(){
   float vdd = ESP.getVcc();
   if( vdd < VOLTAGE_THRESHOLD ){
    Serial.print("Curent voltage: "); Serial.println(String(vdd));
   }
 }
-void setConfigParams(String repository_host, String repository_int_check){
-  Serial.println(String(repository_host));
-  Serial.println(String(repository_int_check));
+void checkConfig(){
+         SPIFFS.begin();
+       if (!SPIFFS.open("/formated.txt", "r")){
+             SPIFFS.format();
+             File format = SPIFFS.open("/formated.txt", "w+");
+             if (format) {
+                     format.close();
+                     Serial.println("SPIFFS has been formated");
+                     File configFile = SPIFFS.open("/config.txt", "w+");
+                     if (configFile)  {Serial.println("config has been created"); }
+                         }
+            }
+}
+void setConfigParams(String repository_host, String repository_interval){
+      File configFile = SPIFFS.open("/config.txt", "w+");
+       if (configFile) {
+       StaticJsonBuffer<200> jsonBuffer;
+       JsonObject& data = jsonBuffer.createObject();
+          data["repository_host"] = repository_host;
+          data["repository_interval"] = repository_interval;
+       data.printTo(configFile);
+       configFile.close();
+       }
+}
+String getConfigParam(String name){
+       StaticJsonBuffer<200> jsonBuffer;
+       SPIFFS.begin();
+       File config = SPIFFS.open("/config.txt", "r");
+     if (config) {
+          String line = config.readStringUntil('\n');
+          config.close();
+          JsonObject& jdata = jsonBuffer.parseObject(line);
+          String paramValue = jdata[name];
+          return paramValue;
+
+     }else{
+          return "";
+     }
+}
+void initVars(){
+ DID = getID();
+ DHEX = getHex(DID);
+
+  String rhost = getConfigParam("repository_host");
+  if(rhost != ""){
+    char *cstr = new char[rhost.length() + 1];
+    rhost.toCharArray(cstr, rhost.length() + 1);
+ REPOSITORY_HOST = cstr;
+  }
+  String rint = getConfigParam("repository_interval");
+  if(rint != ""){
+ REPOSITORY_INTERVAL = rint.toInt()*60*1000;
+  }
+}
+void setStaticIP(String ip, String gw, String sn){
+       File configFile = SPIFFS.open("/wificonfig.txt", "w+");
+       if (configFile) {
+       StaticJsonBuffer<200> jsonBuffer;
+       JsonObject& data = jsonBuffer.createObject();
+          data["ip"] = server->arg("ip");
+          data["gw"] = server->arg("gw");
+          data["sn"] = server->arg("sn");
+       data.printTo(configFile);
+       configFile.close();
+       }
 }
 void broadcast(){
    IPAddress broadcastIp = ~WiFi.subnetMask() | WiFi.gatewayIP();

    if(udp.beginPacket(broadcastIp, UPDPORT) == 1){
-    Serial.print(broadcastIp);
+    //Serial.print(broadcastIp);
    }
-   udp.write("IP: ");
    udp.print(WiFi.localIP());
    if(udp.endPacket() == 1){
-    Serial.println(" send endPacket");
+    //Serial.println(" send endPacket");
    }
-
    IPAddress bIp(255, 255, 255, 255);
    if(udp.beginPacket(bIp, UPDPORT) == 1){
-    Serial.print(bIp);
+   // Serial.print(bIp);
    }
-    udp.write("IP: ");
     udp.print(WiFi.localIP());
-    udp.print(WiFi.subnetMask());
    if(udp.endPacket() == 1){
-    Serial.println(" send endPacket");
-   }
-
-      IPAddress bIp1(10, 0, 0, 185);
-   if(udp.beginPacket(bIp, UPDPORT) == 1){
-    Serial.print(bIp1);
-   }
-    udp.write("IP: ");
-    udp.print(WiFi.localIP());
-    udp.print(WiFi.subnetMask());
-   if(udp.endPacket() == 1){
-    Serial.println(" send endPacket");
-   }
-
+   //Serial.println(" send endPacket");
+   }
 }
 //------------- end main functions----------------------------------------
 void setup() {
@@ -173,9 +234,6 @@
   int start_time = millis(); // remember starttime
   servo.attach(MOTOR_PIN);
   servo.write(0); // initial position
-
-  timer_remote.setInterval(REPOSITORY_INTERVAL, checkRepository);
-  timer_vcc.setInterval(POWERCHECK_INTERVAL, batteryCheck);

   Serial.begin(115200);
   Serial.print("\n Starting at :");
@@ -203,24 +261,40 @@
   } else{
     Serial.print("local ip: ");
     Serial.println(WiFi.localIP());
+
+    checkConfig(); //check whether config exist otherwise create
+    initVars(); // set vars
+    timer_remote.setInterval(REPOSITORY_INTERVAL, checkRepository);
+    timer_vcc.setInterval(POWERCHECK_INTERVAL, batteryCheck);
+    timer_broadcast.setInterval(BROADCAST_INTERVAL, broadcast);
+
     Serial.println("Starting http server...");
     server.reset(new ESP8266WebServer(WiFi.localIP(), 80));
         server->on("/whoami", [](){
-          server->send(200, "application/json", "{\"device_name\" : \"PetFeed\", \"version\" : " + DEV_VERSION + "}");
-        });
+          server->send(200, "application/json", "{\"device_name\" : \"PetFeed\", \"version\" : " + DEV_VERSION + ", \"repository_host\" : " + REPOSITORY_HOST + ", \"repository_interval\" : " + REPOSITORY_INTERVAL + ", \"DID\" : " + DID + ", \"DHEX\" : " + DHEX + "}");
+        });
+        /* delete in production
         server->on("/servo", [](){
           goFeed(server->arg("val"));
         });
-        server->on("/servoslow", [](){
-          goFeedSlow(server->arg("val"));
+        */
+        server->on("/dofeed", [](){
+          doFeed(server->arg("portion"));
         });
          server->on("/vcc", [](){
           float vdd = ESP.getVcc();
           server->send(200, "text/plain", String(vdd));
         });
          server->on("/setconfigparams", [](){
-          setConfigParams(server->arg("repository_host"), server->arg("repository_int_check"));
+          setConfigParams(server->arg("repository_host"), server->arg("repository_interval"));
           server->send(200, "text/plain", String("OK"));
+          ESP.reset();
+        });
+        server->on("/setstaticip", [](){
+          //do verify here!!!!!!
+          setStaticIP(server->arg("ip"), server->arg("gw"), server->arg("sn"));
+          server->send(200, "text/plain", String("OK"));
+          ESP.reset();
         });
         server->begin();
         Serial.println("Custom HTTP server started");
@@ -256,5 +330,6 @@
   server->handleClient();
   timer_remote.run();
   timer_vcc.run();
+  timer_broadcast.run();
     }
 }


Target Temp -> 225

Target Temp -> 225

--- app/app.ino
+++ app/app.ino
@@ -3,7 +3,7 @@
 #include "Bellows.h"
 Thermometer thermometer(1);
 Screen screen;
-Bellows bellows(screen, 85);
+Bellows bellows(screen, 225);
 void setup(){
 }
 void loop(){