Opacity meter

Dependencies:   PinDetect mbed

Files at this revision

API Documentation at this revision

Comitter:
BPPearson
Date:
Tue Jan 05 16:44:13 2016 +0000
Commit message:
Opacity meter

Changed in this revision

PinDetect.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 0d9dd22ca491 PinDetect.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PinDetect.lib	Tue Jan 05 16:44:13 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AjK/code/PinDetect/#cb3afc45028b
diff -r 000000000000 -r 0d9dd22ca491 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Jan 05 16:44:13 2016 +0000
@@ -0,0 +1,407 @@
+#include "mbed.h"
+#include "PinDetect.h"
+
+#define COMMAND 0
+#define DATA 1
+
+#define AVERAGE       0
+#define MEDIAN        1
+#define RATEOFCHANGE  2
+#define BINAVERAGE    3
+
+Serial pc(USBTX, USBRX);
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+AnalogIn opacity(p15);
+AnalogOut fOpacity(p18);
+BusInOut databus(p21, p22, p23, p24, p25, p26, p27, p28);
+DigitalOut registerSelect(p5);
+DigitalOut readWriteClock(p6);
+DigitalOut readWrite(p7);
+DigitalIn unlocked(p8);
+PinDetect calibUp(p10);
+PinDetect calibDown(p9);
+Ticker updateLCD;
+LocalFileSystem local("local");
+
+float instantOpacity;
+float filteredOpacity = 0.0;
+char *helloStr = "Hello";
+int filterAlgorithm = AVERAGE;
+float anIn1Sum;
+float anIn1SumSqr;
+float stdDevCount;
+float standardDeviation;
+float calibFactor = 1.0;
+int showCalibFactor = 0;
+float anInVals[100];
+int anInIdx = 0;
+
+
+void readConfigFile()
+{
+    
+    FILE *fp = fopen("/local/config.dat", "r");
+
+    if (fp != NULL)
+    {
+        fscanf(fp, "%f", &calibFactor); 
+        fclose(fp);
+    }
+}
+
+
+
+void writeConfigFile()
+{
+    FILE *fp = fopen("/local/config.dat", "w");
+
+    if (fp != NULL)
+    {
+        fprintf(fp, "%5.3f\n", calibFactor);
+        fclose(fp);
+    }
+}
+
+
+
+
+void incCalibFactor(){
+    
+    //pc.printf("%d\n", unlocked.read());
+    if (unlocked == false){
+        calibFactor += 0.01;
+        //pc.printf("Inc\n");
+        showCalibFactor = 5;
+        
+        writeConfigFile();
+    }
+}
+
+
+void decCalibFactor(){
+    
+    if (unlocked == false){
+        calibFactor -= 0.01;
+        //pc.printf("Dec\n");
+        showCalibFactor = 5;
+
+        writeConfigFile();
+    }
+}
+
+
+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 standardDeviationCalc(float opacity)
+{
+    // add to standard deviation accumulators
+    anIn1Sum += opacity;
+    anIn1SumSqr += (opacity * opacity);
+    
+    // increment standard deviation counter
+    stdDevCount++;
+    
+    // if enough readings for the standard deviation calculation
+    if (stdDevCount >= 100)
+    {
+        // calculate the standard deviation
+        // std dev = sqrt( (n * sum(x2) - sum(x)2)) / (n * (n - 1)))
+        standardDeviation = ((stdDevCount * anIn1SumSqr) - (anIn1Sum * anIn1Sum)) / (stdDevCount * (stdDevCount - 1));
+        if (standardDeviation > 0.0)
+            standardDeviation = sqrt(standardDeviation);
+        else
+            standardDeviation = sqrt(-standardDeviation);
+        
+        // clear standard deviation accumulators for next set of readings
+        anIn1Sum = 0.0;
+        anIn1SumSqr = 0.0;
+        stdDevCount = 0;
+    }
+ }
+ 
+ 
+ void updateDisplay(){
+    char str[20];
+    
+    sprintf( str, "o %5.1f", filteredOpacity * 104.0 * calibFactor);
+
+    displayString(0, 0, str);
+    
+    if (showCalibFactor == 0){
+        sprintf( str, "s %5.2f", standardDeviation);
+
+        displayString(0, 1, str);
+    }
+    else{
+        sprintf( str, "m %5.2f", calibFactor);
+
+        displayString(0, 1, str);
+
+        showCalibFactor--;
+    }
+}
+ 
+ 
+ 
+int main() {
+    float binVal[10];
+    int binCnt[10];
+    int maxCnt = 0;
+    int maxIdx = 0;
+    
+    initLCD();
+    
+    filterAlgorithm = BINAVERAGE;
+    
+    calibUp.mode(PullUp);
+    calibDown.mode(PullUp);
+    unlocked.mode(PullUp);
+    calibUp.attach_deasserted(&incCalibFactor);
+    //calibUp.attach_deasserted_held(&incCalibFactor);
+    calibDown.attach_deasserted(&decCalibFactor);
+    //calibDown.attach_deasserted_held(&decCalibFactor);
+    
+    calibUp.setSampleFrequency();
+    calibDown.setSampleFrequency();
+
+    updateLCD.attach(&updateDisplay, 0.5);
+
+    readConfigFile();
+
+    // initialise analog input values
+    for (int i=0; i<100; i++)
+        anInVals[i] = opacity.read();
+        
+    while(1) {
+        // read next analog input value into circular buffer
+        anInVals[anInIdx] = opacity.read();
+        
+        // increment anInIdx and check for wrap 
+        anInIdx++;
+        if (anInIdx >= 100)
+            anInIdx = 0;
+        
+        // filter analog inputs with required algorithm
+        switch (filterAlgorithm)
+        {
+            case AVERAGE:
+                float accumulator = 0.0;
+                for (int i=0; i<100; i++)
+                {
+                    accumulator += anInVals[i];
+                }
+                instantOpacity = accumulator / 100;
+                break;
+            case MEDIAN:
+                float tempF;
+                for (int j=1; j<100; j++)
+                {
+                    for (int i=1; i<100; i++)
+                    {
+                        if (anInVals[i] < anInVals[i-1])
+                        {
+                            // swap places
+                            tempF = anInVals[i-1] ;
+                            anInVals[i-1] = anInVals[i];
+                            anInVals[i] = tempF;
+                        }
+                    }
+                }
+                instantOpacity = anInVals[49];
+                break;
+            case RATEOFCHANGE:
+                break;
+            case BINAVERAGE:
+                // initialise bins to zero
+                for (int i=0; i<10; i++)
+                {
+                    binVal[i] = 0.0;
+                    binCnt[i] = 0;
+                }
+                
+                // sort analog input values into one of ten bins
+                for (int i=0; i<100; i++)
+                {
+                    int binIdx = anInVals[i] * 10.0;
+                    if (binIdx > 9) 
+                        binIdx = 9;
+                    binVal[binIdx] += anInVals[i];
+                    binCnt[binIdx]++;
+                }
+
+                maxCnt = 0;
+                maxIdx = 0;
+                // find the bin with most values added
+                for (int i=0; i<10; i++)
+                {
+                    if (binCnt[i] > maxCnt)
+                    {
+                        maxCnt = binCnt[i];
+                        maxIdx = i;
+                    }
+                }
+                
+                instantOpacity = binVal[maxIdx] / binCnt[maxIdx];
+                break;
+        }
+
+        standardDeviationCalc(instantOpacity);
+    
+        // apply a filter to the instant reading to get the filtered reading
+        filteredOpacity = (instantOpacity * 0.05) + (filteredOpacity * 0.95);
+    
+        fOpacity.write(filteredOpacity  * calibFactor);
+
+        wait(0.1);
+    }
+}
diff -r 000000000000 -r 0d9dd22ca491 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Jan 05 16:44:13 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5
\ No newline at end of file