Update for all changes

Update for all changes

--- src/microController/microController.ino
+++ src/microController/microController.ino
@@ -1,258 +1,356 @@
-// Define  ////////////////////////////////////////////////////////////////////////////////
-
-#define X1_STEP_PIN         54 //X1->X
-#define X1_DIR_PIN          55
-#define X1_ENABLE_PIN       38
-//#define X1_STOP_PIN       37
-
-#define X2_STEP_PIN         60 //X2->Y
-#define X2_DIR_PIN          61
-#define X2_ENABLE_PIN       56
-//#define X2_STOP_PIN       36
-
-#define Y_STEP_PIN          46 //Y->Z
-#define Y_DIR_PIN           48
-#define Y_ENABLE_PIN        62
-//#define Y_STOP_PIN        39
-
-#define R_STEP_PIN          26 //R->E0
-#define R_DIR_PIN           28
-#define R_ENABLE_PIN        24
-//#define R_STOP_PIN        17
-
-#define E_STEP_PIN          36 //E->E1
-#define E_DIR_PIN           34
-#define E_ENABLE_PIN        30
-//#define E_STOP_PIN        20
-
-#define UPPERBOUND_X        10000 //Number of steps for full range of motion in X, need test empirically
-#define UPPERBOUND_Y        10000 //Number of steps for full range of motion in Y, need test empirically
-#define UPPERBOUND_R        10000 //Number of steps for full rotation in R, need test empirically
-#define UPPERBOUND_E        5 //Probably 5?
-
-#define MICRODELAY          800
-
-#define DELIMITER           ','
-#define ENDCHAR             ';'
-
-// Global  ////////////////////////////////////////////////////////////////////////////////
-
-int requestedX = 0; //X coord for shot alignment
-int requestedY= 0; //Y coord for shot alignment
-int requestedR = 0; //Rotation angle for shot alignment
-int requestedE = 0; //Power of shot
-int currentX = 0;
-int currentY = 0;
-int currentR = 0;
-int inputError = 0;
-
-// Main  //////////////////////////////////////////////////////////////////////////////////
-
-void setup()
-{
-  Serial.begin(9600);
-
-  pinMode(X1_STEP_PIN, OUTPUT);
-  pinMode(X1_DIR_PIN, OUTPUT);
-  pinMode(X1_ENABLE_PIN, OUTPUT);
-
-  pinMode(X2_STEP_PIN, OUTPUT);
-  pinMode(X2_DIR_PIN, OUTPUT);
-  pinMode(X2_ENABLE_PIN, OUTPUT);
-
-  pinMode(Y_STEP_PIN, OUTPUT);
-  pinMode(Y_DIR_PIN, OUTPUT);
-  pinMode(Y_ENABLE_PIN, OUTPUT);
-
-  pinMode(R_STEP_PIN, OUTPUT);
-  pinMode(R_DIR_PIN, OUTPUT);
-  pinMode(R_ENABLE_PIN, OUTPUT);
-
-  pinMode(E_STEP_PIN, OUTPUT);
-  pinMode(E_DIR_PIN, OUTPUT);
-  pinMode(E_ENABLE_PIN, OUTPUT);
-
-  //InitializeRoutine(); //Move end effector such that X,Y,R are in initialized positions (0,0,0)
-
-}
-
-void loop()
-{
-  WaitForInput();
-  if(inputError == 0) //Only take action if all inputs are valid
-  {
-    MoveX();
-    if (requestedE != 0) //Are we taking a shot or just moving X to take a picture?
-    {
-      MoveY();
-      MoveR();
-      TakeShot();
-    }
-  }
-  SignalDoneAction();
-}
-
-// Methods  ///////////////////////////////////////////////////////////////////////////////
-
-void WaitForInput() //Expect input X,Y,R,E if only want move X then send X,DC,DC,0
-{
-
-  char readline[32] = {NULL};
-  const char delim[2] = ",";
-  char *var;
-  char c;
-  int count = 0;
-  int varcount = 0;
-
-  do {
-    delay(10);
-  } while(Serial.available() <= 0); //Wait for input, will loop forever until something entered into Serial Monitor
-
-  do {
-    readline[count++] = Serial.read();
-    delay(10);
-  } while(readline[count-1] != ENDCHAR && count != sizeof(readline)); //Fill buffer with line of text entered in Serial Monitor
-
-  readline[count-1] = NULL; //Remove ENDCHAR from buffer
-
-   var = strtok(readline, delim); //Separate buffer into array elements using comma delimiter
-   count = 0;
-   while( var != NULL && count < 4) //Iterate through array elements
-   {
-      if(count == 0)
-      {
-        if (atoi(var) >= 0 && atoi(var) < UPPERBOUND_X) requestedX = atoi(var); //atoi -> char to int
-        else inputError += 1; //inputError is four digit binary number represented as integer
-      }
-      else if (count == 1)
-      {
-        if (atoi(var) >= 0 && atoi(var) < UPPERBOUND_Y) requestedY = atoi(var);
-        else inputError += 2;
-      }
-      else if (count == 2)
-      {
-        if (atoi(var) >= 0 && atoi(var) < UPPERBOUND_R) requestedR = atoi(var);
-        else inputError += 4;
-      }
-      else
-      {
-        if (atoi(var) >= 0 && atoi(var) < UPPERBOUND_E) requestedE = atoi(var);
-        else inputError += 8;
-      }
-      var = strtok(NULL, delim);
-      count++;
-   }
-}
-
-void MoveX(){
-
-  int dir;
-  if (requestedX > currentX) dir = 1;
-  else dir = -1;
-
-  digitalWrite(X1_DIR_PIN, dir > 0);
-  digitalWrite(X2_DIR_PIN, dir > 0);
-
-  while(requestedX-currentX != 0)
-  {
-    digitalWrite(X1_STEP_PIN, HIGH);
-    digitalWrite(X2_STEP_PIN, HIGH);
-    delayMicroseconds(MICRODELAY);
-    digitalWrite(X1_STEP_PIN, LOW);
-    digitalWrite(X2_STEP_PIN, LOW);
-    delayMicroseconds(MICRODELAY);
-    currentX += dir;
-  }
-
-}
-
-void MoveY(){
-
-  int dir;
-  if (requestedY > currentY)  dir = 1;
-  else  dir = -1;
-
-  digitalWrite(Y_DIR_PIN, dir > 0);
-
-  while(requestedY-currentY != 0)
-  {
-    digitalWrite(Y_STEP_PIN, HIGH);
-    delayMicroseconds(MICRODELAY);
-    digitalWrite(Y_STEP_PIN, LOW);
-    delayMicroseconds(MICRODELAY);
-    currentY += dir;
-  }
-
-}
-
-void MoveR(){
-
-  int dir;
-  if (requestedR > currentR)
-  {
-    if ((requestedR - currentR) <= (UPPERBOUND_R/2))  dir  = 1;
-    else dir = -1;
-  }
-  else
-  {
-    if ((currentR - requestedR) <= (UPPERBOUND_R/2))  dir  = -1;
-    else dir = 1;
-  }
-
-  digitalWrite(R_DIR_PIN, dir > 0);
-
-  while(requestedR-currentR != 0)
-  {
-    digitalWrite(R_STEP_PIN, HIGH);
-    delayMicroseconds(MICRODELAY);
-    digitalWrite(R_STEP_PIN, LOW);
-    delayMicroseconds(MICRODELAY);
-    currentR += dir;
-    currentR = (currentR + UPPERBOUND_R) % UPPERBOUND_R; //To wrap around since 0 == UPPERBOUND_R
-  }
-
-}
-
-void TakeShot()
-{
-  if(requestedE != 0) //Redundancy
-  {
-
-    int effectorLength = 10000; //Number of steps for full range of motion in E, need test empirically ;
-
-    digitalWrite(E_DIR_PIN, HIGH);
-
-    for(int i=0;i<effectorLength;i++)
-    {
-      digitalWrite(E_STEP_PIN, HIGH);
-      delayMicroseconds(MICRODELAY*requestedE); //requestedE affects delay between steps -> speed of shot -> power of shot
-      digitalWrite(E_STEP_PIN, LOW);
-      delayMicroseconds(MICRODELAY*requestedE); //requestedE affects delay between steps -> speed of shot -> power of shot
-    }
-
-    digitalWrite(E_DIR_PIN, LOW);
-
-    for(int i=0;i<effectorLength;i++)
-    {
-      digitalWrite(E_STEP_PIN, HIGH);
-      delayMicroseconds(MICRODELAY);
-      digitalWrite(E_STEP_PIN, LOW);
-      delayMicroseconds(MICRODELAY);
-    }
-
-  }
-
-}
-
-
-void SignalDoneAction()
-{
-
-  Serial.println(inputError); //Inform PC if any inputs are invlaid
-  inputError = 0;
-
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////
-
-
+// Include  ////////////////////////////////////////////////////////////////////////////////
+
+#include <EEPROM.h>
+
+// Define  ////////////////////////////////////////////////////////////////////////////////
+
+#define X1_STEP_PIN          54 //X1->X
+#define X1_DIR_PIN           55
+#define X1_ENABLE_PIN        38
+
+#define X2_STEP_PIN          46 //X2->Z
+#define X2_DIR_PIN           48
+#define X2_ENABLE_PIN        62
+
+#define Y_STEP_PIN           60 //Y->Y
+#define Y_DIR_PIN            61
+#define Y_ENABLE_PIN         56
+
+#define R_STEP_PIN           36 //R->E1
+#define R_DIR_PIN            34
+#define R_ENABLE_PIN         30
+
+#define E_STEP_PIN           26 //E->E0
+#define E_DIR_PIN            28
+#define E_ENABLE_PIN         24
+
+#define XMIN_PIN             16 //x sensor 1
+#define XMAX_PIN             17 //x sensor 2
+#define YMIN_PIN             23 //y sensor 1
+#define YMAX_PIN             25 //y sensor 2
+#define RMIN_PIN             27 //r sensor 1
+#define RMAX_PIN             29 //r sensor 2
+
+#define USERBUTTON1_PIN      20
+#define USERBUTTON2_PIN      21
+
+#define UPPERBOUND_X         10000 //Number of steps for full range of motion in X, need test empirically
+#define UPPERBOUND_Y         10000 //Number of steps for full range of motion in Y, need test empirically
+#define UPPERBOUND_R         10000 //Number of steps for full rotation in R, need test empirically
+#define UPPERBOUND_E         3     //Number of power settings for take shot, probably 3
+
+#define MICRODELAY           800
+
+#define DELIMITER            ","
+#define ENDCHAR              ";"
+
+// Global  ////////////////////////////////////////////////////////////////////////////////
+
+int requestedX; //X coord for shot alignment
+int requestedY; //Y coord for shot alignment
+int requestedR; //Rotation angle for shot alignment
+int requestedE; //Power of shot
+
+int currentX; //Current X position
+int currentY; //Current Y position
+int currentR; //Current R position
+
+int xDir; //Direction X should move
+int yDir; //Direction Y should move
+int rDir; //Direction R should move
+
+bool userControl = false; //Enable or disable user buttons
+int inputError = 0; //4 bit binary error check
+
+// Setup  /////////////////////////////////////////////////////////////////////////////////
+
+void setup()
+{
+
+  Serial.begin(9600);
+
+  pinMode(X1_STEP_PIN, OUTPUT);
+  pinMode(X1_DIR_PIN, OUTPUT);
+  pinMode(X1_ENABLE_PIN, OUTPUT);
+
+  pinMode(X2_STEP_PIN, OUTPUT);
+  pinMode(X2_DIR_PIN, OUTPUT);
+  pinMode(X2_ENABLE_PIN, OUTPUT);
+
+  pinMode(Y_STEP_PIN, OUTPUT);
+  pinMode(Y_DIR_PIN, OUTPUT);
+  pinMode(Y_ENABLE_PIN, OUTPUT);
+
+  pinMode(R_STEP_PIN, OUTPUT);
+  pinMode(R_DIR_PIN, OUTPUT);
+  pinMode(R_ENABLE_PIN, OUTPUT);
+
+  pinMode(E_STEP_PIN, OUTPUT);
+  pinMode(E_DIR_PIN, OUTPUT);
+  pinMode(E_ENABLE_PIN, OUTPUT);
+
+  pinMode(XMIN_PIN, INPUT);
+  pinMode(XMAX_PIN, INPUT);
+  pinMode(YMIN_PIN, INPUT);
+  pinMode(YMAX_PIN, INPUT);
+  pinMode(RMIN_PIN, INPUT);
+  pinMode(RMAX_PIN, INPUT);
+
+  pinMode(USERBUTTON1_PIN, INPUT);
+  attachInterrupt(digitalPinToInterrupt(USERBUTTON1_PIN), UserButton1, FALLING);
+  pinMode(USERBUTTON2_PIN, INPUT);
+  attachInterrupt(digitalPinToInterrupt(USERBUTTON2_PIN), UserButton2, FALLING);
+
+  InitializeRoutine();
+
+}
+
+// Main  //////////////////////////////////////////////////////////////////////////////////
+
+void loop()
+{
+
+  WaitForPCInstruction();
+  if(inputError == 0) //Only take action if all inputs are valid
+  {
+    MoveXYR();
+    TakeShot();
+    AllowUserTurn();
+    PoseForPicture();
+    RequestPCInstruction();
+  }
+  else
+  {
+    RequestPCInstruction();
+  }
+
+}
+
+// Methods  ///////////////////////////////////////////////////////////////////////////////
+
+void InitializeRoutine() //Move end effector such that X,Y,R are in initialized positions (0,0,0) and let user break
+{
+
+  requestedX = 0;
+  requestedY = 0;
+  requestedR = 0;
+  currentX = UPPERBOUND_X - 1;
+  currentY = UPPERBOUND_Y - 1;
+  currentR = UPPERBOUND_R / 2;
+  MoveXYR();
+  AllowUserTurn();
+  PoseForPicture();
+  RequestPCInstruction();
+
+}
+
+void WaitForPCInstruction() //Loop during PC operation
+{
+
+  char readline[32];
+  char aChar;
+  int val;
+  int count = 0;
+
+  memset(&readline[0], 0, sizeof(readline));
+
+  do {
+    delay(10);
+  } while(Serial.available() <= 0); //Will loop forever until something entered into Serial Monitor
+
+  do {
+    aChar = Serial.read();
+    readline[count] = aChar;
+    count++;
+    delay(10);
+  } while(count != sizeof(readline) && Serial.available() > 0);
+
+  val = atoi(strtok(readline, DELIMITER));
+  if (val >= 0 && val < UPPERBOUND_X) requestedX = val;
+  else inputError += 1; //0001 -> bad x
+  val = atoi(strtok(NULL, DELIMITER));
+  if (val >= 0 && val < UPPERBOUND_Y) requestedY = val;
+  else inputError += 2; //0010 -> bad y
+  val = atoi(strtok(NULL, DELIMITER));
+  if (val >= 0 && val < UPPERBOUND_R) requestedR = val;
+  else inputError += 4; //0100 -> bad r
+  val = atoi(strtok(NULL, ENDCHAR));
+  if (val >= 0 && val < UPPERBOUND_E) requestedE = val;
+  else inputError += 8; //1000 -> bad e
+
+  memset(&readline[0], 0, sizeof(readline));
+
+}
+
+void MoveXYR() //Move X Y and R simultaneously
+{
+
+  if (requestedX > currentX) xDir = 1;
+  else xDir = -1;
+
+  digitalWrite(X1_DIR_PIN, xDir > 0);
+  digitalWrite(X2_DIR_PIN, xDir > 0);
+
+  if (requestedY > currentY)  yDir = 1;
+  else  yDir = -1;
+
+  digitalWrite(Y_DIR_PIN, yDir > 0);
+
+  if (requestedR > currentR)
+  {
+    if ((requestedR - currentR) <= (UPPERBOUND_R/2))  rDir  = 1;
+    else rDir = -1;
+  }
+  else
+  {
+    if ((currentR - requestedR) <= (UPPERBOUND_R/2))  rDir  = -1;
+    else rDir = 1;
+  }
+
+  digitalWrite(R_DIR_PIN, rDir > 0);
+
+  while(requestedX-currentX != 0 || requestedY-currentY != 0 || requestedR-currentR != 0)
+  {
+
+    if(xDir == -1 && digitalRead(XMIN_PIN) == 0) //XMIN endstop hit
+    {
+      currentX = 0;
+      xDir = 1;
+      digitalWrite(X1_DIR_PIN, HIGH);
+      digitalWrite(X2_DIR_PIN, HIGH);
+    }
+
+    if(xDir == 1 && digitalRead(XMAX_PIN) == 0) //XMAX endstop hit
+    {
+      currentX = UPPERBOUND_X - 1;
+      xDir = -1;
+      digitalWrite(X1_DIR_PIN, LOW);
+      digitalWrite(X2_DIR_PIN, LOW);
+    }
+
+    if(yDir == -1 && digitalRead(YMIN_PIN) == 0) //YMIN endstop hit
+    {
+      currentY = 0;
+      yDir = 1;
+      digitalWrite(Y_DIR_PIN, HIGH);
+    }
+
+    if(yDir == 1 && digitalRead(YMAX_PIN) == 0) //YMAX endstop hit
+    {
+      currentY = UPPERBOUND_Y - 1;
+      yDir = -1;
+      digitalWrite(Y_DIR_PIN, LOW);
+    }
+
+    if(digitalRead(RMIN_PIN) == 0 && digitalRead(RMAX_PIN) == 0) //R reference point hit
+    {
+      currentR = 0;
+    }
+
+    if(requestedX-currentX != 0)
+    {
+      digitalWrite(X1_STEP_PIN, HIGH);
+      digitalWrite(X2_STEP_PIN, HIGH);
+    }
+
+    if(requestedY-currentY != 0)
+    {
+      digitalWrite(Y_STEP_PIN, HIGH);
+    }
+
+    if(requestedR-currentR != 0)
+    {
+      digitalWrite(R_STEP_PIN, HIGH);
+    }
+
+    delayMicroseconds(MICRODELAY);
+
+    if(requestedX-currentX != 0)
+    {
+      digitalWrite(X1_STEP_PIN, LOW);
+      digitalWrite(X2_STEP_PIN, LOW);
+      currentX += xDir;
+    }
+
+    if(requestedY-currentY != 0)
+    {
+      digitalWrite(Y_STEP_PIN, LOW);
+      currentY += yDir;
+    }
+
+    if(requestedR-currentR != 0)
+    {
+      digitalWrite(R_STEP_PIN, LOW);
+      currentR += rDir;
+      currentR = (currentR + UPPERBOUND_R) % UPPERBOUND_R; //Since 0 == UPPERBOUND_R
+    }
+
+    delayMicroseconds(MICRODELAY);
+
+  }
+
+}
+
+void TakeShot()
+{
+  /*
+  Something something pnuematics
+  */
+}
+
+void AllowUserTurn() //Loop during user turn
+{
+
+  userControl = true;
+  while(userControl)
+  {
+    MoveXYR():
+    delay(10);
+  }
+
+}
+
+void PoseForPicture() //Move machine so camera can see unobstructed table
+{
+
+  if(currentX < UPPERBOUND_X / 2) requestedX = 0;
+  else requestedX = UPPERBOUND_X - 1;
+  if(currentY < UPPERBOUND_Y / 2) requestedY = 0;
+  else requestedY = UPPERBOUND_Y - 1;
+  requestedR = 0;
+  MoveXYR();
+
+}
+
+void RequestPCInstruction()
+{
+
+  Serial.println(inputError); //Inform PC if any inputs are invlaid
+  inputError = 0;
+
+}
+
+void UserButton1() //Tell machine to move out of the way
+{
+
+  if (userControl)
+  {
+    if(requestedX != 0) requestedX = 0;
+    else requestedX = UPPERBOUND_X - 1;
+  }
+
+}
+
+void UserButton2() //Tell machine to take another turn
+{
+
+  if (userControl)
+  {
+    requestedX = currentX;
+    userControl = false;
+  }
+
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////
+


Implementa comunicação com mosquitto para envio de temperatura e mudança de status (liga/desliga) do ar condicionado.


Joint Struct example.

Joint Struct example.

--- arduino/arduino_md03_v_5_0/arduino_md03_v_5_0.ino
+++ arduino/arduino_md03_v_5_0/arduino_md03_v_5_0.ino
@@ -59,6 +59,17 @@

 Status stat = { 0, 0, 0 };
 Command cmd = { 0, true, 0, true, 0, true };
+
+//struct Joint {
+//  String name;
+//  int pos;
+//  int command;
+//  boolean brake;
+//}
+//
+//Joint yaw = { "Yaw", 0, 0, LOW };
+//Joint pitch = { "Pitch", 0, 0, LOW };
+//Joint lid = { "Lid", 0, 0, LOW };

 //serial
 String inputString = "";         // a string to hold incoming data


Switches to using the regular loop method instead of the background task.


Update rs485_smodbus_master.ino

Update rs485_smodbus_master.ino

--- protocol/modbus/lab/rs485_smodbus_master.ino
+++ protocol/modbus/lab/rs485_smodbus_master.ino
@@ -5,7 +5,7 @@
 #define polling 2000
 #define retry_count 10
 #define TxEnablePin 2
-#define LED 9
+#define ERRORLED 13
 //ID slave node
 #define SLAVEID 10
 #define SLAVEADDREG 1
@@ -31,7 +31,7 @@
   modbus_construct(&packets[PACKET2], SLAVEID, PRESET_MULTIPLE_REGISTERS, SLAVEADDREG, 1, 0);
   modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);

-  pinMode(LED, OUTPUT);
+  pinMode(ERRORLED, OUTPUT);
 }

 void loop()


