Hardware components | ||||||
| × | 3 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 6 | ||||
| × | 6 | ||||
| × | 2 | ||||
| × | 3 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
Hand tools and fabrication machines | ||||||
|
You could use this project and modify it to control the lights of your house matching the colour of the sun (indoors sunset) etc....I used to struggle with shitty low quality LED lights on my bike, my goal was to be noticed.
So i purchased some of the cheapest rgb stripes (they played me, the stripes were R,G and B on an individual LED each one) , a cuple of arduino nano , lipo batterys and transistors.
Now i have the most gaudy bike on the city, why?, because i know about electronics and i could do silly things whenever i please.
TRANSMITTERThe size, form and range that you find suitable for your project, i needed something strong and pocketsize.
Arduino nano with 433mhz transmmiter module on the back, three scavenged potenciometers from an old music amplifier(100kohm each), the potenciometers have a bad response to the arduino analog reading wich only recognices values at the low resistance levels if i do it again i will use 10k or lower.
It depends highly of your boxing and placement of the transmmiter in your project but you can archieve 100m range easily.
RECEIVERNo big deal, the easy part of the project. Arduino nano with 433mhz receiver module and three power pnp mosfets for current gating the led stripe. We also are gonna need a bigger lipo of 11,1v (3S and the current mAh you find just okay for your needs) cause my RGBstripe is 12v.
RX, receiver on the weels
C/C++its reads an specific datagram with this concrete sintaxis
MaRRRRaGGGGaBBBB;
M->mode , 0 for waving colours, 1 for analog transmitted from the TX unit
RRRR-> RED VALUE
GGGG->GREEN VALUE
BBBB->BLUE VALUE
a->for separate the data
#include <VirtualWire.h>
//pin map, RX and pwm analogOutupts to PNP transistors
#define RX 3
#define pwmledRED 5
#define pwmledGREEN 6
#define pwmledBLUE 11
//arrays of data for build the final message
char datarraycharred [(sizeof(int)*4+1)];
char datarraychargreen[(sizeof(int)*4+1)];
char datarraycharblue [(sizeof(int)*4+1)];
char datarraymodo [(sizeof(int)*4+1)];
char datarrayclear [(sizeof(int)*4+1)]={"FFFF"};//tricky thing to reorder the data
char datatotal [(sizeof(int)*4+1)*4+4];
int datared =0;
int datagreen =0;
int datablue =0;
int bandera=0;
int i=0,j=0,index=0;
int indexchill=0;
int datamodo=3;//initialice with idle state all LED turned off
int ired=0,igreen=0,iblue=0;
void setup() {
Serial.begin(9600);
// VirtualWire
// Initialise the IO and ISR
// Required for DR3100
vw_set_rx_pin(RX); //Config pin as RX
vw_set_ptt_inverted(true);
// Bits per sec
vw_setup(2000);
// Start the receiver PLL running
vw_rx_start();
pinMode(pwmledRED,OUTPUT); //trt--->leds outuput
pinMode(pwmledGREEN,OUTPUT);
pinMode(pwmledBLUE,OUTPUT);
}
void loop(){
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
// Non-blocking
if (vw_get_message(buf, &buflen))
{
int i;
// Message with a good checksum received, dump it.
for (i = 0; i < buflen; i++)
{
// Fill Sensor1CharMsg Char array with corresponding
// chars from buffer.
datatotal[i] = char(buf[i]);
}
datatotal[buflen] = '\0';
// Convert Sensor1CharMsg Char array to TRUE integer, not the direct ASCII equivalent shit
chartointconvert();
}
if(datamodo==0)// chill wabing colour mode
modochill();
//write outupts
analogWrite(pwmledRED,datared);
analogWrite(pwmledGREEN,datagreen);
analogWrite(pwmledBLUE,datablue);
// DEBUG
Serial.print(datatotal);
Serial.print(" ");
Serial.print(datarraymodo);
Serial.print(" ");
Serial.print(datarraycharred);
Serial.print(" ");
Serial.print(datarraychargreen);
Serial.print(" ");
Serial.print(datarraycharblue);
Serial.print(" ");
Serial.print(datamodo);
Serial.print(" ");
Serial.print(datared);
Serial.print(" ");
Serial.print(datagreen);
Serial.print(" ");
Serial.println(datablue);
delay(50);
}
void chartointconvert(){
bandera=0;
strcpy (datarraymodo,datarrayclear);
strcpy (datarraycharred,datarrayclear);
strcpy (datarraychargreen,datarrayclear);
strcpy (datarraycharblue,datarrayclear);
index=0;
for(i=0;datatotal[i]!='a';i++)
{
datarraymodo[index]=datatotal[i];
index++;
}
i++;
j=i;
index=0;
for(i=j;datatotal[i]!='a';i++)
{
datarraycharred[index]=datatotal[i];
index++;
}
i++;
j=i;
index=0;
for(i=j;datatotal[i]!='a';i++)
{
datarraychargreen[index]=datatotal[i];
index++;
}
i++;
j=i;
index=0;
for(i=j;datatotal[i]!='a';i++)
{
datarraycharblue[index]=datatotal[i];
index++;
}
////arranging the char array
//WE NEED TRUE INTEGER DATA
for(i=0;i<4;i++)
{
if (datarraymodo[3]=='F')
{
datarraymodo[3]=datarraymodo[2];
datarraymodo[2]=datarraymodo[1];
datarraymodo[1]=datarraymodo[0];
datarraymodo[0]='0';
}
}
for(i=0;i<4;i++)
{
if (datarraycharred[3]=='F')
{
datarraycharred[3]=datarraycharred[2];
datarraycharred[2]=datarraycharred[1];
datarraycharred[1]=datarraycharred[0];
datarraycharred[0]='0';
}
}
for(i=0;i<4;i++)
{
if (datarraychargreen[3]=='F')
{
datarraychargreen[3]=datarraychargreen[2];
datarraychargreen[2]=datarraychargreen[1];
datarraychargreen[1]=datarraychargreen[0];
datarraychargreen[0]='0';
}
}
for(i=0;i<4;i++)
{
if (datarraycharblue[3]=='F')
{
datarraycharblue[3]=datarraycharblue[2];
datarraycharblue[2]=datarraycharblue[1];
datarraycharblue[1]=datarraycharblue[0];
datarraycharblue[0]='0';
}
}
datamodo = atoi(datarraymodo);
if(datamodo!=0)
{
datared = atoi(datarraycharred);
datagreen = atoi(datarraychargreen);
datablue = atoi(datarraycharblue);
datared=map(datared,0,1023,0,255);
datagreen=map(datagreen,0,1023,0,255);
datablue=map(datablue,0,1023,0,255);
}
}
void modochill()
{
//when first time on chill mode, set random numbers
if(indexchill==0){
datared=random(170, 255);
datagreen=random(85, 170);
datablue=random(0, 85);
indexchill=1;
}
//after first time just wave the values
if(datared>=250)
{ired=1;}
if(datared<=3)
{ired=0;}
if(ired==0)
{datared=datared+3;}
if(ired==1)
{datared=datared-3;}
if(datagreen>=240)
{igreen=1;}
if(datagreen<=3)
{igreen=0;}
if(igreen==0)
{datagreen=datagreen+3;}
if(igreen==1)
{datagreen=datagreen-3;}
if(datablue>=240)
{iblue=1;}
if(datablue<=3)
{iblue=0;}
if(iblue==0)
{datablue=datablue+3;}
if(iblue==1)
{datablue=datablue-3;}
}
TX, transmitter with three different functions
C/C++just chill, the receiver waves the colours slowly
mode 1 0
read and send analog values
mode 0 1
read colours with rgb sensor
mode 1 1
calibrate rgb sensor
#include <VirtualWire.h>
#define LEDRED A0
#define LEDGREEN A1
#define LEDBLUE A2
#define LIGHTSENSOR A3
#define TX 10
#define buttonA 5
#define buttonB 6
//variables TX - RX
char separador [2] = {"a"};
char datarraycharred[(sizeof(int)*4+1)];
char datarraychargreen[(sizeof(int)*4+1)];
char datarraycharblue[(sizeof(int)*4+1)];
char datamodo[(sizeof(int)*4+1)];
char datatotal[(sizeof(int)*4+3)*3];
int index=0,ired=0,igreen=0,iblue=0;
int datared=0,datagreen=0,datablue=0 ; //cm/seg
int modo=0;
//for led copycat
int ledArray[] = {2,3,4};
int red = 0;
int green = 0;
int blue = 0;
int avgRead;
float colourArray[] = {0,0,0};
float whiteArray[] = {0,0,0};
float blackArray[] = {0,0,0};
void setup() {
pinMode(LEDRED,OUTPUT);
pinMode(LEDGREEN,OUTPUT);
pinMode(LEDBLUE,OUTPUT);
pinMode(LIGHTSENSOR,INPUT);
pinMode(buttonA,INPUT);
pinMode(buttonB,INPUT);
pinMode(TX,OUTPUT);
//ledarray copycat
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
digitalWrite(2,HIGH);
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
Serial.begin(9600);
pinMode(TX, INPUT);
pinMode(TX, OUTPUT);
vw_set_tx_pin(TX); // Configura el pin como TX
vw_set_ptt_inverted(true); // Requerido para DR3100
vw_setup(2000); // Bits por segundo
}
void loop() {
if(digitalRead(buttonA)==0&&digitalRead(buttonB)==0)
modochill();
if(digitalRead(buttonA)==1&&digitalRead(buttonB)==0)
modoanalogico();
if(digitalRead(buttonB)==1)
modoLEDcopycat();
//construccion del array de datos a enviar
strcpy (datatotal,datamodo);
strcat (datatotal,separador);
strcat (datatotal,datarraycharred);
strcat (datatotal,separador);
strcat (datatotal,datarraychargreen);
strcat (datatotal,separador);
strcat (datatotal,datarraycharblue);
strcat (datatotal,separador);
//DEBUG
//Serial.print(datatotal);
Serial.print(" ");
Serial.println(datatotal);
//ENVIO RX
digitalWrite(13, HIGH); // Turn on a light to show transmitting
vw_send((uint8_t *)datatotal, strlen(datatotal));
vw_wait_tx(); // Wait until the whole message is gone
delay(50);
digitalWrite(13, LOW); // Turn off a light after transmission
}
//mode chillout defined at receiver, just freeze the dataflow and send modo=0
void modochill(){
modo=0;
itoa(modo,datamodo,10);//10--> base decimal
}
//mode and data rgb analog
void modoanalogico(){
modo=1;
itoa(modo,datamodo,10);//10--> base decimal
//analog read and int to char conversion
datared=analogRead(LEDRED);
itoa(datared,datarraycharred,10);//10--> base decimal
datagreen=analogRead(LEDGREEN);
itoa(datagreen,datarraychargreen,10);
datablue=analogRead(LEDBLUE);
itoa(datablue,datarraycharblue,10);
}
void modoLEDcopycat()
{
if(digitalRead(buttonA)==1&&digitalRead(buttonB)==1){setBalance();}
for(int i = 0;i<=2;i++){
digitalWrite(ledArray[i],LOW); //turn or the LED, red, green or blue depending which iteration
delay(100); //delay to allow CdS to stabalize, they are slow
getReading(5); //take a reading however many times
colourArray[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
colourArray[i] = (colourArray[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
digitalWrite(ledArray[i],HIGH); //turn off the current LED
delay(100);
}
//rgb con catodo comun , dar la vuelta al valor de intensidad con map
analogWrite(LEDRED,map(colourArray[0],0,255,255,0));
analogWrite(LEDGREEN,map(colourArray[1],0,255,255,0));
analogWrite(LEDBLUE,map(colourArray[2],0,255,255,0));
}
//asymetric blink for humans to notice
void piiipipi(){
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
delay(1000);
digitalWrite(10,HIGH);
digitalWrite(11,HIGH);
digitalWrite(12,HIGH);
delay(500);
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
delay(500);
digitalWrite(10,HIGH);
digitalWrite(11,HIGH);
digitalWrite(12,HIGH);
delay(500);
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
delay(500);
digitalWrite(10,HIGH);
digitalWrite(11,HIGH);
digitalWrite(12,HIGH);
delay(1000);
}
//when two buttons pressed, calibrate the rgb readings with white and black objects
void setBalance(){
piiipipi() ;
for(int i = 0;i<=2;i++){
digitalWrite(ledArray[i],LOW);
delay(100);
getReading(5); //number is the number of scans to take for average, this whole function is redundant, one reading works just as well.
whiteArray[i] = avgRead;
digitalWrite(ledArray[i],HIGH);
delay(100);
}
//done scanning white, now it will pulse blue to tell you that it is time for the black (or grey) sample.
//set black balance
piiipipi() ;
//go ahead and scan, sets the colour values for red, green, and blue when exposed to black
for(int i = 0;i<=2;i++){
digitalWrite(ledArray[i],LOW);
delay(100);
getReading(5);
blackArray[i] = avgRead;
//blackArray[i] = analogRead(2);
digitalWrite(ledArray[i],HIGH);
delay(100);
}
//delay another 5 seconds to allow the human to catch up to what is going on
delay(5000);
}
//get the colour!
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 = analogRead(LIGHTSENSOR);
tally = reading + tally;
delay(10);
}
}
Comments