deploy ready

deploy ready

--- ESP8266/moisture_sensor.ino
+++ ESP8266/moisture_sensor.ino
@@ -1,145 +0,0 @@
-#include <ESP8266HTTPClient.h>
-#include <ESP8266WiFi.h>
-#include <WiFiUdp.h>
-#include <TimeLib.h>
-
-const char *ssid = "Orange-A67C";
-const char *pass = "33385907";
-
-const int AnalogIn  = A0;
-int readSensor;
-
-const char ntpServerName[] = "us.pool.ntp.org";
-const int timeZone = 2;
-
-WiFiUDP Udp;
-unsigned int localPort = 9876;
-time_t getNtpTime();
-void sendNTPpacket(IPAddress &address);
-
-HTTPClient http;
-
-void setup(){
-  pinMode(0, OUTPUT);
-
-  Serial.begin(115200);
-  Udp.begin(localPort);
-  Serial.print("Local port: ");
-  Serial.println(Udp.localPort());
-  Serial.println("waiting for sync");
-  setSyncProvider(getNtpTime);
-  setSyncInterval(300);
-
-  if(WiFi.status() != WL_CONNECTED) {
-    Serial.print(".");
-    delay(500);
-    WiFi.begin(ssid, pass);
-    if(WiFi.waitForConnectResult() != WL_CONNECTED) {
-      return;
-    }
-  }
-
-  if(WiFi.status() == WL_CONNECTED) {
-    Serial.println('WiFi connected');
-    delay(1000);
-
-  }
-}
-
-int timeBetweenPOST = 60*60*1000;
-time_t prevDisplay = 0;
-
-void loop() {
-  for(int cnt = 0; cnt <= 23; cnt++){
-    Serial.println(cnt);
-
-    readSensor = analogRead(AnalogIn);
-    Serial.println(readSensor);
-
-    prevDisplay = now();
-    int hours = hour();
-    Serial.println("hour");
-    Serial.println(hours);
-    Serial.println("");
-
-    http.begin("http://mintsensor.herokuapp.com/value/");
-    http.addHeader("content-type", "application/json");
-    char buffer[100];
-    char bufID[16];
-    char bufVal[16];
-    sprintf(bufID, "%d", hours);
-    sprintf(bufVal, "%d", readSensor);
-    strcat(buffer, "{\"value\": \"");
-    strcat(buffer, bufVal);
-    strcat(buffer, "\",\"id\":\"");
-    strcat(buffer, bufID);
-    strcat(buffer, "\"}");
-    Serial.println(buffer);
-
-    String postMsg = buffer;
-    int httpCode = http.POST(postMsg);
-    Serial.println(httpCode);
-    http.writeToStream(&Serial);
-    http.end();
-    delay(timeBetweenPOST);
-  }
-}
-
-/*-------- NTP code ----------*/
-
-const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
-byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
-
-time_t getNtpTime()
-{
-  IPAddress ntpServerIP; // NTP server's ip address
-
-  while (Udp.parsePacket() > 0) ; // discard any previously received packets
-  Serial.println("Transmit NTP Request");
-  // get a random server from the pool
-  WiFi.hostByName(ntpServerName, ntpServerIP);
-  Serial.print(ntpServerName);
-  Serial.print(": ");
-  Serial.println(ntpServerIP);
-  sendNTPpacket(ntpServerIP);
-  uint32_t beginWait = millis();
-  while (millis() - beginWait < 1500) {
-    int size = Udp.parsePacket();
-    if (size >= NTP_PACKET_SIZE) {
-      Serial.println("Receive NTP Response");
-      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
-      unsigned long secsSince1900;
-      // convert four bytes starting at location 40 to a long integer
-      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
-      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
-      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
-      secsSince1900 |= (unsigned long)packetBuffer[43];
-      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
-    }
-  }
-  Serial.println("No NTP Response :-(");
-  return 0; // return 0 if unable to get the time
-}
-
-// send an NTP request to the time server at the given address
-void sendNTPpacket(IPAddress &address)
-{
-  // set all bytes in the buffer to 0
-  memset(packetBuffer, 0, NTP_PACKET_SIZE);
-  // Initialize values needed to form NTP request
-  // (see URL above for details on the packets)
-  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
-  packetBuffer[1] = 0;     // Stratum, or type of clock
-  packetBuffer[2] = 6;     // Polling Interval
-  packetBuffer[3] = 0xEC;  // Peer Clock Precision
-  // 8 bytes of zero for Root Delay & Root Dispersion
-  packetBuffer[12] = 49;
-  packetBuffer[13] = 0x4E;
-  packetBuffer[14] = 49;
-  packetBuffer[15] = 52;
-  // all NTP fields have been given values, now
-  // you can send a packet requesting a timestamp:
-  Udp.beginPacket(address, 123); //NTP requests are to port 123
-  Udp.write(packetBuffer, NTP_PACKET_SIZE);
-  Udp.endPacket();
-}


Delete Touchscreen

Delete Touchscreen

Redundant It is in the folder

--- Touch_Screen.ino
+++ Touch_Screen.ino
@@ -1,121 +0,0 @@
-/* This is my Sketch for the Touch Screen interface for the relay box that will be installed in my Jeep
-    Robert L. Wardecker
-    cna2rn@gmail.com
-
-    This code is in public domain.
-
-Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
-
-NonCommercial — You may not use the material for commercial purposes.
-
-ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
-
-No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
-*/
-
-#include <SoftwareSerial.h>
-#include <Nextion.h>
-
-
-
-const int relayaPin = 52;
-const int relaybPin = 53;
-const int relaycPin = 50;
-const int relaydPin = 51;
-
-
-SoftwareSerial nextion(10, 11);// Nextion TX to pin 10 and RX to pin 11 of Arduino
-
-Nextion myNextion(nextion, 9600); //create a Nextion object named myNextion using the nextion serial port @ 9600bps
-
-boolean button1State;
-boolean button2State;
-boolean button3State;
-boolean button4State;
-boolean button5State;
-
-
-void setup() {
-
-  Serial.begin(9600);
-  myNextion.init(); // send the initialization commands for Page 0
-
-  pinMode(relayaPin, OUTPUT);
-  pinMode(relaybPin, OUTPUT);
-  pinMode(relaycPin, OUTPUT);
-  pinMode(relaydPin, OUTPUT);
-
-}
-
-void loop() {
-
-  String message = myNextion.listen(); //check for message
-
-  //52" Lightbar
-  if (message == "65 0 1 1 ffff ffff ffff") {
-    myNextion.buttonToggle(button1State, "b0", 0, 2);
-
-    if (button1State == HIGH) {
-      // turn Relay on:
-      digitalWrite(relayaPin, HIGH);
-    } else {
-      // turn Relay off:
-      digitalWrite(relayaPin, LOW);
-    }
-  }
-
-  //6" Pods
-  if (message == "65 0 2 1 ffff ffff ffff") {
-    myNextion.buttonToggle(button2State, "b1", 0, 2);
-    if (button2State == HIGH) {
-      // turn Relay on:
-      digitalWrite(relaybPin, HIGH);
-    } else {
-      // turn Relay off:
-      digitalWrite(relaybPin, LOW);
-    }
-  }
-
-  //Fender Pods
-  if (message == "65 0 3 1 ffff ffff ffff") {
-    myNextion.buttonToggle(button3State, "b2", 0, 2);
-    if (button3State == HIGH) {
-      // turn Relay on:
-      digitalWrite(relaycPin, HIGH);
-    } else {
-      // turn Relay off:
-      digitalWrite(relaycPin, LOW);
-    }
-  }
-
-  //Rock Lights
-  if (message == "65 0 4 1 ffff ffff ffff") {
-    myNextion.buttonToggle(button4State, "b3", 0, 2);
-    if (button4State == HIGH) {
-      // turn Relay on:
-      digitalWrite(relaydPin, HIGH);
-    } else {
-      // turn Relay off:
-      digitalWrite(relaydPin, LOW);
-    }
-  }
-
-  //All On
-  if (message == "65 0 5 1 ffff ffff ffff") {
-    myNextion.buttonToggle(button5State, "b4", 0, 2);
-
-    if (button5State == HIGH) {
-      digitalWrite(relayaPin, HIGH);
-      digitalWrite(relaybPin, HIGH);
-      digitalWrite(relaycPin, HIGH);
-      digitalWrite(relaydPin, HIGH);
-    }
-    else {
-      digitalWrite(relayaPin, LOW);
-      digitalWrite(relaybPin, LOW);
-      digitalWrite(relaycPin, LOW);
-      digitalWrite(relaydPin, LOW);
-    }
-  }
-
-}


Update revTest.ino

Update revTest.ino

infrared receive pin change to A0

--- libraries/IRSendRev/examples/revTest/revTest.ino
+++ libraries/IRSendRev/examples/revTest/revTest.ino
@@ -4,7 +4,7 @@
 void setup()
 {
     Serial.begin(38400);
-    IR.Init(A4);
+    IR.Init(A0);
     Serial.println("init over");
 }


lib change

lib change

--- _02-mqtt-sw/_02-mqtt-sw.ino
+++ _02-mqtt-sw/_02-mqtt-sw.ino
@@ -1,32 +1,25 @@
-/*
-*/
 #include <OneWire.h>
 #include "DHT.h"
 #include <PubSubClient.h>
 #include <ESP8266WiFi.h>
 #include <DallasTemperature.h>
-
 #include <WiFiUdp.h>
 #include <Time.h>

 // wifi
 #ifdef __IS_MY_HOME
-  #include "/usr/local/src/ap_setting.h"
+#include "/usr/local/src/ap_setting.h"
 #else
-  #include "ap_setting.h"
+#include "ap_setting.h"
 #endif

-// mqtt
-char* topic = "esp8266/arduino/s02";
-char* subtopic = "esp8266/cmd/light";
-char* hellotopic = "HELLO";
-IPAddress server(192, 168, 10, 10);
+#define DEBUG_PRINT 1

 // pin
 #define pir 13
 #define DHTPIN 14     // what pin we're connected to
 #define RELAYPIN 4
-#define TOPBUTTONPIN 5
+#define TOPBUTTONPIN 5

 // DHT22
 #define DHTTYPE DHT22   // DHT 22  (AM2302)
@@ -42,6 +35,12 @@
 DallasTemperature sensors(&oneWire);
 DeviceAddress insideThermometer, outsideThermometer;

+// mqtt
+char* topic = "esp8266/arduino/s02";
+char* subtopic = "esp8266/cmd/light";
+char* hellotopic = "HELLO";
+IPAddress server(192, 168, 10, 10);
+
 //
 unsigned int localPort = 2390;  // local port to listen for UDP packets
 IPAddress timeServer(192, 168, 10, 10); // time.nist.gov NTP server
@@ -72,55 +71,21 @@
 //
 long startMills;

-void callback(const MQTT::Publish& pub) {
-
-  Serial.print(" => ");
-  Serial.print(pub.topic());
-  Serial.print(" => ");
-  Serial.print(pub.payload_string());
-
-  String subPayload = pub.payload_string() ;
-
-  if ( subPayload == "{\"LIGHT\":1}")
-  {
-       relaystatus = 1 ;
-
-  } else if ( subPayload == "{\"LIGHT\":0}")
-  {
-       relaystatus = 0 ;
-  }
-  changelight() ;
-  Serial.println("");
-  Serial.print(" => relaystatus => ");
-  Serial.println(relaystatus);
-}
-
 WiFiClient wifiClient;
-PubSubClient client(wifiClient, server);
+PubSubClient client(server, 1883, callback, wifiClient);
 WiFiUDP udp;

