implemented minimun time for each state to protect on-off on the fan and the heating element

version is now 0.9

--- minimalistthermostat.ino
+++ minimalistthermostat.ino
@@ -1,6 +1,3 @@
-//TODO:
-// have a minimun time for each state to protect on-off on the fan and the heating element
-
 //The MIT License (MIT)
 //Copyright (c) 2016 Gustavo Gonnet
 //
@@ -20,24 +17,24 @@
 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
+
 #include "application.h"
 #include "elapsedMillis.h"
 #include "PietteTech_DHT.h"
 #include "FiniteStateMachine.h"
-
 #define APP_NAME "Thermostat"
-// IO mapping
-// D0 : relay: fan
-// D1 : relay: heat
-// D2 : relay: cold
-// D3 : relay:
-// D4 : DHT22
-// D5 : unused
-// D6 : unused
-// D7 : unused
-// A0~A7 : unused
-
-//initialize states with proper enter, update and exit functions
+
+String VERSION = "Version 0.09";
+/*******************************************************************************
+ * changes in version 0.09:
+       * reorganized code to group functions
+       * added minimum time to protect on-off on the fan and the heating element
+          in function heatingUpdateFunction()
+*******************************************************************************/
+
+/*******************************************************************************
+ initialize FSM states with proper enter, update and exit functions
+*******************************************************************************/
 State initState = State( initEnterFunction, initUpdateFunction, initExitFunction );
 State idleState = State( idleEnterFunction, idleUpdateFunction, idleExitFunction );
 State heatingState = State( heatingEnterFunction, heatingUpdateFunction, heatingExitFunction );
@@ -46,15 +43,41 @@
 //initialize state machine, start in state: Idle
 FSM thermostatStateMachine = FSM(initState);

-String VERSION = "Version 0.07";
+//milliseconds for the init cycle, so temperature samples get stabilized
+//this should be in the order of the 5 minutes: 5*60*1000==300000
+#define INIT_TIMEOUT 30000
+elapsedMillis initTimer;
+
+//milliseconds to leave the fan on when the target temp has been reached
+//this evacuates the heat or the cold air from vents
+#define END_OF_CYCLE_TIMEOUT 15000
+elapsedMillis endOfCycleTimer;
+
+//minimum number of milliseconds to leave the heating element on
+// to protect on-off on the fan and the heating element
+#define MINIMUM_ON_TIMEOUT 5000
+elapsedMillis minimumOnTimer;
+
+/*******************************************************************************
+ IO mapping
+*******************************************************************************/
+// D0 : relay: fan
+// D1 : relay: heat
+// D2 : relay: cold
+// D4 : DHT22
+// D3, D5~D7 : unused
+// A0~A7 : unused
 int fan = D0;
 int heat = D1;
 int cold = D2;
+//TESTING_HACK
 int fanTesting;
 int heatTesting;
 int coldTesting;

-// system defines
+/*******************************************************************************
+ DHT sensor
+*******************************************************************************/
 #define DHTTYPE  DHT22                // Sensor type DHT11/21/22/AM2301/AM2302
 #define DHTPIN   4                    // Digital pin for communications
 #define DHT_SAMPLE_INTERVAL   30000   // Sample room temperature every 30 seconds
@@ -63,16 +86,9 @@
 bool bDHTstarted;       // flag to indicate we started acquisition
 elapsedMillis dhtSampleInterval;

-//milliseconds for the init cycle, so temperature samples get stabilized
-//this should be in the order of the 5 minutes: 5*60*1000==300000
-#define INIT_TIMEOUT 30000
-elapsedMillis initTimer;
-
-//milliseconds to leave the fan on when the target temp has been reached
-//this evacuates the heat or the cold air from vents
-#define END_OF_CYCLE_TIMEOUT 15000
-elapsedMillis endOfCycleTimer;
-
+/*******************************************************************************
+ thermostat related declarations
+*******************************************************************************/
 //temperature related variables - internal
 float targetTemp = 19.0;
 float currentTemp = 20.0;
@@ -83,54 +99,62 @@
 String currentTempString = String(currentTemp); //String to store the sensor's temp so it can be exposed
 String currentHumidityString = String(currentHumidity); //String to store the sensor's humidity so it can be exposed

-//testing variables
+//TESTING_HACK
+// this allows me to system test the project
 bool testing = false;

+
+/*******************************************************************************
+ * Function Name  : setup
+ * Description    : this function runs once at system boot
+ *******************************************************************************/
 void setup() {

- //publish startup message with firmware version
- Particle.publish(APP_NAME, VERSION, 60, PRIVATE);
-
- //declare and init pins
- pinMode(fan, OUTPUT);
- pinMode(heat, OUTPUT);
- pinMode(cold, OUTPUT);
- myDigitalWrite(fan, LOW);
- myDigitalWrite(heat, LOW);
- myDigitalWrite(cold, LOW);
-
- //declare cloud variables
- //https://docs.particle.io/reference/firmware/photon/#particle-variable-
- //Currently, up to 10 cloud variables may be defined and each variable name is limited to a maximum of 12 characters
- if (Particle.variable("targetTemp", targetTempString)==false) {
-   Particle.publish(APP_NAME, "ERROR: Failed to register variable targetTemp", 60, PRIVATE);
- }
- if (Particle.variable("currentTemp", currentTempString)==false) {
-   Particle.publish(APP_NAME, "ERROR: Failed to register variable currentTemp", 60, PRIVATE);
- }
- if (Particle.variable("humidity", currentHumidityString)==false) {
-   Particle.publish(APP_NAME, "ERROR: Failed to register variable humidity", 60, PRIVATE);
- }
-
- //declare cloud functions
- //https://docs.particle.io/reference/firmware/photon/#particle-function-
- //Currently the application supports the creation of up to 4 different cloud functions.
- //The length of the funcKey is limited to a max of 12 characters.
- // If you declare a function name longer than 12 characters the function will not be registered.
- //user functions
- if (Particle.function("setTargetTmp", setTargetTemp)==false) {
-    Particle.publish(APP_NAME, "ERROR: Failed to register function setTargetTemp", 60, PRIVATE);
- }
- //testing functions
- if (Particle.function("setTesting", setTesting)==false) {
-    Particle.publish(APP_NAME, "ERROR: Failed to register function setTesting", 60, PRIVATE);
- }
- if (Particle.function("setCurrTmp", setCurrentTemp)==false) {
-    Particle.publish(APP_NAME, "ERROR: Failed to register function setCurrentTemp", 60, PRIVATE);
- }
- if (Particle.function("getOutputs", getOutputs)==false) {
-    Particle.publish(APP_NAME, "ERROR: Failed to register function getOutputs", 60, PRIVATE);
- }
+  //pulish startup message with firmware version
+  Particle.publish(APP_NAME, VERSION, 60, PRIVATE);
+
+  //declare and init pins
+  pinMode(fan, OUTPUT);
+  pinMode(heat, OUTPUT);
+  pinMode(cold, OUTPUT);
+  myDigitalWrite(fan, LOW);
+  myDigitalWrite(heat, LOW);
+  myDigitalWrite(cold, LOW);
+
+  //declare cloud variables
+  //https://docs.particle.io/reference/firmware/photon/#particle-variable-
+  //Currently, up to 10 cloud variables may be defined and each variable name is limited to a maximum of 12 characters
+  if (Particle.variable("targetTemp", targetTempString)==false) {
+    Particle.publish(APP_NAME, "ERROR: Failed to register variable targetTemp", 60, PRIVATE);
+  }
+  if (Particle.variable("currentTemp", currentTempString)==false) {
+    Particle.publish(APP_NAME, "ERROR: Failed to register variable currentTemp", 60, PRIVATE);
+  }
+  if (Particle.variable("humidity", currentHumidityString)==false) {
+    Particle.publish(APP_NAME, "ERROR: Failed to register variable humidity", 60, PRIVATE);
+  }
+
+  //declare cloud functions
+  //https://docs.particle.io/reference/firmware/photon/#particle-function-
+  //Currently the application supports the creation of up to 4 different cloud functions.
+  //The length of the funcKey is limited to a max of 12 characters.
+  // If you declare a function name longer than 12 characters the function will not be registered.
+  //user functions
+  if (Particle.function("setTargetTmp", setTargetTemp)==false) {
+     Particle.publish(APP_NAME, "ERROR: Failed to register function setTargetTemp", 60, PRIVATE);
+  }
+  //TESTING_HACK
+  if (Particle.function("setTesting", setTesting)==false) {
+     Particle.publish(APP_NAME, "ERROR: Failed to register function setTesting", 60, PRIVATE);
+  }
+  //TESTING_HACK
+  if (Particle.function("setCurrTmp", setCurrentTemp)==false) {
+     Particle.publish(APP_NAME, "ERROR: Failed to register function setCurrentTemp", 60, PRIVATE);
+  }
+  //TESTING_HACK
+  if (Particle.function("getOutputs", getOutputs)==false) {
+     Particle.publish(APP_NAME, "ERROR: Failed to register function getOutputs", 60, PRIVATE);
+  }

 }

@@ -138,200 +162,19 @@
 void dht_wrapper() { DHT.isrCallback(); }

