adding states to treat alarms

adding states to treat alarms

--- src/elm_clk.ino
+++ src/elm_clk.ino
@@ -47,8 +47,8 @@
 #define EDIT_ALARM_MODE 1
 #define SHOW_TIME_MODE  2
 #define SHOW_TEMP_MODE  3
-#define ERROR_MODE      4
-
+#define SHOW_ALARM_MODE 4
+#define ERROR_MODE      5

 #define SHOW_TIME_DURATION 7000
 #define SHOW_TEMP_DURATION 3000
@@ -432,6 +432,7 @@
 		fsmState = ERROR_MODE;
 	}

+	// default alarm settings, 08:30, disabled
 	pinMode(ALARM_PIN, INPUT_PULLUP);
 	setRtcAlarm(8,30);
 	disableRtcAlarm();
@@ -439,10 +440,18 @@

 void loop()
 {
+	// If not in error state, increment button ticks
 	if (fsmState != ERROR_MODE)
 	{
 		buttonA.tick();
 		buttonB.tick();
+	}
+
+	// If alarm condition is detected, modify FSM state accordingly
+	// When an alarm is triggered, the alarm pin is pulled low.
+	if (!digitalRead(ALARM_PIN))
+	{
+		fsmState = SHOW_ALARM_MODE;
 	}

 	switch (fsmState)
@@ -539,6 +548,14 @@

 			break;

+		case SHOW_ALARM_MODE:
+			if (RTC.alarm(ALARM_0) | (RTC.alarm(ALARM_1)))
+				Serial.println("Alarm!");
+			else
+				oldFsmState = fsmState;
+				fsmState = SHOW_TIME_MODE;
+			break;
+
 		case ERROR_MODE:
 			if (oldFsmState != fsmState)
 			{


fixed conflict

fixed conflict

--- display/display.ino
+++ display/display.ino
@@ -23,7 +23,7 @@
   uView.begin();      // begin of MicroView
   uView.clear(PAGE);   // erase hardware memory inside the OLED controller
   uView.display();
-  uView.setFontType(1);
+  uView.setFontType(2);

 }

@@ -57,12 +57,12 @@

   if(!upButtonState && ((currentMillis - timeLastPressedUpButton) > DEBOUNCE_TIME)){
       timeLastPressedUpButton = currentMillis;
-      Serial.print("u");
+      Serial.print("u\n");
   }

    if(!downButtonState && ((currentMillis - timeLastPressedDownButton) > DEBOUNCE_TIME)){
       timeLastPressedDownButton = currentMillis;
-      Serial.print("d");
+      Serial.print("d\n");
   }


min/max speed

min/max speed

--- example/main.ino
+++ example/main.ino
@@ -14,6 +14,8 @@
   Fan fan1 = Fan(9);

   Fan fan2 = Fan(10);
+
+  // set custom min/max speed
   fan2.setMinSpeed(minSpeed+20);
   fan2.setMaxSpeed(fullSpeed-20);


Changed Baudrate

Changed Baudrate

--- arduino_wifi_duck/arduino_wifi_duck.ino
+++ arduino_wifi_duck/arduino_wifi_duck.ino
@@ -1,5 +1,5 @@
 #include <Keyboard.h>
-#define BAUD_RATE 9600
+#define BAUD_RATE 57200

 #define ExternSerial Serial1


Documentation additions to the firmware

Documentation additions to the firmware


Start of mode button handling refactor

Start of mode button handling refactor

--- moros/moros.ino
+++ moros/moros.ino
@@ -84,7 +84,9 @@
       pressed_at = 0;
       state->pressed = false;
       state->just_released = true;
+      state->press_duration_ms = 0;
       //state.press_duration_ms = 0;
+      return state;
     } else {
       // ???
       serprintf("PollButton::poll: unrecognized return value from digitalRead: %d\r\n", pin_status);
@@ -227,7 +229,7 @@
   const unsigned long mode_button_reset_ms = 3000;
   const unsigned long mode_button_settime_ms = 5000;
   const unsigned long mode_button_poweroff_ms = 7000;
-  enum { INIT, PRE_GAME, IN_PROGRESS, PAUSED, SET_TIME } game_state;
+  enum { INIT, PRE_GAME, IN_PROGRESS, PAUSED, SET_TIME, SET_TIME_CLOCK_1, SET_TIME_CLOCK_2 } game_state;
   bool mode_button_last_pressed_state;
   unsigned long blink_start_ms;
 public:
@@ -316,6 +318,8 @@
     if (game_state == PRE_GAME) return;
     serprintf("Controller reset...\r\n");
     game_state = PRE_GAME;
+    active_player = NONE;
+    clock_being_set = 0;

     for(unsigned int i = 0; i < NUM_PLAYERS; i++) {
       serprintf("player %d clock...\r\n", i);
@@ -325,15 +329,48 @@
       serprintf("player %d update_display...\r\n", i);
       players[i]->update_display();
     }
-    active_player = NONE;
-    clock_being_set = 0;
     serprintf("Controller reset complete.\r\n");
   }

   void handle_mode_button() {

     ButtonState *state = mode_button->poll();
-
+
+    unsigned long press_duration_ms = state->press_duration_ms;
+    bool button_pressed = state->pressed;
+    bool just_released = state->just_released;
+
+
+    switch (game_state) {
+      case PRE_GAME:
+        if (button_pressed) {
+          if (press_duration_ms > mode_button_settime_ms) {
+            set_time();
+          }
+        }
+        break;
+      case IN_PROGRESS:
+        if (button_pressed) {
+          if (press_duration_ms > mode_button_reset_ms) {
+            reset();
+          } else if (press_duration_ms > 0) {
+            pause();
+          }
+        }
+        break;
+      case SET_TIME:
+        if (just_released) {
+          game_state = SET_TIME_CLOCK_1;
+        }
+        break;
+      case SET_TIME_CLOCK_1:
+      case SET_TIME_CLOCK_2:
+        if (press_duration_ms > 0) {
+          set_time_next_step();
+        }
+        break;
+    }
+/*
     //unsigned long mode_button_held = mode_button->poll();
     unsigned long mode_button_held = state->press_duration_ms;
     bool button_pressed = state->pressed;
@@ -353,11 +390,7 @@
 //      serprintf("mode button, _in_ SET_TIME, button_pressed is %d held for %lu and previous %lu\r\n", button_pressed, mode_button_held, mode_button_previous_hold_time_ms);
       // we don't want to be in here because we changed state but the button is still pressed

-      //if (mode_button_held > 0 && !button_pressed && mode_button_last_pressed_at_ms != state->pressed_at) {
       if ((mode_button_held < mode_button_previous_hold_time_ms) && !button_pressed) {
-      //if (mode_button_held > 0 && !button_pressed && mode_button_last_pressed_state) {
-
-      //if (mode_button_held > 0 && !button_pressed) {
         serprintf("reset button was held for %lu and is pressed: %d\r\n", state->press_duration_ms, state->pressed);
         // move to the next clock to set or exit
         serprintf("in handle_mode_button, calling set_time_next_step\r\n");
@@ -378,6 +411,7 @@
 //      serprintf("mode_button_held %lu mode_button_previous_hold_time_ms %lu\r\n", mode_button_held, mode_button_previous_hold_time_ms);
       mode_button_previous_hold_time_ms = mode_button_held;
     }
+    */
   }

@@ -419,7 +453,7 @@
         active_player = (player_who_pressed+1) % 2;
         players[active_player]->clock->start();
       } else {
-        serprintf("Ignoring button press for inactive player %d\r\n", player_who_pressed);
+        //serprintf("Ignoring button press for inactive player %d\r\n", player_who_pressed);
       }
       interrupt_fired = NONE;
     }
@@ -454,6 +488,12 @@
         serprintf("Received interrupt %d, but no player has a button on that interrupt!\r\n", interrupt_fired);
         return;
       }
+
+      if (active_player == NONE) {
+        serprintf("Supposed to pause, but there's no active palyer\r\n");
+        return;
+      }
+
       game_state = IN_PROGRESS;
       interrupt_fired = NONE;
     }
@@ -465,30 +505,32 @@

     switch (game_state) {
       case INIT:
+        return;
         break;
       case PRE_GAME:
         handle_pre_game_player_buttons();
-        handle_mode_button();
         break;
       case IN_PROGRESS:
         handle_in_progress_player_buttons();
-        handle_mode_button();
         if (players[active_player]->out_of_time()) {
           players[active_player]->flag();
-        } else {
-          players[active_player]->tick();
-        }
+          break;
+        }
+        players[active_player]->tick();
         break;
       case SET_TIME:
+      case SET_TIME_CLOCK_1:
+      case SET_TIME_CLOCK_2:
         handle_set_time_player_buttons();
-        handle_mode_button();
         break;
       case PAUSED:
         handle_paused_player_buttons();
         break;
       default:
