Cast tube scanner

Dependencies:   EALib mbed

main.cpp

Committer:
BPPearson
Date:
2016-01-05
Revision:
1:196b5b827e29
Parent:
0:ceb7120ddb13

File content as of revision 1:196b5b827e29:

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "mbed.h"
#include "XBee.h"

/******************************************************************************
 * Typedefs and defines
 *****************************************************************************/
//#define CMD_BTN_MSG (0)
//#define XBEE_REMOTE_ADDR_HI (0X0013A200)
//#define XBEE_REMOTE_ADDR_LO (0x40B3EB68)

#define RS422_Underflow                 0x01
#define RS422_Overflow                  0x02
#define Data_Overflow                   0x04
#define No_Peak_Available               0x08
#define Peak_Before_Measuring_Range     0x10
#define Peak_After_Measuring_Range      0x20
#define Measurement_Incalcuable         0x40
#define Measurement_Not_Evaluable       0x80
#define Peak_Too_Wide                   0x100
#define Laser_Off                       0x200
#define ThicknessSensorRangeError       0x400


/******************************************************************************
 * Local variables
 *****************************************************************************/

static XBee xbee(P4_22, P4_23, P4_17, P4_19);
static DigitalOut led1(LED1);        // led1 + led 2 -> active low
static DigitalOut led2(LED2);
static DigitalOut led3(LED3);             // led3 + led 4 -> active high
static DigitalOut led4(LED4);
Ticker readInputsTic;
Ticker XBeeCommsTic;
Ticker ledPulseCheck;
Serial temperatureSensor(p9, p10);
Serial thicknessSensor(p37,p31);
Serial pc(USBTX, USBRX); // tx, rx

static bool xbeeIsUp = false;
static uint32_t endpointAddrHi = 0x0013A200;
static uint32_t endpointAddrLo = 0x40F92FFA;
float rawTemperature = 0.0;
float rawThickness = 0.0;
uint16_t errorFlags = 0;
uint32_t packetId = 0;
uint8_t tChr0, tChr1, tChr2;
uint16_t binaryThickness;
bool thicknessReadingToProcess = false;
int led1Duration = 0;
int led2Duration = 0;
int led3Duration = 0;
int led4Duration = 0;


void pulseLed(int led, int duration)
{
    
    switch (led)
    {
        case LED1:
            led1 = 0;            // turn on led
            
            led1Duration = duration;            // set duration
            break;

        case LED2:
            led2 = 0;            // turn on led
            
            led2Duration = duration;            // set duration
            break;

        case LED3:
            led3 = 1;            // turn on led
            
            led3Duration = duration;            // set duration
            break;

        case LED4:
            led4 = 1;            // turn on led
            
            led4Duration = duration;            // set duration
            break;
        default: ;
    }
}



void ledPulser()
{

    if (led1Duration > 0)
    {
        led1Duration--;
        
        if (led1Duration == 0)
            led1 = 1;            // turn led off
    }

    if (led2Duration > 0)
    {
        led2Duration--;
        
        if (led2Duration == 0)
            led2 = 1;            // turn led off
    }

    if (led3Duration > 0)
    {
        led3Duration--;
        
        if (led3Duration == 0)
            led3 = 0;            // turn led off
    }

    if (led4Duration > 0)
    {
        led4Duration--;
        
        if (led4Duration == 0)
            led4 = 0;            // turn led off
    }
}


static void xbeeDeviceUp(void) 
{
    xbeeIsUp = true;
}


static void xbeeDeviceDown(void) 
{
    xbeeIsUp = false;
}


static void xbeeNodeFound(void) 
{
    uint32_t addrHi = 0;
    uint32_t addrLo = 0;
    uint8_t rssi = 0;

    xbee.getRemoteAddress(&addrHi, &addrLo);
    xbee.getRssi(&rssi);
}


static void xbeeTxStat(void) 
{
    uint8_t frameId = 0;

    XBee::XBeeTxStatus status = XBee::TxStatusOk;

    xbee.getTxStatus(&frameId, &status);
}



static void xbeeDataAvailable(void) 
{
    char* data = NULL;
    uint8_t len = 0;
    uint32_t addrHi = 0;
    uint32_t addrLo = 0;
    uint8_t rssi = 0;

    xbee.getRemoteAddress(&addrHi, &addrLo);
    xbee.getData(&data, &len);
    xbee.getRssi(&rssi);

    if (len > 0) 
    {
        switch(data[0]) 
        {
        }

    }

}



static bool xbeeInit()
{

    xbee.registerCallback(xbeeDeviceUp, XBee::CbDeviceUp);
    xbee.registerCallback(xbeeDeviceDown, XBee::CbDeviceDown);
    xbee.registerCallback(xbeeNodeFound, XBee::CbNodeFound);
    xbee.registerCallback(xbeeTxStat, XBee::CbTxStat);
    xbee.registerCallback(xbeeDataAvailable, XBee::CbDataAvailable);
    XBee::XBeeError err = xbee.init(XBee::Coordinator, "EAEA");
    
    if (err != XBee::Ok) 
    {
        return false;
    }

    return true;
}


static void reportInitFailed() 
{

    while (true) 
    {
        led4 = !led4;
        wait_ms(200);
    }
}


static void ledInit() 
{

    led1 = 1;  // turn off
    led2 = 1; // turn off
    led3 = 0;       // turn off
    led4 = 0;         // turn off
}



