- wifi configuration portal - establish wifi connection - Next TODO: read credentials from a file in SPIFFS

--- nodemcu-rgbstrip.ino
+++ nodemcu-rgbstrip.ino
@@ -1,26 +1,117 @@
 #include <FS.h>                   //this needs to be first, or it all crashes and burns...
-
 #include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
-
 //needed for library
 #include <DNSServer.h>
 #include <ESP8266WebServer.h>
 #include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
-
 #include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson

-#define FSTR(x) (__FlashStringHelper*)(x)
-const char HTTP[]  PROGMEM  = "Content-type: text/html";
+/* Store strings in PROGMEM
+ *
+*/
+const char CANNOT_CONNECT[] PROGMEM = {'Cannot connect to the AP: '};
+const char MOUNTFAIL[] PROGMEM = {'Failed to mount file system!'};
+const char SAVEWCONF[] PROGMEM = {'Saving the WiFi configuration...'};
+const char CONFMODE[] PROGMEM = {'Entered to configuration mode...'};
+const char RESETNODE[] PROGMEM = {'Entered to configuration mode...'};
+const char CONFSTR[] PROGMEM = {'Config: '};
+const char SETUPSTR[] PROGMEM = {'Setup...'};
+const char MACMSG[] PROGMEM = {'MAC Address: '};
+const char APIPSTR[] PROGMEM = {'AP IP: '};
+
+#define PWM_FREQ 100
+#define AP_PASSW "xxx0xxx"
+
+ESP8266WebServer myServer(80);
+String stassid = "";
+String stapass = "";
+
+void deleteSavedConfig() {
+  // TODO: reset the WiFi connection parameters
+}
+
+void saveWifiConfigCallback() {
+  // TODO: Save the WiFiManager configuration
+  Serial.println(FPSTR(SAVEWCONF));
+  // Store the credentials for using it in the program
+  stassid = WiFi.SSID();
+  stapass = WiFi.psk();
+}
+
+void configModeCallback(WiFiManager *myWfMan) {
+  Serial.println(FPSTR(CONFMODE));
+  Serial.print(FPSTR(APIPSTR));
+  Serial.println(WiFi.softAPIP());
+  Serial.print(FPSTR(MACMSG));
+  Serial.println(WiFi.softAPmacAddress());
+  Serial.println(myWfMan->getConfigPortalSSID());
+}

 void setup() {
-  // put your setup code here, to run once:
+  boolean hasSavedConfig = false;
+
   Serial.begin(115200);
-  char *a =(char*)FSTR(HTTP);
-  Serial.println('Setup...');
+  Serial.println(FPSTR(SETUPSTR));
+
+  pinMode(D1, OUTPUT);
+  pinMode(D2, OUTPUT);
+  pinMode(D3, OUTPUT);
+  analogWriteFreq(PWM_FREQ);
+  analogWriteRange(1023);

+  // Start the SPIFFS
+  if (!SPIFFS.begin()) {
+    Serial.println(FPSTR(MOUNTFAIL));
+    Serial.println(FPSTR(RESETNODE));
+    delay(1000);
+    ESP.reset();
+    return;
+  }
+
+  /*
+   * TODO: Open and parse the stored credential file
+   */
+
+  if (!hasSavedConfig) {
+      // Setup WiFiManager and start the config portal
+      WiFiManager wfMan;
+      String ssid = "ESP" + String(ESP.getChipId());
+      wfMan.setConfigPortalTimeout(180);
+      wfMan.setAPCallback(configModeCallback);
+      wfMan.setSaveConfigCallback(saveWifiConfigCallback);
+      wfMan.setMinimumSignalQuality(10);
+      wfMan.setBreakAfterConfig(true);
+      //wfMan.setDebugOutput(false);        // for final installation
+      wfMan.startConfigPortal(ssid.c_str(), AP_PASSW);
+  }
+
+  // Connect to the AP if not connected by the WiFiManager
+  WiFi.setAutoConnect(false);
+  WiFi.setAutoReconnect(true);
+  for (uint8_t count = 5; count>0; count--) {
+    if (!WiFi.isConnected()){
+      WiFi.begin(stassid.c_str(), stapass.c_str());
+    } else {
+      break;
+    }
+    delay(1000);
+  }
+  if (!WiFi.isConnected()) {
+    Serial.print(FPSTR(CANNOT_CONNECT));
+    Serial.println(stassid.c_str());
+    Serial.println(FPSTR(CONFSTR));
+    WiFi.printDiag(Serial);
+    Serial.println(FPSTR(RESETNODE));
+    delay(1000);
+    ESP.reset();
+  }
+
+  /*
+   *  TODO: Setup the webserver (myServer)
+   */
 }

 void loop() {
   // put your main code here, to run repeatedly:
-
+  myServer.handleClient();
 }


simple comments.

simple comments.

--- modbusserialtest/modbusserialtest.ino
+++ modbusserialtest/modbusserialtest.ino
@@ -49,12 +49,12 @@

    digitalWrite(ledPin, mb.Coil(LAMP));

-   if (millis() > t1 + 1000) {
+   if (millis() > t1 + 1000) {   //Increment each second
        t1 = millis();
        mb.Ireg(INPREG, mb.Ireg(INPREG)+1);
    }

-   if (millis() > t2 + 7000) {
+   if (millis() > t2 + 7000) {   //Change state each seven seconds
        t2 = millis();
        mb.Dimp(DISCINP, !mb.Dimp(DISCINP));
    }


added turnLeft to enable turning left

added turnLeft to enable turning left

--- arduino_motor/mains/movements.ino
+++ arduino_motor/mains/movements.ino
@@ -74,24 +74,8 @@
   Serial.print("m2: "); Serial.println(m2Speed);
   */
   motorShield.setSpeeds(m1Speed, m2Speed);
-    }
+  }
  // }
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-void halt()
-{
-  motorShield.setSpeeds(0, 0);
-  delay(100);
-}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-void stopIfFault()
-{
-  if (motorShield.getM1Fault()) {
-    Serial.println("M1 fault"); while(1);
-  }
-  if (motorShield.getM2Fault()) {
-    Serial.println("M2 fault"); while(1);
-  }
 }
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /*
@@ -114,8 +98,8 @@

   while (avgTicksForAngleOrDist < noOfTicksForDist) {
-    leftTicksForAngleOrDist = PololuWheelEncoders::getCountsM1() - leftCount0;
-    rightTicksForAngleOrDist = PololuWheelEncoders::getCountsM2() - rightCount0;
+    leftTicksForAngleOrDist = abs(PololuWheelEncoders::getCountsM1() - leftCount0);
+    rightTicksForAngleOrDist = abs(PololuWheelEncoders::getCountsM2() - rightCount0);

     avgTicksForAngleOrDist = (leftTicksForAngleOrDist + rightTicksForAngleOrDist) / 2.0; // reaching the target

@@ -124,7 +108,6 @@

   motorShield.setBrakes(Config::MAX_SPEED, Config::MAX_SPEED);
   delay(40);
-  //halt();
 }
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // angle in this function is abs
@@ -175,7 +158,7 @@
   // Turning completed

   // minus sign indicating turning right
-  errorCumulator->record_turning_error_compass(-adjusted_angle);
+  errorCumulator->record_turning_error_compass(isRightForward*adjusted_angle);
   // not affect the polling
   Serial.print("Turning right: "); Serial.print(avgTicksForAngleOrDist); Serial.print(" / "); Serial.println(noOfTicksForAngle);

@@ -185,3 +168,62 @@
   resetPololuTicks();
   errorCumulator->theta = 0;
 }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// depends on whether turning right and turning left is symmetric
+void turnLeft(double angle) {
+  resetPololuTicks();
+  errorCumulator->theta = 0; // theta_error
+  const int isLeftForward = -1;
+  const int isRightForward = +1;
+
+  //double noOfTicksForAngle = turnAngleR(angle);
+  double adjusted_angle = abs(errorCumulator->adjust_turning_angle(angle));
+  double noOfTicksForAngle = adjusted_angle*Config::TICKS_PER_DEGREE;
+  // ------ Angle to ticks formula ------- //
+
+  double avgTicksForAngleOrDist = 0;
+  long firstLeftCount = PololuWheelEncoders::getCountsM1();
+  long firstRightCount = PololuWheelEncoders::getCountsM2();
+
+
+
+
+  while (noOfTicksForAngle - avgTicksForAngleOrDist > 200) { //noOfTicksForAngle - change to 'angle' for other formula
+  // the tolerance value affect the turning errors
+    double leftTicksForAngleOrDist = PololuWheelEncoders::getCountsM1();
+    leftTicksForAngleOrDist = abs(leftTicksForAngleOrDist - firstLeftCount);
+
+    double rightlTicksForAngleOrDist = PololuWheelEncoders::getCountsM2();
+    rightTicksForAngleOrDist = abs(rightlTicksForAngleOrDist - firstRightCount); // left backward
+
+    avgTicksForAngleOrDist = (leftTicksForAngleOrDist + rightTicksForAngleOrDist) / 2; // turn left
+    configureMotor(isLeftForward, isRightForward);
+  }
+  // fading
+  setScale(0.4);
+  while (noOfTicksForAngle - avgTicksForAngleOrDist > 8) { //noOfTicksForAngle - change to 'angle' for other formula
+  // the tolerance value affect the turning errors
+    double leftTicksForAngleOrDist = PololuWheelEncoders::getCountsM1();
+    leftTicksForAngleOrDist = abs(leftTicksForAngleOrDist - firstLeftCount);
+
+    double rightlTicksForAngleOrDist = PololuWheelEncoders::getCountsM2();
+    rightTicksForAngleOrDist = abs(rightlTicksForAngleOrDist - firstRightCount); // left backward
+
+    avgTicksForAngleOrDist = (leftTicksForAngleOrDist + rightTicksForAngleOrDist) / 2; // turn left
+    configureMotor(isLeftForward, isRightForward);
+  }
+  setScale(1/0.4);
+  // Turning completed
+
+  // minus sign indicating turning left
+  errorCumulator->record_turning_error_compass(isRightForward*adjusted_angle);  // turning left, positive
+  // not affect the polling
+  Serial.print("Turning left: "); Serial.print(avgTicksForAngleOrDist); Serial.print(" / "); Serial.println(noOfTicksForAngle);
+
+
+  motorShield.setBrakes(Config::MAX_SPEED, Config::MAX_SPEED);
+  delay(40);
+  resetPololuTicks();
+  errorCumulator->theta = 0;
+}


file rename

file rename

--- singingInTheRain.ino
+++ singingInTheRain.ino
@@ -1,54 +0,0 @@
-/*
-  Melody
-
- Plays a melody
-
- circuit:
- * 8-ohm speaker on digital pin 8
-
- created 21 Jan 2010
- modified 30 Aug 2011
- by Tom Igoe
-
-This example code is in the public domain.
-
- http://arduino.cc/en/Tutorial/Tone
-
- */
-#include "pitches.h"
-
-// notes in the melody:
-int melody[] = {
-  NOTE_D4, NOTE_D4, NOTE_B3, NOTE_A3, NOTE_G3, NOTE_E3, NOTE_E3, NOTE_D3, NOTE_G3,
-  NOTE_G3, NOTE_G3, NOTE_A3, NOTE_B3, NOTE_D4, NOTE_D4, NOTE_D3, NOTE_E3, NOTE_G3, NOTE_G3,
-  NOTE_A3, NOTE_B3, NOTE_D4, NOTE_B3, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_B3, NOTE_A3,
-  NOTE_E3, NOTE_E3
-};
-
-// note durations: 4 = quarter note, 8 = eighth note, etc.:
-float noteDurations[] = {
-  2, 8, 8, 8, 8, 2, 4, 4, 2, 8, 8, 8, 8, 8, 2, 4, 8, 8, 2, 8, 8, 8, 2, 8, 8, 2, 8, 8, 8, 2, 4
-};
-
-void setup() {
-  // iterate over the notes of the melody:
-  for (int thisNote = 0; thisNote < sizeof(melody)/sizeof(melody[0]); thisNote++) {
-
-    // to calculate the note duration, take one second
-    // divided by the note type.
-    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
-    int noteDuration = 1000 / noteDurations[thisNote];
-    tone(2, melody[thisNote], noteDuration);
-
-    // to distinguish the notes, set a minimum time between them.
-    // the note's duration + 30% seems to work well:
-    int pauseBetweenNotes = noteDuration * 1.30;
-    delay(pauseBetweenNotes);
-    // stop the tone playing:
-    noTone(2);
-  }
-}
-
-void loop() {
-  // no need to repeat the melody.
-}


- display correct mode colors on startup

--- GeheimTuer.ino
+++ GeheimTuer.ino
@@ -288,34 +288,35 @@

   if (swTrigger == LOW || (swFront == LOW && swBack == LOW)) {
     doorState = doorError;
+    setLeds1(red, ledBlink);
     Serial.print(F("ERROR\r\n"));
   } else if (swFront == LOW) {
     doorState = doorClosed;
+    setLeds1(green, ledFade);
     Serial.print(F("closed\r\n"));
   } else if (swBack == LOW) {
     doorState = doorOpen;
+    setLeds1(green, ledBlink);
     Serial.print(F("open\r\n"));
   } else {
     doorState = doorBlocked;
+    setLeds1(red, ledSolid);
     Serial.print(F("blocked\r\n"));
   }

   if (doorState != doorError) {
-    // enable driver
-    motorEnable();
-
-    // diag pull-ups should have brought the lines up by now
-    motorDiagADebounce = (motorDiagA = motorDiagADeglitch = digitalRead(motorDiagAPin)) * 0xFFFF;
-    motorDiagBDebounce = (motorDiagB = motorDiagBDeglitch = digitalRead(motorDiagBPin)) * 0xFFFF;
-
     if (doorState != doorBlocked) {
       motorBrake();
     } else {
       motorFree();
-      setLeds1(red, ledSolid);
     }
-  } else {
-    setLeds1(red, ledBlink);
+
+    // enable driver
+    motorEnable();
+
+    // diag pull-ups should have brought the lines up by now
+    motorDiagADebounce = (motorDiagA = motorDiagADeglitch = digitalRead(motorDiagAPin)) * 0xFFFF;
+    motorDiagBDebounce = (motorDiagB = motorDiagBDeglitch = digitalRead(motorDiagBPin)) * 0xFFFF;
   }

 //  attachInterrupt(switchFrontIRQ, switchFrontInterrupt, CHANGE);