+/*******************************************************************************
+ * Function Name  : loop
+ * Description    : this function runs continuously while the project is running
+ *******************************************************************************/
 void loop() {
+
+  //this function reads the temperature of the DHT sensor
   readTemperature();
+
+  //this function updates the FSM
+  // the FSM is the heart of the thermostat - all actions are defined by its states
   thermostatStateMachine.update();
-}
-
-/*******************************************************************************
- * Function Name  : readTemperature
- * Description    : reads the temperature of the DHT22 sensor at every DHT_SAMPLE_INTERVAL
-                    if testing the app, it returns right away
- * Return         : 0
- *******************************************************************************/
-int readTemperature() {
-
-  //are we testing the app? then no need to acquire from the sensor
-  if (testing) {
-   return 0;
-  }
-
-  //time is up? no, then come back later
-  if (dhtSampleInterval < DHT_SAMPLE_INTERVAL) {
-   return 0;
-  }
-
-  //time is up, reset timer
-  dhtSampleInterval = 0;
-
-  // start the sample
-  if (!bDHTstarted) {
-    DHT.acquire();
-    bDHTstarted = true;
-  }
-
-  //still acquiring sample? go away
-  if (DHT.acquiring()) {
-    return 0;
-  }
-
-  //sample acquired - go ahead and store temperature and humidity in internal variables
-  publishTemperature( (float)DHT.getCelsius(), (float)DHT.getHumidity() );
-
-  //reset the sample flag so we can take another
-  bDHTstarted = false;
-
-  return 0;
-}
-
-/*******************************************************************************
- * Function Name  : publishTemperature
- * Description    : the temperature/humidity passed as parameters get stored in internal variables
-                    and then published
- * Return         : 0
- *******************************************************************************/
-int publishTemperature( float temperature, float humidity ) {
-
- char currentTempChar[32];
- currentTemp = temperature;
- int currentTempDecimals = (currentTemp - (int)currentTemp) * 100;
- sprintf(currentTempChar,"%0d.%d", (int)currentTemp, currentTempDecimals);
-
- char currentHumidityChar[32];
- currentHumidity = humidity;
- int currentHumidityDecimals = (currentHumidity - (int)currentHumidity) * 100;
- sprintf(currentHumidityChar,"%0d.%d", (int)currentHumidity, currentHumidityDecimals);
-
- //publish readings into exposed variables
- currentTempString = String(currentTempChar);
- currentHumidityString = String(currentHumidityChar);
-
- //publish readings
- Particle.publish(APP_NAME, "Current temperature: " + currentTempString, 60, PRIVATE);
- Particle.publish(APP_NAME, "Current humidity: " + currentHumidityString, 60, PRIVATE);
-
- return 0;
-
-}
-
-//utility functions
-void initEnterFunction(){
- Particle.publish(APP_NAME, "initEnterFunction", 60, PRIVATE);
- //start the timer of this cycle
- initTimer = 0;
-
-}
-void initUpdateFunction(){
- //time is up?
- if (initTimer > INIT_TIMEOUT) {
-  thermostatStateMachine.transitionTo(idleState);
- }
-}
-void initExitFunction(){
- Particle.publish(APP_NAME, "initExitFunction", 60, PRIVATE);
-}
-
-void idleEnterFunction(){
- Particle.publish(APP_NAME, "idleEnterFunction", 60, PRIVATE);
- myDigitalWrite(fan, LOW);
- myDigitalWrite(heat, LOW);
- myDigitalWrite(cold, LOW);
-}
-void idleUpdateFunction(){
- if ( currentTemp <= (targetTemp - margin) ) {
-  Particle.publish(APP_NAME, "Starting to heat", 60, PRIVATE);
-  thermostatStateMachine.transitionTo(heatingState);
- }
-}
-void idleExitFunction(){
- Particle.publish(APP_NAME, "idleExitFunction", 60, PRIVATE);
-}
-
-void heatingEnterFunction(){
- Particle.publish(APP_NAME, "heatingEnterFunction", 60, PRIVATE);
- myDigitalWrite(fan, HIGH);
- myDigitalWrite(heat, HIGH);
- myDigitalWrite(cold, LOW);
-}
-void heatingUpdateFunction(){
- if ( currentTemp >= (targetTemp + margin) ) {
-  Particle.publish(APP_NAME, "Desired temperature reached", 60, PRIVATE);
-  thermostatStateMachine.transitionTo(endOfCycleState);
- }
-}
-void heatingExitFunction(){
- Particle.publish(APP_NAME, "heatingExitFunction", 60, PRIVATE);
- myDigitalWrite(fan, HIGH);
- myDigitalWrite(heat, LOW);
- myDigitalWrite(cold, LOW);
-}
-
-void endOfCycleEnterFunction(){
- Particle.publish(APP_NAME, "endOfCycleEnterFunction", 60, PRIVATE);
- myDigitalWrite(fan, HIGH);
- myDigitalWrite(heat, LOW);
- myDigitalWrite(cold, LOW);
-
- //start the timer of this cycle
- endOfCycleTimer = 0;
-
-}
-void endOfCycleUpdateFunction(){
- //time is up?
- if (endOfCycleTimer > END_OF_CYCLE_TIMEOUT) {
-  thermostatStateMachine.transitionTo(idleState);
- }
-}
-void endOfCycleExitFunction(){
- Particle.publish(APP_NAME, "endOfCycleExitFunction", 60, PRIVATE);
-}
-
-/*******************************************************************************
- * Function Name  : setTesting
- * Description    : sets the testing variable to true
- * Return         : 0
- *******************************************************************************/
-int setTesting(String dummy)
-{
-  testing = true;
-  return 0;
-}
-
-/*******************************************************************************
- * Function Name  : getOutputs
- * Description    : returns the outputs so we can test the program
- * Return         : returns the outputs
- *******************************************************************************/
-int getOutputs(String dummy)
-{
-  // int fan = D0;
-  // int heat = D1;
-  // int cold = D2;
-  return coldTesting*4 + heatTesting*2 + fanTesting*1;
-}
-
-/*******************************************************************************
- * Function Name  : setCurrentTemp
- * Description    : sets the current temperature of the thermostat
-                    newCurrentTemp has to be a valid float value, or no new current temp will be set
- * Return         : 0, or -1 if it fails to convert the temp to float
- *******************************************************************************/
-int setCurrentTemp(String newCurrentTemp)
-{
-  float tmpFloat = newCurrentTemp.toFloat();
-
-  //update the current temp only in the case the conversion to float works
-  // (toFloat returns 0 if there is a problem in the conversion)
-  // sorry, if you wanted to set 0 as the current temp, you can't :)
-  if ( tmpFloat > 0 ) {
-    currentTemp = tmpFloat;
-    currentTempString = String(currentTemp);
-    Particle.publish(APP_NAME, "New current temp: " + currentTempString, 60, PRIVATE);
-    return 0;
-  } else {
-    Particle.publish(APP_NAME, "ERROR: Failed to set new current temp to " + newCurrentTemp, 60, PRIVATE);
-    return -1;
-  }
+
 }

 /*******************************************************************************
@@ -357,6 +200,233 @@
   }
 }

+/*******************************************************************************
+ * Function Name  : readTemperature
+ * Description    : reads the temperature of the DHT22 sensor at every DHT_SAMPLE_INTERVAL
+                    if testing the app, it returns right away
+ * Return         : 0
+ *******************************************************************************/
+int readTemperature() {
+
+  //TESTING_HACK
+  //are we testing the app? then no need to acquire from the sensor
+  if (testing) {
+   return 0;
+  }
+
+  //time is up? no, then come back later
+  if (dhtSampleInterval < DHT_SAMPLE_INTERVAL) {
+   return 0;
+  }
+
+  //time is up, reset timer
+  dhtSampleInterval = 0;
+
+  // start the sample
+  if (!bDHTstarted) {
+    DHT.acquireAndWait(5);
+    bDHTstarted = true;
+  }
+
+  //still acquiring sample? go away
+  if (DHT.acquiring()) {
+    return 0;
+  }
+
+  //sample acquired - go ahead and store temperature and humidity in internal variables
+  publishTemperature( (float)DHT.getCelsius(), (float)DHT.getHumidity() );
+
+  //reset the sample flag so we can take another
+  bDHTstarted = false;
+
+  return 0;
+}
+
+/*******************************************************************************
+ * Function Name  : publishTemperature
+ * Description    : the temperature/humidity passed as parameters get stored in internal variables
+                    and then published
+ * Return         : 0
+ *******************************************************************************/
+int publishTemperature( float temperature, float humidity ) {
+
+ char currentTempChar[32];
+ currentTemp = temperature;
+ int currentTempDecimals = (currentTemp - (int)currentTemp) * 100;
+ sprintf(currentTempChar,"%0d.%d", (int)currentTemp, currentTempDecimals);
+
+ char currentHumidityChar[32];
+ currentHumidity = humidity;
+ int currentHumidityDecimals = (currentHumidity - (int)currentHumidity) * 100;
+ sprintf(currentHumidityChar,"%0d.%d", (int)currentHumidity, currentHumidityDecimals);
+
+ //publish readings into exposed variables
+ currentTempString = String(currentTempChar);
+ currentHumidityString = String(currentHumidityChar);
+
+ //publish readings
+ Particle.publish(APP_NAME, "Current temperature: " + currentTempString, 60, PRIVATE);
+ Particle.publish(APP_NAME, "Current humidity: " + currentHumidityString, 60, PRIVATE);
+
+ return 0;
+
+}
+
+
+/*******************************************************************************
+********************************************************************************
+********************************************************************************
+ FINITE STATE MACHINE FUNCTIONS
+********************************************************************************
+********************************************************************************
+*******************************************************************************/
+void initEnterFunction(){
+ Particle.publish(APP_NAME, "initEnterFunction", 60, PRIVATE);
+ //start the timer of this cycle
+ initTimer = 0;
+
+}
+void initUpdateFunction(){
+ //time is up?
+ if (initTimer > INIT_TIMEOUT) {
+  thermostatStateMachine.transitionTo(idleState);
+ }
+}
+void initExitFunction(){
+ Particle.publish(APP_NAME, "initExitFunction", 60, PRIVATE);
+}
+
+void idleEnterFunction(){
+ Particle.publish(APP_NAME, "idleEnterFunction", 60, PRIVATE);
+ myDigitalWrite(fan, LOW);
+ myDigitalWrite(heat, LOW);
+ myDigitalWrite(cold, LOW);
+}
+void idleUpdateFunction(){
+ if ( currentTemp <= (targetTemp - margin) ) {
+  Particle.publish(APP_NAME, "Starting to heat", 60, PRIVATE);
+  thermostatStateMachine.transitionTo(heatingState);
+ }
+}
+void idleExitFunction(){
+ Particle.publish(APP_NAME, "idleExitFunction", 60, PRIVATE);
+}
+
+void heatingEnterFunction(){
+ Particle.publish(APP_NAME, "heatingEnterFunction", 60, PRIVATE);
+ myDigitalWrite(fan, HIGH);
+ myDigitalWrite(heat, HIGH);
+ myDigitalWrite(cold, LOW);
+
+ //start the minimum timer of this cycle
+ minimumOnTimer = 0;
+}
+void heatingUpdateFunction(){
+  //is minimum time up?
+  if (minimumOnTimer < MINIMUM_ON_TIMEOUT) {
+    //not yet, so get out of here
+    return;
+  }
+
+  if ( currentTemp >= (targetTemp + margin) ) {
+    Particle.publish(APP_NAME, "Desired temperature reached", 60, PRIVATE);
+    thermostatStateMachine.transitionTo(endOfCycleState);
+  }
+}
+void heatingExitFunction(){
+ Particle.publish(APP_NAME, "heatingExitFunction", 60, PRIVATE);
+ myDigitalWrite(fan, HIGH);
+ myDigitalWrite(heat, LOW);
+ myDigitalWrite(cold, LOW);
+}
+
+void endOfCycleEnterFunction(){
+ Particle.publish(APP_NAME, "endOfCycleEnterFunction", 60, PRIVATE);
+ myDigitalWrite(fan, HIGH);
+ myDigitalWrite(heat, LOW);
+ myDigitalWrite(cold, LOW);
+
+ //start the timer of this cycle
+ endOfCycleTimer = 0;
+
+}
+void endOfCycleUpdateFunction(){
+ //time is up?
+ if (endOfCycleTimer > END_OF_CYCLE_TIMEOUT) {
+  thermostatStateMachine.transitionTo(idleState);
+ }
+}
+void endOfCycleExitFunction(){
+ Particle.publish(APP_NAME, "endOfCycleExitFunction", 60, PRIVATE);
+}
+
+
+/*******************************************************************************
+********************************************************************************
+********************************************************************************
+ TESTING HACKS
+********************************************************************************
+********************************************************************************
+*******************************************************************************/
+
+/*******************************************************************************
+ * Function Name  : setTesting
+ * Description    : sets the testing variable to true - this enables me to override
+                     the temperature read by the DHT sensor.
+                    this is a hack that allows me to system test the project
+ * Return         : 0
+ *******************************************************************************/
+int setTesting(String dummy)
+{
+  testing = true;
+  return 0;
+}
+
+/*******************************************************************************
+ * Function Name  : getOutputs
+ * Description    : returns the outputs so we can test the program
+                    this is a hack that allows me to system test the project
+ * Return         : returns the outputs
+ *******************************************************************************/
+int getOutputs(String dummy)
+{
+  // int fan = D0;
+  // int heat = D1;
+  // int cold = D2;
+  return coldTesting*4 + heatTesting*2 + fanTesting*1;
+}
+
+/*******************************************************************************
+ * Function Name  : setCurrentTemp
+ * Description    : sets the current temperature of the thermostat
+                    newCurrentTemp has to be a valid float value, or no new current temp will be set
+                    this is a hack that allows me to system test the project
+* Return         : 0, or -1 if it fails to convert the temp to float
+ *******************************************************************************/
+int setCurrentTemp(String newCurrentTemp)
+{
+  float tmpFloat = newCurrentTemp.toFloat();
+
+  //update the current temp only in the case the conversion to float works
+  // (toFloat returns 0 if there is a problem in the conversion)
+  // sorry, if you wanted to set 0 as the current temp, you can't :)
+  if ( tmpFloat > 0 ) {
+    currentTemp = tmpFloat;
+    currentTempString = String(currentTemp);
+    Particle.publish(APP_NAME, "New current temp: " + currentTempString, 60, PRIVATE);
+    return 0;
+  } else {
+    Particle.publish(APP_NAME, "ERROR: Failed to set new current temp to " + newCurrentTemp, 60, PRIVATE);
+    return -1;
+  }
+}
+
+/*******************************************************************************
+ * Function Name  : getOutputs
+ * Description    : returns the outputs so we can test the program
+                    this is a hack that allows me to system test the project
+ * Return         : returns the outputs
+ *******************************************************************************/
 void myDigitalWrite( int input, int status){
   digitalWrite(input, status);
   if (input == fan){


Fixed trace setup banner; wrong example file name.

--- examples/Sandbox/CosaSwitch/CosaSwitch.ino
+++ examples/Sandbox/CosaSwitch/CosaSwitch.ino
@@ -154,7 +154,7 @@
 void setup()
 {
   uart.begin(9600);
-  trace.begin(&uart, PSTR("CosaGoto: started"));
+  trace.begin(&uart, PSTR("CosaSwitch: started"));
   Watchdog::begin();
   RTC::begin();
 }


reconnect on disconnect

reconnect on disconnect

--- examples/pseudopod-wifi/pseudopod-wifi.ino
+++ examples/pseudopod-wifi/pseudopod-wifi.ino
@@ -34,8 +34,6 @@
   Serial.begin(9600);
   Serial.println("Starting up.");
   setupWifi();
-  Serial.println("wifi should be setup!");
-
   pseudopod = new Pseudopod(conn, conn);
 }

@@ -47,15 +45,16 @@
 }

 void loop() {
-  connectToServer();
+  if (!conn.connected()) {
+    connectToServer();
+  }
+
   Serial.println("writing");
   Serial.flush();
-  pins.clear();
-  for(int i = 0; i < 80; i++) {
-    pins.push_back(Pin(i,NULL, i));
-  }
-  Serial.println("pushed a lot of pins into a vector");
+
+  pins = tentacle.getValue();
   int written = pseudopod->writeStateMessage(pins);
+
   Serial.print(written);
   Serial.println(" bytes written.");
   Serial.print(freeMemory());
@@ -64,42 +63,29 @@
   Serial.println(" bytes free");
   Serial.flush();
   delay(2000);
-  conn.stop();
+}
+
+void connectToServer() {
+  Serial.println("Connecting to the server.");
+  Serial.flush();
+  while(!conn.connect(server, port)) {
+    Serial.println("Can't connect to the server.");
+    Serial.flush();
+    conn.stop();
+    delay(1000);
+  }
 }

 void setupWifi() {
-  initWifi();
-
-  Serial.println("\nWifi initialized. Connecting to server.");
-  printWifiStatus();
-
-  Serial.println("connected to server");
-  Serial.flush();
-}
-
-void connectToServer() {
-  while(!conn.connect(server, port)) {
-      Serial.println("Can't connect to the server.");
-      Serial.flush();
-      delay(1000);
-    }
-}
-
-void initWifi() {
   int status = WL_IDLE_STATUS;

   while (status != WL_CONNECTED) {
     Serial.print("Attempting to connect to SSID: ");
     Serial.println(ssid);
     Serial.flush();
+    status = WiFi.begin(ssid, password);
+  }

-    status = WiFi.begin(ssid, password);
-
-    delay(3000);
-  }
-}
-
-void printWifiStatus() {
   // print the SSID of the network you're attached to:
   Serial.print("SSID: ");
   Serial.println(WiFi.SSID());
@@ -114,6 +100,8 @@
   Serial.print("signal strength (RSSI):");
   Serial.print(rssi);
   Serial.println(" dBm");
+
+  Serial.flush();
 }

 void softReset() {


Refactored

Refactored

--- hardware/powerManager.ino
+++ hardware/powerManager.ino
@@ -63,12 +63,7 @@
 */
 bool getSleepState() {
   DateTime now = RTC.now();
-  if ((now.hour() + TIMEZONE_OFFSET) <= HOUR_ON || (now.hour() + TIMEZONE_OFFSET) >= HOUR_OFF) {
-    return true;
-  }
-  else {
-    return false;
-  }
+  return (now.hour() + TIMEZONE_OFFSET) <= HOUR_ON || (now.hour() + TIMEZONE_OFFSET) >= HOUR_OFF)
 }

 /*
@@ -77,11 +72,5 @@
     False = keep power ON
 */
 bool getBatteryState() {
-  if (analogRead(BATTERY_PIN) < MINIMUM_VOLTAGE) {
-    return true;
-  }
-  else {
-    return false;
-  }
+  return analogRead(BATTERY_PIN) < MINIMUM_VOLTAGE)
 }
