Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- Revision:
- 2:f2583b56777e
- Parent:
- 1:610dc7763656
- Child:
- 3:3b45e830ebe1
--- a/main.cpp Thu Jul 23 18:39:24 2015 +0000 +++ b/main.cpp Wed May 11 16:13:49 2016 +0000 @@ -1,237 +1,262 @@ +//Chesapeake Embedded code by Sami Kanderian. Date of last update (version) shown below. #include "mbed.h" +#include "string" +#include "iostream" +#include "math.h" +//#include "stdio.h" //#include "rtos.h" //Declare hardware inputs Timer timer; -AnalogIn potSet(A0); -AnalogIn pressureDAQZO(A1); -PwmOut pumpStep(D8); -DigitalOut dir(D9); -DigitalOut visDir(LED2); -PwmOut r(LED_RED); -PwmOut g(LED_GREEN); -PwmOut b(LED_BLUE); +Serial serial(USBTX, USBRX); +//IMPORTANT NOTE: PTA1 and PTA2 ARE RESERVED FOR SERIAL COMMUNICATION!!! DO NOT USE FOR SENSOR/ACTUATOR I/O!!! + +//Analog inputs : 0-3.3V +AnalogIn pin1(PTE20); +AnalogIn pin2(PTB0); +AnalogIn pin3(PTE21);//should be 16bit but doesnt work on mbed +AnalogIn pin4(PTB1); +AnalogIn pin5(PTE22); +AnalogIn pin6(PTB2); +AnalogIn pin7(PTE23); +AnalogIn pin8(PTB3); +AnalogIn pin9(PTE29); +AnalogIn pin10(PTC2); +AnalogIn pin11(PTE30); +AnalogIn pin12(PTC1); +AnalogIn pin13(PTC0); +AnalogIn pin14(PTD1);// doesnt work. Seems to be stuck at 3.3 +AnalogIn pin15(PTD5); +AnalogIn pin16(PTD6); + +//Built in LEDs +PwmOut rLed(LED_RED); +PwmOut gLed(LED_GREEN); +PwmOut bLed(LED_BLUE); + +//Date version as global +string dateVersion = "#Microcontroller Detected! uC code ver.: 04.12.2016"; + +//New globals for RxInterrupt routine +const int bufferSize = 256; +char rxBuffer[bufferSize]; +char txBuffer[bufferSize]; +volatile int rxIn = 0; +volatile int rxOut = 0; +bool rxFlag = 0; //Declare globals -char bufferIn[10]; -char bufferOut[8]; char hexCCIn[2]; char hexDDDDIn[4]; int decCCIn; int decDDDDIn; -unsigned long lastTime; //start it at 0, so at least one run of computePressureCommand is guaranteed -float outputCmd, iTerm; -float kp=2/9.9; -float ki=0; -float setPoint=0.000f; -int sampleTime = 250; //1/4 sec -float outMin=-1.0; -float outMax=1.0; -float smallChange=0.01*9.9/5; -float oldOutputCmd; //dont need -bool runPump=false; + +void ledConfirmSent()//Light up blue LED 10% +{ + rLed = 1; + gLed = 1; + bLed = 0.9; +} + +void ledConfirmReceive()//Light up green LED 10% +{ + rLed = 1; + gLed = 0.9; + bLed = 1; +} -//------------------------------------ -// Hyperterminal configuration 9600 bauds, 8N -//------------------------------------ -Serial pc(USBTX, USBRX); +void sendAnalogIn(int pinNum) //send Analog input in V +{ + + //serial.printf("\r\n"); + if (pinNum == 0 || pinNum == 1) { + serial.printf("%s%03.1f%s\r\n", "#PTE20: ", 3.3f*pin1.read(), "V^"); + } + if (pinNum == 0 || pinNum == 2) { + serial.printf("%s%03.1f%s\r\n", "#PTB0: ", 3.3f*pin2.read(), "V^"); + } + if (pinNum == 0 || pinNum == 3) { + serial.printf("%s%03.1f%s\r\n", "#PTE21: ", 3.3f*pin3.read(), "V^"); + } + if (pinNum == 0 || pinNum == 4) { + serial.printf("%s%03.1f%s\r\n", "#PTB1: ", 3.3f*pin4.read(), "V^"); + } + if (pinNum == 0 || pinNum == 5) { + serial.printf("%s%03.1f%s\r\n", "#PTE22: ", 3.3f*pin5.read(), "V^"); + } + if (pinNum == 0 || pinNum == 6) { + serial.printf("%s%03.1f%s\r\n", "#PTB2: ", 3.3f*pin6.read(), "V^"); + } + if (pinNum == 0 || pinNum == 7) { + serial.printf("%s%03.1f%s\r\n", "#PTE23: ", 3.3f*pin7.read(), "V^"); + } + if (pinNum == 0 || pinNum == 8) { + serial.printf("%s%03.1f%s\r\n", "#PTB3: ", 3.3f*pin8.read(), "V^"); + } + if (pinNum == 0 || pinNum == 9) { + serial.printf("%s%03.1f%s\r\n", "#PTE29: ", 3.3f*pin9.read(), "V^"); + } + if (pinNum == 0 || pinNum == 10) { + serial.printf("%s%03.1f%s\r\n", "#PTC2: ", 3.3f*pin10.read(), "V^"); + } + if (pinNum == 0 || pinNum == 11) { + serial.printf("%s%03.1f%s\r\n", "#PTE30: ", 3.3f*pin11.read(), "V^"); + } + if (pinNum == 0 || pinNum == 12) { + serial.printf("%s%03.1f%s\r\n", "#PTC1: ", 3.3f*pin12.read(), "V^"); + } + if (pinNum == 0 || pinNum == 13) { + serial.printf("%s%03.1f%s\r\n", "#PTC0: ", 3.3f*pin13.read(), "V^"); + } + if (pinNum == 0 || pinNum == 14) { + serial.printf("%s%03.1f%s\r\n", "#PTD1: ", 3.3f*pin14.read(), "V^"); + } + if (pinNum == 0 || pinNum == 15) { + serial.printf("%s%03.1f%s\r\n", "#PTD5: ", 3.3f*pin15.read(), "V^"); + } + if (pinNum == 0 || pinNum == 16) { + serial.printf("%s%03.1f%s\r\n", "#PTD6: ", 3.3f*pin16.read(), "V^"); + } -void ledConfirmReceive() -{ - r=1; - g=1; - b=0.9; + ledConfirmSent(); } -void ledConfirmSent() -{ - r=1; - g=0.9; - b=1; +string decToHexDDDD(int i) { + //Do twos complement to handle negative numbers + if (i < 0) { + i = 32767 - i; + } + char hex_string[10]; + sprintf(hex_string, "0x%02X", i); + return string(hex_string); +} + +int hexDDDDToDec(char hex[]) { + int decValue = strtol(hex, NULL, 16); + if (decValue >= 32768) { //Do twos complement to handle negative numbers + decValue = 32767 - decValue; + } + return decValue; +} + +int hexToDec(char hex[]) { + int decValue = strtol(hex, NULL, 16); + return decValue; +} + +int hexToDecSub(char hex[], int st, int ed) { + int n = ed - st + 1; + char hexSubset[n]; + for (int i = st; i < ed + 1; i++) { + hexSubset[i - st] = hex[i]; + } + int decValue = strtol(hexSubset, NULL, 16); + return decValue; } +void sendHexDDDDValTimes100(float val) { + int valTimes100 = (int) ((100 * val)); + string hexDDDD = decToHexDDDD(valTimes100); + int nLeadingZeros = 4 - hexDDDD.length(); -int hexToDec(char hex[]) -{ - int decValue = strtol(hex, NULL, 16); - - return decValue; - + char hexDDDDout[hexDDDD.length()]; + for (int i = 0; i < hexDDDD.length(); i++) { + hexDDDDout[i] = hexDDDD[i]; + } + char leadingZeros[nLeadingZeros]; + for (int i = 0; i < nLeadingZeros; i++) { + leadingZeros[i] = '0'; + } + //serial.printf("#%s%saa^\r\n", leadingZeros, hexDDDDout); + serial.printf("#%s%saa", leadingZeros, hexDDDDout); + //ledConfirmSent(); } -int hexToDecSub(char hex[], int st, int ed) -{ - int n=ed-st+1; - char hexSubset[n]; - for(int i=st; i<ed+1; i++) { - hexSubset[i-st]=hex[i]; +void runSingleCommand(int comInd) { + int endBuffer = (comInd + 1)*8; + int startBuffer = endBuffer - 7; + + //get hexCCIn + for (int i = 0; i < 2; i++) { + hexCCIn[i] = rxBuffer[i + startBuffer]; + } + //serial.printf("hexCCIn= is %s\r\n", hexCCIn); + + for (int i = 0; i < 4; i++) { + hexDDDDIn[i] = rxBuffer[i + startBuffer + 2]; } - int decValue = strtol(hexSubset, NULL, 16); - return decValue; + decCCIn = hexToDec(hexCCIn); + decDDDDIn = hexDDDDToDec(hexDDDDIn); + + //Make sure incoming checksum pans out: DO THIS LATER + + if (comInd == 0) { //include # if first command + startBuffer = startBuffer - 1; + } + int i2 = 0; + for (int i = startBuffer; i <= endBuffer; i++) { // duplicate bytes 0 to 9 for now; + txBuffer[i2] = rxBuffer[i]; + i2++; + } + + //Do action based on CC: already in while loop + } -void computePressureCommand() -{ - unsigned int now = timer.read_ms(); - int nSamplesToAverage=10; - int timeChange = (now - lastTime); - if(timeChange>=sampleTime) { - - float avePressureDAQZO=0; - for (int i=0; i<nSamplesToAverage; i++) { - avePressureDAQZO = avePressureDAQZO+pressureDAQZO; - } - avePressureDAQZO=avePressureDAQZO/(double)(nSamplesToAverage); - //setPoint = potSet; - float inputPressure=avePressureDAQZO*9.9; - - float error = setPoint - inputPressure; - - iTerm+= (ki * error); - if(iTerm > outMax) iTerm= outMax; - else if(iTerm < outMin) iTerm= outMin; - - outputCmd = kp * error + iTerm; - if(outputCmd > outMax) outputCmd = outMax; - else if(outputCmd < outMin) outputCmd = outMin; - - visDir=0; - if (outputCmd < 0) { - dir=1; - visDir=1; - outputCmd = outputCmd * -1.0; - } else dir=0; - - if (abs(error) > smallChange) { - pumpStep.write(0.50f); // turn back on - pumpStep.period_us((1.0/outputCmd)*200); - } else pumpStep.write(0.0f); //shut off steps for too small change - - - char signSetPoint='+'; - if(setPoint<0) { - signSetPoint='-'; - } - char signinputVoltage='+'; - if(setPoint<0) { - signinputVoltage='-'; - } - - - pc.printf("%s%c%2.3f%s%c%2.3f%s","#SP",signSetPoint,abs(setPoint),"MP",signinputVoltage,abs(inputPressure),"SS^"); - //printf("%f, %f, %f, %f, %f, %f \n\r ",setPoint, inputVoltage, outputCmd, kp*error, iTerm, (-0.5-dir.read())); - ledConfirmSent(); - oldOutputCmd=outputCmd; //don't need - lastTime = now; /*Remember time for next time*/ - }//end if timeChange - -}//end computePressureVoltage - - -void runWhenNewSerialIn() -{ - - - - bufferOut[0]=bufferIn[0]; +void runWhenNewSerialIn() { + int nCommands = (rxIn - 1) / 8; //find out how many commands are sent in one serial message + //serial.printf("%s%d%s\r\n", "#nCommands: ", nCommands, "commands"); + for (int comInd = 0; comInd < nCommands; comInd++) { // duplicate bytes 0 to 9 for now; + runSingleCommand(comInd); + } + serial.printf("^\r\n"); //end line after responses to all commands returned +} - for(int i=0; i<7; i++) { // duplicate bytes 0 to 9 for now; - bufferOut[i]=bufferIn[i]; - } - bufferOut[7]='^';//IMPORTANT! - - - //get hexCCIn - for(int i=0; i<2; i++) { - hexCCIn[i]=bufferIn[i+1]; - } - //pc.printf("hexCCIn= is %s\r\n", hexCCIn); - - for(int i=0; i<4; i++) { - hexDDDDIn[i]=bufferIn[i+3]; - } - - //pc.printf("hello test= is %s\r\n", test); - - //int value = strtol(hexDDDDIn, NULL, 16); - decCCIn = hexToDec(hexCCIn); - decDDDDIn = hexToDec(hexDDDDIn); - //int decDDDDIn = hexToDec("0000"); - - //Make sure incoming checksum pans out: - - //Do action based on CC +void Rx_interrupt() { + // Loop just in case more than one character is in UART's receive FIFO buffer + // Stop if buffer full + //while ((serial.readable()) && (((rxIn + 1) % bufferSize) != 0)) { + while (serial.readable()) { + rxBuffer[rxIn] = serial.getc(); + if (rxBuffer[rxIn] == '\r') { //looking for character not string (string is double quotes) \r is CR, \n is LF + rxFlag = 1; + //Turn built in LED blue (at half intensity) to confirm command recieved + ledConfirmReceive(); + //Execute runWhenNewSerialIn when new Rx recieved (ending with \r) + runWhenNewSerialIn(); + rxFlag = 0; //reset flag to listen for next message + rxIn = 0; // reset position index to 0 - //pc.printf("hexCCIn= is %c%c\r\n", hexCCIn[0],hexCCIn[1]); - //pc.printf("hexDDDDIn= is %c%c%c%c\r\n", hexDDDDIn[0],hexDDDDIn[1],hexDDDDIn[2],hexDDDDIn[3]); - //pc.printf("decCCIn= is %d\r\n", decCCIn); - //pc.printf("decDDDDIn= is %d\r\n", decDDDDIn); - if (decCCIn==1) { //control built in LED - //PwmOut led(LED_RED); //set to red just for now, change later if nec. - //Get desired intensity - double ledIntensity=(double)(hexToDecSub(bufferIn, 4, 5)); - if (bufferIn[3]=='0') { //red - //PwmOut r(LED_RED); - r=(255-ledIntensity)/255; - } else if(bufferIn[3]=='1') { - //PwmOut g(LED_GREEN); - g=(255-ledIntensity)/255; - } else if (bufferIn[3]=='2') { - //PwmOut led(LED_BLUE); - b=(255-ledIntensity)/255; + } else { + rxIn = (rxIn + 1) % bufferSize; } - - pc.printf("%s", bufferOut); - - } else if(decCCIn==27) { //CC=1b, Enable pump - pumpStep.write(0.50f); // set fixed duty cycle to 50% (hold position?) - ledConfirmSent(); - runPump=true; - //pc.printf("%s\n", bufferOut); //No output SP & MP instead via computePressureCommand - ledConfirmSent(); - - } else if(decCCIn==28) { //CC=1c, Define new pressure setPoint - setPoint=((double)(decDDDDIn))/100; //converted fron hex above - - } else if (decCCIn==29) {//CC=1d, Deactivate pump - pumpStep.write(0.0f); - ledConfirmSent(); - runPump=false; - pc.printf("%s", bufferOut); - ledConfirmSent(); } } -int main() -{ - r.period(0.001f); - g.period(0.001f); - b.period(0.001f); +int main() { + + serial.baud(9600); + serial.attach(&Rx_interrupt, Serial::RxIrq); - r=1; - g=1; - b=1; - - //pc.printf("\r\n"); //Important - timer.start(); - + //rLed.period(0.001f); + //gLed.period(0.001f); + //bLed.period(0.001f); + - while(1) { - - scanf("%10s", bufferIn); - //Turn built in LED blue (at half intensity) to confirm command recieved - ledConfirmReceive(); - runWhenNewSerialIn(); + //flash LED blue then green on startup or system reset + //serial.printf("Before Blue on Startup^\r\n"); + ledConfirmSent(); + ledConfirmReceive(); + //serial.printf("After Green on Startup^\r\n"); + timer.start(); - //Always keep running computePressureCommand if requred - if(runPump) { - computePressureCommand(); - } - //pc.printf("NEW value of '%s' is %ld\n", hexDDDDIn, decDDDDIn); - //Turn built in LED green (at half intensity) to confirm reponse sent back - + while (1) { + //scanf("%10s", rxBuffer);// NO! Use Rx_interrupt instead! + //Always keep running computePressureCommand when pump is enabled (runPump=true) + sendAnalogIn(decDDDDIn); + wait(1); } } \ No newline at end of file