Arduino: Working motor control

Arduino: Working motor control

--- src/Arduino/RobotCtrl/RobotCtrl.ino
+++ src/Arduino/RobotCtrl/RobotCtrl.ino
@@ -1,25 +1,20 @@
 /*
-  Blink
-  Turns on an LED on for one second, then off for one second, repeatedly.
-
-  Most Arduinos have an on-board LED you can control. On the Uno and
-  Leonardo, it is attached to digital pin 13. If you're unsure what
-  pin the on-board LED is connected to on your Arduino model, check
-  the documentation at http://www.arduino.cc
-
-  This example code is in the public domain.
-
-  modified 8 May 2014
-  by Scott Fitzgerald
+  Motor Control - Simon Lees simon@simotek.net
  */

 // Pins In USE
 // Motor PWM
-int PIN_LEFT_REV = 3;
-int PIN_LEFT_FOR = 5;
-
-int PIN_RIGHT_REV = 6;
-int PIN_RIGHT_FOR = 9;
+int PIN_LEFT_REV = A3;
+int PIN_LEFT_FOR = A2;
+
+int PIN_LEFT_SPEED = 3;
+
+
+int PIN_RIGHT_REV = A1;
+int PIN_RIGHT_FOR = A0;
+
+int PIN_RIGHT_SPEED = 5;
+

 // Serial Pins are only used by the Serial Driver
 int PIN_SERIAL_RX = 0;
@@ -31,6 +26,10 @@
 int PIN_SPI_MISO = 12;
 int PIN_SPI_SCK  = 13;

+// Note I2C Pins are Used by the ODROID
+int PIN_I2C_SDA  = 27;
+int PIN_I2C_SCL  = 28;
+
 // Command Strings
 // // Incoming
 String CMD_IN_DRIVE_MOTOR_CTRL = "DMC";
@@ -46,6 +45,17 @@

 // the setup function runs once when you press reset or power the board
 void setup() {
+
+  // Motor pins as outputs
+  pinMode(PIN_LEFT_REV,   OUTPUT);
+  pinMode(PIN_LEFT_FOR,   OUTPUT);
+  pinMode(PIN_LEFT_SPEED, OUTPUT);
+  pinMode(PIN_RIGHT_REV,  OUTPUT);
+  pinMode(PIN_RIGHT_FOR,  OUTPUT);
+  pinMode(PIN_RIGHT_SPEED,OUTPUT);
+
+  leftMotorSpeed(0);
+  rightMotorSpeed(0);

   // Wait 10 seconds before starting to give the ISP programmer a chance to kick in
   //  Will remove once the prog command is tested
@@ -63,12 +73,7 @@
   pinMode(PIN_SPI_MISO, INPUT);
   pinMode(PIN_SPI_SCK, INPUT);

-  // PWM pins as outputs
-  pinMode(PIN_LEFT_REV,  OUTPUT);
-  pinMode(PIN_LEFT_FOR,  OUTPUT);
-  pinMode(PIN_RIGHT_REV, OUTPUT);
-  pinMode(PIN_RIGHT_FOR, OUTPUT);
-
+
   inputString.reserve(200);  // Reserve space for incoming command
   Serial.begin(115200);      // open the serial port at 9600 bps:

@@ -82,7 +87,7 @@
   if (stringComplete)
   {
     // Temp debug code
-    String echo = String("echo: ");
+    String echo = String("echo:");
     Serial.println(echo+inputString);
     String DecodeString = inputString;
     // clear the string early incase more comes in
@@ -106,30 +111,27 @@
        DataString = DecodeString.substring(DecodeSplit+1);
     }

-    String dcd = String("dcd::");
-    Serial.print(dcd+CMDString+"::"+DataString+"\n");
-
-     // Main Drive Motor Control, value from -100 to 100
-     if (CMDString == CMD_IN_DRIVE_MOTOR_CTRL)
-     {
+    // Main Drive Motor Control, value from -100 to 100
+    if (CMDString == CMD_IN_DRIVE_MOTOR_CTRL)
+    {
        int DataSplit = DataString.indexOf(',');
        String LeftStr = String("0");
        String RightStr = String("0");
        if (DataSplit == -1)
        {
-          LeftStr = DecodeString;
+          LeftStr = DataString;
        }
        else
        {
-         LeftStr = DecodeString.substring(0,DataSplit);
-         RightStr = DecodeString.substring(DataSplit+1);
+         LeftStr = DataString.substring(0,DataSplit);
+         RightStr = DataString.substring(DataSplit+1);
        }

        leftMotorSpeed(LeftStr.toInt());
        rightMotorSpeed(RightStr.toInt());
-     }
-     else if (CMDString == CMD_IN_PROGRAM)
-     {
+    }
+    else if (CMDString == CMD_IN_PROGRAM)
+    {
        // SPI Pins back to High for ISP
        digitalWrite(PIN_SPI_SS,   HIGH);
        digitalWrite(PIN_SPI_MOSI, HIGH);
@@ -137,7 +139,7 @@
        digitalWrite(PIN_SPI_SCK,  HIGH);

        Serial.print(CMD_OUT_READY+" Program\n");
-     }
+    }
   }

 }
@@ -154,6 +156,7 @@
     char inChar = (char)Serial.read();
     // add it to the inputString:
     inputString += inChar;
+
     // if the incoming character is a newline, set a flag
     // so the main loop can do something about it:
     if (inChar == '\n') {
@@ -165,45 +168,63 @@
 // Sets left Motor Speed -100 to 100
 void leftMotorSpeed(int Speed)
 {
-    if (Speed == 0)
+   char Direction = 'N';
+   if (Speed == 0 ||
+       Speed > 100 ||
+       Speed < -100)
    {
-     analogWrite(PIN_LEFT_REV, 0);
-     analogWrite(PIN_LEFT_FOR, 0);
+     Speed = 0;
+     digitalWrite(PIN_LEFT_FOR, LOW);
+     digitalWrite(PIN_LEFT_REV, LOW);
+     analogWrite(PIN_LEFT_SPEED,0);
    }
    else if (Speed < 0)
    {
+     Direction = 'R';
      Speed = Speed*-1;
      // Convert from 0-100 to 0-255
-     analogWrite(PIN_LEFT_FOR, 0);
-     analogWrite(PIN_LEFT_REV, (Speed/100)*255);
+     digitalWrite(PIN_LEFT_FOR, LOW);
+     digitalWrite(PIN_LEFT_REV, HIGH);
+     analogWrite(PIN_LEFT_SPEED,(Speed*255)/100);
    }
    else
    {
-     analogWrite(PIN_LEFT_REV, 0);
-     analogWrite(PIN_LEFT_FOR, (Speed/100)*255);
+     Direction = 'F';
+     digitalWrite(PIN_LEFT_FOR, HIGH);
+     digitalWrite(PIN_LEFT_REV, LOW);
+     analogWrite(PIN_LEFT_SPEED,(Speed*255)/100);
    }
-   Serial.print(CMD_OUT_DRIVE_MOTOR_LEFT_SPEED+":"+Speed+"\n");
+   Serial.print(CMD_OUT_DRIVE_MOTOR_LEFT_SPEED+":"+Speed+","+Direction+"\n");
 }

 void rightMotorSpeed(int Speed)
   {
-    if (Speed == 0)
+    char Direction = 'N';
+    if (Speed == 0 ||
+       Speed > 100 ||
+       Speed < -100)
      {
-       analogWrite(PIN_RIGHT_REV, 0);
-       analogWrite(PIN_RIGHT_FOR, 0);
+       Speed = 0;
+       digitalWrite(PIN_RIGHT_FOR, LOW);
+       digitalWrite(PIN_RIGHT_REV, LOW);
+       analogWrite(PIN_RIGHT_SPEED,0);
      }
      else if (Speed < 0)
      {
        Speed = Speed*-1;
+       Direction = 'R';
        // Convert from 0-100 to 0-255
-       analogWrite(PIN_RIGHT_FOR, 0);
-       analogWrite(PIN_RIGHT_REV, (Speed/100)*255);
+       digitalWrite(PIN_RIGHT_FOR, LOW);
+       digitalWrite(PIN_RIGHT_REV, HIGH);
+       analogWrite(PIN_RIGHT_SPEED,(Speed*255)/100);
      }
      else
      {
-       analogWrite(PIN_RIGHT_REV, 0);
-       analogWrite(PIN_RIGHT_FOR, (Speed/100)*255);
+       Direction = 'F';
+       digitalWrite(PIN_RIGHT_FOR, HIGH);
+       digitalWrite(PIN_RIGHT_REV, LOW);
+       analogWrite(PIN_RIGHT_SPEED,(Speed*255)/100);
      }
-     Serial.print(CMD_OUT_DRIVE_MOTOR_RIGHT_SPEED+":"+Speed+"\n");
-}
-
+     Serial.print(CMD_OUT_DRIVE_MOTOR_RIGHT_SPEED+":"+Speed+","+Direction+"\n");
+}
+


Improve robustness of status code checking.

On the second request, checking the status code would fail. This seems to work
much better.

I've also restructured the end of the download loop to be clearer and simpler
in terms of the error cases and behaviour.

--- printer.ino
+++ printer.ino
@@ -152,6 +152,9 @@
 char* cacheFilename = "TMP";
 unsigned long content_length = 0;
 boolean statusOk = false;
+#ifdef DEBUG
+    unsigned long start;
+#endif

 void checkForDownload() {
   unsigned long length = 0;
@@ -176,14 +179,14 @@
     client.println();
     boolean parsingHeader = true;
 #ifdef DEBUG
-    unsigned long start = millis();
+    start = millis();
 #endif
     while(client.connected()) {
       debug("Still connected");
       while(client.available()) {
         if (parsingHeader) {
           client.find("HTTP/1.1 ");
-          char statusCode[4];
+          char *statusCode = "xxx";
           client.readBytes(statusCode, 3);
           statusOk = (strcmp(statusCode, "200") == 0);
           client.find("Content-Length: ");
@@ -207,49 +210,53 @@
     // Close the connection, and flush any unwritten bytes to the cache.
     client.stop();
     cache.seek(0);
-    boolean success = statusOk && (content_length == length) && (content_length == cache.size());
-#ifdef DEBUG
-    if (!success) {
-      debug2("Failure, content length was ", content_length);
-      if (content_length != length) {
-        debug2("but length was ", length);
+
+    if (statusOk) {
+      if ((content_length == length) && (content_length == cache.size())) {
+        if (content_length > 0) {
+          downloadWaiting = true;
+          digitalWrite(readyLED, HIGH);
+        }
+      } else {
+        debug2("Failure, content length was ", content_length);
+        if (content_length != length)
+          debug2("but length was ", length);
+        if (content_length != cache.size())
+          debug2("but cache size was ", cache.size());
+        systemError(); // you should probably reboot
       }
-      if (content_length != cache.size()) {
-        debug2("but cache size was ", cache.size());
-      }
-    }
-#endif
-    cache.close();
+    } else {
+      debug("Response code wasn't 200");
+      recoverableError();
+    }
+  } else {
+    debug("Couldn't connect");
+    recoverableError();
+  }
+
+  cache.close();

 #ifdef DEBUG
     unsigned long duration = millis() - start;
     debug2("Total bytes: ", length);
     debug2("Duration: ", duration);
 #endif
-
-    if (success) {
-      if (content_length > 0) {
-        downloadWaiting = true;
-        digitalWrite(readyLED, HIGH);
-      }
-    } else {
-      debug("Oh no, a failure.");
-      digitalWrite(errorLED, HIGH);
-      digitalWrite(downloadLED, HIGH);
-    }
-  } else {
-    debug("Couldn't connect");
-    cache.close();
-    byte i = 5;
-    while(i--) {
-      digitalWrite(errorLED, HIGH);
-      delay(100);
-      digitalWrite(errorLED, LOW);
-      delay(100);
-    }
-  }
-}
-
+}
+
+inline void recoverableError() {
+  byte i = 5;
+  while(i--) {
+    digitalWrite(errorLED, HIGH);
+    delay(100);
+    digitalWrite(errorLED, LOW);
+    delay(100);
+  }
+}
+
+inline void systemError() {
+  digitalWrite(errorLED, HIGH);
+  // ... and stay on.
+}

 // -- Print send any data from the cache to the printer

@@ -277,7 +284,9 @@
       printFromDownload();
     }
   } else {
-    delay(pollingDelay);
     checkForDownload();
-  }
-}
+    if (!downloadWaiting) {
+      delay(pollingDelay);
+    }
+  }
+}


Improvements: better variable naming, read photoresistor right after reading the moisture sensor. Fix: read sensor function variables are now right type

--- moist-plants.ino
+++ moist-plants.ino
@@ -1,5 +1,5 @@
 // Arduino Hygrometer
-// version: 1.0
+// version: 1.0.1
 // Author: Mika Hassinen

 #include <FastLED.h>
@@ -10,26 +10,27 @@
 #define MAX_LED_VALUE 255

 // timer and sensor
-#define TIME_INTERVAL 1000	// 1 second interval
-#define FLASH_TIME_INTERVAL 400	// 400 ms flash interval
-#define SENSOR_PIN A1		// input pin for the sensor
+#define TIME_INTERVAL 1000  // 1 second interval
+#define FLASH_TIME_INTERVAL 400 // 400 ms flash interval
+#define MOISTURE_SENSOR_PIN A1    // input pin for the sensor

 // To test the capacitive sensor put it in a body of water and read the value of 100 % humidity
 // 0 % is measured when the sensor is held in air and not touching anything.
 // moisture sensor test values:
-// 0% humidity (air):	575
+// 0% humidity (air): 575
 // 100% humidity (water): 285
-#define MIN_LEVEL 300	// 99% humidity
-#define MAX_LEVEL 450	// 1% humidity
-#define LOW_LEVEL_THRESHOLD 1	// minimum threshold for the water level (=desert dry soil)
+#define MOISTURE_LEVEL_MIN 300  // 99% humidity
+#define MOISTURE_LEVEL_MAX 450  // 1% humidity
+#define LOW_LEVEL_THRESHOLD 1 // minimum threshold for the water level (=desert dry soil)

 #define BRIGHTNESS_OFF 0
 #define BRIGHTNESS_MIN 10
 #define BRIGHTNESS_MAX 150
-#define BRIGHTNESS_PIN A2
 #define BRIGHTNESS_THRESHOLD 70
+#define PHOTORESISTOR_PIN A2

 int sensorValue = 0;  // variable to store the value coming from the sensor
+int brightnessValue = 0;

 int ledLevel = 0;
 CRGB smartLed[NUM_LEDS];
