Brian Pearson
/
LPC4088CastTubeScanner
Cast tube scanner
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); } }