Renamed to leftTicks/rightTicks

Renamed to leftTicks/rightTicks

--- Wild_Thumper_Controller/Wild_Thumper_Controller.ino
+++ Wild_Thumper_Controller/Wild_Thumper_Controller.ino
@@ -55,8 +55,8 @@
 // For positive numbers when going forward, left should be backwards, right should be in order
 Encoder leftEnc(D9, D8);
 Encoder rightEnc(D10, D12);
-long leftEncPos;
-long rightEncPos;
+long leftTicks;
+long rightTicks;

 void setup() {
   // Initialize I/O pins
@@ -202,8 +202,8 @@

 void readEncoders() {
   // Read encoders
-  leftEncPos = leftEnc.read();
-  rightEncPos = rightEnc.read();
+  leftTicks = leftEnc.read();
+  rightTicks = rightEnc.read();
 }

 //
@@ -362,10 +362,10 @@
   Serial.print("{\"type\":\"state\"");
   Serial.print(",\"heading\":");
   Serial.print(heading);
-  Serial.print(",\"leftEncPos\":");
-  Serial.print(leftEncPos);
-  Serial.print(",\"rightEncPos\":");
-  Serial.print(rightEncPos);
+  Serial.print(",\"leftTicks\":");
+  Serial.print(leftTicks);
+  Serial.print(",\"rightTicks\":");
+  Serial.print(rightTicks);
   Serial.print(",\"leftDist\":");
   Serial.print(leftDist);
   Serial.print(",\"centerDist\":");


reduce size

reduce size

--- testing/arduino/omniwheel4_EncoderD.ino
+++ testing/arduino/omniwheel4_EncoderD.ino
@@ -40,7 +40,7 @@
 // ----------

 uint8_t initState = 0;
-uint32_t initTimestamp = 0;
+uint16_t initTimestamp = 0;
 uint8_t initSpeed = 255;

 // ----------
@@ -128,9 +128,7 @@
     if (initState == 1 && initTimestamp + delta <= time && initSpeed > 0)
     {
         SpeedMapping_Motor1[initSpeed] = 255 / motor1_MaxRPM * motor1_RPMCount;
-
         SpeedMapping_Motor2[initSpeed] = 255 / motor2_MaxRPM * motor2_RPMCount;
-
         SpeedMapping_Motor3[initSpeed] = 255 / motor3_MaxRPM * motor3_RPMCount;

         // 12:  255 - 245 - 235 - 225 - 215 - 205 - 195 - 185 - 175 - 165 - 155 - 145
@@ -209,14 +207,9 @@

-
-
-
-
 void loop()
 {
     UpdateRPM();

     Calibration();
-
-}
+}


Improving Webserver example sketch (when using an Ethernet Shield).

1. Add SD chip select output pin to force correct mode.

--- examples/Ethernet/CosaWebServer/CosaWebServer.ino
+++ examples/Ethernet/CosaWebServer/CosaWebServer.ino
@@ -127,6 +127,12 @@
 W5100 ethernet(mac);
 WebServer server;

+// Ethernet Shield SD device must be disabled
+#define USE_ETHERNET_SHIELD
+#if defined(USE_ETHERNET_SHIELD)
+OutputPin sd(Board::D4, 1);
+#endif
+
 void setup()
 {
   // Initiate uart and trace output stream. And watchdog


- another final update to accel profile

- another final update to accel profile

--- GeheimTuer.ino
+++ GeheimTuer.ino
@@ -65,9 +65,9 @@
 const struct accelProfile accelProfileLow[] = {
   {
     maxMillis: 13000,
-    stepMillis: 50,
+    stepMillis: 5,
     factor: 1,
-    add: 4,
+    add: 1,
     minPWM: 0,
     maxPWM: 64,
     startPWM: 0,
@@ -85,7 +85,7 @@
 // TODO: install less stiff spring between belt and door to dampen the initial pull
 const struct accelProfile accelProfileHigh[] = {
   { // accelerate and keep running
-    maxMillis: 2450,
+    maxMillis: 2500,
     stepMillis: 4,
     factor: 1,
     add: 1,


Example: update for new Rev system

Example: update for new Rev system


Added timestamp values test for a single sensor

--- Sensorizer.ino
+++ Sensorizer.ino
@@ -89,6 +89,22 @@
 unsigned long testTimestamps[TEST_TIMESTAMPS_LENGTH];

 #endif
+
+
+
+
+#define ENABLE_TIMESTAMP_VAL_TEST 1
+#if ENABLE_TIMESTAMP_VAL_TEST
+
+#define TIMSTAMP_VAL_TEST_SENSOR_IDX_TO_LOG 0
+#define TEST_VAL_TIMESTAMPS_LENGTH 256
+
+int testValTimestampsIdx = 0;
+unsigned long testValTimestamps[TEST_VAL_TIMESTAMPS_LENGTH];
+int testVals[TEST_VAL_TIMESTAMPS_LENGTH];
+
+#endif
+

 void setupServer() {
     // must wait a bit for the MIDI device to boot up before it accepts our messages
@@ -246,7 +262,7 @@

 #if ENABLE_TIMESTAMP_TEST
   unsigned long microTimestamp = micros();
-
+
 #endif

   /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
@@ -279,6 +295,29 @@
         val = getCurrentTestVal(analogPin);
 #endif

+
+#if ENABLE_TIMESTAMP_VAL_TEST
+
+        if (pinIdx == TIMSTAMP_VAL_TEST_SENSOR_IDX_TO_LOG) {
+
+          testValTimestamps[testValTimestampsIdx] = micros();
+          testVals[testValTimestampsIdx] = val;
+
+          if (++testValTimestampsIdx >= TEST_VAL_TIMESTAMPS_LENGTH) {
+            testValTimestampsIdx = 0;
+
+            SerialUSB.println("ValTimestamps:");
+            unsigned long firstValTimestamp = testValTimestamps[0];
+            for (int i = 0; i < TEST_VAL_TIMESTAMPS_LENGTH; i++) {
+              SerialUSB.print(testValTimestamps[i]);
+              SerialUSB.print(',');
+              SerialUSB.println(testVals[i]);
+            }
+          }
+        }
+#endif
+
+

         //DEBUG_PRINT_NUM("check pin ", pinIdx);
 #if !ENABLE_TEST


updated AnalogDelayDemo to work with Teensyduino 1.41


Shortens boot animation

Shortens boot animation

--- animations.ino
+++ animations.ino
@@ -15,7 +15,7 @@
     }

     oled.drawString(sequence[idx], (RGB_OLED_WIDTH-FONT_X*5)/2, RGB_OLED_HEIGHT/2-FONT_Y/2, 1, COLOR_BLUE);
-    delay(500);
+    delay(200);
   }
   delay(1000);
 }


Delete C_DISCOR.ino

Delete C_DISCOR.ino


Pins numbers instead of pins labels for portability

Pins numbers instead of pins labels for portability

--- libraries/SimplelinkWifi/examples/simpleWebServer/simpleWebServer.ino
+++ libraries/SimplelinkWifi/examples/simpleWebServer/simpleWebServer.ino
@@ -28,9 +28,10 @@
 void setup() {
   Serial.begin(115200);

-  WiFi.setCSpin(P2_2);
-  WiFi.setENpin(P6_5);
-  WiFi.setIRQpin(P2_0);
+    WiFi.setCSpin(18);  // 18: P2_2 @ F5529, PE_0 @ LM4F/TM4C
+    WiFi.setENpin(2);   //  2: P6_5 @ F5529, PB_5 @ LM4F/TM4C
+    WiFi.setIRQpin(19); // 19: P2_0 @ F5529, PB_2 @ LM4F/TM4C
+

   pinMode(RED_LED, OUTPUT);
   pinMode(GREEN_LED, OUTPUT);


Minor update.

Minor update.


AHHHHH

AHHHHH

--- ElevatorGUI/ElevatorController_arduino/ArielsMotorCode/ArielsMotorCode.ino
+++ ElevatorGUI/ElevatorController_arduino/ArielsMotorCode/ArielsMotorCode.ino
@@ -78,9 +78,9 @@
       for (int x = 0; x < input_step; x++)
       {
         //unsigned long t = micros();
-        step(input_delay);
+        step(input_delay * 1000);
         //Serial.println(micros()-t);
-        //Serial.println(x);
+        Serial.println(x);
       }
   }
 }
@@ -93,9 +93,9 @@
   digitalWrite(amisStepPin, HIGH);
   // delay = time each step takes, or
   // delay = ((60,000 msecs)/(200 steps)) * (1/RPM)
-  delayMicroseconds(input_delay * 1000);
+  delayMicroseconds(input_delay);
   digitalWrite(amisStepPin, LOW);
-  delayMicroseconds(input_delay * 1000);
+  delayMicroseconds(input_delay);
 }

 // Writes a high or low value to the direction pin to specify


fix error in mean wind speed measurement


Add voltage check function and clean up top bar clearing; closes #41

--- brew-buddy-firmware/src/brew-buddy-firmware.ino
+++ brew-buddy-firmware/src/brew-buddy-firmware.ino
@@ -118,6 +118,7 @@
   Particle.function("setMode", setBrewMode);
   Particle.function("checkTemp", checkTemp);
   Particle.function("checkRate", checkFermentationRate);
+  Particle.function("checkBatt", checkBatterylevel);

   // Initialize TFT
   tft.begin(TFT_SPEED);
@@ -139,8 +140,8 @@
   printSubheadingLine("Waiting for Brew...");

   // Check and display the battery level
-  int voltage = checkVoltage();
-  displayVoltage(voltage);
+  int voltage = getBatteryPercantage();
+  displayBattLevel(voltage);

   //Connect to Azure MQTT Server
   /* client.connect("e00fce681290df8ab5487791", "brew-buddy-hub.azure-devices.net/e00fce681290df8ab5487791/?api-version=2018-06-30", "SharedAccessSignature sr=brew-buddy-hub.azure-devices.net&sig=RKWH%2FV8CD595YeAnXOZ8jXsSYMnWf6RiJBnzhUoxCzE%3D&skn=iothubowner&se=1552683541");
@@ -233,13 +234,12 @@

   if (currentMillis - previousBattMillis > battInterval)
   {
-    int voltage = checkVoltage();
-
-    displayVoltage(voltage);
-    Particle.publish(messageBase + "voltage", String(voltage));
-
-    // If voltage < 30%, show a low batt message and publish message to cloud
-    if (voltage < BATT_LOW_VOLTAGE)
+    int battLevel = getBatteryPercantage();
+
+    displayBattLevel(battLevel);
+    Particle.publish(messageBase + "batt-level", String(battLevel));
+
+    if (battLevel < BATT_LOW_VOLTAGE)
     {
       displayLowBattAlert();
       Particle.publish(messageBase + "alert", "low-batt");
@@ -287,6 +287,14 @@
   return rate;
 }

+int checkBatterylevel(String args)
+{
+  int battLevel = getBatteryPercantage();
+  Particle.publish(messageBase + "batt-level", String(battLevel));
+
+  return 1;
+}
+
 int checkFermentationRate(String args)
 {
   if (isFermentationMode)
@@ -312,7 +320,7 @@
   return 0;
 }

-int checkVoltage()
+int getBatteryPercantage()
 {
   int voltage = analogRead(BATT) * 0.0011224;

@@ -411,6 +419,13 @@
   delay(3000);
 }

+void clearTopBar()
+{
+  tft.fillRect(0, 0, 240, 30, ILI9341_BLACK);
+  tft.setCursor(0, 0);
+  tft.setTextColor(ILI9341_WHITE);
+}
+
 void clearScreen()
 {
   tft.fillRect(0, 30, 240, 320, ILI9341_BLACK);
@@ -548,8 +563,9 @@
   tft.println(timeString);
 }

-void displayVoltage(int voltage)
-{
+void displayBattLevel(int voltage)
+{
+  clearTopBar();
   tft.setCursor(160, 10);
   tft.setTextSize(1);
   tft.print("Batt: ");
@@ -559,7 +575,7 @@

 void displayLowBattAlert()
 {
-  tft.setCursor(160, 30);
+  tft.setCursor(10, 10);
   tft.setTextSize(2);
   tft.setTextColor(ILI9341_RED);
   tft.println("LOW BATT");


Corregido bug parpadeo al inicio

Corregido bug parpadeo al inicio

--- proyecto/proyecto.ino
+++ proyecto/proyecto.ino
@@ -19,7 +19,7 @@
 #include <Board.h>
 #include <IA.h>

-byte player = 2;
+byte player = 0;

 byte mask_int[4] = {0,0,0,0};
 bool mask[25] = {};
@@ -72,7 +72,7 @@
             if(((pos % 5) != 0)&& board.getPlayer(pos-1)==0){
               turnOn(pos-1);
             }
-          }else{
+          }else if(board.getPlayer(pos)==0){

            for(byte k=0;k<10;k++){
              toggle(pos);


Metro board used by SARJs had bad pin 3.  Using pin 5 instead.

Debugging:
With D3 set as an encoder pin, it defaults to 0.  Other such declared pins default to 1.   In this cfg, jumper from 3.3v to Pin 3 does result in it toggling to 1.  Perhaps voltage from encoder isn't quite high enough to achieve this.  Note that any pin not declared as encoder pin (or otherwise manually set as input), will always have zero, even with jumper from 3.3v.

Component-level test (not installed in Mimic) shows good motor encoder reads for the pairs in code (2,5 for Port SARJ, 7,8 for Stbd SARJ).

--- Arduino/Master_Arduino_Metro_SARJs_TRRJs_r8_9600/Master_Arduino_Metro_SARJs_TRRJs_r8_9600.ino
+++ Arduino/Master_Arduino_Metro_SARJs_TRRJs_r8_9600/Master_Arduino_Metro_SARJs_TRRJs_r8_9600.ino
@@ -3,7 +3,7 @@
 // Still need to add servo stuff for TRRJs
 //
 // This version is just for STBD BGAs, board 78
-// PSARJ is Motor 1, Encoder pins 2,5; Pin 3 not working properly on this Arduino Metro.
+// PSARJ is Motor 1, Encoder pins 2,5; Pin 3 not working properly on this Arduino Metro.  Updated 7/6/2019
 // SSARJ is Motor 2, Encoder pins 7,8
 /
 //// for LCD  =============================================


changed time to use uint64_t

changed time to use uint64_t

--- firmware/rallyx_timer/rallyx_timer.ino
+++ firmware/rallyx_timer/rallyx_timer.ino
@@ -43,20 +43,20 @@
   bool      active;
   uint32_t  debounce_count;
   uint32_t  deadtime_count;
-  uint32_t  time;
+  uint64_t  time;
   source_t  source;
 } trigger_state_t;

 typedef struct
 {
-  uint32_t time;
+  uint64_t time;
   source_t source;
 } event_t;

 volatile uint32_t debounce = DEFAULT_DEBOUNCE; // max number of debounce cycles
 volatile uint32_t deadtime = DEFAULT_DEADTIME; // deadtime before next trigger

-volatile uint32_t ms_time = 0; // master millisecond time
+volatile uint64_t ms_time = 0; // master millisecond time

 volatile uint32_t event_count = 0;
 volatile event_t events[EVENT_MAX];
@@ -152,30 +152,26 @@
   eeprom_write(ROM_OFFSET_START, 0xff);
 }

-void print_time(uint32_t time)
-{
-  uint32_t ms = time % 1000;
-  uint32_t s = (time / 1000) % 60;
-  uint32_t m = (time / 60000) % 60;
-  uint32_t h = time / 3600000;
-
-  if( h < 10 )
-    Serial.write('0');
-  Serial.print(h);
-  Serial.write(':');
-  if( m < 10 )
-    Serial.write('0');
-  Serial.print(m);
-  Serial.write(':');
-  if( s < 10 )
-    Serial.write('0');
-  Serial.print(s);
-  Serial.write('.');
-  if( ms < 100 )
-    Serial.write('0');
-  if( ms < 10 )
-    Serial.write('0');
-  Serial.print(ms);
+void print_uint64(uint64_t value)
+{
+  char buf[32];
+  int i = 0;
+
+  if( value == 0 )
+  {
+    Serial.print('0');
+  }
+
+  while( value > 0 )
+  {
+    buf[i++] = '0' + (value % 10);
+    value /= 10;
+  }
+  while( i > 0 )
+  {
+    Serial.print(buf[i-1]);
+    i--;
+  }
 }

 void print_event(uint32_t index)
@@ -196,11 +192,8 @@
       break;
   }

-  print_time(events[index].time);
-  Serial.write(' ');
-  Serial.print(events[index].time);
-}
-
+  print_uint64(events[index].time);
+}

 void setup(void)
 {
@@ -234,7 +227,7 @@
   Timer1.start();
 }

-void command_process(char * cmd, uint32_t value, bool val_ok )
+void command_process(char * cmd, uint64_t value, bool val_ok )
 {
   if( strcasecmp(cmd, "time") == 0 )
   {
@@ -243,12 +236,14 @@
       ms_time = value;
     }
     Serial.print("N ");
-    Serial.println(ms_time);
+    print_uint64(ms_time);
+    Serial.println();
   }
   else if( strcasecmp(cmd, "ping") == 0 )
   {
     Serial.print("P ");
-    Serial.println(val_ok ? value : 0);
+    print_uint64(val_ok ? value : 0);
+    Serial.println();
   }
   else if( strcasecmp(cmd, "id") == 0 )
   {
@@ -261,8 +256,8 @@
       Serial.print("R ");
       print_event(value % EVENT_MAX);
       Serial.write(' ');
-      Serial.println(value);
-      //Serial.println("R M1 01:23:45.678 123345 123");
+      Serial.println((uint32_t)value);
+      //Serial.println("R M1 123345 123");
     }
     else
     {
@@ -288,7 +283,7 @@
   {
     if( val_ok )
     {
-      debounce = value;
+      debounce = (uint32_t)value;
       eeprom_write(ROM_OFFSET_DEBOUNCE, debounce);
     }
     Serial.print("B ");
@@ -298,7 +293,7 @@
   {
     if( val_ok )
     {
-      deadtime = value;
+      deadtime = (uint32_t)value;
       eeprom_write(ROM_OFFSET_DEADTIME, deadtime);
     }
     Serial.print("D ");
@@ -320,7 +315,7 @@
   char *cmd;
   char *param;
   char *endptr;
-  uint32_t value;
+  uint64_t value;

   while( Serial.available() )
   {
@@ -335,7 +330,7 @@
           // format: <cmd> <value>
           cmd = strtok(buffer, " ");
           param = strtok(NULL, " ");
-          value = param != NULL ? strtoul(param, &endptr, 0) : 0;
+          value = param != NULL ? strtoull(param, &endptr, 0) : 0;

           command_process(cmd, value, (param != NULL) && (*endptr == 0));

@@ -376,7 +371,7 @@

 void loop_wait(void)
 {
-  static uint32_t prev_time = 0;
+  static uint64_t prev_time = 0;
   while( prev_time == ms_time );
   prev_time = ms_time;
 }


supports 3 sensors

supports 3 sensors

--- ir_targets/ir_targets.ino
+++ ir_targets/ir_targets.ino
@@ -8,8 +8,8 @@

 // Define all the devices as global variables
 IRrecv *irrecvs[BASE_COUNT];
-int ledPins[] = {7,2};
-int receiverPins[] = {8,12};
+int ledPins[] = {7,2,4};
+int receiverPins[] = {8,13,13};

 // Define all time related variables
 unsigned long startMillis;


Check if gimbal already running Only start the motor if it's not already running

--- control/control.ino
+++ control/control.ino
@@ -12,6 +12,10 @@
 Servo gimbal;
 const int laser = 11; // PWM to control laser intensity
 const int gimbalPower = 2; // to transistor to switch power to gimbal
+
+// need to keep track of gimbal status because if it's already on
+// and you try and turn it on it will stop and then restart.
+boolean gimbalOn = false;

 void setup()
 {
@@ -34,23 +38,24 @@
   if (Serial.available() > 0) {
       int msg = Serial.read();

-      if (msg == 76) {
-        // L = laser on
+      if (msg == 76) {          // L = laser on
         analogWrite(laser,255);
         Serial.print("1");
-      } else if (msg == 108) {
-        // l = laser off
+      } else if (msg == 108) {  // l = laser off
         analogWrite(laser,0);
         Serial.print("1");
-      } else if (msg == 71) {
-        // G = start
-        startGimbal();
+      } else if (msg == 71) {   // G = start
+        // only switch it on if it's not running
+        if (gimbalOn == false) {
+          startGimbal();
+          gimbalOn = true;
+        }
         Serial.print("1");
-      } else if (msg = 103) {
-        // g = stop
+      } else if (msg = 103) {   // g = stop
         gimbal.write(0);
         digitalWrite(gimbalPower, LOW);
         Serial.print("1");
+        gimbalOn = false;
       }
   }
 }


Reads all characters of iButtons

Reads all characters of iButtons

--- Harold.ino
+++ Harold.ino
@@ -5,7 +5,7 @@

 //iButton Variables
 OneWire  ds(7);
-byte addr[7];
+byte addr[8];
 int but[6] = {0,149,107,48,13,0};
 String keyStatus = "";

@@ -21,7 +21,7 @@
   //Set up iButton
   pinMode(13, OUTPUT);
   //Print a ready message
-  Serial.println("Everything's Ready!");
+  Serial.println("ready");
 }

 //The char in iButton
@@ -60,9 +60,9 @@
   getKeyCode();
   //if the key is good go through this
   if(keyStatus=="ok"){
-      byte i;
+      int i;
       //For CSH iButtons there are 7 code segments in hexidecimal
-      for( i = 7; i > 0; i--) {
+      for( i = 7; i >= 0; i--) {

         //Adds leading zeros to hex if only one character long
         if( addr[i] < 0x10){
@@ -73,23 +73,17 @@
        Serial.print(addr[i], HEX);

       }
-      //Adds 01 at the end of iButton info since all CSHers have that at the end
-      Serial.print("01");
+
        //Keep a delay so that it doesn't mistakenly read the same iButton more than once
       delay(1000);
       //Makes a new line
       Serial.println();

-      //Makes LED on Arduino blink so we know iButton was read
-      if(addr[1] == but[1] && addr[2] == but[2] && addr[3] == but[3] && addr[4] == but[4]){
-      digitalWrite(13, HIGH);
-      delay(500);
-      digitalWrite(13, LOW);}
-      else {digitalWrite(13, LOW);}
   }
-  else if (keyStatus!="") { Serial.print(keyStatus);}
-
-}
+  else if (keyStatus!="") {
+    Serial.print(keyStatus);
+  }
+  }

 //This does a lot of weird stuff about seeing if the data in the iButton is worth getting
 void getKeyCode(){
@@ -102,15 +96,6 @@
       return;
   }

-  if ( OneWire::crc8( addr, 7) != addr[7]) {
-      keyStatus="CRC invalid";
-      return;
-  }
-
-  if ( addr[0] != 0x01) {
-      keyStatus="not DS1990A";
-      return;
-  }
   keyStatus="ok";
   ds.reset();
 }


Create common touch calibration/test code


Add LEDMatrixOneByOne multiple devices

Add LEDMatrixOneByOne multiple devices

--- LEDMatrixOneByOne/LEDMatrixOneByOne.ino
+++ LEDMatrixOneByOne/LEDMatrixOneByOne.ino
@@ -15,31 +15,37 @@

 #include "LedControl.h"

-// Initialize 1 device
+// Initialize 1 device; possible up to 8 devices
 LedControl lc=LedControl(12,11,10,1);

 void setup() {
-  // deactivate power saving mode on the first device (addr 0)
-  lc.shutdown(0,false);
-  // set brightness to medium on the first device (addr 0) possible values are 0-15
-  lc.setIntensity(0,8);
-  // turn all LEDs off on the first device
-  lc.clearDisplay(0);
+  for (int addr=0; addr<lc.getDeviceCount(); addr++){
+    // deactivate power saving mode
+    lc.shutdown(addr,false);
+    // set brightness to medium; possible values are 0-15
+    lc.setIntensity(addr,8);
+    // turn all LEDs off
+    lc.clearDisplay(addr);
+  }
 }

 void loop(){
   // activate one by one LED
   for (int row=0; row<8; row++){
-    for (int col=0; col<8; col++){
-      lc.setLed(0,row,col,true);
-      delay(50);
+    for (int addr=0; addr<lc.getDeviceCount(); addr++){
+      for (int col=0; col<8; col++){
+        lc.setLed(addr,row,col,true);
+        delay(50);
+      }
     }
   }
   // deactivate one by one LED
   for (int row=0; row<8; row++){
-    for (int col=0; col<8; col++){
-      lc.setLed(0,row,col,false);
-      delay(50);
+    for (int addr=0; addr<lc.getDeviceCount(); addr++){
+      for (int col=0; col<8; col++){
+        lc.setLed(addr,row,col,false);
+        delay(50);
+      }
     }
   }
 }


Adding Watchdog

Adding Watchdog

--- knot/arduino/bedlight.ino
+++ knot/arduino/bedlight.ino
@@ -1,4 +1,5 @@
 #include "FastLED.h"
+#include <avr/wdt.h>

 #define OVERHEAD                  0
 #define NUM_LEDS_OVERHEAD        20
@@ -30,7 +31,7 @@
 #define PLANT_MEASURE_PIN        A0
 #define PLANT_ENABLE_PIN         10
 #define PLANT_ENABLE_DELTA       23
-#define PLANT_UPDATE_VALUE    60000
+#define PLANT_UPDATE_VALUE    30000
 #define PLANT_ENABLE_COUNTER  (PLANT_UPDATE_VALUE - PLANT_ENABLE_DELTA)

 #define COMMAND_RGB               0
@@ -56,6 +57,9 @@

 void setup() {

+  wdt_enable(WDTO_250MS);
+  wdt_reset();
+
   Serial.begin(9600);

   pinMode(PLANT_ENABLE_PIN, OUTPUT);
@@ -65,10 +69,14 @@
   FastLED.addLeds<WS2811,  PIN_BED_LEFT_CENTER, BRG>(BedLedsLeftCenter, NUM_LEDS_BED_LEFT_CENTER ).setCorrection( TypicalLEDStrip );
   FastLED.addLeds<WS2811,  PIN_BED_RIGHT,       BRG>(BedLedsRight,      NUM_LEDS_BED_RIGHT       ).setCorrection( TypicalLEDStrip );

+  wdt_reset();
+
   FastLED.clear(true);
   FastLED.show();

   PlantCounter = 0;
+
+  wdt_reset();

 }

@@ -185,6 +193,8 @@

 void loop() {

+  wdt_reset();
+
   plantCheck();

   if(SleepFireActive > 0){


Menu support

Menu support

Added support for auto calibrate with eeprom and tare. Added menu.

--- Weight.ino
+++ Weight.ino
@@ -21,21 +21,31 @@
 #include <LiquidCrystal.h>
 #include <stdlib.h>
 #include <string.h>
-#include <EEPROM.h>
-
-#define DEBUG 0
+#include <EEPROMex.h>
+#include <EEPROMVar.h> //https://github.com/thijse/Arduino-Libraries/tree/master/EEPROMEx
+
+#define DEBUG 1
 #define TEST 1

 #define WEIGHT_SENSORS 1
 #define DELAY 100
-#define DEFAULT_WEIGHT_TIME 300
-#define DEFAULT_WEIGHT_PRINT_TIME 5000
+#define DEFAULT_WEIGHT_TIME 1000
+#define DEFAULT_WEIGHT_TIME_FAST 50
+#define DEFAULT_WEIGHT_PRINT_TIME 500
 #define DEFAULT_EMPTY_VALUE 8236505
 #define BAUD_RATE 9600
 #define KILO 1000
 #define TAP_SIZE 330
 #define KEG_WEIGHT 4000
-#define USE_EEPROM 0
+#define USE_EEPROM 1
+#define btnRIGHT  0
+#define btnUP     1
+#define btnDOWN   2
+#define btnLEFT   3
+#define btnSELECT 4
+#define btnNONE   5
+
+#define BUTTON_PIN   0

 // Not in use. May be used in the future.
 //int EEPROM_ADDR = 0;
@@ -44,29 +54,89 @@
 //LiquidCrystal lcd(13, 12, 8, 9, 10, 11); //PROD
 LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //DEBUG
 HX711 scales[WEIGHT_SENSORS] = {
-  HX711 (A1, A2)};
+  HX711 (A1, A2)}; //A1 = ANALOG1 = DT // A2=SCK
+int eepromAddress[WEIGHT_SENSORS] = {0};

 unsigned long last = 0;
 unsigned long lastPrint = 0;
-const String kilo = "kg";
-
+const String kilo = "kg   ";
+
+// KEY VARIABLES
+int lcd_key = btnNONE;
+int lcd_key_prev = btnNONE;
+unsigned long lcd_key_prev_pressed = 0;
+unsigned long millisPressedKey = 0;
+int buttonPressed = 0;
+unsigned long debounceTime = 0;
+
+// WEIGHT VARIABLES
+float lastValue = 0;
+unsigned int useFastWeight = 0;
+
+//GUI VARIABLES
+unsigned int printGUI = 0;
+unsigned int menuMarker = 0;
+unsigned int lastItem = 1;

 void setup() {
   Serial.begin(BAUD_RATE);
+
   lcd.begin(16, 2);
   lcd.print("Starting....");
   for (int i = 0; i < WEIGHT_SENSORS; i++) {
-    scales[i].set_scale(-228.f);
+    //scales[i].set_scale(-228.f);
+    scales[i].set_scale(228.f);
     scales[i].tare();
     delay(DELAY);
-    if (USE_EEPROM) {
-      scales[i].set_offset(DEFAULT_EMPTY_VALUE);//TODO: use eeprom.
+    if (USE_EEPROM) { //Firstime use please use calibrate.
+      double value = EEPROM.readDouble(eepromAddress[i]);
+      scales[i].set_offset(value);//TODO: use eeprom.
     }
-    else {
-      scales[i].set_offset(DEFAULT_EMPTY_VALUE);
-    }
   }
   lcd.clear();
+}
+
+
+// read the buttons
+int read_LCD_buttons() {
+  int adc_key_in = 0;
+  adc_key_in = analogRead(BUTTON_PIN);
+  // my buttons when read are centered at these valies: 0, 97, 254, 437, 639
+  // we add approx 50 to those values and check to see if we are close
+  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
+  // For V1.1 us this threshold
+  if (adc_key_in < 50)   return btnRIGHT;
+  if (adc_key_in < 150)  return btnUP;
+  if (adc_key_in < 350)  return btnDOWN;
+  if (adc_key_in < 550)  return btnLEFT;
+  if (adc_key_in < 850)  return btnSELECT;
+  return btnNONE;  // when all others fail, return this...
+}
+
+
+int getButtonPressed() {
+  lcd_key = read_LCD_buttons();  // read the buttons
+  unsigned long now = millis();
+  if (lcd_key == btnNONE) {
+    return btnNONE;
+  } else if (millisPressedKey == 0 && lcd_key != btnNONE) {
+    millisPressedKey = now;
+    return btnNONE;
+  } else if (((millisPressedKey + 10) < now) && (debounceTime < now)) {
+    int lcd_key_confirm = read_LCD_buttons();
+    debounceTime = now + 300;
+    millisPressedKey = 0;
+    if (lcd_key == lcd_key_confirm) {
+      //Serial.println(lcd_key);
+      buttonPressed = 0;
+      return lcd_key;
+    } else {
+      millisPressedKey = now;
+      return btnNONE;
+    }
+  } else {
+    return btnNONE;
+  }
 }

 String getName(const int i) {
@@ -76,7 +146,7 @@
 }

 float getValue(HX711 scale) {
-  float value = scale.get_units(10) ;
+  float value = scale.get_units(3) ;
   if (value > -10 && value < 10)  {
     value = 0;
   }
@@ -84,7 +154,7 @@
 }

 void printToSerial(const float value, const unsigned long now, String& weightName) {
-  if ((lastPrint + DEFAULT_WEIGHT_PRINT_TIME) < now) {
+  if ((lastPrint + DEFAULT_WEIGHT_PRINT_TIME) < now || ((useFastWeight && (last + DEFAULT_WEIGHT_TIME_FAST) < now))) {
     Serial.print(weightName);
     Serial.println(value, 1);
     lastPrint = now;
@@ -122,9 +192,12 @@
 }

 void printWeightOnLCD(const float value, String weightName) {
+  if (printGUI) {
+    return;
+  }
   char* weight = new char[7];
   getWeight(value, weight);
-
+  //lcd.clear();
   if (WEIGHT_SENSORS > 2) {
     lcd.print(weight + kilo);
   } else {
@@ -145,17 +218,35 @@
   delete weight;
 }

-void doWeigth(int value) {
+void doWeigth() {
+   if (printGUI){
+    return;
+  }
   unsigned long now = millis();
-
-  if ((last + DEFAULT_WEIGHT_TIME) < now) {
+  if (((last + DEFAULT_WEIGHT_TIME) < now) || ((useFastWeight && (last + DEFAULT_WEIGHT_TIME_FAST) < now))) {
     for (int i = 0; i < WEIGHT_SENSORS; i++) {
-      scales[i].power_up();
       lcd.setCursor(0, 1);

       String weightName = getName(i);
       float value = getValue(scales[i]);
-
+
+#if defined(DEBUG)
+         Serial.print("Value:");
+         Serial.print(value);
+         Serial.print(" LastValue:");
+         Serial.print(lastValue);
+#endif
+      if ((value > (lastValue + 50)) || (value < (lastValue - 50))) {
+        useFastWeight = 1;
+        lastValue = value;
+      } else {
+        useFastWeight = 0;
+      }
+
+#if defined(DEBUG)
+         Serial.print(" Using FastWeight:");
+         Serial.println(useFastWeight);
+#endif
       printToSerial(value, now, weightName);

       const int row = getRow(i);
@@ -164,15 +255,140 @@

       printWeightOnLCD(value, weightName);

-      delay(50);
-      scales[i].power_down();	// put the ADC in sleep mode
       last = millis();
     }
   }
 }

+
+void printMenuMarker(int up) {
+  //Menu marker
+  if (up) {
+    lcd.setCursor(0, 0);
+    lcd.print(" ");
+    lcd.setCursor(0, 1);
+    lcd.print(">");
+  } else {
+    lcd.setCursor(0, 0);
+    lcd.print(">");
+    lcd.setCursor(0, 1);
+    lcd.print(" ");
+  }
+}
+
+void printMenu() {
+  if (!printGUI){
+    return;
+  }
+  printMenuMarker(menuMarker % 2);
+  lcd.setCursor(1, 0);
+  lcd.print("Calibrate       ");
+  lcd.setCursor(1, 1);
+  lcd.print("Tare       ");
+}
+
+void doTare() {
+  lcd.clear();
+  lcd.setCursor(0, 1);
+  lcd.print("Tare all weights");
+  for (int i = 0; i < WEIGHT_SENSORS; i++) {
+    scales[i].tare();
+    delay(DELAY);
+  }
+  lcd.print("Done tare...");
+  delay(DELAY * 3);
+  printGUI = 0;
+  lcd.clear();
+}
+
+void doCalibrate() {
+  lcd.clear();
+  lcd.setCursor(0, 0);
+  lcd.print("Calibrate all weights");
+  lcd.setCursor(0, 1);
+  lcd.print("Please clear all.");
+  delay(4000);
+  for (int i = 0; i < WEIGHT_SENSORS; i++) {
+    scales[i].tare();
+    double sum = scales[i].read_average(10);
+#if defined(DEBUG)
+    Serial.print("Offset is");
+    Serial.println(sum);
+    //TODO: Safe into eeprom. http://playground.arduino.cc/Code/EEPROMex
+#endif
+    EEPROM.writeDouble(eepromAddress[i], sum);
+    delay(DELAY);
+    printGUI = 0;
+    lcd.clear();
+  }
+}
+
+void doButtonAction(int btn) {
+  if (btn != btnNONE) {
+#if defined(DEBUG)
+    Serial.print(btn);
+#endif
+
+   switch (btn) {
+    case btnRIGHT: {
+      if (printGUI) {
+
+      } else {
+          lcd.clear();
+          printGUI = 1;
+       }
+        break;
+    }
+    case btnSELECT: {
+       if (printGUI) {
+           if (menuMarker == 1) {
+             doTare();
+           } else if (menuMarker == 0) {
+             doCalibrate();
+           }
+       }
+        break;
+      }
+    case btnLEFT: {
+      if (printGUI) {
+         lcd.clear();
+         printGUI = 0;
+      } else {
+
+       }
+        break;
+      }
+    case btnUP: {
+       if (menuMarker == 0) {
+             menuMarker = lastItem;
+       } else {
+             menuMarker = menuMarker - 1;
+       }
+       break;
+      }
+    case btnDOWN: {
+         if (printGUI) {
+           if (menuMarker >= lastItem) {
+             menuMarker = 0;
+           } else {
+             menuMarker = menuMarker + 1;
+           }
+         }
+        break;
+      }
+    case btnNONE:
+      {
+        break;
+      }
+    }
+  }
+}
+
 void loop() {
-  doWeigth(0);
+  int btn = getButtonPressed();
+  doButtonAction(btn);
+  doWeigth();
+  printMenu();
   delay(2);
 }


Common function for JSON headers

Common function for JSON headers

--- weather_station/dashboard/arduino/weather_station_02.ino
+++ weather_station/dashboard/arduino/weather_station_02.ino
@@ -47,7 +47,8 @@
   // Compute heat index
   // Must send in temp in Fahrenheit!
   float hif = dht.computeHeatIndex(f, h);
-
+  float hic = fToC(hif);
+
   // How cold? (temperature and humidity with Arduino)
   // http://wodieskodie.com/how-cold-temperature-and-humidity-with-arduino/
   float dp = dewPoint(c, h);
@@ -73,10 +74,7 @@
       }

       if (request == "tempc") {
-        client.println("Status: 200");
-        client.println("Content-type: application/json");
-        client.println("Access-Control-Allow-Origin: *");
-        client.println(); //mandatory blank line
+        remoteJSONHeaders();

         // JSON response
         client.print("{\"type\":\"temperature\",");
@@ -129,6 +127,21 @@
         client.print("\"title\":\"Heat Index\",");
         client.print("\"value\":\"");
         client.print(hif);
+        client.print("\"}");
+      }
+
+      if (request == "hic") {
+        client.println("Status: 200");
+        client.println("Content-type: application/json");
+        client.println("Access-Control-Allow-Origin: *");
+        client.println(); //mandatory blank line
+
+        // JSON response
+        client.print("{\"type\":\"index\",");
+        client.print("\"scale\":\"Apparent Temperature (Heat Index) in Celsius\",");
+        client.print("\"title\":\"Heat Index\",");
+        client.print("\"value\":\"");
+        client.print(hic);
         client.print("\"}");
       }

@@ -175,3 +188,19 @@

   return (241.88 * T) / (17.558-T);
 }
+
+// Fahrenheit to Celsius formula
+// http://www.rapidtables.com/convert/temperature/how-fahrenheit-to-celsius.htm
+// T(C) = (T(F) - 32) x 5/9
+double fToC(double fahrenheit) {
+  return ((fahrenheit - 32) * 5/9);
+}
+
+// Common JSON response headers to allow remote API calls
+void remoteJSONHeaders() {
+  YunClient client = server.accept();
+  client.println("Status: 200");
+  client.println("Content-type: application/json");
+  client.println("Access-Control-Allow-Origin: *");
+  client.println(); //mandatory blank line
+}


Fixed bug.

Fixed bug.

--- dimmertask.ino
+++ dimmertask.ino
@@ -72,7 +72,7 @@
         float newPercentage;

         /* only do a lot of math if really neccesary */
-        if ( channel[channelNumber].timer[thisTimer].time != channel[channelNumber].timer[thisTimer - 1].time )
+        if ( channel[channelNumber].timer[thisTimer].percentage != channel[channelNumber].timer[thisTimer - 1].percentage )
         {
           newPercentage = mapFloat( milliSecondsToday,
                                     channel[channelNumber].timer[thisTimer - 1].time * 1000U,


Disable diagnostic pin detect for ESP8266

--- examples/arduino/diag_ard_touch_detect/diag_ard_touch_detect.ino
+++ examples/arduino/diag_ard_touch_detect/diag_ard_touch_detect.ino
@@ -31,8 +31,8 @@
   #error "Only DRV_TOUCH_ADA_SIMPLE supports pin detection"
 #endif

-#if defined(__arm__) || defined(ESP32)
-#error "Pin detection not supported on ARM or ESP32 platforms"
+#if defined(__arm__) || defined(ESP32) || defined(ESP8266)
+#error "Pin detection not supported on ARM or ESP platforms"
 #endif


Catch asserts in compliance sketch and log instead

--- examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino
+++ examples/compliance-otaa-halconfig/compliance-otaa-halconfig.ino
@@ -162,6 +162,16 @@
     }
 #endif // LMIC_ENABLE_event_logging

+hal_failure_handler_t log_assertion;
+
+void log_assertion(const char *pMessage, uint16_t line) {
+    eventQueue.putEvent(ev_t(-3), pMessage, line);
+    eventPrintAll();
+    Serial.println("***HALTED BY ASSERT***");
+    while (true)
+        yield();
+}
+
 uint8_t lastTxChannel;
 bool lastTxStart;

@@ -216,6 +226,7 @@
 }

 void printFreq(u4_t freq) {
+    Serial.print(F(": freq="));
     Serial.print(freq / 1000000);
     Serial.print(F("."));
     Serial.print((freq % 1000000) / 100000);
@@ -241,6 +252,54 @@
     Serial.print(F(", txend=")); Serial.print(txend);
 }

+void printTxChnl(u1_t txChnl) {
+    Serial.print(F(": ch="));
+    Serial.print(unsigned(txChnl));
+}
+
+void printDatarate(u1_t datarate) {
+    Serial.print(F(", datarate=")); Serial.print(unsigned(datarate));
+}
+
+void printTxrxflags(u2_t txrxFlags) {
+    Serial.print(F(", txrxFlags=0x")); Serial.print(unsigned(txrxFlags), HEX);
+    if (txrxFlags & TXRX_ACK)
+        Serial.print(F("; Received ack"));
+}
+
+void printSaveIrqFlags(u1_t saveIrqFlags) {
+    Serial.print(F(", saveIrqFlags 0x"));
+    Serial.print(unsigned(saveIrqFlags), HEX);
+}
+
+// dump all the registers.
+void printAllRegisters(void) {
+    uint8_t regbuf[0x80];
+    regbuf[0] = 0;
+    hal_spi_read(1, regbuf + 1, sizeof(regbuf) - 1);
+
+    for (unsigned i = 0; i < sizeof(regbuf); ++i) {
+        if (i % 16 == 0) {
+            printf("\r\n%02x:", i);
+        }
+        printf("%s%02x", ((i % 16) == 8) ? " - " : " ", regbuf[i]);
+    }
+
+    // reset the radio, just in case the register dump caused issues.
+    hal_pin_rst(0);
+    delay(2);
+    hal_pin_rst(2);
+    delay(6);
+
+    // restore the radio to idle.
+    const uint8_t opmode = 0x88;    // LoRa and sleep.
+    hal_spi_write(0x81, &opmode, 1);
+}
+
+void printNl(void) {
+    Serial.println("");
+}
+
 void eventPrint(cEventQueue::eventnode_t &e) {
     ev_t ev = e.event;

@@ -255,6 +314,17 @@
             Serial.print(F(", datum=0x")); Serial.print(e.datum, HEX);
         }
         printOpmode(e.opmode, '.');
+    } else if (ev == ev_t(-3)) {
+        Serial.print(e.pMessage);
+        Serial.print(F(", line ")); Serial.print(e.datum);
+        printFreq(e.freq);
+        printTxend(e.txend);
+        printTxChnl(e.txChnl);
+        printRps(e.rps);
+        printOpmode(e.opmode);
+        printTxrxflags(e.opmode);
+        printSaveIrqFlags(e.saveIrqFlags);
+        printAllRegisters();
     } else {
         if (ev < sizeof(evNames) / sizeof(evNames[0])) {
             Serial.print(evNames[ev]);
@@ -275,8 +345,8 @@
                 break;

             case EV_JOINED:
-                Serial.print(F(": ch "));
-                Serial.println(unsigned(e.txChnl));
+                printTxChnl(e.txChnl);
+                printNl();
                 do  {
                     u4_t netid = 0;
                     devaddr_t devaddr = 0;
@@ -312,35 +382,12 @@
             */
             case EV_JOIN_FAILED:
                 // print out rx info
-                Serial.print(F(":  freq=")); printFreq(e.freq);
+                printFreq(e.freq);
                 printRps(e.rps);
                 printOpmode(e.opmode);
                 printf(" irqLevel %u", hal_getIrqLevel());

-                // dump all the registers.
-                do {
-                    uint8_t regbuf[0x80];
-                    regbuf[0] = 0;
-                    hal_spi_read(1, regbuf + 1, sizeof(regbuf) - 1);
-
-                    for (unsigned i = 0; i < sizeof(regbuf); ++i) {
-                        if (i % 16 == 0) {
-                            printf("\r\n%02x:", i);
-                        }
-                        printf("%s%02x", ((i % 16) == 8) ? " - " : " ", regbuf[i]);
-                    }
-
-                    // reset the radio, just in case the register dump caused issues.
-                    hal_pin_rst(0);
-                    delay(2);
-                    hal_pin_rst(2);
-                    delay(6);
-
-                    // restore the radio to idle.
-                    const uint8_t opmode = 0x88;    // LoRa and sleep.
-                    hal_spi_write(0x81, &opmode, 1);
-
-                } while (0);
+                printAllRegisters();
                 break;

             case EV_REJOIN_FAILED:
@@ -349,12 +396,9 @@
                 break;

             case EV_TXCOMPLETE:
-                Serial.print(F(": ch "));
-                Serial.print(e.txChnl);
+                printTxChnl(e.txChnl);
                 printRps(e.rps);
-                Serial.print(F(" txrxflags 0x")); Serial.print(e.txrxFlags, HEX);
-                if (e.txrxFlags & TXRX_ACK)
-                    Serial.print(F("; Received ack"));
+                printTxrxflags(e.txrxFlags);
                 break;
             case EV_LOST_TSYNC:
                 break;
@@ -377,34 +421,31 @@
             case EV_TXSTART:
                 // this event tells us that a transmit is about to start.
                 // but printing here is bad for timing.
-                Serial.print(F(": ch "));
-                Serial.print(unsigned(e.txChnl));
+                printTxChnl(e.txChnl);
                 printRps(e.rps);
-                Serial.print(F(", datarate ")); Serial.print(unsigned(e.datarate));
+                printDatarate(e.datarate);
                 printOpmode(e.opmode);
                 printTxend(e.txend);
                 break;

             case EV_RXSTART:
-                Serial.print(F(": freq="));
                 printFreq(e.freq);
                 printRps(e.rps);
-                Serial.print(F(", datarate ")); Serial.print(unsigned(e.datarate));
+                printDatarate(e.datarate);
                 printOpmode(e.opmode);
                 printTxend(e.txend);
                 Serial.print(F(", delta ms ")); Serial.print(osticks2ms(e.time - e.txend));
                 break;

             case EV_JOIN_TXCOMPLETE:
-                Serial.print(F(": saveIrqFlags 0x"));
-                Serial.print(unsigned(e.saveIrqFlags), HEX);
+                printSaveIrqFlags(e.saveIrqFlags);
                 break;

             default:
                 break;
         }
     }
-    Serial.println("");
+    printNl();
 }

 /*
@@ -534,7 +575,7 @@
     while (! Serial)
         ;
     Serial.begin(115200);
-    Serial.println(F("Starting"));
+    setup_printSignOn();

     // LMIC init using the computed target
     const auto pPinMap = Arduino_LMIC::GetPinmap_ThisBoard();
@@ -545,6 +586,7 @@
     }

     // now that we have a pinmap, initalize the low levels accordingly.
+    hal_set_failure_handler(log_assertion);
     os_init_ex(pPinMap);

     // LMIC_reset() doesn't affect callbacks, so we can do this first.
@@ -564,6 +606,62 @@
     // Start job (sending automatically starts OTAA too)
     do_send(&sendjob);
 }
+
+void setup_printSignOnDashes(void)
+    {
+    Serial.print(F("------------------------------------"));
+    }
+void setup_printSignOnDashLine()
+    {
+    setup_printSignOnDashes();
+    setup_printSignOnDashes();
+    printNl();
+    }
+
+static constexpr const char *filebasename2(const char *s, const char *p) {
+    return p[0] == '\0'                     ? s                             :
+           (p[0] == '/' || p[0] == '\\')    ? filebasename2(p + 1, p + 1)   :
+                                              filebasename2(s, p + 1)       ;
+}
+
+static constexpr const char *filebasename(const char *s)
+    {
+    return filebasename2(s, s);
+    }
+
+void printVersionFragment(char sep, uint8_t v) {
+    if (sep != 0) {
+        Serial.print(sep);
+    }
+    Serial.print(unsigned(v));
+}
+
+void printVersion(uint32_t v) {
+    printVersionFragment(0, uint8_t(v >> 24u));
+    printVersionFragment('.', uint8_t(v >> 16u));
+    printVersionFragment('.', uint8_t(v >> 8u));
+    if (uint8_t(v) != 0) {
+        printVersionFragment('.', uint8_t(v));
+    }
+}
+
+void setup_printSignOn()
+    {
+    printNl();
+
+    setup_printSignOnDashLine();
+
+    Serial.println(filebasename(__FILE__));
+    Serial.print(F("LMIC version "));
+    printVersion(ARDUINO_LMIC_VERSION);
+    Serial.print(F(" configured for region "));
+    Serial.print(CFG_region);
+    Serial.println(F("."));
+    Serial.println(F("Remember to select 'Line Ending: Newline' at the bottom of the monitor window."));
+
+    setup_printSignOnDashLine();
+    printNl();
+    }

 void setupForNetwork(bool preJoin) {
 #if defined(CFG_us915)


Reworked story adressing. Working now.

Reworked story adressing. Working now.

--- src/tools/NOKO_EEPROM_Disk0/NOKO_EEPROM_Disk0.ino
+++ src/tools/NOKO_EEPROM_Disk0/NOKO_EEPROM_Disk0.ino
@@ -118,19 +118,7 @@
   #endif
   Wire.begin();
   delay(100);
-
-  while (!Serial);
-  delay(200);
-  if (parse)
-  {
-    Serial.print(__TIME__);
-    Serial.println(__DATE__);
-    if (check_summertime()) Serial.println("Summertime");
-    else Serial.println("Wintertime");
-  }
-  else Serial.print("ERROR!");
-
-
+
   // Write EEPROM
   EEPROM.update(0,0);
   EEPROM.update(1,0);
@@ -164,32 +152,33 @@

   // Write AT24C32
   writeDisk(Disk0,0,birth_day);
-  delay(30);
+  delay(10);
   writeDisk(Disk0,1,birth_month);
-  delay(30);
+  delay(10);

   // Write owner name
   for (addr=0;addr<20;addr++)
   {
     writeDisk(Disk0,addr+20,name[addr]);
-    delay(50);
+    delay(10);
   }

   // Write owner email
   for (addr=0;addr<40;addr++)
   {
     writeDisk(Disk0,addr+40,email[addr]);
-    delay(50);
+    delay(10);
   }

   // Write number of stories
   writeDisk(Disk0,2,max_stories);
-  delay(30);
+  delay(10);

   // Write length of stories
   #ifdef def_stories
     for (addr=0;addr<(max_stories*2);addr++)
-      writeDisk(Disk0,addr+(max_stories-1)*40+100,stories_length[addr]);
+      writeDisk(Disk0,addr+100,stories_length[addr]);
+      delay(10);
   #endif

    // Starting adress of stories


updated arduino code, index mapping

updated arduino code, index mapping

--- socket_controller.ino
+++ socket_controller.ino
@@ -1,24 +1,24 @@
 /***
 Arduino controller script for a interactive, light up table.
-
 Author: Bereket Abraham
 ***/
-
 #include "FastSPI_LED2.h"

+// col 13, row 8
+#define NUM_LEDS 104
+#define COL_SIZE 13
+#define ROW_SIZE 8
+#define DATA_PIN 6
 #define STATUS_PIN 3
-#define NUM_LEDS 50
-#define DATA_PIN 6
-CRGB leds[NUM_LEDS];
-
-int index1, index2, red, green, blue;
+#define BUFFER_SIZE 5
 #define DEBUG false

+CRGB leds[NUM_LEDS];
+int serialBuffer[] = {0,0,0,0,0};
+int currIndex = 0;

 void setColor(unsigned int index, unsigned long hexcolor) {
     // Accepts the LED index (int) and the 3 byte color # (unsigned long)
-
-    //leds[index] = CRGB::White;
     leds[index] = hexcolor;
     FastLED.show();

@@ -28,20 +28,33 @@
     }
 }