-
-void setup()
-{
-  Serial.begin(38400);
-  Serial.println("DHTxx test!");
-  delay(20);
-
-  startMills = millis();
-
-  pinMode(pir,INPUT);
-  pinMode(RELAYPIN, OUTPUT);
-  pinMode(TOPBUTTONPIN, INPUT_PULLUP);
-
-  digitalWrite(RELAYPIN, relaystatus);
-
+long lastReconnectAttempt = 0;
+
+void wifi_connect() {
+  // WIFI
   Serial.println();
   Serial.println();
   Serial.print("Connecting to ");
   Serial.println(ssid);

   WiFi.mode(WIFI_STA);
-  WiFi.begin(ssid, password);
+  WiFi.begin(ssid, password);

   int Attempt = 0;
   while (WiFi.status() != WL_CONNECTED) {
@@ -140,6 +105,97 @@
   Serial.println("IP address: ");
   Serial.println(WiFi.localIP());

+}
+
+void callback(char* topic, byte* payload, unsigned int length)
+{
+  String receivedtopic = topic;
+  String receivedpayload ;
+
+  for (int i = 0; i < length; i++) {
+    receivedpayload += (char)payload[i];
+  }
+
+  if (DEBUG_PRINT) {
+    Serial.print(topic);
+    Serial.print(" => ");
+    Serial.println(receivedpayload);
+  }
+
+  if ( receivedpayload == "{\"LIGHT\":1}") {
+    relaystatus = 1 ;
+  }
+  if ( receivedpayload == "{\"LIGHT\":0}") {
+    relaystatus = 0 ;
+  }
+
+  changelight();
+
+  if (DEBUG_PRINT) {
+    Serial.print("");
+    Serial.print(" => relaystatus => ");
+    Serial.println(relaystatus);
+  }
+}
+
+boolean reconnect()
+{
+  if (client.connect((char*) clientName.c_str())) {
+    Serial.println("connected");
+    client.publish(hellotopic, "hello again 1 from ESP8266 s02");
+    client.subscribe(subtopic);
+    client.setCallback(callback);
+  } else {
+    Serial.print("failed, rc=");
+    Serial.print(client.state());
+  }
+  return client.connected();
+}
+
+void setup()
+{
+  Serial.begin(38400);
+  Serial.println("DHTxx test!");
+  delay(20);
+
+  startMills = millis();
+
+  pinMode(pir, INPUT);
+  pinMode(RELAYPIN, OUTPUT);
+  pinMode(TOPBUTTONPIN, INPUT_PULLUP);
+
+  digitalWrite(RELAYPIN, relaystatus);
+
+  wifi_connect();
+
+  clientName += "esp8266-";
+  uint8_t mac[6];
+  WiFi.macAddress(mac);
+  clientName += macToStr(mac);
+  clientName += "-";
+  clientName += String(micros() & 0xff, 16);
+
+  //
+  client.setCallback(callback);
+
+  //
+  lastReconnectAttempt = 0;
+
+  String getResetInfo = "hello from ESP8266 s02 ";
+  getResetInfo += ESP.getResetInfo().substring(0, 30);
+
+  if (WiFi.status() == WL_CONNECTED) {
+    if (!client.connected()) {
+      if (client.connect((char*) clientName.c_str())) {
+        client.publish(hellotopic, (char*) getResetInfo.c_str());
+        client.subscribe(subtopic);
+        client.setCallback(callback);
+        Serial.print("Sending payload: ");
+        Serial.println(getResetInfo);
+      }
+    }
+  }
+
   //
   Serial.println("Starting UDP");
   udp.begin(localPort);
@@ -153,18 +209,11 @@
   }

   attachInterrupt(13, motion_detection, RISING);
-  attachInterrupt(5, run_lightcmd, CHANGE);
-
-  clientName += "esp8266-";
-  uint8_t mac[6];
-  WiFi.macAddress(mac);
-  clientName += macToStr(mac);
-  clientName += "-";
-  clientName += String(micros() & 0xff, 16);
+  attachInterrupt(5, run_lightcmd, CHANGE);

   sensors.begin();
-  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
-  if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1");
+  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");
+  if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1");

   // set the resolution to 9 bit
   sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
@@ -189,38 +238,33 @@
     Serial.println("Failed to read from sensor!");
     return;
   }
-
-}
-
-void loop()
-{
-
+}
+
+void loop()
+{
   if (WiFi.status() == WL_CONNECTED) {
     if (!client.connected()) {
-      if  (
-        client.connect(MQTT::Connect((char*) clientName.c_str()).set_clean_session().set_keepalive(120))) {
-        client.subscribe(subtopic);
-        client.publish(hellotopic, "hello from ESP8266 s02");
-        client.set_callback(callback);
+      long now = millis();
+      if (now - lastReconnectAttempt > 5000) {
+        lastReconnectAttempt = now;
+        if (reconnect()) {
+          lastReconnectAttempt = 0;
+        }
       }
-    }
-
-    if (client.connected()) {
+      Serial.print("failed, rc=");
+      Serial.print(client.state());
+    } else {
       client.loop();
-    } else {
-      ESP.restart();
     }
   } else {
-      Serial.println("Could not connect to WIFI");
-      ESP.restart();
-  }
-
+    wifi_connect();
+  }

   changelight();
   runTimerDoLightOff();
-
+
   pirValue = digitalRead(pir);
-
+
   payload = "{\"Humidity\":";
   payload += h;
   payload += ",\"Temperature\":";
@@ -232,27 +276,27 @@
   payload += ",\"PIRSTATUS\":";
   payload += pirValue;
   payload += "}";
-
+

   if ( pirSent == HIGH && pirValue == HIGH )
-  {
+  {
     sendmqttMsg(topic, payload);
     pirSent = LOW ;
     startMills = millis();
   }
-
+
   if (((millis() - startMills) > REPORT_INTERVAL ) && ( getdalastempstatus == 0))
   {
     getdalastemp();
     getdalastempstatus = 1;
   }
-
+
   if (((millis() - startMills) > REPORT_INTERVAL ) && ( getdht22tempstatus == 0))
   {
     getdht22temp();
     getdht22tempstatus = 1;
   }
-
+
   if ((millis() - startMills) > REPORT_INTERVAL )
   {
     sendmqttMsg(topic, payload);
@@ -268,151 +312,103 @@
   {
     relaystatus = 0;
   }
-
-}
-
-void changelight()
-{
-  if ( relaystatus != oldrelaystatus )
-  {
-      Serial.print(" => ");
-      Serial.println("checking relay status changelight");
-      delay(10);
-      digitalWrite(RELAYPIN, relaystatus);
-      delay(20);
-      digitalWrite(RELAYPIN, relaystatus);
-      delay(20);
-      digitalWrite(RELAYPIN, relaystatus);
-      delay(20);
-      oldrelaystatus = relaystatus ;
-      Serial.print(" => ");
-      Serial.println("changing relay status");
-
-      sendlightstatus();
+}
+
+void changelight()
+{
+  if ( relaystatus != oldrelaystatus )
+  {
+    Serial.print(" => ");
+    Serial.println("checking relay status changelight");
+    delay(10);
+    digitalWrite(RELAYPIN, relaystatus);
+    delay(20);
+    digitalWrite(RELAYPIN, relaystatus);
+    delay(20);
+    digitalWrite(RELAYPIN, relaystatus);
+    delay(20);
+    oldrelaystatus = relaystatus ;
+    Serial.print(" => ");
+    Serial.println("changing relay status");
+
+    sendlightstatus();
   }
 }

 void getdht22temp()
 {
-
-    h = dht.readHumidity();
-    t = dht.readTemperature();
-    f = dht.readTemperature(true);
-
-    if (isnan(h) || isnan(t) || isnan(f)) {
-      Serial.println("Failed to read from DHT sensor!");
-    }
-
-    float hi = dht.computeHeatIndex(f, h);
+
+  h = dht.readHumidity();
+  t = dht.readTemperature();
+  f = dht.readTemperature(true);
+
+  if (isnan(h) || isnan(t) || isnan(f)) {
+    Serial.println("Failed to read from DHT sensor!");
+  }
+
+  float hi = dht.computeHeatIndex(f, h);
 }

 void getdalastemp()
 {
-    sensors.requestTemperatures();
-    tempCinside  = sensors.getTempC(outsideThermometer);
-    tempCoutside = sensors.getTempC(insideThermometer);
-
-    if ( isnan(tempCinside) || isnan(tempCoutside) ) {
-      Serial.println("Failed to read from sensor!");
-    }
-}
-
-void sendlightstatus()
-{
-      String lightpayload = "{\"LIGHT\":";
-      lightpayload += relaystatus;
-      lightpayload += "}";
-
-      sendmqttMsg(subtopic, lightpayload);
-}
-
-void sendmqttMsg(char* topictosend, String payload)
-{
-  if (WiFi.status() == WL_CONNECTED) {
-    if (!client.connected()) {
-      if (client.connect((char*) clientName.c_str())) {
-        Serial.println("Connected to MQTT broker again TEMP");
-        Serial.print("Topic is: ");
-        Serial.println(topictosend);
-      }
-      else {
-        Serial.println("MQTT connect failed");
-        Serial.println("Will reset and try again...");
-        ESP.restart();
-      }
-    }
-
-    if (client.connected()) {
-      Serial.print("Sending payload: ");
-      Serial.println(payload);
-
-      if (
-        client.publish(MQTT::Publish(topictosend, (char*) payload.c_str())
-                  .set_retain()
-                 )
-        ) {
-        //Serial.println("Publish ok");
-      }
-      else {
-        Serial.println("Publish failed");
-        ESP.restart();
-      }
-    }
-  } else {
-      Serial.println("Could not connect to WIFI");
-      ESP.restart();
-  }
-}
-
-void run_lightcmd()
+  sensors.requestTemperatures();
+  tempCinside  = sensors.getTempC(outsideThermometer);
+  tempCoutside = sensors.getTempC(insideThermometer);
+
+  if ( isnan(tempCinside) || isnan(tempCoutside) ) {
+    Serial.println("Failed to read from sensor!");
+  }
+}
+
+void sendlightstatus()
+{
+  String lightpayload = "{\"LIGHT\":";
+  lightpayload += relaystatus;
+  lightpayload += "}";
+
+  sendmqttMsg(subtopic, lightpayload);
+}
+
+void sendmqttMsg(char* topictosend, String payload)
+{
+  if (!client.connected()) {
+    if (client.connect((char*) clientName.c_str())) {
+      client.publish(hellotopic, "hello again 2 from ESP8266 s02");
+    }
+  }
+
+  if (client.connected()) {
+    Serial.print("Sending payload: ");
+    Serial.print(payload);
+
+    unsigned int msg_length = payload.length();
+
+    Serial.print(" length: ");
+    Serial.println(msg_length);
+
+    byte* p = (byte*)malloc(msg_length);
+    memcpy(p, (char*) payload.c_str(), msg_length);
+
+    if ( client.publish(topictosend, p, msg_length, 1)) {
+      Serial.println("Publish ok");
+      free(p);
+    } else {
+      Serial.println("Publish failed");
+      free(p);
+    }
+  }
+}
+
+void run_lightcmd()
 {
   int topbuttonstatus =  ! digitalRead(TOPBUTTONPIN);
   relaystatus = topbuttonstatus ;
 }

-void motion_detection()
+void motion_detection()
 {
   pirValue = HIGH ;
   pirSent  = HIGH ;
-}
-
-// function to print a device address
-void printAddress(DeviceAddress deviceAddress)
-{
-  for (uint8_t i = 0; i < 8; i++)
-  {
-    // zero pad the address if necessary
-    if (deviceAddress[i] < 16) Serial.print("0");
-    Serial.print(deviceAddress[i], HEX);
-  }
-}
-
-// function to print the temperature for a device
-void printTemperature(DeviceAddress deviceAddress)
-{
-  float tempC = sensors.getTempC(deviceAddress);
-  Serial.print("Temp C: ");
-  Serial.print(tempC);
-  Serial.print(" Temp F: ");
-  Serial.print(DallasTemperature::toFahrenheit(tempC));
-}
-
-// function to print a device's resolution
-void printResolution(DeviceAddress deviceAddress)
-{
-  Serial.print("Resolution: ");
-  Serial.print(sensors.getResolution(deviceAddress));
-  Serial.println();
-}
-
-// main function to print information about a device
-void printData(DeviceAddress deviceAddress)
-{
-  Serial.print("Device Address: ");
-  printAddress(deviceAddress);
-  Serial.print(" ");
-  printTemperature(deviceAddress);
-  Serial.println();
 }

 String macToStr(const uint8_t* mac)
@@ -426,9 +422,7 @@
   return result;
 }

-
 /*-------- NTP code ----------*/
-
 const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
 byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets


bean program now prints one character at a time when receiving from serial

--- beanWheelwriterControl/beanWheelwriterControl.ino
+++ beanWheelwriterControl/beanWheelwriterControl.ino
@@ -74,6 +74,7 @@
 // the loop routine runs over and over again forever:
 void loop()
 {
+      static int charCount = 0;
       char buffer[64];
       size_t readLength = 64;
       uint8_t length = 0;
@@ -87,12 +88,16 @@
       // if we have data, so do something with it
       if ( length > 0 )
       {
-          // strip newline from end and println if we had a newline
-          if (buffer[length-1] == '\r' or buffer[length-1] == '\n') {
-              buffer[length-1] = 0;
-              print_strln(buffer);
-          } else {
-              print_str(buffer);
+          // print each character
+          for (int i=0; i < length; i++) {
+              if (buffer[i] == '\r' or buffer[i] == '\n') {
+                  send_return(charCount);
+                  charCount = 0;
+              }
+              else {
+                  send_letter(asciiTrans[buffer[i]]);
+                  charCount++;
+              }
           }
           Bean.setLed(255, 0, 0);
           Bean.sleep(50);


Update code for anklet component

Update code for anklet component

--- anklet_code/anklet_code.ino
+++ anklet_code/anklet_code.ino
@@ -1,45 +1,122 @@
+#include <VirtualWire.h>
+
 const int xPin = 2;
 const int yPin = 1;
 const int zPin = 0;

-double x, y, z;
-
-int minVal = 265;
-int maxVal = 500;
-
-int accumulatedXValues[20];
-int accumulatedYValues[20];
-int accumulatedZValues[20];
-int count = 0;
+int steps = 0;

 void setup() {
-	Serial.begin(9600);
+  // Initializations for RF transmitter
+  vw_set_ptt_inverted(true);
+  vw_setup(2000);
+  vw_set_tx_pin(11);
+}
+
+// Helper function to get the length of an array of floats
+int arrayLength(float numbers[]) {
+  int size_ = sizeof(numbers) / sizeof(*numbers);
+  return sizeof(numbers) / sizeof(*numbers);
+}
+
+// Helper function to return the sum of elements in a list
+float sum(float numbers[]) {
+  float sum = 0;
+  for (int i = 0; i < 100; i++) {
+    sum += numbers[i];
+  }
+  return float(sum);
+}
+
+// Helper function to return the average of elements in a list
+float average(float numbers[]) {
+  return sum(numbers) / 100;
+}
+
+// Function to find average values on each axis
+void calibrate(float results[]) {
+  Serial.print("Calibrating accelerometer...");
+  Serial.print("\n");
+  float xSum, ySum, zSum = 0.0;
+  float xValues[100], yValues[100], zValues[100] = {0.0};
+
+  for (int i = 0; i < 100; i++) {
+    xValues[i] = float(analogRead(xPin));
+    yValues[i] = float(analogRead(yPin));
+    zValues[i] = float(analogRead(zPin));
+  }
+  results[0] = average(xValues);
+  results[1] = average(yValues);
+  results[2] = average(zValues);
+}
+
+// Function to transmit a message using RF transmitter
+void send(char *msg) {
+  vw_send((uint8_t *)msg, strlen(msg));
+  vw_wait_tx();
+}
+
+// Helper function to print out accelerometer data
+void prettyPrintData(int x, int y, int z) {
+  Serial.print("X: ");
+  Serial.print(x);
+  Serial.print("\n");
+  Serial.print("Y: ");
+  Serial.print(y);
+  Serial.print("\n");
+  Serial.print("Z: ");
+  Serial.print(z);
+  Serial.print("\n");
+}
+
+float distance(float numbers[]) {
+  float sum = 0.0;
+  for (int i = 0; i < 3; i++) {
+    sum += numbers[i];
+  }
+  return sqrt(sum);
+}
+
+int isStep(float x, float y, float z) {
+
 }

 void loop() {
-  // This portion of code reads data from the
-  int xRead = analogRead(xPin);
-  int yRead = analogRead(yPin);
-  int zRead = analogRead(zPin);
-  int xAng  = map(xRead, minVal, maxVal, -90, 90);
-  int yAng  = map(yRead, minVal, maxVal, -90, 90);
-  int zAng  = map(zRead, minVal, maxVal, -90, 90);
+  float prevX = float(analogRead(xPin));
+  float prevY = float(analogRead(yPin));
+  float prevZ = float(analogRead(zPin));
+
+  prettyPrintData(prevX, prevY, prevZ);

-  // This portion of the code is for testing purposes and
-  // should be commented out in the production version
-  Serial.print("X: ");
-  Serial.print(xAng);
-  Serial.print("Y: ");
-  Serial.print(yAng);
-  Serial.print("Z: ");
-  Serial.print(zAng);
-  delay(100);
+  float oldAverages[3];
+  calibrate(oldAverages);

-  accumulatedXValues[count] = xAng;
-  accumulatedYValues[count] = yAng;
-  accumulatedZValues[count] = zAng;
+  prettyPrintData(oldAverages[0], oldAverages[1], oldAverages[2]);
+
+  float xThreshold = oldAverages[0] * 0.05;
+  float yThreshold = oldAverages[1] * 0.05;
+  float zThreshold = oldAverages[2] * 0.05;
+
+  float x = float(analogRead(xPin));
+  float y = float(analogRead(yPin));
+  float z = float(analogRead(zPin));
+
+  prettyPrintData(x, y, z);
+
+  if (abs(prevX - x) > xThreshold || abs(prevY - y) > yThreshold || abs(prevZ - z) > zThreshold) {
+    steps++;
+    Serial.println("Incremented step count to: ");
+    Serial.println(steps);
+  }
+
+  if (steps >= 3) {
+    send("1");
+    Serial.print("Sucessfully sent movement indicator!\n");
+    steps = 0;
+  } else {
+    send("0");
+    Serial.print("Sucessfully sent no movement indicator!\n");
+  }
+
+  delay(1000);
 }
-
-int calculateDelta(int previousValues, int timePeriod) {
-
-}


Power up the LOCK_PIN to allow access

Power up the LOCK_PIN to allow access

--- firmware/sentry.ino
+++ firmware/sentry.ino
@@ -22,7 +22,7 @@
 #define LCD_BL_G A2
 #define LCD_BL_B A1

-#define LED_PIN D7
+#define LOCK_PIN D7

 // Dont demand wifi before our code starts running.
 SYSTEM_MODE(MANUAL);
@@ -49,7 +49,7 @@
   Serial.begin(9600);
   rfid.begin();

-  pinMode(LED_PIN, OUTPUT);
+  pinMode(LOCK_PIN, OUTPUT);
   pinMode(LCD_BL_R, OUTPUT);
   pinMode(LCD_BL_G, OUTPUT);
   pinMode(LCD_BL_B, OUTPUT);
@@ -82,7 +82,7 @@
     Particle.publish("sentry/request-members");
   } else if (cloud.didStartConnecting()) {
     lcd.clear();
-    lcd.print("Connecting...");
+    lcd.print("  Connecting... ");
   }
 }

@@ -106,7 +106,6 @@
   store.appendCards(data);
 }

-
 void checkCode(int code) {
   char line1[17];
   char line2[17];
@@ -128,7 +127,11 @@
   digitalWrite(LCD_BL_G, LOW);
   digitalWrite(LCD_BL_B, HIGH);

-  delay(2000);
+  digitalWrite(LOCK_PIN, HIGH);
+
+  delay(3000);
+
+  digitalWrite(LOCK_PIN, LOW);
   resetLCD();
 }


Update hrl_arduino.ino

Update hrl_arduino.ino


Update SimpleBitmap.ino

Update SimpleBitmap.ino


Beautifying part two. Adding methods for light resistor and hygrometer


Make sure the muhenkan key behave like the left shift key

--- arduino/dudrack/dudrack.ino
+++ arduino/dudrack/dudrack.ino
@@ -1,4 +1,4 @@
-#define USBCON
+//#define USBCON

 #include <hidboot.h>
 #include <hiduniversal.h>
@@ -306,7 +306,7 @@
 }

 void changeModifiers(uint8_t modifiers) {
-    keyReport.modifiers = modifiers | (keyboardState.spacePressed ? MODIFIER_LEFT_SHIFT : 0);
+    keyReport.modifiers = modifiers | (keyboardState.muhenkanPressed || keyboardState.spacePressed ? MODIFIER_LEFT_SHIFT : 0);
     Keyboard.sendReport(&keyReport);
 }