Put the icons in PROGMEM

Put the icons in PROGMEM

--- esp8266_dht11_oled.ino
+++ esp8266_dht11_oled.ino
@@ -45,7 +45,7 @@
 static unsigned int pause_in_ms = PAUSE_ACTIVE_IN_MS;

 static const unsigned int NUM_WIFI_FRAMES = 5;
-static const uint8_t WIFI_FRAMES[NUM_WIFI_FRAMES][32] = {
+static const uint8_t WIFI_FRAMES[NUM_WIFI_FRAMES][32] PROGMEM= {
 	{
 	0x00, 0x00, 0x0A, 0x60, 0x04, 0x60, 0x0A, 0x60, 0x00, 0x6C, 0x04, 0x6C,
 	0x04, 0x60, 0x24, 0x64, 0x74, 0x6E, 0xE4, 0x67, 0xC4, 0x63, 0xC4, 0x63,
@@ -173,7 +173,7 @@
 		displayData += (int)event.temperature;
 		displayData += "°C";
 	}
-	displayData += " ";
+	displayData += " - ";
 	dht.humidity().getEvent(&event);
 	if (isnan(event.relative_humidity)) {
 		DEBUG_PRINTLN("Error reading humidity!");
@@ -198,7 +198,7 @@
 		wifiFrame = wifiConnection.getSignalStrength();
 	else
 		wifiFrame = wifiFrame + 1 % NUM_WIFI_FRAMES;
-	u8g2.drawXBM(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 16, 16, 16, WIFI_FRAMES[wifiFrame]);
+	u8g2.drawXBMP(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 16, 16, 16, WIFI_FRAMES[wifiFrame]);
 	u8g2.sendBuffer();

 }


servo power problem solved

servo power problem solved

by detaching servo after positioning

--- arduino/medox/medox.ino
+++ arduino/medox/medox.ino
@@ -84,10 +84,6 @@
   pinMode(  lightLevel,  INPUT);
   //initialize Serial Communication to communicate with RPI, with Baud rate=9600
   Serial.begin(9600);
-
-  //servos
-  drawerServo.attach(drawer);        // attaches the doorServo on pin Arduino pin
-  warehouseServo.attach(warehouse);  // attaches the warehouseServo on pin Arduino pin

   //define drawer limit switch pin as interrupt pin to secure drawer automatically
   attachInterrupt(digitalPinToInterrupt(doorSwitch), closeDoor, RISING);
@@ -171,20 +167,32 @@
   }
 }

+
+//Servos Functions
+//attach then detach to avoid servos power disipating trying to
+//stay in the same position
 void openDoor(){
+  drawerServo.attach(drawer);        // attaches the doorServo on pin Arduino pin
   drawerServo.write(drawerServoOpen);
+  drawerServo.detach(); //detaches the doorServo
 }

 void openWarehouse(){
+  warehouseServo.attach(warehouse);  // attaches the warehouseServo on pin Arduino pin
   warehouseServo.write(WarehouseServoOpen);
+  warehouseServo.detach(); //detaches the warehouseServo
 }

 void closeDoor(){
+  drawerServo.attach(drawer);        // attaches the doorServo on pin Arduino pin
   drawerServo.write(drawerServoClose);
+  drawerServo.detach(); //detaches the doorServo
 }

 void closeWarehouse(){
+  warehouseServo.attach(warehouse);  // attaches the warehouseServo on pin Arduino pin
   warehouseServo.write(WarehouseServoClose);
+  warehouseServo.detach(); //detaches the warehouseServo
 }

 void sendSensorData(){


Added get_serial function.

Added get_serial function.

--- ppt/ppt.ino
+++ ppt/ppt.ino
@@ -464,6 +464,38 @@
   }
 }

+void get_serial_command() {
+  /* Variables used for parsing and tokenising */
+  char cmd[BUFF_MAX]; // char string to store the command
+  int val;  // Integer to store value
+
+  char in_buff[BUFF_MAX]; // Buffer in input
+  int end = Serial.readBytesUntil('}', in_buff, BUFF_MAX); // Read command from serial monitor
+  in_buff[end] = 0; // null terminate the string
+
+  sscanf(in_buff, "{%[^= ] = %d}", cmd, &val); // parse the string
+
+  #define stricmp strcasecmp // strangely, arduino uses a different API
+
+  if(!stricmp(cmd,"P")) {
+    state_switch(const_power,val);
+  }
+  else if(!stricmp(cmd,"V")) {
+    state_switch(const_volt,val);
+  }
+  else if(!stricmp(cmd,"MPPT") && val) {
+    state_switch(mppt_on);
+  }
+  else if(!stricmp(cmd,"OFF") && val) {
+    state_switch(off);
+  }
+  else {
+    Serial.print("{\"time\": ");
+    Serial.print(seconds, DEC);
+    Serial.println(", \"state\": \"read_err\"}");
+  }
+}
+
 //------------------------------------------------------------------------------------------------------
 // This routine is automatically called at powerup/reset
 //------------------------------------------------------------------------------------------------------
@@ -516,17 +548,9 @@
     //state_switch(const_volt, current_target);
   }*/

-  //TODO:
-  // Get data from serial
-  // Parse data
-  // if is "{P=0400}"
-  // state_switch(const_power, 400);
-  // if is "{V=0400}"
-  // state_switch(const_volt, 400);
-  // if is "{MPPT=1}"
-  // state_switch(mppt_on);
-  // if is "{OFF=1}"
-  // state_switch(off);
+  if (Serial.available() >= 4) {
+    get_serial_command();
+  }

   // diagnosistic prints
   static int print_counter = 0;


Fixed bug in command add

Fixed bug in command add

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -16,7 +16,7 @@
   char command = char(0);
   char end_stop = char(255);
   String send_message = String(message + end_stop);
-  send_message = String(command + message);
+  send_message = String(command + send_message);

   int send_length = send_message.length()+1;


Got all parameters tuned properly and should work for demo.


prototype 3: word

prototype 3: word

--- prototype/prototype-3/prototype-3.ino
+++ prototype/prototype-3/prototype-3.ino
@@ -124,9 +124,9 @@
   // put your main code here, to run repeatedly:
 }

