Brian Pearson / Mbed 2 deprecated LPC1768OpacityMeter

Dependencies:   PinDetect mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "PinDetect.h"
00003 
00004 #define COMMAND 0
00005 #define DATA 1
00006 
00007 #define AVERAGE       0
00008 #define MEDIAN        1
00009 #define RATEOFCHANGE  2
00010 #define BINAVERAGE    3
00011 
00012 Serial pc(USBTX, USBRX);
00013 DigitalOut led1(LED1);
00014 DigitalOut led2(LED2);
00015 DigitalOut led3(LED3);
00016 DigitalOut led4(LED4);
00017 AnalogIn opacity(p15);
00018 AnalogOut fOpacity(p18);
00019 BusInOut databus(p21, p22, p23, p24, p25, p26, p27, p28);
00020 DigitalOut registerSelect(p5);
00021 DigitalOut readWriteClock(p6);
00022 DigitalOut readWrite(p7);
00023 DigitalIn unlocked(p8);
00024 PinDetect calibUp(p10);
00025 PinDetect calibDown(p9);
00026 Ticker updateLCD;
00027 LocalFileSystem local("local");
00028 
00029 float instantOpacity;
00030 float filteredOpacity = 0.0;
00031 char *helloStr = "Hello";
00032 int filterAlgorithm = AVERAGE;
00033 float anIn1Sum;
00034 float anIn1SumSqr;
00035 float stdDevCount;
00036 float standardDeviation;
00037 float calibFactor = 1.0;
00038 int showCalibFactor = 0;
00039 float anInVals[100];
00040 int anInIdx = 0;
00041 
00042 
00043 void readConfigFile()
00044 {
00045     
00046     FILE *fp = fopen("/local/config.dat", "r");
00047 
00048     if (fp != NULL)
00049     {
00050         fscanf(fp, "%f", &calibFactor); 
00051         fclose(fp);
00052     }
00053 }
00054 
00055 
00056 
00057 void writeConfigFile()
00058 {
00059     FILE *fp = fopen("/local/config.dat", "w");
00060 
00061     if (fp != NULL)
00062     {
00063         fprintf(fp, "%5.3f\n", calibFactor);
00064         fclose(fp);
00065     }
00066 }
00067 
00068 
00069 
00070 
00071 void incCalibFactor(){
00072     
00073     //pc.printf("%d\n", unlocked.read());
00074     if (unlocked == false){
00075         calibFactor += 0.01;
00076         //pc.printf("Inc\n");
00077         showCalibFactor = 5;
00078         
00079         writeConfigFile();
00080     }
00081 }
00082 
00083 
00084 void decCalibFactor(){
00085     
00086     if (unlocked == false){
00087         calibFactor -= 0.01;
00088         //pc.printf("Dec\n");
00089         showCalibFactor = 5;
00090 
00091         writeConfigFile();
00092     }
00093 }
00094 
00095 
00096 void writeToLCD(bool rs, char data){
00097 
00098     // set register select pin 
00099     registerSelect = rs;
00100     
00101     // set read/write pin to write
00102     readWrite = 0;
00103     
00104     // set bus as output
00105     databus.output();
00106     
00107     // put data onto bus
00108     databus = data;
00109     
00110     // pulse read/write clock
00111     readWriteClock = 1;
00112     
00113     wait_us(1);
00114     
00115     readWriteClock = 0;
00116 
00117     wait_us(1);
00118     
00119     // clear data bus
00120     databus = 0;
00121     
00122     //pc.printf("%02x\n", data);
00123     
00124 }
00125 
00126 
00127 char readFromLCD(bool rs){
00128 
00129     char data;
00130     
00131     // set register select pin 
00132     registerSelect = rs;
00133     
00134     // set read/write pin to read
00135     readWrite = 1;
00136     
00137     // set bus as output
00138     databus.input();
00139     
00140     // put data onto bus
00141     data = databus;
00142     
00143     // pulse read/write clock
00144     readWriteClock = 1;
00145     
00146     wait_us(10);
00147     
00148     readWriteClock = 0;
00149     
00150     return data;
00151 }
00152 
00153 
00154 void resetLCD(){
00155 }
00156 
00157 
00158 void initLCD(){
00159     
00160     // wait 15 ms to allow LCD to initialise
00161     wait_ms(15);
00162     
00163     // set interface for 8 bit mode
00164     writeToLCD(COMMAND, 0x30);
00165 
00166     // give it time    
00167     wait_ms(5);
00168 
00169     // set interface for 8 bit mode again
00170     writeToLCD(COMMAND, 0x30);
00171 
00172     // give it time    
00173     wait_us(100);
00174 
00175     // set interface for 8 bit mode again, last one before we can configure the display
00176     writeToLCD(COMMAND, 0x30);
00177 
00178     // give it time    
00179     wait_us(500);
00180     
00181     // set interface for 8 bit mode, 2 display lines and 5 x 8 character font
00182     writeToLCD(COMMAND, 0x38);
00183 
00184     // give it time    
00185     wait_us(100);
00186     
00187     // display off
00188     writeToLCD(COMMAND, 0x08);
00189 
00190     // give it time    
00191     wait_us(100);
00192     
00193     // clear the screen
00194     writeToLCD(COMMAND, 0x01);
00195 
00196     // give it time to finish    
00197     wait_ms(2);
00198 
00199     // set entry mode to increment cursor position cursor on write
00200     writeToLCD(COMMAND, 0x03);
00201     
00202     // give it time to finish    
00203     wait_us(100);
00204 
00205     // position cursor at home
00206     writeToLCD(COMMAND, 0x02);
00207     
00208     // give it time to finish    
00209     wait_ms(2);
00210 
00211     // display on
00212     writeToLCD(COMMAND, 0x0F);
00213 }
00214 
00215 
00216 
00217 
00218 void positionCursor(uint8_t x, uint8_t y){
00219 
00220     if (x > 7) x = 0;
00221     
00222     if (y == 1)
00223         writeToLCD(COMMAND, 0x80 + 0x40 + x);
00224     else
00225         writeToLCD(COMMAND, 0x80 + 0x00 + x);
00226         
00227     wait_us(50);
00228 }
00229 
00230 
00231 void displayString(int x, int y, char *str){
00232     
00233     // position cursor
00234     positionCursor(x, y);    
00235     
00236     // write string to screen
00237     for (int i=0; i<strlen(str); i++){
00238         writeToLCD(DATA, str[i]);
00239         
00240         wait_us(50);
00241     }
00242 }
00243 
00244 
00245 void standardDeviationCalc(float opacity)
00246 {
00247     // add to standard deviation accumulators
00248     anIn1Sum += opacity;
00249     anIn1SumSqr += (opacity * opacity);
00250     
00251     // increment standard deviation counter
00252     stdDevCount++;
00253     
00254     // if enough readings for the standard deviation calculation
00255     if (stdDevCount >= 100)
00256     {
00257         // calculate the standard deviation
00258         // std dev = sqrt( (n * sum(x2) - sum(x)2)) / (n * (n - 1)))
00259         standardDeviation = ((stdDevCount * anIn1SumSqr) - (anIn1Sum * anIn1Sum)) / (stdDevCount * (stdDevCount - 1));
00260         if (standardDeviation > 0.0)
00261             standardDeviation = sqrt(standardDeviation);
00262         else
00263             standardDeviation = sqrt(-standardDeviation);
00264         
00265         // clear standard deviation accumulators for next set of readings
00266         anIn1Sum = 0.0;
00267         anIn1SumSqr = 0.0;
00268         stdDevCount = 0;
00269     }
00270  }
00271  
00272  
00273  void updateDisplay(){
00274     char str[20];
00275     
00276     sprintf( str, "o %5.1f", filteredOpacity * 104.0 * calibFactor);
00277 
00278     displayString(0, 0, str);
00279     
00280     if (showCalibFactor == 0){
00281         sprintf( str, "s %5.2f", standardDeviation);
00282 
00283         displayString(0, 1, str);
00284     }
00285     else{
00286         sprintf( str, "m %5.2f", calibFactor);
00287 
00288         displayString(0, 1, str);
00289 
00290         showCalibFactor--;
00291     }
00292 }
00293  
00294  
00295  
00296 int main() {
00297     float binVal[10];
00298     int binCnt[10];
00299     int maxCnt = 0;
00300     int maxIdx = 0;
00301     
00302     initLCD();
00303     
00304     filterAlgorithm = BINAVERAGE;
00305     
00306     calibUp.mode(PullUp);
00307     calibDown.mode(PullUp);
00308     unlocked.mode(PullUp);
00309     calibUp.attach_deasserted(&incCalibFactor);
00310     //calibUp.attach_deasserted_held(&incCalibFactor);
00311     calibDown.attach_deasserted(&decCalibFactor);
00312     //calibDown.attach_deasserted_held(&decCalibFactor);
00313     
00314     calibUp.setSampleFrequency();
00315     calibDown.setSampleFrequency();
00316 
00317     updateLCD.attach(&updateDisplay, 0.5);
00318 
00319     readConfigFile();
00320 
00321     // initialise analog input values
00322     for (int i=0; i<100; i++)
00323         anInVals[i] = opacity.read();
00324         
00325     while(1) {
00326         // read next analog input value into circular buffer
00327         anInVals[anInIdx] = opacity.read();
00328         
00329         // increment anInIdx and check for wrap 
00330         anInIdx++;
00331         if (anInIdx >= 100)
00332             anInIdx = 0;
00333         
00334         // filter analog inputs with required algorithm
00335         switch (filterAlgorithm)
00336         {
00337             case AVERAGE:
00338                 float accumulator = 0.0;
00339                 for (int i=0; i<100; i++)
00340                 {
00341                     accumulator += anInVals[i];
00342                 }
00343                 instantOpacity = accumulator / 100;
00344                 break;
00345             case MEDIAN:
00346                 float tempF;
00347                 for (int j=1; j<100; j++)
00348                 {
00349                     for (int i=1; i<100; i++)
00350                     {
00351                         if (anInVals[i] < anInVals[i-1])
00352                         {
00353                             // swap places
00354                             tempF = anInVals[i-1] ;
00355                             anInVals[i-1] = anInVals[i];
00356                             anInVals[i] = tempF;
00357                         }
00358                     }
00359                 }
00360                 instantOpacity = anInVals[49];
00361                 break;
00362             case RATEOFCHANGE:
00363                 break;
00364             case BINAVERAGE:
00365                 // initialise bins to zero
00366                 for (int i=0; i<10; i++)
00367                 {
00368                     binVal[i] = 0.0;
00369                     binCnt[i] = 0;
00370                 }
00371                 
00372                 // sort analog input values into one of ten bins
00373                 for (int i=0; i<100; i++)
00374                 {
00375                     int binIdx = anInVals[i] * 10.0;
00376                     if (binIdx > 9) 
00377                         binIdx = 9;
00378                     binVal[binIdx] += anInVals[i];
00379                     binCnt[binIdx]++;
00380                 }
00381 
00382                 maxCnt = 0;
00383                 maxIdx = 0;
00384                 // find the bin with most values added
00385                 for (int i=0; i<10; i++)
00386                 {
00387                     if (binCnt[i] > maxCnt)
00388                     {
00389                         maxCnt = binCnt[i];
00390                         maxIdx = i;
00391                     }
00392                 }
00393                 
00394                 instantOpacity = binVal[maxIdx] / binCnt[maxIdx];
00395                 break;
00396         }
00397 
00398         standardDeviationCalc(instantOpacity);
00399     
00400         // apply a filter to the instant reading to get the filtered reading
00401         filteredOpacity = (instantOpacity * 0.05) + (filteredOpacity * 0.95);
00402     
00403         fOpacity.write(filteredOpacity  * calibFactor);
00404 
00405         wait(0.1);
00406     }
00407 }