Change stg mode key layout

Change stg mode key layout

--- arduino/dudrack/dudrack.ino
+++ arduino/dudrack/dudrack.ino
@@ -21,6 +21,7 @@
 #define KEY_HENKAN 0x8A
 #define KEY_MUHENKAN 0x8B
 #define KEY_HIRAGANA 0x88
+#define KEY_PRINT_SCREEN 0x46

 #define KEY_1 0x1E
 #define KEY_2 0x1F
@@ -109,16 +110,17 @@
 #define STICK_LEFT -1
 #define STICK_RIGHT 1

-#define STICK_DOWN_KEY KEY_A
-#define STICK_UP_KEY KEY_S
+#define STICK_DOWN_KEY KEY_Z
+#define STICK_UP_KEY KEY_X
 #define STICK_LEFT_KEY KEY_AT
 #define STICK_RIGHT_KEY KEY_BRACKET_OPEN
-#define BUTTON_0_MODIFIER bmRightAlt
-#define BUTTON_1_KEY KEY_ENTER
-#define BUTTON_2_MODIFIER bmLeftAlt
-#define BUTTON_3_KEY KEY_TAB
+#define BUTTON_0_KEY KEY_ENTER
+#define BUTTON_1_MODIFIER bmRightAlt
+#define BUTTON_2_KEY KEY_PRINT_SCREEN
+#define BUTTON_3_MODIFIER bmLeftShift
 #define BUTTON_4_MODIFIER bmLeftCtrl
-#define BUTTON_5_KEY KEY_SPACE
+#define BUTTON_5_KEY KEY_A
+#define BUTTON_6_KEY KEY_SPACE

 USB    Usb;
 USBHub Hub(&Usb);
@@ -414,18 +416,23 @@

             return;

-        case BUTTON_1_KEY:
-            Joystick.pressButton(1);
-
-            return;
-
-        case BUTTON_3_KEY:
-            Joystick.pressButton(3);
+        case BUTTON_0_KEY:
+            Joystick.pressButton(0);
+
+            return;
+
+        case BUTTON_2_KEY:
+            Joystick.pressButton(2);

             return;

         case BUTTON_5_KEY:
             Joystick.pressButton(5);
+
+            return;
+
+        case BUTTON_6_KEY:
+            Joystick.pressButton(6);

             return;
     }
@@ -457,13 +464,13 @@

             return;

-        case BUTTON_1_KEY:
-            Joystick.releaseButton(1);
-
-            return;
-
-        case BUTTON_3_KEY:
-            Joystick.releaseButton(3);
+        case BUTTON_0_KEY:
+            Joystick.releaseButton(0);
+
+            return;
+
+        case BUTTON_2_KEY:
+            Joystick.releaseButton(2);

             return;

@@ -471,22 +478,27 @@
             Joystick.releaseButton(5);

             return;
+
+        case BUTTON_6_KEY:
+            Joystick.releaseButton(6);
+
+            return;
     }
 }

 void stgModifiersChange(uint8_t modifiers) {
     MODIFIERKEYS mod = *((MODIFIERKEYS*)&modifiers);

-    if (mod.BUTTON_0_MODIFIER) {
-        Joystick.pressButton(0);
+    if (mod.BUTTON_1_MODIFIER) {
+        Joystick.pressButton(1);
     } else {
-        Joystick.releaseButton(0);
-    }
-
-    if (mod.BUTTON_2_MODIFIER) {
-        Joystick.pressButton(2);
+        Joystick.releaseButton(1);
+    }
+
+    if (mod.BUTTON_3_MODIFIER) {
+        Joystick.pressButton(3);
     } else {
-        Joystick.releaseButton(2);
+        Joystick.releaseButton(3);
     }

     if (mod.BUTTON_4_MODIFIER) {


Better timing Makes use of the rn2483's "ok" when it wakes up from sleep. Use a WDT in case the rn2483's ok is not received. Use custom sleep function rather than library.

--- things_uno/weather_uno.ino
+++ things_uno/weather_uno.ino
@@ -1,55 +1,95 @@
 /*
- * Author: NC Thompson
+ * Authors: NC Thompson, JP Meijers
  * Date: 2017-02-15
  *
  */
 #include <rn2xx3.h>
 #include <SHT1x.h>
-#include "LowPower.h"
+#include <avr/wdt.h>
+#include <avr/power.h>
+#include <avr/sleep.h>
+
+// The interval at which the sensors should be read and the values transmitted
+#define SAMPLE_INTERVAL_MS 60000UL
+
+// after this amount of time, if the rn2483 did not wake us up, reset the system
+#define WDT_INTERVAL_MS 600000UL

 //create an instance of the rn2483 library, using the given Serial port
 rn2xx3 myLora(Serial1);
 #define dataPin  SDA
 #define clockPin SCL
-#define PIN_SERIAL1_TX PIN1
+#define SELF_RESET_PIN 12

 SHT1x sht1x(dataPin, clockPin);
-
-uint8_t count = 0;

 uint8_t txBuffer[7];
 int batVoltPin = A5;    // select the input pin for the battery voltage

-// the setup routine runs once when you press reset:
+unsigned long startTime = 0;
+unsigned long sleepTime = 0;
+unsigned int wdtCount = 0;
+
+
+/*
+ * Define Timer4 labels
+ */
+#if defined __AVR_ATmega32U4__
+  // Timer 4 PRR bit is currently not defined in iom32u4.h
+  #ifndef PRTIM4
+    #define PRTIM4 4
+  #endif
+
+  // Timer 4 power reduction macro is not defined currently in power.h
+  #ifndef power_timer4_disable
+    #define power_timer4_disable()  (PRR1 |= (uint8_t)(1 << PRTIM4))
+  #endif
+
+  #ifndef power_timer4_enable
+    #define power_timer4_enable()   (PRR1 &= (uint8_t)~(1 << PRTIM4))
+  #endif
+#endif
+
+
+
 void setup()
 {
+  digitalWrite(SELF_RESET_PIN, HIGH);
+  wdt_disable();
+
   //output LED pin
   pinMode(13, OUTPUT);
   led_on();

-  // Open serial communications and wait for port to open:
   Serial.begin(57600); //serial port to computer

-  Serial1.begin(57600); //serial port to radio
-  //wakeUP_RN2483();
   // make sure usb serial connection is available,
-  // or after 10s go on anyway for 'headless' use of the
-  // node.
+  // or after 10s go on anyway for 'headless' use of the node.
   while ((!Serial) && (millis() < 10000));

   Serial.println("Startup");

   initialize_radio();

-  //transmit a startup message
-  myLora.tx("TTN Mapper on TTN Uno node");
+  // set up interrupt on Serial1 RX
+  // RXD1 = INT2 - enable interrupt on rising and falling edge
+  EICRA = 0b01010101;
+  EIMSK = 0b00000100;
+
   Serial.end();
   led_off();
-  delay(2000);
 }

 void initialize_radio()
 {
+  Serial1.begin(57600); //serial port to radio
+
+  //reset rn2483
+  pinMode(4, OUTPUT);
+  digitalWrite(4, LOW);
+  delay(100);
+  digitalWrite(4, HIGH);
+
   delay(100); //wait for the RN2xx3's startup message
   Serial1.flush();

@@ -83,8 +123,8 @@
   }
   Serial.println("Successfully joined TTN");
   okSeq();
-
-}
+}
+
 void okSeq () {
     led_on();
     delay(100);
@@ -99,51 +139,40 @@
     led_off();
 }

-void wakeUP_RN2483() {
-    Serial1.end();
-    pinMode(PIN_SERIAL1_TX, OUTPUT);
-    digitalWrite(PIN_SERIAL1_TX, LOW);
-    delay(5);
-    digitalWrite(PIN_SERIAL1_TX, HIGH);
-    Serial1.begin(57600);
-    Serial1.write(0x55);
-    delay(100); //wait for the RN2xx3's startup message
-    Serial1.flush();
-}
-
 // the loop routine runs over and over again forever:
 void loop()
 {
-  if (count == 0) {
-     //wakeUP_RN2483();
-    myLora.autobaud();
-    int16_t temp_c;
-    int16_t humidity;
-    int16_t battery;
-    led_on();
-
-    temp_c = int16_t(sht1x.readTemperatureC()*100);
-    humidity = int16_t(sht1x.readHumidity()*100);
-    battery = analogRead(batVoltPin)*4.88;
-
-
-    txBuffer[0] = byte(temp_c>>8);
-    txBuffer[1] = byte(temp_c);
-    txBuffer[2] = byte(humidity>>8);
-    txBuffer[3] = byte(humidity);
-    txBuffer[4] = byte(battery>>8);
-    txBuffer[5] = byte(battery);
-    txBuffer[6] = 0xFE;
-
-    myLora.txBytes(txBuffer, sizeof(txBuffer));
-    led_off();
-    myLora.sleep(128000);
-    delay(100);
-    count = 16;
-  } else {
-    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
-    count --;
-  }
+  startTime = millis();
+  led_on();
+  myLora.autobaud();
+  led_off();
+  delay(100);
+  led_on();
+  int16_t temp_c;
+  int16_t humidity;
+  int16_t battery;
+
+  temp_c = int16_t(sht1x.readTemperatureC()*100);
+  humidity = int16_t(sht1x.readHumidity()*100);
+  battery = analogRead(batVoltPin)*4.88;
+
+
+  txBuffer[0] = byte(temp_c>>8);
+  txBuffer[1] = byte(temp_c);
+  txBuffer[2] = byte(humidity>>8);
+  txBuffer[3] = byte(humidity);
+  txBuffer[4] = byte(battery>>8);
+  txBuffer[5] = byte(battery);
+  txBuffer[6] = 0xFE;
+
+  myLora.txBytes(txBuffer, sizeof(txBuffer));
+  led_off();
+
+  sleepTime = (SAMPLE_INTERVAL_MS-(millis()-startTime));
+  myLora.sleep(sleepTime);
+  delay(100);
+
+  go_to_sleep();
 }

 void led_on()
@@ -156,3 +185,91 @@
   digitalWrite(13, 0);
 }

