![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Speed and length measurement based on counting the rotational time of a roller
main.cpp
- Committer:
- BPPearson
- Date:
- 2016-01-05
- Revision:
- 0:0b32433dec5d
File content as of revision 0:0b32433dec5d:
#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 } }