-        break;
-    }
+        serprintf("Should not get here; default case of controller tick switch!\r\n");
+        break;
+    }
+    handle_mode_button();
 /*
     if (interrupt_fired != NONE) {
       // Someone pressed a button since the last time we checked.


Extinguisher integration

Extinguisher integration

--- firefighter/firefighter.ino
+++ firefighter/firefighter.ino
@@ -7,6 +7,13 @@
 #define SOUND_LED 52

 #define WALL_DISTANCE 7
+
+#define flame_sensor 30
+#define servo_pin 31
+#define interval 10
+
+Motor fan_motor(50,51);
+Servo extingusher_servo;

 Motor leftMotor1(3, 4);
 Motor leftMotor2(5, 6);
@@ -49,11 +56,13 @@
 double getAngle();

 // Sound Sensor
-int sensorPin = A0;
-int ledPin = 13;
+int sensorPin = A0;
 int sensorValue = 0;
 bool robotOn = false;
 bool soundStart();
+
+// Extinguisher
+void extinguish();

 void setup() {
   Serial.begin(9600);
@@ -73,25 +82,33 @@
   attachInterrupt(4, countPulseLeft, CHANGE);

   // Sound Sensor
-  pinMode(ledPin, OUTPUT);
   pinMode(sensorPin, INPUT);
+
+  // Extinguisher
+  pinMode(flame_sensor, INPUT);
+
+  extingusher_servo.attach(servo_pin);
+  extingusher_servo.write(0);
 }

 void loop() {
   // put your main code here, to run repeatedly:
   if (soundStart() || digitalRead(13)) {
+    digitalWrite(SOUND_LED, HIGH);
     robotOn = !robotOn;
   }
+
+  delay(300);

   if(robotOn){
 //    Serial.println(pulseRight);
 //    definedStartSearch();
-     digitalWrite(SOUND_LED, HIGH);
-	  digitalWrite(FLAME_LED, HIGH);
-	  delay(1000);
-	 digitalWrite(SOUND_LED, LOW);
-	  digitalWrite(FLAME_LED, LOW);
-	  delay(1000);
+//	  digitalWrite(FLAME_LED, HIGH);
+//	  delay(1000);
+//
+//	  digitalWrite(FLAME_LED, LOW);
+//	  delay(1000);
+    extinguish();
   }
   else{
     hDrive(0.0, 0.0, 0.0);
@@ -256,3 +273,41 @@
   hDrive(0.0, 0.0, 0.0);
 }

+void extinguish() {
+  for(int i = 0; i <= 180; i += interval){
+    extingusher_servo.write(i);
+    delay(15*interval);//give time for servo to move
+
+    if(!digitalRead(flame_sensor))
+      digitalWrite(FLAME_LED, HIGH);
+
+    //turn on fan
+    fan_motor.set(1);
+    while(!digitalRead(flame_sensor)){
+      //while there is a fire
+      delay(1000);
+    }
+    //turn off fan
+    fan_motor.set(0);
+    digitalWrite(FLAME_LED, LOW);
+  }
+
+  for(int i = 180; i >=0; i -= interval){
+    extingusher_servo.write(i);
+    delay(15*interval);//give time for servo to move
+
+    if(!digitalRead(flame_sensor))
+      digitalWrite(FLAME_LED, HIGH);
+
+    //turn on fan
+    fan_motor.set(1);
+    while(!digitalRead(flame_sensor)){
+      //while there is a fire
+      delay(1000);
+    }
+    //turn off fan
+    fan_motor.set(0);
+    digitalWrite(FLAME_LED, LOW);
+  }
+}
+


bump turn on with low current 13.0 -> 13.1

Signed-off-by: Robert Nelson <d6c41255011d14bfa93d8562b946ca186cfa0c7b@gmail.com>

--- BatteryCharger/BatteryCharger.ino
+++ BatteryCharger/BatteryCharger.ino
@@ -114,7 +114,7 @@

 		//Turn on
 		if ( relay_mode == RELAY_A1_ON ) {
-			if ( busvoltage_A > 13.0 ) {
+			if ( busvoltage_A > 13.1 ) {
 				pinMode(A0, OUTPUT);
 				digitalWrite(A0, HIGH);
 				delay(10);


Implemented the timer feature and it is tested.

--- ServerSketch/ServerSketch.ino
+++ ServerSketch/ServerSketch.ino
@@ -736,41 +736,13 @@
   {
     if( !g_aPins[i].is_input ) // Process output pins
     {
-      if( g_aPins[i].is_analog ) // Process analog pins
-      {
-        if( g_aPins[i].is_timer_on ) // Process timer
-        {
-          Serial.print("Pin ");Serial.print(i);Serial.print(" timer ON");
-          Serial.print(" Start Time: ");Serial.println(g_aPins[i].timer_start_time);
-          if( (millis() - g_aPins[i].timer_start_time) >= g_aPins[i].timer_value*1000 ) // Timer expired
-          {
-            Serial.println("EXPIRED...!!!");
-            analogWrite(i, 0.0);
-          }
-          else
-          {
-            analogWrite(i, getTotalPinValue(i)*ANALOG_OUT_MAX_VALUE );
-          }
-        }
-        else // Timer is off
-        {
-          //Serial.print("Pin ");Serial.print(i);Serial.println(" timer OFF");
-          analogWrite(i, getTotalPinValue(i)*ANALOG_OUT_MAX_VALUE );
-        }
-      }
+      if( g_aPins[i].is_analog ) // Process analog pins
+        analogWrite(i, getTotalPinValue(i)*ANALOG_OUT_MAX_VALUE );
       else // Process digital pins
-      {
-        if( g_aPins[i].is_timer_on ) // Process timer
-        {
-          digitalWrite(i, getTotalPinValue(i) );
-        }
-        else
-        {
-          digitalWrite(i, getTotalPinValue(i) );
-        }
-      }
-    }
-  }
+        digitalWrite(i, getTotalPinValue(i) );
+    }
+  }
+
 }

 ////////////////////////////////////////////////////////////////////////////
@@ -813,6 +785,19 @@
     g_aPins[_iOutPinNum].value = fPinValSum;

   //Serial.print("Analog Pin #: "); Serial.print(_iOutPinNum); Serial.print(" Total Value: "); Serial.println(fPinValSum);
+
+  // Set pin value to zero if timer expired
+  if( g_aPins[_iOutPinNum].is_timer_on )
+  {
+//    Serial.print("Pin ");Serial.print(_iOutPinNum);Serial.print(" timer ON");
+//    Serial.print(" Start Time: ");Serial.println(g_aPins[_iOutPinNum].timer_start_time);
+    if( (millis() - g_aPins[_iOutPinNum].timer_start_time) >= (g_aPins[_iOutPinNum].timer_value-1)*1000 ) // Timer expired
+    {
+//      Serial.println("EXPIRED...!!!");
+      fPinValSum = 0.0;
+      g_aPins[_iOutPinNum].value = fPinValSum;
+    }
+  }

   return fPinValSum;
 }


chore: v2.0.1

chore: v2.0.1

--- moist-plants.ino
+++ moist-plants.ino
@@ -1,5 +1,5 @@
 // Moist Plants
-// version: 2.0
+// version: 2.0.1
 // Author: Mika Hassinen

 #define FASTLED_INTERNAL  // disable pragma message for fastled


stairs: use cubic in/out eased triangle wave for the breathing effect

--- stairs/main.ino
+++ stairs/main.ino
@@ -188,7 +188,7 @@
     uint8_t sine;
     uint8_t value;

-    sine = sin8(animation());
+    sine = cubicwave8(animation());
     start = pots.val - 100;
     if (start > pots.val) {
         start = 0;


Add danielawspush publish.

Add danielawspush publish.

--- gpsfeatures/gpsfeatures.ino
+++ gpsfeatures/gpsfeatures.ino
@@ -42,6 +42,7 @@

     // Subscribe to the integration response event
     Particle.subscribe("hook-response/gps-coordinates", myHandler, MY_DEVICES);
+    Particle.subscribe("hook-response/danielawspush", myHandler, MY_DEVICES);
     // These three functions are useful for remote diagnostics. Read more below.
     Particle.function("tmode", transmitMode);
     Particle.function("batt", batteryStatus);
@@ -72,6 +73,7 @@
             if(transmittingData){
                 // Short publish names save data!
                 Particle.publish("gps-coordinates", t.readLatLon(), 60, PRIVATE);
+                Particle.publish("danielawspush", t.readLatLon(), 60, PRIVATE);
             }
             // but always report the data over serial for local development
             Serial.println(t.readLatLon());


Update featuring optimisations

Update featuring optimisations

The next three months, I had to create a website for my project with a well-based front-end and back-end, test the product in my room almost daily, fix the bugs and take my exams.
This is the piece I updated from the last source code with further optimisation and bug fixes.

In the event of winning the competition in the county, I will have to do more upgrades to it, but we'll see what the future gives in.
- 19th of April 2017

--- temp/temp.ino
+++ temp/temp.ino
@@ -16,13 +16,12 @@
 #define ESP8266_PASS  "certificat"
 #define RXpinSEND 12   // ESP-01 wifiSEND module TX
 #define TXpinSEND 13   // ESP-01 wifiSEND module RX
-#define RELAYbutton 14 // digital switch 1
-#define ALARMbutton 15 // digital switch 2
-#define RELAYpin 16    // digital relay
+#define RELAYbutton 15 // digital switch 1
+#define ALARMbutton 14 // digital switch 2
 #define DHTpin 21      // digital temp sensor
 #define BUZZpin 22     // digital buzzer

-#define REFRESHupload 30 //15*60 second to upload data to server / to be changed to 15 min
+#define REFRESHupload 30 //30*60 second to upload data to server / to be changed to 15 min

 LiquidCrystal lcd(51, 50, 6, 7, 8, 9);
 ESP8266_Simple wifiSEND( RXpinSEND, TXpinSEND);
@@ -101,31 +100,36 @@
   pinMode(PIRsensorPin,INPUT);
   pinMode(ALARMbutton,INPUT);
   pinMode(RELAYbutton,INPUT);
-  pinMode(RELAYpin, OUTPUT);
   pinMode(BUZZpin, OUTPUT);
   Serial.begin(9600);
   wifiSEND.begin(9600); loadScreen(loadTime); loadTime++;
-
+

   lcd.setCursor(0,0); lcd.print("Resetting...             ");
   for( loadTime = 2 ; loadTime < 10; ++loadTime)
     loadScreen(loadTime);
+
+
+

   char bufferr[300];
+  wifiSEND.sendCommand(F("AT"), bufferr, sizeof(bufferr)); delay(50);
+  if(DEBUG)
+    Serial.println(bufferr);
+
   wifiSEND.sendCommand(F("AT+CWJAP?"), bufferr, sizeof(bufferr));
-  delay(5000);
+  delay(2000);
   if(DEBUG){
     Serial.println(bufferr);
     Serial.println(ESP8266_SSID);
   }

-  if(bufferr!=ESP8266_SSID){
-  char buffer11[300];
-  wifiSEND.sendCommand(F("AT+RST"), buffer11, sizeof(buffer11));
-  delay(5000);
+  if(bufferr[0]!=ESP8266_SSID[0] || bufferr[1]!=ESP8266_SSID[1] || bufferr[2]!=ESP8266_SSID[2]){
+  wifiSEND.sendCommand(F("AT+RST"), bufferr, sizeof(bufferr));
+  delay(1000);
   wifiSEND.setupAsWifiStation(ESP8266_SSID, ESP8266_PASS, &Serial);
   delay(5000);
-  }
+  }

   lcd.setCursor(0,0); lcd.print("Connecting...             ");
   for( loadTime = 10 ; loadTime < 16; ++loadTime)
@@ -136,11 +140,12 @@
 }

 int alarm=0,lightBulb=0;
-int lastON=0,r=0;
+int r=0;
 unsigned long WIFIupload = -REFRESHupload ,LASTmotion = 0;

 void loop()
 {
+  Serial.println("Starting new cycle");

   if(DEBUG) Serial.print("Gas value is ");
   if(DEBUG) Serial.println(analogRead(GASpin));
@@ -154,7 +159,7 @@
       char buffer[250];

       memcpy(buffer, 0, sizeof(buffer));
-      strncpy_P(buffer, PSTR("/getgas.php?p=abc"), sizeof(buffer)-1);
+      strncpy_P(buffer, PSTR("/get/getgas.php?p=abc"), sizeof(buffer)-1);

       strncpy_P(buffer+strlen(buffer), PSTR("&lastg="), sizeof(buffer)-strlen(buffer)-1);
       ltoa(analogRead(GASpin), buffer+strlen(buffer), 10);
@@ -203,7 +208,7 @@
       lcd.setCursor(0,1); lcd.print(" armed in         ");
       delay(1000);

-      for( int i = 59 ; i>=0 ; --i ){
+      for( int i = 19 ; i>=0 ; --i ){
         lcd.setCursor(12,1);
         if(i<10) lcd.setCursor(11,1);
         lcd.print(i); lcd.print("         ");
@@ -255,7 +260,6 @@
       lcd.setCursor(0,1);
       lcd.print("         ON!          ");
       setColor(255,255,255);
-      digitalWrite(RELAYpin,HIGH);
     }
     else{
       lcd.setCursor(0,0);
@@ -263,15 +267,10 @@
       lcd.setCursor(0,1);
       lcd.print("         OFF!     ");
       setColor(0,0,0);
-      digitalWrite(RELAYpin,LOW);
     }
     delay(900);
-    if(lastON){
-      r++; r%=2;
-    }
-  }
-  lastON=digitalRead(RELAYbutton);
-
+  }
+

   if(digitalRead(PIRsensorPin)){ // motion sense
     if(DEBUG) Serial.println("Somebody is in this area!");
@@ -281,7 +280,7 @@
       char buffer[250];

       memcpy(buffer, 0, sizeof(buffer));
-      strncpy_P(buffer, PSTR("/getmotion.php?p=abc"), sizeof(buffer)-1);
+      strncpy_P(buffer, PSTR("/get/getmotion.php?p=abc"), sizeof(buffer)-1);

       strncpy_P(buffer+strlen(buffer), PSTR("&lastm="), sizeof(buffer)-strlen(buffer)-1);
       ltoa(millis()/1000, buffer+strlen(buffer), 10);
@@ -352,7 +351,7 @@
     char buffer[250];

       memcpy(buffer, 0, sizeof(buffer));
-      strncpy_P(buffer, PSTR("/get.php?p=abc"), sizeof(buffer)-1);
+      strncpy_P(buffer, PSTR("/get/get.php?p=abc"), sizeof(buffer)-1);

       strncpy_P(buffer+strlen(buffer), PSTR("&temp="), sizeof(buffer)-strlen(buffer)-1);
       ltoa((int)dht.readTemperature(), buffer+strlen(buffer), 10);
@@ -365,9 +364,6 @@

       strncpy_P(buffer+strlen(buffer), PSTR("&light="), sizeof(buffer)-strlen(buffer)-1);
       ltoa(analogRead(PHOTOpin), buffer+strlen(buffer), 10);
-
-      strncpy_P(buffer+strlen(buffer), PSTR("&relay="), sizeof(buffer)-strlen(buffer)-1);
-      ltoa(lightBulb, buffer+strlen(buffer), 10);

       strncpy_P(buffer+strlen(buffer), PSTR("&ms="), sizeof(buffer)-strlen(buffer)-1);
       ltoa(millis()/1000, buffer+strlen(buffer), 10);


marking future changes

marking future changes

--- KSPboard.ino
+++ KSPboard.ino
@@ -22,7 +22,7 @@

 #define ENABLE true
 #define DISABLE false
-#define NEUTRAL 2
+#define NEUTRAL 2 // the natural extension to HIGH and LOW ;-)

 // serial
 #define SERIAL_SPEED 115200
@@ -57,10 +57,11 @@
 #define IO_DEVICE_OPS 0

 // delays
-#define DELAY_LOOP 10
+#define DELAY_LOOP 10 // these are milliseconds
 #define DELAY_START 30
 #define DELAY_OP 100
 #define DELAY_CTRL 100
+#define DELAY_MATRIX 3 // this is in microseconds

 // misc
 #define OPS 16 // Action 1-10, stage, gear, light, rcs, brake, abort
@@ -88,6 +89,7 @@

 // helm control variables
+// convert to structure for storage savings?
 int16_t pitch, yaw, roll, throttle;
 int8_t pitchAdjust = 0, yawAdjust = 0, rollAdjust = 0; // for ramping the direction input

@@ -145,6 +147,7 @@
 }

 // direction helpers
+//convert to matrix
 int16_t getAdjustment(uint8_t pinH, uint8_t pinL, int8_t adj) // get control input
 {
   switch (digitalRead(pinH) ? HIGH : (digitalRead(pinL) ? LOW : NEUTRAL))
@@ -159,8 +162,8 @@
         adj = RAMP_MIN;
       break;

+    default:
     case NEUTRAL: // stuck in the middle with you
-    default:
       adj = 0;
   }

@@ -230,6 +233,7 @@

 void setupHelm()
 {
+  //convert to matrix
   pinMode(PIN_PITCH_U, INPUT_PULLUP);
   pinMode(PIN_PITCH_D, INPUT_PULLUP);
   pinMode(PIN_PITCH_S, INPUT_PULLUP);
@@ -261,16 +265,16 @@
   roter = _vol_rotaryControl; // copy the volatile control variable
   interrupts(); // reenable interrupts immediately

-  uint8_t state = rotaryControl2State(roter);
-
-  if (state != controlState)
-  {
-    controlState = state; // update the hilighted state
+  uint8_t newState = rotaryControl2State(roter);
+
+  if (newState != controlState)
+  {
+    controlState = newState; // update the hilighted state

     // do hiligting stuff //
   }

-  if (controlDebounce > 0)
+  if (controlDebounce > 0) //
   {
     controlDebounce--; // do dat sweet digi debounce
   }
@@ -299,6 +303,7 @@

 void updateHelm()
 {
+  //convert to matrix
   // update control surface inputs
   pitchAdjust = getAdjustment(PITCH_PINS, pitchAdjust);
   pitch = getDirection(pitch, pitchAdjust, PITCH_STICK);
@@ -340,7 +345,9 @@
           // if that switch is 1 then set it's state to DELAY_OP to flag
           // it to be sent out over serial, otherwise set it to zero
           opState[index] =  ((1 << index) & data) ? DELAY_OP : 0;
-          ops++;
+
+          // increase the operations counter
+          ops++;
         }
       }
     }


Fix encoder bug

Fix encoder bug

--- KomaRoof.ino
+++ KomaRoof.ino
@@ -115,7 +115,7 @@
     }

     motorTask.enable();
-    buttonTask.enable();
+//    buttonTask.enable();
     currentMeasurementTask.enable();
     test("");
 }
@@ -142,13 +142,13 @@

 void encoderGate1ISR() {
     int previousEncoderState = encoderState;
-    encoderState = (encoderState & 0x01) | (digitalRead(PIN_ENCODER_GATE_1 == LOW) ? 2 : 0);
+    encoderState = (encoderState & 0x01) | (digitalRead(PIN_ENCODER_GATE_1) == LOW ? 2 : 0);
     updateEncoder(previousEncoderState, encoderState);
 }

 void encoderGate2ISR() {
     int previousEncoderState = encoderState;
-    encoderState = (encoderState & 0x2) | (digitalRead(PIN_ENCODER_GATE_2 == LOW) ? 1 : 0);
+    encoderState = (encoderState & 0x2) | (digitalRead(PIN_ENCODER_GATE_2) == LOW ? 1 : 0);
     updateEncoder(previousEncoderState, encoderState);
 }


Dylan needs comments for his code

Dylan needs comments for his code

--- touch/touch.ino
+++ touch/touch.ino
@@ -53,32 +53,32 @@
   last[2] = 0;
   readAccel();

-  while (true) {
-    if (!(reading[0] == 0 || reading[1] == 0 || reading[2] == 0)) {
-      if ((last[0] == reading[0] || last[1] == reading[1] || last[2] == reading[2])) {
-        count++;
-        if (count > 5) {
-          base[0] = last[0];
-          base[1] = last[1];
-          base[2] = last[2];
-          break;
-        } else {
-          readAccel();
-          delay(200);
-        }
-      } else {
-        last[0] = reading[0];
-        last[1] = reading[1];
-        last[2] = reading[2];
-        count = 0;
-        readAccel();
-        delay(200);
-      }
-    } else {
-      count = 0;
-      readAccel();
-      delay(200);
-    }
+  while (true) { // Comment your code dylan
+    if (!(reading[0] == 0 || reading[1] == 0 || reading[2] == 0)) { // Comment your code dylan
+      if ((last[0] == reading[0] || last[1] == reading[1] || last[2] == reading[2])) { // Comment your code dylan
+        count++; // Comment your code dylan
+        if (count > 5) { // Comment your code dylan
+          base[0] = last[0]; // Comment your code dylan
+          base[1] = last[1]; // Comment your code dylan
+          base[2] = last[2]; // Comment your code dylan
+          break; // Comment your code dylan
+        } else { // Comment your code dylan
+          readAccel(); // Comment your code dylan
+          delay(200); // Comment your code dylan
+        } // Comment your code dylan
+      } else { // Comment your code dylan
+        last[0] = reading[0]; // Comment your code dylan
+        last[1] = reading[1]; // Comment your code dylan
+        last[2] = reading[2]; // Comment your code dylan
+        count = 0; // Comment your code dylan
+        readAccel(); // Comment your code dylan
+        delay(200); // Comment your code dylan
+      } // Comment your code dylan
+    } else { // Comment your code dylan
+      count = 0; // Comment your code dylan
+      readAccel(); // Comment your code dylan
+      delay(200); // Comment your code dylan
+    } // Comment your code dylan
   }
   Serial.println("Done Calibrating");
 }


Various bug fixes and improvements

Various bug fixes and improvements

--- ManeAvis.ino
+++ ManeAvis.ino
@@ -12,22 +12,19 @@
 #include "FiniteStateMachine.h"
 #include "AlarmToneLanguage.h"
 #include "AlarmManager.h"
+#include "ClickButton.h"
 #include "Runtime.h"

+SYSTEM_MODE(SEMI_AUTOMATIC);
 SYSTEM_THREAD(ENABLED);
-SYSTEM_MODE(SEMI_AUTOMATIC);
-
-State Start = State(NULL, updateStart, exitStart);
-State Clock = State(updateClock);
-State Alarm = State(enterAlarm, updateAlarm, exitAlarm);
-// State Snuze = State(enterSnuze, updateSnuze, exitSnuze); // Snooze is too many letters, broke my trend
-
-FSM stateMachine = FSM(Start);

 // use hardware SPI
 #define OLED_DC     D3
 #define OLED_CS     D4
 #define OLED_RESET  D5
+
+#define SPEAKER     D0
+#define BUTTON      D1

 #if defined COLOR_SCREEN
 // Color definitions
@@ -45,31 +42,48 @@
 Adafruit_SSD1306 Display(OLED_DC, OLED_RESET, OLED_CS);
 #endif

-#define ALARM_LENGTH 30000
+#define ALARM_LENGTH      30 * 1000 // 30 seconds
+#define SNUZE_LENGTH 10 * 60 * 1000 // 10 minutes TODO: make this configurable
+
 AlarmManager alarms = AlarmManager();

+State Start = State(enterStart, updateStart, exitStart);
+State Clock = State(updateClock);
+State Alarm = State(enterAlarm, updateAlarm, exitAlarm);
+State Snuze = State(enterSnuze, updateSnuze, exitSnuze); // Snooze is too many letters, broke my trend
+
+FSM stateMachine = FSM(Start);
+
+ClickButton button(BUTTON, HIGH);
+
 /*Thread renderer;*/