@@ -41,16 +42,25 @@
 void setup() {

 	// setup sensors as inputs
-	pinMode(SENSOR_PIN, INPUT);
-	pinMode(BRIGHTNESS_PIN, INPUT);
+	pinMode(MOISTURE_SENSOR_PIN, INPUT);
+	pinMode(PHOTORESISTOR_PIN, INPUT);

+	// set initial values
+	sensorValue = MOISTURE_LEVEL_MAX;
+	brightnessValue = 1024;
+
+	// Serial.print("test led");
 	FastLED.addLeds<NEOPIXEL, DATA_PIN>(smartLed, NUM_LEDS);
-	setLedLevel(0);
-	delay(400);	// add a short delay so the transition to real led level is more subtle
-	for (int i = 0; i < MAX_LED_VALUE; i++) {
+	setLedLevel(10);
+	delay(400); // add a short delay so the transition to real led level is more subtle
+	for (int i = 0; i < MAX_LED_VALUE; i+=10) {
 		setLedLevel(i);
-		delay(10);
+		delay(100);
 	}
+	delay(400);
+	smartLed[0].setRGB(230, 230, 250);  // purple
+	FastLED.show();
+	delay(400);
 }

 void loop() {
@@ -60,7 +70,7 @@
 	// This means that rollover will occur in about 49 days
 	unsigned long currentTime = millis();

-	// avoid rollover
+	// // avoid rollover
 	if ((unsigned long)(currentTime - timer) >= TIME_INTERVAL) {
 		doUpdate();
 		timer = currentTime; // save time
@@ -84,10 +94,11 @@
 void doUpdate() {
 	int newLedLevel;
 	// read the value from the sensor:
-	sensorValue = readSensor(SENSOR_PIN, MIN_LEVEL, MAX_LEVEL);
+	sensorValue = readSensor(MOISTURE_SENSOR_PIN, MOISTURE_LEVEL_MIN, MOISTURE_LEVEL_MAX);
+	brightnessValue = readSensor(PHOTORESISTOR_PIN, 0, 1024); //

 	// sensor values are reversed (bigger value is dry and smaller value is moist)
-	newLedLevel = map(sensorValue, MIN_LEVEL, MAX_LEVEL, 255, 1);
+	newLedLevel = map(sensorValue, MOISTURE_LEVEL_MIN, MOISTURE_LEVEL_MAX, 255, 1);

 	// update if the value changes
 	if (ledLevel != newLedLevel) {
@@ -102,17 +113,17 @@
  * @param Integer level number of leds to light up from 0 to 5
  */
 void setLedLevel(int level) {
+
 	int ledR = 0,
 		ledG = 0,
 		ledB = 0;
-
-	int brightnessValue = readSensor(BRIGHTNESS_PIN, 0, 200);

 	// turn off LED if level is zero
 	if (level == 0) {
 		FastLED.setBrightness(BRIGHTNESS_OFF);
 	} else {
-		if (brightnessValue > BRIGHTNESS_THRESHOLD) FastLED.setBrightness(BRIGHTNESS_MAX);
+		if (brightnessValue > BRIGHTNESS_THRESHOLD)
+			FastLED.setBrightness(BRIGHTNESS_MAX);
 		else FastLED.setBrightness(BRIGHTNESS_MIN);
 	}

@@ -133,9 +144,8 @@
  * @return Integer
  */
 int readSensor(int sensorPin, int min, int max) {
-
-	int average;
-	float sensorValue, sum;
+	int sensorValue, average;
+	float sum;
 	for (int i = 0; i < 50; i++) {
 		sensorValue = analogRead(sensorPin);
 		sum += sensorValue;
@@ -146,8 +156,9 @@
 	average = (int)(sum/50.0);

 	// limit sensor reading between min & max calibration values
-	average = min(average, max);	// min: the smaller of two numbers
-	average = max(average, min);	// max: the bigger of two numbers
+	average = min(average, max);  // min: the smaller of two numbers
+	average = max(average, min);  // max: the bigger of two numbers

 	return constrain(average, min, max);
 }
+


TODO-721: improved comments

TODO-721: improved comments


forgot to save the code!

forgot to save the code!

--- Arduino/robotdesk/robotdesk.ino
+++ Arduino/robotdesk/robotdesk.ino
@@ -1 +1,71 @@
+/*
+  This is the main robotdesk runtime.

+
+
+REFERENCE:
+http://www.firgelliauto.com/blogs/news/18090523-how-to-use-an-arduino-with-firgelli-automations-linear-actuators
+
+
+*/
+
+const int RELAY_1_A = 0;
+const int RELAY_1_B = 1;
+
+
+// the setup routine runs once when you press reset:
+void setup() {
+  // initialize serial communication at 9600 bits per second:
+  //Serial.begin(9600);
+
+  //initialize the pins
+  pinMode(RELAY_1_A, OUTPUT);
+  pinMode(RELAY_1_B, OUTPUT);
+
+}
+
+// the loop routine runs over and over again forever:
+void loop() {
+  hello_actuator();
+
+
+}
+
+
+void hello_actuator(){
+
+  //lets try to extend the actuator for 10 seconds,
+  // then wait for 10 seconds
+  // then retract for 10 seconds
+
+}
+
+void listen_on_serial(){
+   // read the input on analog pin 0:
+  //int sensorValue = analogRead(A0);
+  // print out the value you read:
+  //Serial.println(sensorValue);
+  //delay(1);        // delay in between reads for stability
+}
+
+
+void extendActuator(int actuator) {
+  //Set one relay one and the other off
+  //this will move extend the actuator
+  digitalWrite(RELAY_1_A, HIGH);
+  digitalWrite(RELAY_1_B, LOW);
+}
+
+void retractActuator(int actuator) {
+  //Set one relay off and the other on
+  //this will move retract the actuator
+  digitalWrite(RELAY_1_A, LOW);
+  digitalWrite(RELAY_1_B, HIGH);
+}
+
+void stopActuator(int actuator) {
+ //Set both relays off
+ //this will stop the actuator in a braking
+ digitalWrite(RELAY_1_A, LOW);
+ digitalWrite(RELAY_1_B, LOW); }
+


TODO-593: WIP

TODO-593: WIP

--- test_VALVEMODEL/test_VALVEMODEL.ino
+++ test_VALVEMODEL/test_VALVEMODEL.ino
@@ -31,6 +31,7 @@
 #define UNIT_TESTS

 // Include the library under test.
+#include <Wire.h>
 #include <OTV0p2Base.h>
 #include <OTRadValve.h>


unit to nA

unit to nA


Updated code

Updated code

Added necessary \" before and after the value.

--- thethingsiO_Yun/thethingsiO_Yun.ino
+++ thethingsiO_Yun/thethingsiO_Yun.ino
@@ -33,10 +33,10 @@
 void addValue(String key, int value) {
   if (firstValue == true) {
     firstValue = false;
-    message.concat("{\"key\":\"" + key + "\",\"value\":" + value+"}");
+    message.concat("{\"key\":\"" + key + "\",\"value\":\"" + value+"\"}");
   }
   else {
-    message.concat(",{\"key\":\"" + key + "\",\"value\":" + value+"}");
+    message.concat(",{\"key\":\"" + key + "\",\"value\":\"" + value+"\"}");
   }
 }


prepending the device address placeholder with 0x

--- examples/ttn-abp-feather-us915-dht22/ttn-abp-feather-us915-dht22.ino
+++ examples/ttn-abp-feather-us915-dht22/ttn-abp-feather-us915-dht22.ino
@@ -53,7 +53,7 @@
 // LoRaWAN end-device address (DevAddr)
 // See http://thethingsnetwork.org/wiki/AddressSpace
 // The library converts the address to network byte order as needed.
-static const u4_t DEVADDR = FILLMEIN ; // <-- Change this address for every node!
+static const u4_t DEVADDR = 0xFILLMEIN;

 // These callbacks are only used in over-the-air activation, so they are
 // left empty here (we cannot leave them out completely unless


TODO-632: test of tamper resistance

TODO-632: test of tamper resistance

Test that flipping any 1 bit in a secure enc/auth frame
is enough to prevent decode/decrypt/auth.

--- test_SECFRAME/test_SECFRAME.ino
+++ test_SECFRAME/test_SECFRAME.ino
@@ -705,6 +705,14 @@
   // Body content should be correctly decrypted and extracted.
   AssertIsEqual(sizeof(body), decodedBodyOutSize);
   AssertIsEqual(0, memcmp(body, decryptedBodyOut, sizeof(body)));
+  // Check that flipping any single bit should make the decode fail...
+  buf[OTV0P2BASE::randRNG8() % encodedLength] ^= (uint8_t) (0x100U >> (1+(OTV0P2BASE::randRNG8()&7)));
+  AssertIsTrue((0 == sfhRX.checkAndDecodeSmallFrameHeader(buf, encodedLength)) ||
+               (0 == OTRadioLink::decodeSecureSmallFrameRaw(&sfhRX,
+                                        buf, encodedLength,
+                                        OTAESGCM::fixed32BTextSize12BNonce16BTagSimpleDec_DEFAULT_STATELESS,
+                                        NULL, zeroKey, iv,
+                                        decryptedBodyOut, sizeof(decryptedBodyOut), decodedBodyOutSize)));
   }


Correction for characters

Correction for characters

--- Arduino/sketch_mar14b/sketch_mar14b.ino
+++ Arduino/sketch_mar14b/sketch_mar14b.ino
@@ -4,10 +4,9 @@

 /*Bitmap of ANSI chars - letters+numbers+common signs:  starts at char Ox21, ends at 0x7E */
- String  ansiCharsByCols [97] = {
-  "0000000000000000", //20
+ String  ansiCharsByCols [96] = {
+  "0000000000000000", //32
   "000000fa00000000",
-  "0000000000000000",
   "0000c000c0000000",
   "000028fe28fe2800",
   "00002454fe544800",
@@ -186,8 +185,8 @@
  }

 String getCharHexa(char value) {
-  if (value >= 20 && value <= 0x7e) {
-    return ansiCharsByCols[value - 31];
+  if (value >=32 && value <= 125) {
+    return ansiCharsByCols[value - 32];
   }
   else {
     return "ffffffffffffffff";
@@ -374,23 +373,57 @@
       strip.Show();
     }
 }
+
+String decodeUrl(String req) {
+  return req;
+}
+
 /* REST service to set entire image colors=RRGGBB,RRGGBB,RRGGBB,RRGGBB,....,RRGGBB (64 colors passed */
 void handleMessageScrollRequest(String req ){
     blink(1);

     printDebug("Confirm handleMessageScrollRequest  received");
     printDebug(req);
-
+    req.replace("%20", " ");
+    req.replace("%21", "!");
+    req.replace("%22", "\"");
+    req.replace("%23", "#");
+    req.replace("%24", "$");
+    req.replace("%25", "%");
+    req.replace("%26", "&");
+    req.replace("%27", "'");
+    req.replace("%28", "(");
+    req.replace("%29", ")");
+    req.replace("%2A", "*");
+    req.replace("%2B", "+");
+    req.replace("%2C", ",");
+    req.replace("%2D", "-");
+    req.replace("%2E", ".");
+    req.replace("%2F", "/");
+    req.replace("%3A", ":");
+    req.replace("%3B", ";");
+    req.replace("%3C", "<");
+    req.replace("%3D", "?");
+    req.replace("%3F", ">");
+    req.replace("%3F", "?");
+    req.replace("%40", "@");
+    req.replace("%5B", "[");
+    req.replace("%5C", "\\");
+    req.replace("%5D", "]");
+    req.replace("%5E", "^");
+    req.replace("%5F", "_");
+    req.replace("%60", "`");
+    req.replace("%7B", "{");
+    req.replace("%7C", "|");
+    req.replace("%7D", "}");
+    req.replace("%7E", "~");
     size_t equals = req.indexOf("?");
     if (equals != -1) {
       String message=req.substring(equals+1, req.length()-9);
       printDebug("message : " + message);
       printScroll(message, 100, 1);
-
-
-    }
-}
-
+    }
+}

 void handleDefault(WiFiClient client){
 blink(1);


Tidied printed output.

Tidied printed output.

--- examples/MLX90614_demo/MLX90614_demo.ino
+++ examples/MLX90614_demo/MLX90614_demo.ino
@@ -42,8 +42,6 @@

 float convertToDegC(uint16_t data)
 {
-  Serial.print("  data = ");
-  Serial.println(data, HEX);
   // Remove MSB (error bit, ignored for temperatures)
   return (((data & (uint16_t)0x7FFF)) / 50) - 273.15;
 }
@@ -61,7 +59,7 @@
   digitalWrite(LED_BUILTIN, HIGH); delayMicroseconds(50);
   i2c.startWait(address, SoftWire::writeMode);
   i2c.rawWrite(command);
-
+
   // read
   i2c.repeatedStart(address, SoftWire::readMode);
   i2c.readThenAck(dataLow);  // Read 1 byte and then send ack
@@ -112,12 +110,13 @@
 #endif

   Serial.print("Ambient: ");
-  Serial.println(convertToDegC(readMLX90614(cmdAmbient)));
-  Serial.print("Object 1: ");
-  Serial.println(convertToDegC(readMLX90614(cmdObject1)));
+  Serial.print(convertToDegC(readMLX90614(cmdAmbient)));
+  Serial.print("    Object 1: ");
+  Serial.print(convertToDegC(readMLX90614(cmdObject1)));
   // Uncomment lines below for dual FoV sensors
-  // Serial.print("Object 2: ");
-  // Serial.println(convertToDegC(readMLX90614(cmdObject2)));
+  // Serial.print("    Object 2: ");
+  // Serial.print(convertToDegC(readMLX90614(cmdObject2)));
+  Serial.println();
 #ifdef CALUNIUM
   digitalWrite(powerPin, LOW);
 #endif


Change Color based on potentiometer

Change Color based on potentiometer

--- helloworld.ino/helloworld/helloworld.ino
+++ helloworld.ino/helloworld/helloworld.ino
@@ -31,34 +31,38 @@
 const int colorG = 0;
 const int colorB = 130;

+const int potentiometer = A0;                    // rotary angle sensor connect to A0
+
 void setup()
 {
+    // Serial.begin(9600);                         // set the serial communication frequency at 9600 bits per sec
+    pinMode(potentiometer, INPUT);
+
     // set up the LCD's number of columns and rows:
     lcd.begin(16, 2);

     lcd.setRGB(colorR, colorG, colorB);
-
-    // Print a message to the LCD.
-    lcd.print("hello, world!");

     delay(1000);
 }

 void loop()
 {
-    // set the cursor to column 0, line 1
-    // (note: line 1 is the second row, since counting begins with 0):
-    lcd.setCursor(0, 1);
-    // print the number of seconds since reset:
-    lcd.print(millis()/1000);
-
-    int sensorValue = analogRead(pinSound);   //read the sensorValue on Analog 0
-    if(sensorValue>thresholdValue)
-      digitalWrite(pinLed,HIGH);
-    delay(200);
-    digitalWrite(pinLed,LOW);
-
-    delay(100);
+    int color = 0;
+    for (int i=0; i<10; i++){
+      lcd.clear();
+      // Print a message to the LCD.
+      lcd.print("hello, world!");
+      // set the cursor to column 0, line 1
+      // (note: line 1 is the second row, since counting begins with 0):
+      lcd.setCursor(0, 1);
+      int value = analogRead(potentiometer);
+      // Serial.println(value);                      // pirnt the value on the serial monitor screen
+      lcd.print(value);
+      color=1.0*value/1024.0*256;
+      lcd.setRGB(color, color, color);
+      delay(100);
+    }
 }

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


add setBright()

add setBright()

--- examples/rss_disp/rss_disp.ino
+++ examples/rss_disp/rss_disp.ino
@@ -162,7 +162,7 @@
     LedMat.setTextColor("yellow","black");
     LedMat.setTextSize(textSize);
 		LedMat.alignPrintf(x+w/2,y, TA_CENTER, TA_TOP,
-											 "%d/%d(%s)",
+											 "%d/%d(%s)",
 											 tm->tm_mon+1, tm->tm_mday, wd[tm->tm_wday]);
     t0 = dt;
 	}
@@ -197,8 +197,9 @@
   LedMat.begin();
 	LedMat.setImgBuf(imgBuf, sizeof imgBuf);
 	LedMat.setPlane(1);
-	LedMat.setLedMode(1);			// for HSLM-6432P4B
+	// LedMat.setLedMode(1);			// for HSLM-6432P4B
   LedMat.setRotation(0);
+  LedMat.setBright(2);          // 1..100
   LedMat.clear();
   LedMat.display();
   scroll.setTextSize(1);


Add some retrying algorithm

Add some retrying algorithm

--- Seth.ino
+++ Seth.ino
@@ -48,6 +48,7 @@

 void gsm_reset();
 uint8_t gsm_init();
+uint8_t gsm_setup();
 void gsm_check_sms();
 void gsm_process_sms(uint16_t id, const char* sender, const char* text);
 uint8_t gsm_send_sms(const char* destination, const char* text);
@@ -65,15 +66,26 @@
 void gsm_reset() {
   pinMode(GSM_RESET_PIN, OUTPUT);
   digitalWrite(GSM_RESET_PIN, HIGH);
-  delay(1000);
+  delay(100);
   digitalWrite(GSM_RESET_PIN, LOW);
-  delay(1000);
+  delay(100);
   digitalWrite(GSM_RESET_PIN, HIGH);
-  delay(1000);
+  delay(100);
 }

 uint8_t gsm_init() {
-  if (gsm_send_command_P(F("AT"))) {
+  gsm_reset();
+
+  bool success = false;
+
+  for (uint8_t i = 0; i < 10; ++i) {
+    if (gsm_send_command_P(F("AT")) == 0) {
+      success = true;
+      break;
+    }
+  }
+
+  if (!success) {
     return 1;
   }

@@ -89,6 +101,10 @@
     return 4;
   }

+  return 0;
+}
+
+uint8_t gsm_setup() {
   bool success = false;

   for (uint8_t n = 0; n < 30; n++) {
@@ -109,15 +125,15 @@
   }

   if (!success) {
-    return 5;
+    return 1;
   }

   if (gsm_send_command_P(F("AT+CMGF=1"))) {
-    return 6;
+    return 2;
   }

   if (gsm_send_command_P(F("AT+CPMS=\"SM\",\"SM\",\"SM\""))) {
-    return 7;
+    return 3;
   }

   eeprom_read_block((void*)&_apn, (const void*)&_apn_E, sizeof(_apn) - 1);
@@ -125,7 +141,7 @@
   Serial.println(_apn);

   if (gsm_send_command_P(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""))) {
-    return 8;
+    return 4;
   }

   _gsm_serial.listen();
@@ -134,14 +150,12 @@
   _gsm_serial.println(F("\""));

   if (gsm_send_command(0)) {
-    return 9;
+    return 5;
   }

   if (gsm_send_command_P(F("ATS0=1"))) {
-    return 10;
-  }
-
-  return 0;
+    return 6;
+  }
 }

 void gsm_check_sms() {
@@ -439,7 +453,17 @@
 }

 uint8_t gsm_send_post_request(const char* url, const char* params) {
-  if (gsm_send_command_P(F("AT+SAPBR=1,1"), 10000)) {
+  bool connected = false;
+
+  for (uint8_t i = 0; i < 10; ++i) {
+    uint8_t result = gsm_send_command_P(F("AT+SAPBR=1,1"), 10000);
+    if (result == 0) {
+      connected = true;
+      break;
+    }
+  }
+
+  if (!connected) {
     return 1;
   }

@@ -536,12 +560,18 @@
       _gsm_serial_buffer[n++] = c;
       _gsm_serial_buffer[n] = 0;

-      if (expected && strstr(_gsm_serial_buffer, expected)) {
-        return 0;
-      } else if (strstr_P(_gsm_serial_buffer, PSTR("OK\r"))) {
-        return 0;
-      } else if (strstr_P(_gsm_serial_buffer, PSTR("ERROR\r"))) {
-        return 1;
+      if (expected) {
+        if (strstr(_gsm_serial_buffer, expected)) {
+          return 0;
+        } else if (strstr_P(_gsm_serial_buffer, PSTR("ERROR\r"))) {
+          return 1;
+        }
+      } else {
+        if (strstr_P(_gsm_serial_buffer, PSTR("OK\r"))) {
+          return 0;
+        } else if (strstr_P(_gsm_serial_buffer, PSTR("ERROR\r"))) {
+          return 1;
+        }
       }
     }
   } while (millis() - t < timeout);
@@ -573,12 +603,18 @@
       _gsm_serial_buffer[n++] = c;
       _gsm_serial_buffer[n] = 0;

-      if (expected && strstr(_gsm_serial_buffer, expected)) {
-        return 0;
-      } else if (strstr_P(_gsm_serial_buffer, PSTR("OK\r"))) {
-        return 0;
-      } else if (strstr_P(_gsm_serial_buffer, PSTR("ERROR\r"))) {
-        return 1;
+      if (expected) {
+        if (strstr(_gsm_serial_buffer, expected)) {
+          return 0;
+        } else if (strstr_P(_gsm_serial_buffer, PSTR("ERROR\r"))) {
+          return 1;
+        }
+      } else {
+        if (strstr_P(_gsm_serial_buffer, PSTR("OK\r"))) {
+          return 0;
+        } else if (strstr_P(_gsm_serial_buffer, PSTR("ERROR\r"))) {
+          return 1;
+        }
       }
     }
   } while (millis() - t < timeout);
@@ -609,9 +645,22 @@
   Serial.println(_interval);

   for (;;) {
-    gsm_reset();
+    Serial.println(F("Initializing GSM..."));
     uint8_t result = gsm_init();
     if (result == 0) break;
+
+    Serial.print(F("Error code: "));
+    Serial.println(result);
+    delay(2000);
+  }
+
+  for (;;) {
+    uint8_t result = gsm_setup();
+    if (result == 0) break;
+
+    Serial.print(F("Error code: "));
+    Serial.println(result);
+    delay(2000);
   }

   gps_init_values();
@@ -627,29 +676,36 @@
   }

   if (millis() - _last_sms_check > 5000) {
-    Serial.println(F("Check SMS"));
+    Serial.println(F("Checking SMS..."));
     gsm_check_sms();
     _last_sms_check = millis();
   }

   if (millis() - _last_upload > _interval) {
-    uint8_t battery_percentage = 78;
-    uint16_t battery_voltage = 4700;
-    int8_t signal_strength = 20;
+    uint8_t battery_percentage;
+    uint16_t battery_voltage;
+    gsm_get_battery_level(&battery_percentage, &battery_voltage);
+    int8_t signal_strength = gsm_get_signal_quality();

     char params_buffer[200];
     sprintf_P(params_buffer, _format_post, _device_id, _fix, _lat, _lng, _altitude, _speed, _course, _date_day, _date_month, _date_year, _time_hour, _time_minute, _time_second, _satellites, _hdop, _age, battery_percentage, battery_voltage, signal_strength);
     Serial.println(params_buffer);

+    Serial.print(F("Sending HTTP request... "));
     uint8_t result = gsm_send_post_request("seth.bekti.io/api/v1/location", params_buffer);

     if (result != 0) {
       ++_failure_count;
+      Serial.print(F("ERROR "));
+      Serial.println(result);
     } else {
       _failure_count = 0;
+      Serial.println(F("OK"));
     }

     if (_failure_count >= 1) {
+      Serial.println(F("Rebooting..."));
+      delay(1000);
       reboot();
     }


made to look prettier

made to look prettier

--- slave1/slave1.ino
+++ slave1/slave1.ino
@@ -175,21 +175,21 @@
 		rightSum = slave1.lightArray.armRightSum;
 		leftSum  = slave1.lightArray.armLeftSum;
 	}
-	else if (bearing > 45 && bearing <= 135){
+	else if (bearing > 90 - 45 && bearing <= 90 + 45){
 		// facing right
 		rightSum = slave1.lightArray.armFrontSum;
 		leftSum  = slave1.lightArray.armBackSum;
 		backSum  = slave1.lightArray.armRightSum;
 		frontSum = slave1.lightArray.armLeftSum;
 	}
-	else if (bearing < -45  && bearing >= -135){
+	else if (bearing < -90 + 45  && bearing >= -90 - 45){
 		// facing left
 		leftSum = slave1.lightArray.armFrontSum;
 		rightSum  = slave1.lightArray.armBackSum;
 		frontSum = slave1.lightArray.armRightSum;
 		backSum  = slave1.lightArray.armLeftSum;
 	}
-	else{
+	else if ((bearing < -180 + 45 && bearing >= 180)||(bearing > 180 - 45)){
 		// facing back
 		backSum   = slave1.lightArray.armFrontSum;
 		frontSum = slave1.lightArray.armBackSum;


useless commit msg

useless commit msg

--- data_types/data_types.ino
+++ data_types/data_types.ino
@@ -74,6 +74,7 @@
 */

 int an_array_of_ints[5];
+//an_array_of_ints[0] = 1; //this doesn't compile on mine, but maybe this isn't universal?
 /*
 We have declared an array of 5 integers.
 **Arrays (and variables in general) are not always guaranteed to be
@@ -117,6 +118,7 @@

 String will_be_Math = mike.enrolled_classes[0];
 String will_be_Mike = mike.first_name;
+//mike.enrolled_classes[0] = "P.E.";

 //this even more powerfull when you realize
 //you can make an array of students...


Update BLE_Generic_Read_Write.ino

Update BLE_Generic_Read_Write.ino

Updated comments

--- BLE_Generic_Read_Write/BLE_Generic_Read_Write.ino
+++ BLE_Generic_Read_Write/BLE_Generic_Read_Write.ino
@@ -1,9 +1,10 @@
 // Arduino Bluetooth Low Energy demonstration sketch
 // GAP Slave (aka Peripheral) - GATT Server
-// 03-22-2015 by Jim Wootten
-// Updates should be available at https://github.com/TBD
+// 03-23-2015 by Jim Wootten
+// Updates should be available at https://github.com/BlueEmeraldSystems/BLE-Arduino-Shield
 //
 // Changelog:
+//      03-23-2015 - Updated comments
 //      03-22-2015 - Initial release

 /* ============================================


add note for CompText.ino

add note for CompText.ino

--- examples/CompText/CompText.ino
+++ examples/CompText/CompText.ino
@@ -22,12 +22,26 @@
 void b0PopCallback(void *ptr);
 void b1PopCallback(void *ptr);

+/*
+ * Declare a text object [page id:0,component id:1, component name: "t0"].
+ */
 NexText t0 = NexText(0, 1, "t0");
+
+/*
+ * Declare a button object [page id:0,component id:2, component name: "b0"].
+ */
 NexButton b0 = NexButton(0, 2, "b0");
+
+/*
+ * Declare a button object [page id:0,component id:3, component name: "b1"].
+ */
 NexButton b1 = NexButton(0, 3, "b1");

 char buffer[100] = {0};

+/*
+ * Register object t0, b0, b1, to the touch event list.
+ */
 NexTouch *nex_listen_list[] =
 {
     &t0,
@@ -36,12 +50,19 @@
     NULL
 };

+/*
+ * Text component pop callback function.
+ */
 void t0PopCallback(void *ptr)
 {
     dbSerialPrintln("t0PopCallback");
     t0.setText("50");
 }

+/*
+ * Button0 component pop callback function.
+ * In this example,the value of the text component will plus one every time when button0 is released.
+ */
 void b0PopCallback(void *ptr)
 {
     uint16_t len;
@@ -61,6 +82,10 @@
     t0.setText(buffer);
 }

+/*
+ * Button1 component pop callback function.
+ * In this example,the value of the text component will minus one every time when button1 is released.
+ */
 void b1PopCallback(void *ptr)
 {
     uint16_t len;
@@ -82,15 +107,27 @@

 void setup(void)
 {
+    /* Set the baudrate which is for debug and communicate with Nextion screen. */
     nexInit();
+
+    /* Register the pop event callback function of the current text component. */
     t0.attachPop(t0PopCallback);
+
+    /* Register the pop event callback function of the current button0 component. */
     b0.attachPop(b0PopCallback);
+
+    /* Register the pop event callback function of the current button1 component. */
     b1.attachPop(b1PopCallback);
+
     dbSerialPrintln("setup done");
 }

 void loop(void)
 {
+    /*
+     * When a pop or push event occured every time,
+     * the corresponding component[right page id and component id] in touch event list will be asked.
+     */
     nexLoop(nex_listen_list);
 }


src: add certificate support

src: add certificate support

--- Mqtt433Bridge/Mqtt433Bridge.ino
+++ Mqtt433Bridge/Mqtt433Bridge.ino
@@ -1,31 +1,49 @@
-// Copyright 2016 the project authors as listed in the AUTHORS file.
+// Copyright 2016-2018 the project authors as listed in the AUTHORS file.
 // All rights reserved. Use of this source code is governed by the
 // license that can be found in the LICENSE file.

 #include <ESP8266WiFi.h>
+#include <WiFiClientSecure.h>
 #include <PubSubClient.h>
 #include "WirelessConfig.h"
 #include "RXCore433.h"

 #include "MqttDevice2262n.h"
 #include "MeatThermometer1.h"
-#include "BluelineDevice.h"
-#include "ArduinoTHSensor.h"
 #include "Device1527.h"
 #include "LacrossTX141.h"
-#include "ArduinoLightSensor.h"
 #include "Device2262.h"
+//#include "BluelineDevice.h"
+//#include "ArduinoTHSensor.h"
+//#include "ArduinoLightSensor.h"
 //#include "ArduinoDS18B20Sensor.h"
 //#include "ArduinoTHSensor2.h"

 #define RX_433_PIN D4

-IPAddress server(mqttServer[0], mqttServer[1],
-                 mqttServer[2], mqttServer[3]);
+void callback(char* topic, uint8_t* message, unsigned int length) {};

+ESP8266WiFiGenericClass wifi;
+
+#ifdef USE_CERTS
+// if certs are used the following must be defined in WirelessConfig.h
+//    unsigned char client_cert[] PROGMEM = {bytes in DER format};
+//    unsigned int client_cert_len = 918;
+//    unsigned char client_key[] PROGMEM = {bytes in DER format};
+//    unsigned int client_key_len = 1193;
+//
+//    conversion can be done using
+//    openssl x509 -in cert -out client.cert -outform DER
+//    openssl rsa -in key -out client.key -outform DER
+//    and then using xxd to generate the required array and lengths
+//    see https://nofurtherquestions.wordpress.com/2016/03/14/making-an-esp8266-web-accessible/
+//    for more detailed info
+WiFiClientSecure wclient;
+#else
 WiFiClient wclient;
-ESP8266WiFiGenericClass wifi;
-PubSubClient client(wclient, server);
+#endif
+
+PubSubClient client(mqttServerString, mqttServerPort, callback, wclient);

 RXCore433 receiver(RX_433_PIN);

@@ -33,21 +51,25 @@
   Serial.begin(9600);
   Serial.println("Started\n");

+#ifdef USE_CERTS
+  wclient.setCertificate_P(client_cert, client_cert_len);
+  wclient.setPrivateKey_P(client_key, client_key_len);
+#endif
+
   // note you can only use a subset of the devices at the same time.  This
   // is because the interrupt handlers need to be in ram and only so many of
   // them can fit at the same time.
-  receiver.registerDevice(new MqttDevice2262n(200, 75, 2, &client, "esp/house/2262/200"));
-  receiver.registerDevice(new MqttDevice2262n(350, 50, 4, &client, "esp/house/2262/200"));
-  receiver.registerDevice(new Device2262(&client, "esp/house/2262"));
-  receiver.registerDevice(new MeatThermometer1(&client, "esp/house/meat/temp"));
-  receiver.registerDevice(new BluelineDevice(0x1efd, &client, "esp/house/blueline"));
-  receiver.registerDevice(new ArduinoTHSensor(&client, "esp/house/arduinoTHSensor"));
-  receiver.registerDevice(new Device1527(350, 50, 4, &client, "esp/house/1527/350"));
-  receiver.registerDevice(new LacrossTX141(&client, "esp/house/lacrossTX141"));
-  receiver.registerDevice(new ArduinoLightSensor(&client, "esp/house/arduinoLightSensor"));
- // receiver.registerDevice(new ArduinoDS18B20Sensor(&client, "esp/house/arduinoDS18B20Sensor"));
- // receiver.registerDevice(new ArduinoTHSensor2(&client, "esp/house/arduinoTHSensor"));
-
+  receiver.registerDevice(new MqttDevice2262n(200, 75, 2, &client, "house/2262/200"));
+  receiver.registerDevice(new MqttDevice2262n(350, 50, 4, &client, "house/2262/200"));
+  receiver.registerDevice(new Device2262(&client, "house/2262"));
+  receiver.registerDevice(new Device1527(350, 50, 4, &client, "house/1527/350"));
+  receiver.registerDevice(new LacrossTX141(&client, "house/lacrossTX141"));
+  receiver.registerDevice(new MeatThermometer1(&client, "house/meat/temp"));
+  // receiver.registerDevice(new BluelineDevice(0x1efd, &client, "esp/house/blueline"));
+  // receiver.registerDevice(new ArduinoTHSensor(&client, "esp/house/arduinoTHSensor"));
+  // receiver.registerDevice(new ArduinoLightSensor(&client, "esp/house/arduinoLightSensor"));
+  // receiver.registerDevice(new ArduinoDS18B20Sensor(&client, "esp/house/arduinoDS18B20Sensor"));
+  // receiver.registerDevice(new ArduinoTHSensor2(&client, "esp/house/arduinoTHSensor"));
   // turn of the Access Point as we are not using it
   wifi.mode(WIFI_STA);
 }
@@ -62,13 +84,14 @@
     WiFi.begin(ssid, pass);

     if (WiFi.waitForConnectResult() != WL_CONNECTED) {
+      Serial.println("WiFi connected");
       return;
-      Serial.println("WiFi connected");
     }
   }

   if (!client.connected()) {
-    if (client.connect("arduinoClient")) {
+    if (client.connect("cottage-443rx1")) {
+      Serial.println("mqtt connected\n");
     }
   }


Update Example_1.ino

Update Example_1.ino

--- firmware/examples/Example_1.ino
+++ firmware/examples/Example_1.ino
@@ -4,8 +4,5 @@
 String ncd_firmware = "gateway:v1.0";

 void setup() {
-    Wire.begin();
-    Serial.begin(115200);
-    Particle.function("deviceComm", gatewayCommand);
-    Particle.variable("ncd_firmware", ncd_firmware);
+    init_gateway();
 }


lower device sensitivity

lower device sensitivity

--- embedded-particle/sense-motion.ino
+++ embedded-particle/sense-motion.ino
@@ -19,7 +19,8 @@

 // tracks how many PIR reads have been high in a row
 const int reallyOnThreshold = 180;
-const int onThreshold = 10;
+// 10 is too sensitive
+const int onThreshold = 20;
 int highReads = 0;

 // 0 is off, 1 is motion, 2 is waving motion


Cleaning up the debounced button/switch example.

--- examples/CosaButton/CosaButton.ino
+++ examples/CosaButton/CosaButton.ino
@@ -26,18 +26,25 @@
  * This file is part of the Arduino Che Cosa project.
  */

+#include "Cosa/Button.h"
+#include "Cosa/Pins.h"
+#include "Cosa/Event.h"
 #include "Cosa/Memory.h"
-#include "Cosa/Pins.h"
-#include "Cosa/Button.h"
-#include "Cosa/Event.h"

 // Input pin and button
-InputPin onoffPin(7);
-Button onoffButton;
+InputPin onoffPin(7, InputPin::PULLUP_MODE);
+Button onoffButton(Button::ON_FALLING_MODE);
+
+// Use the built-in led
+OutputPin ledPin(13);

 void on_change(Thing* it, uint8_t type, uint16_t value)
 {
-  INFO("on_change(%p, %d, %d)", it, type, value);
+  static uint8_t count = 1;
+  ledPin.toggle();
+  TRACE(count++);
+  Watchdog::delay(16);
+  ledPin.toggle();
 }

 void setup()


Implemented simplifyMaze and printPath()

Wir haben vergessen den Commit in der Schule zu pushen

--- MazeSolver/MazeSolver.ino
+++ MazeSolver/MazeSolver.ino
@@ -8,6 +8,9 @@
 const float derivateConst = 1.0f;

 const int maxMotorSpeed = 150;
+
+Direction path[300];
+unsigned int ;

 int drivePastDelay = 300; // tune value in mseconds motors will run past intersection to align wheels for turn NOT TESTED

@@ -137,6 +140,7 @@
 	int motorSpeed;
 	int posPropotionalToMid;

+  int ;
 	//direction = forward;

 	turnOffAllLeds();
@@ -160,6 +164,8 @@

 		moveBothMotors(maxMotorSpeed, forward, maxMotorSpeed, backward);
 		checkForNewLineOnSide(right);
+    path[pathLength]= back;
+    simplifyMaze();
 		break;

 	case left:
@@ -167,6 +173,9 @@

 		moveBothMotors(maxMotorSpeed, backward, maxMotorSpeed, forward);
 		checkForNewLineOnSide(left);
+
+		path[pathLength]= left;
+    simplifyMaze();
 		break;

 	case forward:
@@ -189,6 +198,9 @@
 		{
 			direction = backward;
 		}
+
+    path[pathLength]= forward;
+    simplifyMaze();
 		break;

 	case right:
@@ -196,6 +208,9 @@

 		moveBothMotors(maxMotorSpeed, forward, maxMotorSpeed, backward);
 		checkForNewLineOnSide(right);
+
+    path[pathLength]= right;
+    simplifyMaze();
 		break;
 	}
 }
@@ -306,6 +321,62 @@
 	diversionCheckingStartTime = millis();
 }

+//LBR = B
+//LBS = R
+//RBL = B
+//SBL = R
+//SBS = B
+//LBL = S
+void simplifyMaze()
+{
+  pathLength++;
+
+  if(pathLength < 3 || path[pathLength-2] != back)
+    return;
+
+  int totalAngle = 0;
+  int i;
+  for(i=1;i<=3;i++)
+  {
+    switch(path[pathLength-i])
+    {
+      case right:
+        totalAngle += 90;
+  break;
+      case left:
+  totalAngle += 270;
+  break;
+      case backward:
+  totalAngle += 180;
+  break;
+    }
+  }
+
+  // Get the angle as a number between 0 and 360 degrees.
+  totalAngle = totalAngle % 360;
+
+  // Replace all of those turns with a single one.
+  switch(totalAngle)
+  {
+    case 0:
+  path[pathLength - 3] = 'S';
+  break;
+    case 90:
+  path[pathLength - 3] = 'R';
+  break;
+    case 180:
+  path[pathLength - 3] = 'B';
+  break;
+    case 270:
+  path[pathLength - 3] = 'L';
+  break;
+  }
+
+  // The path is now two steps shorter.
+  pathLength -= 2;
+
+}
+
 #pragma endregion

 void printSensorValues()
@@ -318,3 +389,13 @@

 	Serial.println((int)position - 2500);
 }
+
+void printPath(){
+  Serial.println("+++++++++++++++++");
+  int x;
+  while(x<=pathLength){
+  Serial.println(path[x]);
+  x++;
+  }
+  Serial.println("+++++++++++++++++");
+}


Expand documentation and refactor to supply intended application symantic names

--- door-lock-test.ino
+++ door-lock-test.ino
@@ -1,9 +1,15 @@
-/*
-This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
-It won't work with v1.x motor shields! Only for the v2's with built in PWM
-control
+/* door lock test

-For use with the Adafruit Motor Shield v2
+This sketch tests basic functionality of an electric car door lock mechanisim
+using a v2 Adafruit motor shield.
+
+This is a test with a single mechanisim, and uses simple delay() calls to control
+timing.  When multiple devices are being used, the structure will need to change
+to use the current state, and timing information, to perform later operations in
+later passes through void loop().  Similar to the blink without delay example
+code.
+
+For use with the Adafruit Motor Shield v2
 ---->	http://www.adafruit.com/products/1438
 */

@@ -11,27 +17,39 @@
 #include <Adafruit_MotorShield.h>
 #include "utility/Adafruit_PWMServoDriver.h"

+unsigned const int MOTOR_PORT = 1;
+
+// Timing constants: Tests done with the door lock power directly from the Arduino 5V line.
+
+// Time for (nearly) full travel of the lock mechanisim, at the specified speed
+unsigned long const travelTime = 60;//ms
+// Speed range is 0 to 255.  For now, full speed for both strike and return
+unsigned int const strikeSpeed = 255;
+unsigned int const liftSpeed = 255;
+// Time to wait after the mechanisim is pulled in (normal 'lock' state)
+// This is (will be) the delay after the stick is returned to start, before the
+// next beat.
+unsigned long const beatDelay = 150;// ms
+// The delay at the end of the forward strike, before lifting back up.  This is
+// intended to be the time for the stick to bound off of the drum head.
+unsigned long const bounceTime = 50;// ms
+// In the drum application, the time for one 'beat' cycle, is 2 times the travel time,
+// pluss the in and out wait times.
+
 // Create the motor shield object with the default I2C address
-Adafruit_MotorShield AFMS = Adafruit_MotorShield();
-// Or, create it with a different I2C address (say for stacking)
-// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
+Adafruit_MotorShield AFMS = Adafruit_MotorShield();

-// Select which 'port' M1, M2, M3 or M4. In this case, M1
-Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
-// You can also make another motor on port M2
-//Adafruit_DCMotor *myOtherMotor = AFMS.getMotor(2);
-unsigned long const pulseTime = 60;//ms
-unsigned int const testSpeed = 255;// 0 .. 255
-unsigned long const inTime = 150;// 2 seconds
-unsigned long const outTime = 50;// 2 seconds
+// Select which motor 'port' to use on the shield
+Adafruit_DCMotor *myMotor = AFMS.getMotor(MOTOR_PORT);
+

 void setup() {
   Serial.begin(9600);           // set up Serial library at 9600 bps
-  Serial.println("Adafruit Motorshield v2 - DC Motor test!");
+  Serial.println("Car Door Lock test for Drumming!");

   AFMS.begin();  // create with the default frequency 1.6KHz
   //AFMS.begin(1000);  // OR with a different frequency, say 1KHz
-
+
   // Set the speed to start, from 0 (off) to 255 (max speed)
   myMotor->setSpeed(150);
   myMotor->run(FORWARD);
@@ -39,18 +57,38 @@
   myMotor->run(RELEASE);
 }

-void loop() {
-  Serial.print("tick");
-  myMotor->run(FORWARD);
-  myMotor->setSpeed(testSpeed);
-  delay(pulseTime);
+// For 'good' drum strikes, the mechanisim needs to accelerate the stick toward the drum,
+// then 'release' it to travel the final distance without directly being 'pushed', so that
+// the stick will 'bounce' off of the drum head.  As the stick comes back up, finish
+// pulling it back up for the next strike.
+void loop() {
+  singleStrike();
+  // The time before the next swing, which will need to be the beat spacing minus
+  // the time needed to do a single strike and recovery
+  delay(beatDelay);
+}
+
+void singleStrike() {
+  Serial.println("strike");
+  swingStick();
+  // Wait for the bounce before pulling back
+  delay(bounceTime);
+  Serial.print("lift");
+  recoverStick();
+}
+
+void swingStick() {
+  myMotor->run(FORWARD);// swing the stick at the drum
+  myMotor->setSpeed(strikeSpeed);
+  // Time needed to get to the end of the travel for the lock mechanisim
+  delay(travelTime);
+  // Remove power to the motor while the stick bounces
   myMotor->run(RELEASE);
-  //delay(outTime);
+}

-  Serial.print("tock");
-  myMotor->run(BACKWARD);
-  myMotor->setSpeed(testSpeed);
-  delay(pulseTime);
-  myMotor->run(RELEASE);
-  delay(inTime);
+void recoverStick() {
+  myMotor->run(BACKWARD);// bring the stick back to the starting position
+  myMotor->setSpeed(strikeSpeed); // Currently same speed as the strike
+  delay(travelTime); // and the same time to do the movement
+  myMotor->run(RELEASE); // remove power
 }


udp sender adedd

udp sender adedd

--- nodmcu.ino
+++ nodmcu.ino
@@ -22,8 +22,9 @@
 String DEV_VERSION = "1.0";
 const int POWERCHECK_INTERVAL = 10000; // Check battery volage
 float VOLTAGE_THRESHOLD = 2710; // voltage threshold , mv
-const int REPOSITORY_INTERVAL = 120000; //Repository interval check, milisecond
+const int REPOSITORY_INTERVAL = 5000; //Repository interval check, milisecond
 const char* HOST = "http://345.kiev.ua/1.php"; //Repository  full adress for remote job
+unsigned int UPDPORT = 28031;

 const int TRIGGER_PIN = D3; // D3 on NodeMCU and WeMos.
 const int LED_PIN = D7; //Diod pin
@@ -40,6 +41,7 @@
 std::unique_ptr<ESP8266WebServer> server;
 SimpleTimer timer_remote;
 SimpleTimer timer_vcc;
+WiFiUDP udp;

 //-------------main functions----------------------------------------
   void goFeed(String sval) {
@@ -93,6 +95,8 @@
           String response = http.getString();
           http.end();
           CheckRemoteFeedback(response);
+          // UPD broadcast also
+          broadcast();
  }
  void CheckRemoteFeedback(String json){
      StaticJsonBuffer<200> jsonBuffer;
@@ -122,6 +126,45 @@
    Serial.print("Curent voltage: "); Serial.println(String(vdd));
   }
 }
+void setConfigParams(String repository_host, String repository_int_check){
+  Serial.println(String(repository_host));
+  Serial.println(String(repository_int_check));
+}
+void broadcast(){
+   IPAddress broadcastIp = ~WiFi.subnetMask() | WiFi.gatewayIP();
+
+   if(udp.beginPacket(broadcastIp, UPDPORT) == 1){
+    Serial.print(broadcastIp);
+   }
+   udp.write("IP: ");
+   udp.print(WiFi.localIP());
+   if(udp.endPacket() == 1){
+    Serial.println(" send endPacket");
+   }
+
+   IPAddress bIp(255, 255, 255, 255);
+   if(udp.beginPacket(bIp, UPDPORT) == 1){
+    Serial.print(bIp);
+   }
+    udp.write("IP: ");
+    udp.print(WiFi.localIP());
+    udp.print(WiFi.subnetMask());
+   if(udp.endPacket() == 1){
+    Serial.println(" send endPacket");
+   }
+
+      IPAddress bIp1(10, 0, 0, 185);
+   if(udp.beginPacket(bIp, UPDPORT) == 1){
+    Serial.print(bIp1);
+   }
+    udp.write("IP: ");
+    udp.print(WiFi.localIP());
+    udp.print(WiFi.subnetMask());
+   if(udp.endPacket() == 1){
+    Serial.println(" send endPacket");
+   }
+
+}
 //------------- end main functions----------------------------------------
 void setup() {
   pinMode(LED_PIN, OUTPUT);
@@ -175,8 +218,14 @@
           float vdd = ESP.getVcc();
           server->send(200, "text/plain", String(vdd));
         });
+         server->on("/setconfigparams", [](){
+          setConfigParams(server->arg("repository_host"), server->arg("repository_int_check"));
+          server->send(200, "text/plain", String("OK"));
+        });
         server->begin();
         Serial.println("Custom HTTP server started");
+        udp.begin(UPDPORT);
+        Serial.println("UPD server started");
         doblink(LED_PIN, 1, 5000);
   }
 }