-


commit

commit

--- watermeter/watermeter.ino
+++ watermeter/watermeter.ino
@@ -22,7 +22,7 @@
 #define EXT_POWER_PIN D0                          /* Check external input Vcc          */
 #define BAT_VOLT_PIN A0                           /* Measuring the battery voltage     */

-#define TIME_BOUNCE 50                            /* Pause for debounce                 */
+#define TIME_BOUNCE 50                            /* Pause for debounce in msec        */

 /* Name and Version */
 #define PLATFORM "Wemos D1 mini & Micro SD"


fix max wind error

fix max wind error

--- arduino/sadr_meteo_no_firmata/sadr_meteo_no_firmata.ino
+++ arduino/sadr_meteo_no_firmata/sadr_meteo_no_firmata.ino
@@ -58,6 +58,7 @@
 // Wind sensor
 // Activation threshold for wind in km/h
 #define WIND_FLAG_TRIGGER 20
+#define MAX_WIND_FLAG_TRIGGER 50
 // A wind speed of 1.492 MPH (2.4 km/h) causes the switch to close once per second.
 #define WIND_RPM_TO_KMH 25 // Relation between windspeed in km/h and rotation per minute
 #define ANEMOMETER_BOUNCE_TIME 10 //Below this value, no count is adding
@@ -227,17 +228,15 @@

         // Winspeed and MaxWindSpeed in RPM - switch closed 2 times per revolution - SERIAL_DELAY in ms
         //WindSpeed = (reedSwitchCount / 2 * 60) / (reedSwitchTime / 1000);
-        WindSpeed = reedSwitchCount / reedSwitchTime * 30000;
-
-
-        if (MaxWindSpeed < 30000 / reedSwitchDeltaTime) {
-           //MaxWindSpeed = (1 / 2 * 60) / (reedSwitchDeltaTime / 1000);
-            MaxWindSpeed = 30000 / reedSwitchDeltaTime;
-        }
+        WindSpeed = (reedSwitchCount-1) * 30000 / reedSwitchTime;

         // Winspeed and MaxWindSpeed in Km/h
         WindSpeed = WindSpeed / WIND_RPM_TO_KMH;
-        MaxWindSpeed = MaxWindSpeed / WIND_RPM_TO_KMH;
+        if (MaxWindSpeed < 30000 / reedSwitchDeltaTime / WIND_RPM_TO_KMH) {
+           //MaxWindSpeed = (1 / 2 * 60) / (reedSwitchDeltaTime / 1000);
+            MaxWindSpeed = 30000 / reedSwitchDeltaTime/ WIND_RPM_TO_KMH;
+        }
+
     }
 }
 #endif //USE_WIND_SENSOR
@@ -449,7 +448,7 @@
 #endif //USE_RAIN_SENSOR*/

 #ifdef USE_WIND_SENSOR
