I am still quite new to arduino coding, so I would very much appreciate your help!
I have recently made a circuit using reed switch and a simple LED light, which makes a light slowly fade out once it is taken away from a magnetic field and light up again once it is close to the magnet.
For my project, I need the LED to produce constant yellow light when it is close to the magnetic field, but as soon as it is taken away, the light has to fade to the red light and fade out in general at the same time.
So simply put:
reed switch "closed" = constant yellow light
reed switch "open" = fading to the red light and fading out at the same time
Bellow is the code that I already have for simple LED and reed switch.
`
int ledPin = 9;
int reedPin = 2;
int brightness = 0;
int fadeAmount = 5;
unsigned long timestamp = 0;
void setup(){
pinMode(ledPin, OUTPUT);
pinMode(reedPin, INPUT_PULLUP);
}
void loop(){
if(millis()-timestamp > 30){
brightness = brightness - fadeAmount;
if(brightness < 0) brightness = 0;
timestamp = millis();
}
if(!digitalRead(reedPin)){
brightness = 255;
}
analogWrite(ledPin, brightness);
}
//different code begins here
int rVal = 254;
int gVal = 1;
int bVal = 127;
int rDir = -1;
int gDir = 1;
int bDir = -1;
const int rPin = 11;
const int gPin = 10;
const int bPin = 9;
void setup() {
pinMode(rPin, OUTPUT);
pinMode(gPin, OUTPUT);
pinMode(bPin, OUTPUT);
}
void loop() {
analogWrite(rPin, rVal);
analogWrite(gPin, gVal);
analogWrite(bPin, bVal);
// change the values of the LEDs
rVal = rVal + rDir;
gVal = gVal + gDir;
bVal = bVal + bDir;
if (rVal >= 255 || rVal <= 0) {
rDir = rDir * -1;
}
if (gVal >= 255 || gVal <= 0) {
gDir = gDir * -1;
}
if (bVal >= 255 || bVal <= 0) {
bDir = bDir * -1;
}
delay(33);
}
}
`
Bottom one is the code that makes RGB led crossfade different colours, but I need it to go from yellow to red. How could I do that? And how can I incorporate the RGB light code into reed switch code?
You achieve yellow with the green and red emitter at the same level.
In order to fade to red you need to decrease the green emitter to 0.
This of course will also decrease the overall brightness.
Once you faded out green you can fade red to 0.
Of course you can also fade out both leds at the same time. Fading the green component faster will also move the colour towards red.
That's personal preference
Related
good morning!
I wanted to ask if someone can guide me through this code because even if I try, I can't make it work. What I want to do is to be able to change if individual leds illuminate or not. I have a 60 LEDs on my strip. Thank you.
else
{
Serial.println ("Someone Is Infront Of the Sensor");
for (uint8_t i = 0; i < strip.numPixels(); i++) {
if (i <= secondval) {
pixelColorBlue = (i + 1) * (128 / (secondval + 1));
//pixelColorBlue = 255;
}
else {
pixelColorBlue = 0;
}
strip.setPixelColor((i + STARTPIXEL) % 60, strip.Color(pixelColorBlue));
}
strip.show();
delay(100);
}
is this Neo ?
you can try the simple
void loop() {
for(int i=0;i<NUMPIXELS;i++){
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(0,100,0)); // Moderately bright green
pixels.show(); // This sends the updated pixel color to the hardware.
delay(500); // Delay for a period of time (in milliseconds).
}
}
I'm working on a program for an addressable LED strip. It is working and at this point I'm trying to make my code better. I have 3 LED strips and I made a function which all three has to do. In the function I want to specify which one needs to be updated so I used attributes, but this doesn't seem to work. I can't find this on the FastLed documentation.
//Number of leds powered
int led_state_1 = 0;
int led_state_2 = 0;
int led_state_3 = 0;
// This is an array of leds. One item for each led in your strip.
CRGB leds1[NUM_LEDS];
CRGB leds2[NUM_LEDS];
CRGB leds3[NUM_LEDS];
void CheckAndUpdateLed(CRGB LedArray, int led_state){
resetLedStrip(LedArray);
for(int whiteLed = 0; whiteLed < led_state; whiteLed = whiteLed + 1) {
// Turn our current led on to white, then show the leds
LedArray[whiteLed] = CRGB::White;
// Show the leds (only one of which is set to white, from above)
FastLED.show();
}
}
When I change LedArray to leds1 it is working. I'm calling the function as CheckAndUpdateLed(leds1, led_state_1);
I think my question was a bit unclear sorry for that. I came up with another way of doing this. Instead of 1 led strip I check them all in the same function.
#define NUM_STRIPS 3
#define NUM_LEDS_PER_STRIP 15
CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];
int led_states[] = {0, 0, 0};
void CheckAndUpdateLeds(){
//resets the leds to black
resetLedStrips();
// This outer loop will go over each LED strip, one at a time
for(int x = 0; x < NUM_STRIPS; x++) {
// This inner loop will go over each led in the current strip, one at a time till the amount of light is the same as in the led_state
for(int led = 0; led < led_states[x]; led = led + 1) {
// Turn our current led on to white, then show the leds
leds[x][led] = CRGB::White;
FastLED.show();
}
}
}
void resetLedStrips(){
for(int x = 0; x < NUM_STRIPS; x++) {
for(int led = 0; led < NUM_LEDS_PER_STRIP; led = led + 1) {
leds[x][led] = CRGB::Black;
}
}
}
I am trying to make a led controller for my room rgb led strip.
I am using arduino uno. I want two pushbuttons:
controls static colors of led (one color at a time.cycles color on pressing that same switch again)
rgb crossfade
Both programs work separately. Now I want these two programs in one sketch and toggled by two pushbuttons one for color cycle and one for crossfade
sketch works but only one pushbutton is working.
I have connected 2 10k ohm resistors with both buttons according to various guides and tutorials. I think the wiring is correct.
Here is the sketch:
const int buttonPin1 = 2; // button 1
const int buttonPin2 = 3; // button 2
const int redPin = 9; // red led pin
const int greenPin = 11; // green led pin
const int bluePin = 10; // blue led pin
int pushCounter = 0; // push counter for changing colors at each press
int buttonState = 0; // button state i.e. HIGH or LOW
int lastButtonState = 0;
void setup()
{
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
setColourRgb(0,0,0);
}
void setColor(int red, int green, int blue) // function for setting custom colors
{
//#ifdef COMMON_ANODE
//red = 255 - red;
//green = 255 - green;
//blue = 255 - blue;
//#endif
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) { //function for setting crossfade colors
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
void loop()
{
int buttonState1 = 0;
int buttonState2 = 0;
buttonState1 = digitalRead(buttonPin1); //reads button states
buttonState2 = digitalRead(buttonPin2);
if ((buttonState1 == HIGH) && (buttonState2 == LOW)) //compares button states of both switches to enable the correct program
{
buttonState = digitalRead(buttonPin1);
if (buttonState != lastButtonState)
{
if (buttonState == HIGH) //increases pushcounter of button1 on every press
{
pushCounter++;
}
}
//delay(1);
lastButtonState = buttonState;
if (pushCounter == 1) //custom led colors
{ setColor(255, 0, 0);}; //red
if (pushCounter == 2)
{ setColor(0, 255, 0);}; //green
if (pushCounter == 3)
{ setColor(0, 0, 255);}; //blue
if (pushCounter == 4)
{ setColor(255,200,255);}; //white
if (pushCounter == 5)
{ setColor(255,255,0);}; //lime
if (pushCounter == 6)
{ setColor(0,255,255);}; //aqua
if (pushCounter == 7)
{ setColor(255,0,255);}; //violet
if (pushCounter == 8)
{ setColor(128,0,128);}; //dim_violet
if (pushCounter == 9)
{ pushCounter = 0;}
}
if ((buttonState1 == LOW) && (buttonState2 == HIGH)) //compares button states to load second program
{
unsigned int rgbColour[3];
// Start off with red.
rgbColour[0] = 255; //sets first color
rgbColour[1] = 0;
rgbColour[2] = 0;
// Choose the colours to increment and decrement.
for (int decColour = 0; decColour < 3; decColour += 1)
{
int incColour = decColour == 2 ? 0 : decColour + 1;
// cross-fade the two colours.
for(int i = 0; i < 255; i += 1)
{
rgbColour[decColour] -= 1;
rgbColour[incColour] += 1;
setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);
delay(30);
}
}
};
}
Now if I reverse the if condition for second program... the second program runs but the first doesn't run. What is wrong here?
Since you are reading from two buttons you need to do some debouncing.
Something like you've done but a bit better :)
There is a library that does this for you and can be downloaded from Arduino web
Once downloaded Change the #include "WProgram.h" to #include "Arduino.h" in Debounce.cpp and you should be good to go.
below is the implementation of the lib with your code.
From what described the logic is right.
#include <Debounce.h>
#define buttonPin1 2 // button 1
#define buttonPin2 3 // button 2
#define redPin 9 // red led pin
#define greenPin 11 // green led pin
#define bluePin 10 // blue led pin
#define debounceTime 20 // debounce time
int pushCounter = 0; // push counter for changing colors at each press
int buttonState = 0; // button state i.e. HIGH or LOW
int lastButtonState = 0;
// Instantiate a Debounce object
Debounce button1 = Debounce(debounceTime, buttonPin1); //for button 1
Debounce button2 = Debounce(debounceTime, buttonPin2); //for button 2
void setup()
{
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
setColourRgb(0,0,0);
}
void loop()
{
//update debounce stat for both buttons
button1.update();
button2.update();
int button1State = button1.read(); //reads button states
int button2State = button2.read();
if ((button1State == 1) && (button2State == 0)) //compares button states of both switches to enable the correct program
{
//Since we are checking for the first button being HIGH or 1 we can increament the counter
pushCounter++;
/*
buttonState = button1State;
if (buttonState != lastButtonState)
{
if (buttonState == HIGH) //increases pushcounter of button1 on every press
{
pushCounter++;
lastButtonState = buttonState;
}
}
*/
//delay(1);
switch (pushCounter)
{
case 1:
setColor(255, 0, 0); //red
break;
case 2:
setColor(0, 255, 0); //green
break;
case 3:
setColor(0, 0, 255); //blue
break;
case 4:
setColor(255,200,255); //white
break;
case 5:
setColor(255,255,0); //lime
break;
case 6:
setColor(0,255,255); //aqua
break;
case 7:
setColor(255, 0, 0); //violet
break;
case 8:
setColor(128,0,128); //dim_violet
break;
case 9:
pushCounter = 0; // reset the counter
break;
}
}
else if ((button1State == 0) && (button2State == 1)) //compares button states to load second program
{
unsigned int rgbColour[3];
// Start off with red.
rgbColour[0] = 255; //sets first color
rgbColour[1] = 0;
rgbColour[2] = 0;
// Choose the colours to increment and decrement.
for (int decColour = 0; decColour < 3; decColour++)
{
int incColour = decColour == 2 ? 0 : decColour + 1;
// cross-fade the two colours.
for(int i = 0; i < 255; i += 1)
{
rgbColour[decColour] -= 1;
rgbColour[incColour] += 1;
setColourRgb(rgbColour[0], rgbColour[1], rgbColour[2]);
delay(30);
}
}
}
}
void setColor(int red, int green, int blue) // function for setting custom colors
{
//#ifdef COMMON_ANODE
//red = 255 - red;
//green = 255 - green;
//blue = 255 - blue;
//#endif
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
void setColourRgb(unsigned int red, unsigned int green, unsigned int blue) { //function for setting crossfade colors
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
im having a problem, i just bought an arduino and i was wondering if anyone could help, here is my code. (i am just trying to get two leds to fade in and out).
int ledCount = 2;
int ledPins [ ] = {11,12 };
int brightness = 0;
int delayTime = 10;
void setup() {
pinMode(ledPins, OUTPUT);
}
void loop() {
while(brightness < 255)
{
analogWrite(ledPins, brightness);
delay(delayTime);
brightness = brightness + 1;
}
while(brightness > 0)
{
analogWrite(ledPins, brightness);
delay(delayTime);
brightness = brightness - 1;
}
}
You are passing an array to analogWrite or pinMode, where it is expecting a uint8_t.
Arduino pin manipulation functions will only handle a single pin at a time. There are ways around that, by directly manipulating the AVR/ARM GPIO registers, but those can be finicky (not recommended for use unless you really need speed).
The reason it says int * is because under the hood, arrays in C/C++ are represented as pointers.
If you want to analogWrite or pinMode to both LEDs, you will have to call the function once for each LED. Example:
analogWrite(ledPins[0], brightness);
analogWrite(ledPins[1], brightness);
Or
for(int currentLED = 0;currentLED < ledCount;i++){
analogWrite(ledPins[currentLED], brightness);
}
In the context of your program:
int ledCount = 2;
int ledPins [] = {11, 12};
int brightness = 0;
int delayTime = 10;
#define INCREASE 1
#define DECREASE 2
int brightness_change = INCREASE;
void setup(){
for(int i = 0;i < ledCount;i++){
pinMode(i, OUTPUT);
}
}
void loop(){
while(brightness < 255 && brightness_change == INCREASE){
brightness = brightness + 1;
}
while(brightness > 0 && brightness_change == DECREASE){
brightness = brightness - 1;
}
if(brightness == 255){
brightness_change = DECREASE;
}
if(brightness == 0){
brightness_change = INCREASE;
}
for(int current_led = 0;current_led < ledCount;current_led++){
analogWrite(current_led, brightness;
}
delay(delayTime;
}
Not tested, but it should work.
I am working on a stereo controller and have 1 rotary encoder with a push button. When I push the button it cycles through the options and the rotary encoder lets me set the intensity. I want the individual intensities to remain when I am switching back and forth. When I turn the bass to 50% and then set the volume to 80% I want to come back and the base still be at 50%. The problem I am having is that the intensities are transferring over.
For prototyping I am using 3 LEDS. I can set individual brightness but when I go to change the next LED it automatically changes to the intensity of the previous LED.
The reasoning behind this is that when I set the bass and treble and the volume I don't want the values jumping around when I come back to change something. I want to pick off where it left off.
I think the structure I am going for is a counter based on cases. A common variable outside the case is incremented by the rotary encoder and then stored in case if that is possible.
/*
** Rotary Encoder Example
** Use the Sparkfun Rotary Encoder to vary brightness of LED
**
** Sample the encoder at 200Hz using the millis() function
*/
int brightness = 0; // how bright the LED is, start at half brightness
int fadeAmount = 30; // how many points to fade the LED by
unsigned long currentTime;
unsigned long loopTime;
const int pin_A = 4; // pin 12
const int pin_B = 5; // pin 11
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
const int green = 11;
const int blue = 10;
const int red=9;
int last_bright=0;
int mode = 0; // Selector State (Initial state = ALL OFF)
int val = 0; // Pin 13 HIGH/LOW Status
int butState = 0; // Last Button State
int modeState = 0;
int selected=710;
int greenvol=0;
int redvol=0;
int bluevol=0;
int select_bright=0;
void setup() {
// declare pin 9 to be an output:
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(pin_A, INPUT);
pinMode(pin_B, INPUT);
currentTime = millis();
loopTime = currentTime;
}
void loop() {
// get the current elapsed time
currentTime = millis();
brightness=select_bright;
if(currentTime >= (loopTime + 5)){
// 5ms since last check of encoder = 200Hz
encoder_A = digitalRead(pin_A); // Read encoder pins
encoder_B = digitalRead(pin_B);
if((!encoder_A) && (encoder_A_prev)){
// A has gone from high to low
if(encoder_B) {
// B is high so clockwise
// increase the brightness, dont go over 255
if(brightness + fadeAmount <= 255) brightness += fadeAmount;
}
else {
// B is low so counter-clockwise
// decrease the brightness, dont go below 0
if(brightness - fadeAmount >= 0) brightness -= fadeAmount;
}
}
encoder_A_prev = encoder_A; // Store value of A for next time
// set the brightness of pin 9:
analogWrite(selected, brightness);
last_bright=brightness;
loopTime = currentTime; // Updates loopTime
}
// end of rotary encoder
val = digitalRead(8);
delay(5);
// If we see a change in button state, increment mode value
if (val != butState && val == HIGH){
mode++;
}
butState = val; // Keep track of most recent button state
// No need to keep setting pins *every* loop
if (modeState != mode)
// If no keys have been pressed yet don't execute
// the switch code below
{
switch ( mode ) {
case 2:
selected=red;
select_bright=redvol;
redvol=last_bright;
break;
case 3:
selected=green;
select_bright=greenvol;
greenvol = last_bright;
break;
default:
selected=blue;
select_bright=bluevol;
bluevol = last_bright;
mode = 1;
break;
}
}
}
I'd store the brightness value in an array and then use an index to change only one led.
Here is a (i hope) working example. Try it and see if it fits your needs ;)
I made some other changes (you can see them in the comments). Anyway I suggest you to add at least
debouncing on the encoder and the button pins
the complete encoder checking, i.e. check if either A or B changed, and in both directions.
Here is the code; just let me know ;)
byte fadeAmount = 30;
const byte pin_button = 8;
const byte pin_A = 4; // pin 12
const byte pin_B = 5; // pin 11
unsigned long loopTime;
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
// Array to store the brightness of the
// red (0), green (1) and blue (2) leds
byte brightnesses[3];
byte lastbrightnesses[3];
byte currentLed;
// Pins for red (0), green (1) and blue (2) leds
byte led_pins[] = {9, 10, 11};
void setup() {
pinMode(pin_button, INPUT);
pinMode(pin_A, INPUT);
pinMode(pin_B, INPUT);
// set the brightnesses to their initial states
// and the lastbrightnesses to ANOTHER value
for (currentLed=0; currentLed<3; i++)
{
pinMode(led_pins[currentLed], OUTPUT);
brightnesses[currentLed] = 255;
lastbrightnesses[currentLed] = 0;
}
currentLed = 0;
loopTime = millis() - 5;
}
void loop() {
// I prefer this instead of yours
// because this is overflow-safe
if((millis() - loopTime) >= 5) {
loopTime += 5;
// Check encoder
encoder_A = digitalRead(pin_A);
encoder_B = digitalRead(pin_B);
if((!encoder_A) && (encoder_A_prev)){
// A has gone from high to low
if(encoder_B) {
// B is high so clockwise
// Again, this is overflow-safe
// And it compensates for not reaching the end of the values
if(brightnesses[currentLed] <= 255 - fadeAmount)
brightnesses[currentLed] += fadeAmount;
else
brightnesses[currentLed] = 255;
}
else {
// B is low so counter-clockwise
// decrease the brightness, dont go below 0
if(brightnesses[currentLed] >= fadeAmount)
brightnesses[currentLed] -= fadeAmount;
else
brightnesses[currentLed] = 0;
}
}
encoder_A_prev = encoder_A; // Store value of A for next time
// I'd read the button every 5ms too
val = digitalRead(pin_button);
if (val != butState && val == HIGH){
currentLed++;
if (currentLed >= 3) currentLed = 0;
butState = val;
}
}
// Here you can also check only currentLed instead
// of every led if you can only change it through
// the encoder
byte i;
for (i=0; i<3; i++)
{
if (lastbrightnesses[i] != brightnesses[i])
{
analogWrite(led_pins[i], brightnesses[i]);
lastbrightnesses[i] = brightnesses[i];
}
}
}