Cast tube base station
Dependencies: EALib USBDevice mbed
main.cpp
- Committer:
- BPPearson
- Date:
- 2016-01-05
- Revision:
- 1:240b94a8d002
- Parent:
- 0:e559b5160d84
File content as of revision 1:240b94a8d002:
/****************************************************************************** * Includes *****************************************************************************/ #include "mbed.h" #include "XBee.h" #include "USBHID.h" #include "ByteOperations.h" #include "USBHIDProtocol.h" /****************************************************************************** * Typedefs and defines *****************************************************************************/ // define NODE_IS_COORDINATOR if this board should act // as XBee coordinator. Make sure it is undefined if the board // should act as End-Device //#define NODE_IS_COORDINATOR (0) //#define CMD_BTN_MSG (0) //#define CMD_ACK_MSG (1) //#define NUMBER_OF_ZONES 72 //#define ECHO_SERVER_PORT 7 #define VERSION 0x01 #define COMMAND 0 #define DATA 1 #define XBeeDisconnected 0x400 #define MaxTeethExceeded 0x800 // rotational stage modes #define STOPPED 1 #define PARKING 2 #define GOTOMDPOSITION 3 #define DRIVINGTOPOSITION 4 #define STARTROTATING 5 #define ROTATING 6 #define MDSCAN 7 #define MAX_TEETH 384 #define LOW 0 #define HIGH 1 // input/output devices static XBee xbee(P4_22, P4_23, P4_17, P4_19); static DigitalIn indexInputLevel(p10); static DigitalIn zeroInputLevel(p11); 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); static DigitalOut motorDrive(p12); Serial pc(USBTX, USBRX); // tx, rx Ticker lossOfSignalTimer; Ticker updateLCD; Ticker rotationalControl; Ticker debounceDigInputs; Ticker ledPulseCheck; BusInOut databus(p25, p26, p27, p28, p29, p30, p31, p32); DigitalOut registerSelect(p39); DigitalOut readWrite(p38); DigitalOut readWriteClock(p37); USBHID *hid; HID_REPORT send_report __attribute__((aligned (4))); // Aligned for fast access HID_REPORT recv_report __attribute__((aligned (4))); // Aligned for fast access // local variables float rawTemperature = 0.0; float rawThickness = 0.0; uint32_t position = 0; uint32_t seqNo = 0; uint32_t prevSeqNo = 0; bool xbeeIsUp = false; bool saveProfileToDatabase = false; char inBuff[256]; char outBuff[256]; uint8_t xbeeSigStrength = 0; uint32_t errorFlags = 0; int rotationalMode = STOPPED; int mdPosition = 0; int toothLowCount = 0; int zeroLowCount = 0; int zeroHighCount = 0; int led1Duration = 0; int led2Duration = 0; int led3Duration = 0; int led4Duration = 0; int parkPosition = 0; int indexInputState = HIGH; int zeroInputState = HIGH; 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 } } void debounceInputs() { if (indexInputLevel == 0) { if (toothLowCount < 5) // times 10 mS for debounce period { toothLowCount++; if (toothLowCount >= 5) { position++; if (position >= MAX_TEETH) { position = 0; errorFlags |= MaxTeethExceeded; } } } } else toothLowCount = 0; if (zeroInputLevel == 0) { if (zeroLowCount < 5) // times 10 mS debounce period { zeroLowCount++; if (zeroLowCount >= 5) { position = 0; // zero position counter } } } else { zeroLowCount = 0; } } 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; xbee.getRemoteAddress(&addrHi, &addrLo); xbee.getData(&data, &len); //xbee.getRssi(&rssi); if (len > 0) { switch(data[0]) { case '1': if (len > 1) { pulseLed( LED4, 5); // get values from data packet // packet format - sprintf(data, "1%5.3f, %5.3f, %5.3f, %5.3f, %4x\n", rawTemperature, rawThickness, filteredTemperature, filteredThickness, errorFlags); sscanf(&data[1], "%f,%f, %x\n", &rawTemperature, &rawThickness, &errorFlags); } break; default: pc.printf("Unknown packet format %d\n", 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::EndDevice, "EAEA"); if (err != XBee::Ok) { return false; } return true; } static void reportInitFailed() { while (true) { wait_ms(200); } } static void ledInit() { led1 = 1; // turn off led2 = 1; // turn off led3 = 0; // turn off led4 = 0; // turn off } void empty_report(HID_REPORT *data){ register uint32_t *p = (uint32_t *)data->data; for( register int i=0; i<((sizeof(HID_REPORT)-1)/4); i++ ){ *p = 0xFFFFFFFF; p++; } } void processUSB() { uint8_t hiPosition; uint8_t loPosition; if(hid->readNB(&recv_report)) //try to read a msg { pulseLed(LED3, 5); // pulse led3 to show USB activity // Data packet received, start parsing int irx=0; int itx=0; send_report.data[itx++] = recv_report.data[0]; switch ( recv_report.data[irx++] ) { case CMD_SYS_CHECK: send_report.data[itx++] = VERSION; break; case CMD_SYS_RESET: empty_report(&recv_report); // Soft reset break; case CMD_CURRENT_VALUES: write_32_to_8(&itx, send_report.data, (uint32_t)(rawTemperature * 1000)); write_32_to_8(&itx, send_report.data, (uint32_t)(rawThickness * 1000)); write_32_to_8(&itx, send_report.data, position); write_32_to_8(&itx, send_report.data, xbeeSigStrength); write_32_to_8(&itx, send_report.data, errorFlags); write_32_to_8(&itx, send_report.data, rotationalMode); break; case PARK_AT_ZERO: parkPosition = MAX_TEETH - 2; // to allow it to slow donw and hit zero rotationalMode = PARKING; break; case PARK_AT_POSITION: hiPosition = recv_report.data[irx++]; loPosition = recv_report.data[irx++]; parkPosition = (hiPosition << 8) + loPosition; parkPosition -= 2; // to allow it to slow down and hit the required position if (parkPosition < 0) parkPosition += MAX_TEETH; rotationalMode = PARKING; break; case MD_SCAN: hiPosition = recv_report.data[irx++]; loPosition = recv_report.data[irx++]; mdPosition = (hiPosition << 8) + loPosition; rotationalMode = GOTOMDPOSITION; break; case ROTATIONAL_SCAN: rotationalMode = STARTROTATING; break; case 0xEE: hid->sendNB(&send_report); break; default: send_report.data[0] = 0xFF; //Failure break; } hid->send(&send_report); // Return command + optional new args empty_report(&recv_report); empty_report(&send_report); } } void checkForLossOfSignal() { xbee.getRssi(&xbeeSigStrength); } void writeToLCD(bool rs, char data) { registerSelect = rs; // set register select pin readWrite = 0; // set read/write pin to write databus.output(); // set bus as output databus = data; // put data onto bus readWriteClock = 1; // pulse read/write clock wait_us(1); readWriteClock = 0; wait_us(1); databus = 0; // clear data bus } char readFromLCD(bool rs) { char data; registerSelect = rs; // set register select pin readWrite = 1; // set read/write pin to read databus.input(); // set bus as input data = databus; // read data from bus readWriteClock = 1; // pulse read/write clock wait_us(10); readWriteClock = 0; return data; } void resetLCD() { } void initLCD(){ readWrite = 0; // set output so we always write to LCD wait_ms(15); // wait 15 ms to allow LCD to initialise writeToLCD(COMMAND, 0x30); // set interface for 8 bit mode wait_ms(5); // give it time writeToLCD(COMMAND, 0x30); // set interface for 8 bit mode again wait_us(100); // give it time writeToLCD(COMMAND, 0x30); // set interface for 8 bit mode again, last one before we can configure the display wait_us(500); // give it time writeToLCD(COMMAND, 0x38); // set interface for 8 bit mode, 2 display lines and 5 x 8 character font wait_us(100); // give it time writeToLCD(COMMAND, 0x08); // display off wait_us(100); // give it time writeToLCD(COMMAND, 0x01); // clear the screen wait_ms(2); // give it time to finish writeToLCD(COMMAND, 0x03); // set entry mode to increment cursor position cursor on write wait_us(100); // give it time to finish writeToLCD(COMMAND, 0x02); // position cursor at home wait_ms(2); // give it time to finish writeToLCD(COMMAND, 0x0C); // display on } void positionCursor(uint8_t x, uint8_t y) { switch (y) { case 0: writeToLCD(COMMAND, 0x80 + 0x00 + x); break; case 1: writeToLCD(COMMAND, 0x80 + 0x40 + x); break; case 2: writeToLCD(COMMAND, 0x80 + 0x14 + x); break; case 3: writeToLCD(COMMAND, 0x80 + 0x54 + x); break; default: writeToLCD(COMMAND, 0x80 + 0x00 + x); } wait_us(50); } void clearLcdScreen() { writeToLCD(COMMAND, 0x01); wait_ms(2); } void displayString(int x, int y, char *str) { positionCursor(x, y); // position cursor for (int i=0; i<strlen(str); i++) // write string to screen { writeToLCD(DATA, str[i]); wait_us(50); } } void updateDisplay() { char lineStr[20]; clearLcdScreen(); sprintf( lineStr, "Thickness %4.2f mm", rawThickness); displayString(0, 0, lineStr); sprintf( lineStr, "Temperature %4.1f C ", rawTemperature); displayString(0, 1, lineStr); sprintf( lineStr, "Sig strength %2d", xbeeSigStrength); displayString(0, 2, lineStr); switch (rotationalMode) { case STOPPED: displayString(0, 3, "Parked"); sprintf( lineStr, "%3d", position); displayString(16, 3, lineStr); break; case PARKING: displayString(0, 3, "Parking"); sprintf( lineStr, "%3d", position); displayString(16, 3, lineStr); break; case GOTOMDPOSITION: displayString(0, 3, "Go to MD pos"); sprintf( lineStr, "%3d", position); displayString(16, 3, lineStr); break; case DRIVINGTOPOSITION: displayString(0, 3, "Go to MD pos"); sprintf( lineStr, "%3d", position); displayString(16, 3, lineStr); break; case STARTROTATING: displayString(0, 3, "Start scan"); sprintf( lineStr, "%3d", position); displayString(16, 3, lineStr); break; case ROTATING: displayString(0, 3, "Scanning"); sprintf( lineStr, "%3d", position); displayString(16, 3, lineStr); break; case MDSCAN: displayString(0, 3, "MD scanning"); sprintf( lineStr, "%3d", position); displayString(16, 3, lineStr); break; default: break; } } void displayDebugMsg(char *str) { clearLcdScreen(); displayString(0, 0, str); } void checkRotationMode() { switch (rotationalMode) { case STOPPED: break; case PARKING: if (motorDrive == 0) motorDrive = 1; if (position == parkPosition) { motorDrive = 0; rotationalMode = STOPPED; } break; case GOTOMDPOSITION: motorDrive = 1; rotationalMode = DRIVINGTOPOSITION; break; case DRIVINGTOPOSITION: if (position == mdPosition) { motorDrive = 0; rotationalMode = MDSCAN; } break; case STARTROTATING: motorDrive = 1; rotationalMode = ROTATING; break; case ROTATING: break; default: break; } } int main() { ledInit(); // initialise leds motorDrive = 0; // set motor drive output to off initLCD(); // initialize the LCD displayDebugMsg("Initializing XBee"); if (!xbeeInit()) { reportInitFailed(); } // 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 displayDebugMsg("Connecting to XBee"); while(!xbeeIsUp) { xbee.process(); } displayDebugMsg(" "); // clear display displayDebugMsg("Initialising USB"); static USBHID hid_object(64, 64); // USB Initialize displayDebugMsg("USB initialised"); hid = &hid_object; send_report.length = 64; displayDebugMsg("Starting tickers"); lossOfSignalTimer.attach(&checkForLossOfSignal, 2.0); // check for loss of signal every 2 seconds updateLCD.attach(&updateDisplay, 1.0); rotationalControl.attach(checkRotationMode, 0.05); debounceDigInputs.attach(debounceInputs, 0.01); ledPulseCheck.attach(ledPulser, 0.01); ledInit(); // turn off all leds as initialisation complete displayDebugMsg("while (1)"); while (1) { if (xbeeIsUp) { xbee.process(); processUSB(); wait_ms(2); } else { errorFlags = XBeeDisconnected; // set error flag for no connection to XBee rawTemperature = 0.0; // clear display values rawThickness = 0.0; } } }