+ISR(WDT_vect)
+{
+  wdt_reset();
+  wdtCount++;
+  if(wdtCount<=(WDT_INTERVAL_MS/8000))
+  {
+    sleep_now();
+  }
+  else
+  {
+    pinMode(12, OUTPUT);
+    digitalWrite(12, LOW);
+  }
+}
+
+ISR(INT2_vect)
+{
+  //wake up if we are in sleep
+}
+
+ISR(BADISR_vect)
+{
+  //unknown interrupt - do nothing, just wake up
+}
+
+void enable_wdt_interrupt_8s()
+{
+  /*
+  WDTCSR configuration:
+  WDIE = 1 :Interrupt Enable
+  WDE = 1  :Reset Enable
+  WDP3:0 = 1001 = 8s
+  */
+  MCUSR &= ~(1<<WDRF);  // because the data sheet said to
+  // Enter Watchdog Configuration mode:
+  WDTCSR = (1<<WDCE) | (1<<WDE);
+  // Set Watchdog settings: interrupte enable, 1001 for timer
+  WDTCSR = (0<<WDE) | (1<<WDIE) | (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);
+  wdt_reset();
+}
+
+void go_to_sleep()
+{
+  enable_wdt_interrupt_8s();
+
+  ADCSRA &= ~(1 << ADEN);
+  power_adc_disable();
+
+  power_timer4_disable();
+  power_timer3_disable();
+  power_timer1_disable();
+  power_timer0_disable();
+  power_spi_disable();
+  power_usart1_disable();
+  power_twi_disable();
+  power_usb_disable();
+
+  sleep_now();
+
+  wdt_reset();
+  wdt_disable();
+  wdtCount=0;
+
+  power_adc_enable();
+  ADCSRA |= (1 << ADEN);
+
+  power_timer4_enable();
+  power_timer3_enable();
+  power_timer1_enable();
+  power_timer0_enable();
+  power_spi_enable();
+  power_usart1_enable();
+  power_twi_enable();
+  power_usb_enable();
+}
+
+void sleep_now()
+{
+  // mcu sleep
+  cli();
+  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+  sleep_enable();
+  //sleep_bod_disable(); // Only Pico Power devices can change BOD settings through software
+  sei();
+  sleep_cpu();
+  sleep_disable();
+}
+


Add kludge for wiring mistake. Update reference values and add some forward declarations

--- KomaRoof.ino
+++ KomaRoof.ino
@@ -33,6 +33,7 @@
 #include "Version.h"

 #define BOARD_NAME "KOMAROOF"
+#define PIN_UNUSED 46
 #define PIN_ONE_WIRE_BUS 44
 #define PIN_BUTTON_CLOSE 42
 #define PIN_BUTTON_OPEN 40
@@ -42,8 +43,8 @@
 #define PIN_ENCODER_GATE_1 20
 #define PIN_ENCODER_GATE_2 21
 #define PIN_BATTERY_VOLTAGE A2
-#define REFERENCE_VOLTAGE 5.0
-#define BATTERY_RESISTOR_DIVISOR 1.0
+#define REFERENCE_VOLTAGE 4.987
+#define BATTERY_RESISTOR_DIVISOR 3.2473
 #define MOTOR_CURRENT_LIMIT_MILLIAMPS 2500
 #define MOTOR_CLOSING_CURRENT_LIMIT_MILLIAMPS 1000
 #define MOTOR_POLARITY 1    // Change to -1 to invert movement direction
@@ -84,8 +85,22 @@
 static volatile int encoderState = 0;
 static volatile int encoderPosition = 0;

+static void emergencyStopISR();
+static void limitSwitchCloseISR();
+static void limitSwitchOpenISR();
+static void encoderGate1ISR();
+static void encoderGate2ISR();
+static void stop(const String&);
+static void open(const String&);
+static void close(const String&);
+static void setspeed(const String&);
+static void status(const String&);
+static void test(const String&);
+
+
 void setup() {

+    pinMode(PIN_UNUSED, INPUT);
     pinMode(PIN_BUTTON_CLOSE, INPUT);
     pinMode(PIN_BUTTON_OPEN, INPUT);
     pinMode(PIN_BUTTON_EMERGENCYSTOP, INPUT);
@@ -151,6 +166,17 @@
     limitSwitchCloseActive = (digitalRead(PIN_LIMITSWITCH_CLOSE) == LOW);
 }

+void updateEncoder(int previous, int current) {
+    static int grayToBinary[4] = { 0, 1, 3, 2 };
+    previous = grayToBinary[previous & 0x3];
+    current = grayToBinary[current & 0x3];
+
+    if (current == ((previous+1) & 0x3))
+        encoderPosition++;
+    if (current == ((previous-1) & 0x3))
+        encoderPosition--;
+}
+
 void encoderGate1ISR() {
     int previousEncoderState = encoderState;
     encoderState = (encoderState & 0x1) | (digitalRead(PIN_ENCODER_GATE_1) == LOW ? 0x2 : 0);
@@ -161,17 +187,6 @@
     int previousEncoderState = encoderState;
     encoderState = (encoderState & 0x2) | (digitalRead(PIN_ENCODER_GATE_2) == LOW ? 0x1 : 0);
     updateEncoder(previousEncoderState, encoderState);
-}
-
-void updateEncoder(int previous, int current) {
-    static int grayToBinary[4] = { 0, 1, 3, 2 };
-    previous = grayToBinary[previous & 0x3];
-    current = grayToBinary[current & 0x3];
-
-    if (current == ((previous+1) & 0x3))
-        encoderPosition++;
-    if (current == ((previous-1) & 0x3))
-        encoderPosition--;
 }

 void currentMeasurementTick() {


GPRS interface

GPRS interface

--- Lab_s1e5.ino
+++ Lab_s1e5.ino
@@ -4,18 +4,18 @@
 #include <Servo.h>
 #include <SoftwareSerial.h>

-typedef struct{
-  String name;
-  String phone_number;
-} Contact;
+// typedef struct{
+//   String name;
+//   String phone_number;
+// } Contact;

-void constact_set_name(String name, Contact* contact){
-  contact->name = name;
-}
+// void constact_set_name(String name, Contact* contact){
+//   contact->name = name;
+// }

-void constact_set_phone_num(String number, Contact* contact){
-  contact->phone_number = number;
-}
+// void constact_set_phone_num(String number, Contact* contact){
+//   contact->phone_number = number;
+// }

 void GPRS_init(){
   // Enter PIN code: AT+CPIN=<pin>
@@ -51,15 +51,13 @@
   delay(3000);
 }

-//
-
 #define N_ENTRIES 2

 // device phone number: 0466259105

 SoftwareSerial GPRS(7, 8);
 unsigned char buffer[64]; // buffer array for data recieve over serial port
-int count=0;     // counter for buffer array
+int count = 0;     // counter for buffer array
 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 Servo gate;

@@ -78,8 +76,9 @@
   pinMode(LEDPIN, HIGH);
   gate.attach(9);

-
   GPRS.begin(19200);
+  delay(5000);
+  GPRS_init();
 }

 void loop() {


Typo correction

--- BrickBreak/BrickBreak.ino
+++ BrickBreak/BrickBreak.ino
@@ -28,7 +28,7 @@
 #define PIN 0 //Pin D3 on the NodeMCU
 #define FRAMERATE 30

-//Comment this out after you've confirmed that the sensor works is working.
+//Comment this out after you've confirmed that the sensor works.
 #define SENSORTEST

 static int frameInterval = 1000 / FRAMERATE;


Adding library files.

Adding library files.

--- examples/example_rpc_client/example_rpc_client.ino
+++ examples/example_rpc_client/example_rpc_client.ino
@@ -0,0 +1 @@
+


Add a safety instruction on Arduino which stop the robot if the Android app is not responding

--- Arduino/Arduino.ino
+++ Arduino/Arduino.ino
@@ -117,7 +117,7 @@
 int blinkGreenTimer, blinkYellowTimer;
 bool stateYellow,stateGreen;
 bool emergency_mode,warning,FL_edge,FR_edge;
-int emergency_sensor_threshold =850,currentState=IDLE;
+int emergency_sensor_threshold =800,currentState=IDLE;

@@ -232,6 +232,8 @@
         digitalWrite(LED_YELLOW, stateYellow);
       }
       Serial.print("*");
+      //Safety command. Stop the robot if Android app is gone
+      stop(false);
     }
     getDistance();
   }


v3.2.0 template update

v3.2.0 template update

--- examples/Scheduler_template/Scheduler_template.ino
+++ examples/Scheduler_template/Scheduler_template.ino
@@ -37,20 +37,22 @@
 // ==== INCLUDES ==================================================================================

 // ==== Uncomment desired compile options =================================
-// #define _TASK_TIMECRITICAL      // Enable monitoring scheduling overruns
-// #define _TASK_SLEEP_ON_IDLE_RUN // Enable 1 ms SLEEP_IDLE powerdowns between tasks if no callback methods were invoked during the pass
-// #define _TASK_STATUS_REQUEST    // Compile with support for StatusRequest functionality - triggering tasks on status change events in addition to time only
-// #define _TASK_WDT_IDS           // Compile with support for wdt control points and task ids
-// #define _TASK_LTS_POINTER       // Compile with support for local task storage pointer
-// #define _TASK_PRIORITY          // Support for layered scheduling priority
-// #define _TASK_MICRO_RES         // Support for microsecond resolution
-// #define _TASK_STD_FUNCTION      // Support for std::function (ESP8266 and ESP32 ONLY)
-// #define _TASK_DEBUG             // Make all methods and variables public for debug purposes
-// #define _TASK_INLINE            // Make all methods "inline" - needed to support some multi-tab, multi-file implementations
-// #define _TASK_TIMEOUT           // Support for overall task timeout
-// #define _TASK_OO_CALLBACKS      // Support for dynamic callback method binding
-// #define _TASK_DEFINE_MILLIS     // Force forward declaration of millis() and micros() "C" style
-// #define _TASK_EXPOSE_CHAIN      // Methods to access tasks in the task chain
+// #define _TASK_SLEEP_ON_IDLE_RUN  // Enable 1 ms SLEEP_IDLE powerdowns between tasks if no callback methods were invoked during the pass
+// #define _TASK_TIMECRITICAL       // Enable monitoring scheduling overruns
+// #define _TASK_STATUS_REQUEST     // Compile with support for StatusRequest functionality - triggering tasks on status change events in addition to time only
+// #define _TASK_WDT_IDS            // Compile with support for wdt control points and task ids
+// #define _TASK_LTS_POINTER        // Compile with support for local task storage pointer
+// #define _TASK_PRIORITY           // Support for layered scheduling priority
+// #define _TASK_MICRO_RES          // Support for microsecond resolution
+// #define _TASK_STD_FUNCTION       // Support for std::function (ESP8266 and ESP32 ONLY)
+// #define _TASK_DEBUG              // Make all methods and variables public for debug purposes
+// #define _TASK_INLINE             // Make all methods "inline" - needed to support some multi-tab, multi-file implementations
+// #define _TASK_TIMEOUT            // Support for overall task timeout
+// #define _TASK_OO_CALLBACKS       // Support for dynamic callback method binding
+// #define _TASK_DEFINE_MILLIS      // Force forward declaration of millis() and micros() "C" style
+// #define _TASK_EXPOSE_CHAIN       // Methods to access tasks in the task chain
+// #define _TASK_SCHEDULING_OPTIONS // Support for multiple scheduling options
+
 #include <TaskScheduler.h>

@@ -72,6 +74,10 @@
   TASK_FOREVER
   TASK_ONCE
   TASK_NOTIMEOUT
+
+  TASK_SCHEDULE     - schedule is a priority, with "catch up" (default)
+  TASK_SCHEDULE_NC  - schedule is a priority, without "catch up"
+  TASK_INTERVAL     - interval is a priority, without "catch up"
 */

 // ==== Task definitions ========================


Removed extra code that was added for troubleshooting a non-existant problem

