Cast tube base station

Dependencies:   EALib USBDevice mbed

Revision:
0:e559b5160d84
Child:
1:240b94a8d002
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Dec 16 19:49:47 2015 +0000
@@ -0,0 +1,759 @@
+/******************************************************************************
+ * 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   
+    hid = &hid_object;
+    send_report.length = 64;
+
+    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
+
+    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;
+        }
+    }
+}