Project picture
Color sensor APDS-9960 on breadboard
One LED light on
LCD connected to Arduino
All three lED lights on
On the left side of the chipboard, there is a small white board with a light color sensor attached to it, positioned so that it faces toward the opposite side. On the right side, there is another white board, and mounted on top of it are three lights, each emitting a different color. When the color sensor detects a specific light, a corresponding number of lights on the right board will turn on. It could be one, two, or all three. Next to these lights, a second sensor is placed to measure the overall intensity of the illumination. The reading from this intensity sensor controls the servo motor, with its values mapped to determine the rotation angle.
Each image with caption and alt text.
skip button conntected through breadboard
Middle step LED lights connected through breadboard
Middle step Photoresistor connected through breadboard
It has been a great experience to engage in these hands-on works and actually build something tangible. Looking back on my design and building process, I feel that I did a good job understanding the interaction sequence of the system, and the coding side went relatively smoothly. I was able to translate my design intentions into functioning code.
That said, I also see areas where I could improve. My understanding of the electronic components still feels a bit shallow. For instance, in this project I used a light color sensor as the input, but I processed the data simply by averaging the RGB values without realizing at the time that this essentially gave me brightness rather than meaningful color differentiation. Similarly, with the LCD display, I didn't notice the need to use the clear function, so the digits overflowed and cluttered the screen.
I think these issues could have been avoided if I had started the project earlier and given myself more time to carefully test and refine the input and output behaviors. Being more mindful of the details of the electronic components.
#include <Adafruit_APDS9960.h>
/***************************************************************************
Double Transducer: light color to rotation
This script uses the Adafruit library to read RGB value of light, then calculates the
average of RGB value and uses it to determine the number of LEDs turned on. More
LEDs get turned on means the reading of photoresistor will be higher. The reading of
photoresistor determines the angle of rotation. When the skip button is pressed, the script
will directly map the average of RGB value to the rotation angle of the servo motor.
Pin mapping table:
component Arduino pin role
servo motor 7 output
skip button 8 input
blue LED 11 output
yellow LED 12 output
green LED 13 output
photoresistor A3 input
credit:
intial ideation with G Meloche
***************************************************************************/
#include <Servo.h>
#include "Adafruit_APDS9960.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,2);
Adafruit_APDS9960 apds;
const int MOTORPIN = 7;
const int PHOTOPIN = A3;
const int BUTTONPIN = 8;
const int BLUELED = 11;
const int YELLOWLED = 12;
const int GREENLED = 13;
Servo ServoMotor;
void setup() {
pinMode(BUTTONPIN,INPUT);
pinMode(PHOTOPIN,INPUT);
pinMode(BLUELED, OUTPUT);
pinMode(YELLOWLED, OUTPUT);
pinMode(GREENLED, OUTPUT);
ServoMotor.attach(MOTORPIN);
Serial.begin(115200);
if(!apds.begin()){
Serial.println("failed to initialize device! Please check your wiring.");
}
else Serial.println("Device initialized!");
//enable color sensign mode
apds.enableColor(true);
//Display setup
lcd.init();
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("i:");
lcd.setCursor(6,0);
lcd.print("m:");
lcd.setCursor(12,1);
lcd.print("o:");
}
void loop() {
//create some variables to store the color data in
uint16_t r, g, b, c;
int button = digitalRead(BUTTONPIN);
int photoVal = analogRead(PHOTOPIN);
//wait for color data to be ready
while(!apds.colorDataReady()){
delay(5);
}
//get the data and print the different channels
apds.getColorData(&r, &g, &b, &c);
Serial.print("photoVal: ");
Serial.print(photoVal);
Serial.print("red: ");
Serial.print(r);
Serial.print(" green: ");
Serial.print(g);
Serial.print(" blue: ");
Serial.print(b);
Serial.print(" clear: ");
Serial.println(c);
Serial.println();
int avg = (r+g+b)/3;
Serial.print("avg:");
Serial.println(avg);
//lcd input print
lcd.setCursor(2,0);
int inputLCD = map(avg, 0,100,0,99);
lcd.print(inputLCD);
Serial.print("LCD input:");
Serial.println(inputLCD);
lcd.noDisplay();
delay(100);
lcd.display();
delay(100);
int degree = map(avg, 0,80,10,170);
if (button==1){
//if button is pressed
digitalWrite(BLUELED,LOW);
digitalWrite(YELLOWLED,LOW);
digitalWrite(GREENLED,LOW);
ServoMotor.write(degree);
}
else{
if (avg>10){
digitalWrite(BLUELED,HIGH);
digitalWrite(YELLOWLED,LOW);
digitalWrite(GREENLED,LOW);
lcd.setCursor(8,0);
lcd.print("1 on");
}
if (avg>15){
digitalWrite(YELLOWLED,HIGH);
digitalWrite(BLUELED,HIGH);
digitalWrite(GREENLED,LOW);
lcd.setCursor(8,0);
lcd.print("2 on");
}
if (avg>20){
digitalWrite(GREENLED,HIGH);
digitalWrite(YELLOWLED,HIGH);
digitalWrite(BLUELED,HIGH);
lcd.setCursor(8,0);
lcd.print("3 on");
}
lcd.setCursor(8,1);
int lcdMSensor = map(photoVal, 650, 850, 0, 99);
Serial.print("lcdphotoVal:");
Serial.println(lcdMSensor);
lcd.print(lcdMSensor);
degree = map(photoVal, 700, 850, 10, 170);
ServoMotor.write(degree);
Serial.print("degree:");
Serial.println(degree);
//lcd.setCursor(14,1);
//int lcdOut = map(degree, 10 , 170, 0, 99);
//lcd.print(lcdOut);
}
lcd.setCursor(14,1);
int lcdOut = map(degree, 10 , 170, 0, 99);
lcd.print(lcdOut);
//delay(100);
}