--- FumeHoodMonitor/TMP36.ino
+++ FumeHoodMonitor/TMP36.ino
@@ -9,27 +9,10 @@
 // Gets a reading from the TMP36 sensor and stores it in the array for averaging
 float readTMP36Temp(){
   updateReadings();
-  float voltage = readTMP36Voltage(false);
+  float voltage = average * 3.3 / 1024;
   float tempC = (voltage - 0.5) * 100;
   float tempF = (tempC * 9.0 / 5.0) + 32.0;
   return tempF;
-}
-
-float readTMP36Voltage() {
-  updateReadings();
-  float voltage = average * 3.3 / 1024;
-  return voltage;
-}
-
-float readTMP36Voltage(bool updateReadingsArray) {
-  if (updateReadingsArray) updateReadings();
-  float voltage = average * 3.3 / 1024;
-  return voltage;
-}
-
-float getReadingAverage(){
-  updateReadings();
-  return average;
 }

 void updateReadings(){


LED on Pin 13, typo updated.

LED on Pin 13, typo updated.

--- PulseSensorAmped_Arduino_1dot4/Interrupt.ino
+++ PulseSensorAmped_Arduino_1dot4/Interrupt.ino
@@ -46,7 +46,7 @@
   if (N > 250){                                   // avoid high frequency noise
     if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){
       Pulse = true;                               // set the Pulse flag when we think there is a pulse
-//      digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED
+      digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED
       IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
       lastBeatTime = sampleCounter;               // keep track of time for next pulse


Much improved ATtiny firmware

Much improved ATtiny firmware

--- hw/bot_attiny_controller/bot_attiny_controller.ino
+++ hw/bot_attiny_controller/bot_attiny_controller.ino
@@ -6,11 +6,17 @@
  * continuous turn servos. It also has an ADC input for checking
  * the battery level.
  *
- * To test on Linux:
- *
- * # # Assume that the ATtiny85's I2C pins are connected to the
- * # # host's I2C bus 1
- * # i2cdetect -y 1
+ * To test on Raspian:
+ *
+ * Connect the ATtiny85's I2C pins to the I2C pins on the
+ * Raspberry Pi's GPIO connector
+ *
+ * # sudo apt-get install i2c-tools
+ * # sudo raspi-config
+ * In raspi-config, enable I2C through the advanced menu.
+ *
+ * # sudo modprobe i2c-dev
+ * # sudo i2cdetect -y 1
  *      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
  * 00:          -- 04 -- -- -- -- -- -- -- -- -- -- --
  * 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
@@ -20,14 +26,23 @@
  * 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  * 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  * 70: -- -- -- -- -- -- -- --
- * # i2cget -y 1 4 0  ## get left PWM duration
- * 0x60
- * # i2cget -y 1 4 1  ## get right PWM duration
- * 0x60
- * # i2cget -y 1 4 2  ## get battery voltage/2 (0-255)
- * 0xbe
- * # i2cset -y 1 4 0 160 ## set left PWM duration
- * # i2cset -y 1 4 1 160 ## set right PWM duration
+ *
+ * If the device doesn't show up (i.e. the 04), then
+ * check the connections.
+ *
+ * # sudo i2cget -y 1 4 0 w    ## get left servo pulse duration
+ * 0x05dc                      ## 0x05dc = 1500 microsecond pulse
+ *
+ * # sudo i2cget -y 1 4 2 w    ## get right servopulse duration
+ * 0x05dc
+ *
+ * # sudo i2cget -y 1 4 4 w    ## get battery voltage
+ * 0x138e                      ## 0x138e = 5006 microVolts
+ *
+ * # sudo i2cset -y 1 4 0 1200 ## set the left servo pulse to 1200 us
+ * # sudo i2cset -y 1 4 2 1500 ## set the right right pulse to 1500 us
+ *
+ * *** There are intermittent I2C failures. I have not tracked them down. ***
  *
  * Programming an ATtiny85 with an Arduino Uno
  *
@@ -35,14 +50,17 @@
  *    Arduino sketchbook directory is. These files come from http://hlt.media.mit.edu/?p=1229,
  *    but they're not always available. As a bonus, I've already made
  *    a boards.txt that defines the right ATtiny85 configuration for this project.
- * 2. In the Arduino IDE, program the ArduinoISP firmware onto the Uno
+ * 2. In ~/sketchbook/libraries, run:
+ *       git clone https://github.com/rambo/TinyWire.git
+ * 3. Restart the Arduino IDE if you have it open, so that it finds the TinyWireS library
+ * 4. In the Arduino IDE, program the ArduinoISP firmware onto the Uno
  *    (it's an example Arduino program)
- * 3. In Arduino IDE, set the board to "ATtiny85 @ 8 MHz (internal oscillator; BOD disabled)
- * 4. Set the programmer to "Arduino as ISP"
+ * 5. In Arduino IDE, set the board to "ATtiny85 @ 8 MHz (internal oscillator; BOD disabled)
+ * 6. Set the programmer to "Arduino as ISP"
  *
  *  -- Setup steps are done --
  *
- * 5. Wire the Uno to the ATtiny85 like this:
+ * 7. Wire the Uno to the ATtiny85 like this:
  *      Arduino +5V    ---> ATtiny Pin 8
  *      Arduino Ground ---> ATtiny Pin 4
  *      Arduino Pin 10 ---> ATtiny Pin 1
@@ -50,8 +68,8 @@
  *      Arduino Pin 12 ---> ATtiny Pin 6
  *      Arduino Pin 13 ---> ATtiny Pin 7
  *      Arduino Reset, Arduino group -> connect with 10 uF capacitor
- * 5. Burn bootloader (VERY, VERY IMPORTANT. I learned the hard way.)
- * 6. Compile and upload this program.
+ * 8. Burn bootloader (VERY, VERY IMPORTANT. I learned the hard way.)
+ * 9. Compile and upload this program.
  */

@@ -61,10 +79,10 @@
  * Pin   Function
  * 1     NRESET
  * 2     PB3 - Battery level/2 * 3.3/255
- * 3     PB4 - Right servo
+ * 3     PB4 - Right servo (OC1B)
  * 4     GND
  * 5     PB0 - I2C SDA
- * 6     PB1 - Left servo
+ * 6     PB1 - Left servo (OC1A)
  * 7     PB2 - I2C SCL
  * 8     VCC (+3.3V)
  */
@@ -72,58 +90,80 @@
 #define I2C_SLAVE_ADDRESS 0x4
 #include <TinyWireS.h>

-// The default buffer size, Can't recall the scope of defines right now
-#ifndef TWI_RX_BUFFER_SIZE
-#define TWI_RX_BUFFER_SIZE ( 16 )
+enum I2cRegisters {
+  I2cRegLeftServoLo = 0,
+  I2cRegLeftServoHi,
+  I2cRegRightServoLo,
+  I2cRegRightServoHi,
+  I2cRegBatteryLo,
+  I2cRegBatteryHi,
+  I2cRegCount
+};
+
+volatile uint8_t currentRegister = 0;
+
+uint16_t leftServoMicros = 1500;
+uint16_t rightServoMicros = 1500;
+uint16_t batteryMicroVolts = 0;
+
+#if F_CPU == 8000000L
+    // Divide FCLK by 64 -> 8 MHz/64 = 125 KHz (each tick is 8 uS)
+    #define TCCR1_CS_BITS 0x7
+#else
+    #error Unexpected CPU speed
 #endif

-// Tracks the current register pointer position
-volatile byte reg_position;
-const byte reg_count = 3;
-
-/**
- * This is called for each read request we receive, never put more than one byte of data (with TinyWireS.send) to the
- * send-buffer when using this callback
+/*
+ * Handle a 'get' request from the I2C master.
  */
 void requestEvent()
 {
     byte value = 0;
-    switch (reg_position) {
-    case 0:
-       value = OCR1A;
-       break;
-    case 1:
-       value = OCR1B;
-       break;
-    case 2:
-       value = byte(analogRead(3) >> 2);
+    switch (currentRegister) {
+    case I2cRegLeftServoLo:
+       value = lowByte(leftServoMicros);
+       break;
+    case I2cRegLeftServoHi:
+       value = highByte(leftServoMicros);
+       break;
+    case I2cRegRightServoLo:
+       value = lowByte(rightServoMicros);
+       break;
+    case I2cRegRightServoHi:
+       value = highByte(rightServoMicros);
+       break;
+    case I2cRegBatteryLo:
+       value = lowByte(batteryMicroVolts);
+       break;
+    case I2cRegBatteryHi:
+       value = highByte(batteryMicroVolts);
        break;
     }
     TinyWireS.send(value);
-    reg_position++;
-    if (reg_position >= reg_count)
-       reg_position = 0;
-}
-
-/**
- * The I2C data receive handler
- *
- * This needs to complete before the next incoming transaction (start, data, restart/stop) on the bus does
- * so be quick, set flags for long running tasks to be called from the mainloop instead of running them directly,
+    currentRegister++;
+    if (currentRegister >= I2cRegCount)
+       currentRegister = 0;
+}
+
+/*
+ * Handle a 'set' request from the I2C master.
  */
 void receiveEvent(uint8_t howMany)
 {
+   static uint16_t nextLeftServoMicros = 0;
+   static uint16_t nextRightServoMicros = 0;
+
     // Sanity check
-    if (howMany < 1 || howMany > TWI_RX_BUFFER_SIZE)
+    if (howMany < 1 || howMany > I2cRegCount)
       return;

     // Read register position
-    reg_position = TinyWireS.receive();
+    currentRegister = TinyWireS.receive();
     howMany--;

-    if (reg_position >= reg_count) {
+    if (currentRegister >= I2cRegCount) {
        // If invalid register, ignore the request
-       reg_position = 0;
+       currentRegister = 0;
        return;
     }

@@ -131,60 +171,101 @@
     while (howMany) {
        byte value = TinyWireS.receive();
        howMany--;
-      switch (reg_position) {
-      case 0:
-         if (value >= 17 && value <= 28)
-            OCR1A = value;
-         break;
-      case 1:
-         if (value >= 17 && value <= 28)
-            OCR1B = value;
+      switch (currentRegister) {
+      case I2cRegLeftServoLo:
+         nextLeftServoMicros = (nextLeftServoMicros & 0xff00) | value;
+         break;
+      case I2cRegLeftServoHi:
+         nextLeftServoMicros = (nextLeftServoMicros & 0x00ff) | (value << 8);
+         break;
+      case I2cRegRightServoLo:
+         nextRightServoMicros = (nextRightServoMicros & 0xff00) | value;
+         break;
+      case I2cRegRightServoHi:
+         nextRightServoMicros = (nextRightServoMicros & 0x00ff) | (value << 8);
          break;
       default:
          break;
       }
-      reg_position++;
-      if (reg_position >= reg_count)
-         reg_position = 0;
+      currentRegister++;
+      if (currentRegister >= I2cRegCount)
+         currentRegister = 0;
     }
-}
-
+
+    if (nextLeftServoMicros >= 1000 && nextLeftServoMicros <= 2000)
+         leftServoMicros = nextLeftServoMicros;
+
+    if (nextRightServoMicros >= 1000 && nextRightServoMicros <= 2000)
+         rightServoMicros = nextRightServoMicros;
+}

 void setup()
 {
     // Servos like PWM durations around 1.5 ms with periods of 15-20 ms
-    //
-    // Set Timer/Counter 1 to increment at 15625 Hz (8 MHz/512) and
-    // count to 255. This gives a PWM period of ~16 ms (256/15625)
-    // See ATtiny25/45/85 datasheet
-    // OCR1C = value to count up to (period for PWM)
-    // COM1A1,COM1A0 = 1,0  # set output low when counter matches OCR1A value (See Table 13-1)
-    OCR1C = 255; // Count to 255, then reset counter
-    OCR1A = 22; // servo idle (~1.5 ms)
-    OCR1B = 22; // servo idle (~1.5 ms)
-    TCCR1 = _BV(PWM1A) | _BV(COM1A1) | 0xa; // Enable PWM1A; CK/512 (Table 12-5) NOTE: Table 12-5 not for PWM Mode???
-    GTCCR = _BV(PWM1B) | _BV(COM1B1);       // Enable PWM1B
-
-    pinMode(1, OUTPUT); // PWM1A
-    pinMode(4, OUTPUT); // PWM1B
+    // The important part is the duration.
+
+    // Since the ATtiny85 only has an 8 bit PWM, there's not enough precision
+    // to just use a PWM (aka Timer/Counter). To see this, we'd like to get
+    // 180 or more steps between 1-2 ms (so that we can do 0-180 degrees with
+    // 1 degree resolution). This requires about 5 uS resolution. To get to
+    // 20 ms would require counting to 4000, and that's not considering that
+    // the ATtiny85 can't be set to count at any frequency.
+
+    // What we do instead is send a pulse using Timer/Counter1 and then busy
+    // wait between pulses. The busy wait doesn't need to be perfect, so if
+    // I2C handling delays things a little, that's ok.
+
+    pinMode(1, OUTPUT); // Left servo
+    pinMode(4, OUTPUT); // Right servo
     pinMode(3, INPUT);  // Battery level

     /**
      * Reminder: taking care of pull-ups is the masters job
      */
-
     TinyWireS.begin(I2C_SLAVE_ADDRESS);
     TinyWireS.onReceive(receiveEvent);
     TinyWireS.onRequest(requestEvent);
 }

+uint8_t mapServoMicros(uint16_t micros)
+{
+    return (uint8_t) (uint32_t(micros - 16) * 254 / 2032) + 1;
+}
+
 void loop()
 {
-    /**
-     * This is the only way we can detect stop condition (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=984716&sid=82e9dc7299a8243b86cf7969dd41b5b5#984716)
-     * it needs to be called in a very tight loop in order not to miss any (REMINDER: Do *not* use delay() anywhere, use tws_delay() instead).
-     * It will call the function registered via TinyWireS.onReceive(); if there is data in the buffer on stop.
-     */
-    TinyWireS_stop_check();
-}
-
+    // Our target is around 20 ms between pulses, so wait for 19 ms
+    // between pulses to give time for ADC read and calculations.
+    tws_delay(19); // Can't call delay() due to TinyWireS limitation
+
+    // Sample the battery voltage (this takes about 100 microseconds according to docs)
+    // The battery voltage is halved by a resister divider so that 6 V is
+    // less that the 3.3 V reference voltage.
+    batteryMicroVolts = (uint16_t) (uint32_t(analogRead(3)) * 2 * 3300 / 1023); // 6600 microvolts at 1023 counts
+
+    // Start the counter over from 0 (Have to do this first to avoid spurious pulse since
+    // there's no stopping the timer/counter)
+    TCNT1 = 0;
+
+    // Calculate the new pulse durations
+    // This calculation takes more than a few microseconds, so will need to restart the
+    // TCNT1 to accurately measure the duration
+    OCR1A = mapServoMicros(leftServoMicros);
+    OCR1B = mapServoMicros(rightServoMicros);
+
+    // Force both outputs high.
+    // The way this is done is by telling the Timer/Counter to set the outputs
+    // high on match and then artificially trigger a match.
+    // NOTE: You can't just set the output high since the Timer/Counter is now
+    //       controlling it.
+    TCCR1 = (1 << COM1A1) | (1 << COM1A0) | TCCR1_CS_BITS;
+    GTCCR = (1 << COM1B1) | (1 << COM1B0) | (1 << FOC1B) | (1 << FOC1A);
+
+    // Start the counter counting for real now that the outputs are officially high
+    TCNT1 = 0;
+
+    // Tell the Timer/Counter to set the outputs low on match (a real match this time)
+    GTCCR = (1 << COM1B1) | (0 << COM1B0);
+    TCCR1 = (1 << COM1A1) | (0 << COM1A0) | TCCR1_CS_BITS;
+}
+


Print downlink ack status in examples

Print downlink ack status in examples

When a packet is received that has the ack flag set, print a notice
about that.

--- examples/ttn-abp/ttn-abp.ino
+++ examples/ttn-abp/ttn-abp.ino
@@ -101,6 +101,8 @@
             break;
         case EV_TXCOMPLETE:
             Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
+            if (LMIC.txrxFlags & TXRX_ACK)
+              Serial.println(F("Received ack"));
             if (LMIC.dataLen) {
               Serial.println(F("Received "));
               Serial.println(LMIC.dataLen);


IRSend now sets my light to strobe mode

IRSend now sets my light to strobe mode

--- IRSend/IRSend.ino
+++ IRSend/IRSend.ino
@@ -1,29 +1,28 @@
+#include <Arduino.h>
 #include <IRremote2.h>

-#if defined(__SAM3X8E__) || defined(__SAM3X8H)
-  // This is an Arudino Due, probably my Tilda MKe
-  #define LED 72
-  #define DEBUG SerialUSB
-#else
-  // Its something else
-  #define LED 13
-  #define DEBUG Serial
-#endif
+#define LED PIN_LED_RXL
+#define BUTTON BUTTON_A
+
+int i = 0;
+long codes[4] = { 0xF720DF, 0xF7A05F, 0xF7609F, 0xF7E01F };

 IRsend irsend;

 void setup() {
-//  while(!SerialUSB);
-  DEBUG.begin(9600);
-  DEBUG
+  pinMode(BUTTON, INPUT);
+  pinMode(LED, OUTPUT);
+  digitalWrite(LED, LOW);
 }

 void loop() {
-  DEBUG.print(".");
-  digitalWrite(LED, HIGH);
-  irsend.sendNEC(0x20DF10EF, 32);
-  delay(1000);
-
-  digitalWrite(LED, LOW);
-  delay(1000);
+  if (digitalRead(BUTTON) == LOW) {
+    digitalWrite(LED, HIGH);
+    irsend.sendNEC(codes[i], 32);
+    i += 1;
+    if (i > 3) { i = 0; }
+    delay(50);
+  } else {
+    digitalWrite(LED, LOW);
+  }
 }


Sending SMS on initialization of weather station: OK

--- IWMIv3/IWMIv3.ino
+++ IWMIv3/IWMIv3.ino
@@ -22,6 +22,7 @@
 #include "MPL3115A2.h" //Pressure sensor
 #include "HTU21D.h" //Humidity sensor
 #include <SoftwareSerial.h> //Needed for GPS
+#include "GSM_Module.h" //Needed for SMS/Server upload
 #include <TinyGPS++.h> //GPS parsing
 #include <LiquidCrystal_I2C.h>//16x2 LCD library
 //It requires using fm's LiquidCrystal library replacement:
@@ -33,53 +34,17 @@
 //Some use this PCF8574
 LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

-//this is for RTC
-int clockAddress = 0x68;  // This is the I2C address
-int command = 0;  // This is the command char, in ascii form, sent from the serial port
-long previousMillis = 0;  // will store last time Temp was updated
-byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
-
-byte decToBcd(byte val)
-{
-  return ( (val/10*16) + (val%10) );
-}
-
-// Convert binary coded decimal to normal decimal numbers
-byte bcdToDec(byte val)
-{
-  return ( (val/16*10) + (val%16) );
-}
-
-// Gets the date and time from the ds1307 and prints result
-char* getDateDs1307(int flag) {
-  //if flag == 0 : date output
-  //if flag == 1 : time output
-  // Reset the register pointer
-  Wire.beginTransmission(clockAddress);
-  Wire.write(byte(0x00));
-  Wire.endTransmission();
-
-  Wire.requestFrom(clockAddress, 7);
-
-  // A few of these need masks because certain bits are control bits
-  second     = bcdToDec(Wire.read() & 0x7f);
-  minute     = bcdToDec(Wire.read());
-
-  // Need to change this if 12 hour am/pm
-  hour       = bcdToDec(Wire.read() & 0x3f);
-  dayOfWeek  = bcdToDec(Wire.read());
-  dayOfMonth = bcdToDec(Wire.read());
-  month      = bcdToDec(Wire.read());
-  year       = bcdToDec(Wire.read());
-
-  char sza[32];
-  if (flag==0)
-    sprintf(sza, "%02d-%02d-%02d",year,month,dayOfMonth);
-  if (flag==1)
-    sprintf(sza, "%02d:%02d:%02d",hour,minute,second);
-  return(sza);
-}
-//end of RTC
+//FOR GSM COMS
+GSM_Module Module(SIM900);// For SIM900 GSM
+//GSM_Module Module(SM5100B);// For SM5100B GSM
+//SERVER Definitions
+//String HOST      = "lahiruwije.ddns.net";   // Host name or address of the web server
+//int    PORT      = 80;
+String Mobile_No = "+94776141305";          // Mobile Number which the SMS Sends
+String Test_SMS  = "IWMIMWSv3 Station initializing";    // Test content of the SMS
+int Status;
+
+

 TinyGPSPlus gps;
@@ -284,10 +249,45 @@
   delay(1000);
   digitalWrite(STAT2, LOW); //Blink stat LED
   lcd.print("Weather Station online!");
+
+  //GSM COMS MODULE
+  /*****************************************************************************************************************
+    Initialize the GSM module.
+  *****************************************************************************************************************/
+  Serial.println("Module Initializing..");
+  Status = Module.Init(9600);
+  if( Status == OK ){
+    Serial.println("Module Ready.");
+  }else{
+    Serial.println("Module Initializing Failed.");
+    Serial.print("ERROR : ");
+    Serial.println(Status);
+    while(1){};
+  }
+  Module.Refresh();
+  delay(5000);
+  /*****************************************************************************************************************
+    Finished Initializing the GSM module.
+  *****************************************************************************************************************/
+  /*****************************************************************************************************************
+    Sending a test SMS
+  *****************************************************************************************************************/
+  Serial.println("Sending a Test SMS");
+  Status = Module.Send_SMS(Mobile_No, Test_SMS);
+  if( Status == OK ){
+    Serial.println("SMS Sent");
+  }else{
+    Serial.print("SMS ERROR : ");
+    Serial.println(Status);
+  }
+  /*****************************************************************************************************************
+    Finished Sending a test SMS
+  *****************************************************************************************************************/
 }

 void loop()
 {
+
   //Keep track of which minute it is
   loopMSecond = millis() - lastSecond;
   digitalWrite(STAT2, HIGH); //Blink stat LED


Update arduino.ino

Update arduino.ino

--- Arduino/arduino/arduino.ino
+++ Arduino/arduino/arduino.ino
@@ -132,7 +132,8 @@
   }
   // on mémorise l'id
   char strId[sizeof(id->valuestring)*2];
-  String(id->valuestring).toCharArray(strId, sizeof(strId));
+  String(id->valuestring).toCharArray(strId, sizeof(strId));
+  //char *strId = id->valuestring;

   // attribut action
   aJsonObject *action = aJson.getObjectItem(json, "ac");
@@ -146,8 +147,9 @@
   }
   // on mémorise l'action
   //String strAction = action->valuestring;
-  char strAction[sizeof(action->valuestring)*2];
-  String(action->valuestring).toCharArray(strAction, sizeof(strAction));
+  /*char strAction[sizeof(action->valuestring)*2];
+  String(action->valuestring).toCharArray(strAction, sizeof(strAction));*/
+  char *strAction = action->valuestring;

   // on récupère les parametres
   aJsonObject *parametres = aJson.getObjectItem(json, "pa");
@@ -217,7 +219,7 @@

 // lecture d'une commande du serveur
 String lireCommande(EthernetClient *client){
-  String commande;;
+  String commande;
   while(client->available()) {
     char c = client->read();
     commande += c;
@@ -239,6 +241,7 @@
   if(etat==NULL) etat="{}";
   // construction de la réponse
   String reponse="{\"id\":\""+id+"\",\"er\":\""+erreur+"\",\"et\":"+etat+"}";
+  //String reponse = "{\"id\":\""+id+"\",\"er\":\""+erreur+"\",\"et\":\""+etat+"\"}";
   // résultat
   return reponse;
 }


Update arduino.ino

Update arduino.ino

Utilise plus de pointeurs et de variables globales pour limiter la consommation mémoire.
Effectue des vérifications sur les paramètres json reçus, en cas d'erreur un code erreur spécifique est renvoyé au serveur.

--- Arduino/arduino/arduino.ino
+++ Arduino/arduino/arduino.ino
@@ -14,6 +14,8 @@
 IPAddress ipServeurEnregistrement(192,168,2,1); // IP du serveur d'enregistrement
 int portServeurEnregistrement=100; // port du serveur d'enregistrement
 EthernetClient clientArduino; // le client Arduino du serveur d'enregistrement
+String commandeGlobal; //commande reçue par le serveur
+String reponseGlobal; //réponse à envoyer au serveur

 // initialisation
 void setup() {
@@ -32,7 +34,7 @@
   while(!enregistrementFait){
     // on se connecte au serveur d'enregistrement
     Serial.println(F("Connexion au serveur d'enregistrement..."));
-    if (connecte(&clientArduino,ipServeurEnregistrement,portServeurEnregistrement)) {
+    if (connecte(&clientArduino,&ipServeurEnregistrement,&portServeurEnregistrement)) {
       // suivi
       Serial.println(F("Connecte..."));
       // on envoie l'adresse Mac de l'Arduino, une description de ses fonctionnalités, son port de service
@@ -78,15 +80,15 @@
       Serial.print(F("Memoire disponible debut boucle : "));
       Serial.println(freeRam());
       // on lit la commande de ce client
-      String commande=lireCommande(&client);
+      commandeGlobal=lireCommande(&client);
       // suivi
       Serial.print(F("commande : ["));
-      Serial.print(commande);
+      Serial.print(commandeGlobal);
       Serial.println(F("]"));
       // si la commande est vide, on ne la traite pas
-      if(commande.length()==0) continue;
+      if(commandeGlobal.length()==0) continue;
       // sinon on la traite
-      traiterCommande(&client,commande);
+      traiterCommande(&client,&commandeGlobal);
       // mémoire disponible
       Serial.print(F("Memoire disponible fin boucle : "));
       Serial.println(freeRam());
@@ -106,11 +108,11 @@
 }

 // traitement d'une commande
-void traiterCommande(EthernetClient *client, String commande){
+void traiterCommande(EthernetClient *client, String *commande){
   // on décode la commande pour voir quelle action est demandée
-  int l = commande.length();
+  int l = (*commande).length();
   char cmd[l+1];
-  commande.toCharArray(cmd, l+1);
+  (*commande).toCharArray(cmd, l+1);
   // on parse la commande JSON
   aJsonObject *json = aJson.parse(cmd);

@@ -131,16 +133,7 @@
     return;
   }
   // on mémorise l'id
-  char strId[sizeof(id->valuestring)*2];
-  String(id->valuestring).toCharArray(strId, sizeof(strId));
-  /* get last digit if id is an ip => causes problems because of lack of memory
-  int index = String(id->valuestring).lastIndexOf('.');
-  String subString = String(id->valuestring).substring(index+1);
-  char strId[sizeof(subString)*2];
-  subString.toCharArray(strId, sizeof(strId));
-  Serial.print("Debug: id = ");
-  Serial.println(strId);
-  */
+  char *strId = id->valuestring;

   // attribut action
   aJsonObject *action = aJson.getObjectItem(json, "ac");
@@ -217,19 +210,19 @@
 }

   // connexion au serveur
-int connecte(EthernetClient *client, IPAddress serveurIP, int serveurPort) {
+int connecte(EthernetClient *client, IPAddress *serveurIP, int *serveurPort) {
   delay(1000); // on se connecte au serveur après 1 seconde d'attente
-  return client->connect(serveurIP, serveurPort);
+  return client->connect(*serveurIP, *serveurPort);
 }

 // lecture d'une commande du serveur
 String lireCommande(EthernetClient *client){
-  String commande;
+  commandeGlobal = "";
   while(client->available()) {
     char c = client->read();
-    commande += c;
-  }
-  return commande; // on rend la commande
+    commandeGlobal += c;
+  }
+  return commandeGlobal; // on rend la commande
 }

 // formatage json de la réponse au client
@@ -241,10 +234,11 @@
   if(erreur==NULL) erreur="";
   // attribut etat - pour l'instant dictionnaire vide
   if(etat==NULL) etat="{}";
+
   // construction de la réponse
-  String reponse="{\"id\":\""+id+"\",\"er\":\""+erreur+"\",\"et\":"+etat+"}";
+  reponseGlobal="{\"id\":\""+id+"\",\"er\":\""+erreur+"\",\"et\":"+etat+"}";
   // résultat
-  return reponse;
+  return reponseGlobal;
 }

 // echo
@@ -258,53 +252,63 @@
   // il faut une pin
   aJsonObject *pin = aJson.getObjectItem(parametres, "pin");
   if(pin==NULL){
-    // réponse d'erreur
+    // réponse d'erreur 201
+    sendReponse(client, reponse(strId,"201",NULL));
+    return;
+  }
+  // valeur de la pin à eteindre
+  int led = atoi(pin->valuestring);
+  //paramètre pin non numérique ou hors des limites: erreur 202
+  if(!isValidNumber(pin) || led < 0 || led > 13) {
     sendReponse(client, reponse(strId,"202",NULL));
     return;
   }
-  // valeur de la pin à eteindre
-  String strLed = pin->valuestring;
-  int led = strLed.toInt();
   Serial.print(F("clignoter led="));
   Serial.println(led);
-
+
   // il faut la durée d'un clignotement
   aJsonObject *dur = aJson.getObjectItem(parametres, "dur");
   if(dur==NULL){
     // réponse d'erreur
-    sendReponse(client, reponse(strId,"211",NULL));
+    sendReponse(client, reponse(strId,"203",NULL));
     return;
   }
   // valeur de la durée
-  String strDuree = dur->valuestring;
-  int duree = strDuree.toInt();
+  int duree = atoi(dur->valuestring);
+  //paramètre durée non numérique ou non supérieur à 0: erreur 204
+  if(!isValidNumber(dur) || duree < 1) {
+    sendReponse(client, reponse(strId,"204",NULL));
+    return;
+  }
   Serial.print(F("duree="));
   Serial.println(duree);
-
+
   // il faut le nombre de clignotements
   aJsonObject *nb = aJson.getObjectItem(parametres, "nb");
   if(nb==NULL){
     // réponse d'erreur
-    sendReponse(client, reponse(strId,"212",NULL));
+    sendReponse(client, reponse(strId,"205",NULL));
     return;
   }
   // valeur du nombre de clignotements
-  String strNbClignotements = nb->valuestring;
-  int nbClignotements = strNbClignotements.toInt();
+  int nbClignotements = atoi(nb->valuestring);
+  //paramètre nb non numérique ou non supérieur à 0: erreur 206
+  if(!isValidNumber(nb) || nbClignotements < 1) {
+    sendReponse(client, reponse(strId,"206",NULL));
+    return;
+  }
   Serial.print(F("nb="));
   Serial.println(nbClignotements);
-
+
   // on rend la réponse tout de suite
   sendReponse(client, reponse(strId,"0",NULL));
   // on opère le clignotement
-  int i = 0;
   pinMode(led, OUTPUT);
-  while(i < nbClignotements) {
+  for(int i=0; i < nbClignotements; ++i) {
     digitalWrite(led, HIGH);
     delay(duree);
     digitalWrite(led, LOW);
     delay(duree);
-    ++i;
   }
 }

@@ -313,41 +317,51 @@
   // il faut une pin
   aJsonObject *pin = aJson.getObjectItem(parametres, "pin");
   if(pin==NULL){
-    sendReponse(client, reponse(strId,"201",NULL)); // réponse d'erreur
+    sendReponse(client, reponse(strId,"301",NULL)); // réponse d'erreur
     return;
   }
   // numéro de la pin à écrire
-  String strPin = pin->valuestring;
-  int pin2 = strPin.toInt();
+  int pin2 = atoi(pin->valuestring);
   // suivi
   Serial.print(F("pw pin="));
   Serial.println(pin2);
   // il faut une valeur
   aJsonObject *val = aJson.getObjectItem(parametres, "val");
   if(val==NULL){
-    sendReponse(client, reponse(strId,"202",NULL)); // réponse d'erreur
+    sendReponse(client, reponse(strId,"302",NULL)); // réponse d'erreur
     return;
   }
   // valeur à écrire
-  String strVal = val->valuestring;
-  int val2 = strVal.toInt();
+  int val2 = atoi(val->valuestring);
+
   // suivi
   Serial.print(F("pw val="));
   Serial.println(val2);
   // il faut un mode d'écriture
   aJsonObject *mod = aJson.getObjectItem(parametres, "mod");
   if(mod==NULL){
-      sendReponse(client, reponse(strId,"203",NULL)); // réponse d'erreur
+      sendReponse(client, reponse(strId,"303",NULL)); // réponse d'erreur
       return;
   }

   char* mod2 = mod->valuestring;

-  // ce doit être a (analogique) ou b (binaire)
+  // le mod doit être a (analogique) ou b (binaire)
   if(strcmp(mod2,"b")!=0 && strcmp(mod2,"a")!=0){
-    sendReponse(client, reponse(strId,"204",NULL)); // réponse d'erreur
-    return;
-  }
+    sendReponse(client, reponse(strId,"304",NULL)); // réponse d'erreur
+    return;
+  }
+  //paramètre pin non numérique ou pas dans les bornes (selon mode binaire ou analogique): erreur 305
+  if(!isValidNumber(pin) || (strcmp(mod2, "b")==0 && (pin2 < 0 || pin2 > 13)) || (strcmp(mod2, "a")==0 && (pin2 < 0 || pin2 > 5)) ) {
+    sendReponse(client, reponse(strId,"305",NULL)); // réponse d'erreur
+    return;
+  }
+  //paramètre val non numérique ou pas dans les bornes (selon mode binaire ou analogique): erreur 306
+  if(!isValidNumber(val) || (strcmp(mod2, "b")==0 && (val2 < 0 || val2 > 1)) || (strcmp(mod2, "a")==0 && (val2 < 0 || val2 > 255)) ) {
+    sendReponse(client, reponse(strId,"306",NULL)); // réponse d'erreur
+    return;
+  }
+
   // c'est bon pas d'erreur
   sendReponse(client,reponse(strId,"0",NULL));
   // suivi
@@ -369,19 +383,18 @@
   aJsonObject *pin = aJson.getObjectItem(parametres, "pin");
   if(pin==NULL){
     // réponse d'erreur
-    sendReponse(client, reponse(strId,"302",NULL));
+    sendReponse(client, reponse(strId,"401",NULL));
     return;
   }
   // numéro de la pin à lire
-  String strPin = pin->valuestring;
-  int pin2 = strPin.toInt();
+  int pin2 = atoi(pin->valuestring);
   // suivi
   Serial.print(F("pr pin="));
   Serial.println(pin2);
   // il faut un mode d'écriture
   aJsonObject *mod = aJson.getObjectItem(parametres, "mod");
   if(mod==NULL){
-    sendReponse(client, reponse(strId,"303",NULL)); // réponse d'erreur
+    sendReponse(client, reponse(strId,"402",NULL)); // réponse d'erreur
     return;
   }
   char* mod2 = mod->valuestring;
@@ -389,12 +402,18 @@
   // ce doit être a (analogique) ou b (binaire)
   if(strcmp(mod2,"a")!=0 && strcmp(mod2,"b")!=0){
     // réponse d'erreur
-    sendReponse(client, reponse(strId,"304",NULL));
+    sendReponse(client, reponse(strId,"403",NULL));
+    return;
+  }
+
+  //paramètre pin non numérique ou hors des limites: erreur 404
+  if(!isValidNumber(pin) || (strcmp(mod2, "b")==0 && (pin2 < 0 || pin2 > 13)) || (strcmp(mod2, "a")==0 && (pin2 < 0 || pin2 > 5)) ) {
+    sendReponse(client, reponse(strId,"404",NULL)); // réponse d'erreur
     return;
   }
   // c'est bon pas d'erreur
   // suivi
-  Serial.print(F("pw mod="));
+  Serial.print(F("pr mod="));
   Serial.println(mod2);
   // on lit la pin
   pinMode(pin2, INPUT);
@@ -406,13 +425,25 @@
   sendReponse(client, reponse(strId,"0",json));
 }

-// envoi réponse
+// envoi réponse au client
 void sendReponse(EthernetClient *client, String message){
+  Serial.print(F("Memoire disponible : ")); // mémoire disponible
+  Serial.println(freeRam());
   // envoi de la réponse
   client->println(message);
   // suivi
   Serial.print(F("reponse="));
   Serial.println(message);
+}
+
+//vérifie que la valeur json en paramètre est numérique
+boolean isValidNumber(aJsonObject *json) {
+   boolean isNum = false;
+   for(byte i=0; i < String(json->valuestring).length(); ++i) {
+     isNum = isDigit(String(json->valuestring).charAt(i));
+     if(!isNum) return false;
+   }
+   return isNum;
 }

 // mémoire libre


Debug printing of wifi IP

Debug printing of wifi IP

--- Sattrack.ino
+++ Sattrack.ino
@@ -79,8 +79,13 @@

   #ifdef DEBUG
     Serial.println();
-    Serial.print("IP address: ");
-    Serial.println(WiFi.localIP());
+    if (!dataError) {
+        Serial.print("Local IP address: ");
+        Serial.println(WiFi.localIP());
+    } else {
+        Serial.print("SoftAP IP address: ");
+        Serial.println(WiFi.softAPIP());
+    }
     Serial.println();
   #endif


Revision changes done

Revision changes done

--- libraries/BLE/examples/ble_A_Hello_World_Program/ble_A_Hello_World_Program.ino
+++ libraries/BLE/examples/ble_A_Hello_World_Program/ble_A_Hello_World_Program.ino
@@ -3,7 +3,7 @@
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sub-license, and/or sell
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  * copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
  *


Example new code style

Example new code style

--- lib-arduino/ACNode/examples/DoorNode/DoorNode.ino
+++ lib-arduino/ACNode/examples/DoorNode/DoorNode.ino
@@ -48,7 +48,23 @@
 // sent an i-am-alive ping every 3 seconds.
 #define DEBUG_ALIVE

-#import <ACNode.h>
+#ifdef  ESP32
+#include <WiFi.h>
+#include <ESPmDNS.h>
+#include <WiFiUdp.h>
+#else
+#include <ESP8266WiFi.h>
+#endif
+#include <PubSubClient.h>        // https://github.com/knolleary/
+
+#include <SPI.h>
+
+#include "MakerspaceMQTT.h"
+#include "Log.h"
+#include "LEDs.h"
+#include "OTA.h"
+#include "ConfigPortal.h"
+#include "RFID.h"

 WiFiClient espClient;
 PubSubClient client(espClient);


Updated XML

Updated XML

--- WebRGB_LED/WebRGB_LED.ino
+++ WebRGB_LED/WebRGB_LED.ino
@@ -40,7 +40,7 @@

 //Webserver
 static uint8_t MAC[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
-static uint8_t IP[] = {192, 168, 1, 200};
+static uint8_t IP[] = {172, 18, 16, 200};
 WebServer webserver("", 80);

 //Variables
@@ -138,13 +138,13 @@
   "updateHandler();"
   "}"
   "function setLights(red, green, blue, transition, ttime) {"
-  "$.post('http://192.168.1.200/service', {r: red, g: green, b: blue, trans: transition, time: ttime})"
+  "$.post('http://172.18.16.200/service', {r: red, g: green, b: blue, trans: transition, time: ttime})"
   ".done(function(data) {"
   "handleXMLresponse(data);"
   "});"
   "}"
   "function getLightState() {"
-  "$.get('http://192.168.1.200/service')"
+  "$.get('http://172.18.16.200/service')"
   ".done(function(data) {"
   "handleXMLresponse(data);"
   "});"
@@ -244,6 +244,7 @@
     }
   }
   if((type == WebServer::POST) || (type == WebServer::GET)) {
+    server.println("<?xml version='1.0'?>");
     server.println("<xml>");
     server.println("<currentColour>");
     server.print("<r>");


Fixed a bug where first input of first iteration...

...of inner loop is skipped.


v2.0 Add file size to display file name screen

--- PictureViewer.ino
+++ PictureViewer.ino
@@ -137,7 +137,7 @@
   boolean  flip    = true;        // BMP is stored bottom-to-top
   int      w, h, row, col;
   uint8_t  r, g, b;
-  uint32_t pos = 0, startTime = millis();
+  uint32_t pos = 0;

   if ((x >= tft.width()) || (y >= tft.height())) return;

@@ -152,7 +152,6 @@
     displayFileName(filename, false);
     return (false);
   }
-  displayFileName(filename);

   // Parse BMP header
   if (read16(bmpFile) == 0x4D42) { // BMP signature
@@ -182,6 +181,8 @@
         Serial.print('H');
         Serial.println(" Pixels");

+        displayFileName(filename, true, bmpWidth, bmpHeight);
+
         // BMP rows are padded (if needed) to 4-byte boundary
         rowSize = (bmpWidth * 3 + 3) & ~3;

@@ -232,9 +233,6 @@
             tft.pushColor(tft.Color565(r, g, b));
           } // end pixel
         } // end scanline
-        Serial.print("Loaded in ");
-        Serial.print(millis() - startTime);
-        Serial.println(" ms");
       } // end goodBmp
     }
   }
