行数を削減

行数を削減

--- 1_practice/esp32_18_voice/esp32_18_voice.ino
+++ 1_practice/esp32_18_voice/esp32_18_voice.ino
@@ -15,13 +15,12 @@
 #define PORT 1024                           // 受信ポート番号
 #define DEVICE "voice_1,"                   // デバイス名(5文字+"_"+番号+",")

-int LED=0;                                  // LEDの出力状態
 signal voice(PIN_AIN);                      // 音声入力の有効化
 char phoneme[17];                           // 音声データ用の変数
-int phoneme_i=0;                            // 音声データ数
-int t=0;                                    // 待ち時間カウント用の変数
+int phoneme_i=0,t=0,LED=0;                  // 音声データ数,待ち時間,LED状態保持

 void setup(){
+    WiFi.mode(WIFI_OFF); btStop();          // 無線LANとBluetoothをOFFに設定する
     pinMode(PIN_LED, OUTPUT);               // LEDを接続したポートを出力に
     digitalWrite(PIN_LED,HIGH);             // LEDを点灯する(起動を知らせる)
     voice.f_enabled = true;                 // f音の検出を行う
@@ -31,11 +30,8 @@
     voice.vconstant = 3;                    // v音の閾値設定
     voice.shconstant = 4;                   // sh音の閾値設定
     voice.calibrate();                      // マイク入力のDC値の設定
+    memset(phoneme,0,17);                   // 音声データ用の変数の初期化
     Serial.begin(115200);                   // 動作確認のためのシリアル出力開始
-    Serial.println("esp32 18 voice");       // 「esp32 18 voice」をシリアル出力
-    memset(phoneme,0,17);                   // 音声データ用の変数の初期化
-    WiFi.mode(WIFI_OFF);                    // 無線LANをOFFに設定する
-    btStop();                               // BluetoothをOFFに設定する
 }

 void loop(){
@@ -44,22 +40,16 @@
     if(p!=' '){                             // 認識結果が有音だった場合
         Serial.print(p);                    // 認識した音をシリアル出力表示
         if(phoneme_i > 0 && p==phoneme[phoneme_i-1]) return;    // 同音時に戻る
-        digitalWrite(PIN_LED,!LED);         // 変数LEDの値を反転してLEDへ出力
-        t=0;                                // 終了待ち時間のリセット
-        phoneme[phoneme_i] = p;             // 認識音を音声データ配列変数へ保存
-        phoneme_i++;                        // 音声データ数を加算
+        t=0; digitalWrite(PIN_LED,!LED);    // 終了待ち時間のリセット
+        phoneme[phoneme_i++] = p;           // 認識音を音声データ配列変数へ保存
         if(phoneme_i<16) return;            // 配列16以内ならloopの先頭へ戻る
     }else{                                  // 認識結果が無音だったとき
         if(phoneme_i && t==0) Serial.print(' ');    // 空白をシリアル出力表示
-        t++;                                // 終了待ち時間を1つカウント
-        digitalWrite(PIN_LED,LED);          // 変数LEDの値をLEDへ出力
-        if(t < 16 || phoneme_i == 0) return; // 待ち時間変数tが16未満の時に戻る
+        t++; digitalWrite(PIN_LED,LED);     // 終了待ち時間を1つカウント
+        if(t < 16 || phoneme_i == 0)return; // 待ち時間変数tが16未満の時に戻る
     }
-
-    /* 認識部 */
-    char vr[9];                             // 認識結果の保存用変数
+    char vr[9]; memset(vr,0,9);             // 認識結果の保存用変数定期と初期化
     int led=-1;                             // 認識結果(未/ON/OFF)の保存用変数
-    memset(vr,0,9);                         // 認識結果の初期化
     char *spo=strchr(phoneme,'o');          // 音声データ内に「o」が含まれる
     char *sph=strchr(phoneme,'h');          // 音声データ内に「h」が含まれる
     char *spf=strchr(phoneme,'f');          // 音声データ内に「f」が含まれる
@@ -73,31 +63,25 @@
         else led=1;                         // なければONと判定し変数ledを1へ
     }
     if(led>=0) digitalWrite(PIN_LED,led);   // 判定結果でLEDを制御
-    else strcpy(vr,",ERR");                 // 結果無し時は文字列変数へERRを代入
+      else strcpy(vr,",ERR");               // 結果無し時は文字列変数へERRを代入
     if(led==0) strcpy(vr,",OFF");           // led=0のとき文字列変数へOFFを代入
-    else if(led==1) strcpy(vr,",ON");       // led=1のとき文字列変数へONを代入
+      else if(led==1) strcpy(vr,",ON");     // led=1のとき文字列変数へONを代入
     Serial.println(vr);                     // 文字列変数をシリアル出力表示
-    t=0;                                    // 待ち時間カウンタのリセット
-    phoneme_i=0;                            // 音声データ数を0に
-    memset(phoneme,0,17);                   // 音声データ用の変数の初期化
+    t=0; phoneme_i=0; memset(phoneme,0,17); // 時間、音声データ用の変数の初期化
     if(led==LED || led<0) return;           // LED状態に変化がないときに戻る
     LED=led;                                // LED状態を保持する変数LEDの更新
-
-    /* 送信部 */
     WiFi.mode(WIFI_STA);                    // 無線LANをSTAモードに設定
     WiFi.begin(SSID,PASS);                  // 無線LANアクセスポイントへ接続
     while(WiFi.status() != WL_CONNECTED){   // 接続に成功するまで待つ
         digitalWrite(PIN_LED,!digitalRead(PIN_LED));            // LEDの点滅
         delay(100);                         // 待ち時間
-    }
-    Serial.println(WiFi.localIP());         // 本機のIPアドレスをシリアル出力
+    } Serial.println(WiFi.localIP());       // 本機のIPアドレスをシリアル出力
     WiFiUDP udp;                            // UDP通信用のインスタンスを定義
     udp.beginPacket(SENDTO, PORT);          // UDP送信先を設定
     udp.print(DEVICE);                      // デバイス名を送信
     udp.print(LED);                         // ON=1、OFF=0を送信
     udp.println(vr);                        // 認識結果の文字列vrを送信
-    udp.endPacket();                        // UDP送信の終了(実際に送信する)
-    delay(10);
+    udp.endPacket(); delay(10);             // UDP送信の終了(実際に送信する)
     WiFi.disconnect(true);                  // WiFiアクセスポイントを切断する
     WiFi.mode(WIFI_OFF);                    // 無線LANをOFFに設定する
 }


Added gyroscope data acquisition to main loop

--- oktopus-autopilote/oktopus-autopilote.ino
+++ oktopus-autopilote/oktopus-autopilote.ino
@@ -6,22 +6,26 @@
 // Licence: Apache License Version 2.0, January 2004 http://www.apache.org/licenses/

 #include "GPS.h"
+#include "Gyroscope.h"
 #include "Moisture.h"
 #include "Temperature.h"

 GPS gps;
+Gyroscope gyroscope;
 Moisture moistureSensor;
 Temperature temperatureSensor;

+float heading = 0.00;
+NMEAData gpsData;
 String moisture = "Unknown";
 short temperature = 0;
-NMEAData gpsData;

 void setup() {
   Serial.begin(115200);
   gps.enable();
   moistureSensor.enable();
   temperatureSensor.enable();
+  gyroscope.enable();
 }

 uint32_t timer = millis();
@@ -36,11 +40,13 @@
   if (millis() - timer > 2000) {

     timer = millis(); // reset the time
-
+
+    heading = gyroscope.getData();
     moisture = moistureSensor.getData();
     temperature = temperatureSensor.getData();

     gps.printData(gpsData);
+    gyroscope.printData(heading);
     moistureSensor.printData(moisture);
     temperatureSensor.printData(temperature);
   }


BasicGain: switched to INPUT_JACK_MIC

BasicGain: switched to INPUT_JACK_MIC

--- examples/01-Basic/BasicGain/BasicGain.ino
+++ examples/01-Basic/BasicGain/BasicGain.ino
@@ -48,8 +48,8 @@
   audioHardware.enable(); // activate AIC

   //Choose the desired input
-  audioHardware.inputSelect(TYMPAN_INPUT_ON_BOARD_MIC); // use the on board microphones
-  //  audioHardware.inputSelect(TYMPAN_INPUT_JACK_AS_MIC); // use the microphone jack - defaults to mic bias 2.5V
+  //audioHardware.inputSelect(TYMPAN_INPUT_ON_BOARD_MIC); // use the on board microphones
+  audioHardware.inputSelect(TYMPAN_INPUT_JACK_AS_MIC); // use the microphone jack - defaults to mic bias 2.5V
   //  audioHardware.inputSelect(TYMPAN_INPUT_JACK_AS_LINEIN); // use the microphone jack - defaults to mic bias OFF

   //Set the desired volume levels


Teensy MIDI velocity fix

Teensy MIDI velocity fix

This fixes the way the TeensyMidi sketch interprets velocity and volume
from linear to logarithmic scale.