-/*Timer player(1, play);      // Play alarm tones 100x per second*/
-Timer renderer(100, render); // Render 10x per second
-Timer syncer(60000, sync);   // Sync cloud data once per minute
-
-Runtime alarmRuntime = Runtime();
-/*Runtime playerRuntime = Runtime();*/
-
-uint16_t speakerPin = D0;
-
-/*String song = "SMB Theme:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6";*/
-
-/*AlarmToneLanguage *parser;*/
+Timer player(1, play);       // Play alarm tone
+Timer renderer(200, render); // Render screen
+Timer syncer(1000, sync);   // Update Particle Cloud variables
+
+/*Runtime alarmRuntime  = Runtime();*/
+Runtime snuzeRuntime  = Runtime();
+Runtime playerRuntime = Runtime();
+
+String song = "SMB Theme:d=4,o=5,b=80:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6";
+
+AlarmToneLanguage *parser;

 int rssi = 0;
 uint32_t freeMemory = 0;
+uint32_t frameTime = 0;
+uint32_t loopTime = 0;

 uint8_t previousMinute;

 void setup() {
-  RGB.control(true);
+  pinMode(SPEAKER, OUTPUT);
+  pinMode(BUTTON, INPUT);
+
+  button.debounceTime   = 20;
+  button.multiclickTime = 20; // Only allow 1 click
+  button.longClickTime  = 2000;

   #if defined COLOR_SCREEN
   Display.begin();
@@ -77,25 +91,42 @@
   Display.begin(SSD1306_SWITCHCAPVCC);
   #endif

+  #if defined COLOR_SCREEN
+  Display.fillScreen(BLACK);
+  #else
+  Display.display();
+  #endif
+
+  Particle.variable("loopTime", loopTime);
+  Particle.variable("frameTime", frameTime);
   Particle.variable("freeMemory", freeMemory);
   Particle.variable("rssi", rssi);
-
+
   Particle.function("alarm", handleAlarm);
-
-  #if defined COLOR_SCREEN
-  Display.fillScreen(BLACK);
-  #else
-  Display.display();
-  #endif
-
+}
+
+void loop() {
+  uint32_t start = millis();
+
+  if(!Particle.connected()) {
+    Particle.connect();
+  }
+
+  if(stateMachine.isInState(Alarm) || stateMachine.isInState(Snuze)) {
+    button.Update();
+  }
+
+  stateMachine.update();
+
+  loopTime = millis() - start;
+}
+
+void enterStart() {
   Time.zone(-6); // TODO: EEPROM/flash and configure

+  // Display splash screen
+
   alarms.load();
-}
-
-void loop() {
-  if(!Particle.connected()) Particle.connect();
-  stateMachine.update();
 }

 void updateStart() {
@@ -107,6 +138,8 @@
 void exitStart() {
   renderer.start();
   syncer.start();
+
+  RGB.control(true);
 }

 void updateClock() {
@@ -123,71 +156,140 @@
 }

 void enterAlarm() {
-  alarmRuntime.start();
+  Particle.publish("alarm:start", Time.format(Time.now(), TIME_FORMAT_ISO8601_FULL));
+
+  /*alarmRuntime.start();*/
+
   RGB.color(0, 0, 255);

-  Particle.publish("alarm:start", Time.format(Time.now(), TIME_FORMAT_ISO8601_FULL));
-
-  /*parser = new AlarmToneLanguage(song);*/
-  /*player.reset();*/
+  parser = new AlarmToneLanguage(song);
+  player.reset();
 }

 void updateAlarm() {
   RGB.brightness(map(abs((millis() % 2000) - 1000), 0, 1000, 0, 255));

-  // TODO: Remove when snooze/terminate functionality is implemented
-  if(alarmRuntime.check(ALARM_LENGTH)) {
+  uint8_t clicks = button.clicks;
+
+  switch(button.clicks) {
+    case -1:
+      stateMachine.transitionTo(Clock);
+      return;
+    case 1:
+      stateMachine.transitionTo(Snuze);
+      return;
+  }
+
+  // TODO: Remove when snooze/dismiss functionality is implemented
+  /*if(alarmRuntime.check(ALARM_LENGTH)) {
     stateMachine.transitionTo(Clock);
-  }
+  }*/
 }

 void exitAlarm() {
-  /*player.stop();*/
-  noTone(speakerPin);
+  player.stop();
+  noTone(SPEAKER);

   RGB.color(0, 0, 0);
   RGB.brightness(0);

+  delete parser;
+
   Particle.publish("alarm:end", Time.format(Time.now(), TIME_FORMAT_ISO8601_FULL));
-
-  /*delete parser;*/
+}
+
+void enterSnuze() {
+  Particle.publish("snooze:start");
+  snuzeRuntime.start();
+}
+
+void updateSnuze() {
+  if(button.clicks == -1) {
+    stateMachine.transitionTo(Clock);
+    return;
+  }
+
+  if(snuzeRuntime.check(SNUZE_LENGTH)) {
+    stateMachine.transitionTo(Alarm);
+  }
+}
+
+void exitSnuze() {
+  Particle.publish("snooze:end");
 }

 void render() {
+  uint32_t start = millis();

   time_t time = Time.now();
+  bool isAM   = Time.isAM();
+  static bool wasAM = false;

   #if !defined COLOR_SCREEN
   Display.clearDisplay();
   #endif

   #if defined COLOR_SCREEN
+  drawIcon(1, 1, 12, abs(WiFi.RSSI()), YELLOW, WHITE);
+
+  Display.setTextSize(1);
   Display.setTextColor(YELLOW, BLACK);
+  Display.setCursor(18, 6);
+
+  Display.print(WiFi.SSID());
+  #endif
+
+  Display.setTextSize(3);
+
+  #if defined COLOR_SCREEN
+  Display.setTextColor(BLUE, BLACK);
+  Display.setCursor(12, 55);
   #else
   Display.setTextColor(WHITE);
-  #endif
-  Display.setTextSize(3);
   Display.setCursor(12, 22);
+  #endif

   Display.print(Time.format(time, Time.second() % 2 == 0 ? "%l:%M" : "%l %M"));

+  #if defined COLOR_SCREEN
+  if(isAM != wasAM) {
+    wasAM = isAM;
+    Display.print(' ');
+  }
+  #else
+  Display.print(' ');
+  #endif
+
+  if(isAM) {
+    #if defined COLOR_SCREEN
+    Display.setCursor(102, 70);
+    #else
+    Display.setCursor(102, 37);
+    #endif
+  } else {
+    #if defined COLOR_SCREEN
+    Display.setCursor(102, 55);
+    #else
+    Display.setCursor(102, 22);
+    #endif
+  }
+
   Display.setTextSize(1);
-
-  if(Time.isAM()) {
-    #if defined COLOR_SCREEN
-    Display.print("  ");
-    #endif
-    Display.setCursor(102, 37);
-  }
   Display.print(Time.format(time, "%p"));

-  Display.setTextSize(1);
-  Display.setCursor(68, 1);
+  #if defined COLOR_SCREEN
+  Display.setCursor(34, 80);
+  #else
+  Display.setCursor(34, 42);
+  #endif
+
   Display.print(Time.format(time, "%F"));

   #if !defined COLOR_SCREEN
   Display.display();
   #endif
+
+  frameTime = millis() - start;
 }

 void sync() {
@@ -197,13 +299,15 @@
   if(Time.hour() == 0 && Time.minute() == 0) Particle.syncTime();
 }

-/*void play() {
+void play() {
   if(playerRuntime.check(parser->getDuration())) {
     if(parser->next()) {
-      parser->isRest() ? noTone(speakerPin) : tone(speakerPin, parser->getNote(), parser->getDuration());
+      parser->isRest() ? noTone(SPEAKER) : tone(SPEAKER, parser->getNote(), parser->getDuration());
+    } else {
+      parser->rewind();
     }
   }
-}*/
+}

 int handleAlarm(String value) {
   bool result = false;
@@ -224,3 +328,16 @@

   return result ? 1 : -1;
 }
+
+void drawIcon(uint16_t x, uint16_t y, uint16_t size, uint16_t signalStrength, uint16_t color, uint16_t dimColor) {
+  uint16_t gap = size / 5;
+  uint16_t unit = 127 / 5;
+
+  x += gap / 2;
+  y += size - gap / 2;
+
+  for(int i = 0; i < 5; i++) {
+    uint16_t radius = i * gap;
+    Display.drawLine(x + radius, y, x + radius, y - (i + 1) * gap, signalStrength > i * unit ? color : dimColor);
+  }
+}


Display initial countdown

Display initial countdown

--- short-circuit-limiter/short-circuit-limiter.ino
+++ short-circuit-limiter/short-circuit-limiter.ino
@@ -1,4 +1,4 @@
-#include <UC1701.h>
+#include <U8g2lib.h>
 #include "CTSensor.h"

 #define CURRENT_ENABLE_THRESHOLD 0.2
@@ -12,7 +12,7 @@
 #define PIN_RELAY_LIMITER 7

 #define CT_CALIBRATION_VALUE 60.6  // (100A / 0.05A) / 33 ohms
-#define INITIAL_SETTLE_TIME 5000 //15 seconds
+#define INITIAL_SETTLE_TIME 15000 //15 seconds

 #define DELAY_BEFORE_LIMITER_RELAY_ENABLE 1000

@@ -29,7 +29,7 @@
 STATE currentState = STATE_MCB_TRIPPED;
 STATE nextState = STATE_WINDOW_BEFORE;

-UC1701 lcd;
+U8G2_UC1701_MINI12864_F_4W_SW_SPI u8g2(U8G2_R2, 21, 20, 19, 22);
 CTSensor clamp(PIN_ANALOG, CT_CALIBRATION_VALUE);

 unsigned long lastDisplayTime = 0;
@@ -48,28 +48,40 @@
   pinMode(PIN_RELAY_MCB, OUTPUT);
   pinMode(PIN_BUTTON_ENTER, INPUT);

-
   changeDisplayBacklight(true);
   passFullCurrentThrough(false);
   changeMCBRelayState(false);

-
-  lcd.begin();
-  lcd.setCursor(0, 0);
-  lcd.print("Short Circuit Limiter");
-
-  lcd.setCursor(0, 3);
-  lcd.print("Waiting to settle...");
-
-  unsigned long initialTime = 0;
-
-  while((millis() - initialTime) < INITIAL_SETTLE_TIME){
+  u8g2.begin();
+
+  unsigned long initialTime = millis();
+  unsigned long timeElapsedSinceStart;
+
+  while((timeElapsedSinceStart = (millis() - initialTime)) < INITIAL_SETTLE_TIME){
     clamp.doIncrementalMeasurement();
+    unsigned long timeLeft = INITIAL_SETTLE_TIME - timeElapsedSinceStart;
+    unsigned int timeLeftSeconds = timeLeft / 1000;
+
+    u8g2.clearBuffer();
+
+    u8g2.setFont(u8g2_font_6x10_tr);
+    u8g2.drawStr(0,10, "Short Circuit Limiter\n");
+    u8g2.drawStr(0,35, "Starting in: ");
+
+    u8g2.setFont(u8g2_font_9x18_tr);
+    char secondsBuffer[10];
+    sprintf(secondsBuffer, "%ds", timeLeftSeconds);
+
+    u8g2.drawStr(80, 35, secondsBuffer);
+    u8g2.setFont(u8g2_font_5x8_tr);
+    u8g2.drawStr(0,60, "Designer: Yeo Kheng Meng");
+
+    u8g2.sendBuffer();
+
   }

   //To clear the accmulated reading
   clamp.getIrmsFromIncrementalMeasurement();
-  lcd.clear();

   Serial.begin(115200);
   Serial.println("Setup complete");
@@ -116,23 +128,23 @@
    }

-  long long currentTime = millis();
-
-  runningTotal += currentValue;
-  samplesTaken++;
-
-  //We don't want to keep printing to screen as it is slow so we just do a running average
-  if((currentTime - lastDisplayTime) >= INTERVAL_PRINT){
-
-    lastDisplayTime = currentTime;
-    double average = runningTotal / samplesTaken;
-
-    runningTotal = 0;
-    samplesTaken = 0;
-
-    lcd.setCursor(0, 0);
-    lcd.print(currentValue);
-  }
+//  long long currentTime = millis();
+//
+//  runningTotal += currentValue;
+//  samplesTaken++;
+//
+//  //We don't want to keep printing to screen as it is slow so we just do a running average
+//  if((currentTime - lastDisplayTime) >= INTERVAL_PRINT){
+//
+//    lastDisplayTime = currentTime;
+//    double average = runningTotal / samplesTaken;
+//
+//    runningTotal = 0;
+//    samplesTaken = 0;
+//
+//    lcd.setCursor(0, 0);
+//    lcd.print(currentValue);
+//  }

 }


