Go Down

Topic: control RGB LED, LED, servo motor with one button (Read 965 times) previous topic - next topic

jimmii

hellooo! Im a beginner, and Im working on a little project.
I wanted to control(basically on/off) a RGB LED, a LED, a servo motor with one button.
when I tried each actions - on/off RGB LED with a button, on/off LED+servo motor with a button - and they worked perfectly fine.

so I put those codes together, and it is ehhh working, but not alright.
the problem is, only blue colour is on (of RGB LED)

is it because of the power? because servo motor need much power and so RGB LED does.

or is there something wrong with the code?

this is the code I used, (thanks to people who kindly posted their codes. those helped me a lot!)

Quote

//on LED when btn is pushed, off LED when btn pushed again.
//final code
#define POS 8//POS = LED
#define BTN 2
#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int rpin = 9;
int gpin = 10;
int bpin = 11;
int val = 0; // val = used for save the state of input pin
int old_val = 0; //to save old val's former state
int state = 0; //0=led off /1=led on
int pos = 0;    // variable to store the servo position
int fadered = 0;

//function prototypes
void solid(int r, int g, int b, int t);
void fade(int r1, int g1, int b1, int r2, int g2, int b2, int t);

void setup() {
 pinMode(POS, OUTPUT);
 pinMode(BTN, INPUT);
 myservo.attach(3);  // attaches the servo on pin 9 to the servo object
}

void loop() {
 val = digitalRead(BTN);  //save the input amount by reading it. um~new data!
 if ((val==HIGH) && (old_val==LOW)) {
 state = 1 - state;
 delay(10);
 }
 
 old_val = val;  //val=former amout. save
 if (state ==1) {
   fade(255,0,0,0,255,0,500); //fade from red to green over 5 seconds
   fade(0,255,0,0,0,255,500); //fade from green to blue over 5 seconds
   fade(0,0,255,255,0,0,500); //fade from blue to red over 5 seconds
   
   digitalWrite(POS, HIGH);
   
   myservo.write(160);
   delay(500);
   myservo.write(20);
   delay(500);

 } else {
   analogWrite(rpin, LOW);
   analogWrite(gpin, LOW);
   analogWrite(bpin, LOW);
   
   digitalWrite(POS, LOW);
   
   myservo.write(160);
   delay(10);
 }
}

//function holds RGB values for time t milliseconds
void solid(int r, int g, int b, int t) {
 //map values - arduino is sinking current, not sourcing it
 r = map(r, 0, 255, 255, 0);
 g = map(g, 0, 255, 255, 0);
 b = map(b, 0, 255, 255, 0);

 //output
 analogWrite(rpin,r);
 analogWrite(gpin,g);
 analogWrite(bpin,b);
 
 //hold at this colour set for t ms
 delay(t);
}

//function fades between two RGB values over fade time period t
//maximum value of fade time = 30 seconds before gradient values
//get too small for floating point math to work? replace floats
//with doubles to remedy this?
void fade(int r1, int g1, int b1, int r2, int g2, int b2, int t) {
 float r_float1, g_float1, b_float1;
 float r_float2, g_float2, b_float2;
 float grad_r, grad_g, grad_b;
 float output_r, output_g, output_b;
 
 //declare integer RGB values as float values
 r_float1 = (float) r1;
 g_float1 = (float) g1;
 b_float1 = (float) b1;
 r_float2 = (float) r2;
 g_float2 = (float) g2;
 b_float2 = (float) b2;
 
 //calculate rates of change of R, G, and B values
 grad_r = (r_float2-r_float1)/t;
 grad_g = (g_float2-g_float1)/t;
 grad_b = (b_float2-b_float1)/t;
 
 //loop round, incrementing time value "i"
 for ( float i=0; i<=t; i++ )  {
   output_r = r_float1 + grad_r*i;
   output_g = g_float1 + grad_g*i;
   output_b = b_float1 + grad_b*i;
   
   //map values - arduino is sinking current, not sourcing it
   output_r = map (output_r,0,255,255,0);
   output_g = map (output_g,0,255,255,0);
   output_b = map (output_b,0,255,255,0);
   
   //output
   analogWrite(rpin, (int)output_r);
   analogWrite(gpin, (int)output_g);
   analogWrite(bpin, (int)output_b);
   
   //hold at this colour set for 1ms
   delay(0.5);//higher number = holds it longer
   }
}



PaulS

Code: [Select]
output_r = map (output_r,0,255,255,0);
This is an absolutely hideous way of accomplishing this:
Code: [Select]
output_r =255 - output_r;
This is especially true since output_r is a float, and map expects integer arguments.

Code: [Select]
  //hold at this colour set for 1ms
  delay(0.5);//higher number = holds it longer

The delay function expects a time in milliseconds, as an integer. You are asking it to wait 1/2 a millisecond. First off, this is far too short a duration to be noticeable, and second, 0.5 gets truncated to 0, and delay(0); causes unpredictable results.

Quote
is it because of the power? because servo motor need much power and so RGB LED does.

How are you powering the servo? Not directly from the Arduino, I hope. If that is the case, get yourself a proper power supply for the servo.

Code: [Select]
  fade(255,0,0,0,255,0,500); //fade from red to green over 5 seconds
Hint: 500 milliseconds is NOT 5 seconds. If you are going to have useless comments, at least make them correct.

marklar

In the code below, as mentioned in the last post, your delay of .5 is truncated to 0 in the fade function.  So the below code runs through the fade at full speed, way faster than you can see and the result is naturally just the final color.

Code: [Select]

 fade(255,0,0,0,255,0,500); //fade from red to green over 5 seconds
  fade(0,255,0,0,0,255,500); //fade from green to blue over 5 seconds
  fade(0,0,255,255,0,0,500); //fade from blue to red over 5 seconds


If you update the delay in fade (maybe a global variable you can use to effect fade speed) .. then you should be good to go.

Go Up