Cast tube scanner

Dependencies:   EALib mbed

Revision:
0:ceb7120ddb13
Child:
1:196b5b827e29
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Dec 16 19:50:25 2015 +0000
@@ -0,0 +1,474 @@
+/******************************************************************************
+ * 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 = 0x40E67BE7;
+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);
+    }
+}