First attempt at adding MavLink support

First attempt at adding MavLink support

--- SDLogger.ino
+++ SDLogger.ino
@@ -2,6 +2,7 @@
 #include <SPI.h>

 #include "mk_serial.h"
+#include "mavlink.h"
 #include "ublox.h"

 // Pin definitions


updated sample

updated sample

--- installation/examples/Debug_uSpeech/Debug_uSpeech.ino
+++ installation/examples/Debug_uSpeech/Debug_uSpeech.ino
@@ -3,10 +3,12 @@
 char option = 0;
 void setup(){
   voice.calibrate();
+  voice.f_enabled = true;
   Serial.begin(9600);
 }
 void loop(){
-  voice.sample();
+  //voice.sample();
+
   char c=voice.getPhoneme();
   if(option==0){
     Serial.println("uSpeech debug tool--------");
@@ -35,8 +37,5 @@
   if(option=='d'){
   	Serial.println(voice.testCoeff);
   }
-  if(option=='e'){
-
-    Serial.println(voice.vowelRatio);
-  }
-}+
+}


Update to use animation_boot and adds disconnect interaction during boot

Disconnect interaction requires disconnection of USB before powering down USB
module. Not doing so seems to be a source of kernel panics on OS X

--- xadow-watch.ino
+++ xadow-watch.ino
@@ -17,25 +17,22 @@

 #define LEFT_GUTTER_SIZE    (FONT_X)
 #define FONT_SIZE           (1)
-#define LINE_SPACING        (FONT_SIZE*FONT_Y+4)
+#define LINE_HEIGHT         (FONT_SIZE*FONT_Y+4)

-SSD1331 oled = SSD1331(cs, dc, mosi, sclk);
+SSD1331 oled = SSD1331(cs, dc, mosi, sclk);

 char *test_menu[] = {"hello", "world", "here be", "dragons", NULL};

 char _sbuf[64];
 char _sbuf2[64];

-uint8_t logbat = 0;
-uint16_t eeaddr = 1;
-
 uint16_t now = 0;
 uint16_t checkpoint;
-

 typedef enum {
   SCREEN_WATCH,
   SCREEN_STATUS,
+  SCREEN_OTHER,
 } Screen;

 Screen currentScreen;
@@ -48,35 +45,31 @@

   oled.init();
   oled.fillScreen(COLOR_BLACK);
-  oled.drawString("BOOTING", (RGB_OLED_WIDTH-FONT_X*6)/2, RGB_OLED_HEIGHT/2-FONT_Y/2, 1, COLOR_BLUE);
-  delay(1000);
+  animation_boot();
   oled.fillScreen(COLOR_BLACK);
-
+
   menu_init();
   status_init();
   watch_init(now);
-
+
   status_show();
-
+
   delay(1000);
-
+
   menu_show(test_menu);
-
+
   delay(1000);
-
+
   oled.fillScreen(COLOR_BLACK);
-  watch_show(0xFF);

-  if (EEPROM[0] != 0x05) {
-    EEPROM[0] = 0x05;
-    logbat = 1;
-  } else {
-    Serial.begin(9600);
-    Serial.println("Battery log detected, not overwriting");
-    for (eeaddr = 1; eeaddr < 1024; ++eeaddr) {
-      Serial.println(EEPROM[eeaddr], DEC);
-    }
-  }
+  currentScreen = SCREEN_OTHER;
+
+  oled.drawString("Disconnect USB", 0, 0, FONT_SIZE, COLOR_RED);
+  oled.drawString("then press WAKE", 0, LINE_HEIGHT, FONT_SIZE, COLOR_RED);
+  while(digitalRead(10) == HIGH);;
+
+  now = 0;
+  checkpoint = millis();

   power_twi_disable();
   power_usart1_disable();
@@ -85,10 +78,6 @@
   power_timer1_disable();
   power_timer2_disable();
   power_timer3_disable();
-
-  now = 0;
-  checkpoint = millis();
-  currentScreen = SCREEN_WATCH;
 }

 void loop() {
@@ -100,6 +89,8 @@

   power_spi_enable();
   uint8_t changes = watch_tick(now);
+
+  batlog_tick(changes);

   Screen nextscreen = currentScreen;

@@ -122,15 +113,7 @@

     case SCREEN_WATCH:
       watch_show(changes);
-      break;
-  }
-
-  if (changes >= 2 && logbat) {
-    if (eeaddr < 1024) {
-      uint8_t batvol = Xadow.getBatVol()*10;
-      EEPROM[eeaddr] = batvol;
-      eeaddr += 1;
-    }
+      break;
   }

   uint16_t t = millis();


Updates time keeping and screen handling in xadow-watch

--- xadow-watch.ino
+++ xadow-watch.ino
@@ -29,7 +29,20 @@
 uint8_t logbat = 0;
 uint16_t eeaddr = 1;