-  if ((WindSpeed > WIND_FLAG_TRIGGER) | (MaxWindSpeed > WIND_FLAG_TRIGGER)) {
+  if ((WindSpeed > WIND_FLAG_TRIGGER) | (MaxWindSpeed > MAX_WIND_FLAG_TRIGGER)) {
         windy=1;
     } else {
         windy=0;


update ir simple

update ir simple

--- infrared/simpleinfrared/simpleinfrared.ino
+++ infrared/simpleinfrared/simpleinfrared.ino
@@ -6,8 +6,8 @@
  *
  *
  */
- int ledpin = 3; // this is just for reference
- int irsensorpin = 2; // read digital
+ int ledpin = 13; // this is just for reference
+ int irsensorpin = 3; // read digital

  void setup(){
  Serial.begin(9600);// for seeing whats going on


oeps streepje vergeten

oeps streepje vergeten

--- programmaNano/programmaNano.ino
+++ programmaNano/programmaNano.ino
@@ -204,7 +204,7 @@
           Serial.println(4);        // Verstuurd om links te draaien

           schuinKijken = false;
-          myservo.write(80);      / zet servo terug in het midden
+          myservo.write(80);      // zet servo terug in het midden
           afstand=0;
           delay(4000);
           stippenlijn = true ;      // zorgt dat er terug een stippellijn patroon wordt getekend


Motors based on doubles

Motors based on doubles

Custom variables for motor speeds

--- 2018-FirefighterL1/2018-FirefighterL1.ino
+++ 2018-FirefighterL1/2018-FirefighterL1.ino
@@ -41,6 +41,10 @@
 Motor rightMotor(RIGHT_MOTOR_1,RIGHT_MOTOR_2);
 Servo extinguisher;

+//Motor top speeds
+double rightSpeed = 0.5;
+double leftSpeed = 0.5;
+
 //Ultrasonic frontLeftUltrasonic(F_L_ECHO, F_L_TRIG, true);
 Ultrasonic frontRightUltrasonic(F_R_ECHO, F_R_TRIG, true);
 Ultrasonic leftUltrasonic(L_ECHO, L_TRIG, true);
@@ -58,25 +62,25 @@
 double closeToWall = 2;   //defines how close the robot should be (inches) to the wall to register as being "too close"

 void rollForward() {
-  leftMotor.set(0.5);
-  rightMotor.set(0.5);
+  leftMotor.set(leftSpeed);
+  rightMotor.set(rightSpeed);
 }

 void rollBackward() {
-  leftMotor.set(-0.5);
-  rightMotor.set(-0.5);
+  leftMotor.set(-leftSpeed);
+  rightMotor.set(-rightSpeed);
 }

 void moveSlightLeft() {
-  leftMotor.set(0.25);
-  rightMotor.set(0.375);
+  leftMotor.set(leftSpeed/2);
+  rightMotor.set(rightSpeed*.75);
   delay(100);
   stopRobot();
 }

 void moveSlightRight() {
-  leftMotor.set(0.375); //Half power plus additional 25
-  rightMotor.set(0.25);
+  leftMotor.set(leftSpeed*.75); //Half power plus additional 25
+  rightMotor.set(rightSpeed/2);
   delay(100);
   stopRobot();
 }
@@ -128,8 +132,8 @@
     gyroTargetAngle = 360 + gyroTargetAngle;
   }
   if(gyroTargetAngle < getGyroAngle()){
-    leftMotor.set(0.5);
-    rightMotor.set(0.5);
+    leftMotor.set(leftSpeed);
+    rightMotor.set(rightSpeed);
     while(gyroTargetAngle < getGyroAngle()){
       delay(50);
     }


Update ArduAutoController.ino

Update ArduAutoController.ino

--- ArduAutoController/ArduAutoController.ino
+++ ArduAutoController/ArduAutoController.ino
@@ -10,12 +10,7 @@

 ArduinoNunchuk nunchuk = ArduinoNunchuk();

-class RF24Test: public RF24
-{
-public: RF24Test(int a, int b): RF24(a,b) {}
-};
-
-RF24Test radio(9,10);
+RF24 radio(9, 10);

 // Radio pipe addresses for the 2 nodes to communicate.
 const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
@@ -28,7 +23,7 @@
   radio.begin();
   radio.openWritingPipe(pipes[0]);
   radio.openReadingPipe(1,pipes[1]);
-  radio.printDetails();
+
 }

 void loop()


Fix LSM303::vector syntax error

Fix LSM303::vector syntax error

Fixed syntax error

--- Flora_NeoGeo_Watch/Flora_NeoGeo_Watch.ino
+++ Flora_NeoGeo_Watch/Flora_NeoGeo_Watch.ino
@@ -502,7 +502,7 @@
   if (millis() - compassTimer > 50) {
     compassTimer = millis(); // reset the timer
     compass.read();
-    compassReading = compass.heading((LSM303::vector){0,-1,0});
+    compassReading = compass.heading((LSM303::vector<int>){0,-1,0});
     }
 }


bug fix

bug fix

first bug. It compiles now

--- sketches/gear_indicator/gear_indicator.ino
+++ sketches/gear_indicator/gear_indicator.ino
@@ -1,6 +1,8 @@
 /*
 * Gear Indicator
 * Could be used alone or with Arduino DataLogger
+* Some information about interrupts:
+* - http://arduino.cc/en/Reference/attachInterrupt
 * Some useful information about Aprilia RSV/SL bikes work: (See: http://www.aprilia-v60.com/index.php?topic=262315)
 * - Speed sensor: purple/green wire=Vcc ~ 9V ? / grey/white: signal ~6.5V, falling to 0V
 * - Engine pulses/revolution: 3 if read from the dashboard wire
@@ -18,7 +20,7 @@

 unsigned int engine_rpm;
 unsigned int wheel_rpm;
-unsigned float ratio;
+float ratio;

 unsigned long lastmillis;


Improve codes

Improve codes

--- DigitalSynthVRA8Px/DigitalSynthVRA8Px.ino
+++ DigitalSynthVRA8Px/DigitalSynthVRA8Px.ino
@@ -1,4 +1,3 @@
-#include "Arduino.h"
 #include "common.h"
 #include "synth.h"
 #include "serial-in.h"


tuning distance sensor

tuning distance sensor

--- Modules/Sensor/DistanceSensor/ArduinoCodes/DistanceSensorNewATtiny/DistanceSensorNewATtiny.ino
+++ Modules/Sensor/DistanceSensor/ArduinoCodes/DistanceSensorNewATtiny/DistanceSensorNewATtiny.ino
@@ -52,7 +52,7 @@
   int val = readIR(20);                        // calling the function that will read the distance and passing the "accuracy" to it
   int distance = A*pow(val, B);                //converting to distance
   //Serial.println(distance);
-  int output_val = cutAndMap(distance, 5, 65, input_val/4, 0);
+  int output_val = cutAndMap(distance, 6, 85, input_val/4, 0);
   //Serial.println(output_val);
   analogWrite(output_pin, output_val);
 }


Device timers updated

Device timers updated

Some of the device timer functions had been mixed up and was sending
‘on’ and ‘off’ instead of ‘off’ and ‘on’, respectively.

--- elfi/elfi.ino
+++ elfi/elfi.ino
@@ -130,8 +130,8 @@
 DeviceTimer deviceTimers[5] = {
   DeviceTimer(weekDays,     6, 40,  0, all, on),       //  1 Weekday morning on
   DeviceTimer(weekDays,     7, 25,  0, all, off),      //  2 Weekday morning off
-  DeviceTimer(weekDays,    22, 30,  0, all, on),       //  3 Weekday night off
-  DeviceTimer(weekendDays,  8, 30,  0, all, off),      //  4 Weekend morning on
+  DeviceTimer(weekDays,    22, 30,  0, all, off),      //  3 Weekday night off
+  DeviceTimer(weekendDays,  8, 30,  0, all, on),       //  4 Weekend morning on
   DeviceTimer(allDays,     23, 30,  0, all, off)       //  5 All days night off
 };


processGetPos function implemented and working.

--- skypointer.ino
+++ skypointer.ino
@@ -71,6 +71,15 @@
     Serial.print("OK\r");
 }

+void ProcessGetPos() {
+    char buff[13];
+    uint16_t pos1, pos2;
+    pos1 = MOD(AZ.currentPosition(), USTEPS_REV);
+    pos2 = MOD(ALT.currentPosition(), USTEPS_REV);
+    sprintf(buff, "P %04d %04d\r", pos1, pos2);
+    Serial.print(buff);
+}
+
 void Unrecognized() {
     Serial.print("NK\r");
 }
@@ -91,6 +100,7 @@
     ALT.setEnablePin(ENABLE);

     sCmd.addCommand("G", ProcessGoto);
+    sCmd.addCommand("P", ProcessGetPos);
     sCmd.addDefaultHandler(Unrecognized);

     Serial.begin(BAUDRATE);
@@ -100,5 +110,5 @@
     sCmd.readSerial();
     AZ.run();
     ALT.run();
-
+    //Serial.println(MOD(AZ.currentPosition(), USTEPS_REV), DEC);
 }


Added interrupt lock Added filtering for mph output

--- quadcopter/quadcopter.ino
+++ quadcopter/quadcopter.ino
@@ -59,8 +59,8 @@
  *
  */

-#define PITCH_P_VAL 2
-#define PITCH_I_VAL 5
+#define PITCH_P_VAL 0.5
+#define PITCH_I_VAL 0
 #define PITCH_D_VAL 1

 #define ROLL_P_VAL 2
@@ -82,8 +82,8 @@
 #define ROLL_MAX 30
 #define YAW_MIN -180
 #define YAW_MAX 180
-#define PID_PITCH_INFLUENCE 50
-#define PID_ROLL_INFLUENCE 50
+#define PID_PITCH_INFLUENCE 20
+#define PID_ROLL_INFLUENCE 20
 #define PID_YAW_INFLUENCE 20

@@ -103,9 +103,15 @@
 Quaternion q;                          // quaternion for mpu output
 VectorFloat gravity;                   // gravity vector for ypr
 float ypr[3] = {0.0f,0.0f,0.0f};       // yaw pitch roll values
+float yprLast[3] = {0.0f, 0.0f, 0.0f};

 volatile bool mpuInterrupt = false;    //interrupt flag

+/* Interrupt lock
+ *
+ */
+
+boolean interruptLock = false;

 /*  RC variables
  *
@@ -197,6 +203,7 @@

 void computePID(){

+  acquireLock();
   roundInput();

   ch2 = map(ch2, RC_LOW_CH2, RC_HIGH_CH2, PITCH_MIN, PITCH_MAX);
@@ -214,10 +221,20 @@
   ypr[0] = ypr[0] * 180/M_PI;
   ypr[1] = ypr[1] * 180/M_PI;
   ypr[2] = ypr[2] * 180/M_PI;
-
+
+  if(abs(ypr[0]-yprLast[0])>30) ypr[0] = yprLast[0];
+  if(abs(ypr[1]-yprLast[1])>30) ypr[1] = yprLast[1];
+  if(abs(ypr[2]-yprLast[2])>30) ypr[2] = yprLast[2];
+
+  yprLast[0] = ypr[0];
+  yprLast[1] = ypr[1];
+  yprLast[2] = ypr[2];
+
   pitchReg.Compute();
   rollReg.Compute();
   yawReg.Compute();
+
+  releaseLock();

 }

@@ -233,7 +250,7 @@
     mpuIntStatus = mpu.getIntStatus();
     fifoCount = mpu.getFIFOCount();

-    if((mpuIntStatus & 0x10) || fifoCount == 1024){
+    if((mpuIntStatus & 0x10) || fifoCount >= 1024){

       mpu.resetFIFO();

@@ -290,6 +307,8 @@

   vc = (abs((-100+bal_ac)/100))*v_ac;
   vd = (abs((-100+bal_bd)/100))*v_bd;
+
+  Serial.println(bal_bd);

   if(velocity < ESC_TAKEOFF_OFFSET){

@@ -389,30 +408,38 @@
 }

 void rcInterrupt1(){
-   ch1 = micros() - rcLastChange1;
+   if(!interruptLock) ch1 = micros() - rcLastChange1;
    rcLastChange1 = micros();
 }

 void rcInterrupt2(){
-  ch2 = micros() - rcLastChange2;
+  if(!interruptLock) ch2 = micros() - rcLastChange2;
   rcLastChange2 = micros();
 }

 void rcInterrupt3(){
-  ch3 = micros() - rcLastChange3;
+  if(!interruptLock) ch3 = micros() - rcLastChange3;
   rcLastChange3 = micros();
 }

 void rcInterrupt4(){
-  ch4 = micros() - rcLastChange4;
+  if(!interruptLock) ch4 = micros() - rcLastChange4;
   rcLastChange4 = micros();
 }

 void rcInterrupt5(){
-  ch5 = micros() - rcLastChange5;
+  if(!interruptLock) ch5 = micros() - rcLastChange5;
   rcLastChange5 = micros();
 }

+void acquireLock(){
+  interruptLock = true;
+}
+
+void releaseLock(){
+  interruptLock = false;
+}
+
 #endif


Add recording of measurements #5

Add recording of measurements #5

Transmit data to UART in JSON #7

--- Node/Node.ino
+++ Node/Node.ino
@@ -23,6 +23,8 @@

 SI7021 sensor;
 Adafruit_BMP085 bmp;
+StaticJsonBuffer<200> jsonBuffer;
+

 void setup() {

@@ -112,14 +114,20 @@
   Serial.print("Temp: "); Serial.print(t);
   Serial.print("\tHum: "); Serial.println(RH);

-  double P = bmp.readPressure() / 100.0;
-  Serial.print("Temp: "); Serial.print(bmp.readTemperature()); // Celsius
+  int32_t p = bmp.readPressure();
+  double P = p / 100.0;
+  double bmpTemp = bmp.readTemperature();
+  Serial.print("Temp: "); Serial.print(bmpTemp); // Celsius
   Serial.print("\tPressure: "); Serial.println(P); // Gecto Pascals
+
+  int humudutyTempWeight = 1;
+  int pressureTempWeight = 1;
+  double temperature = (t * humudutyTempWeight + bmpTemp * pressureTempWeight) / (humudutyTempWeight + pressureTempWeight);

   double V = 1.0;
   double Rv = 461.5;

-  double T = 273.15 + t;
+  double T = 273.15 + temperature;
   double e_omega_t = 6.112*exp((17.62*T - 4812.903)/(T - 30.03));
   double f = 1.0016 + 0.00000315*P - 0.074/P;
   double e_omega = e_omega_t*f;
@@ -139,5 +147,30 @@
     Serial.println(" ppm");
   }

+  JsonObject& root = jsonBuffer.createObject();
+  root["time"] = currentTime;
+  root["temperature"] = temperature;
+  root["pressure"] = P;
+  root["humidity"] = RH;
+  root.printTo(Serial);
+  char dirName[12];
+  sprintf(dirName, 12, "/%.4i/%.2i/%.2i", tmYearToCalendar(tm.Year), tm.Month, tm.Day)
+  char fileName[25];
+  sprintf(fileName, 25, "/%s/%.2i.csv", dirName, tm.Hour)
+
+  File dataFile;
+  if(!SD.exists(fileName)){
+    if(!SD.mkdir(dirName)){
+      Serial.printf("Failed to create directory %s\r\n", dirName);
+      return;
+    }
+    dataFile = SD.open(buffer, O_WRITE | O_CREAT);
+  }else{
+    dataFile = SD.open(buffer, O_WRITE);
+  }
+
+  dataFile.seek(dataFile.size());
+  dataFile.printf("%i;%i;%i;%.2f;%i;%i\r\n", currentTime, thc.celsiusHundredths, thc.humidityPercent, bmpTemp, p, ppm);
+  dataFile.close();
   Serial.println();
 }


cleaned up variable names & comments

cleaned up variable names & comments

--- head-turning-sine-wave.ino
+++ head-turning-sine-wave.ino
@@ -1,50 +1,63 @@
+//-*- C -*-
+
 #include <Math.h>
-#include <Servo.h>
+#include <Servo.h>

-Servo myservo;  // create servo object to control a servo
-                // a maximum of eight servo objects can be created
+Servo myservo;  // create servo object to control a servo
+                // a maximum of eight servo objects can be created
+
+// multiply by degrees to get radians
+//
 const double degrees_to_radians = 0.0174532925;

-//int pos = 0;    // variable to store the servo position
-
-void setup()
-{
-  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
+void setup()
+{
+  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
   myservo.write(90);
 }

-void loop()
-{
+void loop()
+{
+  const int startAngle = 10;
+  const int endAngle = 170;
+
+  // milliseconds to wait between servo movement
   const int delayTime = 25;
-  const int startPoint = 5;
-  const int endPoint = 175;
+
+  // maximum servo movement per iteration
   const int increment = 3;
-  const int turnaroundTime = 10;
-  int pos = 0;
-
+
+  // milliseconds to wait at one end point before reversing rotation
+  const int turnaroundTime = 25;
+
+  int angle = 0;
+
   delay(turnaroundTime);

-  for(pos = startPoint; pos < endPoint; )  // goes from 0 degrees to 180 degrees
-  {                                  // in steps of 1 degree
-    myservo.write(pos);     // tell servo to go to position in variable 'pos'
-    delay(delayTime);                       // waits 15ms for the servo to reach the position
-
-    float rad = pos * degrees_to_radians;
+  for(angle = startAngle; angle < endAngle; )
+  {
+    myservo.write(angle);       // tell servo to go to position in variable 'angle'
+    delay(delayTime);           // waits for the servo to reach the position
+
+    // amount to rotate head depends on where it is: more in the
+    // middle, & less at the ends. AKA sine wave.
+    float rad = angle * degrees_to_radians;
     int increAngle = ceil(increment * sin(rad));

-    pos += increAngle;
-  }
-
+    angle += increAngle;
+  }
+
   delay(turnaroundTime);
-
-  for(pos = endPoint; pos > startPoint; )     // goes from 180 degrees to 0 degrees
-  {
-    myservo.write(pos);              // tell servo to go to position in variable 'pos'
-    delay(delayTime);                       // waits 15ms for the servo to reach the position
-
-    float rad = pos * degrees_to_radians;
+
+  for(angle = endAngle; angle > startAngle; )
+  {
+    myservo.write(angle);       // tell servo to go to position in variable 'angle'
+    delay(delayTime);           // waits for the servo to reach the position
+
+    float rad = angle * degrees_to_radians;
     int increAngle = ceil(increment * sin(rad));

-    pos -= increAngle;
-  }
-}
+    // note decrement instead of increment
+    angle -= increAngle;
+  }
+}


Adjusted speed for fresh battery.  Adjusted tape threshold up.

--- linefollow/linefollow.ino
+++ linefollow/linefollow.ino
@@ -8,13 +8,13 @@
 RedBotSensor center = RedBotSensor(A6); // initialize a center sensor object on A6
 RedBotSensor right = RedBotSensor(A7);  // initialize a right sensor object on A7

-#define SPEED 100
+#define SPEED 80
 #define MIN_SPEED 60

 #define SPEED_ADJUSTMENT 20

 // These thresholds are manually configured.
-#define TAPE_THRESHOLD  150 // below this value, we are looking at the tape
+#define TAPE_THRESHOLD  175 // below this value, we are looking at the tape

 RedBotMotors motors;
 int leftSpeed;   // variable used to store the leftMotor speed


edit soil values

edit soil values

--- motor_pump/motor_pump.ino
+++ motor_pump/motor_pump.ino
@@ -36,7 +36,7 @@
  if (death >11){
    death = 0;
  }
-  if (switchstate == HIGH | average < 200) {
+  if (switchstate == HIGH | average < 642 {
     digitalWrite(motorPin, HIGH);

   }
@@ -54,3 +54,4 @@

 }

+


Cleanup code.ino

Cleanup code.ino

--- code.ino
+++ code.ino
@@ -1,22 +1,16 @@
-#include <OneWire.h>            // OneWire-Bibliothek einbinden
-#include <DallasTemperature.h>  // DS18B20-Bibliothek einbinden
+#include <OneWire.h>
+#include <DallasTemperature.h>

-#define DS18B20_PIN 10   // Pin für DS18B20 definieren Arduino D2
+#define DS18B20_PIN 10
 #define READ A0
-int basis = 0;

-OneWire oneWire(DS18B20_PIN);          // OneWire Referenz setzen
-DallasTemperature sensors(&oneWire);   // DS18B20 initialisieren
-
+OneWire oneWire(DS18B20_PIN);
+DallasTemperature sensors(&oneWire);

 void setup() {
-
-  pinMode(LED, OUTPUT);
   Serial.begin(9600);
-  sensors.begin();  // DS18B20 starten
-  //Serial.println(sensors.getDeviceCount());
+  sensors.begin();
 }
-

 void loop() {

@@ -25,45 +19,31 @@

   //if ((char)b == 'r') {

-    sensors.requestTemperatures(); // Temperatursensor(en) auslesen
-    for (byte i = 0; i < sensors.getDeviceCount(); i++) {	// Temperatur ausgeben
-      json += show_temperature(i + 1, sensors.getTempCByIndex(i));
-    }
-    json += brightness()+"}";
-    Serial.println(json);
-
-    delay(100);
+  json += temperature();
+  json += brightness() + "}";
+  Serial.println(json);
+
+  delay(100);
   //}
 }

-String show_temperature(byte num, float temp) {
-  String result = "'temp':{'num_sensor':";
-  result += num;
-  result += ",'value':";
-  result += temp;
-  result += "},";
-  return result;
+String temperature() {
+  String json;
+  sensors.requestTemperatures();
+  for (byte i = 0; i < sensors.getDeviceCount(); i++) {
+    json += "'temp':{'num_sensor':" + String(i + 1) + ",'value':" + String(sensors.getTempCByIndex(i)) + "},";
+  }
+
+  return json;
 }

 String brightness() {
   int sens = readLED(50);
-  String result = "";
-  basis = sens - 20;                 // setting sensitivity - now it will react if the LED is 20 lower than the setting above
-  //for(int y = 0; y < 1000; y++) {    // after every 1000 tests the program will reset the led to cope with changing light
-  sens = readLED(50);
-  if (sens < basis) {               // testing is the led was in the dark
-    result += "'light':{'light':false,'value':";
-    result += sens;
-    result += "},";
-  }
-  else {
-    result += "'light':{'light':true,'value':"; result += sens; result += "}";
-  }
-  //}
-  return result;
+
+  return "'light':" + String(sens) + "}";
 }

-int readLED(int number) {            // Read analog value n times and avarage over those n times
+int readLED(int number) { // Read analog value n times and avarage over those n times
   int totaal = 0;
   for (int x = 0; x < number; x++) {
     totaal += analogRead(READ);


Clarify restart reasons

Clarify restart reasons

--- src/homie-sonoff-touch.ino
+++ src/homie-sonoff-touch.ino
@@ -257,8 +257,7 @@
   } else {
     // If disconnected for over 5 minutes
     if ( millis() - connectedMillis >= 300000 ) {
-      Serial.println("Restarting in ten seconds");
-      delay(10000);
+      Serial.println("No connection - restarting");
       // The chances of being in OTA whilst disconnected from MQTT are slim.
       ESP.restart();
     };
@@ -268,6 +267,7 @@
   // Check if keepalive is supported and expired
   if (EEpromData.keepAliveTimeOut != 0 && (millis() - keepAliveReceived) > EEpromData.keepAliveTimeOut*1000 )
   {
+    Serial.println("No keepalive - restarting");
     ESP.restart();
   }
   if (watchDogCounterStart!=0 && EEpromData.watchDogTimeOut!=0 && (millis() - watchDogCounterStart) > EEpromData.watchDogTimeOut * 1000 )


:bug: Don't retain events. Fixes #3

:bug: Don't retain events. Fixes #3

--- src/homie-sonoff-touch.ino
+++ src/homie-sonoff-touch.ino
@@ -32,8 +32,9 @@
 ClickButton button1(PIN_BUTTON, LOW, CLICKBTN_PULLUP);

 // Register our two HomieNode instances
+// nodeName(property, value, retained);
 HomieNode relayNode("relay", "relay");
-HomieNode buttonNode("button", "button");
+HomieNode buttonNode("button", "button", false);

 bool RelayHandler(const HomieRange& range, const String& value) {
   /*


Updated client

Updated client

--- backend/Arduino/ping_client/ping_client.ino
+++ backend/Arduino/ping_client/ping_client.ino
@@ -25,7 +25,7 @@
 XimuReceiver receiver;

 void setup(){
-  Serial1.begin(57600);
+  Serial1.begin(115200);
   Serial.begin(28800);
   /*
    * Setup pins / SPI.
@@ -91,11 +91,12 @@
     if (receiver.isInertialAndMagGetReady() && receiver.isQuaternionGetReady()) {
       DrumSet drum = receiver.getDrum();
       if (drum.drumID > 0 && drum.strength > 0) {
-        if (receiver.detectPeak()) {
+        if (receiver.detectPeak()) {
             // Use drum.drumID to get ID and drum.strength to get strength
             data = drum.drumID;
-            data = data + drum.strength << 4;
-            data = data + 0 << 8;
+            data = data + (drum.strength << 4);
+            data = data + (0 << 8);
+            Serial.println(data);
         }
       }
     }
@@ -107,8 +108,9 @@

   while(Mirf.isSending()){
   }
-  Serial.println("Finished sending");
+  // Serial.println("Finished sending");
   delay(10);
+  /*
   while(!Mirf.dataReady()){
     //Serial.println("Waiting");
     if ( ( millis() - time ) > 200 ) {
@@ -118,6 +120,7 @@

     }
   }
+
   unsigned long feedback;
   Mirf.getData((byte *) &feedback);
   if(feedback==data){
@@ -129,6 +132,7 @@
   Serial.println("Wrong data");
   }
   delay(1);
+  */
 }