Finished converting the benchmark ino file to use the new benchmark method. It has been renamed ionbench uno memory in preparation for the file split. timertest.exe is a temporary example case to show the usage of the benchmark.

--- src/ionbench.ino
+++ src/ionbench.ino
@@ -1,85 +0,0 @@
-#include "dictionary/dictionary.h"
-#include "benchmark/benchmark.h"
-
-#include "dictionary/skiplist/slhandler.h"
-//#include "dictionary/openaddresshash/oadictionaryhandler.h"
-//#include "dictionary/openaddressfilehash/oafdictionaryhandler.h"
-//#include "dictionary/flatfilestore/ffdictionaryhandler.h"
-
-//#include <SD.h>
-//#include "sd_if/SD_stdio_c_iface.h"
-
-#include "lfsr/lfsr.h"
-
-#define SHOW() printf("%s: ", __func__)
-/**< MAKE_ION_KEY :: int -> ion_key_t (unsigned char*) */
-#define MAKE_ION_KEY(x) (_keyswap = x, (ion_key_t) &_keyswap)
-/**< ION_KEY_TO_INT :: ion_key_t (unsigned char*) -> int */
-#define ION_KEY_TO_INT(key) *((int*) key)
-
-static int _keyswap;
-
-/** CONFIG PARAMS **/
-
-/**< Handler of dict to test. */
-err_t               (*handler_fptr)(dictionary_handler_t*)  = sldict_init;
-//void              (*handler_fptr)(dictionary_handler_t*)  = oadict_init;
-//void              (*handler_fptr)(dictionary_handler_t*)  = oafdict_init;
-//void              (*handler_fptr)(dictionary_handler_t*)  = ffdict_init;
-
-/**< Type of key to test. */
-key_type_t          key_type                                = key_type_numeric_signed;
-/**< Size of key to test. (Default = 2) */
-ion_key_size_t      key_size                                = 2;
-/**< Size of value to test. (Default = 8) */
-ion_value_size_t    value_size                              = 8;
-/**< Size of dict to test. */
-int                 dict_size                               = 10;
-
-/**< Dictionary instances. */
-dictionary_t            dict;
-dictionary_handler_t    handler;
-/**< Value payload. */
-ion_value_t     test_value  = (ion_value_t) (char*){"IonDB Test String"};
-/**< Number sequence */
-lfsr_t keygen;
-/**< LFSR Seed */
-#define KEY_SEED 0xACE1u
-
-void
-bench_dict_initialize(
-    void
-)
-{
-    handler_fptr(&handler);
-    dictionary_create(&handler, &dict, key_type, key_size, value_size, dict_size);
-    lfsr_reset(&keygen);
-}
-
-void
-bench_dict_cleanup(
-    void
-)
-{
-    dictionary_delete_dictionary(&dict);
-}
-
-void
-bench_insert(
-    int count
-)
-{
-    SHOW();
-    bench_dict_initialize();
-
-    int i;
-    benchmark_start();
-    for(i = 0; i < count; i++)
-    {
-        ion_key_t       key     = MAKE_ION_KEY(lfsr_get_next(&keygen));
-        dictionary_insert(&dict, key, test_value);
-    }
-    benchmark_stop();
-
-    bench_dict_cleanup();
-}