+uint16_t now = 0;
+uint16_t checkpoint;
+
+
+typedef enum {
+  SCREEN_WATCH,
+  SCREEN_STATUS,
+} Screen;
+
+Screen currentScreen;
+
 void setup() {
+  pinMode(10, INPUT);
+
   Xadow.init();
   //Xadow.greenLed(LEDON);

@@ -37,29 +50,28 @@
   oled.fillScreen(COLOR_BLACK);
   oled.drawString("BOOTING", (RGB_OLED_WIDTH-FONT_X*6)/2, RGB_OLED_HEIGHT/2-FONT_Y/2, 1, COLOR_BLUE);
   delay(1000);
+  oled.fillScreen(COLOR_BLACK);

   menu_init();
   status_init();
-  watch_init();
+  watch_init(now);

   status_show();

-  delay(3000);
+  delay(1000);

   menu_show(test_menu);

-  delay(3000);
+  delay(1000);

   oled.fillScreen(COLOR_BLACK);
   watch_show(0xFF);

-  Serial.begin(9600);
-  if (EEPROM[0] != 0x03) {
-    EEPROM[0] = 0x03;
+  if (EEPROM[0] != 0x05) {
+    EEPROM[0] = 0x05;
     logbat = 1;
-
-    Serial.println("Battery log started");
   } else {
+    Serial.begin(9600);
     Serial.println("Battery log detected, not overwriting");
     for (eeaddr = 1; eeaddr < 1024; ++eeaddr) {
       Serial.println(EEPROM[eeaddr], DEC);
@@ -73,6 +85,10 @@
   power_timer1_disable();
   power_timer2_disable();
   power_timer3_disable();
+
+  now = 0;
+  checkpoint = millis();
+  currentScreen = SCREEN_WATCH;
 }

 void loop() {
@@ -80,20 +96,44 @@

   // sleep for a bit to save power. This is OK b/c timer0 which provides
   // millis is not disabled
-  Xadow.goToSleep(SLEEP_MODE_IDLE, 100);
+  Xadow.goToSleep(SLEEP_MODE_PWR_DOWN, 200);

   power_spi_enable();
-  uint8_t changes = watch_tick(millis());
-  if (changes) {
-    watch_show(changes);
-    //status_show();
-    // log voltage every minute
-    if (changes >= 2 && logbat) {
-      if (eeaddr < 1024) {
-        uint8_t batvol = Xadow.getBatVol()*10;
-        EEPROM[eeaddr] = batvol;
-        eeaddr += 1;
-      }
+  uint8_t changes = watch_tick(now);
+
+  Screen nextscreen = currentScreen;
+
+  if (digitalRead(10) == LOW) {
+    nextscreen = SCREEN_STATUS;
+  } else {
+    nextscreen = SCREEN_WATCH;
+  }
+
+  if (nextscreen != currentScreen) {
+    oled.fillScreen(COLOR_BLACK);
+    currentScreen = nextscreen;
+  }
+
+  switch(nextscreen) {
+    case SCREEN_STATUS:
+      status_show();
+      delay(1000);
+      break;
+
+    case SCREEN_WATCH:
+      watch_show(changes);
+      break;
+  }
+
+  if (changes >= 2 && logbat) {
+    if (eeaddr < 1024) {
+      uint8_t batvol = Xadow.getBatVol()*10;
+      EEPROM[eeaddr] = batvol;
+      eeaddr += 1;
     }
   }
+
+  uint16_t t = millis();
+  now += millis() - checkpoint + 200;
+  checkpoint = t;
 }


Use more channels

Use more channels

--- VardeLED.ino
+++ VardeLED.ino
@@ -2,6 +2,7 @@
 #include <SPI.h>
 #include <Ethernet.h>
 #include <ArtNode.h>
+#include "ArtNetFrameExtension.h"

 #include "TeensyMAC.h"
 #include <EEPROM.h>
@@ -9,11 +10,11 @@
 #define VERSION_HI 0
 #define VERSION_LO 3

-#define RGBW_PER_UNIVERSE   127 // Should be 128, but madmapper wont send 128 rgbw channels out....
+#define RGBW_PER_UNIVERSE   128
 #define RGB_PER_UNIVERSE    RGBW_PER_UNIVERSE*4.0/3.0

 #define NUM_RGB_LEDS_4      (int)ceil(RGB_PER_UNIVERSE * 4)
-//#define NUM_RGB_LEDS_3    (int)ceil(RGB_PER_UNIVERSE * 3)
+//#define NUM_RGB_LEDS_3    (int)ceil(RGB_PER_UNIVERSE * 3)
 #define NUM_RGB_LEDS_3      287 // We never use 3 full universes, so cap the length for better performance
 #define NUM_RGB_LEDS_2      (int)ceil(RGB_PER_UNIVERSE * 2)
 #define NUM_RGB_LEDS_1      (int)ceil(RGB_PER_UNIVERSE)
@@ -39,8 +40,8 @@
 CRGB led_data[NUM_RGB_LEDS_4];
 byte * led_data_ptr_1 = (byte*)led_data;
 byte * led_data_ptr_2 = (byte*)led_data + RGBW_PER_UNIVERSE * 4;
-byte * led_data_ptr_3 = (byte*)led_data + 2*RGBW_PER_UNIVERSE * 4;
-byte * led_data_ptr_4 = (byte*)led_data + 3*RGBW_PER_UNIVERSE * 4;
+byte * led_data_ptr_3 = (byte*)led_data + 2 * RGBW_PER_UNIVERSE * 4;
+byte * led_data_ptr_4 = (byte*)led_data + 3 * RGBW_PER_UNIVERSE * 4;

 bool locateMode = false;

@@ -66,14 +67,14 @@
   VERSION_LO
 };

-ArtNode node;
+ArtNodeExtended node;
 ////////////////////////////////////////////////////////////

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

@@ -108,7 +109,7 @@
   udp.begin(config.udpPort);

   // Open ArtNet
-  node = ArtNode(config, sizeof(udp_buffer), udp_buffer);
+  node = ArtNodeExtended(config, sizeof(udp_buffer), udp_buffer);

   // Create 4 outputs with different lengths (can be tweaked)
   FastLED.addLeds<WS2812, PIN_LED_1, RGB>(led_data, NUM_RGB_LEDS_3);
@@ -116,7 +117,7 @@
   FastLED.addLeds<WS2812, PIN_LED_3, RGB>(led_data, NUM_RGB_LEDS_2);
   FastLED.addLeds<WS2812, PIN_LED_4, RGB>(led_data, NUM_RGB_LEDS_1);
   FastLED.setDither(0);
-
+
   Serial.begin(9600);

   blink();
@@ -126,15 +127,30 @@
 void loop() {

   while (udp.parsePacket()) {
-digitalWrite(PIN_DEBUG, HIGH);
-
-    // First read the header to make sure it's Art-Net
+    digitalWrite(PIN_DEBUG, HIGH);
+
+    // Special ArtNet Frame Extension
     unsigned int n = udp.read(udp_buffer, sizeof(ArtHeader));
     if (n >= sizeof(ArtHeader)) {
-
       ArtHeader* header = (ArtHeader*)udp_buffer;
       // Check packet ID
-      if (memcmp(header->ID, "Art-Net", 8) == 0) {
+      /*if (memcmp(header->ID, "Art-Ext", 8) == 0) {
+        // Read the rest of the packet
+        udp.read(udp_buffer + sizeof(ArtHeader), udp.available());
+
+        // Package Op-Code determines type of packet
+        switch (header->OpCode) {
+          // ArtNet Frame Extension
+          case OpPoll | 0x0001:
+            node.createExtendedPollReply();
+            artnetSend(udp_buffer, node.sizeOfExtendedPollReply());
+            break;
+
+        }
+      }
+
+      // Standard ArtNet commands
+      else */if (memcmp(header->ID, "Art-Net", 8) == 0) {

         // Read the rest of the packet
         udp.read(udp_buffer + sizeof(ArtHeader), udp.available());
@@ -147,6 +163,7 @@
             node.createPollReply();
             artnetSend(udp_buffer, sizeof(ArtPollReply));
             break;
+

           // DMX packet
           case OpDmx: {
@@ -168,12 +185,12 @@
                       //FastLED[0].show(led_data, NUM_RGB_LEDS_1, 255);
                       break;
                     }
-                  case 1: {
-                      // Copy dmx data to the second 1/4 of the led_data
+                  case 1: {
+                      // Copy dmx data to the second 1/4 of the led_data
                       memcpy(led_data_ptr_2, dmx->Data, dmx_length);
-                     // FastLED[0].show((CRGB*)led_data_ptr_1, NUM_RGB_LEDS_2, 255);
+                      // FastLED[0].show((CRGB*)led_data_ptr_1, NUM_RGB_LEDS_2, 255);
                       //FastLED[1].show((CRGB*)led_data_ptr_2, NUM_RGB_LEDS_1, 255);
-
+
                       break;
                     }
                   case 2: {
@@ -196,12 +213,12 @@
             }
             break;
           case 0x5200: { //OpSync
-            FastLED[0].show(led_data, NUM_RGB_LEDS_3, 255);
-             /*FastLED[1].show(led_data, NUM_RGB_LEDS_3, 255);
-              FastLED[2].show(led_data, NUM_RGB_LEDS_2, 255);
-               FastLED[3].show(led_data, NUM_RGB_LEDS_1, 255);              */
-           break;
-          }
+              FastLED[0].show(led_data, NUM_RGB_LEDS_1, 255);
+              FastLED[1].show(led_data, NUM_RGB_LEDS_1, 255);
+              FastLED[2].show(led_data, NUM_RGB_LEDS_1, 255);
+              FastLED[3].show(led_data, NUM_RGB_LEDS_1, 255);
+              break;
+            }
           case OpAddress: {
               T_ArtAddress * address = (T_ArtAddress*)udp_buffer;

@@ -232,7 +249,7 @@
               }

-              node = ArtNode(config, sizeof(udp_buffer), udp_buffer);
+              node = ArtNodeExtended(config, sizeof(udp_buffer), udp_buffer);

               saveConfig();
               loadConfig();
@@ -252,8 +269,8 @@
         }
       }
     }
-      digitalWrite(PIN_DEBUG, LOW);
-
+    digitalWrite(PIN_DEBUG, LOW);
+

   }


Output system time.

Output system time.

--- webserver.ino
+++ webserver.ino
@@ -55,7 +55,7 @@
   });

   webServer.on( "/api/getpercentage", []() {
-    String HTTPresponse = String(random( 100 )) + "," + String(random( 100 )) + "," + String(random( 100 )) + "," + String(random( 100 )) + "," + String(random( 100 )) + ",11:25:57,Lights controlled by program.";
+    String HTTPresponse = String(random( 100 )) + "," + String(random( 100 )) + "," + String(random( 100 )) + "," + String(random( 100 )) + "," + String(random( 100 )) + "," + formattedTime( localTime() ) + ",Lights controlled by program.";
     webServer.send( 200, "text/plain", HTTPresponse );
   });


Slow down servo for winding

Slow down servo for winding

--- Arduino/PechDavid/PechDavid.ino
+++ Arduino/PechDavid/PechDavid.ino
@@ -73,13 +73,13 @@
   sendSabertooth(cmd);

   // Trancannage/winding
-  servocmd = 110+30*sin(get_cmd_integral()/127.0);
+  servocmd = 110+30*sin(get_cmd_integral()/127.0*0.1);
   sendServo(servocmd);

  // Debug output
-/*  Serial.print("thmin:");
+ Serial.print("thmin:");
   Serial.print(threshold_min);
   Serial.print('\t');
   Serial.print("thmax:");
@@ -98,6 +98,6 @@
   Serial.println(cmd);
   Serial.print('\t');
   Serial.print("servocmd:");
-  Serial.print(servocmd);*/
+  Serial.print(servocmd);

 }


Attempt to identify I2C timeouts and data integrity in BitbucketsIMU

Signed-off-by: uutzinger <dca2bfcf3b7373646a3cf317d4b044d0de6da9ab@email.arizona.edu>

--- BitBucketsIMU/BitBucketsIMU.ino
+++ BitBucketsIMU/BitBucketsIMU.ino
@@ -45,6 +45,11 @@
 unsigned long lastTimestamp;
 unsigned long motionstart;
 unsigned long lastBlink;
+unsigned long lastPoll;
+unsigned long lastIMUPoll;
+unsigned long lastHumidityPoll;
+unsigned long lastPressurePoll;
+unsigned long timeout;

 int dt;       // time in between samples
 int dtmotion; // time during which motion occured
@@ -260,20 +265,44 @@
   ledStatus = true;
   lastBlink = micros();

+  lastPoll = lastIMUPoll = lastHumidityPoll = lastPressurePoll = micros();
+  timeout= (unsigned long) (10*(imu->IMUGetPollInterval() * 1000));
+
 } // setup

 void loop()
 {
-    unsigned long currentTime = micros();
-
     RTQuaternion rotatedGravity;
     RTQuaternion fusedConjugate;
     RTQuaternion qTemp;
     float residualsAlpha;
     float biasAlpha;
-
+
+    //  poll at the rate recommended by the IMU
+    unsigned long currentTime = micros();
+    int pollDelay = ((imu->IMUGetPollInterval() * 1000) - (int)(currentTime - lastPoll));
+    if (pollDelay > 0) { delayMicroseconds(pollDelay); }
+    lastPoll = currentTime;
+
+    // check IMU stalled
+    if ( (currentTime - lastIMUPoll) > timeout ) {
+      // We have IMU stalled and need to reset it
+      Serial.println("!!!!!!!!!!!!!!!!!!!! IMU RESET: wait of data for too long !!!!!!!!!!!!!!!!!!!!\n");
+      imu->IMUInit();
+      lastPoll = micros();
+    }
+
     if (imu->IMURead()) {                       // get the latest data if any avail
         imuData = imu->getIMUData();
+        lastIMUPoll = micros();
+
+        if ( (imuData.gyro.length() > 35.0) || (imuData.accel.length() > 16.0) || (imuData.compass.length() > 1000.0) ) {
+          // IMU Data Error
+          Serial.println("!!!!!!!!!!!!!!!!!!!! IMU RESET: Data out of range !!!!!!!!!!!!!!!!!!!!\n");
+          imu->IMUInit();
+          lastIMUPoll = micros();
+        }
+
         sampleCount++;
         dt=imuData.timestamp-lastTimestamp;
         lastTimestamp = imuData.timestamp;
@@ -299,7 +328,7 @@
    			//  Probably too late to adjust here as value was already inserted into fusion algorithm
    			//  imu->setCompassEnable(false);
     		//}
-
+
         ////////////////////////////////////////////////////////////////////////////////
         // Calibration
         ////////////////////////////////////////////////////////////////////////////////
@@ -528,6 +557,26 @@
     } // imuread

     ///////////////////////////////////////////////////////////////
+    // AUX Sensors
+    ///////////////////////////////////////////////////////////////
+
+    //  add the pressure data to the structure
+    if (pressure != NULL) {
+      if ( (currentTime - lastPressurePoll) >= 20000 ) { // 20ms
+        lastPressurePoll = currentTime;
+        pressure->pressureRead(imuData);
+      }
+    }
+
+    //  add the humidity data to the structure
+    if (humidity != NULL) {
+      if ( (currentTime - lastHumidityPoll) >= 80000 ) { // 12.5Hz = 80ms
+        lastHumidityPoll = currentTime;
+        humidity->humidityRead(imuData);
+      }
+    }
+
+    ///////////////////////////////////////////////////////////////
     // Input Commands
     ///////////////////////////////////////////////////////////////
     if (INAVAIL) {
@@ -633,6 +682,7 @@
       } // end if serial input available
     } // end INAVAIL

+    ///////////////////////////////////////////////////////////////
     // Blink LED if gyro is calibrated otherwise keep it on
     ///////////////////////////////////////////////////////////////
     // But keep LED on if system is moving


Added laser Shake

Added laser Shake

--- Pan_Tilt_laser/Pan_Tilt_laser.ino
+++ Pan_Tilt_laser/Pan_Tilt_laser.ino
@@ -82,8 +82,6 @@

   panTiltX.angle = getDeltaPosition(&panTiltX, changeVal, DIRECTION_CHANGE_PROBABILITY) + panTiltX.angle;

-
-
   panTiltY.angle = getDeltaPosition(&panTiltY, changeVal, DIRECTION_CHANGE_PROBABILITY) + panTiltY.angle;

@@ -145,41 +143,43 @@
 }

 int getMarkovSpeed(int oldSpeed){
-  int val = random(101);
-  int lowVal, midVal, hiVal;
-
-  if(oldSpeed == 1){
-    if(val < 20){
-      return 3;
+  int probability = random(101);
+  int lowVal = 2;
+  int midVal = 5;
+  int hiVal = 8;
+
+  if(oldSpeed == lowVal){
+    if(probability < 20){
+      return midVal;
     }
     else{
-      return 1;
-    }
-  }
-
-  else if(oldSpeed == 3){
-    if(val < 20){
-      return 5;
-    }
-    else if(val < 70){
-      return 3;
+      return lowVal;
+    }
+  }
+
+  else if(oldSpeed == midVal){
+    if(probability < 20){
+      return hiVal;
+    }
+    else if(probability < 70){
+      return midVal;
     }
     else{
-      return 1;
-    }
-  }
-
-  else if(oldSpeed == 5){
-    if(val < 20){
-      return 3;
+      return lowVal;
+    }
+  }
+
+  else if(oldSpeed == hiVal){
+    if(probability < 20){
+      return midVal;
     }
     else{
-      return 5;
+      return hiVal;
     }
   }

   else{
-    return constrain(oldSpeed, 1, 5);
+    return constrain(oldSpeed, lowVal, hiVal);
   }
 }

@@ -233,3 +233,23 @@
     oldTime = mSeconds;
   }
 }