+unsigned int mapIndex(unsigned int index) {
+    // map the row,col indexing to the layout of
+    // the actual LED string
+    // assuming a zigzag orientation
+    int row = index / ROW_SIZE;
+    int col = index % COL_SIZE;
+    if((row % 2) == 0) {
+      // invert the row if even
+      index = index - ((col*2) - COL_SIZE + 1);
+    }
+    return index;
+}
+
 void blackout() {
     for(int i = 0; i < NUM_LEDS; i++)
     { leds[i] = CRGB::Black; }
-
+
     FastLED.show();
     delay(2000);
 }
 void loop_lights() {
   // Move a single white led
-    for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed++) {
+    for(unsigned int ind = 0; ind < NUM_LEDS; ind++) {
+        unsigned int whiteLed = mapIndex(ind);
         leds[whiteLed] = CRGB::White;
         // Show the leds (only one of which is set to white, from above)
         FastLED.show();
-
         delay(200);
         leds[whiteLed] = CRGB::Black;
     }
@@ -49,41 +62,60 @@

 void setup() {
     Serial.begin(9600);
-    index1 = 0;
-    index2 = 0;
-    red = 0;
-    green = 0;
-    blue = 0;
-
     // Set the LED controller
     delay(1000);
     FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
     blackout();
-    if(DEBUG) { Serial.println("Lights engaged"); }
+    if(DEBUG) {
+        Serial.println("Lights engaged");
+        loop_lights();
+    }

     // Set the status light
     pinMode(STATUS_PIN, OUTPUT);
-
 }

 void loop() {
+    // TODO: create a circular buffer to hold values + end value
+    /*
+    while(Serial.available() > 0) {
+        int val = Serial.read();
+        if(val == ESCPAPE) {
+            int ind1 = (currIndex + BUFFER_SIZE - 5) % BUFFER_SIZE;
+            int ind2 = (currIndex + BUFFER_SIZE - 4) % BUFFER_SIZE;
+            int r = (currIndex + BUFFER_SIZE - 3) % BUFFER_SIZE;
+            int g = (currIndex + BUFFER_SIZE - 2) % BUFFER_SIZE;
+            int b = (currIndex + BUFFER_SIZE - 1) % BUFFER_SIZE;
+            // combine index bytes
+            unsigned int index = ((unsigned int)serialBuffer[ind1] << 8) +
+                                  (unsigned int)serialBuffer[ind2];
+            index = mapIndex(index);
+            // RGB, 0xFFAACC, 3 bytes
+            unsigned long hexcolor = ((unsigned long)serialBuffer[r] << 16) +
+                                     ((unsigned long)serialBuffer[g] << 8) +
+                                     (unsigned long)serialBuffer[b];
+            setColor(index, hexcolor);
+        } else {
+            serialBuffer[currIndex] = val;
+            currIndex = (currIndex + 1) % BUFFER_SIZE;
+        }
+    }
+    */
     // 2 bytes for the index, 3 for the color
     if ( Serial.available() >= 5 )  {
-        index1 = Serial.read();
-        index2 = Serial.read();
-        red = Serial.read();
-        green = Serial.read();
-        blue = Serial.read();
+        int index1 = Serial.read();
+        int index2 = Serial.read();
+        int red = Serial.read();
+        int green = Serial.read();
+        int blue = Serial.read();

         // combine index bytes
         unsigned int index = ((unsigned int)index1 << 8) + (unsigned int)index2;
+        index = mapIndex(index);
         // RGB, 0xFFAACC, 3 bytes
         unsigned long hexcolor = ((unsigned long)red << 16) + ((unsigned long)green << 8) + (unsigned long)blue;

         setColor(index, hexcolor);
     }
-
-    //FastLED.show();
 }

-


Fix 2 0.0.7

Fix 2 0.0.7

--- src/WiFiSensor/measurements.ino
+++ src/WiFiSensor/measurements.ino
@@ -30,7 +30,7 @@
   }

   if(dht2d6){
-	dhtok = false;
+	dhtOK = false;
 	while( !dhtOK){ //Loop to wait for good DHT value
 		dhtOK = true; //assume it is going to work
 		dht.read();


Disable the output after calibrating instead of deprecated stop

--- examples/CalibrateESCs/CalibrateESCs.ino
+++ examples/CalibrateESCs/CalibrateESCs.ino
@@ -5,7 +5,7 @@

 void setup(){
     calibrateESCs();
+    output.disable();
 }
 void loop(){
-    output.stop();
 }


update example for improved ESP32DMX library

--- examples/ESP32-DMX_rdm/ESP32-DMX_rdm.ino
+++ examples/ESP32-DMX_rdm/ESP32-DMX_rdm.ino
@@ -8,10 +8,10 @@
     Example using LXDMXWiFi_Library for output of Art-Net or E1.31 sACN from
     ESP32 WiFi connection to serial DMX.  Or, input from DMX to the network.
     Allows remote configuration of WiFi connection and protocol settings.
-
+
     Art-Net(TM) Designed by and Copyright Artistic Licence Holdings Ltd.
     sACN E 1.31 is a public standard published by the PLASA technical standards program
-
+
     Note:  This example requires the LXESP32DMX library for DMX serial output
            https://github.com/claudeheintz/LXESP32DMX

@@ -32,28 +32,34 @@
 #include <LXWiFiArtNet.h>
 #include <LXWiFiSACN.h>
 #include "LXDMXWiFiConfig.h"
-#include "esp_task_wdt.h"
+#include "freertos/task.h"

 #define STARTUP_MODE_PIN 18      // pin for force default setup when low (use 10k pullup to insure high)
 #define DIRECTION_PIN 21          // pin for output direction enable on MAX481 chip

 #define STATUS_LED 19

+#define DEBUG_PIN_A 22
+#define DEBUG_PIN_B 23
+#define DEBUG_PIN_C 14
+
+char ssid[32];
+char password[32];

 // RDM defines
 #define DISC_STATE_SEARCH 0
 #define DISC_STATE_TBL_CK 1
 /*
- * If RDM_DISCOVER_ALWAYS == 0, the times RDM discovery runs is limited to 10 cycles
- * of table check and search.  When rdm_discovery_enable reaches zero, continous RDM
- * discovery stops.  Other ArtRDM packets continue to be relayed.
- * If an Art-Net TODRequest or TODControl packet is received, the rdm_discovery_enable
- * counter is reset and discovery runs again until rdm_discovery_enable reaches zero.
- */
+   If RDM_DISCOVER_ALWAYS == 0, the times RDM discovery runs is limited to 10 cycles
+   of table check and search.  When rdm_discovery_enable reaches zero, continous RDM
+   discovery stops.  Other ArtRDM packets continue to be relayed.
+   If an Art-Net TODRequest or TODControl packet is received, the rdm_discovery_enable
+   counter is reset and discovery runs again until rdm_discovery_enable reaches zero.
+*/
 #define RDM_DISCOVER_ALWAYS 0

-/*
- *  Edit the LXDMXWiFiConfig.initConfig() function in LXDMXWiFiConfig.cpp to configure the WiFi connection and protocol options
+/*
+    Edit the LXDMXWiFiConfig.initConfig() function in LXDMXWiFiConfig.cpp to configure the WiFi connection and protocol options
 */

 // dmx protocol interfaces for parsing packets (created in setup)
@@ -84,15 +90,15 @@
 TOD tableOfDevices;                           // UUIDs of found devices
 TOD discoveryTree;                            // stack of UUID ranges for discovery search

-UID lower(0,0,0,0,0,0);
-UID upper(0,0,0,0,0,0);
-UID mid(0,0,0,0,0,0);
-UID found(0,0,0,0,0,0);
+UID lower(0, 0, 0, 0, 0, 0);
+UID upper(0, 0, 0, 0, 0, 0);
+UID mid(0, 0, 0, 0, 0, 0);
+UID found(0, 0, 0, 0, 0, 0);

 // used to toggle indicator LED on and off
 uint8_t led_state = 0;

-/*
+/*
    utility function to toggle indicator LED on/off
 */
 void blinkLED() {
@@ -105,7 +111,7 @@
   }
 }

-/*
+/*
    artAddress callback allows storing of config information
    artAddress may or may not have set this information
    but relevant fields are copied to config struct and stored to EEPROM
@@ -127,47 +133,47 @@

   //copy into ESP32DMX outgoing packet
   uint8_t* pkt = ESP32DMX.rdmData();
-  for (j=0; j<plen; j++) {
-    pkt[j+1] = pdata[j];
+  for (j = 0; j < plen; j++) {
+    pkt[j + 1] = pdata[j];
   }
   pkt[0] = 0xCC;

-
+
   if ( ESP32DMX.sendRDMControllerPacket() ) {
     artNetInterface->send_art_rdm(&aUDP, ESP32DMX.receivedRDMData(), aUDP.remoteIP());
   }
 }

-/*
+/*
    artIpProg callback allows storing of config information
    cmd field bit 7 indicates that settings should be programmed
 */
 void artIpProgReceived(uint8_t cmd, IPAddress addr, IPAddress subnet) {
-   if ( cmd & 0x80 ) {
-      if ( cmd & 0x40 ) {	//enable dhcp, other fields not written
-      	if ( DMXWiFiConfig.staticIPAddress() ) {
-      		DMXWiFiConfig.setStaticIPAddress(0);
-      	} else {
-      	   return;	// already set to dhcp
-      	}
+  if ( cmd & 0x80 ) {
+    if ( cmd & 0x40 ) {	//enable dhcp, other fields not written
+      if ( DMXWiFiConfig.staticIPAddress() ) {
+        DMXWiFiConfig.setStaticIPAddress(0);
       } else {
-         if ( ! DMXWiFiConfig.staticIPAddress() ) {
-      	   DMXWiFiConfig.setStaticIPAddress(1);	// static not dhcp
-      	}
-      	if ( cmd & 0x08 ) {	//factory reset
-      	   DMXWiFiConfig.initConfig();
-      	} else {
-      	   if ( cmd & 0x04 ) {	//programIP
-      	      DMXWiFiConfig.setStationIPAddress(addr);
-      	   }
-      	   if ( cmd & 0x02 ) {	//programSubnet
-      	      DMXWiFiConfig.setStationSubnetMask(subnet);
-      	   }
-      	}
-      }	// else ( ! dhcp )
-
-      DMXWiFiConfig.commitToPersistentStore();
-   }
+        return;	// already set to dhcp
+      }
+    } else {
+      if ( ! DMXWiFiConfig.staticIPAddress() ) {
+        DMXWiFiConfig.setStaticIPAddress(1);	// static not dhcp
+      }
+      if ( cmd & 0x08 ) {	//factory reset
+        DMXWiFiConfig.initConfig();
+      } else {
+        if ( cmd & 0x04 ) {	//programIP
+          DMXWiFiConfig.setStationIPAddress(addr);
+        }
+        if ( cmd & 0x02 ) {	//programSubnet
+          DMXWiFiConfig.setStationSubnetMask(subnet);
+        }
+      }
+    }	// else ( ! dhcp )
+
+    DMXWiFiConfig.commitToPersistentStore();
+  }
 }

 /*
@@ -181,17 +187,17 @@
 /************************************************************************/

 uint8_t testMute(UID u) {
-   // try three times to get response when sending a mute message
-   if ( ESP32DMX.sendRDMDiscoveryMute(u, RDM_DISC_MUTE) ) {
-     return 1;
-   }
-   if ( ESP32DMX.sendRDMDiscoveryMute(u, RDM_DISC_MUTE) ) {
-     return 1;
-   }
-   if ( ESP32DMX.sendRDMDiscoveryMute(u, RDM_DISC_MUTE) ) {
-     return 1;
-   }
-   return 0;
+  // try three times to get response when sending a mute message
+  if ( ESP32DMX.sendRDMDiscoveryMute(u, RDM_DISC_MUTE) ) {
+    return 1;
+  }
+  if ( ESP32DMX.sendRDMDiscoveryMute(u, RDM_DISC_MUTE) ) {
+    return 1;
+  }
+  if ( ESP32DMX.sendRDMDiscoveryMute(u, RDM_DISC_MUTE) ) {
+    return 1;
+  }
+  return 0;
 }

 void checkDeviceFound(UID found) {
@@ -211,7 +217,7 @@
       // device confirmed
       return ck_index += 6;
     }
-
+
     // device not found
     tableOfDevices.removeUIDAt(ck_index);
     tableChangedFlag = 1;
@@ -258,21 +264,21 @@
         if ( result ) {
           //this range responded, so divide into sub ranges push them on stack to be further checked
           pushActiveBranch(lower, upper);
-
+
         } else if ( ESP32DMX.sendRDMDiscoveryPacket(lower, upper, &found) ) {
-            pushActiveBranch(lower, upper); //if discovery fails, try a second time
+          pushActiveBranch(lower, upper); //if discovery fails, try a second time
         }
       }         // end check range
       return 1; // UID ranges may be remaining to test
     }           // end valid pop