Se agrega codificacion hexadecimal al mensaje encriptado para prueba con arduino

--- src/AES_prueba/aes.ino
+++ src/AES_prueba/aes.ino
@@ -20,13 +20,12 @@
         //Serial.println(sizeof(data));
         Serial.print("encrypted:");
         Serial.println(data);
-         for (int i=0; i<sizeof(data);i++)
-        {
-          //int x =int(data[i]);
-          uint8_t x = uint8_t(data[i]);
-          Serial.print(x);
-          Serial.print(" ");
-        }
+        String dataHEX = "";
+        byte tamano = sizeof(data)-1;
+        convert2Hex(data, tamano, dataHEX);
+        Serial.print("hex: ");
+        Serial.println(dataHEX);
+
         Serial.println("");

         aes128_cbc_dec(key, iv, data, strlen(data));
@@ -44,4 +43,20 @@
 {

 }
+void convert2Hex(char input[], byte tamanoInput, String &output) {
+  String hexa[] = {"0", "1", "2", "3", "4", "5", "6", "7",
+                   "8", "9", "A", "B", "C", "D", "E", "F"};
+  for (uint8_t i = 0; i < tamanoInput; i++) {
+    uint8_t b = (uint8_t)input[i];
+    String first = hexa[GetFirst4Bits(b)];
+    String second = hexa[GetSecond4Bits(b)];
+    output += first + second;
+  }
+}

+uint8_t GetFirst4Bits(uint8_t b) { return b >> 4; }
+uint8_t GetSecond4Bits(uint8_t b) {
+  // b = b << 4;
+  byte a = B00001111;
+  return b & a;
+}


prevent blink after boot screens.

prevent blink after boot screens.

--- src/rx5808-pro-diversity/rx5808-pro-diversity.ino
+++ src/rx5808-pro-diversity/rx5808-pro-diversity.ino
@@ -211,6 +211,7 @@
     // set the channel as soon as we can
     // faster boot up times :)
     setChannelModule(channelIndex);
+    last_channel_index=channelIndex;

     settings_beeps=EEPROM.read(EEPROM_ADR_BEEP);
     settings_orderby_channel=EEPROM.read(EEPROM_ADR_ORDERBY);


Using aJson library

Using aJson library

--- ESP8266HueEmulator/ESP8266HueEmulator.ino
+++ ESP8266HueEmulator/ESP8266HueEmulator.ino
@@ -6,13 +6,18 @@
 // TODO: Change SSDP to get rid of local copies of ESP8266SSDP use the new scheme from the Arduino IDE instead
 // https://github.com/esp8266/Arduino/commit/f5ba04d46c0b6df75348f005e68411a856f89e48
 // can then get rid of the SSDP.update();
+
+// The following MUST be changed in aJSON.h, otherwise JSON will be cut off
+// #define PRINT_BUFFER_LEN 2048

 #include <ESP8266WiFi.h>
 #include <ESP8266WebServer.h>
 #include <WiFiUDP.h>
 #include "ESP8266SSDP.h"
 #include <NeoPixelBus.h> // NeoPixelAnimator branch
-#include <ArduinoJson.h>
+#include <aJSON.h> // Replace avm/pgmspace.h with pgmspace.h there
+
+

 #include "/secrets.h" // Delete this line and populate the following
 //const char* ssid = "********";
@@ -51,6 +56,17 @@
 String client = "e7x4kuCaC8h885jo"; // The client name that the sketch gives to the app
 // FIXME: Parse this out of what is being sent by the app.

+void sendJson(aJsonObject *root)
+{
+  // Take aJsonObject and print it to Serial and to WiFi
+  // From https://github.com/pubnub/msp430f5529/blob/master/msp430f5529.ino
+  char *msgStr = aJson.print(root);
+  aJson.deleteItem(root);
+  Serial.println(msgStr);
+  HTTP.send(200, "text/plain", msgStr);
+  free(msgStr);
+}
+
 void handleAllOthers() {
   Serial.println("===");
   String requestedUri = HTTP.uri();
@@ -59,37 +75,32 @@

   if ( requestedUri.endsWith("/config") )
   {
-
-    StaticJsonBuffer<1024> jsonBuffer;
-    JsonObject& root = jsonBuffer.createObject();
+    aJsonObject *root;
+    root = aJson.createObject();
     addConfigJson(root);
-
-    root.prettyPrintTo(Serial);
-    WiFiClient client = HTTP.client();
-    root.prettyPrintTo((Print&)client); // Thanks me-no-dev for the "(Print&)"
-
+    sendJson(root);
   }

   else if ((requestedUri.startsWith("/api") and (requestedUri.lastIndexOf("/") == 4 )))
   {
     // Serial.println("Respond with complete json as in https://github.com/probonopd/ESP8266HueEmulator/wiki/Hue-API#get-all-information-about-the-bridge");
-
-    StaticJsonBuffer<2048> jsonBuffer;
-    JsonObject& root = jsonBuffer.createObject();
-    JsonObject& groups = root.createNestedObject("groups");
-    JsonObject& scenes = root.createNestedObject("scenes");
-    JsonObject& config = root.createNestedObject("config");
+    aJsonObject *root;
+    root = aJson.createObject();
+    aJsonObject *groups;
+    aJson.addItemToObject(root, "groups", groups = aJson.createObject());
+    aJsonObject *scenes;
+    aJson.addItemToObject(root, "scenes", scenes = aJson.createObject());
+    aJsonObject *config;
+    aJson.addItemToObject(root, "config", config = aJson.createObject());
     addConfigJson(config);
-    JsonObject& lights = root.createNestedObject("lights");
-    addLightJson(lights, 1); // I think this is prone to crashes; see https://github.com/bblanchon/ArduinoJson/issues/87
-//    for (int i = 1; i < 2; i++)
-//    {
-//      addLightJson(root, i); // This crashes when i>1; see https://github.com/bblanchon/ArduinoJson/issues/87
-//    }
-    JsonObject& schedules = root.createNestedObject("schedules");
-    root.prettyPrintTo(Serial);
-    WiFiClient client = HTTP.client();
-    root.prettyPrintTo((Print&)client); // Thanks me-no-dev for the "(Print&)"
+    aJsonObject *lights;
+    aJson.addItemToObject(root, "lights", lights = aJson.createObject());
+    for (int i = 1; i <= 8; i++) // FIXME: Why does this not work for more than 8?
+      addLightJson(lights, i);
+    aJsonObject *schedules;
+    aJson.addItemToObject(root, "schedules", schedules = aJson.createObject());
+    sendJson(root);
+
   }

   else if (requestedUri.endsWith("/api"))
@@ -106,23 +117,23 @@
   {
     // For this to work we need a patched version of esp8266/libraries/ESP8266WebServer/src/Parsing.cpp which hopefully lands in the official channel soon
     // https://github.com/me-no-dev/Arduino/blob/d4894b115e3bbe753a47b1645a55cab7c62d04e2/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp
+    if (HTTP.arg("plain") == "")
+    {
+      Serial.println("You need to use a newer version of the ESP8266WebServer library from https://github.com/me-no-dev/Arduino/blob/d4894b115e3bbe753a47b1645a55cab7c62d04e2/hardware/esp8266com/esp8266/libraries/ESP8266WebServer/src/Parsing.cpp");
+      yield();
+    }
     Serial.println(HTTP.arg("plain"));
     int numberOfTheLight = atoi(subStr(requestedUri.c_str(), "/", 4)) - 1; // The number of the light to be switched; they start with 1
     Serial.print("Number of the light --> ");
     Serial.println(numberOfTheLight);
-
-    StaticJsonBuffer<200> jsonBuffer;
-    JsonObject& root = jsonBuffer.parseObject(( char*) HTTP.arg("plain").c_str());
-    if (!root.success()) {
-      Serial.println("parseObject() failed");
-      return;
-    }
-    bool onValue = root["on"];
+    aJsonObject* parsedRoot = aJson.parse(( char*) HTTP.arg("plain").c_str());
+    aJsonObject* onState = aJson.getObjectItem(parsedRoot, "on");
+    bool onValue = onState->valuebool;
+    aJson.deleteItem(parsedRoot);
     Serial.print("I should --> ");
     Serial.println(onValue);
     // define the effect to apply, in this case linear blend
     HslColor originalColor = strip.GetPixelColor(numberOfTheLight);
-
     if (onValue == true)
     {
       AnimUpdateCallback animUpdate = [ = ](float progress)
@@ -133,7 +144,7 @@
       };
       animator.StartAnimation(numberOfTheLight, transitionTime, animUpdate);
     }
-    if (onValue == false)
+    else
     {
       AnimUpdateCallback animUpdate = [ = ](float progress)
       {
@@ -144,13 +155,10 @@
       animator.StartAnimation(numberOfTheLight, transitionTime, animUpdate);
     }

-    JsonObject& lightJson = jsonBuffer.createObject();
-    addLightJson(lightJson, numberOfTheLight);
-    // lightJson.printTo(HTTP.client()); // FIXME: Why is this not working? Gives "no matching function for call to 'ArduinoJson::JsonObject::printTo(WiFiClient)'"
-    char buffer[256];
-    lightJson.printTo(buffer, sizeof(buffer));
-    HTTP.send(200, "text/plain", buffer);
-    Serial.println(buffer);
+    aJsonObject *root;
+    root = aJson.createObject();
+    addLightJson(root, numberOfTheLight);
+    sendJson(root);
   }

   else if (requestedUri == "/description.xml")
@@ -296,61 +304,62 @@
   return LocalIP;
 }