@@ -311,7 +309,7 @@
 }

 // Displays the file name
-void displayFileName(char *fileName, boolean fileFound) {
+void displayFileName(char *fileName, boolean fileFound, int bmpWidth, int bmpHeight) {
   static long lastRandomNumber;
   long randomColor;
   unsigned int textColor[] = {
@@ -348,14 +346,24 @@
   tft.println("File Name:");
   tft.setCursor(10, 80);
   tft.println(fileName);
-  tft.setCursor(15, 120);
+  tft.setTextSize(1);
   if (!fileFound) {
-    tft.setTextSize(1);
+    tft.setCursor(15, 110);
     tft.println("File not found");
   }
-  tft.setCursor(75, 150);
-  tft.setTextSize(1);
+  else {
+    tft.setCursor(10, 110);
+    tft.println("File Size: ");
+    tft.setCursor(10, 120);
+    tft.print(bmpWidth);
+    tft.print("W ");
+    tft.print("x ");
+    tft.print(bmpHeight);
+    tft.print('H');
+    tft.println(" Pixels");
+  }
+  tft.setCursor(50, 150);
   tft.println(colorType[randomColor]);
-  delay(3000);
+  delay(5000);
   tft.fillScreen(ST7735_BLACK);
 }


Config code

Config code

--- VardeLED.ino
+++ VardeLED.ino
@@ -2,17 +2,34 @@
 #include <SPI.h>
 #include <Ethernet.h>
 #include <ArtNode.h>
+
 #include "TeensyMAC.h"
-
-#define NUM_RGBW  144
+#include <EEPROM.h>
+
+#define VERSION_HI 0
+#define VERSION_LO 2
+
+#define NUM_RGBW  128*2
 #define NUM_RGB   (NUM_RGBW/4*3)
 #define PIN_RESET 9

+// ID of the settings block
+#define CONFIG_VERSION "ls1"
+
+// Tell it where to store your config data in EEPROM
+#define CONFIG_MEM_START 16
+#define CONFIG_START 17
+#define CONFIG_END 2
+
 EthernetUDP udp;
 byte buffer[600];

 CRGB leds1[NUM_RGB];
 CRGB leds2[NUM_RGB];
+CRGB leds3[NUM_RGB];
+CRGB leds4[NUM_RGB];
+
+bool locateMode = false;

 int oemCode = 0x0000; // OemUnkown

@@ -26,16 +43,24 @@
   0, 0,                                 // Net (0-127) and subnet (0-15)
   "VardeLED",                           // Short name
   "VardeLED",                           // Long name
-  1,                                    // Number of ports
+  4,                                    // Number of ports
   {PortTypeDmx|PortTypeOutput, PortTypeDmx|PortTypeOutput, PortTypeDmx|PortTypeOutput, PortTypeDmx|PortTypeOutput}, // Port types
-  {2, 3, 4, 5},                         // Port input universes (0-15)
-  {5, 6, 7, 8}                          // Port output universes (0-15)
+  {0, 0, 0, 0},                         // Port input universes (0-15)
+  {0, 1, 2, 3},                          // Port output universes (0-15)
+  VERSION_HI,
+  VERSION_LO
 };

 ArtNode node;
 ////////////////////////////////////////////////////////////

 void setup() {
+  loadConfig();
+
+  config.numPorts = 4;
+  for(int i=0;i<config.numPorts;i++){
+    config.portTypes[i]= PortTypeDmx|PortTypeOutput;
+  }

 #ifdef PIN_RESET
   pinMode(PIN_RESET, OUTPUT);
@@ -69,7 +94,13 @@
   node = ArtNode(config, sizeof(buffer), buffer);

   FastLED.addLeds<WS2812, 5, RGB>(leds1, NUM_RGB);
-  FastLED.addLeds<WS2812, 21, RGB>(leds2, NUM_RGB);
+  FastLED.addLeds<WS2812, 20, RGB>(leds2, NUM_RGB);
+  FastLED.addLeds<WS2812, 8, RGB>(leds3, NUM_RGB);
+  FastLED.addLeds<WS2812, 14, RGB>(leds4, NUM_RGB);
+
+  Serial.begin(9600);
+
+  blink();
 }

 ////////////////////////////////////////////////////////////
@@ -100,42 +131,144 @@
           case OpDmx: {
             ArtDmx* dmx = (ArtDmx*)buffer;
             int port = node.getPort(dmx->SubUni, dmx->Net);
-            switch (port) {
-              case 0:
-               //mergeRGBWtoLED(dmx->Data, (byte*)leds1, NUM_RGBW);
-                //FastLED[0].show(leds1, NUM_RGB, 255);
-                memcpy(leds1, dmx->Data, NUM_RGBW*4);
-                FastLED[0].show(leds1, NUM_RGB, 255);
-
-                break;
-              case 1:
-                mergeWtoRGBW(dmx->Data, (byte*)leds1, NUM_RGBW);
-                FastLED[0].show(leds1, NUM_RGB, 255);
-                break;
-              case 2:
-                mergeRGBtoRGBW(dmx->Data, (byte*)leds2, NUM_RGBW);
-                FastLED[1].show(leds2, NUM_RGB, 255);
-                break;
-              case 3:
-                mergeWtoRGBW(dmx->Data, (byte*)leds2, NUM_RGBW);
-                FastLED[1].show(leds2, NUM_RGB, 255);
-                break;
+            if(!locateMode){
+              // Bit swap length
+              int l = ((dmx->Length & 0xF) << 8) + ((dmx->Length & 0xF0) >> 8);
+
+              switch (port) {
+                case 0:
+                  memcpy(leds1, dmx->Data, l);
+                  FastLED[0].show(leds1, NUM_RGB, 255);
+                  break;
+                case 1:
+                  memcpy(leds2, dmx->Data, l);
+                  FastLED[1].show(leds2, NUM_RGB, 255);
+                  break;
+                case 2:
+                  memcpy(leds3, dmx->Data, l);
+                  FastLED[2].show(leds3, NUM_RGB, 255);
+
+//                  memcpy(leds1+256, dmx->Data, l);
+  //                FastLED[0].show(leds1, NUM_RGB, 255);
+                  break;
+                case 3:
+                  memcpy(leds4, dmx->Data, l);
+                  FastLED[3].show(leds4, NUM_RGB, 255);
+                  break;
+              }
             }
           }
           break;

+          case OpAddress: {
+            T_ArtAddress * address = (T_ArtAddress*)buffer;
+
+            if(address->LongName[0] != 0)
+              memcpy(config.longName, address->LongName, 64);
+            if(address->ShortName[0] != 0)
+              memcpy(config.shortName, address->ShortName, 18);
+
+            if(address->NetSwitch != 0x7f)
+              config.net = address->NetSwitch;
+
+            if(address->SubSwitch != 0x7f)
+              config.subnet = address->SubSwitch;
+
+
+            for(int i=0;i<4;i++){
+              if(address->SwIn[i] != 0x7f)
+                config.portAddrIn[i] = address->SwIn[i];
+              if(address->SwOut[i] != 0x7f){
+                config.portAddrOut[i] = address->SwOut[i];
+              }
+            }
+
+            if(address->Command == 0x04){
+              locateMode = true;
+            } else {
+              locateMode = false;
+            }
+
+
+            node = ArtNode(config, sizeof(buffer), buffer);
+
+            saveConfig();
+            loadConfig();
+            node.createPollReply();
+            artnetSend(buffer, sizeof(ArtPollReply));
+
+
+            break;
+          }
           // IpProg packet
-          case OpIpProg:
+          /*case OpIpProg:
             node.createIpProgReply();
             artnetSend(buffer, sizeof(ArtIpProgReply));
             break;
-
+*/
           // Unhandled packet
           default:
             break;
         }
       }
     }