-  }             // end valid pop
+  }             // end valid pop
   return 0;     // none left to pop
 }

 void sendTODifChanged() {
   if ( tableChangedFlag ) {   //if the table has changed...
     tableChangedFlag--;
-
+
     artNetInterface->send_art_tod(&aUDP, tableOfDevices.rawBytes(), tableOfDevices.count());

     Serial.println("_______________ Table Of Devices _______________");
@@ -285,16 +291,16 @@
     if ( discovery_state ) {
       // check the table of devices
       discovery_tbl_ck_index = checkTable(discovery_tbl_ck_index);
-
+
       if ( discovery_tbl_ck_index == 0 ) {
         // done with table check
         discovery_state = DISC_STATE_SEARCH;
         pushInitialBranch();
-
+
         sendTODifChanged();
       } //end table check ended
     } else {    // search for devices in range popped from discoveryTree
-
+
       if ( checkNextRange() == 0 ) {
         // done with search
         discovery_tbl_ck_index = 0;
@@ -311,16 +317,16 @@
 /************************************************************************

   Setup creates the WiFi connection.
-
+
   It also creates the network protocol object,
   either an instance of LXWiFiArtNet or LXWiFiSACN.
-
+
   if OUTPUT_FROM_NETWORK_MODE:
      Starts listening on the appropriate UDP port.
-
+
      And, it starts the ESP32DMX sending serial DMX via the UART1 TX pin.
      (see the LXESP32DMX library documentation for driver details)
-
+
    if INPUT_TO_NETWORK_MODE:
      Starts ESP32DMX listening for DMX ( received as serial on UART0 RX pin. )

@@ -332,16 +338,19 @@
   pinMode(STATUS_LED, OUTPUT);
   pinMode(STARTUP_MODE_PIN, INPUT_PULLUP);
   pinMode(DIRECTION_PIN, OUTPUT);
+
   //debugging
-
-
+  pinMode(DEBUG_PIN_A, OUTPUT);
+  pinMode(DEBUG_PIN_B, OUTPUT);
+  pinMode(DEBUG_PIN_C, OUTPUT);
+
   uint8_t bootStatus = DMXWiFiConfig.begin(1);//aparently need to read from persistent to be able to write to it
   uint8_t dhcpStatus = 0;                     //hence, read in begin and replace below if startup pin is low

   if ( digitalRead(STARTUP_MODE_PIN) == 0 ) {
-    DMXWiFiConfig.initConfig();
-  }
-
+    DMXWiFiConfig.initConfig();
+  }
+
   dmx_direction = DMXWiFiConfig.inputToNetworkMode();
   rdm_enabled   = DMXWiFiConfig.rdmMode();

@@ -353,20 +362,23 @@
     Serial.print("created access point at ");
     Serial.print(DMXWiFiConfig.apIPAddress());
     WiFi.softAPConfig(DMXWiFiConfig.apIPAddress(), DMXWiFiConfig.apGateway(), DMXWiFiConfig.apSubnet());
-
+
     Serial.print(" accessPoint SSID ");
     Serial.print(DMXWiFiConfig.SSID());
-
+
     Serial.print(", ");
   } else {
     Serial.print("wifi connecting to ");
     Serial.print(DMXWiFiConfig.SSID());
-    Serial.print(" ... ");
+    Serial.print("... ");
     WiFi.mode(WIFI_STA);
-    WiFi.begin(DMXWiFiConfig.SSID(),DMXWiFiConfig.password());
+    strcpy(ssid, DMXWiFiConfig.SSID());
+    strcpy(password, DMXWiFiConfig.password());
+    WiFi.begin((const char*)ssid, (const char*)password);

     // static IP otherwise uses DHCP
-    if ( DMXWiFiConfig.staticIPAddress() ) {
+    if ( DMXWiFiConfig.staticIPAddress() ) {
+      Serial.print("static IP");
       WiFi.config(DMXWiFiConfig.stationIPAddress(), DMXWiFiConfig.stationGateway(), DMXWiFiConfig.stationSubnet());
     } else {
       dhcpStatus = 1;
@@ -375,7 +387,7 @@
     while (WiFi.status() != WL_CONNECTED)  {
       delay(100);
       blinkLED();
-
+
     }

   }
@@ -393,10 +405,10 @@
     ESP32DMX.setDataReceivedCallback(&gotDMXCallback);
     ESP32DMX.startInput();
   }
-
+
   //------------------- Initialize network<->DMX interfaces -------------------
-
-  sACNInterface = new LXWiFiSACN();
+
+  sACNInterface = new LXWiFiSACN();
   sACNInterface->setUniverse(DMXWiFiConfig.sACNUniverse());

   artNetInterface = new LXWiFiArtNet(WiFi.localIP(), WiFi.subnetMask());
@@ -412,7 +424,7 @@
   artNetInterface->setStatus2Flag(ARTNET_STATUS2_SACN_CAPABLE, 1);
   artNetInterface->setStatus2Flag(ARTNET_STATUS2_DHCP_CAPABLE, 1);
   if ( dhcpStatus ) {
-  	 artNetInterface->setStatus2Flag(ARTNET_STATUS2_DHCP_USED, 1);
+    artNetInterface->setStatus2Flag(ARTNET_STATUS2_DHCP_USED, 1);
   }
   if ( bootStatus ) {
     artNetInterface->setStatus1Flag(ARTNET_STATUS1_FACTORY_BOOT, 1);
@@ -422,144 +434,157 @@
   }
   artNetInterface->setStatus1Flag(ARTNET_STATUS1_RDM_CAPABLE, 1);
   Serial.print("interfaces created, ");
-
+
   // if output from network, start wUDP listening for packets
-  if ( dmx_direction == OUTPUT_FROM_NETWORK_MODE ) {
-		if ( DMXWiFiConfig.multicastMode() ) {
-			if ( DMXWiFiConfig.APMode() ) {
-				sUDP.beginMulticast(DMXWiFiConfig.multicastAddress(), sACNInterface->dmxPort());  //WiFi.softAPIP(),
-			} else {
-				sUDP.beginMulticast(DMXWiFiConfig.multicastAddress(), sACNInterface->dmxPort());  //WiFi.localIP(),
-			}
-		} else {
-			sUDP.begin(sACNInterface->dmxPort());
-		}
-
+  if ( dmx_direction == OUTPUT_FROM_NETWORK_MODE ) {
+    if ( DMXWiFiConfig.multicastMode() ) {
+      if ( DMXWiFiConfig.APMode() ) {
+        sUDP.beginMulticast(DMXWiFiConfig.multicastAddress(), sACNInterface->dmxPort());  //WiFi.softAPIP(),
+      } else {
+        sUDP.beginMulticast(DMXWiFiConfig.multicastAddress(), sACNInterface->dmxPort());  //WiFi.localIP(),
+      }
+    } else {
+      sUDP.begin(sACNInterface->dmxPort());
+    }
+
     aUDP.begin(artNetInterface->dmxPort());
     artNetInterface->send_art_poll_reply(&aUDP);
-	 Serial.print("udp started listening,");
+    Serial.print("udp started listening,");
   }

   Serial.println(" setup complete.");
   blinkLED();

-  // trial:  Increase loop priority to 2 above DMX, which is 1
+
+  // increase the priority of this task (main.cpp sets it at 1);
   vTaskPrioritySet(xTaskGetCurrentTaskHandle(), 2);

+  Serial.print("number of tasks is ");
+  Serial.println(uxTaskGetNumberOfTasks());
+  /*
+  char taskinfo[256];
+  TaskStatus_t tslist[10];
+  uint32_t trt;
+  uxTaskGetSystemState(tslist, 10, &trt);
+  //vTaskList(taskinfo);
+  //Serial.println(taskinfo);*/
+
 } //setup

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

   Copy to output merges slots for Art-Net and sACN on HTP basis
-
+
 *************************************************************************/

 void copyDMXToOutput(void) {
-	uint8_t a, s;
-	uint16_t a_slots = artNetInterface->numberOfSlots();
-	uint16_t s_slots = sACNInterface->numberOfSlots();
-	for (int i=1; i <=DMX_UNIVERSE_SIZE; i++) {
-		if ( i <= a_slots ) {
-			a = artNetInterface->getSlot(i);
-		} else {
-			a = 0;
-		}
-		if ( i <= s_slots ) {
-			s = sACNInterface->getSlot(i);
-		} else {
-			s = 0;
-		}
-		if ( a > s ) {
-      	ESP32DMX.setSlot(i , a);
-      } else {
-      	ESP32DMX.setSlot(i , s);
-      }
-   }
-   ESP32DMX.setMaxSlots(512);
+  uint8_t a, s;
+  uint16_t a_slots = artNetInterface->numberOfSlots();
+  uint16_t s_slots = sACNInterface->numberOfSlots();
+  xSemaphoreTake( ESP32DMX.lxDataLock, portMAX_DELAY );
+  for (int i = 1; i <= DMX_UNIVERSE_SIZE; i++) {
+    if ( i <= a_slots ) {
+      a = artNetInterface->getSlot(i);
+    } else {
+      a = 0;
+    }
+    if ( i <= s_slots ) {
+      s = sACNInterface->getSlot(i);
+    } else {
+      s = 0;
+    }
+    if ( a > s ) {
+      ESP32DMX.setSlot(i , a);
+    } else {
+      ESP32DMX.setSlot(i , s);
+    }
+  }
+  ESP32DMX.setMaxSlots(512);
+  xSemaphoreGive( ESP32DMX.lxDataLock );
 }

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

   Checks to see if packet is a config packet.
-
+
      In the case it is a query, it replies with the current config from persistent storage.
-
+
      In the case of upload, it copies the payload to persistent storage
      and also replies with the config settings.
-
+
 *************************************************************************/

 void checkConfigReceived(LXDMXWiFi* interface, WiFiUDP* cUDP) {
-	if ( strcmp(CONFIG_PACKET_IDENT, (const char *) interface->packetBuffer()) == 0 ) {	//match header to config packet
-		Serial.print("config packet received, ");
-		uint8_t reply = 0;
-		if ( interface->packetBuffer()[8] == '?' ) {	//packet opcode is query
-			DMXWiFiConfig.readFromPersistentStore();
-			reply = 1;
-		} else if (( interface->packetBuffer()[8] == '!' ) && (interface->packetSize() >= 171)) { //packet opcode is set
-			Serial.println("upload packet");
-			DMXWiFiConfig.copyConfig( interface->packetBuffer(), interface->packetSize());
-			DMXWiFiConfig.commitToPersistentStore();
-			reply = 1;
-		} else if ( interface->packetBuffer()[8] == '^' ) {
-			ESP.restart();
-		} else {
-			Serial.println("unknown config opcode.");
-	  	}
-		if ( reply) {
-			DMXWiFiConfig.hidePassword();													// don't transmit password!
-			cUDP->beginPacket(cUDP->remoteIP(), interface->dmxPort());				// unicast reply
-			cUDP->write((uint8_t*)DMXWiFiConfig.config(), DMXWiFiConfigSIZE);
-			cUDP->endPacket();
+  if ( strcmp(CONFIG_PACKET_IDENT, (const char *) interface->packetBuffer()) == 0 ) {	//match header to config packet
+    Serial.print("config packet received, ");
+    uint8_t reply = 0;
+    if ( interface->packetBuffer()[8] == '?' ) {	//packet opcode is query
+      DMXWiFiConfig.readFromPersistentStore();
+      reply = 1;
+    } else if (( interface->packetBuffer()[8] == '!' ) && (interface->packetSize() >= 171)) { //packet opcode is set
+      Serial.println("upload packet");
+      DMXWiFiConfig.copyConfig( interface->packetBuffer(), interface->packetSize());
+      DMXWiFiConfig.commitToPersistentStore();
+      reply = 1;
+    } else if ( interface->packetBuffer()[8] == '^' ) {
+      ESP.restart();
+    } else {
+      Serial.println("unknown config opcode.");
+    }
+    if ( reply) {
+      DMXWiFiConfig.hidePassword();													// don't transmit password!
+      cUDP->beginPacket(cUDP->remoteIP(), interface->dmxPort());				// unicast reply
+      cUDP->write((uint8_t*)DMXWiFiConfig.config(), DMXWiFiConfigSIZE);
+      cUDP->endPacket();
       Serial.println(DMXWiFiConfig.SSID());
-			Serial.println("reply complete.");
-			DMXWiFiConfig.restorePassword();
-		}
-		interface->packetBuffer()[0] = 0; //insure loop without recv doesn't re-trigger
-		interface->packetBuffer()[1] = 0;
-		blinkLED();
-		delay(100);
-		blinkLED();
-		delay(100);
-		blinkLED();
-	}		// packet has config packet header
+      Serial.println("reply complete.");
+      DMXWiFiConfig.restorePassword();
+    }
+    interface->packetBuffer()[0] = 0; //insure loop without recv doesn't re-trigger
+    interface->packetBuffer()[1] = 0;
+    blinkLED();
+    delay(100);
+    blinkLED();
+    delay(100);
+    blinkLED();
+  }		// packet has config packet header
 }

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

   Checks to see if the dmx callback indicates received dmx
      If so, send it using the selected interface.
-
+
 *************************************************************************/

 void checkInput(LXDMXWiFi* interface, WiFiUDP* iUDP, uint8_t multicast) {
-	if ( got_dmx ) {
-		interface->setNumberOfSlots(got_dmx);			// set slots & copy to interface
-		for(int i=1; i<=got_dmx; i++) {
-		  interface->setSlot(i, ESP32DMX.getSlot(i));
-		}
-		if ( multicast ) {
-			interface->sendDMX(iUDP, DMXWiFiConfig.inputAddress(), WiFi.localIP());
-		} else {
-			interface->sendDMX(iUDP, DMXWiFiConfig.inputAddress(), INADDR_NONE);
-		}
-      got_dmx = 0;
-      blinkLED();
-    }       // got_dmx
+  if ( got_dmx ) {
+    interface->setNumberOfSlots(got_dmx);			// set slots & copy to interface
+    for (int i = 1; i <= got_dmx; i++) {
+      interface->setSlot(i, ESP32DMX.getSlot(i));
+    }
+    if ( multicast ) {
+      interface->sendDMX(iUDP, DMXWiFiConfig.inputAddress(), WiFi.localIP());
+    } else {
+      interface->sendDMX(iUDP, DMXWiFiConfig.inputAddress(), INADDR_NONE);
+    }
+    got_dmx = 0;
+    blinkLED();
+  }       // got_dmx
 }

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

   Main loop
-
+
   if OUTPUT_FROM_NETWORK_MODE:
     checks for and reads packets from WiFi UDP socket
     connection.  readDMXPacket() returns true when a DMX packet is received.
-
+
     If dmx is received on either interface, copy from both (HTP) to dmx output.
-
+
     If the packet is an CONFIG_PACKET_IDENT packet, the config struct is modified and stored in EEPROM
-
+
   if INPUT_TO_NETWORK_MODE:
     if serial dmx has been received, sends an sACN or Art-Net packet containing the dmx data.
     Note:  does not listen for incoming packets for remote configuration in this mode.
@@ -567,48 +592,48 @@
 *************************************************************************/

 void loop() {
-	if ( dmx_direction == OUTPUT_FROM_NETWORK_MODE ) {
-
-		art_packet_result = artNetInterface->readDMXPacket(&aUDP);
-		if ( art_packet_result == RESULT_NONE ) {
-			checkConfigReceived(artNetInterface, &aUDP);
-		}
-    esp_task_wdt_feed();
+  //digitalWrite(DEBUG_PIN_C, LOW);
+
+  if ( dmx_direction == OUTPUT_FROM_NETWORK_MODE ) {
+
+    art_packet_result = artNetInterface->readDMXPacket(&aUDP);
+    if ( art_packet_result == RESULT_NONE ) {
+      checkConfigReceived(artNetInterface, &aUDP);
+    }
     vTaskDelay(1);
-
-		acn_packet_result = sACNInterface->readDMXPacket(&sUDP);
-		if ( acn_packet_result == RESULT_NONE ) {
-			checkConfigReceived(sACNInterface, &sUDP);
-		}
-    esp_task_wdt_feed();
+
+    acn_packet_result = sACNInterface->readDMXPacket(&sUDP);
+    if ( acn_packet_result == RESULT_NONE ) {
+      checkConfigReceived(sACNInterface, &sUDP);
+    }
     vTaskDelay(1);
-
-		if ( (art_packet_result == RESULT_DMX_RECEIVED) || (acn_packet_result == RESULT_DMX_RECEIVED) ) {
-			copyDMXToOutput();
-			blinkLED();
-		} else {
+
+    if ( (art_packet_result == RESULT_DMX_RECEIVED) || (acn_packet_result == RESULT_DMX_RECEIVED) ) {
+      copyDMXToOutput();
+      blinkLED();
+    } else {
       // output was not updated last 5 times through loop so use a cycle to perform the next step of RDM discovery
-		  if ( rdm_enabled ) {
+      if ( rdm_enabled ) {
         idle_count++;
         if ( idle_count > 5 ) {
           updateRDMDiscovery();
           idle_count = 0;
         }
       }
-		}
-
-	} else {    //direction is input to network
-
-		if ( DMXWiFiConfig.sACNMode() ) {
-			checkInput(sACNInterface, &sUDP, DMXWiFiConfig.multicastMode());
-		} else {
-			checkInput(artNetInterface, &aUDP, 0);
-		}
-
-	}
-
-  esp_task_wdt_feed();
+    }
+
+  } else {    //direction is input to network
+
+    if ( DMXWiFiConfig.sACNMode() ) {
+      checkInput(sACNInterface, &sUDP, DMXWiFiConfig.multicastMode());
+    } else {
+      checkInput(artNetInterface, &aUDP, 0);
+    }
+
+  }
+  //digitalWrite(DEBUG_PIN_C, HIGH);
   vTaskDelay(1);
   //taskYIELD();
+
 }// loop()


added the JSON to send over udp

added the JSON to send over udp

--- DelayAndSerialAndLuxAndRTC/DelayAndSerialAndLuxAndRTC.ino
+++ DelayAndSerialAndLuxAndRTC/DelayAndSerialAndLuxAndRTC.ino
@@ -2,12 +2,6 @@
 #include <Wire.h>
 #include <TSL2561.h> // this is the Lux sensor
 #include <DS3232RTC.h>    //http://github.com/JChristensen/DS3232RTC
-
-
-/* Based on Blink without Delay, David A. Mellis, Paul Stoffregen, Scott Fitzgerald
-
-*/
-

 /**********************************
@@ -160,6 +154,29 @@
       year(t), month(t), day(t), hour(t), minute(t), second(t));
 }

+String returnISOdate() {
+  time_t t = now();
+  sprintf(isodate, "%4d-%02d-%02dT%02d:%02d:%02dZ",
+      year(t), month(t), day(t), hour(t), minute(t), second(t));
+  return (String(isodate));
+}
+
+String formatJSON(String tm, void *lum, float temp) {
+  Luminosity *lum2 = (Luminosity*)lum;
+  String JSON;
+  JSON = "{\"datetime\":\"" + tm + "\"," +
+         "\"Temperature\":" + String(temp) + "," +
+        "\"Luminosity\": {" +
+            "\"IR\":" + String(lum2->IR) + "," +
+            "\"Full\":" + String(lum2->Full) + "," +
+            "\"Visible\":" + String(lum2->Visible) + "," +
+            "\"Lux\":" + String(lum2->Lux) + "}" +
+        "}";
+    return (JSON);
+
+}
+
+
 void loop()
 {
   uint8_t i;
@@ -204,21 +221,11 @@
     Serial.print("Lux: "); Serial.println(lum.Lux);
 //

-
-//    Serial.print(hour());
-//    printDigits(minute());
-//    printDigits(second());
-//    Serial.print(' ');
-//    Serial.print(day());
-//    Serial.print(' ');
-//    Serial.print(month());
-//    Serial.print(' ');
-//    Serial.print(year());
-//    Serial.println();
-makeISOdate();
-    Serial.println(isodate);
-
-
+
+    Serial.println(returnISOdate());
+
+    Serial.println( formatJSON(returnISOdate(), &lum, temperatureValue) );
+
 //    int seconds = Wire.read(); // get seconds
 //    int minutes = Wire.read(); // get minutes
 //    int hours = Wire.read();   // get hours


servos list

servos list

--- examples/merg_servo_ir/merg_servo_ir.ino
+++ examples/merg_servo_ir/merg_servo_ir.ino
@@ -53,13 +53,12 @@
 byte active_ir;

 struct SENSOR sensors[NUMSENSORS];
-int sensorport[NUMSENSORS]={A0, A1 ,A2 ,A3, A6,A7};
+int sensorport[NUMSENSORS]={A0, A1 ,A2 ,A3, A4, A5, A6, A7};

 //CBUS definitions
-#define GREEN_LED A4                            //merg green led port
-#define YELLOW_LED A5                           //merg yellow led port
-#define PUSH_BUTTON 0                          //std merg push button
-#define PUSH_BUTTON1 1                         //debug push button
+#define GREEN_LED 8                            //merg green led port
+#define YELLOW_LED 7                           //merg yellow led port
+#define PUSH_BUTTON 9                          //std merg push button
 #define NODE_EVENTS 30                          //max number of events
 #define EVENTS_VARS 1                          //number of variables per event
 #define DEVICE_NUMBERS NUMSENSORS+NUM_SERVOS   //number of device numbers. each servo can be a device


copyrights

copyrights


Style formatting.

Style formatting.

--- examples/adsr/adsr.ino
+++ examples/adsr/adsr.ino
@@ -236,7 +236,8 @@
   interface->timer_isr();
 }

-void setup() {
+void setup()
+{
   gate = 0;

   function = new DU_ADSR_Function();
@@ -249,7 +250,8 @@
   Timer1.attachInterrupt(timer_isr);
 }

-void loop() {
+void loop()
+{
   function->loop();
   interface->loop();
 }


Nicer status output

Nicer status output

--- esp8266/esp8266.ino
+++ esp8266/esp8266.ino
@@ -2123,32 +2123,32 @@
   help_info(String(F("Z=")) + virtual_serial_on);
   help_info(String(F("z=")) + virtual_serial_port);

-  help_info(String(F("AP-IP: ")) + WiFi.softAPIP().toString());
+  help_info(String(F("  AP-IP: ")) + WiFi.softAPIP().toString());
   help_info(String(F("WiFi-IP: ")) + WiFi.localIP().toString());

   unsigned long uptime = millis() / 1000.0;
   if (uptime > 86400)
   {
-    help_info(String(F("Uptime: ")) + (uptime / 86400.0) + F(" days"));
+    help_info(String(F(" Uptime: ")) + (uptime / 86400.0) + F(" days"));
   }
   else if (uptime > 3600)
   {
-    help_info(String(F("Uptime: ")) + (uptime / 3600.0) + F(" hours"));
+    help_info(String(F(" Uptime: ")) + (uptime / 3600.0) + F(" hours"));
   }
   else if (uptime > 60)
   {
-    help_info(String(F("Uptime: ")) + (uptime / 60.0) + F(" mins"));
+    help_info(String(F(" Uptime: ")) + (uptime / 60.0) + F(" mins"));
   }
   else
   {
-    help_info(String(F("Uptime: ")) + uptime + F(" secs"));
+    help_info(String(F(" Uptime: ")) + uptime + F(" secs"));
   }

   #ifdef CELLULAR_CODE_ON
-  help_info(String(F("Cell: ")) + cellular_link_up);
-  help_info(String(F("Name: ")) + cellular_provider);
-  help_info(String(F("Sim: ")) + sim_card_number);
+  help_info(String(F("   Cell: ")) + cellular_link_up);
+  help_info(String(F("   Name: ")) + cellular_provider);
+  help_info(String(F("    Sim: ")) + sim_card_number);
   #endif

 }


Edited signature of method to allow his use on more than one specific sensor

--- Arduino-code/two-sensors-test/two-sensors-test.ino
+++ Arduino-code/two-sensors-test/two-sensors-test.ino
@@ -24,8 +24,8 @@
 }

 void loop() {
-  // put your main code here, to run repeatedly:
-
+  estimateDistance(S1-trig, S1-echo);
+  delayMicroseconds(1000);
 }

 void printReadings(String label, long value){
@@ -36,18 +36,23 @@
 /*
 Estimate the distance received from the ultrasonic sensor.
 */
-int estimateDistance(){
-  digitalWrite(trigPin,LOW);
+int estimateDistance(int trig, int echo){
+  digitalWrite(trig,LOW);
   delayMicroseconds(2);

-  digitalWrite(trigPin,HIGH);
+  digitalWrite(trig,HIGH);
   delayMicroseconds(10);

-  digitalWrite(trigPin,LOW);
-  duration = pulseIn(echoPin,HIGH);
+  digitalWrite(trig,LOW);
+
+  //Claculate Duration of pulse.
+  duration = pulseIn(echo,HIGH);
+  printReadings("Duration", duration);

   //Distance in centimeters
   distance = duration/58.2;
+  printReadings("Distance", distance);
+
   return distance;
 }


Delete main.ino

Delete main.ino

--- main.ino
+++ main.ino
@@ -1,152 +0,0 @@
-#include <iostream>
-#include "laserdriver.h"
-
-using namespace std;
-
-void gameLoop();
-void drawCourt(int width, int height);
-bool checkCollision(Ball &ball, const Paddle &lPad, const Paddle &dPad);
-
-
-/******************************************************************************
-*                                Classes                                      *
-******************************************************************************/
-
- /**
- * @brief Ball
- *
- */
-class Ball
-{
-	private:
-
-		/* Radius and Position of Ball */
-		int radius;
-		int yPos;
-		int xPos;
-
-		/* Velocity of Ball*/
-		int dx;
-		int dy;
-
-	public:
-
-	 Ball(int x, int y, int r){xPos=x; yPos =y; radius = r;}
-	 ~Ball();
-
-	 /* Getter methods */
-	 int GetXpos(){return xPos;}
-	 int GetYpos(){return yPos;}
-	 int GetDx(){return dx;}
-	 int GetDy(){return dy;}
-
-	 void UpdateVel(int xVel, int yVel) { dx = xVel; dy = yVel; }
-
-	 void UpdatePos() {xPos+= dx; yPos+= dy;}
-
-	 	/**
-	 	* @brief
-	 	*
-	 	* @param x
-	 	* @param y
-	 	* @param r
-	 	*
-	 	*/
-	 void draw(int x, int y, int r){lCircle( x, y, r );}
-
-};
-
-
-/**
-* @brief Paddle
-*
-*/
-class Paddle
-{
-	private:
-
-		/* Dimmenssions and Position of paddle */
-		int yPos;
-		int xPos;
-		int height;
-		int width;
-
-		int dy;
-		int dx;
-
-	public:
-
-		Paddle(int x, int y, int){xPos= x; yPos=y;}
-
-		/* Getter methods */
-	  int GetXpos(){return xPos;}
-		int GetYpos(){return yPos;}
-	 	int GetDx(){return dx;}
-	 	int GetDy(){return dy;}
-
-	 	void Draw(int xPos,  int yPos, int width, int height)
-	 		{lRect(xPos, yPos, width, height);}
-
-};
-
-
-/******************************************************************************
-*                                  Main                                                                             *
-******************************************************************************/
-
-int main(int argc, char const *argv[])
-{
-
-	gameLoop();
-
-	return 0;
-}
-
-	/* main game loop */
-int gameLoop()
-{
-		/* Dimenssions of Court */
-	const int court_width = 255;
-	const int court_height = 255;
-
-		/* Radius of ball */
-	const int ball_r = 4;
-
-		/* Create Ball at the center of the court */
-	Ball ball( ( (court_width/2)- ball_r), ((court_height/2)- ball_r ) )
-
-		/* Create left and right paddles */
-	Paddle lPad(10, (court_height/2), 10, 20)
-	paddle rPad( ( court_width-20), (court_height/2), 10, 20 )
-
-		/* Game loop */
-	while(true)
-	{
-
-		drawCourt( court_width, court_height);
-		lPad.Draw();
-		rPad.Draw();
-		ball.Draw();
-
-	}
-
-	return true;
-}
-
-void drawCourt(int width, int height)
-{
-
-	lSet( 0, 0 );
-	delayMicroseconds(700);
-	lSet( 0, width );
-	delayMicroseconds(700);
-	lSet( 0, (width/2) );
-	delayMicroseconds(700);
-	lSet( height, (width/2) );
-	delayMicroseconds(700);
-	lSet( width , height );
-	delayMicroseconds(700);
-	lSet( 0, height );
-
-}
-


TODO-861: WIP

TODO-861: WIP


update: version number and test build

update: version number and test build

--- animus-2/animus/animus.ino
+++ animus-2/animus/animus.ino
@@ -1,8 +1,8 @@
 #define builder_row 5
 #define builder_col 8
 #define builder_kbname "Test Build"
-#define builder_kbvariant "Test Vuild VI"
-#define builder_kbdriver "Animus Innova x2.8"
+#define builder_kbvariant "Test Build D3"
+#define builder_kbdriver "Animus Innova v2.8"
 #define builder_kbdriver_build "Test Build OEM"
 #define builder_vpins 5, 6, 7, 8, 9
 #define builder_hpins A3, A2, A1, A0, 15, 14, 16, 10


Adds new mode for the LED strip

Adds new mode for the LED strip

--- arduino/ledstrip/ledstrip.ino
+++ arduino/ledstrip/ledstrip.ino
@@ -171,8 +171,19 @@
         strip.setPixelColor(ii + 1, strip.Color(0, 0, 0));
         strip.show();
         delay(wait);
-      }
-      strip.setPixelColor(i, c);
+        if (ii == i + 1 && i + 2 < strip.numPixels()) // Before last
+        {
+          strip.setPixelColor(i + 2, strip.Color(125, 125, 0));
+          strip.setPixelColor(i + 1, strip.Color(255, 255, 0));
+          strip.show();
+          delay(2 * wait);
+        }
+        strip.setPixelColor(ii, c);
+        strip.setPixelColor(ii + 1, strip.Color(0, 0, 0));
+        strip.show();
+        delay(wait);
+      }
+
       strip.show();
       delay(wait);
      }
@@ -292,4 +303,4 @@
   }
   WheelPos -= 170;
   return strip.Color((WheelPos * 3), (255 - WheelPos * 3), 0);
-}
+}