-void addConfigJson(JsonObject& root)
-{
-  root["name"] = "Philips hue";
-  root["swversion"] = "01005215";
-  root["portalservices"] = false;
-  root["zigbeechannel"] = "0"; // As per spec, 0 is allowed
-  root["mac"] = macString.c_str();
-  root["dhcp"] = "true";
-  root["ipaddress"] = ipString.c_str();
-  root["netmask"] = "255.255.255.0"; // TODO: FIXME
-  root["gateway"] = "192.168.0.1"; // TODO: FIXME
-  root["proxyaddress"] = "";
-  root["proxyport"] = 0;
-  root["UTC"] = "2012-10-29T12:05:00";
-  JsonObject& whitelist = root.createNestedObject("whitelist");
-  JsonObject& whitelistFirstEntry = whitelist.createNestedObject("e7x4kuCaC8h885jo"); // FIXME: Do not hardcode e7x4kuCaC8h885jo
-  whitelistFirstEntry["name"] = "clientname#devicename";
-  whitelistFirstEntry["last use date"] = "2015-07-05T16:48:18";
-  whitelistFirstEntry["create date"] = "2015-07-05T16:48:17";
-  JsonObject& swupdate = root.createNestedObject("swupdate");
-  swupdate["text"] = "";
-  swupdate["notify"] = false;
-  swupdate["updatestate"] = 0;
-  swupdate["url"] = "";
-}
-
-void addLightJson(JsonObject& root, int numberOfTheLight)
+void addConfigJson(aJsonObject *root)
+{
+  aJson.addStringToObject(root, "name", "Philips hue");
+  aJson.addStringToObject(root, "swversion", "01005215");
+  aJson.addBooleanToObject(root, "portalservices", false);
+  aJson.addStringToObject(root, "zigbeechannel", "0"); // As per spec, 0 is allowed
+  aJson.addStringToObject(root, "mac", macString.c_str());
+  aJson.addBooleanToObject(root, "dhcp", true);
+  aJson.addStringToObject(root, "ipaddress", ipString.c_str());
+  aJson.addStringToObject(root, "netmask", "255.255.255.0"); // TODO: FIXME
+  aJson.addStringToObject(root, "gateway", "192.168.0.1"); // TODO: FIXME
+  aJson.addStringToObject(root, "proxyaddress", "");
+  aJson.addNumberToObject(root, "proxyport", 0);
+  aJson.addStringToObject(root, "UTC", "2012-10-29T12:05:00");
+  aJsonObject *whitelist;
+  aJson.addItemToObject(root, "whitelist", whitelist = aJson.createObject());
+  aJsonObject *whitelistFirstEntry;
+  aJson.addItemToObject(whitelist, "e7x4kuCaC8h885jo", whitelistFirstEntry = aJson.createObject()); // FIXME: Do not hardcode e7x4kuCaC8h885jo
+  aJson.addStringToObject(whitelistFirstEntry, "name", "clientname#devicename");
+  aJson.addStringToObject(whitelistFirstEntry, "last use date", "2015-07-05T16:48:18");
+  aJson.addStringToObject(whitelistFirstEntry, "create date", "2015-07-05T16:48:17");
+  aJsonObject *swupdate;
+  aJson.addItemToObject(root, "swupdate", swupdate = aJson.createObject());
+  aJson.addStringToObject(swupdate, "text", "");
+  aJson.addBooleanToObject(swupdate, "notify", false);
+  aJson.addNumberToObject(swupdate, "updatestate", 0);
+  aJson.addStringToObject(swupdate, "url", "");
+}
+
+void addLightJson(aJsonObject* root, int numberOfTheLight)
 {
   String lightName = "" + (String) numberOfTheLight;
-  JsonObject& light = root.createNestedObject(lightName.c_str());
-  light["type"] = "Extended color light";
-  light["name"] =  ("Hue Lamp " + (String) numberOfTheLight).c_str();
-  light["modelid"] = "LCT001";
-  JsonObject& state = light.createNestedObject("state");
+  aJsonObject *light;
+  aJson.addItemToObject(root, lightName.c_str(), light = aJson.createObject());
+  aJson.addStringToObject(light, "type", "Extended color light");
+  aJson.addStringToObject(light, "name",  ("Hue Lamp " + (String) numberOfTheLight).c_str());
+  aJson.addStringToObject(light, "modelid", "LCT001");
+  aJsonObject *state;
+  aJson.addItemToObject(light, "state", state = aJson.createObject());
   unsigned int brightness = strip.GetPixelColor(numberOfTheLight - 1).CalculateBrightness();
   if (brightness == 0)
   {
-    state["on"] = false;
+    aJson.addBooleanToObject(state, "on", false);
   }
   else
   {
-    state["on"] = true;
-  }
-  state["bri"] = 254; // Can be 0-255 but should be 1-254 according to Philips API (why?)
-  state["hue"] = 0; // Should between 0 and 65535. Both 0 and 65535 are red, 25500 is green and 46920 is blue.
-  state["sat"] = 0;
-  JsonArray& array = state.createNestedArray("xy");
-  array.add(0.0);
-  array.add(0.0);
-  state["alert"] = "none";
-  state["effect"] = "none";
-  state["colormode"] = "hs";
-  state["reachable"] = true;
-
-}
-
-
-
+    aJson.addBooleanToObject(state, "on", true);
+  }
+  aJson.addNumberToObject(state, "bri", 254); // Should be 1-254 according to Philips API
+  aJson.addNumberToObject(state, "hue", 0); // Should between 0 and 65535. Both 0 and 65535 are red, 25500 is green and 46920 is blue
+  aJson.addNumberToObject(state, "sat", 0);
+  double numbers[2] = {0.0, 0.0};
+  aJson.addItemToObject(state, "xy", aJson.createFloatArray(numbers, 2));
+  aJson.addStringToObject(state, "alert", "none");
+  aJson.addStringToObject(state, "effect", "none");
+  aJson.addStringToObject(state, "colormode", "hs");
+  aJson.addBooleanToObject(state, "reachable", true);
+
+}


next stage of refactor - making up crap as I go along

--- sketches/meowshoes.ino
+++ sketches/meowshoes.ino
@@ -56,6 +56,34 @@
     leftHeelVal  = analogRead(leftHeelPin);
     rightToeVal  = analogRead(rightToePin);
     rightHeelVal = analogRead(rightHeelPin);
+
+    /*
+     * maybe I can make each foot an object and just check the left & right foot on loop
+     * like one function to check each foot to see what's being pressed and whether to send a tap
+     * this is probably going to have to write to a custom low energy bluetooth service hmm
+     * maybe for example:
+     *
+     * {
+     *   'pins'  :  [0,1],
+     *   'parts' :  ['toe', 'heel']
+     * }
+     *
+     * this should then be all that's required:
+     * Foot leftFoot  = new Foot([0,1]);
+     * Foot rightFoot = new Foot([2,3]);
+     *
+     * uint leftTap  = leftFoot.checkTap();
+     * uint rightTap = rightFoot.checkTap();
+     *
+     * if (leftTap > -1)
+     *   sendTap(leftTap);
+     *
+     * if (rightTap > -1)
+     *   sendTap(rightTap);
+     *
+     * this might just work ya know
+     *
+     */

     // if tap is already pending, and the tap lasted for at least 300 milliseconds
     if ((pendingTapLeft != -1) && (tapTimeoutLeftToe >= tapTimeoutThresh)) {


adding automatic alarm re-trigger. Also allowing alarm and time edit transition from SHOW_TEMP state

--- src/elm_clk.ino
+++ src/elm_clk.ino
@@ -1,3 +1,4 @@
+
 #include <DallasTemperature.h>
 #include <MCP79412RTC.h>
 #include <OneButton.h>
@@ -50,9 +51,9 @@
 #define SHOW_ALARM_MODE 4
 #define ERROR_MODE      5

-#define SHOW_TIME_DURATION    7000
-#define SHOW_TEMP_DURATION    3000
-#define ALARM_CLEAR_DURATION 60001
+#define SHOW_TIME_DURATION 7000
+#define SHOW_TEMP_DURATION 3000
+#define ONE_MINUTE         60000

 // ---------------------- //
 //  Alarm variables
@@ -88,6 +89,7 @@
 unsigned long updateInterval    = 100;
 unsigned long lastTempRead      = 0;
 unsigned long lastClockRead     = 0;
+unsigned long lastAlarmTrigger  = 0;
 unsigned long lastShowTimeStart = 0;
 unsigned long lastShowTempStart = 0;

@@ -146,6 +148,7 @@
 	fsmState    = SHOW_TIME_MODE;
 	disableRtcAlarm();
 	notePosition = 0;
+	lastAlarmTrigger = millis();
 }

 byte isRtcAlarmOn()
@@ -322,6 +325,7 @@
 			break;

 		case SHOW_TIME_MODE:
+		case SHOW_TEMP_MODE:
 			fsmState = EDIT_TIME_MODE;
 			break;

@@ -373,6 +377,7 @@
   			break;

 		case SHOW_TIME_MODE:
+		case SHOW_TEMP_MODE:
 			fsmState = EDIT_ALARM_MODE;
 			break;

@@ -438,7 +443,7 @@

 	// If alarm condition is detected, modify FSM state accordingly
 	// When an alarm is triggered, the alarm pin is pulled low.
-	//if (RTC.alarm(ALARM_0) && RTC.alarm(ALARM_1) && !alarmTriggeredToday)
+	// if (RTC.alarm(ALARM_0) && RTC.alarm(ALARM_1) && !alarmTriggeredToday)
 	if (RTC.alarm(ALARM_0) && RTC.alarm(ALARM_1))
 	{
 		oldFsmState = fsmState;
@@ -446,6 +451,15 @@
 		updateTime();
 		display.enableClockDisplay();
 		fsmState    = SHOW_ALARM_MODE;
+	}
+
+	// After an alarm is cleared by the user, wait for a minute
+	// and re-enable the alarm to provide for repeatable alarms
+	// everyday without user intervention.
+	if ((millis() - lastAlarmTrigger) > ONE_MINUTE && lastAlarmTrigger)
+	{
+		enableRtcAlarm();
+		lastAlarmTrigger = 0;
 	}

 	switch (fsmState)


add comment

add comment

--- examples/firmware_check/firmware_check.ino
+++ examples/firmware_check/firmware_check.ino
@@ -54,6 +54,9 @@

 void loop() {} // nothing to do

+/**
+* Helper to print MFRC522 module info
+*/
 void ShowReaderDetails() {
   // Get the MFRC522 firmware version
   byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);


upd firmware_check example

upd firmware_check example

--- examples/firmware_check/firmware_check.ino
+++ examples/firmware_check/firmware_check.ino
@@ -1,4 +1,6 @@
 /*
+ * ----------------------------------------------------------------------------
+ * Example sketch/program to test your firmware.
  * ----------------------------------------------------------------------------
  * This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid
  * for further details and other examples.
@@ -7,8 +9,6 @@
  * documented in MFRC522.cpp. Please read it.
  *
  * Released into the public domain.
- * ----------------------------------------------------------------------------
- * Example sketch/program showing how to test your firmware.
  *
  * Typical pin layout used:
  * -----------------------------------------------------------------------------------------
@@ -21,6 +21,8 @@
  * SPI MOSI    MOSI         11 / ICSP-4   51        D11        ICSP-4           16
  * SPI MISO    MISO         12 / ICSP-1   50        D12        ICSP-1           14
  * SPI SCK     SCK          13 / ICSP-3   52        D13        ICSP-3           15
+ *
+ * @author Rotzbua
  */

 #include <SPI.h>
@@ -40,7 +42,7 @@
   Serial.println(F("*****************************"));
   Serial.println(F("MFRC522 Digital self test"));
   Serial.println(F("*****************************"));
-  ShowReaderDetails();  // Show details of PCD - MFRC522 Card Reader details
+  ShowReaderVersion();  // Show version of PCD - MFRC522 Card Reader
   Serial.println(F("Performing test..."));
   bool result = mfrc522.PCD_PerformSelfTest();
   Serial.println(F("-----------------------------"));
@@ -48,7 +50,7 @@
   if (result)
     Serial.println(F("OK"));
   else
-    Serial.println(F("defect or unknown"));
+    Serial.println(F("DEFECT or UNKNOWN"));
   Serial.println();
 }

@@ -57,12 +59,14 @@
 /**
 * Helper to print MFRC522 module info
 */