--- examples/Teensy/TeensyMidi/TeensyMidi.ino
+++ examples/Teensy/TeensyMidi/TeensyMidi.ino
@@ -217,7 +217,7 @@

 		// Change volume of a MIDI channel.
 		case CONTROL_VOLUME: {
-			channelVolumes[channel] = log(min((float)velocity, 127.0)) / log(127.0);
+			channelVolumes[channel] = log(min((float)value, 127.0)) / log(127.0);
 			for (byte i = 0; i < OPL2_NUM_CHANNELS; i ++) {
 				if (channelMap[i].midiChannel == channel && opl2.getKeyOn(i)) {
 					setOpl2ChannelVolume(i, channel);


Do not wait forever for WiFi on the Photon, but give up and retry the entire connection again. It has happened that the device remains stuck attempting to connect and never succeeding...

--- Particle/THLMqttSensor/src/THLMqttSensor.ino
+++ Particle/THLMqttSensor/src/THLMqttSensor.ino
@@ -151,8 +151,12 @@
                 ", \"hmin\": " + shmin + ", \"hmax\": " + shmax +
                 ", \"lmin\": " + slmin + ", \"lmax\": " + slmax : "") +
       "}";
-  // make sure we're online
-  waitUntil(WiFi.ready);
+  // make sure we're online, but give up after 10 seconds
+  if(!waitFor(WiFi.ready, 10000)) {
+    // we failed to get online, try again after 2 seconds
+    lastReadoutTime = Time.now() - readoutTimeIntervalMins*60 + 2;
+    return -1;
+  }
   // connect to the MQTT broker
   client.connect("photon");
   // publish data to the MQTT broker


最初の第一声が鳴らなかった対策

最初の第一声が鳴らなかった対策

--- 2_example/example21_talk/example21_talk.ino
+++ 2_example/example21_talk/example21_talk.ino
@@ -17,8 +17,10 @@

 void setup(){                               // 起動時に一度だけ実行する関数
     Serial.begin(9600);                     // AquesTalkとの通信ポート
-    Serial.print("kon'nnichi/wa.\r");       // 音声「こんにちわ」を出力する
-    wifi_set_sleep_type(LIGHT_SLEEP_T);     // 省電力モード設定(将来用)
+    Serial.print("\r$");                    // ブレークコマンドを出力する
+    delay(100);                             // 待ち時間処理
+    Serial.print("$?kon'nnichi/wa.\r");     // 音声「こんにちわ」を出力する
+    wifi_set_sleep_type(LIGHT_SLEEP_T);     // 省電力モード設定
     WiFi.mode(WIFI_STA);                    // 無線LANをSTAモードに設定
     WiFi.begin(SSID,PASS);                  // 無線LANアクセスポイントへ接続
     while(WiFi.status() != WL_CONNECTED){   // 接続に成功するまで待つ


Updating to use string helper, score tracking

--- arduino/duinosays/duinosays.ino
+++ arduino/duinosays/duinosays.ino
@@ -397,7 +397,7 @@
                                                 btnColor[1] * progressCounter >> progressCounterMaxBit,
                                                 btnColor[2] * progressCounter >> progressCounterMaxBit);
                 buffer.drawRect(48-w/2,32-h/2,w,h)->filledRect(rectColor);
-                buffer.drawText(stringBuffer.start()->put(currentStep)->put(":")->put(currentLevel)->get(),42,52,buffer.rgb(255,128,32), &virtualDJ_5ptFontInfo);
+                buffer.drawText(stringBuffer.start()->putDec(currentStep)->put(":")->putDec(currentLevel)->get(),42,52,buffer.rgb(255,128,32), &virtualDJ_5ptFontInfo);
                 if (progressCounter == 0) {
                     spawnQuadParticles(4|col, 48,32,800,24);
                 }
@@ -427,7 +427,7 @@
             if (currentStep > currentLevel) {
                 nextLevel();
             } else {
-                buffer.drawText(stringBuffer.start()->put(currentStep)->put(":")->put(currentLevel)->get(),42,52,buffer.rgb(255,128,32), &virtualDJ_5ptFontInfo);
+                buffer.drawText(stringBuffer.start()->putDec(currentStep)->put(":")->putDec(currentLevel)->get(),42,52,buffer.rgb(255,128,32), &virtualDJ_5ptFontInfo);
             }
         }

@@ -449,7 +449,18 @@
     void loopScores() {
         buffer.drawText(stringBuffer.start()->load(PSTR("scores"))->get(),30,2,buffer.rgb(255,255,255), &virtualDJ_5ptFontInfo);
         buffer.drawRect(8,10,80,1)->filledRect(buffer.rgb(255,255,255));
+
+        for (int i=0;i<3;i+=1) {
+            char *tag = scores.getTag(i);
+            if (tag == 0) break;
+            uint16_t score = scores.getScore(i);
+            buffer.drawText(stringBuffer.start()->putDec(i)->put(')')->get(),10,15 + i * 8,buffer.rgb(255,255,255), &virtualDJ_5ptFontInfo);
+            buffer.drawText(stringBuffer.start()->put(tag)->get(),38,15 + i * 8,buffer.rgb(255,255,255), &virtualDJ_5ptFontInfo);
+            buffer.drawText(stringBuffer.start()->putDec(score)->get(),81 - score / 10 * 5,15 + i * 8,buffer.rgb(255,255,255), &virtualDJ_5ptFontInfo);
+        }
+
         buffer.drawText(stringBuffer.start()->load(PSTR("beat it"))->get(),53,45,buffer.rgb(255,255,255), &virtualDJ_5ptFontInfo);
+
         btnBottomRight.draw(this);
         if (btnBottomRight.getIsPressed()) {
             switchToMainMenu();
@@ -487,7 +498,7 @@

 void GameOverScreen::loop(DuinoSays* ds) {
     ds->buffer.drawText(stringBuffer.start()->load(PSTR("game over"))->get(),20,16,ds->buffer.rgb(255,128,32), &virtualDJ_5ptFontInfo);
-    ds->buffer.drawText(stringBuffer.start()->load(PSTR("score: "))->put(ds->currentScore)->get(),
+    ds->buffer.drawText(stringBuffer.start()->load(PSTR("score: "))->putDec(ds->currentScore)->get(),
                         28 - (ds->currentScore / 10) * 5,40,ds->buffer.rgb(192,192,192), &virtualDJ_5ptFontInfo);
     if (ds->progressCounter < 50) {
         ds->progressCounter++;
@@ -495,10 +506,10 @@
         if (ds->scores.isHighEnough(ds->currentScore)) {
             static uint8_t tag[3] = {0, 0, 0};
             static uint8_t tagPos = 0;
-            const char* alpha = " abcdefghijklmnopqrstuvwxyz0123456789";
+            const char* alpha = " abcdefghijklmnopqrstuvwxyz.-!?0123456789";
             uint8_t currentPos = tag[tagPos];
-            char prevIdx = (currentPos + 37 - 1) % (37);
-            char nextIdx = (currentPos + 37 + 1) % (37);
+            char prevIdx = (currentPos + 41 - 1) % (41);
+            char nextIdx = (currentPos + 41 + 1) % (41);

             const uint8_t grey = 128;


Send the status at boot.

Send the status at boot.

--- arduino/magsensor/magsensor.ino
+++ arduino/magsensor/magsensor.ino
@@ -162,6 +162,8 @@
   // Allow wake up pins to trigger interrupt on state change.
   attachInterrupt(digitalPinToInterrupt(MAGNETIC_SWITCH_PIN), doorInterrupt, CHANGE);
   attachInterrupt(digitalPinToInterrupt(DIAG_SWITCH_PIN), diagnoticInterrupt, RISING);
+  // Send the status on startup
+  sendStatus(g_contact);
 }

 void loop() {


Change interruption code

Change interruption code

--- particle-gui/firmware/setup.ino
+++ particle-gui/firmware/setup.ino
@@ -59,8 +59,8 @@
              "Content-Type": "application/json"
          },
          "json": {
-             "socketNum": "{{socketNum}}",
-             "apiKey": "{{apiKey}}"
+            "apiKey": "{{apiKey}}",
+            "socketNum": "{{socketNum}}"
          },
          "mydevices": true
      }
@@ -147,11 +147,14 @@
     /* SET RELAY PINS AND INTERRUPTIONS - START */
     pinMode(relay1, OUTPUT);                                  //setup of relay1 as output on Photon
     pinMode(pushbutton1, INPUT_PULLUP);                      //setup pushbutton1 as an input with the Pullup resistor enabled (nomally high or 3V3)
-    attachInterrupt(pushbutton1, toggle_relay1, FALLING);   //attach the interruption to toggle the state_relay1 and happen when the negative edge of the signal from pushbutton1
+
+    // attachInterrupt(pushbutton1, toggle_relay1, FALLING);   //attach the interruption to toggle the state_relay1 and happen when the negative edge of the signal from pushbutton1

     pinMode(relay2, OUTPUT);                                 //setup of relay2 as output on Photon
     pinMode(pushbutton2, INPUT_PULLUP);                     //setup pushbutton2 as an input with the Pullup resistor enabled (nomally high or 3V3)
-    attachInterrupt(pushbutton2, toggle_relay2, FALLING);  //attach the interruption to toggle the state_relay2 and happen when the negative edge of the signal from pushbutton2
+
+    // attachInterrupt(pushbutton2, toggle_relay2, FALLING);  //attach the interruption to toggle the state_relay2 and happen when the negative edge of the signal from pushbutton2
+
     /* SET RELAY PINS AND INTERRUPTIONS - END */

     /* TURN OFF WiFi IF NO LUCK CONNECTING - START */
@@ -205,7 +208,7 @@
     Serial.print("Corrente1 (A): ");
     Serial.print(Irms0);                    // Irms0
     Serial.print("      ");
-     Serial.print("Corrente2 (A): ");
+    Serial.print("Corrente2 (A): ");
     Serial.print(Irms1);                    // Irms1
     Serial.print("      ");
     Serial.print("Potencia1 (W): ");
@@ -247,6 +250,39 @@

 /* SEND AND GET INFORMATION FROM SERVER - START */
+
+    if(digitalRead(pushbutton1) == LOW && digitalRead(pushbutton2) == HIGH){
+
+        state_relay1 = !state_relay1;
+        digitalWrite(relay1, state_relay1);  //Writes the state_relay1 to relay 1
+
+        // Send auth data
+        String jsonChangeSocketStatus = String(
+          "{ \"apiKey\": \"" + String("{{{apiKey}}}") + "\"" +
+           ",\"socketNum\": \"" + String(1) +  "\"}" );
+
+        Particle.publish("changeSocketStatus", jsonChangeSocketStatus, PRIVATE);
+
+        // Wait 4 seconds
+        delay(4000);
+    }
+
+    if(digitalRead(pushbutton2) == LOW && digitalRead(pushbutton1) == HIGH){
+
+        state_relay2 = !state_relay2;
+        digitalWrite(relay2, state_relay2); //Writes the state_relay2 to relay 2
+
+        // Send auth data
+        String jsonChangeSocketStatus = String(
+          "{ \"apiKey\": \"" + String("{{{apiKey}}}") + "\"" +
+           ",\"socketNum\": \"" + String(2) +  "\"}" );
+
+        Particle.publish("changeSocketStatus", jsonChangeSocketStatus, PRIVATE);
+
+        // Wait 4 seconds
+        delay(4000);
+    }
+
     if (statuses[0] == String("Active") && Irms0 > 0) {
         // Send reading data
         String jsonSendSocketInformation = String(
@@ -441,38 +477,25 @@

 /* TOGGLE RELAY FUNCTIONS - START */
-void toggle_relay1()
-{
-    /* Function to toggle_relay1 when the interruption from the falling edge signal from pushbutton1 happens */
-    if(digitalRead(pushbutton1) == LOW && digitalRead(pushbutton2) == HIGH){
-        state_relay1 = !state_relay1;
-        digitalWrite(relay1, state_relay1);  //Writes the state_relay1 to relay 1
-
-        // Send auth data
-        String jsonChangeSocketStatus = String(
-          "{ \"apiKey\": \"" + String("{{{apiKey}}}") + "\"" +
-           ",\"socketNum\": \"" + String(1) +  "\"}" );
-
-        Particle.publish("changeSocketStatus", jsonChangeSocketStatus, PRIVATE);
-    }
-}
-
-
-void toggle_relay2()
-{
-    /* Function to toggle_relay2 when the interruption from the falling edge signal from pushbutton2 happens */
-    if(digitalRead(pushbutton2) == LOW && digitalRead(pushbutton1) == HIGH){
-        state_relay2 = !state_relay2;
-        digitalWrite(relay2, state_relay2);     //Writes the state_relay2 to relay 2
-
-        // Send auth data
-        String jsonChangeSocketStatus = String(
-          "{ \"apiKey\": \"" + String("{{{apiKey}}}") + "\"" +
-           ",\"socketNum\": \"" + String(2) +  "\"}" );
-
-        Particle.publish("changeSocketStatus", jsonChangeSocketStatus, PRIVATE);
-    }
-}
+
+//void toggle_relay1()
+//{
+// /* Function to toggle_relay1 when the interruption from the falling edge signal from pushbutton1 happens */
+//    if(digitalRead(pushbutton1) == LOW && digitalRead(pushbutton2) == HIGH){
+//        state_relay1 = !state_relay1;
+//        digitalWrite(relay1, state_relay1);  //Writes the state_relay1 to relay 1
+//    }
+//}
+
+
+//void toggle_relay2()
+//{
+// /* Function to toggle_relay2 when the interruption from the falling edge signal from pushbutton2 happens */
+//    if(digitalRead(pushbutton2) == LOW && digitalRead(pushbutton1) == HIGH){
+//        state_relay2 = !state_relay2;
+//        digitalWrite(relay2, state_relay2); //Writes the state_relay2 to relay 2
+//    }
+//}

 double get_Irms0_current(){


Another fixed because the irrecdump demo does not compile for some reason. Hopefully this time it works.

--- examples/IRrecvDump/IRrecvDump.ino
+++ examples/IRrecvDump/IRrecvDump.ino
@@ -26,21 +26,16 @@
   irrecv.enableIRIn(); // Start the receiver
 }

+void output(decoder_results *results);
+
 void loop() {
   if (irrecv.decode(&results)) {
     Serial.println(results.value, HEX);
-    dump(&results);
+    output(&results);
     irrecv.resume(); // Receive the next value
   }
 }
-
-// Dumps out the AllAboutEE_decoder_results structure.
-// Call this after AllAboutEE_IRrecv::decode()
-// void * to work around compiler issue
-//void dump(void *v) {
-//  AllAboutEE_decoder_results *results = (AllAboutEE_decoder_results *)v
-
-void dump(decoder_results *results) {
+void output(decoder_results *results) {
   int count = results->rawlen;
   if (results->decode_type == UNKNOWN) {
     Serial.print("Unknown encoding: ");


Proper power-up/cool-down to seizure mode

For some reason this is really fun.

--- examples/WearButton/WearButton.ino
+++ examples/WearButton/WearButton.ino
@@ -1,35 +1,62 @@
 #include <Button.h>
 #include <Adafruit_NeoPixel.h>
+#include <math.h>

 #define LED_COUNT 60
 #define THRESHOLD 1

+#define COLOR_MODE 0
+#define COUNTDOWN_MODE 1
+#define SEIZURE_MODE 2
+#define COOLDOWN_MODE 3
+
 Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, 5, NEO_GRB + NEO_KHZ800);

 uint8_t pixel_index;

 long last_time;
+long countdown_start;
+long cooldown_start;
+long countdown_length = 500;
+long cooldown_length;

 Button button = Button(13, BUTTON_PULLUP_INTERNAL, true, 50);

 float brightness = 1.0;
-
-void onPress(Button& b){
-  brightness = brightness - 0.25;
-  if(brightness < 0) brightness = 0;
-  Serial.println("Btn pressed");
-}
-
-void onHold(Button& b){
-  brightness = 1.0;
-  Serial.println("Btn held");
+boolean all_on = false;
+
+int draw_mode = COLOR_MODE;
+
+void onPress(Button& b) {
+  if(draw_mode == COLOR_MODE) {
+    countdown_start = millis();
+    draw_mode = COUNTDOWN_MODE;
+  }
+  if(draw_mode == COOLDOWN_MODE) {
+    countdown_start = millis();
+    countdown_start = countdown_start - (cooldown_length - (countdown_start - cooldown_start));
+    draw_mode = COUNTDOWN_MODE;
+  }
+}
+
+void onRelease(Button& b) {
+  if(draw_mode == COUNTDOWN_MODE) {
+    cooldown_start = millis();
+    cooldown_length = cooldown_start - countdown_start;
+    draw_mode = COOLDOWN_MODE;
+  }
+}
+
+void onHold(Button& b) {
+  if(draw_mode == SEIZURE_MODE)
+    draw_mode = COLOR_MODE;
 }

 void setup()
 {
   // Set the MOSI pin as digital output
   // (only for BB RevA)
-//  DDRB |= _BV(2);
+  //  DDRB |= _BV(2);

   Serial.begin(57600);

@@ -38,6 +65,7 @@
   last_time = millis();

   button.pressHandler(onPress);
+  button.releaseHandler(onRelease);
   button.holdHandler(onHold, 1000); // must be held for at least 1000 ms to trigger
 }

@@ -78,6 +106,59 @@
   j = j + random(1,2);
   f = f + random(1,2);
   k = k + random(1,2);
+}
+
+void countdown_loop() {
+  long elapsed = millis() - countdown_start;
+  if(elapsed > countdown_length) {
+    Serial.println("SEIZURE MODE ACTIVATE");
+    draw_mode = SEIZURE_MODE;
+    last_time = millis();
+  } else {
+    draw_progress(elapsed, countdown_length);
+  }
+}
+
+void cooldown_loop() {
+  long elapsed = millis() - cooldown_start;
+  if(elapsed > cooldown_length) {
+    draw_mode = COLOR_MODE;
+    last_time = millis();
+  } else {
+    draw_progress(cooldown_length - elapsed, countdown_length);
+  }
+}
+
+void draw_progress(long elapsed, long countdown_length) {
+  Serial.print("Elapsed: "); Serial.println(elapsed);
+  float progress = (float) elapsed / (float) countdown_length;
+  int count = round((float)LED_COUNT * progress);
+  for (int x = 0; x < count; x++) {
+    strip.setPixelColor(x, strip.Color(255,255,255));
+  }
+  for(int x = count+1; x < LED_COUNT; x++) {
+    strip.setPixelColor(x, strip.Color(255,0,0));
+  }
+  strip.show();
+}
+
+void seizure_loop() {
+  long elapsed = millis() - last_time;
+  uint32_t new_color;
+  Serial.print("Seizure time Elapsed: ");
+  Serial.println(elapsed);
+  if(elapsed > 30) {
+    all_on = ~all_on;
+    last_time = millis();
+  }
+  if(all_on)
+    new_color = strip.Color(255,255,255);
+  else
+    new_color = strip.Color(0,0,0);
+  for(int x = LED_COUNT; x >= 0; x--) {
+    strip.setPixelColor(x, new_color);
+  }
+  strip.show();
 }

 void serialLoop() {
@@ -115,8 +196,20 @@
   if(Serial.available() > 0) {
     serialLoop();
   }
-
-  color_loop();
+  switch(draw_mode) {
+    case COLOR_MODE:
+      color_loop();
+      break;
+    case COUNTDOWN_MODE:
+      countdown_loop();
+      break;
+    case COOLDOWN_MODE:
+      cooldown_loop();
+      break;
+    case SEIZURE_MODE:
+      seizure_loop();
+      break;
+  }
   button.process();
 }


Use GD2's xy class.

Use GD2's xy class.


Fix the comments at the top of the script, and remove the factory reset option.


took out ph

took out ph

--- aquaponicMCP/aquaponicMCP.ino
+++ aquaponicMCP/aquaponicMCP.ino
@@ -1,7 +1,9 @@
+
+#include <OneWire.h>
 //L = left sensor, R = right sensor
 #define lightSensorR A0
 #define lightSensorL A1
-#define waterTempSensor A2
+OneWire  ds(2); //water temp sensor on digital pin 2
 #define waterTurbSensor A3

 #define minLightL 0
@@ -61,7 +63,6 @@
   lightL = analogRead(lightSensorL);
   waterTemp = analogRead(waterTempSensor);
   waterTurb = analogRead(waterTurbSensor);
-  waterPH = analogRead(waterPHSensor);
   lightRBuffer[bufferCounter] = lightR;
   lightLBuffer[bufferCounter] = lightL;
   tempBuffer[bufferCounter] = waterTemp;
@@ -98,10 +99,10 @@

 void GetInput(){
   if (Serial.available() > 0) {
-    incomingByte = Serial.read();
-    if(incomingByte == 'a'){
-
-    }
+//    incomingByte = Serial.read();
+//    if(incomingByte == 'a'){
+//
+//    }
   }
 }


vehicle #2

vehicle #2

--- MoveActuator/MoveActuator.ino
+++ MoveActuator/MoveActuator.ino
@@ -30,9 +30,9 @@
 7/1/15 TCF  Removed BASSACKWARDS, put in VEHICLE_NUMBER
 */
 // Orange trike
-#define VEHICLE_NUMBER 1
+//#define VEHICLE_NUMBER 1
 // Yellow trike
-//#define VEHICLE_NUMBER 2
+#define VEHICLE_NUMBER 2

 // DIGITAL I/O ----------------------------------------------


minor cosmetic changes to setup()

minor cosmetic changes to setup()

--- OpenStage/d_setupFunction.ino
+++ OpenStage/d_setupFunction.ino
@@ -71,6 +71,7 @@

     pinMode(stageLEDs[ii],OUTPUT);
     digitalWrite(stageLEDs[ii],LOW);
+
     if (verbose){
       Serial.print(ii);
       Serial.print(" ");
@@ -151,7 +152,7 @@
       Usb.Task();
       delay(100);
       if (verbose){
-     //   Serial.print(".");
+        Serial.print(".");
       }
       #ifdef DO_LCD
        lcd.print(".");


コマンド入力とセンサの値の両方を扱えるよう調整

コマンド入力とセンサの値の両方を扱えるよう調整

--- wearlumination.ino
+++ wearlumination.ino
@@ -1,18 +1,82 @@
-int out1 = 3;//PWM
-int out2 = 5;//PWM
-int in1 = 1;
-int in2 = 2;
+/*
+ * wear lumination
+ * Created by t.uehara and a_ono / sweet electronics
+ * https://github.com/usopyon/wearlumination
+ */
+
+#include <wiring_private.h>
+
+// ピン配置
+
+static int out1 = 3;//PWM
+static int out2 = 5;//PWM
+static int in1 = 1;
+static int in2 = 2;
+
+// その他
+
+char buff[8];
+int delay_time = 200;//200ms
+unsigned long cmd_time = 0UL;
+unsigned long wait_time = 10UL * 1000UL; //10秒

 void setup(){
   pinMode(out1, OUTPUT);
   pinMode(out2, OUTPUT);
+  Serial.begin(9600);
+  Serial.println("ready");
+
 }

 void loop()
 {
+  serial_read();
+
   int val1 = analogRead(in1);
   int val2 = analogRead(in2);
+
+  // 直近にコマンドを実行してから10秒以上経過したらセンサの値を扱う
+  if( millis() - cmd_time > wait_time ){
+    analogWrite(out1, val1/8);
+    analogWrite(out2, val2/8);
+  }
+
+  delay(delay_time);
+}
+
+void serial_read(){
+  int pin = 0;
+  int val = 0;
+  int c = 0;
+  while( Serial.available() ){
+    buff[c] = Serial.read();
+    c++;
+  }
+  //Serial.flush();
+  Serial.print(buff);
+
+  switch(buff[0]){
+    case 114: //r
+      Serial.print(" red");
+      pin = out1;
+      break;
+    case 103: //g
+      Serial.print(" green");
+      pin = out2;
+      break;
+  }
+
+  if( buff[1] ){
+    val = (int)(buff[1]-48)*27;// r9で255付近になるよう調整
+    Serial.println(val);
+    analogWrite(pin, val);
+    cmd_time = millis();
+  }
+
+  for(int i = 0; i < 8; i++ ){
+    buff[i] = NULL;
+  }

-  analogWrite(out1, val1/4);
-  analogWrite(out2, val2/4);
 }
+
+


Minor renaming

Minor renaming

--- ManeAvis.ino
+++ ManeAvis.ino
@@ -50,12 +50,12 @@

 /*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();*/
+/*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;

@@ -79,7 +79,6 @@
   Particle.variable("freeMemory", freeMemory);
   Particle.function("alarm", handleAlarm);

-  /*Display.setFont(COMICS_8);*/
   #if defined COLOR_SCREEN
   Display.fillScreen(BLACK);
   #else
@@ -103,8 +102,8 @@
 }

 void exitStart() {
-  Renderer.start();
-  Syncer.start();
+  renderer.start();
+  syncer.start();
 }

 void updateClock() {
@@ -121,24 +120,24 @@
 }

 void enterAlarm() {
-  AlarmRuntime.start();
+  alarmRuntime.start();
   RGB.color(0, 0, 255);

   /*parser = new AlarmToneLanguage(song);*/
-  /*Player.reset();*/
+  /*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)) {
+  if(alarmRuntime.check(ALARM_LENGTH)) {
     stateMachine.transitionTo(Clock);
   }
 }

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

   RGB.color(0, 0, 0);
@@ -191,7 +190,7 @@
 }

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


added boiler on tag

added boiler on tag

--- Arduino/hardware/REV10/REV10MessagePathTest/REV10SecureBHR/REV10SecureBHR.ino
+++ Arduino/hardware/REV10/REV10MessagePathTest/REV10SecureBHR/REV10SecureBHR.ino
@@ -351,7 +351,8 @@
         ss1.enableCount(false);
         ss1.putOrRemove(OTV0P2BASE::ErrorReporter);
         ss1.put(TemperatureC16);
-
+        // Show boiler state for boiler hubs.
+        ss1.put(V0p2_SENSOR_TAG_F("b"), (int) BoilerHub.isBoilerOn());
         // OPTIONAL items
         constexpr uint8_t privacyLevel = OTV0P2BASE::stTXalwaysAll;


コメント充実!

コメント充実!

--- arduino/GeneralIoSerial/GeneralIoSerial.ino
+++ arduino/GeneralIoSerial/GeneralIoSerial.ino
@@ -26,11 +26,55 @@

 // prefixとタスク関数のテーブルを使ってキメる.
 const struct TASK_FUNC TASK_FUNC_TBL[] = {
+  /*
+     Read AI port.
+     format  => ai/read/{port}
+     {port}  => port number.
+     example => ai/read/0
+   */
   {String("ai/read/"), &aiReadTask},
+
+  /*
+    Switch AI reference volt.
+    format  => ai/ref?type={TYPE}
+    {TYPE}  => DEFAULT | INTERNAL | EXTERNAL
+    example => ai/ref?type=INTERNAL
+   */
   {String("ai/ref"), &aiRefSwitchTask},
+
+  /*
+     Write AO port.
+     format  => ao/write/{port}?val={val}
+     {port}  => port number.
+     {val}   => write value.
+     example => ao/write/1?val=100
+   */
   {String("ao/write/"), &aoWriteTask},
+
+  /*
+     Read DI port.
+     format  => di/read/{port}
+     {port}  => port number.
+     example => di/read/2
+   */
   {String("di/read/"), &diReadTask},
+
+
+  /*
+     Write DO port.
+     format  => do/write/{port}?val={val}
+     {port}  => port number.
+     {val}   => write value.
+     example => do/write/3?val=1
+   */
   {String("do/write/"), &doWriteTask},
+
+
+
+  /*
+     Close serial port.
+     format => system/close
+   */
   {String("system/close"), &closeSerial}
 };


Several fixes to have the state machine fully working, but this is still unreliable, need to look for alternate solutions

--- Particle/LuxSensor/src/LuxSensor.ino
+++ Particle/LuxSensor/src/LuxSensor.ino
@@ -10,8 +10,8 @@
  ******************************************************************************/

 int photoPin = A5;           // photoresistor pin
-int powerPin = A0;
-int readoutTimeIntervalMins = 1;   // perform a readout every given minutes
+int powerPin = A0;           // the other leg of the photoresistor
+int readoutTimeIntervalMins = 2;    // perform a readout every given minutes

 const int PHOTON_OFFLINE = 0;
 const int PHOTON_CONNECTING = 1;
@@ -26,6 +26,7 @@
 void setup() {
   pinMode(photoPin, INPUT);     // prepare the photoresistor
   pinMode(powerPin, OUTPUT);
+  pinMode(D7, OUTPUT);       // the integrated LED signals readout errors
   digitalWrite(powerPin, HIGH);
 }

@@ -63,7 +64,7 @@
       // also publish daily max and min values when button pressed
       (button ? ", lmin: " + slmin + ", lmax: " + slmax : "") +
       "}";
-  // publish data
+  // publish data: ttl = 60 for now, in the future it may be readoutTimeIntervalMins*60
   if(!Particle.publish("luxdata", payload, PRIVATE, WITH_ACK)) {
     return -1;
   }
@@ -75,9 +76,11 @@
   int pushButtonState = HIGH;
   if(pushButtonState == LOW) {
     // button was pressed, connect for an immediate readout
+    Particle.connect();
+    // turn off the LED in case it was on
+    digitalWrite(D7, LOW);
     buttonPressed = true;
     photonState = PHOTON_CONNECTING;
-    Particle.connect();
     return;
   }
   else {
@@ -85,25 +88,39 @@
     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
+      lastReadoutTime = Time.now();
+      // connect to WiFi and the cloud (this is asynchronous)
+      Particle.connect();
+      // turn off the LED in case it was on
+      digitalWrite(D7, LOW);
+      buttonPressed = false;
       photonState = PHOTON_CONNECTING;
-      buttonPressed = false;
-      Particle.connect();
-      lastReadoutTime = Time.now();
       return;
     }
   }
   if(photonState == PHOTON_CONNECTING) {
-      digitalWrite(D7, LOW);
-      if(!readout(buttonPressed)) {
+      // make sure we're online
+      waitUntil(Particle.connected);
+      // do the readout
+      if(readout(buttonPressed)) {
+        // something went wrong, signal the error by blinking the LED
         digitalWrite(D7, HIGH);
+        // and don't change state, to try and read out right away
       }
-      photonState = PHOTON_ONLINE;
+      else {
+        // all right, go in ONLINE mode to let the Particle cloud
+        // effectively publish the data. Switching the WiFi off now
+        // without returning control to the main firmware would make
+        // the Publish ineffective!
+        photonState = PHOTON_ONLINE;
+      }
       return;
   }
   if(photonState == PHOTON_ONLINE && !buttonPressed) {
+    // still wait a bit
     delay(1000);
+    // and go offline
     WiFi.off();
-    digitalWrite(D7, LOW);
     photonState = PHOTON_OFFLINE;
   }
   // loop at 5 Hz to catch button press events


Added a 4th fan to the Arduino software config

--- fanduino-nano/fanduino-nano.ino
+++ fanduino-nano/fanduino-nano.ino
@@ -20,10 +20,12 @@
 const int kFan0PwmPin = 3;
 const int kFan1PwmPin = 9;
 const int kFan2PwmPin = 10;
+const int kFan3PwmPin = 11;

 const int kFan0RpmPin = 4;
 const int kFan1RpmPin = 6;
 const int kFan2RpmPin = 7;
+const int kFan3RpmPin = 8;

 void setup() {
   Serial.begin(19200);
@@ -95,11 +97,12 @@
   const int kCommandSetDutycycle = 1;
   const int kCommandSetDefaultDutycycle = 2;

-  unsigned int rpm0, rpm1, rpm2;
+  unsigned int rpm0, rpm1, rpm2, rpm3;

   rpm0 = ReadRpm(kFan0RpmPin);
   rpm1 = ReadRpm(kFan1RpmPin);
   rpm2 = ReadRpm(kFan2RpmPin);
+  rpm3 = ReadRpm(kFan3RpmPin);

   Serial.print(rpm0);
   Serial.print(",");
@@ -107,11 +110,15 @@
   Serial.print(",");
   Serial.print(rpm2);
   Serial.print(",");
+  Serial.print(rpm3);
+  Serial.print(",");
   Serial.print(fan_0_dutycycle);
   Serial.print(",");
   Serial.print(fan_1_dutycycle);
   Serial.print(",");
-  Serial.println(fan_2_dutycycle);
+  Serial.print(fan_2_dutycycle);
+  Serial.print(",");
+  Serial.println(fan_3_dutycycle);

   if (ReadSerial(command, kCommandLength)) {
     switch (command[0]) {
@@ -142,6 +149,7 @@
   analogWrite(kFan0PwmPin, map(fan_0_dutycycle,0,100,0,255));
   analogWrite(kFan1PwmPin, map(fan_1_dutycycle,0,100,0,255));
   analogWrite(kFan2PwmPin, map(fan_2_dutycycle,0,100,0,255));
+  analogWrite(kFan3PwmPin, map(fan_3_dutycycle,0,100,0,255));

   delay(200);
 }


FM Beacon

FM Beacon

--- examples/FMBeacon/FMBeacon.ino
+++ examples/FMBeacon/FMBeacon.ino
@@ -65,4 +65,4 @@
     // Wait 10 seconds and check the channel again.
     delay(10000);
   }
-}+}


Update spark-web.ino

Update spark-web.ino

--- firmware/examples/spark-web.ino
+++ firmware/examples/spark-web.ino
@@ -1,9 +1,9 @@
 // This #include statement was automatically added by the Spark IDE.
-#include "spark-web-embd-rest-json/SparkTime.h"
-#include "spark-web-embd-rest-json/HttpRequest.h"
-#include "spark-web-embd-rest-json/HttpResponse.h"
-#include "spark-web-embd-rest-json/http_parser.h"
-#include "spark-web-embd-rest-json/spark-web-embd-rest-json.h"
+#include "SparkTime.h"
+#include "HttpRequest.h"
+#include "HttpResponse.h"
+#include "http_parser.h"
+#include "spark-web-embd-rest-json.h"
 #include <map>
 #include <list>


Further progress on actions available for the rover.

--- RoverMain/RoverMain.ino
+++ RoverMain/RoverMain.ino
@@ -257,85 +257,142 @@

 	actionScore = epsilon_select(ctxpair, 10);
 	switch(actionScore.action) {
-		case 0: // Drive forward, turn around, drive back
+		case 0: // Drive forward, turn around, drive back UNTESTED
 			wake();
 			allForward(100);
 			delay(1000);
 			brakes();
-			motorize( 0, 50, 1); // UNTESTED 180 deg turn
-			motorize( 1, 50, 0); // UNTESTED
-			motorize( 2, 50, 1); // UNTESTED
-			motorize( 3, 50, 0); // UNTESTED
-			delay(1000); // PROBABLY NEED TO CHANGE DELAY
-			brakes();
+			leftInPlace(180);
 			allForward(100);
 			delay(1000);
 			sleep();
 			break;
-		case 1: // Drive backward
+		case 1: // Drive backward UNTESTED
 			wake();
 			allBackward(50);
 			delay(2000);
 			brakes();
 			sleep();
-		case 2: // Drive in a clockwise circle
+			break;
+		case 2: // Drive in a clockwise circle UNTESTED
 			wake();
 			cwCircle(50);
 			delay(2000); // PROBABLY NEED TO CHANGE DELAY
 			sleep();
-		case 3: // Drive in a counter-clockwise circle
+			break;
+		case 3: // Drive in a counter-clockwise circle UNTESTED
 			wake();
 			ccwCircle(50);
 			delay(2000); // PROBABLY NEED TO CHANGE DELAY
 			sleep();
-		case 4: // Drive in a slight squiggle for 3 seconds
+			break;
+		case 4: // Drive in a slight squiggle for 3 seconds UNTESTED
 			wake();
 			squiggle(75, 3, 2);
 			sleep();
-		case 5: // Drive in a larger squiggle for 3 seconds
+			break;
+		case 5: // Drive in a larger squiggle for 3 seconds UNTESTED
 			wake();
 			squiggle(75, 3, 4);
 			sleep();
-		case 6:
+			break;
+		case 6: // Traverse a square UNTESTED
+			wake();
+			allForward(50);
+			delay(1000);
+			leftInPlace(90);
+			allForward(50);
+			delay(1000);
+			leftInPlace(90);
+			allForward(50);
+			delay(1000);
+			leftInPlace(90);
+			allForward(50);
+			delay(1000);
+			sleep();
+			break;
+		case 7: // Traverse a triangle UNTESTED
+			wake();
+			allForward(50);
+			delay(1000);
+			leftInPlace(60);
+			allForward(50);
+			delay(1000);
+			leftInPlace(60);
+			allForward(50);
+			delay(1000);
+			sleep();
+			break;
+		case 8: // Spin in place UNTESTED
+			wake();
+			leftInPlace(360);
+			rightInPlace(360);
+			sleep();
+			break;
+		case 9: // Short back and forth movements UNTESTED
+			wake();
+			allForward(100);
+			delay(100);
+			allBackward(100);
+			delay(100);
+			allForward(100);
+			delay(100);
+			allBackward(100);
+			delay(100);
+			allForward(100);
+			delay(100);
+			allBackward(100);
+			delay(100);
+			allForward(100);
+			delay(100);
+			allBackward(100);
+			delay(100);
+			sleep();
+			break;
+		case 10: // Half circle, then come back UNTESTED
+			wake();
+			cwCircle(50);
+			delay(1000); // PROBABLY NEED TO CHANGE DELAY
+			rightInPlace(90);
+			allForward(50);
+			delay(800);  // PROBABLY NEED TO CHANGE DELAY
+			sleep();
+			break;
+		case 11: // Traverse a clover UNTESTED
+			wake();
+			cwCircle(50);
+			delay(700); // PROBABLY NEED TO CHANGE DELAY
+			leftInPlace(90);
+			cwCircle(50);
+			delay(700); // PROBABLY NEED TO CHANGE DELAY
+			leftInPlace(90);
+			cwCircle(50);
+			delay(700); // PROBABLY NEED TO CHANGE DELAY
+			leftInPlace(90);
+			cwCircle(50);
+			delay(700); // PROBABLY NEED TO CHANGE DELAY
+			sleep();
+			break;
+		case 12: // Turn left and drive UNTESTED
 			wake();
 			// ACTION
 			sleep();
-		case 7:
+			break;
+		case 13: // Turn right and drive UNTESTED
 			wake();
 			// ACTION
 			sleep();
-		case 8:
+			break;
+		case 14: // Small spins back and forth UNTESTED
 			wake();
 			// ACTION
 			sleep();
-		case 9:
+			break;
+		case 15: // Traverse a spiral UNTESTED
 			wake();
 			// ACTION
 			sleep();
-		case 10:
-			wake();
-			// ACTION
-			sleep();
-		case 11:
-			wake();
-			// ACTION
-			sleep();
-		case 12:
-			wake();
-			// ACTION
-			sleep();
-		case 13:
-			wake();
-			// ACTION
-			sleep();
-		case 14:
-			wake();
-			// ACTION
-			sleep();
-		case 15:
-			wake();
-			// ACTION
-			sleep();
+			break;
 		default: // Do nothing
 			break;
 	}
@@ -383,7 +440,7 @@
 }

 // Moves the rover forward in a squiggly line for a given length in seconds
-// Larger squigFactors result in more squiggly lines
+// Larger squigFactors result in more squiggly lines, must be larger than 1
 void squiggle(int squigSpeed, int squigTime, int squigFactor) {
 	for (int i = 0; i < squigTime; i += 2000) {
 		motorize(0, squigSpeed, 1);
@@ -400,6 +457,26 @@
 	brakes();
 }

+// Turn the rover left in place the given number of degrees
+void leftInPlace(int degrees) {
+	motorize( 0, 50, 1);
+	motorize( 1, 50, 0);
+	motorize( 2, 50, 1);
+	motorize( 3, 50, 0);
+	delay(1000 * (degrees / 360)); // UNTESTED
+	brakes();
+}
+
+// Turn the rover right in place the given number of degrees
+void rightInPlace(int degrees) {
+	motorize( 0, 50, 0);
+	motorize( 1, 50, 1);
+	motorize( 2, 50, 0);
+	motorize( 3, 50, 1);
+	delay(1000 * (degrees / 360)); // UNTESTED
+	brakes();
+}
+
 // Send speeds of zero in backward direction to stop wheels
 void brakes() {
 	motorize( 0, 0, 0);


Fine-tuned actions, some require another look

--- RoverMain/RoverMain.ino
+++ RoverMain/RoverMain.ino
@@ -295,79 +295,79 @@

 	actionScore = epsilon_select(ctxpair, 10);
 	switch(actionScore.action) {
-		case 0: // Drive forward, turn around, drive back UNTESTED
-			wake();
-			allForward(100);
-			delay(1000);
+		case 0: // Drive forward, turn around, drive back
+			wake();
+			allForward(100);
+			delay(2000);
 			brakes();
 			leftInPlace(180);
 			allForward(100);
-			delay(1000);
-			sleep();
-			break;
-		case 1: // Drive backward UNTESTED
-			wake();
-			allBackward(50);
+			delay(2000);
+			sleep();
+			break;
+		case 1: // Drive backward
+			wake();
+			allBackward(100);
 			delay(2000);
 			brakes();
 			sleep();
 			break;
-		case 2: // Drive in a clockwise circle UNTESTED
-			wake();
-			cwCircle(50);
-			delay(2000); // PROBABLY NEED TO CHANGE DELAY
-			sleep();
-			break;
-		case 3: // Drive in a counter-clockwise circle UNTESTED
-			wake();
-			ccwCircle(50);
-			delay(2000); // PROBABLY NEED TO CHANGE DELAY
-			sleep();
-			break;
-		case 4: // Drive in a slight squiggle for 3 seconds UNTESTED
-			wake();
-			squiggle(75, 3, 2);
-			sleep();
-			break;
-		case 5: // Drive in a larger squiggle for 3 seconds UNTESTED
-			wake();
-			squiggle(75, 3, 4);
-			sleep();
-			break;
-		case 6: // Traverse a square UNTESTED
-			wake();
-			allForward(50);
-			delay(1000);
-			leftInPlace(90);
-			allForward(50);
-			delay(1000);
-			leftInPlace(90);
-			allForward(50);
-			delay(1000);
-			leftInPlace(90);
-			allForward(50);
-			delay(1000);
-			sleep();
-			break;
-		case 7: // Traverse a triangle UNTESTED
-			wake();
-			allForward(50);
-			delay(1000);
+		case 2: // Drive in a clockwise circle
+			wake();
+			cwCircle(100);
+			delay(8000);
+			sleep();
+			break;
+		case 3: // Drive in a counter-clockwise circle
+			wake();
+			ccwCircle(100);
+			delay(8000);
+			sleep();
+			break;
+		case 4: // Drive in a slight squiggle for 5 seconds
+			wake();
+			squiggle(100, 5, 2);
+			sleep();
+			break;
+		case 5: // Drive in a larger squiggle for 5 seconds
+			wake();
+			squiggle(100, 3, 4);
+			sleep();
+			break;
+		case 6: // Traverse a square
+			wake();
+			allForward(100);
+			delay(2000);
+			leftInPlace(90);
+			allForward(100);
+			delay(2000);
+			leftInPlace(90);
+			allForward(100);
+			delay(2000);
+			leftInPlace(90);
+			allForward(100);
+			delay(2000);
+			sleep();
+			break;
+		case 7: // Traverse a triangle
+			wake();
+			allForward(100);
+			delay(2000);
 			leftInPlace(60);
-			allForward(50);
-			delay(1000);
+			allForward(100);
+			delay(2000);
 			leftInPlace(60);
-			allForward(50);
-			delay(1000);
-			sleep();
-			break;
-		case 8: // Spin in place UNTESTED
+			allForward(100);
+			delay(2000);
+			sleep();
+			break;
+		case 8: // Spin in place
 			wake();
 			leftInPlace(360);
 			rightInPlace(360);
 			sleep();
 			break;
-		case 9: // Short back and forth movements UNTESTED
+		case 9: // Short back and forth movements
 			wake();
 			allForward(100);
 			delay(100);
@@ -387,45 +387,45 @@
 			delay(100);
 			sleep();
 			break;
-		case 10: // Half circle, then come back UNTESTED
-			wake();
-			cwCircle(50);
-			delay(1000); // PROBABLY NEED TO CHANGE DELAY
+		case 10: // Half circle, then come back NEEDS TWEAKING
+			wake();
+			cwCircle(100);
+			delay(4000);
 			rightInPlace(90);
-			allForward(50);
-			delay(800);  // PROBABLY NEED TO CHANGE DELAY
-			sleep();
-			break;
-		case 11: // Traverse a clover UNTESTED
-			wake();
-			cwCircle(50);
-			delay(700); // PROBABLY NEED TO CHANGE DELAY
-			leftInPlace(90);
-			cwCircle(50);
-			delay(700); // PROBABLY NEED TO CHANGE DELAY
-			leftInPlace(90);
-			cwCircle(50);
-			delay(700); // PROBABLY NEED TO CHANGE DELAY
-			leftInPlace(90);
-			cwCircle(50);
-			delay(700); // PROBABLY NEED TO CHANGE DELAY
-			sleep();
-			break;
-		case 12: // Turn left and drive UNTESTED
-			wake();
-			leftInPlace(90);
-			allForward(100);
-			delay(1000);
-			sleep();
-			break;
-		case 13: // Turn right and drive UNTESTED
+			allForward(100);
+			delay(2000);
+			sleep();
+			break;
+		case 11: // Traverse a clover NEEDS TWEAKING
+			wake();
+			cwCircle(80);
+			delay(2000);
+			leftInPlace(90);
+			cwCircle(80);
+			delay(2000);
+			leftInPlace(90);
+			cwCircle(80);
+			delay(2000);
+			leftInPlace(90);
+			cwCircle(80);
+			delay(2000);
+			sleep();
+			break;
+		case 12: // Turn left and drive
+			wake();
+			leftInPlace(90);
+			allForward(100);
+			delay(2000);
+			sleep();
+			break;
+		case 13: // Turn right and drive
 			wake();
 			rightInPlace(90);
 			allForward(100);
-			delay(1000);
-			sleep();
-			break;
-		case 14: // Wiggle in place UNTESTED
+			delay(2000);
+			sleep();
+			break;
+		case 14: // Wiggle in place
 			wake();
 			leftInPlace(30);
 			rightInPlace(30);
@@ -441,18 +441,18 @@
 			rightInPlace(30);
 			sleep();
 			break;
-		case 15: // Traverse a spiral UNTESTED
-			wake();
+		case 15: // Traverse a spiral NEEDS TWEAKING
+			wake();
+			ccwCircle(120);
+			delay(3000);
 			ccwCircle(100);
-			delay(1000); // PROBABLY NEED TO CHANGE DELAY
+			delay(2800);
 			ccwCircle(80);
-			delay(800); // PROBABLY NEED TO CHANGE DELAY
+			delay(2600);
 			ccwCircle(60);
-			delay(600); // PROBABLY NEED TO CHANGE DELAY
+			delay(2400);
 			ccwCircle(40);
-			delay(400); // PROBABLY NEED TO CHANGE DELAY
-			ccwCircle(20);
-			delay(200); // PROBABLY NEED TO CHANGE DELAY
+			delay(2200);
 			sleep();
 			break;
 		default: // Do nothing
@@ -520,22 +520,22 @@
 }

 // Turn the rover left in place the given number of degrees
-void leftInPlace(int degrees) {
-	motorize( 0, 50, 1);
-	motorize( 1, 50, 0);
-	motorize( 2, 50, 1);
-	motorize( 3, 50, 0);
-	delay(1000 * (degrees / 360)); // UNTESTED
+void leftInPlace(double degrees) {
+	motorize( 0, 80, 1);
+	motorize( 1, 80, 0);
+	motorize( 2, 80, 1);
+	motorize( 3, 80, 0);
+	delay(6000 * (degrees / 360)); // UNTESTED
 	brakes();
 }

 // Turn the rover right in place the given number of degrees
-void rightInPlace(int degrees) {
-	motorize( 0, 50, 0);
-	motorize( 1, 50, 1);
-	motorize( 2, 50, 0);
-	motorize( 3, 50, 1);
-	delay(1000 * (degrees / 360)); // UNTESTED
+void rightInPlace(double degrees) {
+	motorize( 0, 80, 0);
+	motorize( 1, 80, 1);
+	motorize( 2, 80, 0);
+	motorize( 3, 80, 1);
+	delay(6000 * (degrees / 360)); // UNTESTED
 	brakes();
 }


Added publising data to Particle servers

--- main.ino
+++ main.ino
@@ -1,9 +1,8 @@
 #define TEMP_SENSOR_PIN D6

 void setup() {
-  Serial.println("Hello world!");
-
-  Spark.publish("I'm alive", "It's true");
+  Serial.println("Starting up");
+  Spark.publish("Starting up");
 }

 void loop() {
@@ -81,6 +80,9 @@
   Serial.println(temperature);

   verifyChecksum(humidityRaw, temperatureRaw, checksum);
+
+  Spark.publish("Humidity", String(humidity));
+  Spark.publish("Temperature", String(temperature));
 }

 bool waitFor(int pin, int value, unsigned int timeout) {
@@ -149,7 +151,9 @@

   if (calculatedChecksum == receivedChecksum) {
     Serial.println("Checksum OK");
+    Spark.publish("Checksum", "OK");
   } else {
     Serial.println("Checksum not OK!");
+    Spark.publish("Checksum", "Not OK");
   }
 }


- comment out unused characteristics

- comment out unused characteristics

--- examples/ancs/ancs.ino
+++ examples/ancs/ancs.ino
@@ -18,8 +18,8 @@

 // remote characteristics
 BLERemoteCharacteristic          ancsNotificationSourceCharacteristic     = BLERemoteCharacteristic("9fbf120d630142d98c5825e699a21dbd", BLENotify);
-BLERemoteCharacteristic          ancsControlPointCharacteristic           = BLERemoteCharacteristic("69d1d8f345e149a898219bbdfdaad9d9", BLEWrite);
-BLERemoteCharacteristic          ancsDataSourceCharacteristic             = BLERemoteCharacteristic("22eac6e924d64bb5be44b36ace7c7bfb", BLENotify);
+//BLERemoteCharacteristic          ancsControlPointCharacteristic           = BLERemoteCharacteristic("69d1d8f345e149a898219bbdfdaad9d9", BLEWrite);
+//BLERemoteCharacteristic          ancsDataSourceCharacteristic             = BLERemoteCharacteristic("22eac6e924d64bb5be44b36ace7c7bfb", BLENotify);

 void setup() {
@@ -42,8 +42,8 @@

   blePeripheral.addRemoteAttribute(ancsService);
   blePeripheral.addRemoteAttribute(ancsNotificationSourceCharacteristic);
-  blePeripheral.addRemoteAttribute(ancsControlPointCharacteristic);
-  blePeripheral.addRemoteAttribute(ancsDataSourceCharacteristic);
+//  blePeripheral.addRemoteAttribute(ancsControlPointCharacteristic);
+//  blePeripheral.addRemoteAttribute(ancsDataSourceCharacteristic);

   // assign event handlers for connected, disconnected to peripheral
   blePeripheral.setEventHandler(BLEConnected, blePeripheralConnectHandler);
@@ -53,7 +53,7 @@

   // assign event handlers for characteristic
   ancsNotificationSourceCharacteristic.setEventHandler(BLEValueUpdated, ancsNotificationSourceCharacteristicValueUpdated);
-  ancsDataSourceCharacteristic.setEventHandler(BLEValueUpdated, ancsDataSourceCharacteristicCharacteristicValueUpdated);
+//  ancsDataSourceCharacteristic.setEventHandler(BLEValueUpdated, ancsDataSourceCharacteristicCharacteristicValueUpdated);

   // begin initialization
   blePeripheral.begin();
@@ -92,7 +92,7 @@
   Serial.print(F("Remote services discovered event, central: "));
   Serial.println(central.address());

-  if (ancsNotificationSourceCharacteristic.canSubscribe()) {
+  if (ancsNotificationSourceCharacteristic.canSubscribe()) {
     ancsNotificationSourceCharacteristic.subscribe();
   }
 }
@@ -153,9 +153,9 @@
 //  BLEUtil::printBuffer(characteristic.value(), characteristic.valueLength());
 }

-void ancsDataSourceCharacteristicCharacteristicValueUpdated(BLECentral& central, BLERemoteCharacteristic& characteristic) {
-  Serial.print(F("ANCS Data Source Value Updated: "));
+//void ancsDataSourceCharacteristicCharacteristicValueUpdated(BLECentral& central, BLERemoteCharacteristic& characteristic) {
+//  Serial.print(F("ANCS Data Source Value Updated: "));
+//
+//  BLEUtil::printBuffer(characteristic.value(), characteristic.valueLength());
+//}

-  BLEUtil::printBuffer(characteristic.value(), characteristic.valueLength());
-}
-


Update to latest arduino libs

Update to latest arduino libs

--- examples/bandwidth_fritz/bandwidth_fritz.ino
+++ examples/bandwidth_fritz/bandwidth_fritz.ino
@@ -31,8 +31,17 @@
 *
 */

+#include "Arduino.h"
 #include <SoftwareSerial.h>
 #include "WiFlyHQ.h"
+
+bool getBandwidth(uint32_t *rxRate, uint32_t *txRate, char *date, int dateSize);
+bool sendSoapReq(
+    const char *host,
+    uint16_t port,
+    const __FlashStringHelper *path,
+    const __FlashStringHelper *action,
+    const __FlashStringHelper *xmlreq);

 SoftwareSerial wiflySerial(8,9);
 WiFly wifly;
@@ -100,21 +109,23 @@
 // Get the current tx and rx bandwidth from the fritzbox router
 bool getBandwidth(uint32_t *rxRate, uint32_t *txRate, char *date, int dateSize)
 {
-    if (!sendSoapReq("192.168.1.1", 49000, F("/upnp/control/WANIPConn1"),
-	F("urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1#GetAddonInfos"),
-	F("<?xml version=\"1.0\" encodin=\"utf-8\"?>\n"
-	  "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" "
-	  "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
-	  "<s:Body>\n"
-	  "<u:GetAddonInfos xmlns:u=\"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1\" />\n"
-	  "</s:Body>\n</s:Envelope>"))) {
+    const __FlashStringHelper *path =  F("/upnp/control/WANIPConn1");
+    const __FlashStringHelper *action =  F("urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1#GetAddonInfos");
+    const __FlashStringHelper *xmlreq =  F("<?xml version=\"1.0\" encodin=\"utf-8\"?>\n"\
+	  "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" "\
+	  "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"\
+	  "<s:Body>\n"\
+	  "<u:GetAddonInfos xmlns:u=\"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1\" />\n"\
+	  "</s:Body>\n</s:Envelope>");
+
+    if (!sendSoapReq("192.168.1.1", 49000, path, action, xmlreq)) {
 	return false;
     }

     uint32_t now=millis();

     if (date != NULL) {
-	if (!wifly.match(F("DATE: "),5000)) {
+	if (!wifly.match_P(F("DATE: "),5000)) {
 	    Serial.println(F("failed to find DATE:"));
 	    return false;
 	}
@@ -125,14 +136,14 @@
 	wifly.gets(date, dateSize);
     }

-    if (!wifly.match(F("<NewByteSendRate>"))) {
+    if (!wifly.match_P(F("<NewByteSendRate>"))) {
         Serial.println(F("failed to find NewByteSendRate"));
 	return false;
     }

     *txRate = wifly.parseInt();

-    if (!wifly.match(F("<NewByteReceiveRate>"))) {
+    if (!wifly.match_P(F("<NewByteReceiveRate>"))) {
         Serial.println(F("failed to find NewByteReceiveRate"));
 	return false;
     }
@@ -146,7 +157,7 @@

 // Send a SOAP request
 bool sendSoapReq(
-    char *host,
+    const char *host,
     uint16_t port,
     const __FlashStringHelper *path,
     const __FlashStringHelper *action,
@@ -170,11 +181,13 @@
 	wifly.println('"');
 	wifly.println(F("Content-Type: text/xml; charset=\"utf-8\""));
 	wifly.print(F("Content-Length: "));
-	wifly.println(strlen_P((const prog_char *)xmlreq));
+	wifly.println(strlen_P((const char *)xmlreq));
 	wifly.println();
 	wifly.println(xmlreq);
 	wifly.println();
     } else {
         Serial.println(F("Failed to connect"));
+        return false;
     }
+    return true;
 }


Send JSON message instead of just a number

--- bottleopener/bottleopener.ino
+++ bottleopener/bottleopener.ino
@@ -57,8 +57,8 @@
    Send the counter to the IoT platforms
 */
 void sendCounter() {
-  thingspeakSender.sendCounter(counter);
-  shiftrConnector.sendCounter(counter);
+  thingspeakSender.sendMessage("Gwen", counter);
+  shiftrConnector.sendMessage("Gwen", counter);
 }

 /**


Initialize serial bus for debug logging

Initialize serial bus for debug logging

--- Pingduino/Pingduino.ino
+++ Pingduino/Pingduino.ino
@@ -135,6 +135,8 @@

 void setup()
 {
+  Serial.begin(9600);
+
   // Interrupts for scoring buttons
   attachInterrupt(P1PIN, p1ButtonPressed, CHANGE);
   attachInterrupt(P2PIN, p2ButtonPressed, CHANGE);


added method to write changes to torquers

--- WatSat_arduino_code.ino
+++ WatSat_arduino_code.ino
@@ -5,17 +5,23 @@
 low pwm means high voltage
 */

-//All code is using variables, which can change
-//Figure out how data for magnetometers have to be handled (photodiodes and temp are just default
+int NUM_BOARDS = 6;

-int NUM_BOARDS = 6;
+// output pins for controlling the mux
 int control0 = 2;
 int control1 = 3;
 int control2 = 4;
 int control3 = 5;

+// input pins for reading the mux
 int in0 = 0;
 int in1 = 1;
+
+// output pins for controlling the magnetorquers
+int torx = 6;
+int tory = 7;
+int torz = 8;
+int torred = 9;

 SBoard boards[6];
 Data d0;
@@ -30,6 +36,14 @@
   pinMode(control1, OUTPUT);
   pinMode(control2, OUTPUT);
   pinMode(control3, OUTPUT);
+
+  pinMode(in0, INPUT);
+  pinMode(in1, INPUT);
+
+  pinMode(torx, OUTPUT);
+  pinMode(tory, OUTPUT);
+  pinMode(torz, OUTPUT);
+  pinMode(torred, OUTPUT);

   Serial.println("Started serial");
   init_stuff();
@@ -58,8 +72,8 @@
   For example, will post the voltage required to apply to magentorquers
   */
   delay(100);
-  float a = Serial.parseFloat()
-  Serial.println(a);
+  float a = Serial.parseFloat();
+  adjust(a);
 }

 void getRequest(){
@@ -97,6 +111,7 @@
 }

 void readall(){
+  // SOLDERING NOTE: MAKE SURE TO LINE UP OUTPUTS!!
   for (int i=0; i<(NUM_BOARDS/2); i++){
     master[i] = boards[i].readData(in0);
     master[i+1] = boards[i+1].readData(in1);
@@ -117,3 +132,23 @@
   Serial.print("\n");
 }

+void adjust(float mag){
+ /* the value of mag will depend on the voltage required to be applied to the
+    magnetorquers.
+      torquer | key
+      --------+--------
+        x     | mag
+        y     | mag + 100
+        z     | mag + 200
+       red    | mag + 300
+  */
+  if (mag >= 300){
+    analogWrite(torred, (mag-300));
+  }else if (mag >= 200){
+    analogWrite(torz, (mag-200));
+  }else if (mag >= 100){
+    analogWrite(tory, (mag-100));
+  }else{
+    analogWrite(torx, mag);
+  }
+}


Im very commited to this project

Im very commited to this project

--- xBeeMegaRobot_func/xBeeMegaRobot_func.ino
+++ xBeeMegaRobot_func/xBeeMegaRobot_func.ino
@@ -31,7 +31,14 @@
 }*/

 int tempPk[24] = {};
-
+int x, y, z, emg1, emg2;
+for(int a = 13; a < 22; a++) {
+  x = tempPk[14] + (tempPk[13] << 8);
+  y = tempPk[16] + (tempPk[15] << 8);
+  z = tempPk[18] + (tempPk[17] << 8);
+  emg1 = tempPk[20] + (tempPk[19] << 8);
+  emg2 = tempPk[22] + (tempPk[21] << 8);
+}
 void setup() {
   Serial2.begin(SERVO_BAUDRATE);
   Serial1.begin(xBee_Baudrate);
@@ -76,8 +83,6 @@
 float rate;
 */
 }
-int x, y, z, emg1, emg2;
-int tempPk[13,14] = x;

 void loop() {
   for(int i = 0; i < 50; i++){


Stash

Stash

--- mouse_rat.ino
+++ mouse_rat.ino
@@ -38,58 +38,55 @@
 float xNormal = -3.0;
 float yNormal = 1;

-/**************************************************************************/
-/*
-    Displays some basic information on this sensor from the unified
-    sensor API sensor_t type (see Adafruit_Sensor for more information)
-*/
-/**************************************************************************/
+float xRange[2] = [0,0]
+float yRange[2] = [0,0]
+
 void displaySensorDetails(void) {
   sensor_t accel, mag, gyro, temp;

   lsm.getSensor(&accel, &mag, &gyro, &temp);

-//  Serial.println(F("------------------------------------"));
-//  Serial.print  (F("Sensor:       ")); Serial.println(accel.name);
-//  Serial.print  (F("Driver Ver:   ")); Serial.println(accel.version);
-//  Serial.print  (F("Unique ID:    ")); Serial.println(accel.sensor_id);
-//  Serial.print  (F("Max Value:    ")); Serial.print(accel.max_value); Serial.println(F(" m/s^2"));
-//  Serial.print  (F("Min Value:    ")); Serial.print(accel.min_value); Serial.println(F(" m/s^2"));
-//  Serial.print  (F("Resolution:   ")); Serial.print(accel.resolution); Serial.println(F(" m/s^2"));
-//  Serial.println(F("------------------------------------"));
-//  Serial.println(F(""));
-//
-//  Serial.println(F("------------------------------------"));
-//  Serial.print  (F("Sensor:       ")); Serial.println(mag.name);
-//  Serial.print  (F("Driver Ver:   ")); Serial.println(mag.version);
-//  Serial.print  (F("Unique ID:    ")); Serial.println(mag.sensor_id);
-//  Serial.print  (F("Max Value:    ")); Serial.print(mag.max_value); Serial.println(F(" uT"));
-//  Serial.print  (F("Min Value:    ")); Serial.print(mag.min_value); Serial.println(F(" uT"));
-//  Serial.print  (F("Resolution:   ")); Serial.print(mag.resolution); Serial.println(F(" uT"));
-//  Serial.println(F("------------------------------------"));
-//  Serial.println(F(""));
-//
-//  Serial.println(F("------------------------------------"));
-//  Serial.print  (F("Sensor:       ")); Serial.println(gyro.name);
-//  Serial.print  (F("Driver Ver:   ")); Serial.println(gyro.version);
-//  Serial.print  (F("Unique ID:    ")); Serial.println(gyro.sensor_id);
-//  Serial.print  (F("Max Value:    ")); Serial.print(gyro.max_value); Serial.println(F(" rad/s"));
-//  Serial.print  (F("Min Value:    ")); Serial.print(gyro.min_value); Serial.println(F(" rad/s"));
-//  Serial.print  (F("Resolution:   ")); Serial.print(gyro.resolution); Serial.println(F(" rad/s"));
-//  Serial.println(F("------------------------------------"));
-//  Serial.println(F(""));
-//
-//  Serial.println(F("------------------------------------"));
-//  Serial.print  (F("Sensor:       ")); Serial.println(temp.name);
-//  Serial.print  (F("Driver Ver:   ")); Serial.println(temp.version);
-//  Serial.print  (F("Unique ID:    ")); Serial.println(temp.sensor_id);
-//  Serial.print  (F("Max Value:    ")); Serial.print(temp.max_value); Serial.println(F(" C"));
-//  Serial.print  (F("Min Value:    ")); Serial.print(temp.min_value); Serial.println(F(" C"));
-//  Serial.print  (F("Resolution:   ")); Serial.print(temp.resolution); Serial.println(F(" C"));
-//  Serial.println(F("------------------------------------"));
-//  Serial.println(F(""));
-//
-//  delay(500);
+  Serial.println(F("------------------------------------"));
+  Serial.print  (F("Sensor:       ")); Serial.println(accel.name);
+  Serial.print  (F("Driver Ver:   ")); Serial.println(accel.version);
+  Serial.print  (F("Unique ID:    ")); Serial.println(accel.sensor_id);
+  Serial.print  (F("Max Value:    ")); Serial.print(accel.max_value); Serial.println(F(" m/s^2"));
+  Serial.print  (F("Min Value:    ")); Serial.print(accel.min_value); Serial.println(F(" m/s^2"));
+  Serial.print  (F("Resolution:   ")); Serial.print(accel.resolution); Serial.println(F(" m/s^2"));
+  Serial.println(F("------------------------------------"));
+  Serial.println(F(""));
+
+  Serial.println(F("------------------------------------"));
+  Serial.print  (F("Sensor:       ")); Serial.println(mag.name);
+  Serial.print  (F("Driver Ver:   ")); Serial.println(mag.version);
+  Serial.print  (F("Unique ID:    ")); Serial.println(mag.sensor_id);
+  Serial.print  (F("Max Value:    ")); Serial.print(mag.max_value); Serial.println(F(" uT"));
+  Serial.print  (F("Min Value:    ")); Serial.print(mag.min_value); Serial.println(F(" uT"));
+  Serial.print  (F("Resolution:   ")); Serial.print(mag.resolution); Serial.println(F(" uT"));
+  Serial.println(F("------------------------------------"));
+  Serial.println(F(""));
+
+  Serial.println(F("------------------------------------"));
+  Serial.print  (F("Sensor:       ")); Serial.println(gyro.name);
+  Serial.print  (F("Driver Ver:   ")); Serial.println(gyro.version);
+  Serial.print  (F("Unique ID:    ")); Serial.println(gyro.sensor_id);
+  Serial.print  (F("Max Value:    ")); Serial.print(gyro.max_value); Serial.println(F(" rad/s"));
+  Serial.print  (F("Min Value:    ")); Serial.print(gyro.min_value); Serial.println(F(" rad/s"));
+  Serial.print  (F("Resolution:   ")); Serial.print(gyro.resolution); Serial.println(F(" rad/s"));
+  Serial.println(F("------------------------------------"));
+  Serial.println(F(""));
+
+  Serial.println(F("------------------------------------"));
+  Serial.print  (F("Sensor:       ")); Serial.println(temp.name);
+  Serial.print  (F("Driver Ver:   ")); Serial.println(temp.version);
+  Serial.print  (F("Unique ID:    ")); Serial.println(temp.sensor_id);
+  Serial.print  (F("Max Value:    ")); Serial.print(temp.max_value); Serial.println(F(" C"));
+  Serial.print  (F("Min Value:    ")); Serial.print(temp.min_value); Serial.println(F(" C"));
+  Serial.print  (F("Resolution:   ")); Serial.print(temp.resolution); Serial.println(F(" C"));
+  Serial.println(F("------------------------------------"));
+  Serial.println(F(""));
+
+  delay(500);
 }

 /**************************************************************************/
@@ -123,46 +120,20 @@
 */
 /**************************************************************************/
 void setup(void) {
-//  while (!Serial);  // wait for flora/leonardo
-//
-//  Serial.begin(9600);
-//  Serial.println(F("LSM9DS0 9DOF Sensor Test")); Serial.println("");
+  Serial.begin(9600);

   /* Initialise the sensor */
-  if(!lsm.begin())
-  {
-    /* There was a problem detecting the LSM9DS0 ... check your connections */
-//    Serial.print(F("Ooops, no LSM9DS0 detected ... Check your wiring or I2C ADDR!"));
-    while(1);
-  }
-//  Serial.println(F("Found LSM9DS0 9DOF"));
-
-  /* Display some basic information on this sensor */
-  displaySensorDetails();
+  if(!lsm.begin()) { while(1); }

   /* Setup the sensor gain and integration time */
   configureSensor();
-
-  /* We're ready to go! */
-//  Serial.println("");
 }

-/**************************************************************************/
-/*
-    Arduino loop function, called once 'setup' is complete (your own code
-    should go here)
-*/
-/**************************************************************************/
 void loop(void) {
   /* Get a new sensor event */
   sensors_event_t accel, mag, gyro, temp;

   lsm.getEvent(&accel, &mag, &gyro, &temp);
-
-  // print out accelleration data
-//  Serial.print("Accel X: "); Serial.print(accel.acceleration.x); Serial.print(" ");
-//  Serial.print("  \tY: "); Serial.print(accel.acceleration.y);       Serial.print(" ");
-//  Serial.print("  \tZ: "); Serial.print(accel.acceleration.z);     Serial.println("  \tm/s^2");

   float mx, my = 0.0;

@@ -175,22 +146,32 @@
     mx = map(accel.acceleration.y - yNormal, -20, 20, 200, -200);
   }

+  calibrate(accel.acceleration.x, accel.acceleration.y);
+
   Mouse.move(mx, my, 0);

-//  // print out magnetometer data
+  // print out accelleration data
+//  Serial.print("Accel X: "); Serial.print(accel.acceleration.x); Serial.print(" ");
+//  Serial.print("  \tY: "); Serial.print(accel.acceleration.y);   Serial.print(" ");
+//  Serial.print("  \tZ: "); Serial.print(accel.acceleration.z);   Serial.println("  \tm/s^2");
 //  Serial.print("Magn. X: "); Serial.print(mag.magnetic.x); Serial.print(" ");
 //  Serial.print("  \tY: "); Serial.print(mag.magnetic.y);       Serial.print(" ");
 //  Serial.print("  \tZ: "); Serial.print(mag.magnetic.z);     Serial.println("  \tgauss");
-//
-//  // print out gyroscopic data
 //  Serial.print("Gyro  X: "); Serial.print(gyro.gyro.x); Serial.print(" ");
 //  Serial.print("  \tY: "); Serial.print(gyro.gyro.y);       Serial.print(" ");
 //  Serial.print("  \tZ: "); Serial.print(gyro.gyro.z);     Serial.println("  \tdps");
-
-  // print out temperature data
 //  Serial.print("Temp: "); Serial.print(temp.temperature); Serial.println(" *C");
-//
-//  Serial.println("**********************\n");

   delay(16);
 }
+
+void calibrate(float x, float y) {
+   xRange[0] = min(xRange[0], x);
+   xRange[1] = max(xRange[1], x);
+
+   yRange[0] = min(yRange[0], y);
+   yRange[1] = max(yRange[1], y);
+
+   Serial.print(xRange[0]); Serial.print(", "); Serial.println(xRange[1]);
+   Serial.print(yRange[0]); Serial.print(", "); Serial.println(yRange[1]);
+ }


Contribution from Doug Hilton.  Complete rewrite of data processing from lidar including crc error checking.

--- XV_Lidar_Controller.ino
+++ XV_Lidar_Controller.ino
@@ -5,6 +5,8 @@
  https://github.com/getSurreal/XV_Lidar_Controller
  http://www.getsurreal.com/products/xv-lidar-controller

+ Modified to add CRC checking - Doug Hilton, WD0UG November, 2015 mailto: six.speed (at) yahoo (dot) com
+
  See README for additional information

  The F() macro in the Serial statements tells the compiler to keep your strings in PROGMEM
@@ -15,6 +17,8 @@
 #include <EEPROM.h>
 #include "EEPROMAnything.h"
 #include <SerialCommand.h>
+
+const int SHOW_ALL_ANGLES = 360;                                // value means 'display all angle data, 0..359'

 struct EEPROM_Config {
   byte id;
@@ -53,47 +57,61 @@
 unsigned long curMillis;
 unsigned long lastMillis = millis();

+// Added by DSH
+const unsigned char COMMAND = 0xFA;        // Start of new packet
+const int INDEX_LO = 0xA0;                 // lowest index value
+const int INDEX_HI = 0xF9;                 // highest index value
+const int PACKET_LENGTH = 22;              // length of a complete packet
+int Packet[PACKET_LENGTH];                 // an input packet
+int ixPacket = 0;                          // index into 'Packet' array
+const int N_DATA_QUADS = 4;                // there are 4 groups of data elements
+const int N_ELEMENTS_PER_QUAD = 4;         // viz., 0=distance LSB; 1=distance MSB; 2=sig LSB; 3=sig MSB
+// Offsets to bytes within 'Packet'
+const int OFFSET_TO_INDEX = 1;
+const int OFFSET_TO_SPEED_LSB = OFFSET_TO_INDEX + 1;
+const int OFFSET_TO_SPEED_MSB = OFFSET_TO_SPEED_LSB + 1;
+const int OFFSET_TO_4_DATA_READINGS = OFFSET_TO_SPEED_MSB + 1;
+const int OFFSET_TO_CRC_L = PACKET_LENGTH - 2;
+const int OFFSET_TO_CRC_M = PACKET_LENGTH - 1;
+// Offsets to the (4) elements of each of the (4) data quads
+const int OFFSET_DATA_DISTANCE_LSB = 0;
+const int OFFSET_DATA_DISTANCE_MSB = OFFSET_DATA_DISTANCE_LSB + 1;
+const int OFFSET_DATA_SIGNAL_LSB = OFFSET_DATA_DISTANCE_MSB + 1;
+const int OFFSET_DATA_SIGNAL_MSB = OFFSET_DATA_SIGNAL_LSB + 1;
+
+const byte eState_Find_COMMAND = 0;                        // 1st state: find 0xFA (COMMAND) in input stream
+const byte eState_Build_Packet = eState_Find_COMMAND + 1;  // 2nd state: build the packet
+int eState = eState_Find_COMMAND;
 PID rpmPID(&motor_rpm, &pwm_val, &xv_config.rpm_setpoint, xv_config.Kp, xv_config.Ki, xv_config.Kd, DIRECT);

 uint8_t inByte = 0;  // incoming serial byte
-uint16_t data_status = 0;
-uint16_t data_4deg_index = 0;
-uint16_t data_loop_index = 0;
+//uint16_t data_status = 0;
+//uint16_t data_4deg_index = 0;
+//uint16_t data_loop_index = 0;
 uint8_t motor_rph_high_byte = 0;
 uint8_t motor_rph_low_byte = 0;
-uint8_t data0, data2;
-uint16_t dist, quality;
+//uint8_t data0, data2;
+uint16_t dist[N_DATA_QUADS] = {0,0,0,0};      // thre are (4) distances, one for each data quad
+uint16_t quality[N_DATA_QUADS] = {0,0,0,0};   // same with 'quality'
 uint16_t motor_rph = 0;
-uint16_t angle;
+uint16_t startingAngle = 0;                   // the first scan angle (of group of 4, based on 'index'), in degrees (0..359)

 SerialCommand sCmd;

-
-  #if defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)  // if Teensy 2.0
-  const int ledPin = 11;
-  #endif
-
-  #if defined(__MK20DX256__)  // if Teensy 3.1
-  const int ledPin = 13;
-  #endif
+const int ledPin = 11;
 boolean ledState = LOW;

+// initialization (before 'loop')
 void setup() {
   EEPROM_readAnything(0, xv_config);
   if( xv_config.id != EEPROM_ID) { // verify EEPROM values have been initialized
     initEEPROM();
   }
   pinMode(xv_config.motor_pwm_pin, OUTPUT);
-  Serial.begin(115200);  // USB serial
-  #if defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY) // if Teensy 2.0
-  Serial1.begin(115200);  // XV LDS data
-  #endif
-
-  #if defined(__MK20DX256__) // if Teensy 3.1
-  Serial1.begin(115200);  // XV LDS data
-  #endif
-
-  Timer3.initialize(30); // set PWM frequency to 32.768kHz
+  Serial.begin(115200);                            // USB serial
+  Serial1.begin(115200);                           // XV LDS data
+
+  Timer3.initialize(30);                           // set PWM frequency to 32.768kHz

   rpmPID.SetOutputLimits(xv_config.pwm_min,xv_config.pwm_max);
   rpmPID.SetSampleTime(xv_config.sample_time);
@@ -102,21 +120,70 @@

   initSerialCommands();
   pinMode(ledPin, OUTPUT);
-}
-
+
+  eState = eState_Find_COMMAND;
+  for (ixPacket = 0; ixPacket < PACKET_LENGTH; ixPacket++)  // Initialize
+    Packet[ixPacket] = 0;
+  ixPacket = 0;
+}
+// Main loop (forever)
 void loop() {
-
+  boolean bPacketOkay;                            // true = packet is okay (CRC valid)
   sCmd.readSerial();  // check for incoming serial commands
-
-  // read byte from LIDAR and relay to USB
-  if (Serial1.available() > 0) {
-    inByte = Serial1.read();  // get incoming byte:
-    if (xv_config.raw_data) {
-      Serial.print(inByte, BYTE);  // relay
+  if (Serial1.available() > 0) {                  // read byte from LIDAR and relay to USB
+    inByte = Serial1.read();                      // get incoming byte:
+    if (xv_config.raw_data)
+      Serial.print(inByte, BYTE);                 // relay
+    // Switch, based on 'eState':
+    // State 1: We're scanning for 0xFA (COMMAND) in the input stream
+    // State 2: Build a complete data packet
+    if (eState == eState_Find_COMMAND) {          // flush input until we get COMMAND byte
+      if(inByte == COMMAND) {
+        eState++;                                 // switch to 'build a packet' state
+        Packet[ixPacket++] = inByte;              // store 1st byte of data into 'Packet'
+      }
     }
-    decodeData(inByte);
-  }
-
+    else {                                        // eState == eState_Build_Packet
+      Packet[ixPacket++] = inByte;                // keep storing input into 'Packet'
+      if (ixPacket == PACKET_LENGTH) {            // we've got all the input bytes, so we're done building this packet
+        bPacketOkay = (eValidatePacket() == 0);   // Check packet CRC
+        startingAngle = processIndex(bPacketOkay);   // get the starting angle of this group (of 4)
+        processSpeed(bPacketOkay);                // process the speed
+        // process each of the (4) sets of data in the packet
+        for (int ix = 0; ix < N_DATA_QUADS; ix++) // process the distance
+          processDistance(bPacketOkay, ix);
+        for (int ix = 0; ix < N_DATA_QUADS; ix++) // process the signal strength (quality)
+          processSignalStrength(bPacketOkay, ix);
+        if (bPacketOkay) {
+          if (xv_config.show_dist) {              // show distance command is active
+            if (xv_config.show_angle == SHOW_ALL_ANGLES
+            || (xv_config.show_angle >= startingAngle && xv_config.show_angle < startingAngle + N_DATA_QUADS)) {
+              for (int ix = 0; ix < N_DATA_QUADS; ix++) {
+                if ((xv_config.show_angle == SHOW_ALL_ANGLES)
+                || (xv_config.show_angle == startingAngle + ix)) {
+                  Serial.print(startingAngle + ix);
+                  Serial.print(F(": "));
+                  Serial.print(int(dist[ix]));
+                  Serial.print(F(" ("));
+                  Serial.print(quality[ix]);
+                  Serial.println(F(")"));
+                }
+              }  // or (int ix = 0; ix < N_DATA_QUADS; ix++)
+            }  // if (xv_config.show_angle == SHOW_ALL_ANGLES ...
+          }  // if (xv_config.show_dist)
+        }  // if (bPacketOkay)
+        // initialize a bunch of stuff before we switch back to State 1
+        for (int ix = 0; ix < N_DATA_QUADS; ix++) {
+          dist[ix] = 0;
+          quality[ix] = 0;
+        }
+        for (ixPacket = 0; ixPacket < PACKET_LENGTH; ixPacket++)  // clear out this packet
+          Packet[ixPacket] = 0;
+        ixPacket = 0;
+        eState = eState_Find_COMMAND;                // This packet is done -- look for next COMMAND byte
+      }  // if (ixPacket == PACKET_LENGTH)
+    }  // if (eState == eState_Find_COMMAND)
+  }  // if (Serial1.available() > 0)
   if (xv_config.motor_enable) {
     rpmPID.Compute();
     if (pwm_val != pwm_last) {
@@ -124,55 +191,29 @@
       pwm_last = pwm_val;
     }
     motorCheck();
-  }
-}
-
-void decodeData(unsigned char inByte) {
-  switch (data_status) {
-  case 0: // no header
-    if (inByte == 0xFA) {
-      data_status = 1;
-      data_loop_index = 1;
-    }
-    break;
-
-  case 1: // find 2nd FA
-    if (data_loop_index == 22) { // Theres 22 bytes in each packet. Time to start over
-      if (inByte == 0xFA) {
-        data_status = 2;
-        data_loop_index = 1;
-      }
-      else { // if not FA search again
-        data_status = 0;
-      }
-    }
-    else {
-      data_loop_index++;
-    }
-    break;
-
-  case 2: // read data out
-    if (data_loop_index == 22) { // Theres 22 bytes in each packet. Time to start over
-      if (inByte == 0xFA) {
-        data_loop_index = 1;
-      }
-      else { // if not FA search again
-        data_status = 0;
-      }
-    }
-    else {
-      readData(inByte);
-      data_loop_index++;
-    }
-    break;
-  }
-
-}
-void readData(unsigned char inByte) {
-  switch (data_loop_index) {
-  case 1: // 4 degree index
-    data_4deg_index = inByte - 0xA0;
-    angle = data_4deg_index * 4;  // 1st angle in the set of 4
+  }  // if (xv_config.motor_enable)
+}  // loop
+/*
+ * processIndex - Process the packet element 'index'
+ * index is the index byte in the 90 packets, going from A0 (packet 0, readings 0 to 3) to F9
+ *    (packet 89, readings 356 to 359).
+ * Enter with: bValidData = true if packet is okay (good CRC)
+ * Uses:       Packet
+ *             ledState gets toggled if angle = 0
+ *             ledPin = which pin the LED is connected to
+ *             ledState = LED on or off
+ *             xv_config.show_dist = true if we're supposed to show distance
+ *             curMillis = milliseconds, now
+ *             lastMillis = milliseconds, last time through this subroutine
+ * Calls:      digitalWrite() - used to toggle LED pin
+ *             Serial.print
+ * Returns:    The first angle (of 4) in the current 'index' group
+ */
+uint16_t processIndex(boolean bValidData) {
+  uint16_t angle = 0;
+  if (bValidData) {
+    uint16_t data_4deg_index = Packet[OFFSET_TO_INDEX] - INDEX_LO;
+    angle = data_4deg_index * N_DATA_QUADS;     // 1st angle in the set of 4
     if (angle == 0) {
       if (ledState) {
         ledState = LOW;
@@ -183,163 +224,132 @@
       digitalWrite(ledPin, ledState);
       if (xv_config.show_dist) {
         curMillis = millis();
-        Serial.print(F("Time Interval: "));
-        Serial.println(curMillis - lastMillis);
+        if(xv_config.show_angle == SHOW_ALL_ANGLES) {
+          /*
+          Serial.print(F("Time Interval: "));
+          Serial.println(curMillis - lastMillis);
+          */
+        }
         lastMillis = curMillis;
       }
-    }
-    //Serial.print(int(data_4deg_index));
-    //Serial.println(F(" "));
-    break;
-
-  case 2: // speed in RPH low byte
-    motor_rph_low_byte = inByte;
-    break;
-
-  case 3: // speed in RPH high byte
-    motor_rph_high_byte = inByte;
+    } // if (angle == 0)
+  }  // if (bValidData)
+  return angle;
+}
+/*
+ * processSpeed- Process the packet element 'speed'
+ * speed is two-bytes of information, little-endian. It represents the speed, in 64th of RPM (aka value
+ *    in RPM represented in fixed point, with 6 bits used for the decimal part).
+ * Enter with: bValidData = true if packet is okay (good CRC)
+ * Uses:       Packet
+ *             angle = if 0 then enable display of RPM and PWM
+ *             xv_config.show_rpm = true if we're supposed to display RPM and PWM
+ * Calls:      Serial.print
+ */
+void processSpeed(boolean bValidData) {
+  if (bValidData) {
+    motor_rph_low_byte = Packet[OFFSET_TO_SPEED_LSB];
+    motor_rph_high_byte = Packet[OFFSET_TO_SPEED_MSB];
     motor_rph = (motor_rph_high_byte << 8) | motor_rph_low_byte;
     motor_rpm = float( (motor_rph_high_byte << 8) | motor_rph_low_byte ) / 64.0;
-    if (xv_config.show_rpm and angle == 0) {
+    if (xv_config.show_rpm and startingAngle == 0) {
       Serial.print(F("RPM: "));
       Serial.print(motor_rpm);
       Serial.print(F("  PWM: "));
       Serial.println(pwm_val);
     }
-    break;
-
-  case 4:
-    data0 = inByte; // first half of distance data
-    break;
-
-  case 5:
-    if ((inByte & 0x80) >> 7) {  // check for Invalid Flag
-      dist = 0;
-    }
-    else {
-      dist =  data0 | (( inByte & 0x3F) << 8);
-    }
-    break;
-
-  case 6:
-    data2 = inByte; // first half of quality data
-    break;
-
-  case 7:
-    quality = (inByte << 8) | data2;
-    if (xv_config.show_dist) {
-      if (xv_config.show_angle == 360 or xv_config.show_angle == angle) {
-        Serial.print(angle);
-        Serial.print(F(": "));
-        Serial.print(int(dist));
-        Serial.print(F(" ("));
-        Serial.print(quality);
-        Serial.println(F(")"));
-      }
-    }
-    break;
-
-  case 8:
-    angle = data_4deg_index * 4 + 1; // 2nd angle in the set
-    data0 = inByte;
-    break;
-
-  case 9:
-    if ((inByte & 0x80) >> 7) {  // check for Invalid Flag
-      dist = 0;
-    }
-    else {
-      dist =  data0 | (( inByte & 0x3F) << 8);
-    }
-    break;
-
-  case 10:
-    data2 = inByte; // first half of quality data
-    break;
-
-  case 11:
-    quality = (inByte << 8) | data2;
-    if (xv_config.show_dist) {
-      if (xv_config.show_angle == 360 or xv_config.show_angle == angle) {
-        Serial.print(angle);
-        Serial.print(F(": "));
-        Serial.print(int(dist));
-        Serial.print(F(" ("));
-        Serial.print(quality);
-        Serial.println(F(")"));
-      }
-    }
-    break;
-
-  case 12:
-    angle = data_4deg_index * 4 + 2; // 3rd angle in the set
-    data0 = inByte;
-    break;
-
-  case 13:
-    if ((inByte & 0x80) >> 7) {  // check for Invalid Flag
-      dist = 0;
-    }
-    else {
-      dist =  data0 | (( inByte & 0x3F) << 8);
-    }
-    break;
-
-  case 14:
-    data2 = inByte; // first half of quality data
-    break;
-
-  case 15:
-    quality = (inByte << 8) | data2;
-    if (xv_config.show_dist) {
-      if (xv_config.show_angle == 360 or xv_config.show_angle == angle) {
-        Serial.print(angle);
-        Serial.print(F(": "));
-        Serial.print(int(dist));
-        Serial.print(F(" ("));
-        Serial.print(quality);
-        Serial.println(F(")"));
-      }
-    }
-    break;
-
-  case 16:
-    angle = data_4deg_index * 4 + 3;  // 4th angle in the set
-    data0 = inByte;
-    break;
-
-  case 17:
-    if ((inByte & 0x80) >> 7) {  // check for Invalid Flag
-      dist = 0;
-    }
-    else {
-      dist =  data0 | (( inByte & 0x3F) << 8);
-    }
-    break;
-
-  case 18:
-    data2 = inByte; // first half of quality data
-    break;
-
-  case 19:
-    quality = (inByte << 8) | data2;
-    if (xv_config.show_dist) {
-      if (xv_config.show_angle == 360 or xv_config.show_angle == angle) {
-        Serial.print(angle);
-        Serial.print(F(": "));
-        Serial.print(int(dist));
-        Serial.print(F(" ("));
-        Serial.print(quality);
-        Serial.println(F(")"));
-      }
-    }
-    break;
-
-  default: // others do checksum
-    break;
-  }
-}
-
+  }  // if (bValidData)
+}
+/*
+ * Data 0 to Data 3 are the 4 readings. Each one is 4 bytes long, and organized as follows :
+ *   byte 0 : <distance 7:0>
+ *   byte 1 : <"invalid data" flag> <"strength warning" flag> <distance 13:8>
+ *   byte 2 : <signal strength 7:0>
+ *   byte 3 : <signal strength 15:8>
+ */
+/*
+ * processDistance- Process the packet element 'distance'
+ * Enter with: bValidData = true if packet is okay (good CRC)
+ *             iQuad = which one of the (4) readings to process, value = 0..3
+ * Uses:       Packet
+ *             dist[] = distance to object
+ * Calls:      N/A
+ */
+void processDistance(boolean bValidData, int iQuad) {
+  uint8_t dataL, dataM;
+  dist[iQuad] = 0;                       // initialize
+  if (bValidData) {
+    int iOffset = (iQuad * N_DATA_QUADS) + OFFSET_TO_4_DATA_READINGS + OFFSET_DATA_DISTANCE_LSB;
+    // byte 0 : <distance 7:0>
+    // byte 1 : <"invalid data" flag> <"strength warning" flag> <distance 13:8>
+    dataL = Packet[iOffset];             // first half of distance data
+    dataM = Packet[iOffset + 1];         // get MSB of distance data + flags
+    if ((dataM & 0x80) == 0)             // check for Invalid Flag
+      dist[iQuad] = dataL | ((dataM & 0x3F) << 8);
+  }  // if (bValidData)
+}
+/*
+ * processSignalStrength- Process the packet element 'signal strength'
+ * Enter with: bValidData = true if packet is okay (good CRC)
+ *             iQuad = which one of the (4) readings to process, value = 0..3
+ * Uses:       Packet
+ *             quality[] = signal quality
+ * Calls:      N/A
+ */
+void processSignalStrength(boolean bValidData, int iQuad) {
+  uint8_t dataL, dataM;
+  quality[iQuad] = 0;                        // initialize
+  if (bValidData) {
+    int iOffset = (iQuad * N_DATA_QUADS) + OFFSET_TO_4_DATA_READINGS + OFFSET_DATA_SIGNAL_LSB;
+    dataL = Packet[iOffset];                  // signal strength LSB
+    dataM = Packet[iOffset + 1];
+    quality[iQuad] = dataL | (dataM << 8);
+  }  // if (bValidData)
+}
+
+/*
+ * eValidatePacket - Validate 'Packet'
+ * Enter with: 'Packet' is ready to check
+ * Uses:       CalcCRC
+ * Exits with: 0 = Packet is okay
+ * Error:      non-zero = Packet is no good
+ */
+byte eValidatePacket() {
+  unsigned long chk32;
+  unsigned long checksum;
+  const int bytesToCheck = PACKET_LENGTH - 2;
+  const int CalcCRC_Len = bytesToCheck / 2;
+  unsigned int CalcCRC[CalcCRC_Len];
+
+  byte b1a, b1b, b2a, b2b;
+  int ix;
+
+  for (int ix = 0; ix < CalcCRC_Len; ix++)       // initialize 'CalcCRC' array
+    CalcCRC[ix] = 0;
+
+  // Perform checksum validity test
+  for (ix = 0; ix < bytesToCheck; ix += 2)      // build 'CalcCRC' array
+    CalcCRC[ix / 2] = Packet[ix] + ((Packet[ix + 1]) << 8);
+
+  chk32 = 0;
+  for (ix = 0; ix < CalcCRC_Len; ix++)
+    chk32 = (chk32 << 1) + CalcCRC[ix];
+  checksum = (chk32 & 0x7FFF) + (chk32 >> 15);
+  checksum &= 0x7FFF;
+
+  b1a = checksum & 0xFF;
+  b1b = Packet[OFFSET_TO_CRC_L];
+  b2a = checksum >> 8;
+  b2b = Packet[OFFSET_TO_CRC_M];
+  if ((b1a == b1b) && (b2a == b2b))
+    return 0;                                  // okay
+  else
+    return 1;                                  // non-zero = bad CRC
+}
+
+/*
+ * initEEPROM
+ */
 void initEEPROM() {
   xv_config.id = 0x05;
   strcpy(xv_config.version, "1.2.2");
@@ -359,11 +369,13 @@
   xv_config.raw_data = true;
   xv_config.show_dist = false;
   xv_config.show_rpm = false;
-  xv_config.show_angle = 360;
+  xv_config.show_angle = SHOW_ALL_ANGLES;

   EEPROM_writeAnything(0, xv_config);
 }
-
+/*
+ * initSerialCommands
+ */
 void initSerialCommands() {
   sCmd.addCommand("help",       help);
   sCmd.addCommand("Help",       help);
@@ -382,12 +394,15 @@
   sCmd.addCommand("ShowDist",  showDist);
   sCmd.addCommand("HideDist",  hideDist);
   sCmd.addCommand("ShowAngle",  showAngle);
+  sCmd.addCommand("HideAngle",  hideDist);
   sCmd.addCommand("MotorOff", motorOff);
   sCmd.addCommand("MotorOn",  motorOn);
   sCmd.addCommand("HideRaw", hideRaw);
   sCmd.addCommand("ShowRaw",  showRaw);
 }
-
+/*
+ * showRPM
+ */
 void showRPM() {
   xv_config.show_rpm = true;
   if (xv_config.raw_data == true) {
@@ -397,7 +412,9 @@
   Serial.print(F("Showing RPM data"));
   Serial.println(F(" "));
 }
-
+/*
+ * hideRPM
+ */
 void hideRPM() {
   xv_config.show_rpm = false;
   Serial.println(F(" "));
@@ -411,12 +428,13 @@
     hideRaw();
   }
   Serial.println(F(" "));
-  Serial.print(F("Showing Distance data"));
+  Serial.print(F("Showing Distance data <Angle>: <dist.mm> (quality)}"));
   Serial.println(F(" "));
 }

 void hideDist() {
   xv_config.show_dist = false;
+  xv_config.show_angle = SHOW_ALL_ANGLES;              // set default back to 'show all angles'
   Serial.println(F(" "));
   Serial.print(F("Hiding Distance data"));
   Serial.println(F(" "));
@@ -431,7 +449,7 @@
   arg = sCmd.next();
   if (arg != NULL) {
     sVal = atoi(arg);    // Converts a char string to a int
-    if (sVal < 0 or sVal > 360) {
+    if (sVal < 0 or sVal > SHOW_ALL_ANGLES) {
       syntax_error = true;
     }
   }
@@ -547,12 +565,12 @@
     Serial.println(F(" "));
   }
   else {
+    Serial.print(F("Old RPM setpoint:"));
+    Serial.println(xv_config.rpm_setpoint);
     xv_config.rpm_setpoint = sVal;
-    Serial.println(F(" "));
+    //Serial.println(F(" "));
     Serial.print(F("New RPM setpoint: "));
     Serial.println(sVal);
-    Serial.print(F("Old RPM setpoint"));
-    Serial.println(xv_config.rpm_setpoint);
     Serial.println(F(" "));
   }
 }
@@ -698,7 +716,7 @@

   Serial.print(F("XV Lidar Controller Firmware Version "));
   Serial.println(xv_config.version);
-  Serial.print(F("GetSurreal.com"));
+  Serial.print(F("GetSurreal.com *"));

   Serial.println(F(" "));
   Serial.println(F(" "));
@@ -717,6 +735,7 @@
   Serial.println(F("  ShowDist      - Show the distance data"));
   Serial.println(F("  HideDist      - Hide the distance data"));
   Serial.println(F("  ShowAngle     - Show distance data for a specific angle (0 - 359 or 360 for all)"));
+  Serial.println(F("  HideAngle     - Hide distance data for all angles"));
   Serial.println(F("  MotorOff      - Stop spinning the lidar"));
   Serial.println(F("  MotorOn       - Enable spinning of the lidar"));
   Serial.println(F("  HideRaw       - Stop outputting the raw data from the lidar"));
@@ -781,5 +800,3 @@
   Serial.print(F("Config Saved."));
 }

-
-


Fix typo in comment

Fix typo in comment

Fixing serial typo in a comment

--- XV_Lidar_Controller.ino
+++ XV_Lidar_Controller.ino
@@ -39,7 +39,7 @@
   double Kd;

   boolean motor_enable;  // to spin the laser or not.  No data when not spinning
-  boolean raw_data;  // to retransmit the seiral data to the USB port
+  boolean raw_data;  // to retransmit the serial data to the USB port
   boolean show_dist;  //  controlled by ShowDist and HideDist commands
   boolean show_rpm;  // controlled by ShowRPM and HideRPM commands
   boolean show_interval;  // true = show time interval, once per revolution, at angle=0


Update mdns.ino

Update mdns.ino

--- firmware/examples/mdns.ino
+++ firmware/examples/mdns.ino
@@ -1,5 +1,3 @@
-#include "MDNS.h"
-
 #define HTTP_PORT 80

 MDNS mdns;


Implement solid color mode, and parameter changing through rotary encoder

--- main.ino
+++ main.ino
@@ -6,9 +6,9 @@
 #define ENCODER_OPTIMIZE_INTERRUPTS
 #include <Encoder.h>

-/* Digital output pins. */
-#define PIN_ROTARY_LEFT 2
-#define PIN_ROTARY_RIGHT 3
+/* Digital IO pins. */
+#define PIN_ROTARY_ONE 3
+#define PIN_ROTARY_TWO 2
 #define PIN_BUTTON 4
 #define PIN_LED 6

@@ -16,25 +16,32 @@
 #define NUM_LEDS 60

 /* Rotary encoder object */
-Encoder encoder(PIN_ROTARY_LEFT, PIN_ROTARY_RIGHT);
+Encoder encoder(PIN_ROTARY_ONE, PIN_ROTARY_TWO);

 /* This variable holds the LED color state. */
 CRGB leds[NUM_LEDS];

-/* Define the different variables that can be changed using the rotary wheel. */
-#define VARIABLE_MODE 0
-#define VARIABLE_HUE 1
-#define VARIABLE_SATURATION 2
-#define VARIABLE_VALUE 3
-#define VARIABLE_SPEED 4
-//#define VARIABLE_XXX 5
-//#define VARIABLE_XXX 6
-#define MAX_VARIABLES 7
+/* Define the different parameters that can be changed using the rotary wheel. */
+#define PARAMETER_MODE 0
+#define PARAMETER_HUE 1
+#define PARAMETER_SATURATION 2
+#define PARAMETER_VALUE 3
+#define PARAMETER_SPEED 4
+//#define PARAMETER_XXX 5
+//#define PARAMETER_XXX 6
+#define MAX_PARAMETERS 7

-/* Holds the variable that is currently changed using the rotary wheel. */
-uint8_t activeVariable = 0;
+/* Holds the parameter that is currently changed using the rotary wheel. */
+uint8_t activeParameter = PARAMETER_MODE;

-/* Rainbow colors, used to signify active variable to the user. */
+/* Holds the values of the different parameters. */
+uint8_t parameters[MAX_PARAMETERS] = { 0, 0, 255, 80, 80, 0, 0 };
+
+/* Maximum values of the different parameters, plus one. Zero denotes that a
+ * variable can stretch the full range of 0-255. */
+uint8_t parameterMax[MAX_PARAMETERS] = { 1, 0, 0, 0, 0, 0, 0 };
+
+/* Rainbow colors, used to signify active parameter to the user. */
 CRGB rainbowColors[] = {
     CHSV(0,   255, 255),
     CHSV(36,  255, 255),
@@ -47,10 +54,7 @@

 void setup() {
     FastLED.addLeds<NEOPIXEL, PIN_LED>(leds, NUM_LEDS);
-
-    pinMode(PIN_BUTTON,       INPUT_PULLUP);
-    pinMode(PIN_ROTARY_LEFT,  INPUT_PULLUP);
-    pinMode(PIN_ROTARY_RIGHT, INPUT_PULLUP);
+    pinMode(PIN_BUTTON, INPUT_PULLUP);
 }

 /* buttonPressed returns true if the button is pressed, false otherwise. */
@@ -72,29 +76,48 @@
     return rval;
 }

+/* rotary_delta returns the number of full steps the rotary encoder has changed. */
+int8_t rotary_delta() {
+    int32_t e;
+    int8_t rval = 0;
+
+    e = encoder.read();
+
+    rval = e / 4;
+    e -= (rval * 4);
+
+    encoder.write(e);
+
+    return rval;
+}
+
+void modeSolid() {
+    fill_solid(&leds[0], NUM_LEDS, CHSV(
+        parameters[PARAMETER_HUE],
+        parameters[PARAMETER_SATURATION],
+        parameters[PARAMETER_VALUE]
+    ));
+}
+
 void loop() {
-    int32_t e;

-    if (buttonChanged()) {
-        if (buttonPressed()) {
-            activeVariable = (activeVariable + 1) % MAX_VARIABLES;
-            fill_solid(&leds[0], NUM_LEDS, rainbowColors[activeVariable]);
-        } else {
-            fill_solid(&leds[0], NUM_LEDS, CRGB::Black);
-        }
+    /* Increase active parameter if button is pressed. */
+    if (buttonChanged() && buttonPressed()) {
+        activeParameter = (activeParameter + 1) % MAX_PARAMETERS;
+        fill_solid(&leds[0], NUM_LEDS, rainbowColors[activeParameter]);
+        FastLED.show();
     }

-    e = encoder.read();
-    if (e <= -4) {
-        leds[10] = CHSV(0, 255, 255);
-        e += 4;
-    } else if (e >= 4) {
-        leds[10] = CHSV(120, 255, 255);
-        e -= 4;
-    } else {
-        leds[10] = CRGB::Black;
+    /* Pause all activity while button is held down. */
+    if (buttonPressed()) {
+        return;
     }
-    encoder.write(e);

+    /* Increase or decrease parameter if rotary encoder moved. */
+    parameters[activeParameter] += rotary_delta();
+    parameters[activeParameter] %= parameterMax[activeParameter];
+
+    /* Only one mode for now */
+    modeSolid();
     FastLED.show();
 }


Modify the comments to RAW format

Modify the comments to RAW format

--- ArduCAM/examples/REVC/ArduCAM_MT9M001_Camera_RAW/ArduCAM_MT9M001_Camera_RAW.ino
+++ ArduCAM/examples/REVC/ArduCAM_MT9M001_Camera_RAW/ArduCAM_MT9M001_Camera_RAW.ino
@@ -7,7 +7,7 @@
 // It will turn the ArduCAM into a real digital camera with capture and playback functions.
 //
 // 1. Capture and buffer the image to FIFO when shutter pressed quickly.
-// 2. Store the image to Micro SD/TF card with BMP format.
+// 2. Store the image to Micro SD/TF card with RAW format.
 //
 // This program requires the ArduCAM V3.4.5 (or above) library and Rev.C ArduCAM shield
 // and use Arduino IDE 1.5.8 compiler or above


add step-clock example

add step-clock example


Update ArbitraryCommands.ino

Update ArbitraryCommands.ino

--- examples/ArbitraryCommands/ArbitraryCommands.ino
+++ examples/ArbitraryCommands/ArbitraryCommands.ino
@@ -37,7 +37,7 @@

 void setup()
 {
-  Serial.begin(115200);
+  Serial.begin(115200); // Reduce this if your Arduino has trouble talking so fast
   Serial.println("ESP8266 Demo Sketch");

   wifi.begin(9600);
@@ -73,4 +73,4 @@

   Serial.println();
   delay(5000);
-}+}


Opps!

Opps!

--- examples/VWI/CosaVWIreceiver/CosaVWIreceiver.ino
+++ examples/VWI/CosaVWIreceiver/CosaVWIreceiver.ino
@@ -26,7 +26,7 @@
  * and 32-bit data element.
  *
  * @section Circuit
- * Connect RF433/315 Receiver to Arduino D12.
+ * Connect RF433/315 Receiver to Arduino D11.
  *
  * This file is part of the Arduino Che Cosa project.
  */


updated sketch with latest library updates (bob.begin())

--- examples/basic_bt_movement/basic_bt_movement.ino
+++ examples/basic_bt_movement/basic_bt_movement.ino
@@ -1,7 +1,6 @@
 #include <AFMotor.h>
 #include <Smartcar.h>
 #include <SoftwareSerial.h>
-

 SoftwareSerial bluetooth(50,51); // RX, TX
 // Only pins: 10, 11, 12, 13,  50, 51, 52, 53,  62, 63, 64, 65, 66, 67, 68, 69 will only work for SoftwareSerial on Arduino Mega!
@@ -9,6 +8,7 @@

 void setup() {
   bluetooth.begin(9600);
+  bob.begin();
 }

 void loop() {
@@ -31,25 +31,26 @@
     case 'b': //go backward
       bob.goBackward();
       break;
-    case 'z': //turn back left
-      bob.turnBackLeft();
+    case 'z': //steer back left
+      bob.steerBackLeft();
       break;
-    case 'x': //turn back right
-      bob.turnBackRight();
+    case 'x': //steer back right
+      bob.steerBackRight();
       break;
-    case 'p': //turn front left
-      bob.turnFrontLeft();
+    case 'p': //steer front left
+      bob.steerFrontLeft();
       break;
-    case 'k': //turn front right
-      bob.turnFrontRight();
-      break;
-    case 'q': //go forward and backward
-      bob.goForward(100);
-      bob.goBackward(50);
-      bob.goForward(1);
+    case 'k': //steer front right
+      bob.steerFrontRight();
       break;
     default: //if you receive something that you don't know, just stop
       bob.stop();
     }
   }
 }
+
+
+
+
+
+