void     readTemperature()
{
    
    char buff[10];
    int idx = 0;
       
    temperatureSensor.putc('?');    // send request to Raytek temperature probe
    temperatureSensor.putc('T');
    temperatureSensor.putc('\r');
    
    wait_ms(20);    // wait while sensor replies
    
    while (temperatureSensor.readable() && idx < 10)    // get response
    {
        buff[idx] = temperatureSensor.getc();
        
        if (buff[idx] == '\n')        //if (buff[idx] == 0x0d)
        {
            buff[idx + 1] = NULL;

            break;
        }

        idx++;
    }
    
    if (idx > 0)
    {
        sscanf( buff, "!T%f\n", &rawTemperature);        // read temperature from data packet
    }
    else
    {
        pulseLed( LED2, 10);        // pulse led2 to error reading from temperature probe    

        rawTemperature = -1.0;
    }
}



void     readThickness(){    


    if (!thicknessReadingToProcess)                    // set in serial interrput handler once it has received a valid packet
    {
        return;
    }
    
    if (binaryThickness <= 642)
    {
        errorFlags |= ThicknessSensorRangeError;        // set range error bit in error flags
        
        rawThickness = 0.2;        // set a dummy value for the raw thickness
    }
    else    
        if (binaryThickness > 642 && binaryThickness < 64877)    // check signal within valid range
        {
            rawThickness = (((binaryThickness * 1.02 / 65520.0) - 0.01) * 32.0);            // calculate the raw thickness from the binary value (calculation in the ILD2300 manual             
        
            if (rawThickness < 0.5F || rawThickness > 3.0F)            // if raw thickness outside range
            {
                errorFlags |= ThicknessSensorRangeError;                // set error bit in error flags 

                rawThickness = 0.1;                                     // set default value
            }
        }
        else
        {
            pulseLed( LED1, 10);            // pulse error led    
    
            switch (binaryThickness - 262073)            // subtract error offset to get correct switch case
            {
                case 0:
                    errorFlags |= RS422_Underflow;
                    break;

                case 1:
                    errorFlags |= RS422_Overflow;
                    break;

                case 2:
                    errorFlags |= Data_Overflow;
                    break;

                case 3:
                    errorFlags |= No_Peak_Available;
                    break;

                case 4:
                    errorFlags |= Peak_Before_Measuring_Range;
                    break;

                case 5:
                    errorFlags |= Peak_After_Measuring_Range;
                    break;

                case 6:
                    errorFlags |= Measurement_Incalcuable;
                    break;

                case 8:
                    errorFlags |= Measurement_Not_Evaluable;
                    break;

                case 9:
                    errorFlags |= Peak_Too_Wide;
                    break;

                case 10:
                    errorFlags |= Laser_Off;
                    break;

                default:
                    errorFlags |= ThicknessSensorRangeError;
                    rawThickness = 0.0;
            }        
        }

    thicknessReadingToProcess = false;    // clear flag so we know when another packet has been received
}



void serialIntHandler(){

    uint8_t ch;
    
    ch = thicknessSensor.getc();    // get char that caused this interrupt
    
    if (ch < 0x40)              // if first byte of packet
    {
        tChr0 = ch;
        return;
    }
    
    if ((ch & 0x40) == 0x40)    // if second byte of packet
    {
        tChr1 = ch & 0x3f;
        return;
    }
    
    if ((ch & 0x80) == 0x80)    // if third byte of packet
    {
        tChr2 = ch & 0x3f;

        binaryThickness = tChr0 + (tChr1 << 6) + (tChr2 << 12);        // build binary thickness value from the 3 characters received

        thicknessReadingToProcess = true;        // set the flag to indicate a thickness reading to process        
    }
}



void readInputs() 
{
    
    pulseLed( LED3, 5);    // pulse led3 to show periodic read of temperature and thickness

    readTemperature();
    
    readThickness();
}





void xbeeComms()
{
    char data[40];
    uint8_t frameId = 0;

    if (xbeeIsUp) 
    {
        pulseLed( LED4, 5);        // pulse led4 to show XBee transmission    

        sprintf(data, "1%5.3f, %5.3f, %4x\n", rawTemperature, rawThickness, errorFlags);        // build data packet 
    
        xbee.send(endpointAddrHi, endpointAddrLo, data, strlen(data), &frameId);        // send the temperature and thickness packet to the client

        errorFlags = 0;       // clear error flags
    }
}




int main() 
{
    
    ledInit();    // clear all leds

    led1 = 0;    // start of initialisation sequence
    wait_ms(500);

    temperatureSensor.baud(9600);    // initialise the serial port for the temperature sensor
    temperatureSensor.format(8,SerialBase::None,1);
    
    thicknessSensor.baud(9600);    // initialise the serial port for the thickness sensor
    thicknessSensor.format(8,SerialBase::None,1);
    
    led2 = 0;    // next step of initialisation sequence
    wait_ms(500);

    if (!xbeeInit()) 
    {
        reportInitFailed();
    }

    led3 = 1;    // next step of initialisation sequence
    wait_ms(500);

    // Wait until XBee node is reported to be up.
    // - For End-device this means that the node is associated with a
    //   coordinator
    // - For a coordinator this means that the node is initialized and ready
    while(!xbeeIsUp) 
    {
        xbee.process();
    }

    led4 = 1;    // final step of initialisation sequence
    wait_ms(500);

    thicknessSensor.attach(&serialIntHandler);

    // start periodic read of sensors 
    readInputsTic.attach(&readInputs, 0.2);             // read inputs every 200 mS
    XBeeCommsTic.attach(&xbeeComms, 0.2);               // send to base station every 200 mS
    ledPulseCheck.attach(ledPulser, 0.01);

    ledInit();    // clear all leds

    while (1) 
    {

        if (xbeeIsUp) 
        {
            
        }
        
        xbee.process();

        wait_ms(10);
    }
}