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

Dependencies:   microbit

main.cpp

Committer:
cefn
Date:
2016-06-01
Revision:
0:d9a2b95dc9d8

File content as of revision 0:d9a2b95dc9d8:

#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();
        }
        
    }
}