Demo code for Life Detector - attempting to share publically so someone else can tweak and reflash

Dependencies:   microbit

Revision:
0:d9a2b95dc9d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jun 01 17:44:46 2016 +0000
@@ -0,0 +1,223 @@
+#include "MicroBit.h"
+
+/* Raygun pin mapping - listed in Kitronik breakout order
+*  0 : MO Motor low-side-switch NPN pin
+*  5 : TS Trigger Switch (configured as ButtonA)
+*  1 : L1 Light 1 high-side-switch NPN Base
+*  8 : L2 Light 2 high-side-switch NPN Base
+* 11 : RS Red button switch (configured as ButtonB)
+* 12 : BL Blue LED 
+*  2 : PZ Piezo speaker
+* 14 : TX 3.3V Serial Transmit Pin
+* 15 : TX 3.3V Serial Receive Pin
+* 16 : GS Green Switch (unpowered side)
+* 3V : 3.3V reference
+* 0V : Piezo ground, common ground wire from circuit board
+*/
+
+MicroBit uBit;
+
+MicroBitPin motor           =   uBit.io.P0; 
+MicroBitPin speaker         =   uBit.io.P2; 
+
+MicroBitPin frontLight      =   uBit.io.P1;
+MicroBitPin centerLight     =   uBit.io.P8;
+MicroBitPin backLight       =   uBit.io.P12;
+
+//somehow non-functional
+//MicroBitButton triggerButton   =   uBit.buttonA;
+//MicroBitButton topButton        =   uBit.buttonB;
+
+MicroBitPin powerSwitch      =   uBit.io.P16; 
+
+char commandbytes[] =  {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
+char respondbytes[] =  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+bool triggerSwitched = false;
+bool powerSwitched = false;
+bool topSwitched = false;
+bool lifeDetected = false;
+
+int gas = 0;
+int backgroundGas = 1600;
+int diffGas = 200;
+
+int pitch;
+unsigned long pitchedTime;
+
+int minPitch = 1000;
+int maxPitch = 2000;
+int pitchCycle = 500;
+
+bool isAlive(int gas){
+    return gas > backgroundGas + diffGas;
+}
+
+void showGas(){
+    if(gas == 0){
+        uBit.display.scrollAsync("?");
+    }
+    else if(gas == 400){
+        uBit.display.scrollAsync("...");
+    }
+    else if(isAlive(gas)){
+        uBit.display.scrollAsync("+++");
+    }
+    else {
+        uBit.display.scrollAsync(gas);
+    }
+}
+
+void soundAlarm(){
+    speaker.setAnalogValue(512);
+}
+
+void silenceAlarm(){
+    speaker.setAnalogValue(0);
+}
+
+void setPitch(int futurePitch){
+    pitchedTime = uBit.systemTime();
+    pitch = futurePitch;
+    speaker.setAnalogPeriodUs(1000000 / futurePitch);
+}
+
+void displayComplete(MicroBitEvent e){
+    showGas();
+}
+
+int getSample(){
+    uBit.serial.send((uint8_t *)commandbytes, 9);     
+
+    uBit.serial.read((uint8_t *)respondbytes, 9);
+    
+    char header =   respondbytes[1];
+    char highppm =  respondbytes[2];
+    char lowppm =   respondbytes[3];
+    
+    if(header==0x86){
+        return ((int)highppm) * 256 + lowppm;
+    }
+    else{
+        return -1;
+    }
+}
+
+void diagnostic(){
+        //Run diagnostic sequence
+    uBit.display.printChar('M', 0);
+    motor.setDigitalValue(true);
+    uBit.sleep(1000);
+
+    uBit.display.printChar('F', 0);
+    frontLight.setDigitalValue(true);
+    uBit.sleep(1000);
+    frontLight.setDigitalValue(false);
+
+    uBit.display.printChar('C', 0);
+    centerLight.setDigitalValue(true);
+    uBit.sleep(1000);
+    centerLight.setDigitalValue(false);
+
+    motor.setDigitalValue(false);
+
+    uBit.display.printChar('B', 0);
+    backLight.setDigitalValue(true);
+    uBit.sleep(1000);
+    backLight.setDigitalValue(false);
+    
+    speaker.setAnalogPeriod(1000.0/500.0);
+    speaker.setAnalogValue(512);
+    uBit.sleep(1000);
+    speaker.setAnalogValue(0);
+}
+
+
+int main()
+{
+    uBit.init();
+    uBit.serial.baud(9600);
+    uBit.serial.redirect(MICROBIT_PIN_P14, MICROBIT_PIN_P15);
+
+    //begin with all outputs off
+    motor.setDigitalValue(false);
+    frontLight.setDigitalValue(false);
+    centerLight.setDigitalValue(false);
+    backLight.setDigitalValue(false);
+    
+    //force the speaker to be analog
+    speaker.setAnalogValue(0);
+    
+    //force switch to a pull-down implied by reading it
+    powerSwitch.getDigitalValue();
+    
+    while(powerSwitch.getDigitalValue()==false){
+        uBit.display.scrollAsync("After powering gun, reset micro:bit");
+    }
+
+
+    //create implicit 'loop' showing gas, and trigger it
+    uBit.messageBus.listen( MICROBIT_ID_DISPLAY, MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE, displayComplete);
+    showGas();
+        
+    while(1)
+    {
+        if(triggerSwitched != uBit.buttonA.isPressed()){
+            triggerSwitched = !triggerSwitched;
+        }
+        
+        if(topSwitched != uBit.buttonB.isPressed()){
+            topSwitched = !topSwitched;
+
+            if(topSwitched){ //calibration button pushed - acknowledge with new value
+                backgroundGas = getSample();
+                ManagedString prefix("C:");
+                ManagedString suffix(backgroundGas);
+                uBit.display.scroll(prefix+suffix);
+            }
+            
+        }
+        
+        if(powerSwitched != powerSwitch.getDigitalValue()){ //note, totally different logic than buttons (and different pull)
+            powerSwitched = powerSwitch.getDigitalValue();
+        }
+
+        gas = getSample();
+
+        if(powerSwitched){
+            backLight.setDigitalValue(true);
+        }
+        else{
+            backLight.setDigitalValue(false);
+        }
+        
+        if(lifeDetected != isAlive(gas)){
+            lifeDetected = !lifeDetected;
+            setPitch(1000);
+        }
+
+        if(triggerSwitched){
+            motor.setDigitalValue(true);
+            frontLight.setDigitalValue(true);
+            if(lifeDetected){
+                centerLight.setDigitalValue(true);
+                soundAlarm();
+                if(uBit.systemTime() - pitchedTime > 10){
+                    if(pitch < maxPitch){
+                        setPitch(pitch + (100 * (maxPitch - minPitch)/pitchCycle));
+                    }
+                    else{
+                        setPitch(minPitch);
+                    }
+                }
+            }
+        }
+        else{
+            motor.setDigitalValue(false);
+            frontLight.setDigitalValue(false);
+            centerLight.setDigitalValue(false);
+            silenceAlarm();
+        }
+        
+    }
+}