Speed and length measurement based on counting the rotational time of a roller

Dependencies:   USBDevice mbed

Revision:
0:0b32433dec5d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jan 05 16:36:23 2016 +0000
@@ -0,0 +1,444 @@
+#include "mbed.h"
+#include "USBHID/USBHID.h"
+
+
+#define  CMD_GET_ALL_VALUES         1
+#define  CMD_GET_ROLLER_DIAMETER    2
+#define  CMD_SET_ROLLER_DIAMETER    3
+#define  CMD_SYS_CHECK              4
+#define  CMD_SYS_RESET              5
+
+#define COMMAND 0
+#define DATA 1
+
+#define VERSION 0x01
+
+//We declare a USBHID device. By default input and output reports are 64 bytes long.
+USBHID hid(64, 64);
+HID_REPORT send_report __attribute__((aligned (4))); // Aligned for fast access
+HID_REPORT recv_report __attribute__((aligned (4))); // Aligned for fast access
+
+BusInOut databus(p8, p9, p10, p11, p12, p13, p14, p15);
+DigitalOut registerSelect(p5);
+DigitalOut readWriteClock(p7);
+DigitalOut readWrite(p6);
+
+Ticker updateLCD;
+Ticker periodicTimer;
+
+LocalFileSystem local("local");
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+Serial pc(USBTX, USBRX); // tx, rx
+InterruptIn oneRotationPulse(p30);
+InterruptIn reelChangeInput(p29);
+ 
+//unsigned short timer_count;
+
+unsigned int captureVal = 0;
+unsigned int previousVal = 0;
+unsigned int diff = 0;
+bool newValToProcess = false;
+bool newValToSend = false;
+float rollerDiameter = 100.0;
+double lengthFactor =  3.14159265359 * rollerDiameter;
+double speedFactor =  lengthFactor * 1000000.0;
+double speed = 0.0;
+int rotationalCount = 0;
+double reelLength = lengthFactor * (double)rotationalCount;
+int displayMode = 0;
+int noActivityCounter = 0;
+
+
+void pin29ISR()
+{
+    
+    rotationalCount = 0;
+
+    reelLength = lengthFactor * (double)rotationalCount;
+}
+
+
+void pin30ISR()
+{
+
+    captureVal = LPC_TIM0->TC;
+
+    rotationalCount++;
+
+    diff = captureVal - previousVal;
+
+    speed = speedFactor / (double)diff;
+
+    reelLength = lengthFactor * (double)rotationalCount;
+
+    previousVal = captureVal;
+    
+    newValToSend = true;
+    
+    noActivityCounter = 0;
+        
+    led2 = !led2;
+}
+
+
+
+void readConfigFile()
+{
+    
+    FILE *fp = fopen("/local/config.dat", "r");
+
+    if (fp != NULL)
+    {
+        fscanf(fp, "%f", &rollerDiameter); 
+        fclose(fp);
+    }
+}
+
+
+
+void writeConfigFile()
+{
+    FILE *fp = fopen("/local/config.dat", "w");
+
+    if (fp != NULL)
+    {
+        fprintf(fp, "%5.1f\n", rollerDiameter);
+        fclose(fp);
+    }
+}
+
+void writeToLCD(bool rs, char data){
+
+    // set register select pin 
+    registerSelect = rs;
+    
+    // set read/write pin to write
+    readWrite = 0;
+    
+    // set bus as output
+    databus.output();
+    
+    // put data onto bus
+    databus = data;
+    
+    // pulse read/write clock
+    readWriteClock = 1;
+    
+    wait_us(1);
+    
+    readWriteClock = 0;
+
+    wait_us(1);
+    
+    // clear data bus
+    databus = 0;
+    
+    //pc.printf("%02x\n", data);
+    
+}
+
+
+char readFromLCD(bool rs){
+
+    char data;
+    
+    // set register select pin 
+    registerSelect = rs;
+    
+    // set read/write pin to read
+    readWrite = 1;
+    
+    // set bus as output
+    databus.input();
+    
+    // put data onto bus
+    data = databus;
+    
+    // pulse read/write clock
+    readWriteClock = 1;
+    
+    wait_us(10);
+    
+    readWriteClock = 0;
+    
+    return data;
+}
+
+
+void resetLCD(){
+}
+
+
+void initLCD(){
+    
+    // wait 15 ms to allow LCD to initialise
+    wait_ms(15);
+    
+    // set interface for 8 bit mode
+    writeToLCD(COMMAND, 0x30);
+
+    // give it time    
+    wait_ms(5);
+
+    // set interface for 8 bit mode again
+    writeToLCD(COMMAND, 0x30);
+
+    // give it time    
+    wait_us(100);
+
+    // set interface for 8 bit mode again, last one before we can configure the display
+    writeToLCD(COMMAND, 0x30);
+
+    // give it time    
+    wait_us(500);
+    
+    // set interface for 8 bit mode, 2 display lines and 5 x 8 character font
+    writeToLCD(COMMAND, 0x38);
+
+    // give it time    
+    wait_us(100);
+    
+    // display off
+    writeToLCD(COMMAND, 0x08);
+
+    // give it time    
+    wait_us(100);
+    
+    // clear the screen
+    writeToLCD(COMMAND, 0x01);
+
+    // give it time to finish    
+    wait_ms(2);
+
+    // set entry mode to increment cursor position cursor on write
+    writeToLCD(COMMAND, 0x03);
+    
+    // give it time to finish    
+    wait_us(100);
+
+    // position cursor at home
+    writeToLCD(COMMAND, 0x02);
+    
+    // give it time to finish    
+    wait_ms(2);
+
+    // display on
+    writeToLCD(COMMAND, 0x0F);
+}
+
+
+
+
+void positionCursor(uint8_t x, uint8_t y){
+
+    if (x > 7) x = 0;
+    
+    if (y == 1)
+        writeToLCD(COMMAND, 0x80 + 0x40 + x);
+    else
+        writeToLCD(COMMAND, 0x80 + 0x00 + x);
+        
+    wait_us(50);
+}
+
+
+
+void displayString(int x, int y, char *str){
+    
+    // position cursor
+    positionCursor(x, y);    
+    
+    // write string to screen
+    for (int i=0; i<strlen(str); i++)
+    {
+        writeToLCD(DATA, str[i]);
+        
+        wait_us(50);
+    }
+}
+ 
+
+ 
+void updateDisplay(){
+    char str[20];
+    
+    displayMode++;
+    
+    if (displayMode > 10)
+        displayMode = 0;
+        
+    if (displayMode > 5)
+    {
+        sprintf( str, "%6.0f m", reelLength);
+    }
+    else
+    {
+        sprintf( str, "%4.1f m/s", speed);
+    }
+
+    displayString(0, 0, str);
+}
+ 
+
+
+
+
+
+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 checkForUSBRequest()
+{
+    char *cptrR;
+    char *cptrT;
+    //float fTmp;
+    //bool updatePIDValues = false;
+
+    //try to read a msg
+    if(hid.readNB(&recv_report)){
+        
+        // set character pointer to start of the parameter for set commands
+        cptrR = (char *)&recv_report.data[1];
+        cptrT = (char *)&send_report.data[1];
+
+        led1 = 1;
+        
+        // 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       : 
+                  // Soft reset
+                    empty_report(&recv_report);
+                break;
+
+            case CMD_GET_ALL_VALUES:
+                if (newValToSend)
+                {
+                    pc.printf("Capture val = %x, diff = %d, speed = %5.3f m/s, length = %5.1 m\n\r", captureVal, diff, speed, reelLength);
+                
+                    // return the speed, length and raw count values
+                    sprintf((char *)send_report.data, "%c%c%10.1f %10.1f %10d", recv_report.data[0], 1, speed, reelLength, diff);
+    
+                    newValToSend = false;
+                }
+                else
+                {
+                    sprintf((char *)send_report.data, "%c%c", recv_report.data[0], 0);
+    
+                }
+                break;
+                
+            case CMD_GET_ROLLER_DIAMETER:
+                // return the roller diameter
+                sprintf(cptrT, "%5.1f", rollerDiameter);
+                pc.printf("roller diameter = %f\n", rollerDiameter );
+                break;
+                
+            case CMD_SET_ROLLER_DIAMETER:
+                // set roller diameter to value in packet
+                sscanf(cptrR, "%f", &rollerDiameter);
+                writeConfigFile();
+                pc.printf("Set roller diameter to %f\n", rollerDiameter);
+                break;
+                
+            case 0xEE   : {
+                hid.sendNB(&send_report);  
+                //WatchDog_us bello(100);
+                }
+            break;
+
+            default:
+                send_report.data[0] =   0xFF;   //Failure
+            break;
+        } // Switch 
+
+        // Return command + optional new args
+        hid.send(&send_report);
+
+        // 0xFF unused bytes
+        empty_report(&recv_report);         
+        empty_report(&send_report);
+        
+        led1 = 0;
+    }       // if packet
+}
+
+
+void periodicChecks()
+{
+    
+    noActivityCounter++;
+    
+    if (noActivityCounter > 5)
+    {
+        speed = 0;
+    }
+}
+
+
+
+int main (void) 
+{
+        
+    pc.printf("initialise the LCD\n");
+    
+    initLCD();
+    
+    pc.printf("read the config file\n");
+
+    readConfigFile();
+
+    pc.printf("start updateLCD ticker\n");
+
+    updateLCD.attach(&updateDisplay, 0.5);
+    
+    periodicTimer.attach(&periodicChecks, 1.0);
+        
+    pc.printf("initialise the USB interface\n");
+
+    led1 = 0;
+    led2 = 0;
+
+    send_report.length = 64;
+    recv_report.length = 64;
+
+    pc.printf("initialise the timer_init\n\r");
+
+    LPC_SC->PCONP |= 1 < 1;         //timer0 power on
+    LPC_TIM0->TCR = 1;              //enable Timer2
+
+
+    reelChangeInput.mode(PullUp);
+    reelChangeInput.fall(&pin29ISR);  
+
+    oneRotationPulse.mode(PullUp);
+    oneRotationPulse.fall(&pin30ISR);  
+
+    while(1)
+    {
+        
+        checkForUSBRequest();
+        
+        wait(0.1);               // adjust to 0.01 when code working properly so we don't miss events
+    }
+}
\ No newline at end of file