+
+void shake(){
+  panTiltY.angle += 1;
+  panTilt.updateAngles();
+  delay(50);
+  panTiltY.angle -= 1;
+  panTiltX.angle += 1;
+  panTilt.updateAngles();
+  delay(50);
+  panTiltY.angle -= 1;
+  panTiltX.angle -= 1;
+  panTilt.updateAngles();
+  panTiltY.angle += 1;
+  panTiltX.angle -= 1;
+  panTilt.updateAngles();
+  delay(50);
+  panTiltX.angle += 1;
+  panTilt.updateAngles();
+  delay(50);
+}


Update for Arduboy library V1.0

Update for Arduboy library V1.0

Change deprecated library functions to their replacements.
Remove unneeded #includes.
Remove trailing whitespace.

--- flappyhalloween.ino
+++ flappyhalloween.ino
@@ -10,9 +10,7 @@
  *******************************************************************************/

-#include <SPI.h>
-#include "Arduboy.h"
-#include <EEPROM.h>
+#include <Arduboy.h>
 #include "bitmaps.h"
 #include "flight.h"

@@ -52,7 +50,7 @@
 {
   for(int i = -8; i < 28; i = i + 2)
   {
-    arduboy.clearDisplay();
+    arduboy.clear();
     arduboy.setCursor(46, i);
     arduboy.print("ARDUBOY");
     arduboy.display();
@@ -73,11 +71,11 @@

 void setup()
 {
-  arduboy.start();
+  arduboy.begin();
   arduboy.setFrameRate(60);
   intro();
   // put up the title screen until A is pressed
-  arduboy.clearDisplay();
+  arduboy.clear();
   arduboy.drawSlowXYBitmap(0, 0, title, 128, 64, 1);
   arduboy.display();
 }
@@ -92,18 +90,18 @@
     if(arduboy.pressed(A_BUTTON)) {
       start = true;
       frame = 0;
-      arduboy.clearDisplay();
+      arduboy.clear();
       arduboy.initRandomSeed();
     }
   }

   if(start) {

-    arduboy.clearDisplay();
+    arduboy.clear();
     frame++;      // increments forever (looping)

     if(!owlActive) {
-      flightOffset++;
+      flightOffset++;
       if(flightOffset == 462) {  // see flight.cpp
         flightOffset = 0;
       }
@@ -147,7 +145,7 @@
       }
       if (i!= NUMBUGS){ // we found a -1
         bugsX[i] = 128;
-        bugsY[i] = random(1,61);
+        bugsY[i] = random(1,61);
       }
     }
     if(0 == (frame%3)) { // every couple of frames`
@@ -262,23 +260,9 @@
       owlY = 128; // ensure it can't collide with bat
       for (i=0; i<NUMBUGS; i++) {
         bugsX[i] =  -1;
-      }
+      }
     }
   }

 }

-
-
-
-
-
-
-
-
-
-
-
-
-
-


Just load the colors and display for 10 seconds, no slow march cuteness.

--- xy.ino
+++ xy.ino
@@ -183,7 +183,10 @@
 {
    int x,y;
    int dColor = 64;
+   float d1 = 1.0 / (5-1);      // 0..4 ==> 0..1.0 in 5 steps
+   int exponent = 4;            // Non-linear brightness increase as {x^exponent : x in [0.0..1.0]}
    int r,g,b;
+   float rf, gf, bf;
    uint32_t c;
    int i;
    struct point_s pt;
@@ -200,24 +203,30 @@
       for (y = 0; y < 5; y++)
          for (x = 0; x < 5; x++)
          {
-            r = dColor * (run == 0 ? x : run == 1 ? y : 0);
-            g = dColor * (run == 0 ? y : run == 1 ? 0 : x);
-            b = dColor * (run == 0 ? 0 : run == 1 ? x : y);
+            r = (run == 0 ? x : run == 1 ? y : 0);
+            g = (run == 0 ? y : run == 1 ? 0 : x);
+            b = (run == 0 ? 0 : run == 1 ? x : y);
+
+            // pow(): non-linear brightness increase
+            rf = 256 * pow( d1 * r, exponent);
+            gf = 256 * pow( d1 * g, exponent);
+            bf = 256 * pow( d1 * b, exponent);

-            r = constrain( r, 0, 255);
-            g = constrain( g, 0, 255);
-            b = constrain( b, 0, 255);
+            r = constrain( rf, 0, 255);
+            g = constrain( gf, 0, 255);
+            b = constrain( bf, 0, 255);
             c = Color( r, g, b);
             pt = {x,y } ;
             i = point2seq( pt, org, gridSize);
             strip.setPixelColor( i, c);
-            strip.show();
-            delay( 300);
+            // strip.show();
+            // delay( 300);
          }
-      delay( 3000);
-      clearStrip();
       strip.show();
-      delay( 500);
+      delay( 10000);
+      // clearStrip();
+      // strip.show();
+      // delay( 500);
    }

 }


ok rick fix it with your dell

ok rick fix it with your dell

--- 2018-FirefighterL1/2018-FirefighterL1.ino
+++ 2018-FirefighterL1/2018-FirefighterL1.ino
@@ -175,24 +175,6 @@
   }

   stopRobot();
-
-  // if(gyroTargetAngle < getGyroAngle()){
-  //   leftMotor.set(leftSpeed);
-  //   rightMotor.set(rightSpeed);
-  //   while(gyroTargetAngle < getGyroAngle()){
-  //     Serial.println(String(getRotation()));
-  //     delay(50);
-  //   }
-  //   stopRobot();
-  // }else if(gyroTargetAngle > getGyroAngle()){
-  //   leftMotor.set(-leftSpeed);
-  //   rightMotor.set(-rightSpeed);
-  //   while(gyroTargetAngle > getGyroAngle()){
-  //     Serial.println(String(getRotation()));
-  //     delay(50);
-  //   }
-  //   stopRobot();
-  // }
 }

 void extinguishFire(){
@@ -275,33 +257,34 @@

 void setup() {
   // put your setup code here, to run once:
-  //extinguisher.attach(EXTINGUISHER_PIN);
-  //stopRobot();
-  //extinguisher.write(90);
-
-  //pinMode(IR_PIN_LEFT, INPUT);
-  //pinMode(IR_PIN_RIGHT, INPUT);
-
-  //attachInterrupt(digitalPinToInterrupt(IR_PIN_LEFT), extinguishFire, RISING);
-  //attachInterrupt(digitalPinToInterrupt(IR_PIN_RIGHT), extinguishFire, RISING);
-  //pinMode(FLAME_LED, OUTPUT);
-  //pinMode(MIC_LED, OUTPUT);
-
   Serial.begin(115200);
+  Serial.println("Setting up extinguisher");
+  extinguisher.attach(EXTINGUISHER_PIN);
+  extinguisher.write(70);
+
+  Serial.println("Setting up IR pins and interrupts");
+  pinMode(IR_PIN_LEFT, INPUT);
+  pinMode(IR_PIN_RIGHT, INPUT);
+  attachInterrupt(digitalPinToInterrupt(IR_PIN_LEFT), extinguishFire, RISING);
+  attachInterrupt(digitalPinToInterrupt(IR_PIN_RIGHT), extinguishFire, RISING);
+
+  Serial.println("Setting up flame, mic leds");
+  pinMode(FLAME_LED, OUTPUT);
+  pinMode(MIC_LED, OUTPUT);
+
+  Serial.println("Setting up gyro");
   setup_gyro();
   resetGyro();
-  turn(60);
-
-  extinguisher.write(70);
-
-  //FreqCount.begin(1000); // Begin measuring sound
-  //checkMicrophone();  //robot stays in setup until frequency is heard
+
+  Serial.println("Listening for microphone");
+  FreqCount.begin(1000); // Begin measuring sound
+  checkMicrophone();  //robot stays in setup until frequency is heard
 }

 void loop() {

-  //startUp();
-  //levelOneNav();
+  startUp();
+  levelOneNav();
+  getRotation();
   delay(100);
-
-}
+}


pointer and int

pointer and int

--- _04-mqtt-lcd-dust-sensor/_04-mqtt-lcd-dust-sensor-nano/_04-mqtt-lcd-dust-sensor-nano.ino
+++ _04-mqtt-lcd-dust-sensor/_04-mqtt-lcd-dust-sensor-nano/_04-mqtt-lcd-dust-sensor-nano.ino
@@ -177,9 +177,9 @@
   }

   if ( results->bits > 0 && results->bits == 32 ) {
-    if ( results->value == "FF02FD" ) {
+    if ( results->value == 0xFF02FD ) {
        sleepmode = HIGH;
-    } else if ( results->value == "FF9867" ) {
+    } else if ( results->value == 0xFF9867 ) {
        sleepmode = LOW;
     }
   }


stairs: implement rainbow cycle mode

stairs: implement rainbow cycle mode

--- stairs/main.ino
+++ stairs/main.ino
@@ -32,16 +32,17 @@
 // This variable holds the LED color state.
 CRGB leds[NUM_LEDS];

-/* All the different modes that are available. */
+// All the different modes available.
 #define MAX_MODES 10
 void modeOff();
 void modeSolid();
 void modeRainbow();
+void modeRainbowCycle();
 void (*modes[MAX_MODES])() = {
     &modeOff,
     &modeSolid,
     &modeRainbow,
-    &modeOff,
+    &modeRainbowCycle,
     &modeOff,
     &modeOff,
     &modeOff,
@@ -58,7 +59,7 @@
     uint8_t val;
 } pots;

-/* Initial setup, called once on boot. */
+// Initial setup, called once on boot.
 void setup() {
     FastLED.addLeds<NEOPIXEL, PIN_LED>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
 #ifdef DEBUG_POTS
@@ -108,6 +109,34 @@
     }
 }

+// stepAnimation returns true if it is time for the next step in the animation,
+// according to the speed parameter.
+bool stepAnimation(uint8_t speed) {
+    static uint32_t lastClock = 0;
+    uint32_t diff;
+    uint32_t clock;
+    uint32_t expectedDelay;
+    bool rval;
+
+    /* Animations are disabled when speed is zero */
+    if (speed == 0) {
+        return false;
+    }
+
+    clock = millis();
+    diff = clock - lastClock;
+
+    /* Otherwise, delay 1000/speed milliseconds. */
+    expectedDelay = map(speed, 1, 255, 1000, 40);
+    rval = (diff >= expectedDelay);
+
+    if (rval) {
+        lastClock = clock;
+    }
+
+    return rval;
+}
+
 // Read a value from an analog pin as a byte value between 0-255.
 uint8_t adc8(uint8_t pin) {
     uint16_t analog = analogRead(pin);
@@ -134,6 +163,21 @@
     }
 }