+  }
+
+  if(locateMode){
+    byte* d = (byte*)leds1;
+    for(int i=0;i<NUM_RGBW;i++){
+      d[i*4] = 0;
+      d[i*4+1] = (sin(10+i + millis()/100.0)+1)*128.0;
+      d[i*4+2] = 0;
+      d[i*4+3] = (sin(i + millis()/100.0)+1)*128.0;
+
+
+    }
+    FastLED[0].show(leds1, NUM_RGB, 255);
+    FastLED[1].show(leds1, NUM_RGB, 255);
+    FastLED[2].show(leds1, NUM_RGB, 255);
+    FastLED[3].show(leds1, NUM_RGB, 255);
+  }
+}
+
+void blink(){
+  byte* d = (byte*)leds1;
+
+  for(int i=0;i<NUM_RGBW*4;i++){
+    d[i] = 30;
+  }
+  FastLED[0].show(leds1, NUM_RGB, 255);
+
+  delay(300);
+
+  for(int i=0;i<NUM_RGBW*4;i++){
+    d[i] = 0;
+  }
+  FastLED[0].show(leds1, NUM_RGB, 255);
+  delay(100);
+}
+
+
+////////////////////////////////////////////////////////////
+void loadConfig() {
+  // To make sure there are settings, and they are YOURS!
+  // If nothing is found it will use the default settings.
+  if (EEPROM.read(CONFIG_MEM_START + 0) == CONFIG_VERSION[0] &&
+      EEPROM.read(CONFIG_MEM_START + 1) == CONFIG_VERSION[1] &&
+      EEPROM.read(CONFIG_MEM_START + 2) == CONFIG_VERSION[2]){
+    for (unsigned int t=CONFIG_START; t<sizeof(config)-CONFIG_END; t++){
+      *((char*)&config + t ) = EEPROM.read(CONFIG_MEM_START + t + 3 - CONFIG_START);
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////
+void saveConfig() {
+  EEPROM.write(CONFIG_MEM_START + 0, CONFIG_VERSION[0]);
+  EEPROM.write(CONFIG_MEM_START + 1, CONFIG_VERSION[1]);
+  EEPROM.write(CONFIG_MEM_START + 2, CONFIG_VERSION[2]);
+  for (unsigned int t=CONFIG_START; t<sizeof(config)-CONFIG_END; t++){
+    EEPROM.write(CONFIG_MEM_START + t - CONFIG_START + 3, *((char*)&config + t));
   }
 }

@@ -147,35 +280,3 @@
   udp.endPacket();
 }

-////////////////////////////////////////////////////////////
-void mergeRGBWtoLED(uint8_t* rgbw, uint8_t* rgbwout, int n) {
-  for (int i=0; i<n; i++) {
-    rgbwout[0] = rgbw[1];
-    rgbwout[1] = rgbw[0];
-    rgbwout[2] = rgbw[2];
-    rgbwout[3] = rgbw[3];
-    rgbw += 4;
-    rgbwout += 4;
-  }
-}
-
-////////////////////////////////////////////////////////////
-void mergeRGBtoRGBW(uint8_t* rgb, uint8_t* rgbw, int n) {
-  for (int i=0; i<n; i++) {
-    rgbw[1] = rgb[2];
-    rgbw[0] = rgb[0];
-    rgbw[2] = rgb[1];
-    rgb += 3;
-    rgbw += 4;
-  }
-}
-
-////////////////////////////////////////////////////////////
-void mergeWtoRGBW(uint8_t* w, uint8_t* rgbw, int n) {
-  for (int i=0; i<n; i++) {
-    rgbw[3] = w[0];
-    w ++;
-    rgbw += 4;
-  }
-}
-


add debuggind output for timing change responses add timing change on characteristic changed


edited sound sensor

edited sound sensor

--- Modules/Sensor/SoundSensor/ArduinoCodes/SoundSensorATtiny/SoundSensorATtiny.ino
+++ Modules/Sensor/SoundSensor/ArduinoCodes/SoundSensorATtiny/SoundSensorATtiny.ino
@@ -60,7 +60,6 @@
       output_val = 0;
   }
   else{
-      output_val = cutAndMap(signal_max-signal_min, 20, 350, 0, input_val/4);
   }
   analogWrite(output_pin, output_val);
 }