-void ShowReaderDetails() {
+void ShowReaderVersion() {
   // Get the MFRC522 firmware version
   byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
   Serial.print(F("Firmware Version: 0x"));
   Serial.print(v, HEX);
-  if (v == 0x90)
+  if (v == 0x88)
+    Serial.print(F(" = (clone)"));
+  else if (v == 0x90)
     Serial.print(F(" = v0.0"));
   else if (v == 0x91)
     Serial.print(F(" = v1.0"));


Humidity tweaks and temperature added

Humidity tweaks and temperature added

Tweaked humidity to read a bit faster but use more samples. Added
temperature based on Vishay thermistor using datasheet values for the
temperature formula.

--- Arduino_Climate_Node/Arduino_Climate_Node.ino
+++ Arduino_Climate_Node/Arduino_Climate_Node.ino
@@ -1,19 +1,28 @@
 // Arduino Climate Monitor Node
 // 30Aug2014
 // Adam Green (ndsoccer11122@yahoo.com)
+
+//humidity code credit to dpotthast from arduino forums
+//temp code credit to Milan Malesevic and Zoran Stupid from arduino playground

 // HCH-1000 Humidity Sensor
 // 10Mohm R1
 // 220ohm R2

+#include <math.h>
+#define Vishay_10K_Therm 4977.0f,298.15f,10000.0f //define thermistor B,To,R
+
+
 int HumSensorPin = 4;
+int TempSensorPin = 0;
+float TempBalanceR = 10000;

 long HumResult = 0;
 unsigned long HumTime1=0;
 unsigned long HumTime2=0;

 long HumReadingsPer=30.0;
-long HumReadDelay=200.0;
+long HumReadDelay=50.0;

 void setup()                    // run once, when the sketch starts
 {
@@ -24,7 +33,11 @@
 void loop()                     // run over and over again
 {
   long H=evalHumid(HumReadingsPer, HumSensorPin);
+  long TempValue = Temperature(TempSensorPin,Vishay_10K_Therm,TempBalanceR);
   Serial.println("_____");
+  Serial.println("Temperature");
+  Serial.println(TempValue);
+  Serial.println("Humidity");
   Serial.println(H);
   Serial.println("_____");
   delay(100);
@@ -55,18 +68,27 @@
     //result++;
   }
   decayTime(2);
-  delay(readDelay);
+  delay(HumReadDelay);
   //return result;                   // report results
 }

 long decayTime(int input){
   if (input==1){
-    time1=micros();
+    HumTime1=micros();
   }
   if (input==2 ){
-    time2=micros();
+    HumTime2=micros();
   }
   if (input==3){
-    return (time2-time1);
+    return (HumTime2-HumTime1);
   }
 }
+
+float Temperature(int AnalogInputNumber,float B,float T0,float R0,float R_Balance)
+{
+  float R,T;
+  R=R_Balance*(1024.0f/float(analogRead(AnalogInputNumber))-1);
+  T=1.0f/(1.0f/T0+(1.0f/B)*log(R/R0));
+  T=9.0f*(T-273.15f)/5.0f+32.0f;
+  return T;
+}


Renamed smoothInput() to roundInput() Added RC_ROUNDING_BASE factor for roundInput() function

--- quadcopter/quadcopter.ino
+++ quadcopter/quadcopter.ino
@@ -50,14 +50,15 @@
 #define RC_LOW_CH4 2000
 #define RC_HIGH_CH5 1000
 #define RC_LOW_CH5 2000
+#define RC_ROUNDING_BASE 50

 /*  PID configuration
  *
  */

-#define PITCH_P_VAL 2.0
-#define PITCH_I_VAL 0.03
-#define PITCH_D_VAL 13.0
+#define PITCH_P_VAL 2
+#define PITCH_I_VAL 5
+#define PITCH_D_VAL 1

 #define ROLL_P_VAL 2
 #define ROLL_I_VAL 5
@@ -78,8 +79,8 @@
 #define ROLL_MAX 30
 #define YAW_MIN -180
 #define YAW_MAX 180
-#define PID_PITCH_INFLUENCE 20
-#define PID_ROLL_INFLUENCE 20
+#define PID_PITCH_INFLUENCE 50
+#define PID_ROLL_INFLUENCE 50
 #define PID_YAW_INFLUENCE 20

@@ -119,13 +120,13 @@
  *
  */

-int velocity;                         // global velocity
+int velocity;                          // global velocity

 float bal_ac, bal_bd;                 // motor balances can vary between -100 & 100
 float bal_axes;                       // throttle balance between axes -100:ac , +100:bd

-int va, vb, vc, vd;                   //velocities
-int v_ac, v_bd;                       // velocity of axes
+int va, vb, vc, vd;                    //velocities
+int v_ac, v_bd;                        // velocity of axes

 Servo a,b,c,d;

@@ -193,9 +194,9 @@
  */

 void computePID(){
-
-  smoothInput();
-
+
+  roundInput();
+
   ch2 = map(ch2, RC_LOW_CH2, RC_HIGH_CH2, PITCH_MIN, PITCH_MAX);
   ch1 = map(ch1, RC_LOW_CH1, RC_HIGH_CH1, ROLL_MIN, ROLL_MAX);
   ch4 = map(ch4, RC_LOW_CH4, RC_HIGH_CH4, YAW_MIN, YAW_MAX);
@@ -208,15 +209,23 @@
   ch2Last = ch2;
   ch4Last = ch4;

-  Serial.println(ch2);
-
   ypr[0] = ypr[0] * 180/M_PI;
   ypr[1] = ypr[1] * 180/M_PI;
   ypr[2] = ypr[2] * 180/M_PI;

-  pitchReg.Compute();
+  Serial.print("CH2:\t");
+  Serial.print(ch2);
+  Serial.print("\tPITCH:\t");
+  Serial.print(ypr[1]);
+
+  bool test = pitchReg.Compute();
   rollReg.Compute();
   yawReg.Compute();
+
+  Serial.print("\tBAL_BD:\t");
+  Serial.print(bal_bd);
+  Serial.print("\tNEW PID?\t");
+  Serial.println(test);

 }

@@ -258,14 +267,14 @@
  *  filters the rc input
  */

-void smoothInput(){
-
-  ch1 = floor(ch1/100)*100;
-  ch2 = floor(ch2/100)*100;
-  ch3 = floor(ch3/100)*100;
-  ch4 = floor(ch4/100)*100;
-  ch5 = floor(ch5/100)*100;
-
+void roundInput(){
+
+  ch1 = floor(ch1/RC_ROUNDING_BASE)*RC_ROUNDING_BASE;
+  ch2 = floor(ch2/RC_ROUNDING_BASE)*RC_ROUNDING_BASE;
+  ch3 = floor(ch3/RC_ROUNDING_BASE)*RC_ROUNDING_BASE;
+  ch4 = floor(ch4/RC_ROUNDING_BASE)*RC_ROUNDING_BASE;
+  ch5 = floor(ch5/RC_ROUNDING_BASE)*RC_ROUNDING_BASE;
+
 }

 /*  calculateVelocities function


Renvoie enfin la position en cm de l'object. Fonction en cours

--- Pince/Capteur_IR_detection_position/Capteur_IR_detection_position/Capteur_IR_detection_position.ino
+++ Pince/Capteur_IR_detection_position/Capteur_IR_detection_position/Capteur_IR_detection_position.ino
@@ -21,23 +21,20 @@

 int pin_capteur = A0;                   //
-int pin_LED = 13;                       // LED branchée a la pin 13
-int c;
+float c;
 float d;

 void setup() {
-  pinMode(pin_LED,OUTPUT);
   Serial.begin(9600);
 }

 void loop() {
-  Serial.println(analogRead(pin_capteur));
+  //Serial.println(analogRead(pin_capteur));

-    Serial.println("Present alors stop");
-    digitalWrite(pin_LED, HIGH);       // présence donc la led s'allume
     c=analogRead(pin_capteur);
-    d=exp((c-740)/-198);
+    Serial.println(c);
+    d=exp((c-740)/(-198));
     Serial.println("Distance : ");
     Serial.print(d);
     Serial.print("cm");
@@ -47,5 +44,5 @@

-  delay(50);
+  delay(500);
 }


More bugfixes for changeReadMotorsStatus()

--- ps2_controller/ps2_controller.ino
+++ ps2_controller/ps2_controller.ino
@@ -310,6 +310,7 @@
   calculatePong();
   getAttention();
   readMotors();
+  manualResetControllerData();

   serial_rx_buffer_change_motors_status[0] = 0x0F;
   serial_rx_buffer_change_motors_status[1] = 0x00;
@@ -497,7 +498,6 @@
   calculatePong();
   getAttention();
   autoResetControllerData();
-  //changeReadMotorsStatus();
 } // Close Loop Function

 void changeReadMotorsStatus() {


remove old code

remove old code

--- robots/maproom/maproom.ino
+++ robots/maproom/maproom.ino
@@ -22,23 +22,11 @@
 #define BUF_SIZE 125
 #define BUF_VAL_WIDTH 6

-typedef struct {
-  int pulse;
-  bool direction;
-
-  float current;
-  float target;
-} MotorValues;
-
-MotorValues motorA;
-MotorValues motorB;
-MotorValues motorC;
-
-Robot robot;
-
 char buf[BUF_SIZE];
 int bufLen;
 bool bufDone;
+
+Robot robot;

 void setup() {
   robot = Robot(ROBOT_ID, dirA, pwmA, dirB, pwmB, dirC, pwmC, LOGGING);


UltraSonic Sensor

UltraSonic Sensor

Changed the Code for the Arduino to send the right amount of bytes to
let the Rapsberry pi function correcty

--- Testing_Arduino101_2/Testing_Arduino101_2.ino
+++ Testing_Arduino101_2/Testing_Arduino101_2.ino
@@ -45,7 +45,7 @@
                                     ROBOT LAYOUT LEVEL 1

                                         BACK
-                                        Sensor 0 Ard 1
+                                        SENSOR 1 ARD 1
                       -------------------------------------------
                      |                                           |
                      |    BUTTON 2    BUTTON 1      ARD 1        |
@@ -54,7 +54,7 @@
                      |                                           |
                      |                                           |
          RIGHT       |                                           |    LEFT
-     SENSOR 1,ARD 2  |                                           |    SENSOR 1, ARD 1
+     SENSOR 2,ARD 2  |                                           |    SENSOR 2, ARD 1
           SERVO      |                                           |    SERVO
                      |                                           |
                      |    ARD 2                    RASPBERRY     |
@@ -63,7 +63,7 @@
                      |                                           |
                       -------------------------------------------
                                         FRONT
-                                        Sensor 0 Ard 2
+                                        SENSOR 1 ARD 2

@@ -110,7 +110,7 @@
 int stop_button = 10;
 int command_status = 1;
 int motor_speed[2];
-
+int ultrasonic1 = 0, ultrasonic2 = 0;

 //-------------------FUNCTIONs----------------
 void stop_motor_ALL(){
@@ -157,7 +157,6 @@

     analogWrite(AMOTOR, motor_speed[0]);
     analogWrite(BMOTOR, motor_speed[1]);
-
 }
 void move_reverse(){
     digitalWrite(DIR_A, LOW);
@@ -213,15 +212,24 @@

 void us_sensor(){
   delay(50);
-
-  Serial.print("Sensor 1: ");
-  Serial.print(sonar1.ping_cm());
-
-  Serial.print("Sensor 2: ");
-  Serial.print(sonar2.ping_cm());
+
+  ultrasonic1 = sonar1.ping_cm();
+  ultrasonic2 = sonar2.ping_cm();
+
+  if(ultrasonic1 < 20){
+        Serial.print("1");
+  }
+  else
+        Serial.print("0");
+
+  Serial.print("-");
+  if(ultrasonic2 < 20){
+        Serial.print("1");
+  }
+  else
+        Serial.print("0");
+
   Serial.print("\n");
-
-
   delay(50);

 }
@@ -238,7 +246,7 @@
 //------------------CODEs---------------------
 void setup() {
         Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
-
+
         myservo.attach(5);

         enableInterrupt(stop_button, stop_motor_ALL , CHANGE);
@@ -279,7 +287,6 @@
           switch(input){

             case 'w':
-
               if(command_status == 1){
                 //move_forward();
                 variable_forward();


working prototype of IMU with I2C/Serial output

--- Arduino/sketches/Sensor_Module_IMU/Sensor_Module_IMU.ino
+++ Arduino/sketches/Sensor_Module_IMU/Sensor_Module_IMU.ino
@@ -1,26 +1,217 @@
-#include <avr/eeprom.h>
-
-static uint16_t calibratingG;
-static int16_t  gyroADC[3],accADC[3],accSmooth[3],magADC[3];
-static int16_t gyroZero[3] = {0,0,0};
-static uint16_t acc_1G;             // this is the 1G measured acceleration
-static uint16_t calibratingA = 0;  // the calibration is done in the main loop. Calibrating decreases at each cycle down to 0, then we enter in a normal mode.
-static int16_t  acc_25deg;
-
+#include <avr/eeprom.h>       //libray required for eeprom I/O
+//#include "Adafruit_GFX.h"
+#include "Adafruit_SSD1306.h" //libray required for I2C display
+
+#include <SPI.h>             //libray required for I2C display
+#include "includes/tuskalogo.h"        //holds binary bitmap for tuska logo
+
+#define OLED_RESET 4                  // for i2c display
+Adafruit_SSD1306 display(OLED_RESET); //display class for I2C display
+
+static uint16_t calibratingG;         //used for initializing Acc calibration
+static int16_t  gyroADC[3],accADC[3],accSmooth[3]; // RawGyroData,RawAccData,LPAccData
+
+static long calSum;                   //used for gyro calibration
+static float gyroZero[3] = {0,0,0};   //stores values for gyro calibration
+static long pTime = 0;                // variable for determining dt of integration, it will overflow at approx 70min
+static float deltaGyroAngle[3] = {0,0,0}; //holds dø in degrees
+static float angleSum[3]; // unusued variable for debug remove later
+
+static uint16_t acc_1G;               // this is the 1G measured acceleration
+static uint16_t calibratingA = 0;     // the calibration is done in the main loop. Calibrating decreases at each cycle down to 0, then we enter in a normal mode.
+static int16_t  acc_25deg;            // not sure what it is yet but we need it something to do with small angle estimations.
+static float accelFloat[3] = {0,0,0};             // Converting int AccData to float AccData
+static float accLPF[3];               // for Acc lowpass implementation
+
+static float pitchAngle = 0;          // variable for final IMU pitch angle in deg
+static float rollAngle = 0;           // variable for final IMU roll angle in deg
+static float accVectorMagnitude = 0;
+
+static float loopRate = 0;            //used for determining approx IMU sampling rate
+static short loopCount = 1;
+long prevTime = 0;
+
+byte axis = 0;                        // used in for loops for array index
+
+
+#define PI 3.14159265         // approx of Pi which program uses.
+#define dt 10000              // dt in micros seconds
+#define GYROSCALE ((2380 * PI)/((32767.0f / 4.0f ) * 180.0f * 1000000.0f)) * 0.85 // A constant which converts raw data units to radians, determined experimentally
+#define RADTODEG  57.2957795  //constant for converting radians to degrees
+//#define ACC_LPF_FACTOR 50   //magnitude of Acc data lowpass, filtering increases Acc lag
+#define GYROWEIGHT 0.99       // weight of gyro in complementart filter, out of 1
+#define SCREENREFRESH 60      // screen refresh rate in Hz, increasing too much will lag IMU
+static float *pitch, *roll;

 // ************************************************************************************************************
 // Main Program
 // ************************************************************************************************************
 void setup()
 {
-  initSensors();
+  initSensors();        //initilizes sensors for sepecifics see Sensors.ino
+  delay(100);
+  Serial.begin(115200); //initilize serial communication with 115200 baudrate
+
+  displayInit();        //initilizes I2C display and displays logo see more detail in helper functions
+
+  for(axis = 0; axis < 3; axis++) //calculate offsets to zeros gyros
+  {
+	  for(int i = 0; i < 400; i++) //averages 400 readings for each axis
+	  {
+	  	Gyro_getADC();
+	  	calSum += gyroADC[axis];
+      delayMicroseconds(650);
+	  }
+	  gyroZero[axis] = calSum/400.f;
+	  calSum = 0;
+  }
+
+  delay(1000); // so people can see sick logo ;)
+  display.clearDisplay();
+  display.display();
 }

 void loop()
 {
-	ACC_getADC();
-	Gyro_getADC();
+  Gyro_getADC(); // read raw gyro data
+  ACC_getADC(); // read raw accel data
+
+  for(axis = 0; axis < 3; axis++)
+    accelFloat[axis]=accADC[axis]; // raw data from int array to float array also give the option to filter if necessary
+
+    static uint16_t previousT;
+    uint16_t currentT = micros(); // set current time
+    float scale, deltaGyroAngle[3];
+
+    scale = (currentT - previousT) * GYROSCALE; // scalar for raw data GYROSCALE converts raw data to rad/sec then * dt
+    previousT = currentT;
+
+    for (axis = 0; axis < 3; axis++){
+        deltaGyroAngle[axis] = (gyroADC[axis])  * scale * RADTODEG; // (dø/dt - calibration) * dt * constatnt
+      }
+
+    angleSum[0] += deltaGyroAngle[0]; // for debug remove!!!!!!!!!!!!!
+
+    pitchAngle += deltaGyroAngle[0]; //riemann sum
+    rollAngle -= deltaGyroAngle[1]; //riemann sum
+
+
+    float pitchAccel = atan2(accelFloat[1],accelFloat[2]) * RADTODEG; // determine the pitch of Acc vector using atan2 function
+    float rollAccel = atan2(accelFloat[0],accelFloat[2]) * RADTODEG;  // determine the roll of Acc vector using atan2 function
+
+    accVectorMagnitude = sqrt(pow(accADC[0],2) + pow(accADC[1],2) + pow(accADC[2],2))/495.f; // calc of of Acc vector magnitude, could be simplified
+
+    if(accVectorMagnitude < 1.3 && accVectorMagnitude > 0.7) // if !bullshit Acc vector must be <1.3g && >0.7g
+    {
+      pitchAngle = pitchAngle * GYROWEIGHT + pitchAccel * (1 - GYROWEIGHT); // complementary filter
+      rollAngle = rollAngle * GYROWEIGHT + rollAccel * (1 - GYROWEIGHT);    // complementary filter
+    }
+
+    else // for debuging purposes only triggered if Acc magnitude is out of bounds
+    {
+      Serial.print("THROWOUT!!!!!!!!!!!!!!!!!!!!!!!!!!");
+      Serial.print("\t\t");
+      display.drawFastHLine(0,10,30,1);
+    }
+
+    serialPrintDebug(pitchAccel); //prints to Serial for debug
+
+    if(micros() - prevTime >= (1000000/SCREENREFRESH))  // function for refreshing screen
+    {
+      loopRate = loopCount/(1.f/SCREENREFRESH);
+      loopCount = 1;
+      writeOLED();
+      prevTime = micros();
+    }
+    loopCount++;
+
 }
 // ************************************************************************************************************
 // Helper Functions
-// ************************************************************************************************************+// ************************************************************************************************************
+
+int16_t _atan2(float y, float x){
+  #define fp_is_neg(val) ((((uint8_t*)&val)[3] & 0x80) != 0)
+  float z = y / x;
+  int16_t zi = abs(int16_t(z * 100));
+  int8_t y_neg = fp_is_neg(y);
+  if ( zi < 100 ){
+    if (zi > 10)
+     z = z / (1.0f + 0.28f * z * z);
+   if (fp_is_neg(x)) {
+     if (y_neg) z -= PI;
+     else z += PI;
+   }
+  } else {
+   z = (PI / 2.0f) - z / (z * z + 0.28f);
+   if (y_neg) z -= PI;
+  }
+  z *= (180.0f / PI * 10);
+  return z;
+}
+
+void writeOLED() // function that creates OLED display
+{
+  display.drawCircle(64,32,30,1);
+
+  int xCord = (30 * cos(rollAngle/RADTODEG));   // for drawing horizon line
+  int yCord = (30 * sin(rollAngle/RADTODEG));   // for drawing horizon line
+  int yHud  = map(pitchAngle,-100,100,-30,30);  // for y postion of pitch indicator
+
+  display.drawLine(64,32,64 - xCord,32 + yCord,1); // draws half of horizon line
+  display.drawLine(64,32,64 + xCord,32 - yCord,1); // draws other half of horizon line
+  display.drawFastHLine(59,32 - yHud ,10,1);       // draws horizontal line for pitch indicator
+
+  display.setCursor(90,0);            //displays pitchAngle top right
+  display.println(pitchAngle);
+
+  display.setCursor(92,50);           //displays IMU sampling estimation bottom right
+  display.print(loopRate,0);
+  display.println("Hz");
+
+  display.setCursor(0,50);            //displays roll angle bottom left
+  display.println(-rollAngle);
+
+  display.setCursor(0,0);             //displays Acc Vector Magnitude top left
+  display.print(accVectorMagnitude);
+  display.println("g");
+
+  display.display();                  //call for display
+  display.clearDisplay();             //clears buffer for next display
+}
+
+void displayInit()
+{
+  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //init I2C display with adress 0x3C
+
+  display.setTextColor(1); //settings for printing text
+  display.setTextSize(1);
+  display.setTextWrap(0);
+
+  display.clearDisplay();
+  display.drawBitmap(0,17,tuskalogo,127,34,1); //displays beautiful tuska logo
+  display.display();
+}
+
+void serialPrintDebug(float pitchAccel)
+{
+if(Serial.available() > 0)
+      {
+        angleSum[0] = 0;
+        angleSum[1] = 0;
+        angleSum[2] = 0;
+        Serial.read();
+      }
+
+      Serial.print(pitchAngle);
+      Serial.print("\t\t");
+      Serial.print(deltaGyroAngle[0]);
+      Serial.print("\t\t");
+      Serial.print(pitchAccel);
+      Serial.print("\t\t");
+      Serial.print(pitchAngle);
+      Serial.print("\t\t");
+      Serial.println(rollAngle);
+      //Serial.println(accVectorMagnitude);
+
+}


Updated Google numeric address in WifiWebClient

--- WiFi/examples/WifiWebClient/WifiWebClient.ino
+++ WiFi/examples/WifiWebClient/WifiWebClient.ino
@@ -26,10 +26,12 @@

 char ssid[] = "YourNetwork"; //  your network SSID (name)
 char pass[] = "password";    // your network password (use for WPA, or use as key for WEP)
+
 int keyIndex = 0;            // your network key Index number (needed only for WEP)

 int status = WL_IDLE_STATUS;
-IPAddress server(173,194,43,18);  // Google
+IPAddress server(173,194,73,105);  // Google
+//char server[] = "www.google.com";

 // Initialize the Ethernet client library
 // with the IP address and port of the server


Update Counting_Button_Presses_while_LED_Lights_Up_Ver2.ino

--- Counting_Button_Presses_while_LED_Lights_Up_Ver2/Counting_Button_Presses_while_LED_Lights_Up_Ver2.ino
+++ Counting_Button_Presses_while_LED_Lights_Up_Ver2/Counting_Button_Presses_while_LED_Lights_Up_Ver2.ino
@@ -25,7 +25,7 @@
     if (buttonState == LOW){
       count = count + 1;
     }
-  }
+  } preButtonState = buttonState;
 } digitalWrite(ledPin, LOW);
   delay(10);


added calibration support

added calibration support

--- src-arduino/arduair-mega-wifi-shield-DS1307-allSensors/arduair-mega-wifi-shield-DS1307-allSensors.ino
+++ src-arduino/arduair-mega-wifi-shield-DS1307-allSensors/arduair-mega-wifi-shield-DS1307-allSensors.ino
@@ -75,6 +75,19 @@
 float p,h,t,l;
 float co,o3,so2,no2;
 unsigned int second, minute,hour,weekDay,monthDay,month,year;
+//calibration variables
+float pm10_x2=1, pm10_x1=1, pm10_b=0,
+      pm25_x2=1, pm25_x1=1, pm25_b=0,
+      co_x2=1,   co_x1=1,   co_b=0,
+      o3_x2=1,   o3_x1=1,   o3_b=0,
+      so2_x2=1,  so2_x1=1,  so2_b=0,
+      no2_x2=1,  no2_x1=1,  no2_b=0,
+      h_x1=1,  h_b=0,
+      p_x1=1,  p_b=0,
+      t_x1=1,  t_b=0,
+      l_x1=1,  l_b=0;
+
+
 /**
  * Arduair configuration initialization
  */
@@ -139,12 +152,16 @@
  if (client.connect(server, 80)) {
    #if defined(DEVMODE)
    Serial.println("connecting...");
-   Serial.print("GET "); Serial.print("/"); Serial.print(device); Serial.print("/"); Serial.print(password);
+   Serial.print("GET ");
+   Serial.print("/api");
+   Serial.print("/"); Serial.print(device); Serial.print("/"); Serial.print(password);
    Serial.print(monthDay); Serial.print(month);Serial.print(year); Serial.print(hour);Serial.print(minute);
    #endif
    //String getRequest ="GET"+"hola"+" "
    // send the HTTP GET request:
-   client.print("GET "); client.print("/"); client.print(device); client.print("/"); client.print(password);
+   client.print("GET ");
+   client.print("/api");
+   client.print("/"); client.print(device); client.print("/"); client.print(password);
    // HTTP time
    client.print(monthDay);client.print(month);client.print(year);client.print(hour);client.print(minute);
    //http GET end
@@ -163,7 +180,7 @@
    client.println("");
    //server
    client.print("Host: ");client.print(server);
-   client.println("User-Agent: Arduair");
+   //client.println("User-Agent: Arduair");
    client.println("Connection: close");
    client.println();
    #if defined(DEVMODE)
@@ -483,19 +500,19 @@
  * Meteorology read function
  */
 void meteorologyRead(){
-  p = pressureRead();
-  l = lightRead();
-  h = humidityRead();
-  t = temperatureRead();
-  #if defined(DEVMODE)
-  Serial.print("  p: ");
-  Serial.println(p);
-  Serial.print("  l: ");
-  Serial.println(l);
-  Serial.print("  h: ");
-  Serial.println(h);
-  Serial.print("  t: ");
-  Serial.println(t);
+  p = calibrate( pressureRead(),    0, p_x1, p_b);
+  l = calibrate( lightRead(),       0, l_x1, l_b);
+  h = calibrate( humidityRead(),    0, h_x1, h_b);
+  t = calibrate( temperatureRead(), 0, t_x1, t_b);
+  #if defined(DEVMODE)
+    Serial.print("  p: ");
+    Serial.println(p);
+    Serial.print("  l: ");
+    Serial.println(l);
+    Serial.print("  h: ");
+    Serial.println(h);
+    Serial.print("  t: ");
+    Serial.println(t);
   #endif
 }
 /**
@@ -605,6 +622,89 @@
   if (settingName=="second"){
     second=settingValue.toInt();
   }
+
+  if (settingName=="pm10_x2"){
+    pm10_x2=settingValue.toFloat();
+  }
+  if (settingName=="pm10_x1"){
+    pm10_x1=settingValue.toFloat();
+  }
+  if (settingName=="pm10_b"){
+    pm10_b=settingValue.toFloat();
+  }
+
+  if (settingName=="pm25_x2"){
+    pm25_x2=settingValue.toFloat();
+  }
+  if (settingName=="pm25_x1"){
+    pm25_x1=settingValue.toFloat();
+  }
+  if (settingName=="pm25_b"){
+    pm25_b=settingValue.toFloat();
+  }
+  if (settingName=="co_x2"){
+    co_x2=settingValue.toFloat();
+  }
+  if (settingName=="co_x1"){
+    co_x1=settingValue.toFloat();
+  }
+  if (settingName=="co_b"){
+    co_b=settingValue.toFloat();
+  }
+
+  if (settingName=="o3_x2"){
+    o3_x2=settingValue.toFloat();
+  }
+  if (settingName=="o3_x1"){
+    o3_x1=settingValue.toFloat();
+  }
+  if (settingName=="o3_b"){
+    o3_b=settingValue.toFloat();
+  }
+  if (settingName=="so2_x2"){
+    so2_x2=settingValue.toFloat();
+  }
+  if (settingName=="so2_x1"){
+    so2_x1=settingValue.toFloat();
+  }
+  if (settingName=="so2_b"){
+    so2_b=settingValue.toFloat();
+  }
+
+  if (settingName=="no2_x2"){
+    no2_x2=settingValue.toFloat();
+  }
+  if (settingName=="no2_x1"){
+    no2_x1=settingValue.toFloat();
+  }
+  if (settingName=="no2_b"){
+    no2_b=settingValue.toFloat();
+  }
+  if (settingName=="h_x1"){
+    h_x1=settingValue.toFloat();
+  }
+  if (settingName=="h_b"){
+    h_b=settingValue.toFloat();
+  }
+
+  if (settingName=="p_x1"){
+    p_x1=settingValue.toFloat();
+  }
+  if (settingName=="p_b"){
+    p_b=settingValue.toFloat();
+  }
+  if (settingName=="t_x1"){
+    t_x1=settingValue.toFloat();
+  }
+  if (settingName=="t_b"){
+    t_b=settingValue.toFloat();
+  }
+  if (settingName=="l_x1"){
+    l_x1=settingValue.toFloat();
+  }
+  if (settingName=="l_b"){
+    l_b=settingValue.toFloat();
+  }
  }

  // converting string to Float
@@ -719,7 +819,7 @@
         }
         if (measure[0]==0xff && measure[1]==0x86){
           ppm = measure[2]*256+measure[3];
-          co=ppm;
+          co=calibrate(ppm, co_x2, co_x1, co_b);
           #if defined(DEVMODE)
           Serial.print("  [CO]:  ");
           Serial.println(ppm);
@@ -741,7 +841,7 @@
         }
         if (measure[0]==0xff && measure[1]==0x86){
           ppm = measure[2]*256+measure[3];
-          no2=ppm;
+          no2==calibrate(ppm, no2_x2, no2_x1, no2_b);

           #if defined(DEVMODE)
           Serial.print("  [NO2]: ");
@@ -763,7 +863,7 @@
       }
       if (measure[0]==0xff && measure[1]==0x86){
         ppm = measure[2]*256+measure[3];
-        so2=ppm;
+        so2=calibrate(ppm, so2_x2, so2_x1, so2_b);

         #if defined(DEVMODE)
         Serial.print("  [SO2]: ");
@@ -793,7 +893,10 @@

     //String getRequest ="GET"+"hola"+" "
     // send the HTTP GET request:
-    client.print("GET "); client.print("/"); client.print(device); client.print("/"); client.print(password); client.print("/timezone"); client.print(" HTTP/1.1");
+    client.print("GET ");
+    client.print("/api");
+    client.print("/"); client.print(device);
+    client.print("/"); client.print(password); client.print("/timezone"); client.print(" HTTP/1.1");
     client.println("");
     // parameters:
     client.print("?z="); client.print(timezone); client.print(",");
@@ -828,9 +931,10 @@
   Serial.println(server);
   if (client.connect(server, 80)) {
     client.print("GET ");
+    client.print("/api");
     client.print("/"); client.print(device);
     client.print("/"); client.print(password);
-    client.print("/");
+    client.print("/config");
     //http GET end
     client.print(" HTTP/1.1");
     client.println("");
@@ -903,3 +1007,14 @@
 void warn(){
     digitalWrite(RED_LED_PIN,HIGH);
 }
+/**
+ * Calibrates the 'value' with the ecuation x^2*value+x*value+b
+ * @param  value value to be calibrated
+ * @param  x2    cuadratic param
+ * @param  x     linear param
+ * @param  b     constant param
+ * @return       calibrated value
+ */
+float calibrate(float value,float x2,float x,float b){
+  return value*x2*x2 + value*x + b;
+}