+// Draw the rainbow, and gradually move it according to the addition parameter,
+// which regulates the speed.
+void modeRainbowCycle() {
+    static uint8_t offset = 0;
+    uint8_t hue;
+    if (stepAnimation(pots.var)) {
+        offset++;
+    }
+    for (uint8_t led = 0; led < NUM_LEDS; led++) {
+        hue = map(led, 0, NUM_LEDS, 0, 255);
+        hue += offset;
+        leds[led] = CHSV(hue, pots.saturation, pots.val);
+    }
+}
+
 // Read all potentiometers, and run one iteration of the active mode.
 void loop() {
 #ifdef DEBUG_POTS


Relay controlled fading works. Pass 6 bytes instead of 4 over BLE, and the last 2 bytes will be interpreted as an unsigned int for the ms to transition from current color to the payload defined color.

--- arduino/rfglow_panstamp_ble/rfglow_panstamp_ble.ino
+++ arduino/rfglow_panstamp_ble/rfglow_panstamp_ble.ino
@@ -51,7 +51,7 @@
 unsigned int sends = 255;
 unsigned int target_hue = 0, target_saturation = 0, target_brightness = 0, target_fade_ms = 0;
 unsigned int current_hue = 0, current_saturation = 0, current_brightness = 0;
-signed long fade_dH = 0, fade_dS = 0, fade_dV = 0;
+long fade_dH = 0, fade_dS = 0, fade_dV = 0;
 unsigned long fade_start_ms = 0;

 void setup() {
@@ -87,6 +87,7 @@
   //ble.setDisconnectCallback(disconnectCallback);

   ble.setMode(BLUEFRUIT_MODE_DATA);
+  ble.setTimeout(5);

   lastSendMicros = micros();

@@ -100,7 +101,7 @@
     ptr_fhss_schema++;  // Increment pointer of fhss schema array to perform next channel change
     if(ptr_fhss_schema >= sizeof(fhss_schema)) {
       ptr_fhss_schema=0; // To avoid array indexing overflow
-      DEBUG_PRINTLN("Packets sent: "+packets_sent);
+      //DEBUG_PRINTLN("Packets sent: "+packets_sent);
       packets_sent = 0;
     }
     panstamp.cc1101.setChannel(fhss_schema[ptr_fhss_schema]); // Change channel
@@ -113,14 +114,14 @@
   if (currentMicros - lastSendMicros > hopIntervalMicros) {
     sendCurrentColor();
     lastSendMicros = currentMicros;
-    DEBUG_PRINTLN("Sent at: "+currentMicros);
+    //DEBUG_PRINTLN("Sent at: "+currentMicros);
     isInPreHop = false;
   }

   if (ble.available()) {
-    uint8_t buffer[4];
+    uint8_t buffer[32];
     int len;
-    len = ble.readBLEUart(buffer, 4);
+    len = ble.readBLEUart(buffer, 31);
     rxCallback(buffer, len);
   }

@@ -128,7 +129,8 @@
 }

 void rxCallback(uint8_t *buffer, uint16_t len) {
-  DEBUG_PRINTLN("Received "+len+"bytes...");
+
+  DEBUG_PRINTLN("Received "+len+" bytes...");

 //  for(int i=0; i<len; i++)
 //   DEBUG_PRINT((char)buffer[i]);
@@ -175,9 +177,10 @@
         }
       }

-      fade_dH = target_hue - current_hue;
-      fade_dS = target_saturation - current_saturation;
-      fade_dV = target_brightness - current_brightness;
+      fade_dH = (int)target_hue - (int)current_hue;
+      fade_dS = (int)target_saturation - (int)current_saturation;
+      fade_dV = (int)target_brightness - (int)current_brightness;
+      DEBUG_PRINTLN("Fade deltas dH, dS, dV = "+fade_dH+", "+fade_dS+", "+fade_dV);

     } else {
       target_fade_ms = 0;
@@ -225,8 +228,10 @@
     target_fade_ms = 0;
   } else if (target_fade_ms == 65535) {
     // Code for UO decay
-  } else if (millis() - fade_start_ms > 60000 || millis() - fate_start_ms > target_fade_ms) {
+  } else if (millis() - fade_start_ms > 60000 || millis() - fade_start_ms > target_fade_ms) {
     // Max fade is 60 seconds, terminate the transition.
+    // Or we exceeded the fade target ms, also terminate the transition
+
     current_hue = target_hue;
     current_saturation = target_saturation;
     current_brightness = target_brightness;
@@ -234,20 +239,24 @@
     target_fade_ms = 0;
   } else {
     // In the middle of a linear fade
-    long dT = fade_start_ms - (millis() - fade_start_ms);
-    long ratio = dT * 10000 / target_fade_ms;
+    long dT = millis() - fade_start_ms;
+    long ratio = 10000 - (dT * 10000 / target_fade_ms);
+    DEBUG_PRINTLN("Fade at "+ratio/100+"%");
     int dH = ratio * fade_dH / 10000;
     int dS = ratio * fade_dS / 10000;
     int dV = ratio * fade_dV / 10000;

     current_hue = target_hue - dH;
-    current_saturation = target_saturation + dH;
+    current_saturation = target_saturation - dS;
+    current_brightness = target_brightness - dV;
   }

   sendCommand(current_hue, current_saturation, current_brightness);
 }

 void sendCommand(uint16_t hue, uint8_t saturation, uint8_t brightness) {
+
+  DEBUG_PRINTLN("Send HSV: "+hue+", "+saturation+", "+brightness);

   unsigned long startTime = micros();


Adds roughed in static high score entry screen.

--- arduboy-game/arduboy-game.ino
+++ arduboy-game/arduboy-game.ino
@@ -536,7 +536,11 @@
 void newHighScoreScreen() {
   // TODO, this is placeholder
   arduboy.clear();
-  printText("NEW HIGHSCORE", 4, 25, 1);
+  printText("NEW HI!", 24, 1, 2);
+  sprintf(textBuf, "%06d", score);
+  printText(textBuf, 28, 22, 2);
+  printText("AAA", 44, 45, 2);
+  arduboy.fillRect(44, 62, 9, 2, 1);
   arduboy.display();
   delay(3000);
 }


Further interim hi score work.

Further interim hi score work.

--- arduboy-game/arduboy-game.ino
+++ arduboy-game/arduboy-game.ino
@@ -671,7 +671,7 @@
   return NOT_NEW_HI_SCORE;
 }

-void newHighScoreScreen() {
+void newHighScoreScreen(byte newHiPos) {
   long lastDebounceTime = millis();
   bool allDone = false;
   byte currPos = 0;
@@ -754,6 +754,9 @@
        }
     }
   }
+
+  // Store the new high score, newHiPos == 0 is highest score
+  // TODO
 }

 void createStarFieldVals() {
@@ -813,7 +816,7 @@

 // Main program loop
 void loop() {
-  byte result;
+  byte result, newHiScorePos;

   result = titleScreen();

@@ -826,9 +829,9 @@
       gameOverScreen();
       // TODO high score should be checked against a set of high scores
       // in the EEPROM
-      if (isNewHighScore() != NOT_NEW_HI_SCORE) {
-        newHighScoreScreen();
-        // TODO save high score
+      newHiScorePos = isNewHighScore();
+      if (newHiScorePos != NOT_NEW_HI_SCORE) {
+        newHighScoreScreen(newHiScorePos);
       }

       highScoreScreen();


First go at better you win screen.

First go at better you win screen.

--- arduboy-game/arduboy-game.ino
+++ arduboy-game/arduboy-game.ino
@@ -80,7 +80,6 @@
 char textBuf[23];

 void playMusic(byte song) {
-//  return; // SIMON
     if (! soundOn) {
       return;
     }
@@ -751,7 +750,7 @@
     if (playerDying < 65) {
       playerDying++;
     } else {
-      //livesRemaining--;  SIMON
+      livesRemaining--;
       resetPlayer();
     }
   }
@@ -847,18 +846,17 @@
 }

 void playerWinsScreen() {
-//  playMusic(99);
   arduboy.clear();

-  // Temp
-  printText("YOU WIN", 20, 15, 2);
-
-  // TODO display stuff
+  playMusic(6);
+
+  printText("YOU", 46, 6, 2);
+  printText("ESCAPED!", 20, 24, 2);
   arduboy.display();
-
-  // Play the you win music
-  playMusic(6);
-
+  delay(2500);
+  printText("HOWEVER...", 5, 42, 2);
+  arduboy.display();
+
   delay(4500);
 }


cleaned serial port debugging residual code snippets

--- sonoff-homie-dual/sonoff-homie-dual.ino
+++ sonoff-homie-dual/sonoff-homie-dual.ino
@@ -25,10 +25,10 @@
   if (relay1) b++;
   if (relay2) b += 2;

-  SERIAL_PORT_HARDWARE.write((byte)0xA0);
-  SERIAL_PORT_HARDWARE.write((byte)0x04);
-  SERIAL_PORT_HARDWARE.write((byte)b);
-  SERIAL_PORT_HARDWARE.write((byte)0xA1);;
+  Serial.write((byte)0xA0);
+  Serial.write((byte)0x04);
+  Serial.write((byte)b);
+  Serial.write((byte)0xA1);;

   Serial.flush();
 }


put motor drive to sleep on start

put motor drive to sleep on start

--- vibrate_alarm_clock_2.ino
+++ vibrate_alarm_clock_2.ino
@@ -119,6 +119,8 @@
   pinMode(MOTOR_PIN1, OUTPUT);
   pinMode(MOTOR_PIN2, OUTPUT);
   pinMode(MOTOR_SLEEP_PIN, OUTPUT);
+
+  motorDriverState(false);

   timeLastPressedLeftButton = 0;
   timeLastPressedMiddleButton = 0;


A little cleanup for PIXO Pixel

A little cleanup for PIXO Pixel

Touch up the code here and there for human consumption ;-)

And this should be ready to go to code PIXO Pixel:
- 16x16 configuration, non-zigzag
- MAX_MILLIAMPS added, set to 3A
- Second set of data/clock pins set to PIXO defaults

This *will* try to connect to wifi; you'll need to fill in your
SSID/password for that (and OPC support) to work.

--- blume.ino
+++ blume.ino
@@ -1,39 +1,26 @@
 // These settings change per project!
-#define NUM_LEDS    72
-#define BASE_WID  12
+#define NUM_LEDS    256
+#define BASE_WID  16
 // If true, adds 1 to BASE_WID for every other row
 #define STAGGERED false
 // Wiring is in a zig-zag pattern.
 #define ZIGZAG   false
 // Support text mode; currently 6-pixel height only.
 #define TEXTMODE false
+// Set max milliamp draw limit, assuming standard 5-volt LEDs.
+#define MAX_MILLIAMPS 3000
 // Rotary encoder with button control.
 /*#define ENCODER true
 #define ENC_P1 22
 #define ENC_P2 23
 #define ENC_SW 21*/
-// POI: 18/1/false/false
-// STAFF: 50/1/false/false
-// CUCUMBER: 104/6/true/false
-// VICTORIA HAT: 28/16/false/false/Clock=2
-// CARO THING: 18/1/false/false
-// NEHA BULB: 76/6/true/false
-// STOPH: 20/1/false/false
-// NINA: 18/1/false/false
-// TREVOR: 75/6/true/false
-// LEIGH BIKE: 80/1/false/false
-// VICTORIA OTHER: 71/1/false/false
-// NINA OTHER: 56/1/false/false/Clock=2
-// BLUME VIVE: 47/6/true/false
-// BLUME SCARF: 120/40/false/true
-// BLUME DUBIOUS: 60/6/true/false
-// BLUME FEATHER: 72/12/false/false/textmode=true
-// NIC'S BLUME: 40/6/true/false/false
-// BLUME DUBIOUS: 59/6/true/false/false
-// BLUME BEACON: 40/6/true/false/false
-// BLUME LIVING: 298?/1/false/false/false/true:22,23,sw=21 (APA_MHZ=1)
-
-#define DEBUG false
+
+// Turn on R-G-B startup sequence, debug messages to serial console, etc.
+#define DEBUG true
+
+// These are used by ESP32_OTA and ESP32_OPC support.
+#define WIFI_SSID "Your Wifi Network"
+#define WIFI_PASSWORD "yourpassword"

 // Only change these settings if you're wired to different pins, using a non-APA102 chipset,
 // using a different COLOR_ORDER for RGB, etc.
@@ -41,13 +28,16 @@
 #define ESP32_OPC
 // No standard pins for ESP32 yet; I'm using these at the moment.
 #define DATA_PIN_0    12
-#define DATA_PIN_1    14
 #define CLOCK_PIN_0   13
-#define CLOCK_PIN_1   15
+// A second set of pins get the same signal.
+// Useful when connecting multiple strips.
+// Here, use PIXO Pixel's defaults.
+#define DATA_PIN_1    19
+#define CLOCK_PIN_1   18
 #else
 #define DATA_PIN_0    A0
+#define CLOCK_PIN_0   5
 #define DATA_PIN_1    A1
