Brian Pearson
/
LPC4088CastTubeScanner
Cast tube scanner
Diff: main.cpp
- 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); + } +}