pin numbers for COM3505 boards

pin numbers for COM3505 boards


Introduce buffer concept, and use it for ping/pong messages

--- arduino/rflink/rflink.ino
+++ arduino/rflink/rflink.ino
@@ -28,8 +28,28 @@

 static uint8_t node_id;
-static uint8_t pkt[64];
-static uint8_t have_data = 0;
+
+typedef struct {
+    uint8_t len;
+    uint8_t data[64];
+} buffer_t;
+
+static buffer_t buffers[9];
+
+static void fill_buffer(uint8_t to, uint8_t flags, uint8_t len, uint8_t *data)
+{
+    // select our own node buffer as send buffer
+    buffer_t *buf = &buffers[node_id];
+
+    // fill it
+    buf->len = 3 + len;
+    buf->data[0] = to;
+    buf->data[1] = node_id;
+    buf->data[2] = flags;
+    if (len > 0) {
+        memcpy(&buf->data[3], data, len);
+    }
+}

 void setup()
 {
@@ -43,12 +63,6 @@

     // SPI init
     spi_init(1000000L, 0);
-    // TODO BSI move this to HAL
-    SPI.setDataMode(SPI_MODE0);
-    SPI.setBitOrder(MSBFIRST);
-    SPI.setClockDivider(SPI_CLOCK_DIV8);
-    SPI.begin();
-    pinMode(10, OUTPUT);

     radio_init(node_id);
     Serial.print("radio_init = ");
@@ -69,10 +83,10 @@
         node_id = atoi(argv[1]);
         id_write(node_id);
         radio_init(node_id);
-   }
-   Serial.print("id 00 ");
-   Serial.println(node_id);
-   return 0;
+    }
+    Serial.print("id 00 ");
+    Serial.println(node_id);
+    return 0;
 }

 static int do_ping(int argc, char *argv[])