Added Mouse

Added Mouse

--- firmware/malduino_elite/malduino_elite.ino
+++ firmware/malduino_elite/malduino_elite.ino
@@ -7,7 +7,8 @@

 #include <SPI.h>
 #include <SD.h>
-#include "Keyboard.h"
+#include <Keyboard.h>
+#include <Mouse.h>

 #define debug true // <-- uncomment to turn serial output on
 #define CSpin 4 //Chip-Select of the SD-Card reader
@@ -42,12 +43,15 @@

 File payload;
 char* buf = malloc(sizeof(char)*buffersize);
+char* repeatBuffer = malloc(sizeof(char)*12);
+
 int bufSize = 0;
 int defaultDelay = 5;
 int defaultCharDelay = 5;
 bool ledOn = true;
-
-char* repeatBuffer = malloc(sizeof(char)*12);
+int rMin = -100;
+int rMax = 100;
+

 int getSpace(int start, int end){
   for(int i=start;i<end;i++){
@@ -64,11 +68,19 @@
   return true;
 }

+int toPositive(int num){
+  if(num < 0) return num*(-1);
+  else return num;
+}
+
 bool equalsBuffer(int start, int end, char* str){ return equals(buf, start, end, str, String(str).length()); }

 int getInt(char* str, int pos){
-  String amount = String(str).substring(pos+1,pos+6);
-  return amount.toInt();
+  if(equals(str, pos+1, pos+7, "RANDOM", 6)){
+    return random(rMin, rMax);
+  }else{
+    return String(str).substring(pos+1,pos+6).toInt();
+  }
 }

 void KeyboardWrite(uint8_t c){
@@ -92,6 +104,18 @@
     else if(equalsBuffer(0,space,"STRING")){
       for(int i=space+1;i<bufSize;i++) KeyboardWrite(buf[i]);
     }
+    else if(equalsBuffer(0,space,"MOUSE")){
+      int nSpace = getSpace(space+1,bufSize);
+      int x = getInt(buf,space);
+      int y = getInt(buf,nSpace);
+      Mouse.move(x,y);
+      #ifdef debug
+        Serial.println("Move mouse "+(String)x+" "+(String)y);
+      #endif
+    }
+    else if(equalsBuffer(0,space,"SCROLL")) Mouse.move(0,0,getInt(buf,space));
+    else if(equalsBuffer(0,space,"RANDOMMIN")) rMin = getInt(buf,space);
+    else if(equalsBuffer(0,space,"RANDOMMAX")) rMax = getInt(buf,space);
     else if(equalsBuffer(0,space,"REM") || equalsBuffer(0,space,"REPEAT")){}
     else{
       runCommand(0,space);
@@ -169,6 +193,17 @@
   else if(equalsBuffer(s,e,"NUM_PERIOD")) KeyboardWrite(KEYPAD_PERIOD);
   else if(equalsBuffer(s,e,"NUM_PLUS")) KeyboardWrite(KEYPAD_PLUS);

+  else if(equalsBuffer(s,e,"CLICK") || equalsBuffer(s,e,"CLICK_LEFT")) Mouse.click();
+  else if(equalsBuffer(s,e,"CLICK_RIGHT")) Mouse.click(MOUSE_RIGHT);
+  else if(equalsBuffer(s,e,"CLICK_MIDDLE")) Mouse.click(MOUSE_MIDDLE);
+
+  else if(equalsBuffer(s,e,"PRESS") || equalsBuffer(s,e,"PRESS_LEFT")) Mouse.press();
+  else if(equalsBuffer(s,e,"PRESS_LEFT")) Mouse.press(MOUSE_RIGHT);
+  else if(equalsBuffer(s,e,"PRESS_MIDDLE")) Mouse.press(MOUSE_MIDDLE);
+  else if(equalsBuffer(s,e,"RELEASE") || equalsBuffer(s,e,"RELEASE_LEFT")) Mouse.release();
+  else if(equalsBuffer(s,e,"RELEASE_LEFT")) Mouse.release(MOUSE_RIGHT);
+  else if(equalsBuffer(s,e,"RELEASE_MIDDLE")) Mouse.release(MOUSE_MIDDLE);
+
 #ifdef debug
   else Serial.println("failed to find command");
 #endif
@@ -187,7 +222,9 @@
     delay(2000);
     Serial.println("Started!");
   #endif
-
+
+  randomSeed(analogRead(0));
+
   pinMode(ledPin, OUTPUT);
   digitalWrite(ledPin, HIGH);

@@ -220,6 +257,7 @@
     return;
   }else{
     Keyboard.begin();
+    Mouse.begin();
     while(payload.available()){

       buf[bufSize] = payload.read();
@@ -259,6 +297,7 @@
       bufSize = 0;
     }
     payload.close();
+    Mouse.end();
     Keyboard.end();
   }
 }


Change declinaison to Nantes

Change declinaison to Nantes

--- Arduino/MPU9150_AHRS/MPU9150_AHRS.ino
+++ Arduino/MPU9150_AHRS/MPU9150_AHRS.ino
@@ -115,7 +115,7 @@

 // Set up the accelerometer, gyro, and magnetometer for data output

-   mpu.setRate(7); // set gyro rate to 8 kHz/(1 * rate) shows 1 kHz, accelerometer ODR is fixed at 1 KHz
+   mpu.setRate(7); // set gyro rate to 8 kHz/(1 + rate) shows 1 kHz, accelerometer ODR is fixed at 1 KHz

    MagRate = 10; // set magnetometer read rate in Hz; 10 to 100 (max) Hz are reasonable values

@@ -226,7 +226,7 @@
     pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
     roll  = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);
     pitch *= 180.0f / PI;
-    yaw   *= 180.0f / PI - 13.8; // Declination at Danville, California is 13 degrees 48 minutes and 47 seconds on 2014-04-04
+    yaw   *= 180.0f / PI - 3; // Declination at Nantes, France is around 3 degrees in 2014
     roll  *= 180.0f / PI;

     Serial.print("Yaw, Pitch, Roll: ");


Updated to work with the current RF24 library

Last tested January 7 2020.

--- ArduAutoCar/ArduAutoCar.ino
+++ ArduAutoCar/ArduAutoCar.ino
@@ -14,12 +14,7 @@
                             // Beware that I have not shown this connection in the schematic, it is simply here for
                             // debugging.

-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 };
@@ -43,11 +38,11 @@
     if ( radio.available() )
     {
       byte transmission[7];
-      bool done = false;
-      while (!done)
-      {
-        // Fetch the payload, and see if this was the last one.
-        done = radio.read( &transmission, 7 );
+
+        // Fetch the payload
+        while (radio.available()) {
+          radio.read( &transmission, sizeof(transmission));
+        }

         // Spew it
         Serial.print(transmission[0]);
@@ -80,10 +75,10 @@

         turn(turnValue);

-	// Delay just a little bit to let the other unit
-	// make the transition to receiver
-	delay(10);
-      }
+  // Delay just a little bit to let the other unit
+  // make the transition to receiver
+  delay(10);
+

       // First, stop listening so we can talk
       radio.stopListening();


Use vcc for internal temperature calculation

--- sensor/sensor.ino
+++ sensor/sensor.ino
@@ -99,7 +99,7 @@
         digitalWrite(PIN_SENSOR_POWER, LOW);

         double temperature_external = Thermistor(thermistor_read);
-        double temperature_internal = (5.0 * lm35_read * 100.0)/1024.0;
+        double temperature_internal = (vcc/1000 * lm35_read * 100.0)/1024.0;
         int solr_mv = vcc / 1024.0 * solar_read * 2;

         char temp_internal[6];


final-ish version minus cheat

final-ish version minus cheat

--- ISS_tracker/ISS_tracker.ino
+++ ISS_tracker/ISS_tracker.ino
@@ -37,7 +37,8 @@

 //to ensure altitude is positive since servo is 0-180
 altitude = (int)altitude;
-myServo.write(altitude+110);
+//myServo.write(altitude+90);
+myServo.write(90+20); //to make it move in demo for Apple TODO

 // defining variables
 double step_deg = 1.8; //degrees
@@ -47,7 +48,6 @@
 //calculating need for change in stepper motor
 double asmuth_change = asmuth - asmuth_old;
 int stepper_move = asmuth_change / step_deg;
-

 // in case moving N-s or S-n
 if (stepper_move > 1) {