-/*****************************
-   COMPONENT TESTING METHODS
- *****************************/
+/*******************************
+   COMPONENT TESTING FUNCTIONS
+ *******************************/
 #ifdef COMPONENT_TEST_MOTOR_COAST
 void component_test_motor_coast(Motor* motor) {
   for (int i = 0; i < 20; i++) {


updates.

--- slave/main/main.ino
+++ slave/main/main.ino
@@ -1,41 +1,62 @@
 #include <EepromUtil.h>
 #include <EEPROM.h>

+// Serial event holding string
 String inputString = "";         // a string to hold incoming data
 boolean stringComplete = false;  // whether the string is complete
-boolean written = false;
-const int BUFSIZE = 50;
-char buf[BUFSIZE];
+// Temp
+boolean finished_config = false;
+// Read Write buffer config
+const int buffer_size = 50;
+char buffer[buffer_size];
+// Check buffer
+const int check_size = 1;
+char check[check_size];
+// Reading init pos
+int start_pos = 1;
+
+// Setup
 void setup() {
-  // initialize serial:
+  // initialize serial with 9600 baudrate:
   Serial.begin(9600);
   // reserve 200 bytes for the inputString:
   inputString.reserve(200);
+
+
 }

+// main
 void loop() {
-  // print the string when a newline arrives:
+  // Print the string when a newline arrives.
   if (stringComplete) {
+    if inputString{
+
     Serial.println(inputString);
-    inputString.toCharArray(buf,BUFSIZE);
-    EepromUtil::eeprom_write_string(1,buf);
+    inputString.toCharArray(buffer,buffer_size);
+    EepromUtil::eeprom_write_string(start_pos,buffer);
+
     //EepromUtil::eeprom_erase_all();
-    //EepromUtil::eeprom_write_int(8, 123);
+
     // clear the string:
     inputString = "";
     stringComplete = false;
-    written = true;
+    finished_config = true;
+
+    }
+
   }

-    // erase buffer
-  for (int i = 0; i < BUFSIZE; i++) {
-    buf[i] = 0;
+  // Erase buffer.
+  for (int i = 0; i < buffer_size; i++) {
+    buffer[i] = 0;
   }

-  if(written == true){
+  if(finished_config == true){
+    // To not flood the serial interface.
     delay(1000);
-    EepromUtil::eeprom_read_string(1,buf,BUFSIZE);
-    Serial.print(buf);
+    EepromUtil::eeprom_read_string(start_pos,buffer,buffer_size);
+    // Manditory to ensure whole buffer is printed.
+    Serial.print(buffer);
     Serial.println();
   }


Increased remote control functionality

Increased remote control functionality

Alarm now can be adjusted and toggled with the remote control. Increased alarm duration to 3 hours in order for it to catch two breaks between sleep cycles.

--- Sketch.ino
+++ Sketch.ino
@@ -1,3 +1,28 @@
+/*
+My IR Remote codes, see this video to find out the codes for your remote: https://youtu.be/ftdJ0R_5NZk
+
+PLAY: FFA25D
+EQ:	  FF22DD
+CH+:  FFE21D
+CH-:  FF629D
+VOL+: FFC23D
+VOL-: FF02FD
+0:    FFE01F
+PREV: FFA857
+NEXT: FF906F
+1:    FF6897
+2:    FF9867
+3:    FFB04F
+4:    FF30CF
+5:    FF18E7
+6:    FF7A85
+7:    FF10EF
+8:    FF38C7
+9:    FF5AA5
+PICK SONG: FF42BD
+CH SET: FF52AD
+*/
+
 #include <IRremote.h>
 #include <Wire.h>
 #include <LiquidCrystal.h>
@@ -7,9 +32,9 @@
 IRrecv irrecv(RECV_PIN);
 decode_results results;

-byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; // Values to read from DS3231
-byte alarmHour = 15;
-byte alarmMinute = 15;
+byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; // Values to read from DS3231 RTC Module
+byte alarmHour = 5;
+byte alarmMinute = 0;
 bool alarmOn = true;
 bool alarmActive = false;
 long lastTimeReading = 0;
@@ -21,7 +46,7 @@
 const int ledMosfet = 6;

 long alarmTurnedOnAt = 0;
-long alarmDuration = 3600000; //1 hour.
+long alarmDuration = 10800000; //3 hours.
 long alarmStepTime = 0;

 long pushedButtonAt = 0;
@@ -61,7 +86,7 @@
 	return((val / 16 * 10) + (val % 16));
 }

-// Defining a special character to use as brightness icon
+//Defining a special character to use as brightness icon
 byte sunCharacter[8] = {
 	0b00000,
 	0b00100,
@@ -88,8 +113,7 @@
 	lcd.begin(16, 2);
 	/* set the initial time here:
 	   DS3231 seconds, minutes, hours, day(1 for sunday, 2 for monday...), date, month, year
-	   Set the time by uncommenting the following line after editing the values and load the sketch on your arduino. Right after that,
-	    comment out the line and load the sketch again. */
+	   Set the time by uncommenting the following line after editing the values and load the sketch on your arduino. Right after that, comment out the line and load the sketch again. */

 	// setDS3231time(00,59,23,1,31,12,16);
 }
@@ -115,16 +139,16 @@

 	if (alarmActive)
 	{
-		if (millis() - alarmTurnedOnAt < alarmDuration) // For the duration of alarm
+		if (millis() - alarmTurnedOnAt < alarmDuration) //For the duration of alarm
 		{
 			digitalWrite(backlightLCD, HIGH);
-			if (millis() - alarmStepTime > 7000) // Once in seven seconds, will  reach full brightness at 30 minutes
+			if (millis() - alarmStepTime > 7000) //Once in seven seconds, will  reach full brightness at 30 minutes
 			{
 				ChangeBrightness(1);
 				alarmStepTime = millis();
 			}
 		}
-		else // Once at the end of alarm duration
+		else //Once at the end of alarm duration
 		{
 			brightness = 0;
 			SetBrightness(brightness);
@@ -135,18 +159,18 @@

 	if (backlightOnForButton)
 	{
-		if (millis() - pushedButtonAt < backlightDuration) // For the backlight duration
+		if (millis() - pushedButtonAt < backlightDuration) //For the backlight duration
 		{
 			digitalWrite(backlightLCD, HIGH);
 		}
-		else // Once at the end of backlight duration
+		else //Once at the end of backlight duration
 		{
 			digitalWrite(backlightLCD, LOW);
 			backlightOnForButton = false;
 		}
 	}

-	if (irrecv.decode(&results)) {		// If a button is pressed on the IR remote
+	if (irrecv.decode(&results)) {		//If a button is pressed on the IR remote
 		if (results.value == 0xFFA25D)
 		{
 			LightOn();
@@ -187,14 +211,48 @@
 			ChangeBrightness(1);
 			PushedAnyButton();
 		}
+		if (results.value == 0xFF6897)
+		{
+			if (backlightOnForButton)
+			{
+				IncreaseAlarmHour();
+				PushedAnyButton();
+			}
+			else
+			{
+				PushedAnyButton();
+			}
+		}
+		if (results.value == 0xFF9867)
+		{
+			if (backlightOnForButton)
+			{
+				IncreaseAlarmMinute();
+				PushedAnyButton();
+			}
+			else
+			{
+				PushedAnyButton();
+			}
+		}
+		if (results.value == 0xFFB04F)
+		{
+			if (backlightOnForButton)
+			{
+				ToggleAlarm();
+				PushedAnyButton();
+			}
+			else
+			{
+				PushedAnyButton();
+			}
+		}
 		irrecv.resume();
 	}
-	// delay(100);
-}
-
-// Most of the code here is to make buttons work well. See lines 225-226, 244-245, 263-264 for what happens on button press.
-// https://www.arduino.cc/en/Tutorial/Debounce
-void ListenForButtonPress()
+	//delay(100);
+}
+
+void ListenForButtonPress() //https://www.arduino.cc/en/Tutorial/Debounce
 {
 	readingBtnAlarmHour = digitalRead(btnAlarmHour);
 	readingBtnAlarmMinute = digitalRead(btnAlarmMinute);


Update 1_RGBPongClock.ino

Update 1_RGBPongClock.ino

--- firmware/examples/1_RGBPongClock.ino
+++ firmware/examples/1_RGBPongClock.ino
@@ -33,7 +33,7 @@
 extern char* itoa(int a, char* buffer, unsigned char radix);

-#define		RGBPCversion	"V1.1"
+#define		RGBPCversion	"V1.2"

 //#define DEBUGME


Added "Done" state to notify user of state machine completion where all componenets are off.

--- CB_SM.ino
+++ CB_SM.ino
@@ -15,6 +15,8 @@
 extern void drain();
 extern void vacuumUpdate();
 extern void dwellUpdate();
+extern void drainUpdate();
+extern void done();

 ////	Define the states within the SM

@@ -27,8 +29,10 @@
 // Dwell state, with accompanying update function for extra dwell state behaviours
 State dwll_state = State(dwell, dwellUpdate, NULL);

-// Drain state
-State drin_state = State(drain);
+// Drain state, with timeout of X seconds
+State drin_state = State(drain, drainUpdate, NULL);
+
+State done_state = State(done);

 FSM stateMachine = FSM(idle_state);		//	Initial SM with beginning state

@@ -37,6 +41,8 @@

 unsigned long stateStartTime;			//	Used to track times for entering Vacuum/Dwell states
 unsigned long stateDebounceLimit = 30000;	//	Used to define state debounce time limit
+
+unsigned long drainTimeout = 60000;		//	Timeout for Drain

 int buttonState;             // the current reading from the input pin
 int lastButtonState = HIGH;   // the previous reading from the input pin
@@ -44,8 +50,8 @@
 long debounceDelay = 100;    // the debounce time; increase if the output flickers

 // Different states of the machine: Idle, Vacuum, Dwell, and Drain
-enum states {IDLED, VACU, DRIN, DWLL};
-const byte NUM_OF_STATES = 3; 	//	Number of total states
+enum states {IDLED, VACU, DRIN, DONE, DWLL};
+const byte NUM_OF_STATES = 4;	//	Number of total states
 Adafruit_NeoPixel ledStat = Adafruit_NeoPixel(1, NEOPIX, NEO_GRB + NEO_KHZ800);		//	Neopixel initializiation

 void setup() {
@@ -112,6 +118,11 @@
 					stateStartTime = millis();
                 	stateMachine.transitionTo(drin_state);
                 	break;
+
+				case DONE:
+					Serial.println("DONE");
+					stateMachine.transitionTo(done_state);
+					break;
             }
           }
         }
@@ -202,8 +213,24 @@
 	digitalWrite(VALV_PUMP, LOW);
 	digitalWrite(VALV_ATM, HIGH);

-	ledStat.setPixelColor(0, ledStat.Color(0, 255,0));
-	ledStat.show();
-}
-
-
+	ledStat.setPixelColor(0, ledStat.Color(238, 130, 238));
+	ledStat.show();
+	stateStartTime = millis();
+}
+
+
+void drainUpdate() {
+	if((millis() - stateStartTime) < drainTimeout) {
+		stateMachine.transitionTo(done_state);
+	}
+}
+
+void done() {
+	digitalWrite(PUMP, LOW);
+	digitalWrite(VALV_PUMP, LOW);
+	digitalWrite(VALV_ATM, LOW);
+
+	ledStat.setPixelColor(0, ledStat.Color(0, 255, 0));
+	ledStat.show();
+}
+


upload arduino code

upload arduino code

--- devices/pull_alarm/pull_alarm.ino
+++ devices/pull_alarm/pull_alarm.ino
@@ -23,7 +23,6 @@

 /* Libraries
 ********************/
-#include <ArduinoJson.h>    //https://github.com/bblanchon/ArduinoJson/wiki
 #include <WiFi101.h>        //https://www.arduino.cc/en/Reference/WiFi101

 /* Arduino Output Pins
@@ -108,16 +107,8 @@

             APIcallTimer = millis();  //reset APIcallTimer

-            //Flash Onboard LED indicator
-            ledPinTimer = millis();
-            while(millis() - ledPinTimer < 500){
-              digitalWrite(LED_PIN, LOW);
-              delay(50);
-              digitalWrite(LED_PIN, HIGH);
-              delay(50);
-            }
-
-            //delay(500);
+
+            delay(600);

             //Issue request for data from server
             //Uses HTTP commands "printed" as though they were being typed
@@ -165,34 +156,14 @@
                             // Search for '[' (ASCII = 91) if response will be JSON Array (or Array of Objects)

                             if(int(APIresponse[0]) != 'O'){   //If the first character is not "123" (ASCII code for open bracket '{')
-                                Serial.println("Wrong start char detected");
-                                int index = 0;
-                                bool beginFound = false;
-                                while(!beginFound){
-                                    if(int(APIresponse[index]) == 123){   // Step through the string until '{' is found
-                                        beginFound = true;
-                                        Serial.print("'{' found at ");
-                                        Serial.println(index);
-                                    }
-                                    index++;
-                                }   //When '{' is found, "index" will be it's position in the string
-                            }                            }
+                                 digitalWrite(LED_PIN, HIGH);
+
+                            }
             } //End of API Response Processing

             APIclient.stop(); // disconnect from server

           } //End of API Host Server Connection
-
-    Serial.print("** Uptime: ");
-    Serial.print(millis()/(1000*60*60*24));
-    Serial.print(" days, ");
-    Serial.print((millis()/(1000*60*60))%24);
-    Serial.print(" hrs, ");
-    Serial.print((millis()/(1000*60))%60);
-    Serial.print(" mins, ");
-    Serial.print((millis()/(1000))%60);
-    Serial.println(" secs");
-    Serial.println("");       //print blank line to space Serial Monitor read out

 } //END Loop


remove bogus SH

remove bogus SH

--- d_BacpacCommands.ino
+++ d_BacpacCommands.ino
@@ -128,14 +128,6 @@
     return;
   case SET_BACPAC_SHUTTER_ACTION: // SH
     // shutter button of master is pressed
-#ifdef USE_GENLOCK
-    if (1) { // send to Dongle
-      Serial.print(F("SH"));
-      printHex(recv[3], true);
-      Serial.println("");
-      Serial.flush();
-    }
-#endif
     buf[0] = 3; buf[1] = 'S'; buf[2] = 'Y'; buf[3] = recv[3];
     SendBufToCamera();
     return;


break out of loop after successful gps status receive.

--- src/basic/basic.ino
+++ src/basic/basic.ino
@@ -61,6 +61,7 @@
       if (gps.location.isValid()){
         transmit_coords(gps.location.lat(), gps.location.lng());
       }
+      break;
     }
   }
   if(receivedBikeKillSignal()){


Initializing the ~ pins as analog outs.

Initializing the ~ pins as analog outs.

--- ServerSketch/ServerSketch.ino
+++ ServerSketch/ServerSketch.ino
@@ -249,7 +249,7 @@

   case LWS_CALLBACK_RECEIVE:

-    Serial.println("Cleaning Protocol");
+    Serial.println("Process Incomming Messag");

     // **********************************
     // Process Data Receieved from the Website
@@ -434,6 +434,8 @@

     updateBoardState();

+   // delay(1000);
+
     aJsonObject *msg = getJsonBoardState();

     aJsonStringStream stringStream(NULL, (char *)p, WEB_SOCKET_BUFFER_SIZE);
@@ -590,7 +592,11 @@
   // Initialize pins 0-13 as digital out pins
   for(int i=0; i<(TOTAL_NUM_OF_PINS-NUM_OF_ANALOG_PINS); i++)
   {
-    g_aPins[i].is_analog = false;
+    if( i==3 || i==5 || i==6 || i==9 || i==10 || i==11 )
+      g_aPins[i].is_analog = true;
+    else
+      g_aPins[i].is_analog = false;
+
     g_aPins[i].is_input = false;
     g_aPins[i].sensitivity = 0.5;
     g_aPins[i].is_inverted = false;
@@ -659,7 +665,7 @@
 {
   float fPinValSum = 0;
   int iConnCount = 1; // Pins are always connected to themselves
-
+
   for(int i=0; i<TOTAL_NUM_OF_PINS; i++)
   {
     // Checking what pins are connected to iPinNum


fixed turn identification bug

fixed turn identification bug


unified the ADC reference used for calculations

--- src/analog_sensors_board.ino
+++ src/analog_sensors_board.ino
@@ -73,6 +73,10 @@
 #define ADC_INTERNAL_MV 2.483f      // manual calibration (was 2.502f)
 #define ADC_DEFAULT_V 0.004887f     // uncalibrated
 #define ADC_DEFAULT_MV 4.887f       // uncalibrated
+
+// select the ADC reference to use for calculations
+#define ADC_V ADC_DEFAULT_V
+#define ADC_MV ADC_DEFAULT_MV

 #define LED_PIN 13

@@ -390,9 +394,6 @@

     // limit data rate
     if(delta >= DELAY_SLOW) {
-        // switch to precise reference (2.56V)
-        analogReference(INTERNAL);
-
         // analog inputs (battery)
         raw_bat0 = analogRead(A0);      // J4 (pin 1)
         raw_bat0 = analogRead(A0);      // J4 (pin 1)
@@ -407,10 +408,10 @@
         raw_bat3 = analogRead(A3);      // J4 (pin 4)

         // voltage level conversion
-        bat0 = BAT_RK * (float)raw_bat0 * ADC_INTERNAL_V;
-        bat1 = BAT_RK * (float)raw_bat1 * ADC_INTERNAL_V;
-        bat2 = BAT_RK * (float)raw_bat2 * ADC_INTERNAL_V;
-        bat3 = BAT_RK * (float)raw_bat3 * ADC_INTERNAL_V;
+        bat0 = BAT_RK * (float)raw_bat0 * ADC_V;
+        bat1 = BAT_RK * (float)raw_bat1 * ADC_V;
+        bat2 = BAT_RK * (float)raw_bat2 * ADC_V;
+        bat3 = BAT_RK * (float)raw_bat3 * ADC_V;

         // send battery report
         report_battery();
@@ -430,10 +431,10 @@
         //raw_tm3 = analogRead(A11);        // J5 (pin 2)

         // lm35 temperature conversion
-        tm0 = (float(raw_tm0) * ADC_INTERNAL_MV) / LM35_MVC;
-        tm1 = (float(raw_tm1) * ADC_INTERNAL_MV) / LM35_MVC;
-        tm2 = (float(raw_tm2) * ADC_INTERNAL_MV) / LM35_MVC;
-        //tm3 = (float(raw_tm3) * ADC_INTERNAL_MV) / LM35_MVC;
+        tm0 = (float(raw_tm0) * ADC_MV) / LM35_MVC;
+        tm1 = (float(raw_tm1) * ADC_MV) / LM35_MVC;
+        tm2 = (float(raw_tm2) * ADC_MV) / LM35_MVC;
+        //tm3 = (float(raw_tm3) * ADC_MV) / LM35_MVC;

         // send temperature report
         report_temperature();
@@ -458,7 +459,8 @@
         // relative humidity with temperature correction (see hih_4030_fitting.m)
         hm = (0.0002f * temperature) + 0.0763f;         // x-coeffient fitting
         hb = (-0.0612f * temperature) - 24.4265f;       // b-term fitting
-        hih = hm * float(raw_hih) + hb;
+        hih = hm * float(raw_hih + 524) + hb;           // ADC ref (5.0 V)  this is scaling back the ADC reading
+        // hih = hm * float(raw_hih) + hb;              // ADC ref (2.56 V)

         // send humidity report
         report_humidity();
@@ -468,13 +470,6 @@
         report_indicators();

-        // switch to default reference (5V on Arduino Uno/Leonardo)
-        analogReference(DEFAULT);
-
-        // discard the first ADC conversion
-        analogRead(A11);
-
-
         // send timestamp
         Serial.print("$TIME,");
         Serial.println(time_env, DEC);


updated firmware to use ACS715 current sensors, using two acquisition loops (fast and slow) for current and other sensors.

--- src/analog_sensors_board.ino
+++ src/analog_sensors_board.ino
@@ -26,53 +26,59 @@
 	SOFTWARE.
 */

+// ** LM35 Analog Temperature Sensor
+// 	[1]: http://learn.adafruit.com/tmp36-temperature-sensor
+//
+// ** HIH-4043 Humidity Sensor
+// 	[2]: https://www.sparkfun.com/products/9569
+// 	[3]: http://bildr.org/2012/11/hih4030-arduino/
+// 	[4]: http://forum.arduino.cc/index.php/topic,19961.0.html
+//
+// ** BMP085 Barometric Pressure Sensor
+// 	[5]: https://www.sparkfun.com/products/11282
+// 	[6]: https://www.sparkfun.com/tutorials/253
+//
+//  [7]: http://linux.die.net/man/8/picocom
+//  [8]: http://forum.arduino.cc/index.php?topic=128717.0
+//  [9]: http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html
+
 #include <avr/wdt.h>
 #include <Wire.h>

-#define LED_PIN 13
-
-#define DELAY_SETUP 250
-#define DELAY_MAIN 1000
-#define DELTA_IQ 2000
+#define DELAY_SETUP 250         // setup flashing delay
+#define DELAY_FAST 500 			// fast acquisition loop
+#define DELAY_SLOW 2000 		// slow acquisition loop

 // Reference voltages (fine tuned):
 //	measured using AREF when the shield is in place and
 //	the Arduino is powered by external power with vehicle
-
 #define ADC_INTERNAL_V 	0.002483f	// manual calibration (was 0.002502f)
 #define ADC_INTERNAL_MV 2.483f		// manual calibration (was 2.502f)
 #define ADC_DEFAULT_V 0.004887f		// uncalibrated
 #define ADC_DEFAULT_MV 4.887f		// uncalibrated

+#define LED_PIN 13
+
 #define BAT_R1 24000.0f 		// R1 (ohm)
 #define BAT_R2 2200.0f 			// R2 (ohm)

 #define LM35_MVC 10.0f			// mV/C
+#define ACS715_MVA 133.0f		// mv/A
 #define ACS714_MVA 185.0f 		// mv/A

 #define BMP085_ADDRESS 0x77		// I2C address
 #define BMP085_OSS 0 			// Oversampling Setting
 #define BMP_MAX 1000 			// Loop protection (number of loops)

-// ** LM35 Analog Temperature Sensor
-// 	[1]: http://learn.adafruit.com/tmp36-temperature-sensor
-//
-// ** HIH-4043 Humidity Sensor
-// 	[2]: https://www.sparkfun.com/products/9569
-// 	[3]: http://bildr.org/2012/11/hih4030-arduino/
-// 	[4]: http://forum.arduino.cc/index.php/topic,19961.0.html
-//
-// ** BMP085 Barometric Pressure Sensor
-// 	[5]: https://www.sparkfun.com/products/11282
-// 	[6]: https://www.sparkfun.com/tutorials/253
-//
-//  [7]: http://linux.die.net/man/8/picocom
-//  [8]: http://forum.arduino.cc/index.php?topic=128717.0
-//  [9]: http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html
-
-const int ACS_ZERO = (int) 2500 / ADC_INTERNAL_MV;		// ADC reading for 2.5V (~ 1007)
-const float ACS714_CONV = ADC_INTERNAL_MV / ACS714_MVA;	// Amps per ADC level
+// Voltage Divider (for battery levels)
 const float BAT_RK = (BAT_R1 + BAT_R2) / BAT_R2;
+
+// Allegro ACS715 0A to 30A
+const float ACS715_CONV = ADC_INTERNAL_MV / ACS715_MVA;			// Amps per ADC level
+
+// Allegro ACS714 current sensor
+//const int ACS_ZERO = (int) 2500 / ADC_INTERNAL_MV;			// ADC reading for 2.5V (~ 1007)
+//const float ACS714_CONV = ADC_INTERNAL_MV / ACS714_MVA;		// Amps per ADC level

 unsigned long time_iq;
 unsigned long delta;
@@ -87,13 +93,10 @@
 float tm0, tm1, tm2, tm3;
 float hih, hm, hb;

-
-// BMP085 raw readings
-long raw_ut, raw_up;
-
-// BMP085 output values
-short temperature;
-long pressure;
+// BMP085 barometric pressure sensor
+long raw_ut, raw_up;					// BMP085 raw readings
+short temperature;						// local temperature
+long pressure;							// local pressure

 // BMP085 loop control
 short bmp_cnt;
@@ -110,23 +113,23 @@
 long b5;

-// ACS714 current sensor
-//	working in reverse current flow to keep output signal within 0-2.5V range
-//	2.5V output is the steady 0A initial reading
+// Allegro ACS714/715 current sensor
+//   * ACS714 output is 2.5V for 0A up to 4.5V at +5A and down to 0.5V at -5A
+//   * ACS715 output is 0.5V for 0A up to 5V at 30A
+int raw_acs0;
 float acs0;
-int raw_acs0;
-
-
-// the setup routine runs once when you press reset:
+
+
+// the setup routine runs once when you press reset
 void setup() {
-	// disable watchdog, because of [8]
-	wdt_disable();
+	// disable watchdog
+	wdt_disable();					// used [8] as suggestion

 	// not ready
 	pinMode(LED_PIN, OUTPUT);
 	digitalWrite(LED_PIN, LOW);

-	// while the serial stream is not open, flash the on-board led:
+	// flash the on-board led while waiting for connection
 	while(!Serial) {
 		digitalWrite(LED_PIN, HIGH);
 		delay(DELAY_SETUP);
@@ -156,22 +159,24 @@
 	// start acquisition (with double readings to avoid interferences [1])
 	digitalWrite(LED_PIN, HIGH);

+
 	// current sensor
 	raw_acs0 = analogRead(A11);		// J5 (pin 2)
 	raw_acs0 = analogRead(A11);		// J5 (pin 2)

 	// calculate output is Amps
-	acs0 = (float) (ACS_ZERO - raw_acs0) * ACS714_CONV;
+	//acs0 = (float) (ACS_ZERO - raw_acs0) * ACS714_CONV;
+	acs0 = (float) (raw_acs0 - 202)  * ACS715_CONV;

 	// send current report
 	report_current();

-	// acquisition loop delta
+	// acquisition slow-loop delta
 	delta = millis() - time_iq;

 	// limit data rate
-	if( delta > DELTA_IQ ) {
+	if( delta > DELAY_SLOW ) {

 		// analog inputs (battery)
 		raw_bat0 = analogRead(A0);		// J4 (pin 1)
@@ -228,6 +233,7 @@

 		// send pressure report
 		report_pressure();
+		bmp_dirty = 0;					// reset dirty bits

 		// humidity sensor
@@ -242,6 +248,7 @@
 		// send humidity report
 		report_humidity();

+
 		// send timestamp
 		Serial.print("$TIME,");
 		Serial.println(time_iq, DEC);
@@ -249,19 +256,18 @@
 		// update timestamp
 		time_iq = millis();

-		// reset dirty bits
-		bmp_dirty = 0;
+	} else {
+		// pause between data acquisition
+		delay(DELAY_FAST);
 	}

 	// signal end of acquisition
 	digitalWrite(LED_PIN, LOW);

-	// pause between data acquisition
-	delay(DELAY_MAIN);
-
 	// reset watchdog
 	wdt_reset();
 }
+

 void report_current() {
 	Serial.print("$ACS,");


take voltage ADC reading only when lcd is on

--- vibrate_alarm_clock.ino
+++ vibrate_alarm_clock.ino
@@ -79,7 +79,7 @@
   int alarmSetButtonState = digitalRead(BUTTON_ALARM_SET_PIN);
   int timeSetButtonState = digitalRead(BUTTON_TIME_SET_PIN);
   int lcdOffPinState = digitalRead(LCD_OFF_PIN);
-  int voltageADCReading = analogRead(VOLTAGE_MEASURE_PIN);
+

@@ -107,7 +107,9 @@

     boolean blinkOnForSetting = shouldBlinkNow();

-    //Multiply 2 as we are are using a half voltage divider
+
+    int voltageADCReading = analogRead(VOLTAGE_MEASURE_PIN);
+     //Multiply 2 as we are are using a half voltage divider
     int batteryMilliVolt = ((float) voltageADCReading / ADC_PRECISION) * 2 * VOLTAGE_OF_VCC_MV;

     writeDateTimeToDisplayBuffer(now, blinkOnForSetting);


tidy code

tidy code

--- ESP8266-code/ADXL335Test.ino
+++ ESP8266-code/ADXL335Test.ino
@@ -36,10 +36,10 @@
   int yRaw = readAxis(1);
   int zRaw = readAxis(2);

-  if (digitalRead(calibratePin) == LOW)
+  if (digitalRead(calibratePin) == LOW) {
     autoCalibrate(xRaw, yRaw, zRaw);
-/*
-  Serial.print("Raw Ranges: X: ");
+
+    Serial.print("Raw Ranges: X: ");
     Serial.print(xRawMin);
     Serial.print("-");
     Serial.print(xRawMax);
@@ -60,33 +60,27 @@
     Serial.print(yRaw);
     Serial.print(", ");
     Serial.print(zRaw);
- */
-    // Convert raw values to 'milli-Gs"
-    long xScaled = map(xRaw, xRawMin, xRawMax, -1000, 1000);
-    long yScaled = map(yRaw, yRawMin, yRawMax, -1000, 1000);
-    long zScaled = map(zRaw, zRawMin, zRawMax, -1000, 1000);
+  }

-    // re-scale to gs and negated
-    float xAccel = xScaled / 1000.0;
-    float yAccel = yScaled / 1000.0;
-    float zAccel = zScaled / 1000.0;
+  // Convert raw values to 'milli-Gs"
+
+  long xMilliG = map(xRaw, xRawMin, xRawMax, -1000, 1000);
+  long yMilliG = map(yRaw, yRawMin, yRawMax, -1000, 1000);
+  long zMilliG = map(zRaw, zRawMin, zRawMax, -1000, 1000);
+
+  // re-scale to gs and negated
+  float xG = xMilliG / 1000.0;
+  float yG = yMilliG / 1000.0;
+  float zG = zMilliG / 1000.0;

-    Serial.print(xAccel);
-    Serial.print("G, ");
-    Serial.print(yAccel);
-    Serial.print("G, ");
-    Serial.print(zAccel);
-    Serial.print("G");
-    // convert to angles
+  Serial.println(String("Accelerations :")+xG+"G, "+yG+ "G, "+ zG +"G");
+  // convert to pitch and roll

-    float pitch = getPitch(xAccel,yAccel,zAccel);
-    float roll = getRoll(xAccel,yAccel,zAccel);
-    Serial.print(" roll=");
-    Serial.print(roll);
-    Serial.print(", pitch= ");
-    Serial.println(pitch);
+  float pitch = getPitch(xG,yG,zG);
+  float roll = getRoll(xG,yG,zG);
+  Serial.println(String("roll=")+roll+" pitch= "+pitch);

-    delay(intervalms);
+  delay(intervalms);

 }

@@ -98,13 +92,13 @@
    if (x >= 0) return 1; else return -1;
 }

-float getPitch(float gX, float gY,float gZ) {
-   return asDegree(atan2(gX, sqrt(gY*gY + gZ*gZ)));
+float getPitch(float xG, float yG,float zG) {
+   return asDegree(atan2(xG, sqrt(yG*yG + zG*zG)));
 }

-float getRoll(float gX, float gY,float gZ) {
+float getRoll(float xG, float yG,float zG) {
     float mu= 0.01;
-    return asDegree(atan2(gY, signum(gZ) * sqrt(gZ*gZ + mu*gX*gX)));
+    return asDegree(atan2(yG, signum(zG) * sqrt(zG*zG + mu*xG*xG)));
 }

 int readAxis(int i) {


Added BMP180 support

Added BMP180 support

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -1,11 +1,23 @@
 // temps entre actualitzacions de els elements
 // [lm35_1, lm35_2, ldr_1]
-const int numSen = 3;
-const int groundPin = A0;
-int types[] = {0,0,1};
-unsigned long lastUpdate[] = {0,0,0};
-unsigned long updateTimes[] = {60000,60000,30000};
-int pins[] = {A1,A5,A3};
+#include <Wire.h>
+#include <SFE_BMP180.h>
+
+#define count(x) sizeof(x)/sizeof(unsigned long)
+#define groundPin A0
+#define ALTITUDE 570
+
+#define BMP180T 0   // Temperature
+#define BMP180P 1   // Pressure
+
+#define NOTUSED -1  // For BMP180 sensor.
+
+SFE_BMP180 pressure;
+
+int types[] = {BMP180T,BMP180P};
+unsigned long lastUpdate[] = {0,0};
+unsigned long updateTimes[] = {30000,60000};
+int pins[] = {NOTUSED,NOTUSED};

 int secureAnalogRead(int pin) {
   delay(0.01);
@@ -13,6 +25,36 @@
   delay(0.01);
   return analogRead(pin);

+}
+
+boolean bmp180Temperature(double &T) {
+  char status;
+  status = pressure.startTemperature();
+  if (status != 0) {
+    delay(status);
+    status = pressure.getTemperature(T);
+    if(status != 0) return true;
+  }
+  return false;
+}
+
+boolean bmp180Pressure(double &P) {
+  double T, absP;
+  char status;
+  if(bmp180Temperature(T)) {
+    Serial.println(T);
+    delay(500);
+    status = pressure.startPressure(3);
+    if (status != 0) {
+        delay(status);
+        status = pressure.getPressure(absP,T);
+        if (status != 0) {
+          P = pressure.sealevel(absP,ALTITUDE);
+          return true;
+        }
+      }
+  }
+  return false;
 }

 float lm35(int pin) {
@@ -31,20 +73,24 @@
 void update(int type, int pin) {
   String c, v;
   switch (type) {
-    case 0:
-        c = "lm35_" + String(pin);
-        v = String(lm35(pin));
+    case BMP180T:
+        double T;
+        c = "BMP180T";
+        if (bmp180Temperature(T)) v = String(T);
+        else v = c + " Error";
         break;
-    case 1:
-        c = "ldr_" + String(pin);
-        v = String(ldr(pin));
+    case BMP180P:
+        double P;
+        c = "BMP180P";
+        if (bmp180Pressure(P)) v = String(P);
+        else v = c + " Error";
         break;
   }
   sendCommand(c, v);
 }

 void updateAll() {
-  for (int i = 0; i < numSen; i++) {
+  for (int i = 0; i < count(updateTimes); i++) {
     unsigned long actTime = millis();
     if (actTime - lastUpdate[i]  > updateTimes[i]) {
       update(types[i], pins[i]);
@@ -76,7 +122,7 @@
   String inp = readCommand();
   if (inp == "") {
   } else if (inp == "dump") {
-    for (int i = 0; i < numSen; i++) {
+    for (int i = 0; i < count(updateTimes); i++) {
       String com = String(i) + " " + String(types[i]) + " " + String(updateTimes[i]) + " " + String(pins[i]);
       sendCommand("dump_pin", com);
     }
@@ -89,11 +135,14 @@
 }

 void setup() {
-  Serial.begin(57600); // set the baud rate
-  for (int i = 0; i < numSen; i++) {
+  Serial.begin(9600); // set the baud rate
+  if (pressure.begin()) Serial.println("BMP180 init success");
+  else Serial.println("BMP180 init fail\n\n");
+
+  for (int i = 0; i < count(updateTimes); i++) {
     pinMode(pins[i], INPUT);
     update(types[i],pins[i]);
-  }
+  }
 }

 void loop() {


Fixed typo

Fixed typo

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -57,7 +57,7 @@

 void recieve_data() {
   int incomingByte = Serial.read();
-  if(incommingByte != -1) {
+  if(incomingByte != -1) {
     py_log(String(incomingByte));
   }
 }


added temperature reading periodic

added temperature reading periodic

--- arduino/src/src.ino
+++ arduino/src/src.ino
@@ -62,7 +62,7 @@
     Serial.print(data[1]);
     Serial.print(",");
     Serial.print(data[2]);
-    if(temp_count == 18000) {
+    if(temp_count == 18000) { //This is for sending temperature every 5 minutes given avg sampling rate
 	temp_count = 0;
     	float f = dht.readTemperature(true);
 	Serial.print(",");


Updated random visualization with bigger pixels, documentation, license

--- nodemcu_oled_random.ino
+++ nodemcu_oled_random.ino
@@ -1,16 +1,53 @@
+/********************************************************************************
+* MIT License                                                                   *
+*                                                                               *
+* Copyright (c) 2016 Christopher Kuzma                                          *
+*                                                                               *
+* 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, 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:                      *
+*                                                                               *
+* The above copyright notice and this permission notice shall be included in all*
+* copies or substantial portions of the Software.                               *
+*                                                                               *
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR    *
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,      *
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE   *
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER        *
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
+* SOFTWARE.                                                                     *
+********************************************************************************/
+
 #include "SSD1306.h"

-SSD1306  display(0x3c, D3, D4); // Specify pins display is connected to
+// Set where to find the board
+SSD1306  display(0x3c, D3, D4); // Specify pins display is connected to, might have to change address

-int len = 128;
-int ht = 64;
-int board[128][64];
+// Set display stuff
+const int len = 8; // 128 native pixels / 4 pixels per cell = 32 virtual cells length
+const int ht = 4; // 64 native pixels / 4 pixels per cell = 16 virtual cells height
+const int pixelSize = 16; // Set how many native pixels = pixels per cell length or width
+const bool flipScreen = false; // If you need to flip the screen

-void drawBoard(int[128][64]);
+// Initialize the board
+int board[len][ht];
+
+// Function prototypes
+void drawBoard();
 void randomBoard();

 void setup(){
+  // Init the display
   display.init();
+  if(flipScreen == true){
+    display.flipScreenVertically();
+  }
+
+  // Display the title
   display.clear();
   display.setFont(ArialMT_Plain_10);
   display.drawString(40, 15, "Random");
@@ -21,17 +58,18 @@
 }

 void loop() {
-  drawBoard(board);
+  drawBoard();
   randomBoard();
-  delay(10);
+  delay(100);
 }

-void drawBoard(int boardToDraw[128][64]){
+void drawBoard(){
   display.clear();
   for(int x=0; x<len; x++){
     for(int y=0; y<ht; y++){
       if(board[x][y] == 1){
-        display.setPixel(x,y);
+//        display.setPixel(x,y);
+          display.fillRect(x*pixelSize, y*pixelSize, pixelSize, pixelSize);
       }
     }
   }


simplify and no progmem on yun demo

simplify and no progmem on yun demo


Actualizando codigo de red neuronal

Actualizando codigo de red neuronal

--- Redbot/AvoidLines_NN/AvoidLines_NN.ino
+++ Redbot/AvoidLines_NN/AvoidLines_NN.ino
@@ -4,6 +4,9 @@
 #define SPEED 60  // sets the nominal speed. Set to any number from 0 - 255.

 RedBotMotors motors;
+boolean s1 = true;
+boolean s2 = true;
+boolean s3 = true;
 int leftSpeed;   // variable used to store the leftMotor speed
 int rightSpeed;  // variable used to store the rightMotor speed
 RedBotSensor left = RedBotSensor(A3);   // initialize a left sensor object on A3
@@ -85,10 +88,12 @@

 void setup()
 {
+    Serial.begin(9600);
   randomSeed(analogRead(A3));
   brainL.randomize();
   brainR.randomize();
-  Serial.begin(9600);
+
+

 }

@@ -96,14 +101,20 @@
 {

+
+// if(Serial.available())
+ //{
+  //Serial.println("Goodnight moon!");
   int l = left.read();
   int r = right.read();
   int c = center.read();
   //set inputs
   brainL.inputs[0] = l;
-  brainL.inputs[1] = r;
+  brainR.inputs[1] = c;
+  brainL.inputs[2] = r;
   brainR.inputs[0] = l;
-  brainR.inputs[1] = r;
+  brainR.inputs[1] = c;
+  brainR.inputs[2] = r;

   //feed forward and calculate weighted sum
   int resL = brainL.feedForward();
@@ -112,21 +123,25 @@
   //use this to move servos left and right
   moveLeft(resL);
   moveRight(resR);
+  Serial.println(resL);
+  //Serial.println(resR);

   delay(100);//let move for some time then stop
+  stopRedbot();
+  delay(10);
   //train
   brainL.train(eval(l, c, r), resL);
   brainR.train(eval(r, c, l), resR);

-
+ //}
 }

 //***** sensor function******

 int eval(int l, int c, int r) {
-   if((l > LINETHRESHOLD) && (c > LINETHRESHOLD) && (r > LINETHRESHOLD) )
+   if ((l > LINETHRESHOLD) && (c > LINETHRESHOLD) && (r > LINETHRESHOLD) )
 	{
             return 1;
 	}
@@ -137,41 +152,35 @@

 void moveLeft(char d) {
+  leftSpeed = -(SPEED - 50);
   if (d > 0) {
-    motors.leftMotor(0);
+    //Serial.println(d);
+    motors.drive(-80);
+
+  delay(1000);       // for 1000 ms.
   } else {
-    motors.leftMotor(180);
+    //motors.leftMotor(100);//180
+    //motors.rightMotor(150); // Turn on right motor clockwise medium power (motorPower = 150)
+    motors.leftDrive(-255);
+    motors.leftMotor(80); // Turn on left motor counter clockwise medium power (motorPower = 150)
   }
 }

 void moveRight(char d) {
+   rightSpeed = SPEED - 50;
   if (d > 0) {
-    motors.rightMotor(180);
+    //motors.rightMotor(-100);//180
+    //motors.drive(-255);
+    motors.rightDrive(-255);
+    motors.rightMotor(80); // Turn on right motor clockwise medium power (motorPower = 150)
+    //motors.leftMotor(-150); // Turn on left motor counter clockwise medium power (motorPower = 150)
   } else {
-   motors.rightMotor(0);
+   motors.drive(80);
   }
 }

-void moveServo(char d) {
-  if (d > 0) {
-    motors.rightMotor(180);
-    motors.leftMotor(0);
-  } else {
-    motors.rightMotor(0);
-    motors.leftMotor(180);
-  }
-}

-void stopServo() {
-  motors.stop();
+void stopRedbot() {
+  motors.brake();

 }
-
-void turnRedbot(char d) {
-
-    motors.rightMotor(-100);
-    motors.leftMotor(-100);
-
-}
-
-


redo bar graph calc

redo bar graph calc

--- main/main.ino
+++ main/main.ino
@@ -499,11 +499,13 @@

       lcd.setCursor(column, row);
     }
-
-    int bars = ((engineVar.currentValue - engineVar.minimum) * 100) / (engineVar.maximum - engineVar.minimum);
-    int fullBars = bars/(100/(20 - column));   //5;
-    int partialBars = bars % 5;
-
+
+    //calculate bars
+    byte percent = ((engineVar.currentValue - engineVar.minimum) * 100) / (engineVar.maximum - engineVar.minimum);
+    float bars = (percent/(100.0/(20.0 - column)) * 10.0) / 10.0;
+    byte fullBars = floor(bars);
+    byte partialBars = floor((bars - (floor(bars))) /0.2);
+
     //prevent graph overrun
     if(fullBars >= (20 - column)) {
       fullBars = (20 - column);


Update mech.ino

Update mech.ino

--- mech/mech.ino
+++ mech/mech.ino
@@ -164,7 +164,7 @@
       }
     }
     prevSetepPwr = rflPwrVal;
-    if ((fwdPwrVal == 0) || (rflPwrVal == 0)) {
+    if (((fwdPwrVal >> 4) == 0) || ((rflPwrVal >> 4) == 0)) {
       break;
     }
     isFirstStep = false;
@@ -172,7 +172,7 @@
 }

 void autoTune() {
-  if ((fwdPwrVal == 0) || (isAutoTune)) {
+  if (((fwdPwrVal >> 4) == 0) || (isAutoTune)) {
     return;
   }
   isAutoTune = 1;
@@ -186,7 +186,7 @@
 }

 void fineTune() {
-  if ((fwdPwrVal == 0) || (isAutoTune)) {
+  if (((fwdPwrVal >> 4) == 0) || (isAutoTune)) {
     return;
   }
   isAutoTune = 1;


Add arduino code

Add arduino code


added water levels to json output

added water levels to json output

--- ardesp/waterelf/waterelf.ino
+++ ardesp/waterelf/waterelf.ino
@@ -724,7 +724,11 @@
     buf->concat(", \"pH\": ");
     buf->concat(m->pH);
   }
-  // TODO add water levels
+  if(GOT_LEVEL_SENSOR){
+    buf->concat(", \"cm1\": "); buf->concat(m->waterLevel1);
+    buf->concat(", \"cm2\": "); buf->concat(m->waterLevel2);
+    buf->concat(", \"cm3\": "); buf->concat(m->waterLevel3);
+  }
   buf->concat(" }");
 }
 void getTemperature(float* waterCelsius) {


convert payload variables to struct again

--- onboard_controller/onboard_controller.ino
+++ onboard_controller/onboard_controller.ino
@@ -19,10 +19,14 @@
 byte* buf_curr; //current position of buffer

 //fake data
+struct Payload {
   long latitude; //42.4439;
   long longitude;//-76.5018;
   int altitude;//9999
   byte flags;//0xF;
+} payload, *ptr_payload;
+
+Payload* ptr_payload = &payload;

 enum States {
   STOPPED, PRE_LAUNCH, POST_LAUNCH, SEND_DATA, READ_DATA, READ_GPS, ERROR
@@ -85,21 +89,21 @@
     timer = millis(); // reset the timer

     #ifdef fakeGPS //fake gps data
-      latitude = 42.4439*10000;
-      longitude = 76.5018*10000;
-      altitude = 9999;
+      payload.latitude = 42.4439*10000;
+      payload.longitude = 76.5018*10000;
+      payload.altitude = 9999;
       state = SEND_DATA;
     #else
       if (GPS.fix) {
-        latitude = convertDegMinToDecDeg(GPS.latitude)*10000;
-        longitude = convertDegMinToDecDeg(GPS.longitude)*10000;
-        altitude = GPS.altitude;
+        payload.latitude = convertDegMinToDecDeg(GPS.latitude)*10000;
+        payload.longitude = convertDegMinToDecDeg(GPS.longitude)*10000;
+        payload.altitude = GPS.altitude;
         state = SEND_DATA;
       }
       else {
-        latitude = 0;
-        longitude = 0;
-        altitude = 0;
+        payload.latitude = 0;
+        payload.longitude = 0;
+        payload.altitude = 0;

         #ifdef debug
           Serial.println("No fix");
@@ -111,13 +115,13 @@

       //buf_start is pointer to first allocated space
       //buf_curr is pointer to next free space
-      if (latitude != 0 && longitude != 0 && altitude != 0) {
-        buf_curr = stream(MARKER_LAT, buf_start, (void*)&latitude, sizeof(latitude));
-        buf_curr = stream(MARKER_LON, buf_curr, (void*)&longitude, sizeof(longitude));
-        buf_curr = stream(MARKER_ALT, buf_curr, (void*)&altitude, sizeof(altitude));
+      if (payload.latitude != 0 && payload.longitude != 0 && payload.altitude != 0) {
+        buf_curr = stream(MARKER_LAT, buf_start, (void*)&(ptr_payload->latitude), sizeof(payload.latitude));
+        buf_curr = stream(MARKER_LON, buf_curr, (void*)&(ptr_payload->longitude), sizeof(payload.longitude));
+        buf_curr = stream(MARKER_ALT, buf_curr, (void*)&(ptr_payload->altitude), sizeof(payload.altitude));
       }

-      buf_curr = stream(MARKER_FLAG, buf_curr, (void*)&flags, sizeof(flags));
+      buf_curr = stream(MARKER_FLAG, buf_curr, (void*)&(ptr_payload->flags), sizeof(payload.flags));

       //buffer size is the difference between the current and start pointers
       buf_size = buf_curr - buf_start;


export template functions to header file

--- payload/payload.ino
+++ payload/payload.ino
@@ -4,7 +4,7 @@

 // SD card libraries
 #include <BlockDriver.h>
-#include <FreeStack.h> // something is wrong with this library.
+//#include <FreeStack.h> // something is wrong with this library.
 #include <MinimumSerial.h>
 #include <SdFat.h>
 #include <SdFatConfig.h>
@@ -16,8 +16,11 @@
 //#include <Adafruit_BNO055.h>
 #include <Adafruit_BME280.h>

+#include <string>
+
 // RCR headers
-#include "Setupable.h"
+#include "setupable.h"
+#include "setup.h"

 FILE file; // file manager
 SdFatSdio sd_card; // SD card manager
@@ -32,20 +35,10 @@
 // For more info, see "setupable.h".
 //custom::Setupable* setupables[] = {  };

-// Setup the object. Swallow any errors.
-template<typename T>
-void setup_general(T obj, char* error_message, char* success_message) {
-  if (!obj.begin()) {
-    Serial.println(error_message);
-    // Swallow the error; fault tolerance is required.
-  }
-  Serial.println(success_message);
-  Serial.println();
-}

-void setup_objects(void) {
-  setup_general<SdFatSdio>(sd_card, "ERROR: SD card could not be found or setup...",  "Success: SD card ready.");
-  setup_general<Adafruit_BME280>(bme, "Could not find a valid BME280 sensor...",      "Success: BME280 ready.");
+void setup_objects() {
+  custom::setup<>(sd_card, "ERROR: SD card could not be found or setup...", "Success: SD card ready.");
+  custom::setup<>(bme, "Could not find a valid BME280 sensor...", "Success: BME280 ready.");
 }

 void setup() {


nmeademo

nmeademo

--- NmeaDemo/NmeaDemo.ino
+++ NmeaDemo/NmeaDemo.ino
@@ -30,6 +30,13 @@

 void loop(void)
 {
+    while (gps.available())
+    {
+        char c = gps.read();
+        console.print(c);
+        nmea.process(c);
+    }
+
 	unsigned long currentMillis = millis();
 	if (currentMillis - previousMillis >= interval)
 	{
@@ -40,7 +47,10 @@
 		// Output GPS information from previous second
 		console.print("Valid fix: ");
 		console.println(nmea.isValid() ? "yes" : "no");
-
+
+        if (!nmea.isValid())
+          return;
+
 		console.print("Nav. system: ");
 		if (nmea.getNavSystem())
 			console.println(nmea.getNavSystem());
@@ -89,11 +99,4 @@
 		console.println("-----------------------");
 	}

-	while (gps.available())
-	{
-		char c = gps.read();
-		console.print(c);
-		nmea.process(c);
-	}
-
 }


remove duplicate header includes in ArduBreakout

--- examples/ArduBreakout/ArduBreakout.ino
+++ examples/ArduBreakout/ArduBreakout.ino
@@ -9,7 +9,6 @@
  version 2.1 of the License, or (at your option) any later version.
  */

-#include <Arduboy.h>
 #include "Arduboy.h"
 #include <ArduboyPlaytune.h>
 #include "breakout_bitmaps.h"


space?

space?

--- Vsens/src/sketch.ino
+++ Vsens/src/sketch.ino
@@ -54,7 +54,7 @@
   voltage = (float)sumSamples / (float)numSamples; // Calculate avg raw value.
   voltage *= scaleRaw2Volts;      // Scale avg raw value to source voltage.

-  Serial.println(voltage);
+  Serial.println (voltage);
   //Serial.println (" V");
   digitalWrite(activityLED, LOW);
   elapsedTime = millis() - startTime;


dd setRotation() option

dd setRotation() option

--- firmware/bringahackmfba17-dorkbotpdx/bringahackmfba17-dorkbotpdx.ino
+++ firmware/bringahackmfba17-dorkbotpdx/bringahackmfba17-dorkbotpdx.ino
@@ -565,6 +565,7 @@
 };

 void setup() {
+  epaper.setRotation(1);
   epaper.initScreen();    // initialize the epaper hardware
   epaper.updateScreen();  // update the screen with whatever is in the buffer
   epaper.clearScreen();   // clear the epaper buffer


dingens verwijdere

dingens verwijdere

--- programma.ino
+++ programma.ino
@@ -1,283 +0,0 @@
-#include <Servo.h>
-#include "IOpins.h"
-#include "Constants.h"
-
-#include <SPI.h>
-#include <nRF24L01.h>
-#include <RF24.h>
-
-/*-----( Declare objects )-----*/
-RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
-
-void setup() {
-
-  Serial.begin(9600);
-  pinMode(LmotorA,OUTPUT);        // zet de pinnen voor de H brug op output
-  pinMode(RmotorA,OUTPUT);
-  pinMode(LmotorB,OUTPUT);
-  pinMode(RmotorB,OUTPUT);
-
-  radio.begin();                  // voor de RF module te openen
-  radio.openReadingPipe(1,pipe);
-  radio.startListening();
-  /*
-  myservo.attach(3);              // attaches the servo on pin 9 to the servo object
-  pinMode(trigPin, OUTPUT);
-  pinMode(echoPin, INPUT);
-  pinMode(timeOutPin, OUTPUT);
-  */
-
-}
-
-void loop() {
-   Snelheid = 1500;             // zet snelheid in de center positie
-   Stuur = 1500;                // zet stuur in de center positie
-   unsigned long currentMillis = millis(); // wordt gebruikt voor verschillende time-outs
-
-  if (radio.available() )       // kijkt of er een RF signaal is
-  {
-    vooruitRijden = LOW;
-    Serial.println("Het werkt");
-
-    // Fetch the data payload
-
-      done = radio.read(input, sizeof(input));
-
-      Serial.print("Switch:  ");
-      Serial.print(input[0]);
-
-      Snelheid= (input[1])+1000;     // geeft de geontvangde data door aan snelheid.
-
-      Serial.print(input[1]);
-      Serial.print("\n");
-      Serial.print("Y-axis: ");
-      Serial.println(input[2]);
-      Stuur  = (input[2])+1000;     // geeft de geontvangde data door aan stuur.
-      Serial.print("\n\n");
-    }
-
-
-    /*else {
-      if(currentMillis - previousMillisServo >= intervalServo) {
-
-       previousMillisServo = currentMillis;           //zet om de zoveel tijd de positie van de servomotor anders.
-       myservo.write(pos);
-
-       if(vooruitKijken)
-       {
-         pos += hoekServo;                            //schuift de servomotor op
-         if(pos >= 125 || pos <= 55) hoekServo = hoekServo*-1;
-       }
-     }
-
-     if (currentMillis - previousMillisSensor >= intervalSensor) {
-         previousMillisSensor = currentMillis;
-         Distance();                                   //als de servomotor in positie is kijk de distance
-
-         if (pos >= 55 && pos <= 125 && distance <= 10 && distance > 0) { //als hij voor hem iets detecteerd
-             count += 1;
-             vooruitRijden = LOW;
-             if (count >= 5) rechtsKijken = HIGH;
-
-             Serial.println("STOP");
-
-          }
-
-         else if (pos >= 55 && pos <= 125 && distance > 10 || distance == -1) { //als er geen obstakels zijn vooruit rijden
-              count = 0;
-             vooruitRijden = HIGH;
-             //rondKijken = LOW;
-             Serial.println("DRIVE");
-         }
-       }
-     }
-
-
-  if(vooruitRijden){
-         Snelheid = 2000;
-         Stuur = 1500;
-  }
-
-  if(rechtsKijken) {
-    vooruitKijken = LOW;
-    Serial.println("rechtskijken");
-    Serial.println(distance);
-    Serial.println(pos);
-    pos = 0;
-     if ( pos == 0 && distance >= 10 || distance == -1) //als hij links iets detecteerd zal hij naar rechts begeven.
-     {
-       Snelheid = 1500;
-       Stuur = 2000;
-       rechtsDraaien = HIGH;
-
-       Serial.println("rechtsdraaien");
-      //  vooruitKijken = HIGH;
-     }
-    /* else
-     {
-       pos = 180;
-       Serial.println("Linkskijken");
-
-       if (pos == 180 && distance >= 20 ||distance == -1)
-       {
-         Snelheid = 1500;
-         Stuur = 1000;
-         Serial.println("Linksdraaien");
-         vooruitKijken = HIGH;
-       }
-       else vooruitKijken = HIGH;
-     }
-  }
-
-  if (rechtsDraaien)
-  {
-    pos = 90;
-    Serial.println("Rechtsdraaien");
-    if (pos == 90 && distance >= 30 || distance == -1)
-    {
-      rechtsKijken = LOW;
-      vooruitKijken = HIGH;
-    }
-  }
-  */
-
-    Pinkers(Stuur, currentMillis);
-    //------------------------------------------------------------ Code voor RC inputs. ---------------------------------------------------------
-
-
-  if (abs(Snelheid-1500)<RCdeadband) Snelheid=1500;           // Als de snelheid input in de speling is dan zet men het op 1500 (standaard waarde voor meeste servo's).
-  if (abs(Stuur-1500)<RCdeadband) Stuur=1500;                 // Als de sturing input in de speling is dan zet men het op 1500 (standaard waarde voor meeste servo's).
-
-  // Mengt de snelheid en de stuur signalen.
-
-  Stuur=Stuur-1500;
-  LinkseSnelheid=Snelheid-Stuur;
-  RechtseSnelheid=Snelheid+Stuur;
-
-
-  linksemodus=1;
-  rechtsemodus=1;
-  if (LinkseSnelheid>(Leftcenter+RCdeadband)) linksemodus=2;          // Als de linkse input voorwaarts is dan zet de linkde modus naar voorwaarts.
-  if (RechtseSnelheid>(Rightcenter+RCdeadband)) rechtsemodus=2;       // Als de rechtse input voorwaarts is dan zet de rechtse modus naar voorwaarts.
-  if (LinkseSnelheid<(Leftcenter-RCdeadband)) linksemodus=0;
-  if (RechtseSnelheid<(Rightcenter-RCdeadband)) rechtsemodus=0;
-
-  linksePWM=abs(LinkseSnelheid-Leftcenter)*10/scale;                 // Verschaal 1000-2000uS naar 0-255.
-  linksePWM=min(linksePWM,255);                                      // Zet maximum limiet 255.
-
-  rechtsePWM=abs(RechtseSnelheid-Rightcenter)*10/scale;              // Verschaal 1000-2000uS naar 0-255.
-  rechtsePWM=min(rechtsePWM,255);                                    // Zet maximum limiet 255.
-
-
-    // --------------------------------------------------------- Code voor het aandrijven van dd dubbele "H" bruggen. --------------------------------------
-
-
-  switch (linksemodus)                                    // Als de linkse motor niet recent overbelast is geweest.
-  {
-  case 2:                                                 // Linkse motor voorwaarts.
-    analogWrite(LmotorA,0);
-    analogWrite(LmotorB,linksePWM);
-    break;
-
-  case 1:                                                 // Linkse motor stopt.
-    analogWrite(LmotorA,linksePWM);
-    analogWrite(LmotorB,linksePWM);
-    break;
-
-  case 0:                                                 // Linkse motor achterwaarts.
-    analogWrite(LmotorA,linksePWM);
-    analogWrite(LmotorB,0);
-    break;
-  }
-
-  switch (rechtsemodus)                                   // Als de rechtse motor niet recent overbelast is geweest.
-  {
-  case 2:                                                 // Rechtse motor voorwaarts.
-    analogWrite(RmotorA,0);
-    analogWrite(RmotorB,rechtsePWM);
-    break;
-
-  case 1:                                                 // Rechtse motor stopt.
-    analogWrite(RmotorA,rechtsePWM);
-    analogWrite(RmotorB,rechtsePWM);
-    break;
-
-  case 0:                                                 // Rechtse motor achterwaarts.
-    analogWrite(RmotorA,rechtsePWM);
-    analogWrite(RmotorB,0);
-    break;
-  }
-}
-
-void Distance() { // meet de afstand van de sensor
-
- digitalWrite(trigPin, LOW);
- delayMicroseconds(2);
-
- digitalWrite(trigPin, HIGH);
- delayMicroseconds(10);
-
- digitalWrite(trigPin, LOW);
- duration = pulseIn(echoPin, HIGH);
-
- //Calculate the distance (in cm) based on the speed of sound.
- distance = duration/58.2;
-
- if (distance >= maximumRange || distance <= minimumRange){
- /* Send a negative number to computer and Turn LED ON
- to indicate "out of range" */
-   Serial.println("-1");
-   digitalWrite(timeOutPin, LOW);
- }
- else {
- /* Send the distance to the computer using Serial protocol, and
- turn LED OFF to indicate successful reading. */
-   Serial.println(distance);
- }
-  digitalWrite(timeOutPin, HIGH);
-}
-
- void Pinkers(int Stuur, unsigned long currentMillis){ // laat de pinkers pinken
-
-   if (Stuur > 1550){ // als de wagen naar rechts gaat, rechter pinkers pinken
-    if(currentMillis - previousMillis >= interval) {
-          // save the last time you blinked the LED
-
-      previousMillis = currentMillis;
-
-
-       // if the LED is off turn it on and vice-versa:
-       if (RledState == LOW)
-           RledState = HIGH;
-       else
-           RledState = LOW;
-
-         // set the LED with the ledState of the variable:
-           digitalWrite(Rpinker, RledState);
-   }
-  }
-   else {
-       RledState = LOW;
-       digitalWrite(Rpinker, RledState);
-   }
-
-   if (Stuur < 1450) { // als de wagen naar links gaat, linker pinkers pinken
-     if(currentMillis - previousMillis >= interval) {
-      // save the last time you blinked the LED
-        previousMillis = currentMillis;
-
-          // if the LED is off turn it on and vice-versa:
-          if (LledState == LOW)
-            LledState = HIGH;
-          else
-            LledState = LOW;
-
-          // set the LED with the ledState of the variable:
-          digitalWrite(Lpinker, LledState);
-        }
-      }
-      else {
-        LledState = LOW;
-        digitalWrite(Lpinker, LledState);
-      }
-}


improved debugging

improved debugging

--- jenny5-firmware/jenny5-firmware.ino
+++ jenny5-firmware/jenny5-firmware.ino
@@ -12,7 +12,7 @@

 char is_command_running;

-char firmware_version[] = "2015.11.11.0";
+char firmware_version[] = "2015.11.11.3";

 AccelStepper *steppers[num_motors];

@@ -43,8 +43,7 @@
   Serial.println("Lx#  // Lock motor x.");
   Serial.println("Sx y# // Sets speed of motor x to y");
   Serial.println("Ax y# // Sets acceleration of motor x to y");
-  Serial.println("Motor index can be between 0 and num_motors - 1");
-  Serial.println("Each command is terminated with #.");
+  Serial.println("Motor index is between 0 and num_motors - 1");

   Serial.println();

@@ -67,6 +66,7 @@
       #ifdef DEBUG
         Serial.write("initial buffer is=");
         Serial.write(current_buffer);
+        Serial.println();
       #endif

       // parse from the beginning until I find a M, D, S or A
@@ -84,6 +84,7 @@
               #ifdef DEBUG
                 Serial.write("current command is=");
                 Serial.write(tmp_str);
+                Serial.println();
               #endif

               if (current_buffer[i] == 'M' || current_buffer[i] == 'm'){// moves motor
@@ -113,7 +114,8 @@
               #ifdef DEBUG
                 Serial.write("buffer left=");
                 Serial.write(current_buffer);
-                Serial.println(strlen(current_buffer));
+                Serial.write("\n----------------\n");
+                //Serial.println(strlen(current_buffer)); // buffer length
               #endif

               break; //for i
@@ -142,10 +144,7 @@
 void move_motor(int motor_index, int num_steps)
 {
   digitalWrite(enable_pins[motor_index], LOW); // turn motor on
-  //Serial.println("Moving motor1 forward at default step mode.");
   steppers[motor_index]->moveTo(num_steps); //move num_steps
-  //Serial.println("Enter new option");
-  Serial.println();
 }
 //--------------------------------------------------------------------------------------------
 void set_motor_speed(int motor_index, int motor_speed)


Delays should be handled by wait_rssi_ready().

--- src/rx5808-pro-diversity/rx5808-pro-diversity.ino
+++ src/rx5808-pro-diversity/rx5808-pro-diversity.ino
@@ -490,7 +490,7 @@
         drawScreen.screenSaver(pgm_read_byte_near(channelNames + channelIndex), pgm_read_word_near(channelFreqTable + channelIndex));
 #endif
         do{
-            delay(10); // timeout delay
+            //delay(10); // timeout delay
 #ifdef USE_DIVERSITY
             drawScreen.updateScreenSaver(active_receiver, readRSSI(), readRSSI(useReceiverA), readRSSI(useReceiverB));
 #else
@@ -515,7 +515,7 @@
             drawScreen.diversity(diversity_mode);
             do
             {
-                delay(10); // timeout delay
+                //delay(10); // timeout delay
                 readRSSI();
                 drawScreen.updateDiversity(active_receiver, readRSSI(useReceiverA), readRSSI(useReceiverB));
             }
@@ -647,7 +647,6 @@
         }
 #endif
         drawScreen.updateSeekMode(state, channelIndex, channel, rssi, pgm_read_word_near(channelFreqTable + channelIndex), seek_found);
-
     }
     /****************************/
     /*   Processing SCAN MODE   */


Não trava mais, mas perde leituras do giroscópio.

--- quad/quad.ino
+++ quad/quad.ino
@@ -249,20 +249,20 @@
   static float yaw_target = 0;

   /* Se a programação do DMP falhou, não faz nada */
-  Serial.println("!dmpReady");
+  // D(Serial.println("DMP rdy"));
   if (!dmpReady) {
     return;
   }

-  Serial.println("readOrientation");
+  D(Serial.println(" "));
+  D(Serial.println("Red Ori"));
   readOrientation();

-  Serial.println("readRC");
+  // D(Serial.println("Read RC"));
   readRC();

   /* Voe Forest, Voe! */
   if(rcThrottle > MIN_RC_THROTTLE + 100) {  // Throttle raised, turn on stablisation.
-    Serial.println("PID");
     pid_pitch_stab.Compute();
     pid_roll_stab.Compute();
     pid_yaw_stab.Compute();
@@ -305,7 +305,6 @@
     motors[MOTOR_BR] = rcThrottle - roll_stab_output - pitch_stab_output - yaw_stab_output;

   } else {
-    Serial.println("else");
     /* Motores desligados */
     motors[MOTOR_FL] = motors[MOTOR_FR] = motors[MOTOR_BL] = motors[MOTOR_BR] = 1000;

@@ -319,13 +318,11 @@
     // }
   }

-  Serial.println("writeMotor");
+  // D(Serial.println("Wrt mtr"));
   writeMotor();

-  Serial.println("telemetry");
-  D(telemetry());
-
-  Serial.println("blink");
+  // D(telemetry());
+
   /* Pisca a led para indicar atividade */
   blinkState = !blinkState;
   digitalWrite(LED_PIN, blinkState);
@@ -365,6 +362,7 @@
 /* Efetua a leitura da orientação a ser armazenada na variável "ypr" */
 void readOrientation() {
   bool fifoOverflow = false; // Marca se houve overflow da FIFO durante a execução
+  D(Serial.println("init RO"));

   /* Le somente se houve interrupção */
   if (mpuInterrupt) {
@@ -373,40 +371,58 @@

     /* Obtém o byte INT_STATUS do MPU */
     mpuIntStatus = mpu.getIntStatus();
+    D(Serial.println("getIntStatus: " + String(mpuIntStatus)));

     /* Obtém a contagem da FIFO */
     fifoCount = mpu.getFIFOCount();
+    D(Serial.println("getFIFOCount: " + String(fifoCount)));

     /* Verifica se houve overflow da FIFO. Quanto mais ineficiente o código, mais irá ocorrer. */
     if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
       // Reseta a FIFO
+      D(Serial.println("resetFIFO: " + String(fifoCount)));
       mpu.resetFIFO();
       fifoOverflow = true;
+      return;
     }

     /* Se houve overflow, aguarda o próximo valor estar pronto */
-    if (fifoOverflow) {
-      while(!mpuInterrupt);
-    }
-
-    if (mpuIntStatus & 0x02) {
+    // int DMPwatchdog = 0;
+    // if (fifoOverflow) {
+    //   D(Serial.println("Agu Int"));
+    //   while(!mpuInterrupt);
+    //   D(Serial.println("Int rec"));
+    // }
+
+    if (mpuIntStatus & 0x01) {
       /* Obtém a contagem da FIFO */
       fifoCount = mpu.getFIFOCount();

       /* Aguarda encher a FIFO caso não esteja com os todos dados completos (pacote completo) */
-      while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
-
-      /* Dado está pronto para ser lido do MPU */
-      mpu.getFIFOBytes(fifoBuffer, packetSize);
-
-      /* Obtém os valores (Yaw, Pitch e Roll) do DMP */
-      mpu.dmpGetQuaternion(&q, fifoBuffer);
-      mpu.dmpGetGravity(&gravity, &q);
-      mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
-
-      /* Converte para graus/segundo */
-      for (int i = 0; i < 3; i++) {
-        ypr_degree[i] = ypr[i] * 180/M_PI;
+      Serial.println("Agu pac");
+      int DMPwatchdog = 0;
+      while (fifoCount < packetSize && DMPwatchdog < 5) {
+        fifoCount = mpu.getFIFOCount();
+        D(Serial.println("Count: " + String(fifoCount)));
+        DMPwatchdog++;
+      }
+
+      if (DMPwatchdog < 5) {
+        D(Serial.println("Pac rec...."));
+
+        /* Dado está pronto para ser lido do MPU */
+        mpu.getFIFOBytes(fifoBuffer, packetSize);
+
+        /* Obtém os valores (Yaw, Pitch e Roll) do DMP */
+        mpu.dmpGetQuaternion(&q, fifoBuffer);
+        mpu.dmpGetGravity(&gravity, &q);
+        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
+        D(Serial.println("Fim lei"));
+
+        /* Converte para graus/segundo */
+        for (int i = 0; i < 3; i++) {
+          ypr_degree[i] = ypr[i] * 180/M_PI;
+        }
       }
     }
   }
@@ -438,7 +454,8 @@
  * - Canal 6 (em us - entre ~1000 a ~2000)
  * - Intervalo do loop (em us)
  */
-void telemetry() {
+
+D(void telemetry() {
   /* Calcula a frequência do loop */
   tmInterval = micros() - tmCheckpoint;
   tmCheckpoint = micros();
@@ -481,4 +498,4 @@
   }

   return newString;
-}+})


game offside

game offside

--- f-alpha/f-alpha.ino
+++ f-alpha/f-alpha.ino
@@ -403,7 +403,7 @@
                         {
                             digitalWrite(l3r, HIGH);
                         }
-                        break;
+                    break;
                 case 4:
                     if (vector == GREENS)
                     {
@@ -414,11 +414,12 @@
                         {
                             digitalWrite(l4r, HIGH);
                         }
-                        break;
+                    break;
                 default:
             }
         }
-        digitalWrite(field[x][y], HIGH); // проверка наличия светодиода в новой координате
+        else
+            digitalWrite(field[x][y], HIGH); // проверка наличия светодиода в новой координате
     }
     digitalWrite(field[xPrev][yPrev], LOW);
     if (y == 0 || y == 4)
@@ -720,6 +721,25 @@
                 {
                     newxy(10, 1, GREENS);
                 }
+        }
+}
+
+void offside()
+{
+    currentMillis = millis();
+    log("Side out at " + String(currentMillis) + " after " + String(previousMillis));
+    previousMillis = currentMillis;
+    reset_buttons_flagClick();
+    ballkick = false;
+    game = GAME_PERFORMED;
+    if (vector == GREENS)
+    {
+        newxy(6, 2, REDS);
+    }
+    else
+        if (vector == REDS)
+        {
+            newxy(5, 2, GREENS);
         }
 }

@@ -751,7 +771,9 @@
         case GAME_END_OUT:
             goalline();
             break;
-
+        case GAME_OFFSIDE:
+            offside();
+            break;
         default:
         // выполняется, если не выбрана ни одна альтернатива
         // default необязателен


Teendy MIDI update 2

Teendy MIDI update 2

Starting to sound very nice :)

* Added implementation for MIDI control events for volume and various
resets.

--- examples/OPL2_Teensy_Midi/OPL2_Teensy_Midi.ino
+++ examples/OPL2_Teensy_Midi/OPL2_Teensy_Midi.ino
@@ -1,6 +1,11 @@
 #include <SPI.h>
 #include <OPL2.h>
 #include <midi_instruments.h>
+
+#define CONTROL_VOLUME          7
+#define CONTROL_ALL_SOUND_OFF 120
+#define CONTROL_RESET_ALL     121
+#define CONTROL_ALL_NOTES_OFF 123

 #define MIDI_CHANNELS 16
 #define OPL2_CHANNELS 9
@@ -19,6 +24,9 @@
 struct ChannelMapping {
   byte midiChannel;
   byte midiNote;
+  float midiVelocity;
+  float op1Level;
+  float op2Level;
 };

@@ -26,21 +34,19 @@
 ChannelMapping channelMap[OPL2_CHANNELS];
 byte lastUsed[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 byte programMap[MIDI_CHANNELS];
+float channelVolumes[MIDI_CHANNELS];

 void setup() {
+  // Serial.begin(115200);
+
   usbMIDI.setHandleNoteOn(onNoteOn);
   usbMIDI.setHandleNoteOff(onNoteOff);
   usbMIDI.setHandleProgramChange(onProgramChange);
-
-  opl2.init();
-  for (byte i = 0; i < OPL2_CHANNELS; i ++) {
-    opl2.setInstrument(i, PIANO1);
-  }
-
-  for (byte i = 0; i < MIDI_CHANNELS; i ++) {
-    programMap[i] = 0;
-  }
+  usbMIDI.setHandlePitchChange(onPitchChange);
+  usbMIDI.setHandleControlChange(onControlChange);
+  usbMIDI.setHandleSystemReset(onSystemReset);
+  onSystemReset();
 }

@@ -82,6 +88,15 @@
 }

+void setOpl2ChannelVolume(byte opl2Channel, byte midiChannel) {
+  float volume = channelMap[opl2Channel].midiVelocity * channelVolumes[midiChannel];
+  byte volumeOp1 = round(channelMap[opl2Channel].op1Level * volume * 63.0);
+  byte volumeOp2 = round(channelMap[opl2Channel].op2Level * volume * 63.0);
+  opl2.setVolume(opl2Channel, OPERATOR1, 63 - volumeOp1);
+  opl2.setVolume(opl2Channel, OPERATOR2, 63 - volumeOp2);
+}
+
+
 void onNoteOn(byte channel, byte note, byte velocity) {
   // Treat notes with a velocity of 0 as note off.
   if (velocity == 0) {
@@ -93,16 +108,15 @@

   // Get an available OPL2 channel and setup instrument parameters.
   byte i = getFreeChannel(channel);
-  channelMap[i].midiChannel = channel;
-  channelMap[i].midiNote    = note;
   opl2.setInstrument(i, instruments[programMap[channel]]);
+  channelMap[i].midiChannel  = channel;
+  channelMap[i].midiNote     = note;
+  channelMap[i].midiVelocity = round(velocity / 127.0);
+  channelMap[i].op1Level     = round((63 - opl2.getVolume(i, OPERATOR1)) / 63.0);
+  channelMap[i].op2Level     = round((63 - opl2.getVolume(i, OPERATOR2)) / 63.0);

   // Set operator output levels based on note velocity.
-  float volume = velocity / 127.0;
-  byte opl2VolumeOP1 = 63 - opl2.getVolume(i, OPERATOR1);
-  byte opl2VolumeOP2 = 63 - opl2.getVolume(i, OPERATOR2);
-  opl2.setVolume(i, OPERATOR1, 63 - (opl2VolumeOP1 * volume));
-  opl2.setVolume(i, OPERATOR2, 63 - (opl2VolumeOP2 * volume));
+  setOpl2ChannelVolume(i, channel);

   // Calculate octave and note number and play note!
   note = max(24, min(note, 119));
@@ -115,18 +129,75 @@
 void onNoteOff(byte channel, byte note, byte velocity) {
   for (byte i = 0; i < OPL2_CHANNELS; i ++) {
     if (channelMap[i].midiChannel == channel && channelMap[i].midiNote == note) {
-      channelMap[i].midiChannel = 255;
-      channelMap[i].midiNote    = 255;
       opl2.setKeyOn(i, false);
       break;
     }
   }
 }
-
+

 void onProgramChange(byte channel, byte program) {
   programMap[channel] = program;
 }

+void onPitchChange(byte channel, int pitch) {
+  // Serial.print("Pitch change on channel ");
+  // Serial.print(channel);
+  // Serial.print(" to ");
+  // Serial.println(pitch);
+}
+
+
+void onControlChange(byte channel, byte control, byte value) {
+  switch (control) {
+
+    // Change volume of a MIDI channel.
+    case CONTROL_VOLUME: {
+      channelVolumes[channel] = round(min(value, 63) / 63.0);
+
+      for (byte i = 0; i < OPL2_CHANNELS; i ++) {
+        if (channelMap[i].midiChannel == channel && opl2.getKeyOn(i)) {
+          setOpl2ChannelVolume(i, channel);
+        }
+      }
+      break;
+    }
+
+    // Reset all controller values.
+    case CONTROL_RESET_ALL:
+      for (byte i = 0; i < MIDI_CHANNELS; i ++) {
+        channelVolumes[channel] = 0.8;
+      }
+    break;
+
+    // Silence all MIDI channels.
+    case CONTROL_ALL_SOUND_OFF:
+    case CONTROL_ALL_NOTES_OFF: {
+      for (byte i = 0; i < OPL2_CHANNELS; i ++) {
+        if (channelMap[i].midiChannel == channel) {
+          onNoteOff(channelMap[i].midiChannel, channelMap[i].midiNote, 0);
+        }
+      }
+      break;
+    }
+
+    default:
+      break;
+  }
+}
+
+
+void onSystemReset() {
+  opl2.init();
+  for (byte i = 0; i < OPL2_CHANNELS; i ++) {
+    opl2.setKeyOn(i, false);
+    opl2.setInstrument(i, PIANO1);
+  }
+
+  for (byte i = 0; i < MIDI_CHANNELS; i ++) {
+    programMap[i] = 0;
+    channelVolumes[i] = 0.8;
+  }
+}


Improved state machine to properly handle cloud reconnections. To be integrated in the main temp/humidity sensor

--- Particle/LuxSensor/src/LuxSensor.ino
+++ Particle/LuxSensor/src/LuxSensor.ino
@@ -5,18 +5,23 @@
  *
  * Changelog:
  * v1.0 - 22-06-2017: initial fork from THDweeter to experiment with analogRead
- * v2.0 - 28-06-2017: use the Particle cloud API instead of dweet.io
+ * v2.0 - 29-06-2017: use the Particle cloud API instead of dweet.io and include
+ *                    a state machine to properly handle reconnections
  ******************************************************************************/

 int photoPin = A5;           // photoresistor pin
 int powerPin = A0;
 int readoutTimeIntervalMins = 1;   // perform a readout every given minutes

+const int PHOTON_OFFLINE = 0;
+const int PHOTON_CONNECTING = 1;
+const int PHOTON_ONLINE = 2;
+
 long lastReadoutTime = 0;    // timestamp of the last readout
 float lux, lmin, lmax;
 int day = 0;
-bool connecting = false;
-
+int photonState = PHOTON_ONLINE;
+bool buttonPressed = false;

 void setup() {
   pinMode(photoPin, INPUT);     // prepare the photoresistor
@@ -69,32 +74,37 @@
 void loop() {
   int pushButtonState = HIGH;
   if(pushButtonState == LOW) {
-    // button was pressed, readout
-    readout(true);
-    // and keep WiFi on for other Photon activities/upgrades
+    // button was pressed, connect for an immediate readout
+    buttonPressed = true;
+    photonState = PHOTON_CONNECTING;
+    Particle.connect();
+    return;
   }
   else {
     // force a readout after the given time interval
     if(Time.now() - lastReadoutTime >= readoutTimeIntervalMins*60) {
       // for regular readouts, record the time of this readout: this way,
       // we make the readings as evenly spread in time as possible
-      connecting = true;
+      photonState = PHOTON_CONNECTING;
+      buttonPressed = false;
       Particle.connect();
       lastReadoutTime = Time.now();
       return;
     }
-    if(connecting) {
-      connecting = false;
+  }
+  if(photonState == PHOTON_CONNECTING) {
       digitalWrite(D7, LOW);
-      if(!readout(false)) {
+      if(!readout(buttonPressed)) {
         digitalWrite(D7, HIGH);
       }
-    }
-    if(Time.now() - lastReadoutTime >= 2) {
-      // turn off WiFi to spare power after 20 secs of inactivity
-      WiFi.off();
-      digitalWrite(D7, LOW);
-    }
+      photonState = PHOTON_ONLINE;
+      return;
+  }
+  if(photonState == PHOTON_ONLINE && !buttonPressed) {
+    delay(1000);
+    WiFi.off();
+    digitalWrite(D7, LOW);
+    photonState = PHOTON_OFFLINE;
   }
   // loop at 5 Hz to catch button press events
   delay(200);


Deleting the Clear_Eeprom example

Deleting the Clear_Eeprom example

The example doesn't work anymore now that the library automatically
stores a signature.

--- Examples/Clear_Eeprom/Clear_Eeprom.ino
+++ Examples/Clear_Eeprom/Clear_Eeprom.ino
@@ -1,37 +0,0 @@
-/*
-  Clear the entire EEPROM
-  -----------------------
-  Example using the EEPROM Manager library to erase the entire EEPROM
-  By Jac Goudsmit
-  Distributed under the BSD (3-clause) license.
-  http://github.com/jacgoudsmit/EEPROM_mgr
-
-*/
-
-#include <arduino.h>
-#include <stdlib.h>
-#include <EEPROM_mgr.h>
-
-// The highest usable EEPROM address is #defined in the Arduino header files
-// as E2END. The value depends on the microcontroller that's used. For
-// example, the AVR328 has 1KB of EEPROM, the AVR168 has 512 bytes.
-// The following line declares a type that takes up the entire size of the
-// EEPROM.
-typedef char entire_eeprom[E2END + 1];
-
-// Create an item that uses the entire EEPROM
-EEPROM_item<entire_eeprom> everything;
-
-void setup()
-{
-  // Fill the item with 0xFF to clear the EEPROM
-  // We can't use the assignment operator here so we use the Data operator
-  // to get a pointer to the internal data of the item, fill the data with
-  // bytes containing value 255, and then store the item to the EEPROM.
-  memset(everything.Data(), 255, sizeof(entire_eeprom));
-  everything.Store();
-}
-
-void loop()
-{
-}


working on interrupts

working on interrupts

--- display/display.ino
+++ display/display.ino
@@ -75,7 +75,7 @@

 // Create ECG trace
 ECGReadout ecg = ECGReadout(10,50,tft.height() - BOXSIZE, 100, 15 , 0, &tft);
-TS_Point p;
+//TS_Point p;

 /*
  * draw_submenu() - draws color box submenu on left of screen
@@ -337,9 +337,9 @@
 }

 TS_Point getFixedCoordinates(void){
-   p = ts.getPoint();
+   TS_Point p = ts.getPoint();
    while(!ts.bufferEmpty()){
-       TS_Point throwaway = ts.getPoint();
+       volatile TS_Point q = ts.getPoint();
    }
    // Scale from 0-4000 to tft.width() using calibration numbers
    p.x = tft.height() - map(p.x, TS_MINX, TS_MAXX, 0, tft.height());
@@ -359,8 +359,9 @@
   //temperature_setup();
   //settings_setup();
   ecg.read();
-  myTimer.begin(isr, 150);
-  myTimer.priority(128);
+  //myTimer.begin(isr, 1000000);
+  //myTimer.priority(128);
+  // Serial.begin(9600);
 }

 int display_count = 0;
@@ -385,7 +386,9 @@
         display_count += 1;
       }
 }
-void isr(void) {
+/* void isr(void) {
+  if (ts.bufferEmpty()) { return; }
+  TS_Point p = getFixedCoordinates();
   if (currentMode == HOMESCREEN && alarm_button.isTapped(p.x,p.y)){
     currentMode = ALARMSCREEN;
   }
@@ -394,7 +397,7 @@
       currentMode = HOMESCREEN;
     }
   }
-}
+} */

 void loop(void) {
@@ -402,21 +405,24 @@
   if (currentMode == HOMESCREEN){
     MainScreenInit();
     while (currentMode == HOMESCREEN){
-      dispECGWave();
+      // dispECGWave();
       // Retrieve the touch point
-      p = getFixedCoordinates();
+      TS_Point p = getFixedCoordinates();
       //TS_Point p = ts.getPoint();
       // Scale from 0-4000 to tft.width() using calibration numbers
       //p.x = tft.height() - map(p.x, TS_MINX, TS_MAXX, 0, tft.height());
       //p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.width());
       //fixCoordinates(&(p.x), &(p.y));
+      if (alarm_button.isTapped(p.x,p.y)){
+        currentMode = ALARMSCREEN;
+      }
     }
   }
   /*alarm screen*/
   if (currentMode == ALARMSCREEN){
     SettingsScreenInit();
     while(currentMode == ALARMSCREEN){
-      p = getFixedCoordinates();
+      TS_Point p = getFixedCoordinates();
       if(ECGPlus.isTapped(p.x,p.y)){
         biasECGMin += 1;
         /*for two digit numbers*/
@@ -426,11 +432,7 @@
           tft.setTextSize(2);
           tft.setTextColor(ILI9341_GREEN);
           tft.printf("%d", DEFAULT_ECG_MIN + biasECGMin);
-            if (ts.bufferEmpty()){
-        p.x = 0;
-        p.y = 0;
-      }
-        }
+          }
         else if (DEFAULT_ECG_MIN + biasECGMin > 99){
           /*for three digit numbers*/
           tft.fillRect(56, 72, 45, 20, ILI9341_BLACK);
@@ -438,13 +440,11 @@
           tft.setTextSize(2);
           tft.setTextColor(ILI9341_GREEN);
           tft.printf("%d", DEFAULT_ECG_MIN + biasECGMin);
-            if (ts.bufferEmpty()){
-        p.x = 0;
-        p.y = 0;
-      }
         }
       }
-
+        if(confirm_button.isTapped(p.x,p.y)){
+            currentMode = HOMESCREEN;
+        }
       /*if(ECGMinus.isTapped(p.x,p.y)){
       biasECGMin -= 1;
       //for two digit numbers


Optimization float to int

Optimization float to int

--- Patterns.ino
+++ Patterns.ino
@@ -166,7 +166,7 @@
   // The number of fps required "frame per second"
   int fps = 60;
   // The delta between 2 LED display to fit the fps requirements (in micro-second)
-  int deltaLED = 1000000. / LEDSnum / fps;
+  int deltaLED = 1000000 / (LEDSnum * fps);
   for (int i = 0; i < (LEDSnum); ++i)
   {
     displayNum(i);


implmemented new clock and display functionality

--- src/clock.ino
+++ src/clock.ino
@@ -1,15 +1,16 @@
 #include <Wire.h>
 #include "RTClib.h"
-#include "Adafruit_LEDBackpack.h"
-#include "Adafruit_GFX.h"
 #include "Clock.h"
+#include "Display.h"

 #define VIEW_BUTTON 9
 #define SET_MINUTE_BUTTON 8
 #define SET_HOUR_BUTTON 7
+#define SNOOZE_BUTTON 6
+#define ENABLE_ALARM_BUTTON 5

 RTC_DS1307 rtc;
-Adafruit_7segment matrix = Adafruit_7segment();
+Display* display;
 AlarmClock* alarm;

 void setup () {
@@ -24,11 +25,14 @@
   if (! rtc.isrunning()) {
     Serial.println("RTC is NOT running!");
   }
-  matrix.begin(0x70);
+
   alarm = new AlarmClock();
+  display = new Display();
   pinMode(VIEW_BUTTON, INPUT_PULLUP);
   pinMode(SET_MINUTE_BUTTON, INPUT_PULLUP);
   pinMode(SET_HOUR_BUTTON, INPUT_PULLUP);
+  pinMode(ENABLE_ALARM_BUTTON, INPUT_PULLUP);
+  pinMode(SNOOZE_BUTTON, INPUT_PULLUP);
 }

 void loop () {
@@ -43,13 +47,11 @@
     }
     delete clock;
     clock = alarm;
+  }else if(digitalRead(ENABLE_ALARM_BUTTON)==LOW){
+    alarm->setAlarmEnabled(!alarm->alarmEnabled());
   }
-  matrix.print(formattedTime(clock), DEC);
-  if(clock->isPm()){
-    matrix.writeDigitRaw(2, 0x0A);
-  }else{
-    matrix.drawColon(true);
-  }
-  matrix.writeDisplay();
+
+  display->setDisplay(clock, alarm->alarmEnabled());
+  display->writeDisplay();
   delay(500);
 }


Made LED indicate WiFi connectivity

Made LED indicate WiFi connectivity

--- software/_proto_ESPTesting/ESPNano/ESPNano.ino
+++ software/_proto_ESPTesting/ESPNano/ESPNano.ino
@@ -2,7 +2,9 @@

 #define SSID    "NickNet"
 #define PASS    "27304600"
-#define DST_IP  "173.194.33.136" //Google.com
+#define DST_IP  "140.211.12.4" //Corvalis, OR Transit System
+
+#define LED 13

 SoftwareSerial dbgSerial(11, 10); //Rx, Tx

@@ -13,6 +15,9 @@

 	dbgSerial.begin(9600);
 	dbgSerial.println("\n\r[ESP8266 Interface Test]");
+
+	pinMode(LED, OUTPUT);
+	digitalWrite(LED, LOW);

 	//Test if the module is ready
 	Serial.print("AT\015\012");
@@ -59,7 +64,8 @@
 		testFailed();
 	}

-	delay(5000);
+	digitalWrite(LED, HIGH);
+	delay(1000);

 	dbgSerial.println("[Set single connection mode]");
 	Serial.print("AT+CIPMUX=0\015\012");
@@ -112,11 +118,12 @@
   dbgSerial.println("====");
   delay(1000);

-
+

-	//dbgSerial.println("[Prompting for available networks]");
-	//Serial.print("AT+CWLAP\015\012");
-
+	/*
+	dbgSerial.println("[Prompting for available networks]");
+	Serial.print("AT+CWLAP\015\012");
+	*/

 	//Command prompt to send commands to ESP module
 	while(1){


Connected to WiFi!

Connected to WiFi!

--- software/_proto_ESPTesting/ESPNano/ESPNano.ino
+++ software/_proto_ESPTesting/ESPNano/ESPNano.ino
@@ -1,7 +1,7 @@
 #include <SoftwareSerial.h>

-#define SSID    "NickNet"
-#define PASS    "27304600"
+#define SSID    "OSU_Access"
+#define PASS    ""
 #define DST_IP  "220.181.111.85"

 SoftwareSerial dbgSerial(11, 10); //Rx, Tx
@@ -12,7 +12,7 @@
 	Serial.setTimeout(5000);

 	dbgSerial.begin(9600);
-	dbgSerial.println("ESP8266 Demo");
+	dbgSerial.println("\n\r[ESP8266 Interface Test]");

 	//Test if the module is ready
 	Serial.print("AT\015\012");
@@ -26,10 +26,90 @@
 		dbgSerial.println("The module has not responded.");
 		while(1);
 	}
+
+	if(Serial.find("OK")){
+		dbgSerial.println("[Module Responded OK]");
+	}
+
+	delay(500);
+
+	dbgSerial.println("[Prompting Reset]");
+	Serial.print("AT+RST\015\012");
+
+	if(Serial.find("OK")){
+		dbgSerial.println("[Module Responded OK]");
+	}
+
+	bool connected = false;
+	for (int i = 0; i < 5; i++){
+		if(connectWiFi()){
+			connected = true;
+			break;
+		}
+	}
+	if(!connected){
+		dbgSerial.print("[### Failed to connect to WiFi ###]");
+	}
+
+	delay(5000);
+
+	dbgSerial.println("[Set single connection mode]");
+	Serial.print("AT+CIPMUX=0\015\012");
+
+	if(Serial.find("OK")){
+		dbgSerial.println("[Module Responded OK]");
+	}
 }

 void loop(){
+	/*
 	if(Serial.available()){
 		dbgSerial.print((char) Serial.read());
 	}
-}+	*/
+
+
+
+
+
+	//dbgSerial.println("[Prompting for available networks]");
+	//Serial.print("AT+CWLAP\015\012");
+
+	while(1){
+		if(Serial.available()){
+			dbgSerial.print((char) Serial.read());
+		}
+
+		if(dbgSerial.available()){
+			Serial.print((char)dbgSerial.read());
+		}
+	}
+
+
+	while(1);
+}
+
+bool connectWiFi() {
+	Serial.println("AT+CWMODE=1");
+
+	String cmd = "AT+CWJAP=\"";
+	cmd += SSID;
+	cmd += "\",\"";
+	cmd += PASS;
+	cmd += "\"";
+	cmd += "\015\012";
+
+	dbgSerial.println(cmd);
+	Serial.print(cmd);
+
+	if(Serial.find("OK")) {
+		dbgSerial.println("[Connected to WiFi]");
+		return true;
+	}
+	else {
+		dbgSerial.println("[### Failed to connect to Wifi ###]");
+		return false;
+	}
+
+}
+