@@ -81,14 +95,14 @@
     if (argc >= 2) {
         node = atoi(argv[1]);
     }
-    Serial.print("Sending ping to ");
+
+    // prepare ping message
+    fill_buffer(node, 0x01, 0, NULL);
+
+    Serial.print(argv[0]);
+    Serial.print(" 00 ");
     Serial.println(node, HEX);
-
-    int idx = 0;
-    pkt[idx++] = node;
-    pkt[idx++] = node_id;
-    pkt[idx++] = 0x01;
-    have_data = idx;
+    return 0;
 }

 static const cmd_t commands[] = {
@@ -162,48 +176,63 @@
     }

     // our send slot arrived and we have something to send?
-    if ((m >= next_send) && (m < (next_send + 10))) {
-        if (have_data > 0) {
-            radio_send_packet(have_data, pkt);
-            have_data = 0;
+    if ((m >= next_send) && (m < (next_send + beacon.slot_size))) {
+        buffer_t *buf = &buffers[node_id];
+        if (buf->len > 0) {
+            radio_send_packet(buf->len, buf->data);
+            buf->len = 0;
         }
     }

     // handle received packets
     if (radio_packet_avail()) {
         uint8_t len;
-        uint8_t buf[64];
-        radio_recv_packet(&len, buf, sizeof(buf));
-        if (buf[2] == 0x00) {
-            // beacon
-            memcpy(&beacon, &buf[3], sizeof(beacon));
-//            Serial.print("beacon: time=");
-//            Serial.print(beacon.time);
-//            Serial.print(",frame=");
-//            Serial.println(beacon.frame);
+        uint8_t rcv[64];
+        radio_recv_packet(&len, rcv, sizeof(rcv));
+        uint8_t node = rcv[1];
+        uint8_t flags = rcv[2];
+        switch (flags) {
+
+        case 0x00:
+            // decode beacon packet
+            memcpy(&beacon, &rcv[3], sizeof(beacon));
             // determine next send time
             next_send = m + beacon.slot_offs + (beacon.slot_size * node_id);
-        } else if (buf[2] == 0x01) {
+            break;
+
+        case 0x01:
             // ping received
-            uint8_t node = buf[1];
-            Serial.print("Got ping from ");
-            Serial.print(node);
-            Serial.println(", sending pong...");
-            // prepare pong
-            int idx = 0;
-            pkt[idx++] = node;
-            pkt[idx++] = node_id;
-            pkt[idx++] = 0x02;      // pong
-            have_data = idx;
-        } else {
+            Serial.print("!ping ");
+            Serial.println(node, HEX);
+            // prepare pong message
+            fill_buffer(node, 0x02, 0, NULL);
+            break;
+
+        case 0x02:
+            // pong received
+            Serial.print("!pong ");
+            Serial.println(node, HEX);
+            break;
+
+        default:
+            // copy data into buffer and indicate reception
+            buffer_t *buf = &buffers[node];  // TODO BSI check node in range
+            memcpy(&buf->data, buf, len);
+
+            Serial.print("!r ");
+            Serial.print(node, HEX);
+            Serial.print(" ");
+            Serial.println(len);
+
             Serial.print("Got:");
             for (int i = 0; i < len; i++) {
-                uint8_t b = buf[i];
+                uint8_t b = rcv[i];
                 Serial.print((b >> 4) & 0xF);
                 Serial.print((b >> 0) & 0xF);
             }
             Serial.println(".");
-        }
-    }
-
-}
+            break;
+        }
+    }
+
+}


Power und Act LED hinzugefuegt

Power und Act LED hinzugefuegt

--- Arduino_Humidor_Monitoring/Arduino_Humidor_Monitoring.ino
+++ Arduino_Humidor_Monitoring/Arduino_Humidor_Monitoring.ino
@@ -23,10 +23,9 @@
  * A5  = I2C OLED Display (SCL)
  * ---
  * D5  = (PWM) Servo Motor
- * D7  = 5V Lüfter (Optional)
  * ---
+ * D7  = LED (Power)
  * D8  = LED (Activity)
- * D12 = LED (Power)
  * ---
  *
  * OLED Display SSD1306:
@@ -83,9 +82,8 @@
 // Sender ID for Database
 unsigned long int ID = 234576987654321;

-//int fan_pin=7;
-//int led_act=8;
-//int led_pwr=12;
+int led_pwr=7;
+int led_act=8;

 // ESP8266 WIFI
 #include<SoftwareSerial.h>
@@ -129,7 +127,7 @@
 // OLED Display
 #include <SPI.h>
 #include <Wire.h>
-//#include <Adafruit_GFX.h>
+#include <Adafruit_GFX.h>
 #include <Adafruit_SSD1306.h>

 #define OLED_RESET 4
@@ -144,6 +142,14 @@
 #define LOGO16_GLCD_WIDTH  16
 */

