basic color sensor using cds photocell and shiftbrite led, based on the project here: http://www.instructables.com/id/Using-an-RGB-LED-to-Detect-Colours/?ALLSTEPS

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
vk5653
Date:
Tue Apr 14 13:36:36 2015 +0000
Commit message:
basic color sensor using a cds photosensor and a shiftbrite led, based on the project at http://www.instructables.com/id/Using-an-RGB-LED-to-Detect-Colours/?ALLSTEPS

Changed in this revision

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 118dcae93623 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Apr 14 13:36:36 2015 +0000
@@ -0,0 +1,161 @@
+#include "mbed.h"
+//ShiftBrite Demo
+DigitalOut latch(p15);
+DigitalOut enable(p16);
+AnalogIn aout(p20);
+//Cycles through different colors on RGB LED
+SPI spi(p11, p12, p13);
+
+Serial pc(USBTX, USBRX); // tx, rx
+
+void RGB_LED(int red, int green, int blue);
+void checkBalance();
+void setBalance();
+void checkColor();
+void scanning(int step, int on);
+void getReading(int times);
+void printColor();
+
+//global variables
+    // boolean to know if the balance has been set
+    bool balanceSet = false;
+
+    //floats to hold colour arrays
+    float colorArray[] = {0,0,0};
+    float whiteArray[] = {0,0,0};
+    float blackArray[] = {0,0,0};
+
+    //place holder for average
+    int avgRead = 0;
+
+
+//Use SPI hardware to write color values to LED driver chip
+void RGB_LED(int red, int green, int blue) {
+    unsigned int low_color=0;
+    unsigned int high_color=0;
+    high_color=(blue<<4)|((red&0x3C0)>>6);
+    low_color=(((red&0x3F)<<10)|(green));
+    spi.write(high_color);
+    spi.write(low_color);
+    latch=1;
+    latch=0;
+}
+
+
+void checkBalance(){
+  //check if the balance has been set, if not, set it
+  if(balanceSet == false){
+    setBalance();
+  }
+}
+
+
+void setBalance(){
+  //set white balance
+   wait(5);                              //delay for five seconds, this gives us time to get a white sample in front of our sensor
+  //scan the white sample.
+  //go through each light, get a reading, set the base reading for each colour red, green, and blue to the white array
+  for(int i = 0; i<=2; i++){
+     scanning(i,1);
+     wait(0.1);
+     getReading(1);          //number is the number of scans to take for average, this whole function is redundant, one reading works just as well.
+     whiteArray[i] = avgRead;
+     scanning(i,0);
+     wait(0.1);
+  }
+  //done scanning white, now it will pulse blue to tell you that it is time for the black (or grey) sample.
+   //set black balance
+    wait(5);              //wait for five seconds so we can position our black sample 
+  //go ahead and scan, sets the colour values for red, green, and blue when exposed to black
+  for(int i = 0;i<=2;i++){
+     scanning(i,1);
+     wait(0.1);
+     getReading(1);
+     blackArray[i] = avgRead;
+     scanning(i,0);
+     wait(0.1);
+  }
+   //set boolean value so we know that balance is set
+  balanceSet = true;
+  //delay another 5 seconds to allow the human to catch up to what is going on
+  wait(5);
+}
+
+
+void scanning(int step, int on){
+    int mark = 0;
+    if(on == 1){
+        mark = 50;
+    }
+    else {
+        mark = 0;
+    }
+        
+    if (step == 0){
+        RGB_LED(mark,0,0);
+    }
+    else if (step == 1){
+        RGB_LED(0,mark,0);
+    }
+    else {
+        RGB_LED(0,0,mark);  
+    }
+}
+
+
+
+void checkColor(){
+    for(int i = 0;i<=2;i++){
+     scanning(i,1);  //turn the LED, red, green or blue depending which iteration
+     wait(0.1);                      //delay to allow CdS to stabalize, they are slow
+     getReading(5);                  //take a reading however many times
+     colorArray[i] = avgRead;        //set the current colour in the array to the average reading
+     float greyDiff = whiteArray[i] - blackArray[i];                    //the highest possible return minus the lowest returns the area for values in between
+     colorArray[i] = (colorArray[i] - blackArray[i])/(greyDiff)*255; //the reading returned minus the lowest value divided by the possible range multiplied by 255 will give us a value roughly between 0-255 representing the value for the current reflectivity(for the colour it is exposed to) of what is being scanned
+     scanning(i,0);   //turn off the current LED
+     wait(0.1);
+  }
+}
+
+
+void getReading(int times){
+  int reading;
+  int tally=0;
+  //take the reading however many times was requested and add them up
+    for(int i = 0;i < times;i++){
+        reading = aout.read();
+        tally = reading + tally;
+        wait(0.01);
+    }
+  //calculate the average and set it
+  avgRead = (tally)/times;
+}
+
+
+//prints the colour in the colour array, in the next step, we will send this to processing to see how good the sensor works.
+void printColor(){
+    pc.printf("R = ");
+    pc.printf("%d", colorArray[0]);
+    pc.printf("G = ");
+    pc.printf("%d", colorArray[1]);
+    pc.printf("B = ");
+    pc.printf("%d", colorArray[2]);
+}
+
+
+
+int main() {   
+    spi.format(16,0);
+    spi.frequency(500000);
+    enable=0;
+    latch=0;
+    
+    wait(5);  
+    while(1){
+        checkBalance();
+        checkColor();
+        printColor();
+    }
+    
+
+}
diff -r 000000000000 -r 118dcae93623 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Apr 14 13:36:36 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/487b796308b0
\ No newline at end of file