-#define CLOCK_PIN_0   5
 #define CLOCK_PIN_1   4
 #endif
 #define COLOR_ORDER BGR
@@ -58,11 +48,19 @@
 #define CHIPSET     LPD8806
  */

-// These are used by ESP32_OTA and ESP32_OPC support.
-#define WIFI_SSID "Your Wifi Network"
-#define WIFI_PASSWORD "yourpassword"
+
+
+
+
+
+

 // EVERYTHING BELOW HERE WON'T CHANGE FOR A NORMAL PROJECT.
+
+
+
+
+

 #ifdef ESP32
@@ -80,7 +78,7 @@
 // Something small and reasonable.
 #define EEPROM_SIZE 64
 // This varies by ESP32 dev board.
-#define LED_PIN 2
+#define LED_PIN LED_BUILTIN
 #endif // ESP32

 #ifdef ESP32_OTA
@@ -260,7 +258,7 @@
 BlumeGFX gfx = BlumeGFX(WIDTH, HEIGHT);

 // Max length 32
-char text[32] = "Hello World! I'm Grant.";
+char text[32] = "Hello World! I'm Blume. :-)";
 void runText(bool initialize) {
   // TODO: c1 = speed, or rainbow on?
   // TODO: c2 = rainbow size, or rainbow vertical?
@@ -298,10 +296,24 @@

 void setup() {
-  // Initialize serial connection to bluetooth chip
   Serial.begin(115200);
   // Only wait 500ms for new data before giving up on a command
   Serial.setTimeout(500);
+
+  // Initialize and turn off LEDs before any slower startup stuff.
+  pinMode(DATA_PIN_0, OUTPUT);
+  pinMode(CLOCK_PIN_0, OUTPUT);
+  pinMode(DATA_PIN_1, OUTPUT);
+  pinMode(CLOCK_PIN_1, OUTPUT);
+  FastLED.addLeds<LED_SETTINGS_0>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
+  FastLED.addLeds<LED_SETTINGS_1>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
+  FastLED.setDither(DISABLE_DITHER);
+#if defined(MAX_MILLIAMPS) && MAX_MILLIAMPS
+  FastLED.setMaxPowerInVoltsAndMilliamps(5, MAX_MILLIAMPS);
+#endif
+  // Turn everything off at first to avoid buggy lingering data on the chips
+  FastLED.setBrightness(0);
+  FastLED.show();

 #ifdef ESP32
   BLEDevice::init("Blume ESP");
@@ -329,12 +341,6 @@
 #if defined(ESP32_OTA) || defined(ESP32_OPC)
   WiFi.mode(WIFI_STA);
   WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
-  /*while (WiFi.status() != WL_CONNECTED) {
-    delay(500);
-  }
-  Serial.print("IP address: ");
-  Serial.println(WiFi.localIP());
-  */
 #endif // ESP32_OTA || ESP32_OPC

 #ifdef ESP32_OTA
@@ -392,17 +398,6 @@
   // Make sure we're in sync with current switch state.
   encoderSwitchHandler();
 #endif // ENCODER
-
-  pinMode(DATA_PIN_0, OUTPUT);
-  pinMode(CLOCK_PIN_0, OUTPUT);
-  pinMode(DATA_PIN_1, OUTPUT);
-  pinMode(CLOCK_PIN_1, OUTPUT);
-  FastLED.addLeds<LED_SETTINGS_0>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
-  FastLED.addLeds<LED_SETTINGS_1>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
-  FastLED.setDither(DISABLE_DITHER);
-  // Turn everything off at first to avoid buggy lingering data on the chips
-  FastLED.setBrightness(0);
-  FastLED.show();

 #if DEBUG
 #ifdef LED_PIN
@@ -469,6 +464,8 @@
     Serial.print(" OPCPS: ");
     Serial.print((float)opcCount / (float)totalDurations * 1000.0);
     opcCount = 0;
+    Serial.print(" IP address: ");
+    Serial.print(WiFi.localIP());
 #endif
     Serial.println();
     totalLoops = 0;


Move instrument definition to malaria_instruments.

--- examples/MalariaFMSynth/MalariaDSP1/MalariaDSP1.ino
+++ examples/MalariaFMSynth/MalariaDSP1/MalariaDSP1.ino
@@ -1,39 +1,18 @@
 #include <MozziGuts.h>
-#include <Oscil.h>
-#include <tables/sin2048_int8.h>
-#include <ADSR.h>
-#include <mozzi_midi.h>
 #include <MIDI.h>
 #include <Malaria.h>
+#include <malaria_instruments.h>

 const byte ledPin = 13;
-const Q8n8 mod_index = float_to_Q8n8(1.0f);
-
-Oscil<SIN2048_NUM_CELLS, AUDIO_RATE> aCarrier(SIN2048_DATA);
-Oscil<SIN2048_NUM_CELLS, AUDIO_RATE> aModulator(SIN2048_DATA);
-ADSR <CONTROL_RATE, AUDIO_RATE> modEnv;
-ADSR <CONTROL_RATE, AUDIO_RATE> carEnv;

 MIDI_CREATE_DEFAULT_INSTANCE();
-
-Q16n16 carrierFreq, modulatorFreq, deviation;
+FMBell instrument;
 MalariaPcmWriter pcmWriter;
-
-bool gate = false;
-byte gain = 0;

 void setup() {
   pinMode(ledPin, OUTPUT);
   digitalWrite(ledPin, LOW);
   startMozzi(CONTROL_RATE);
-  aCarrier.setFreq(0);
-  aModulator.setFreq(0);
-  modEnv.setIdleLevel(0);
-  modEnv.setLevels(255, 0, 0, 0);
-  modEnv.setTimes(20, 2000, 0, 0);
-  carEnv.setIdleLevel(0);
-  carEnv.setLevels(255, 0, 0, 0);
-  carEnv.setTimes(20, 2000, 0, 0);
   MIDI.setHandleNoteOn(HandleNoteOn);
   MIDI.setHandleNoteOff(HandleNoteOff);
   MIDI.begin(MIDI_CHANNEL_OMNI);
@@ -44,39 +23,22 @@
 }

 void HandleNoteOn(byte channel, byte note, byte velocity) {
-  float fundamentalHz = mtof(float(note));
-  carrierFreq = float_to_Q16n16(fundamentalHz * 5.f);
-  modulatorFreq = float_to_Q16n16(fundamentalHz * 7.f);
-  deviation = (modulatorFreq>>16) * mod_index;
-  aModulator.setFreq_Q16n16(modulatorFreq);
-  aCarrier.setFreq_Q16n16(carrierFreq);
-  modEnv.noteOn();
-  carEnv.noteOn();
-  gain = velocity;
-  gate = true;
+  instrument.noteOn(note, velocity);
   digitalWrite(ledPin, HIGH);
 }

 void HandleNoteOff(byte channel, byte note, byte velocity) {
-  gate = false;
+  instrument.noteOff(note, velocity);
   digitalWrite(ledPin, LOW);
 }

 void updateControl() {
   MIDI.read();
-  modEnv.update();
-  carEnv.update();
+  instrument.updateControl();
 }

-#define APPLY_GAIN(v, g)  ((v * g) >> 8)
-
 int updateAudio() {
-  if (gate) {
-    Q15n16 modulation = APPLY_GAIN(deviation, APPLY_GAIN(aModulator.next(), modEnv.next()));
-    pcmWriter.write(APPLY_GAIN(APPLY_GAIN(aCarrier.phMod(modulation), carEnv.next()), gain));
-  } else {
-    pcmWriter.write(0);
-  }
+  pcmWriter.write(instrument.updateAudio());
   return 0;
 }


Update name IO class to Control

Update name IO class to Control

--- sketch/sketch.ino
+++ sketch/sketch.ino
@@ -54,7 +54,7 @@
 };

 /* 制御のクラス */
-class IO: public ServoIO, public MotorIO{
+class Control: public ServoIO, public MotorIO{
   void error(void){
     digitalWrite(errorPin,HIGH);
   }
@@ -74,11 +74,11 @@
     }
 };

-IO io;
+Control ctrl;

 void setup(){
-  io.errorPin=13;
-  io.servoPin.attach(9);
+  ctrl.errorPin=13;
+  ctrl.servoPin.attach(9);
 }

 void loop(){


added pi processing app support

added pi processing app support

--- src/piCar2.0.ino
+++ src/piCar2.0.ino
@@ -23,7 +23,7 @@
 #define CCW  2
 #define BRAKEGND 3
 #define CS_THRESHOLD 100
-
+bool headLightON = false;
 //variable declarations
 int horn = 23;
 /*  VNH2SP30 pin definitions
@@ -36,16 +36,23 @@
 int enpin[2] = {0, 1}; // EN: Status of switches output (Analog pin)
 int RRWL = 35;
 int LRWL = 32;
-int RFWL = 36;
-int LFWL = 37;
+int RFWL = 40;
+int LFWL = 41;
 int RRRL = 33;
 int LRRL = 34;
-int seirnRed[5] = {22, 24, 26, 28, 30};
+int seirnRed[5] = {22, 24, 26 };
 int seirnBlue[5] = {23, 25, 27, 29, 31};
 int statpin = 13;
 void setup() {
   BTLEserial.setDeviceName("Pi Car"); /* 7 characters max! */
   BTLEserial.begin();
+  int setDelay = 200;
+  togalFor(RRRL,setDelay);
+  togalFor(LRRL,setDelay);
+  togalFor(RFWL,setDelay);
+  togalFor(LFWL,setDelay);
+  togalFor(RRWL,setDelay);
+  togalFor(LRWL,setDelay);
   pinMode(22, OUTPUT);
   pinMode(23, OUTPUT);
   pinMode(24, OUTPUT);
@@ -58,13 +65,14 @@
   pinMode(31, OUTPUT);
   Serial.begin(57600);
   Serial1.begin(57600);
-  pinMode(RRWL, OUTPUT);
-  pinMode(LRWL, OUTPUT);
+   pinMode(RRWL, OUTPUT);
+   pinMode(LRWL, OUTPUT);
   pinMode(RRRL, OUTPUT);
   pinMode(LRRL, OUTPUT);
-  pinMode(RFWL, OUTPUT);
-  pinMode(LFWL, OUTPUT);
+  // pinMode(RFWL, OUTPUT);
+  // pinMode(LFWL, OUTPUT);
   pinMode(statpin, OUTPUT);
+  //togalFor(RRRL,1000);
   Serial.println("startup");
   // Initialize digital pins as outputs
   for (int i = 0; i < 2; i++)
@@ -89,6 +97,12 @@
     // lcd.print("ESTOP level 1!");
   }
 }
+void togalFor(int pin,int time){
+  pinMode(pin,OUTPUT);
+  digitalWrite(pin,HIGH);
+  delay(time);
+  digitalWrite(pin, LOW);
+}
 void bluetooth(){
   // Tell the nRF8001 to do whatever it should be working on.
   BTLEserial.pollACI();
@@ -148,7 +162,6 @@
   if (eMode) {
     seirn();
   }else{
-    serinLight(0,0);
   }
   if (Serial.available()) {
     serialProcess(0);
@@ -184,11 +197,11 @@
 */

 void serinLight(int red, int blue) {
-  digitalWrite(RFWL, red);
-  digitalWrite(LFWL, red);
+  digitalWrite(RRRL, red);
+  digitalWrite(LRRL, red);
+  digitalWrite(22, red);
+  digitalWrite(24, red);
   digitalWrite(26, red);
-  digitalWrite(28, red);
-  digitalWrite(30, red);
   digitalWrite(23, blue);
   digitalWrite(25, blue);
   digitalWrite(27, blue);
@@ -201,7 +214,6 @@
 }
 void seirn() {
   //Serial.println(millis());
-
   if (millis() > eLight) {
     if (redLight == 0) {
       serinLight(1, 0);
@@ -298,8 +310,8 @@
   Serial.read();
   digitalWrite(RRWL, RRW);
   digitalWrite(LRWL, LRW);
-  digitalWrite(RFWL, RFW);
-  digitalWrite(LFWL, LFW);
+  digitalWrite(RFWL, HIGH);
+  digitalWrite(LFWL, HIGH);
   digitalWrite(RRRL, LRR);
   digitalWrite(LRRL, RRR);
 }
@@ -378,17 +390,28 @@
       Serial.println("Standered Lighting");
       if (eMode) {
         eMode = false;
-        //serinLight(0, 0);
+        serinLight(0, 0);
       } else {
         eMode = true;
         //serinLight(0, 0);
       }
+    }else if (moder=='h'){
+      if (headLightON){
+        digitalWrite(LFWL, LOW);
+        digitalWrite(RFWL,LOW);
+        headLightON=false;
+      }else{
+      digitalWrite(LFWL, HIGH);
+      digitalWrite(RFWL,HIGH);
+      headLightON=true;
+    }
     }else if (moder == 's') {
       setHeadLight(type);
     } else if (moder == 'f') {
       flashHeadLight(type);
     }else if (r=='r'){
     char moder = sRead(type);
+
   }else if (moder=='s') {
     int sensor = parsein(type);
     switch (sensor) {