+void act(int state){
+  if(state==1){
+    digitalWrite(led_act, LOW);
+    digitalWrite(led_act, HIGH);
+  } else {
+    digitalWrite(led_act, LOW);
+  }
+}

 void servo_ctrl(char cmd[5]){
   if(cmd=="open"){
@@ -266,6 +272,12 @@
 void setup() {
   Serial.begin(115200);
   wifi.begin(115200);
+  pinMode(led_pwr, OUTPUT);
+  pinMode(led_act, OUTPUT);
+
+  digitalWrite(led_pwr, HIGH);
+  digitalWrite(led_act, LOW);
+
   //wifi_init();

   root["ID"] = ID;
@@ -288,6 +300,7 @@
   //falls die Befeuchtung aktiv ist pruefe alle 30 Sekunden die Werte
   if (isopen) {
     if ((unsigned long)(currmillis - task2) >= 30000) {
+      act(1);
       byte i;
       //Serial.println(F("check if hum"));
       if ((float)(get_hum() <= 65.0 || get_hum() <= 70.0)) {
@@ -296,11 +309,13 @@
           Serial.println(F("Open Slot"));
           servo_ctrl("open");
         }
+        act(0);
       } else {
         if (isopen) {
           // switch fan1 off und schliesse den Schlitz
           Serial.println(F("Close Slot"));
           servo_ctrl("close");
+          act(0);
         }
       }
       task2 = millis();
@@ -311,20 +326,24 @@
   if ((unsigned long)(currmillis - task1) >= stime || (currmillis == 1000)) {
     //Serial.println(F("check DHT22"));
     //TransmitData(get_temp(), get_hum());
+    act(1);
     root["temperature"] = get_temp();
     root["Humidity"] = get_hum();
     TransmitData();
     task1 = millis();
+    act(0);
   }

   // Sende Messdaten wenn die Befeuchtung aktiv ist alle 60 Sekunden
   if(isopen){
     if((unsigned long)(currmillis - task3) >= 60000){
       //TransmitData(get_temp(), get_hum());
+      act(1);
       root["temperature"]=get_temp();
       root["Humidity"]=get_hum();
       TransmitData();
       task3 = millis();
+      act(0);
     }
   }

@@ -333,16 +352,19 @@
     byte i;
     //Serial.println(F("check if hum"));
     if ((float)(get_hum() <= 65.0 || get_hum() <= 70.0)) {
+      act(1);
       if (!isopen) {
         //oeffne die Belueftung und starte den Luefter
         Serial.println(F("Switch fan on"));
         servo_ctrl("open");
       }
+      act(0);
     } else {
       if (isopen) {
         // switch fan1 off und schliesse den Schlitz
         Serial.println(F("Switch fan off"));
         servo_ctrl("close");
+        act(0);
       }
     }
     task2 = millis();


Uploading first compilable ROS/Arbotix sketch from ROV.

--- jaws2_serial/firmware/firmware.ino
+++ jaws2_serial/firmware/firmware.ino
@@ -1,5 +1,5 @@
 #include <ros.h>
-#include <std_msgs/Float64.h>
+#include <std_msgs/Int32MultiArray.h>

 #include "ax12.h"
 #include <Servo.h>
@@ -8,32 +8,38 @@
 #define GetLoad(id) (ax12GetRegister(id, AX_PRESENT_LOAD_L, 2))

 ros::NodeHandle nh;
-std_msgs::Float64 state;
-std_msgs::Float64 cmd;
+std_msgs::Int32MultiArray state;
+std_msgs::Int32MultiArray cmd;

 int port_servo_cmd = 150;
 int stbd_servo_cmd = 150;
 int port_servo_pos = 150;
 int stbd_servo_pos = 150;
-int state[] = {150, 150, 0, 0, 0, 0};

-void callback(const std_msgs::Float64 cmd);
+const int PORT_SERVO = 18;
+const int STBD_SERVO = 15;
+
+const float ANGLE_CONVERSION = 4096.0/360.0;
+
+void callback(const std_msgs::Int32MultiArray& cmd)
 {
-  port_servo_cmd = cmd[0];
-  stbd_servo_cmd = cmd[1];
+  port_servo_cmd = cmd.data[0];
+  stbd_servo_cmd = cmd.data[1];
   SetPosition(PORT_SERVO, port_servo_cmd * ANGLE_CONVERSION);
   SetPosition(STBD_SERVO, stbd_servo_cmd * ANGLE_CONVERSION);
   // set -- port, stbd, aft -- thrusters
 }

 ros::Publisher state_pub("state", &state);
-ros::Subscriber<std_msgs::Float64> cmd_sub("command", &callback);
+ros::Subscriber<std_msgs::Int32MultiArray> cmd_sub("command", &callback);

-const int PORT_SERVO = 18;
-const int STBD_SERVO = 15;
 const int AFT_THRUSTER = 13;
 const int PORT_THRUSTER = 12;
 const int STBD_THRUSTER = 14;
+
+int port_thrust;
+int stbd_thrust;
+int aft_thrust;

 const int MIN_THRUST = 1000;
 const int ZERO_THRUST = 1500;
@@ -43,12 +49,14 @@
 Servo port_thruster;
 Servo stbd_thruster;

-const float ANGLE_CONVERSION = 4096.0/360.0;
-
 void setup()
 {
   nh.initNode();
   nh.advertise(state_pub);
+  state.layout.data_offset = 0;
+  state.layout.dim[0].label = "command";
+  state.layout.dim[0].size = 2;
+  state.layout.dim[0].stride = 2;

   ax12Init(1000000);
   aft_thruster.attach(AFT_THRUSTER);
@@ -79,12 +87,12 @@
     stbd_thruster.writeMicroseconds(ZERO_THRUST);
     aft_thruster.writeMicroseconds(ZERO_THRUST);
   }
-  state[0] = port_servo_pos;
-  state[1] = stbd_servo_pos;
-  state[2] = GetSpeed(PORT_SERVO);
-  state[2] = GetSpeed(STBD_SERVO);
-  state[4] = GetLoad(PORT_SERVO);
-  state[5] = GetLoad(STBD_SERVO);
+  state.data[0] = port_servo_pos;
+  state.data[1] = stbd_servo_pos;
+  state.data[2] = GetSpeed(PORT_SERVO);
+  state.data[3] = GetSpeed(STBD_SERVO);
+  state.data[4] = GetLoad(PORT_SERVO);
+  state.data[5] = GetLoad(STBD_SERVO);
   state_pub.publish(&state);
   delay(33);
 }


Comment update in Arduino.ino

Comment update in Arduino.ino

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -1,6 +1,6 @@
 /*
- * Emulate a Magic Remote Control to programatically send a color code
- * to a Magic LED Lamp
+ * Emulate a Magic Remote Control to programmatically send a color code
+ * to a Magic Lightning RGB LED light
  * Date October 27, 2014
  * Copyright 2014 Robert Moro
  *
@@ -8,7 +8,7 @@
  * - Go to http://github.com/shirriff/Arduino-IRremote
  * - Follow the download and installation instructions from the readme file.
  * - If exists, remove the folder 'RobotIRremote' from C:\Program Files\Arduino\libraries\ (on 64-bit system: C:\Program Files (x86)\Arduino\libraries\)
- * - Connect an IR LED to Arduino pin D3 and GND using a serie resistor of 100 ohm.
+ * - Connect an IR LED to Arduino pin D3 and GND using a 100 ohm resistor.
  */

 #include <IRremote.h>


use micros() function

use micros() function

--- CalibrationTool.ino
+++ CalibrationTool.ino
@@ -1,6 +1,5 @@
 // Calibration of Arduino quartz ( 16 MHz) with a reference of 1 Hz

-#include <eRCaGuy_Timer2_Counter.h>
 #include <DS3232RTC.h>
 #include <Wire.h>
 #include <LiquidCrystal_I2C.h>
@@ -39,7 +38,6 @@
   lcd.print("Start calibration... ");
   lcd.setCursor(9, 2);
   lcd.print(" MHz");
-  timer2.setup();
   attachInterrupt(1, myinthandler, RISING);
 }

@@ -61,8 +59,7 @@

 void myinthandler() {

-  //currentMicros = micros() ;
-  currentMicros = timer2.get_count() / 2.0;
+  currentMicros = micros() ;
   duration = currentMicros - previousMicros;
   previousMicros = currentMicros;


Added new features

Added new features

--- v2/Motor_control/Distance_Test/Distance_Test.ino
+++ v2/Motor_control/Distance_Test/Distance_Test.ino
@@ -35,13 +35,15 @@
 // Analog pin to which the sensor is connected
 const byte sensorPin = A0;
 const byte sensorPin2 = A1;
-const byte backleft = A2;
-const byte backright = A3;
-const byte frontright = A4;
-const byte frontleft = A5;
+const byte backleft = A6;
+const byte backright = A7;
+const byte frontright = A2;
+const byte frontleft = A3;

 // Window size of the median filter (odd number, 1 = no filtering)
 const byte mediumFilterWindowSize = 5;
+unsigned int distance;
+unsigned int distance2;

 // Create an object instance of the SharpDistSensor class
 SharpDistSensor sensor(sensorPin, mediumFilterWindowSize);
@@ -60,6 +62,7 @@
 char past;
 int count;
 int threshold;
+short iter;
 void setup() {
   Serial.begin(9600);
   pinMode(STBY, OUTPUT);
@@ -73,56 +76,87 @@
   pinMode(BIN2, OUTPUT);
   past = 'f';
   count = 0;
-  threshold = analogRead(backleft) + 200;
+  iter = 0;
+  threshold = analogRead(backleft) - 200;
+  distance = sensor.getDist();
+  distance2 = sensor2.getDist();
 }

 void loop() {
   // Get distance from sensor
-  unsigned int distance = sensor.getDist();
-  unsigned int distance2 = sensor2.getDist();
-  if (backleft > threshold) {
+  iter ++;
+  if (iter == 1) {
+    distance = sensor.getDist();
+    distance2 = sensor2.getDist();
+    Serial.print(past);
+    Serial.print(", ");
+    Serial.print(distance);
+    Serial.print(", ");
+    Serial.print(distance2);
+    Serial.print(", ");
+    Serial.print(analogRead(backleft));
+    Serial.print(", ");
+    Serial.print(analogRead(backright));
+    Serial.print(", ");
+    Serial.print(analogRead(frontleft));
+    Serial.print(", ");
+    Serial.println(analogRead(frontright));
+  } else if (iter == 5) {
+    iter = 0;
+  }
+  if (analogRead(backleft) < threshold) {
     move(1, 120, 1); //motor 1, full speed, left
     move(2, 40, 0); //motor 2, full speed, left
-  } else if (backright > threshold) {
+    past = 'f';
+    delay(50);
+  } else if (analogRead(backright) < threshold) {
     move(1, 40, 1); //motor 1, full speed, left
     move(2, 120, 0); //motor 2, full speed, left
-  } else if (frontleft > threshold) {
+    past = 'f';
+    delay(50);
+  } else if (analogRead(frontleft) < threshold) {
     move(1, 40, 0); //motor 1, full speed, left
     move(2, 120, 1); //motor 2, full speed, left
-  } else if (frontright > threshold) {
+    past = 'f';
+    delay(50);
+  } else if (analogRead(frontright) < threshold) {
     move(1, 120, 0); //motor 1, full speed, left
     move(2, 40, 1); //motor 2, full speed, left
-  } else if (((past == 'f' || count >= 30) && (distance > 600 && distance2 > 600)) || (distance <= 300 && distance2 < 300)) {
-    move(1, 128, 1); //motor 1, full speed, left
-    move(2, 128, 0); //motor 2, full speed, left
-    past == 'f';
-    count = 0;
-  } else if (past == 'l') {
-    move(1, 20, 1); //motor 1, full speed, left
-    move(2, 128, 0); //motor 2, full speed, left
-    past = 'l';
-    count++;
-  } else if (past == 'r') {
-    move(1, 128, 1); //motor 1, full speed, left
-    move(2, 20, 0); //motor 2, full speed, left
-    past = 'r';
-    count++;
-  } else if (distance > 600) {
-    move(1, 20, 1); //motor 1, full speed, left
-    move(2, 128, 0); //motor 2, full speed, left
-    past = 'l';
-  } else{
-    move(1, 128, 1); //motor 1, full speed, left
-    move(2, 20, 0); //motor 2, full speed, left
-    past == 'r';
+    past = 'f';
+    delay(50);
+  } else if (iter == 1){
+    if (((past == 'f' || count >= 100) && (distance > 600 && distance2 > 600)) || (distance <= 300 && distance2 <= 300) || (abs(distance - distance2) <= 150)) {
+      move(1, 128, 1); //motor 1, full speed, left
+      move(2, 128, 0); //motor 2, full speed, left
+      past = 'f';
+      count = 0;
+    } else if (past == 'l') {
+      move(1, 20, 1); //motor 1, full speed, left
+      move(2, 128, 0); //motor 2, full speed, left
+      past = 'l';
+      count++;
+    } else if (past == 'r') {
+      move(1, 128, 1); //motor 1, full speed, left
+      move(2, 20, 0); //motor 2, full speed, left
+      past = 'r';
+      count++;
+    } else if (distance > 600) {
+      move(1, 20, 1); //motor 1, full speed, left
+      move(2, 128, 0); //motor 2, full speed, left
+      past = 'l';
+      count = 0;
+    } else{
+      move(1, 128, 1); //motor 1, full speed, left
+      move(2, 20, 0); //motor 2, full speed, left
+      past = 'r';
+      count = 0;
+    }
   }

-
+
   // Print distance to Serial
-  Serial.println(distance/25.4);
-
   // Wait some time
-  delay(30);
+  delay(5);
 }

 void move(int motor, int speed, int direction){
@@ -156,4 +190,3 @@
 //enable standby
 digitalWrite(STBY, LOW);
 }
-


Change example commands to be more rocket oriented

--- hardware/src/base-station-sketch/example-pycmdmessenger-sketch.ino
+++ hardware/src/base-station-sketch/example-pycmdmessenger-sketch.ino
@@ -17,10 +17,10 @@

 /* Define available CmdMessenger commands */
 enum {
-    current_status,
-    status_is,
-    think_for_me,
-    thought_is,
+    current_location,
+    current_location_is,
+    send_rocket_command,
+    rocket_command_response,
     error,
 };

@@ -31,19 +31,21 @@
 /* Create callback functions to deal with incoming messages */

 /* callback */
-void on_current_status(void){
-    c.sendCmd(status_is,"Developing");
+void on_current_location(void){
+    c.sendCmd(current_location_is, "Developing");
 }

 /* callback */
-void on_think_for_me(void){
+void on_send_rocket_command(void){

     /* Grab two integers */
-    int value1 = c.readBinArg<int>();
-    int value2 = c.readBinArg<int>();
+    int command = c.readBinArg<int>();
+    int options = c.readBinArg<int>();
+
+    // Do command logic

     /* Send result back */
-    c.sendBinCmd(thought_is,value1 * value2);
+    c.sendBinCmd(rocket_command_response, "Command response message");

 }

@@ -54,8 +56,8 @@

 /* Attach callbacks for CmdMessenger commands */
 void attach_callbacks(void) {
-    c.attach(current_status,on_current_status);
-    c.attach(think_for_me,on_think_for_me);
+    c.attach(current_location, on_current_location);
+    c.attach(send_rocket_command, on_send_rocket_command);
     c.attach(on_unknown_command);
 }


Changed slowdown and stopping distances

Changed slowdown and stopping distances

--- Arduino/Rover3Multifunction/Rover3Multifunction.ino
+++ Arduino/Rover3Multifunction/Rover3Multifunction.ino
@@ -127,6 +127,11 @@

 int forward_speed = 0;

+// Slowdown and stopping distances
+int distance_stop = 50;
+int distance_slowdown = 150;
+int speed_slow = 60;
+
 // This is where you declare prototypes for the functions that will be
 // using the TinyGPS library.
 void getgps(TinyGPS &gps);
@@ -207,7 +212,7 @@

       fwd_range_cm = getForwardRangeCm();

-      if ((fwd_range_cm <= 30) && (forward_speed == 0)) {
+      if ((fwd_range_cm <= distance_stop) && (forward_speed == 0)) {
           Serial.println("Object closer than 40cm!");
           Serial.print("Speed: ");
           Serial.println(forward_speed);
@@ -216,7 +221,7 @@
           tone(SPEAKER_PIN, NOTE_B3, 10);
       } else

-      if ((fwd_range_cm <= 30) && (forward_speed > 0)) {
+      if ((fwd_range_cm <= distance_stop) && (forward_speed > 0)) {
           Serial.println("Too close - STOPPING!");
           Serial.print("Speed: ");
           Serial.println(forward_speed);
@@ -226,7 +231,7 @@
           stopMotors();
       } else

-      if ((fwd_range_cm >= 100) && (forward_speed < 255) && (forward_speed > 0)) {
+      if ((fwd_range_cm >= distance_slowdown) && (forward_speed < 255) && (forward_speed > 0)) {
           forward_speed = 255;
           goForward(forward_speed);
           Serial.println("No obstacles - SPEEDING UP!");
@@ -239,8 +244,8 @@

       else

-      if ((fwd_range_cm > 30) && (fwd_range_cm < 100) && (forward_speed > 80)) {
-          forward_speed = 80;
+      if ((fwd_range_cm > distance_stop) && (fwd_range_cm < distance_slowdown) && (forward_speed > speed_slow )) {
+          forward_speed = speed_slow;
           goForward(forward_speed);
           tone(SPEAKER_PIN, NOTE_C8, 10);
           Serial.println("Close to obstacle - SLOWING down!");


update finger. comment returns.

update finger. comment returns.

--- finger-web/finger-web.ino
+++ finger-web/finger-web.ino
@@ -31,7 +31,7 @@
 }

 int getFingerprintID() {
-  uint8_t p = finger.getImage();
+  uint8_t p = finger.getImage(); // search erros
   if (p != FINGERPRINT_OK)  return -1;

   p = finger.image2Tz();


added the timer related code

added the timer related code

(1)Enable Timer1 for the button events
(2)Separate the check_button() into sigle events

--- firmware/nixie_clock/nixie_clock.ino
+++ firmware/nixie_clock/nixie_clock.ino
@@ -12,42 +12,84 @@
     MODE_CNT
 };

-void check_button();
+/* Button event handler */
+void btn_clockMode_event();
+void btn_displayMode_event();

-int clock_mode = TIME_MODE;
+//Flag of the hour format, which provide FORMAT_24HR and FORMAT_12HR two options
 extern int hour_format;
+int clock_mode = TIME_MODE; //Current clock mode
+int isr_count = 0; //The counter of Timer
+int btnTime_record_flg = 0; //The flag of program should record the time of  button press down or not
+int btn_hold_time = 0; //Record the time of user press down the button

 void setup()
 {
+    /* Setting the pin mode */
+    //Fonts
     pinMode(font_pinA, OUTPUT);
     pinMode(font_pinB, OUTPUT);
     pinMode(font_pinC, OUTPUT);
     pinMode(font_pinD, OUTPUT);
-
+    pinMode(dot_pin, OUTPUT);
+    //Digits
     pinMode(digit_pinA, OUTPUT);
     pinMode(digit_pinB, OUTPUT);
     pinMode(digit_pinC, OUTPUT);
-
-    pinMode(dot_pin, OUTPUT);
-
+    //Display enable gate
     pinMode(display_enable_gate, OUTPUT);
-
+    //Buttons
     pinMode(btn_time_mode, INPUT);
     pinMode(btn_display_mode, INPUT);

+    /* Initial the real time clock */
     setSyncProvider(RTC.get);

+    /* Initial the serial for debugging */
     Serial.begin(115200);
+
+    /* Initial the Timer1 */
+    TCCR1A = 0x00; //Normal mode
+    //No prescaling : CS12, CS11, CS10 = 0, 0, 1
+    TCCR1B &= ~_BV(CS12);
+    TCCR1B &= ~_BV(CS11);
+    TCCR1B |= _BV(CS10);
+    //Enable the overflow interrupt of Timer1
+    TIMSK1 |= _BV(TOIE1);
+    //Clear the counter of Timer1
+    TCNT1 = 0;
+}
+
+ISR (TIMER1_OVF_vect)
+{
+    isr_count++;
+
+    if(isr_count == 244) {
+        if(btnTime_record_flg == 1)
+            btn_hold_time++;
+
+            isr_count = 0;
+    }
 }

 void loop()
 {
-    display_time(clock_mode);
-    check_button();
+    /* Handle the action of the each clock mode*/
+    switch(clock_mode) {
+        case DATE_MODE:
+        case TIME_MODE:
+            display_time(clock_mode);
+            break;
+    }
+
+    /* Check the status of the button */
+    btn_clockMode_event();
+    btn_displayMode_event();
 }

-void check_button()
-{
+//Clock mode switch button handler
+void btn_clockMode_event()
+{
     int read_val;

     /* Check the mode switch button */
@@ -58,24 +100,44 @@

     //Waiting for user release the button
     while(read_val == HIGH) {
-      display_time(clock_mode - 1);
-      read_val = digitalRead(btn_time_mode);
-    }
-
-    /* Check the display mode switch button */
-    read_val = digitalRead(btn_display_mode);
-    if(read_val == HIGH) {
-        hour_format++;
-        hour_format %= 2;
-    }
-
-    //Waiting for user release the button
-    while(read_val == HIGH) {
-      display_time(clock_mode);
-      read_val = digitalRead(btn_display_mode);
+        display_time(clock_mode - 1);
+        read_val = digitalRead(btn_time_mode);
     }

     if(clock_mode == MODE_CNT)
         clock_mode = DATE_MODE;
 }

+//Display mode switch button handler
+void btn_displayMode_event()
+{
+    int read_val;
+
+    /* Check the display mode switch button */
+    read_val = digitalRead(btn_display_mode);
+    if(read_val == HIGH) {
+        switch(clock_mode) {
+              case TIME_MODE:
+                hour_format++;
+                hour_format %= 2;
+                break;
+        }
+    }
+
+    //Waiting for user release the button
+    while(read_val == HIGH) {
+        btnTime_record_flg = 1;
+
+        if(btn_hold_time >= 2) {
+            display_time(clock_mode);
+            //TODO: Switch to setting mode
+        } else {
+            display_time(clock_mode);
+        }
+        read_val = digitalRead(btn_display_mode);
+    }
+
+    btnTime_record_flg = 0;
+    btn_hold_time = 0;
+}
+


wrong value

wrong value

--- Weight.ino
+++ Weight.ino
@@ -43,7 +43,6 @@
 // initialize the library with the numbers of the interface pins
 //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)};

@@ -77,7 +76,7 @@
 }

 float getValue(HX711 scale) {
-  float value = scale.get_units(10);
+  float value = scale.get_units(10) ;
   if (value > -10 && value < 10)  {
     value = 0;
   }


Install HTTP client to send SMSs

Install HTTP client to send SMSs

--- iDONT.ino
+++ iDONT.ino
@@ -1,11 +1,16 @@
+
+#include <DNSServer.h>            //Local DNS Server used for redirecting all requests to the configuration portal
+#include <ESP8266WebServer.h>     //Local WebServer used to serve the configuration portal
+#include <WiFiManager.h>          //https://github.com/kentaylor/WiFiManager WiFi
+#include <ESP8266HTTPClient.h>
+
 #include "mainsm.h"
 #include "ledsm.h"
 #include "nvram.h"
-#include <DNSServer.h>            //Local DNS Server used for redirecting all requests to the configuration portal
-#include <ESP8266WebServer.h>     //Local WebServer used to serve the configuration portal
-#include <WiFiManager.h>          //https://github.com/kentaylor/WiFiManager WiFi

 WiFiServer* pWifiServer;
+HTTPClient httpClient;
+
 unsigned char btnState;
 unsigned char mainState;
 unsigned char led1State;
@@ -45,5 +50,14 @@
   led_state_machine(&led2State, SECOND_LED);
   main_state_machine(&mainState, &led1State, &led2State, &doorbellEnabled, &doorbellDepressed, &pWifiServer);
   btn_state_machine(&btnState, &doorbellDepressed);
+  if (btnState == STATE_BTN_EVENT)
+  {
+    httpClient.begin("http://geonetric.joelwhitehouse.com/idont/ring.php");
+    if ( httpClient.GET() == HTTP_CODE_OK)
+    {
+      String payload = httpClient.getString();
+      Serial.println(payload);
+    }
+  }
   yield();
 }


Issue #19: implemented serial communication from Arduino to Node.js app in order to get status update from arduino

--- OpenROV/OpenROV.ino
+++ OpenROV/OpenROV.ino
@@ -67,6 +67,8 @@
   // send voltage
   if (time.elapsed(1000)) {
     vout.send(vout.read());
+    Serial.print("time:");
+    Serial.println(millis());
   }
   // else if (time.elapsed(500)) {
   //   digitalWrite(13, HIGH);


Funcionalidad revisada. En modo AC el relay actua como un pulsador y así actualiza su estado.

--- RelayTemperatureSensor/RelayTemperatureSensor.ino
+++ RelayTemperatureSensor/RelayTemperatureSensor.ino
@@ -1,12 +1,3 @@
-#include <UIPServer.h>
-#include <UIPEthernet.h>
-#include <ethernet_comp.h>
-#include <UIPClient.h>
-#include <Dhcp.h>
-#include <UIPUdp.h>
-#include <Dns.h>
-
-
 #include <MySensor.h>
 #undef DEBUG
 #include "debug.h"
@@ -16,8 +7,8 @@

 // ---- NODE
 #define NODE_ID 110
-#define CHILD_ID_MODE 3 // MODE true: AC, false: Heating
-#define CHILD_ID_RELAY_AC 2 // Relay for Air conditioner
+#define CHILD_ID_LDR 3
+#define CHILD_ID_MODE 2 // MODE true: AC, false: Heating
 #define CHILD_ID_RELAY 1    // Relay for heating
 #define CHILD_ID_TEMP 0

@@ -27,17 +18,26 @@
 #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
 #define PUSH_TIMEOUT 500 // Simulate push button on AC with a relay (milliseconds)

+// LDR SENSOR
+#define LDR_PIN A2
+
 // ----- TEMPERATURE SENSOR
 #define ONE_WIRE_BUS 3 // Pin where dallas sensor is connected
 const float TEMPERATURE_DELTA = 0.2; // Change of temperature to notify
-const unsigned int READ_INTERVAL = 13; //READ Interval in seconds
+const unsigned int READ_INTERVAL = 3; //READ Interval in seconds
 const unsigned long SLEEP_TIME = READ_INTERVAL * 1000; // Sleep time between reads (in milliseconds)

 const unsigned int MAX_ITERATION = (60 / READ_INTERVAL) * 3; // 3 minutes
 unsigned int iteration = 0;

+// Initialize message LDR
+MyMessage msgLDR(CHILD_ID_LDR, V_LEVEL);
+
 // Initialize temperature message
 MyMessage msgTemperature(CHILD_ID_TEMP, V_TEMP);
+
+// Initialize RELAY message
+MyMessage msgRelay(CHILD_ID_RELAY, V_LIGHT);

 OneWire oneWire(ONE_WIRE_BUS);
 DallasTemperature temperatureSensor(&oneWire);
@@ -48,9 +48,11 @@
 MySensor hw;
 static char outstr[15];
 static uint8_t MODE = 0;
+uint8_t lastLDR = 0;

 void setup()
 {
+  Serial.begin(115200);
   // Initialize library and add callback for incoming messages
   hw.begin(incomingMessage, NODE_ID, true);
   // Send the sketch version information to the gateway and Controller
@@ -68,8 +70,8 @@

   // --- RELAY
   hw.present(CHILD_ID_RELAY, S_LIGHT);
-  hw.present(CHILD_ID_RELAY_AC, S_LIGHT);
-  hw.present(CHILD_ID_MODE, S_LIGHT);
+  hw.present(CHILD_ID_MODE, S_BINARY);
+  hw.present(CHILD_ID_LDR, S_LIGHT_LEVEL);

   // Set last mode
   MODE = hw.loadState(CHILD_ID_MODE);
@@ -93,6 +95,9 @@
   if (numSensors > 0 ) {
     sendTemperature(readTemperature());
   }
+  sendLDRStatus(analogRead(LDR_PIN));
+
+  iteration = (iteration + 1) % MAX_ITERATION;

   hw.wait(SLEEP_TIME);
 }
@@ -116,9 +121,17 @@
   if ((iteration == 0) || temperatureChanged(lastTemperature, temperature)) {
     debug(PSTR("Send temperature %s\n"), dtostrf(temperature, 2, 1, outstr));
     lastTemperature= temperature;
-    iteration = sendValue(msgTemperature.set(temperature, 1));
+    sendValue(msgTemperature.set(temperature, 1));
   }
-  iteration = (iteration + 1) % MAX_ITERATION;
+}
+
+
+void sendLDRStatus(uint8_t value) {
+   if ((iteration == 0) || (lastLDR - value) != 0) {
+    debug(PSTR("Send LDR value %s\n"), dtostrf(value, 2, 1, outstr));
+    lastLDR= value;
+    sendValue(msgLDR.set(value, 1));
+   }
 }

 uint8_t sendValue(MyMessage &msg)
@@ -128,9 +141,9 @@
 }

 void incomingMessage(const MyMessage &message) {
+  processModeMessage(message);
   processHeatingMessage(message);
   processACMessage(message);
-  processModeMessage(message);
 }

 void processHeatingMessage(const MyMessage &message) {
@@ -146,11 +159,13 @@

 void processACMessage(const MyMessage &message) {
   // We only expect one type of message from controller. But we better check anyway.
-  if (MODE && message.sensor == CHILD_ID_RELAY_AC && message.type == V_LIGHT) {
+  if (MODE && message.sensor == CHILD_ID_RELAY && message.type == V_LIGHT && message.getBool() == RELAY_ON) {
     digitalWrite(RELAY_PIN, RELAY_ON);
     hw.wait(PUSH_TIMEOUT);
     digitalWrite(RELAY_PIN, RELAY_OFF);
     debug(PSTR("Push button: %d \n"), message.sensor);
+    uint8_t value = RELAY_OFF;
+    sendValue(msgRelay.set(value,1));
   }
 }


update

update

--- src/Firmware.ino
+++ src/Firmware.ino
@@ -4,7 +4,7 @@
 #define CBI(n, b) (n &= ~_BV(b))

 #define POINTS_COUNT 6
-#define PULSES_PER_MM 100
+#define PULSES_PER_MM 10
 #define CURVE_SECTION 0.5
 #define NUM_STEPS 20
 #define NUM_AXIS 2
@@ -15,6 +15,16 @@
     MOTION_NORMAL = 1,
     MOTION_DECELETING = 2
 };
+typedef struct
+{
+    volatile double x;
+    volatile double y;
+} Point;
+typedef struct
+{
+    Point start;
+    Point end;
+} Points;
 typedef struct
 {
     volatile long err;
@@ -52,6 +62,7 @@
     volatile uint8_t plannedLength = 0;
     volatile uint8_t plannedIndex = 0;
     volatile uint8_t isRunningState = MOTION_ACCELETING;
+    volatile bool isRelative = false;
     uint8_t powerPin = 10;
     String buffer = "";
 } SystemStatus;
@@ -91,7 +102,7 @@
 {
     if (c == '\n')
     {
-        parseCommand(_sys.buffer);
+        parseCommand();
         _sys.buffer = "";
     }
     else
@@ -100,133 +111,100 @@
     }
 }

-static String vStr = "";
-static double v[8];
-void parseCommand(String cmd)
-{
-    cmd.toLowerCase();
-    char code = cmd.charAt(0);
-    long x1, y1, x2, y2, x3, y3, x4, y4;
-    uint8_t vIndex = 0;
-    uint8_t len = cmd.length();
-    vStr = "";
-    for (int i = 1; i < len; i++)
-    {
-        char c = cmd.charAt(i);
-        if (c == ' ' || c == ',')
-        {
-            if (vIndex > 0)
-            {
-                v[vIndex - 1] = vStr.toDouble();
-            }
-            vStr = "";
-            vIndex++;
-        }
-        else
-        {
-            vStr += c;
-            if (vIndex > 0 && i == len - 1)
-            {
-                v[vIndex - 1] = vStr.toDouble();
-            }
-        }
-    }
-    switch (code)
-    {
-    case 'm':
-    {
-        x1 = v[0] * PULSES_PER_MM;
-        y1 = v[1] * PULSES_PER_MM;
-        moveTo(x1, y1);
-        _sys.lastPosition[0] = x1;
-        _sys.lastPosition[1] = y1;
-        break;
-    }
-    case 'l':
-    {
-        x1 = v[0] * PULSES_PER_MM;
-        y1 = v[1] * PULSES_PER_MM;
-        lineTo(x1, y1);
-        _sys.lastPosition[0] = x1;
-        _sys.lastPosition[1] = y1;
-        break;
-    }
-    case 'h':
-    {
-        x1 = v[0] * PULSES_PER_MM;
-        lineTo(x1, _sys.lastPosition[1]);
-        _sys.lastPosition[0] = x1;
-        break;
-    }
-    case 'v':
-    {
-        y1 = v[0] * PULSES_PER_MM;
-        lineTo(_sys.lastPosition[0], y1);
-        _sys.lastPosition[1] = y1;
-        break;
-    }
-    case 'c':
-    {
-        x1 = v[0] * PULSES_PER_MM;
-        y1 = v[1] * PULSES_PER_MM;
-        x2 = v[2] * PULSES_PER_MM;
-        y2 = v[3] * PULSES_PER_MM;
-        x3 = v[4] * PULSES_PER_MM;
-        y3 = v[5] * PULSES_PER_MM;
-        curveTo(_sys.lastPosition[0], _sys.lastPosition[1], x1, y1, x2, y2, x3, y3);
-        _sys.lastPosition[0] = x3;
-        _sys.lastPosition[1] = y3;
-        break;
-    }
-    case 'q':
-    {
-        x1 = v[0] * PULSES_PER_MM;
-        y1 = v[1] * PULSES_PER_MM;
-        x2 = v[2] * PULSES_PER_MM;
-        y2 = v[3] * PULSES_PER_MM;
-        quadTo(_sys.lastPosition[0], _sys.lastPosition[1], x1, y1, x2, y2);
-        _sys.lastPosition[0] = x2;
-        _sys.lastPosition[1] = y2;
-        break;
-    }
-    case 'z':
-    {
-        lineTo(_sys.startPosition[0], _sys.startPosition[1]);
-        _sys.lastPosition[0] = _sys.startPosition[0];
-        _sys.lastPosition[1] = _sys.startPosition[1];
-        break;
-    }
-    case 'p':
-    {
-        setPower(v[0]);
-        setSpeed(v[1]);
-        setAccel(v[2]);
-        break;
-    }
-    case 'e':
-    {
-        firePower(v[0]);
-        break;
-    }
-    case 'o':
-    {
-        waitingForFinish();
-        if (v[0] > 0)
-        {
-            for (int i = 0; i < NUM_AXIS; i++)
-            {
-                steppers[i].enableOutputs();
-            }
-        }
-        else
-        {
-            for (int i = 0; i < NUM_AXIS; i++)
-            {
-                steppers[i].disableOutputs();
-            }
-        }
-        break;
-    }
+void parseCommand()
+{
+    _sys.buffer.toLowerCase();
+    int cmdId;
+    if (_sys.buffer.length() > 2)
+    {
+        if (hasCommand('g'))
+        {
+            cmdId = getCommand('g');
+            switch (cmdId)
+            {
+            case 0:
+            case 1:
+            {
+                if (hasCommand('p'))
+                {
+                    firePower(getCommand('p'));
+                }
+                if (hasCommand('f'))
+                {
+                    setSpeed(getCommand('f'));
+                }
+                long x = (hasCommand('x') ? getCommand('x') : 0) * PULSES_PER_MM;
+                long y = (hasCommand('y') ? getCommand('y') : 0) * PULSES_PER_MM;
+                if (_sys.isRelative)
+                {
+                    x += _sys.targetPosition[0];
+                    y += _sys.targetPosition[1];
+                }
+                lineTo(x, y);
+                _sys.targetPosition[0] = x;
+                _sys.targetPosition[1] = y;
+            }
+            break;
+            case 28:
+            {
+                waitingForFinish();
+                _sys.currentPosition[0] = 0;
+                _sys.currentPosition[1] = 0;
+            }
+            break;
+            case 90:
+            {
+                waitingForFinish();
+                _sys.isRelative = false;
+            }
+            break;
+            case 91:
+            {
+                waitingForFinish();
+                _sys.isRelative = true;
+            }
+            break;
+            }
+        }
+        else if (hasCommand('m'))
+        {
+            cmdId = getCommand('m');
+            switch (cmdId)
+            {
+            case 1:
+            {
+                waitingForFinish();
+                if (hasCommand('p') && getCommand('p') == 1)
+                {
+                    for (int i = 0; i < NUM_AXIS; i++)
+                    {
+                        steppers[i].enableOutputs();
+                    }
+                }
+                else
+                {
+                    for (int i = 0; i < NUM_AXIS; i++)
+                    {
+                        steppers[i].disableOutputs();
+                    }
+                }
+                break;
+            }
+            case 4:
+            {
+                waitingForFinish();
+                if (hasCommand('p'))
+                {
+                    firePower(getCommand('p'));
+                }
+                else
+                {
+                    firePower(0);
+                }
+                break;
+            }
+            }
+        }
     }
     finishCommand();
 }
@@ -296,10 +274,6 @@
 {
     firePower(0);
 }
-/**
- * motion control in Timer
- */
-
 void shiftPlanned()
 {
     if (_sys.plannedLength > 0)
@@ -315,12 +289,10 @@
 void lockTimer()
 {
     cli();
-    // noInterrupts();
 }
 void unlockTimer()
 {
     sei();
-    // interrupts();
 }
 void setRun()
 {
@@ -512,8 +484,7 @@
 #endif
     _sys.startPosition[0] = x;
     _sys.startPosition[1] = y;
-    _sys.currentSpeed = _sys.defaultSpeed;
-    addMotion(x, y, 0, _sys.speed, _sys.acceleration);
+    addMotion(x, y, 0, _sys.maxSpeed, _sys.acceleration);
 }
 void lineTo(long x, long y)
 {
@@ -529,116 +500,41 @@
 #endif
     addMotion(x, y, _sys.power, _sys.speed, _sys.acceleration);
 }
-void curveTo(long x0, long y0, long x1, long y1, long x2, long y2, long x3, long y3)
-{
-    double subdiv_step = 1.0 / (NUM_STEPS + 1);
-    double subdiv_step2 = subdiv_step * subdiv_step;
-    double subdiv_step3 = subdiv_step * subdiv_step * subdiv_step;
-    double pre1 = 3.0 * subdiv_step;
-    double pre2 = 3.0 * subdiv_step2;
-    double pre4 = 6.0 * subdiv_step2;
-    double pre5 = 6.0 * subdiv_step3;
-    double tmp1x = x0 - x1 * 2.0 + x2;
-    double tmp1y = y0 - y1 * 2.0 + y2;
-    double tmp2x = (x1 - x2) * 3.0 - x0 + x3;
-    double tmp2y = (y1 - y2) * 3.0 - y0 + y3;
-    double fx = x0;
-    double fy = y0;
-    double dfx = (x1 - x0) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
-    double dfy = (y1 - y0) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
-    double ddfx = tmp1x * pre4 + tmp2x * pre5;
-    double ddfy = tmp1y * pre4 + tmp2y * pre5;
-    double dddfx = tmp2x * pre5;
-    double dddfy = tmp2y * pre5;
-    int step = NUM_STEPS;
-#ifdef DEBUG
-    String str = "curve:";
-    str += x0;
-    str += ",";
-    str += y0;
-    str += " ";
-    str += x1;
-    str += ",";
-    str += y1;
-    str += " ";
-    str += x2;
-    str += ",";
-    str += y2;
-    str += " ";
-    str += x3;
-    str += ",";
-    str += y3;
-    Serial.println(str);
-#endif
-    while (step--)
-    {
-        fx += dfx;
-        fy += dfy;
-        dfx += ddfx;
-        dfy += ddfy;
-        ddfx += dddfx;
-        ddfy += dddfy;
-        lineTo(floorf(fx * 100) / 100, floorf(fy * 100) / 100);
-    }
-    lineTo(floorf(x3 * 100) / 100, floorf(y3 * 100) / 100);
-}
-void quadTo(long x0, long y0, long x1, long y1, long x2, long y2)
-{
-#ifdef DEBUG
-    String str = "quad:";
-    str += " ";
-    str += x1;
-    str += ",";
-    str += y1;
-    str += " ";
-    str += x2;
-    str += ",";
-    str += y2;
-    Serial.println(str);
-#endif
-    int step = NUM_STEPS;
-    double fx, fy;
-    for (int i = 0; i < step; i++)
-    {
-        float t = (float)i / (float)step;
-        float u = 1.0 - t;
-        fx = x0 * u * u + x1 * 2 * u * t + x2 * t * t;
-        fy = y0 * u * u + y1 * 2 * u * t + y2 * t * t;
-        lineTo(floorf(fx * 100) / 100, floorf(fy * 100) / 100);
-    }
-    lineTo(floorf(x2 * 100) / 100, floorf(y2 * 100) / 100);
-}
-
-void arc(long sx, long sy, long cx, long cy, long ex, long ey, bool ccw)
-{
-    double angleA, angleB, angle, radius, length, aX, aY, bX, bY;
-    aX = (sx - cx);
-    aY = (sy - cy);
-    bX = (ex - cx);
-    bY = (ey - cy);
-    if (ccw)
-    {
-        angleA = atan2(aY, aX);
-        angleB = atan2(bY, bX);
-    }
-    else
-    {
-        angleA = atan2(bY, bX);
-        angleB = atan2(aY, aX);
-    }
-    if (angleB <= angleA)
-    {
-        angleB += 2 * M_PI;
-    }
-    angle = angleB - angleA;
-    radius = sqrt(aX * aX + aY * aY);
-    length = radius * angle;
-    int steps, s, step;
-    steps = (int)ceil(length / CURVE_SECTION);
-    for (s = 1; s <= steps; s++)
-    {
-        step = (ccw) ? s : (steps - s);
-        float t = step / steps;
-        lineTo(cx + radius * cos(angleA + angle * t), cy + radius * sin(angleA + angle * t));
-    }
+
+bool hasCommand(char cmd)
+{
+    int index = 0;
+    char c = 0;
+    while (c != cmd)
+    {
+        if (index >= _sys.buffer.length())
+        {
+            return false;
+        }
+        else
+        {
+            c = _sys.buffer.charAt(index);
+        }
+        index++;
+    }
+    return true;
+}
+double getCommand(char cmd)
+{
+    int index = _sys.buffer.indexOf(cmd);
+    int startIndex = _sys.buffer.indexOf(cmd) + 1;
+    char c = 0;
+    while (c != ' ')
+    {
+        index++;
+        if (index >= _sys.buffer.length())
+        {
+            break;
+        }
+        else
+        {
+            c = _sys.buffer.charAt(index);
+        }
+    }
+    return _sys.buffer.substring(startIndex, index).toDouble();
 }


Improved error response on illegal pin number (NO_SUCH_NAME).

--- examples/Ethernet/CosaSNMP/CosaSNMP.ino
+++ examples/Ethernet/CosaSNMP/CosaSNMP.ino
@@ -61,14 +61,14 @@
   if (pdu.type == SNMP::PDU_GET) {
     switch (sys) {
     case SNMP::ardDigitalPin:
-      if (pin > 22)
-	pdu.error_status = SNMP::BAD_VALUE;
+      if (pin > 22)
+	pdu.error_status = SNMP::NO_SUCH_NAME;
       else
 	pdu.value.encode(SNMP::SYNTAX_INT, (int16_t) InputPin::read(pin));
       break;
     case SNMP::ardAnalogPin:
       if (pin > 7)
-	pdu.error_status = SNMP::BAD_VALUE;
+	pdu.error_status = SNMP::NO_SUCH_NAME;
       else
 	pdu.value.encode(SNMP::SYNTAX_INT, (int16_t) AnalogPin::sample(pin));
       break;


fix boost calculation

fix boost calculation

--- examples/RF12/radioBlip2/radioBlip2.ino
+++ examples/RF12/radioBlip2/radioBlip2.ino
@@ -113,10 +113,11 @@
   }

   if (vcc >= VCC_OK) { // enough energy for normal operation
+#if BOOST
+    payload.vcc2 = analogRead(0) >> 2;
+#endif
     sendPayload();
-#if BOOST
-    payload.vcc2 = analogRead(1);
-#else
+#if !BOOST
     vcc = payload.vcc2 = vccRead(); // measure and remember the VCC drop
 #endif
   }