I have a strip of Neopixels that I'm using for underglow on my bed. Recently, I decided to add a sound sensor so that I can clap once to toggle the light animations I'm using either on or off. Now I'm just running into trouble getting my code to work. I can turn the lights on but I can't clap again to turn them off. What I suspect may be the problem is the fact that I only give the condition for the light animation to be turned off at the end of the while loop that I use to run the light animations, however, I have no idea what I can do to fix that. Can somebody help me on this?
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
int soundSensor = 2;
int LED = 13;
void setup()
{
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
strip.begin();
strip.show(); // Initialize all pixels to 'off'
pinMode (soundSensor, INPUT);
pinMode (LED, OUTPUT);
}
void loop()
{
int toggle = 0;
int statusSensor = digitalRead (soundSensor);
if (statusSensor == 1 && toggle == 0)
{
toggle= 1;
digitalWrite(LED, HIGH);
//statusSensor = 0;
statusSensor = digitalRead (soundSensor);
}
//NEOPIXEL CODE:
while (toggle == 1)
{
digitalWrite(LED, HIGH);
delay(200);
digitalWrite(LED, LOW);
delay(200);
digitalWrite(LED, HIGH);
delay(200);
digitalWrite(LED, LOW);
digitalWrite(LED,HIGH);
colorWipe(strip.Color(255, 0, 0), 50); // Red
colorWipe(strip.Color(0, 255, 0), 50); // Green
colorWipe(strip.Color(255,255,255), 50); //White
colorWipe(strip.Color(255,255,255), 50);
colorWipe(strip.Color(0, 0, 255), 50); // Blue
rainbow(20);
rainbowCycle(20);
if(statusSensor == 1){
toggle = 0;
}
}
if (statusSensor == 1 && toggle == 1)
{
toggle = 0;
digitalWrite(LED, LOW);
}
}
//NEOPIXEL Functions:
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
When you set toggle to 0, you don't write any colors to the neo-pixel strip. So they will just be left in whatever state they were in. You can fix this by just setting them all to "black" (i.e. off) when you set the toggle to zero:
if(statusSensor == 1) {
toggle = 0;
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(strip.Color(0,0,0));
}
strip.show();
}
You don't need any delay here if you just want them to turn out straight away, but perhaps you could make them fade down?
Related
I am working on a project to control a DC motor rotation in forward and backward with an H-Bridge. And light up an adafruit neopixel same time when circuit turns on.
I made both things working separately. Now I combined the code but its not working as should. It works like the dc motor does one forward and back loop and stops. Then the neopixel ring lights up. After some time when the neopixel code finishes, the dc motor does same one loop and this cycle continues.
I need help in making this code start dc motor working and neo pixel lighting same time.
Here is the code:
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
//DC motor
const int pwm = 3; //initializing pin 2 as pwm
const int in_1 = 8 ;
const int in_2 = 7 ;
//For providing logic to L298 IC to choose the direction of the DC motor
void setup()
{
pinMode(pwm,OUTPUT) ; //we have to set PWM pin as output
pinMode(in_1,OUTPUT) ; //Logic pins are also set as output
pinMode(in_2,OUTPUT) ;
//Neopixel Ring
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop()
{
//For Clock wise motion , in_1 = High , in_2 = Low
digitalWrite(in_1,HIGH) ;
digitalWrite(in_2,LOW) ;
analogWrite(pwm,255) ;
/*setting pwm of the motor to 255
we can change the speed of rotaion
by chaning pwm input but we are only
using arduino so we are using higest
value to driver the motor */
//Clockwise for 3 secs
delay(1000) ;
//For brake
digitalWrite(in_1,HIGH) ;
digitalWrite(in_2,HIGH) ;
delay(50) ;
//For Anti Clock-wise motion - IN_1 = LOW , IN_2 = HIGH
digitalWrite(in_1,LOW) ;
digitalWrite(in_2,HIGH) ;
delay(1000) ;
//For brake
digitalWrite(in_1,HIGH) ;
digitalWrite(in_2,HIGH) ;
delay(50) ;
//Neopixel Ring
// Some example procedures showing how to display to the pixels:
colorWipe(strip.Color(255, 0, 0), 50); // Red
colorWipe(strip.Color(0, 255, 0), 50); // Green
colorWipe(strip.Color(0, 0, 255), 50); // Blue
//colorWipe(strip.Color(0, 0, 0, 255), 50); // White RGBW
// Send a theater pixel chase in...
theaterChase(strip.Color(127, 127, 127), 50); // White
theaterChase(strip.Color(127, 0, 0), 50); // Red
theaterChase(strip.Color(0, 0, 127), 50); // Blue
rainbow(20);
rainbowCycle(20);
theaterChaseRainbow(50);
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
Essentially every time you call delay, the arduino cannot do anything else. So you need to switch control to whatever else you wanted to be doing.
There are several approaches:
Timers - use a timer to update the state of one of your two tasks. This has the advantage that your tasks don't rely on the other to yield, but doesn't grow beyond a couple of tasks.
Software state machine - create a state machine for each task, and in the loop increment each state machine in turn. You'll want to create a structure to keep track of the state of the task, and each time you would call delay you'd instead update the structure and return. Usually you'd create a class for each task, as is done in this Adafruit tutorial. This can be a lot of work, so there are libraries to do it for you.
Coroutines - these use a library to construct the state machines for you. e.g. http://forum.arduino.cc/index.php?topic=256256.0
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);
}
I am having some issues with my code. What I want it to do:
Fade in leds 0-12
Delay 0.5 sec
Fade in leds 13-26
Delay (x amount)
Fade out leds 0-12
Delay 0.5 sec ( same as above)
Fade out leds 13-26
What it does:
Fade in leds 0-12
Delay (x amount)
Fade out leds 0-12
Fade in leds 13-26
Delay (x amount)
-Fade out leds 13-26
Here is my code:
#include <Adafruit_NeoPixel.h>
#define SENSORPIN 4
#define LEDPIN 13
// variables will change:
int sensorState = 0, lastState=0; // variable for reading the pushbutton status
int PIN = 6;
int totalLEDs = 26;
int ledFadeTime = 10;
int lightuptime = 7000;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(totalLEDs, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
pinMode(SENSORPIN, INPUT);
digitalWrite(SENSORPIN, HIGH); // turn on the pullup
Serial.begin(9600);
}
void loop() {
// read the state of the sensor value:
sensorState = digitalRead(SENSORPIN);
// check if the sensor beam is broken
// if it is, the sensorState is LOW:
if (sensorState == LOW) {
rgbFadeInAndOut(255, 255, 255, ledFadeTime,0,13);
delay(50);
rgbFadeInAndOut(255, 255, 255, ledFadeTime,13,26);
}
else {
}
lastState = sensorState;
}
void rgbFadeInAndOut(uint8_t red, uint8_t green, uint8_t blue, uint8_t wait, uint8_t ledStart, uint8_t ledEnd) {
for(uint8_t b = 0; b <255; b++) {
for(uint8_t i=ledStart; i < ledEnd; i++) {
strip.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
}
delay(25);
strip.show();
//delay(wait);
};
delay(lightuptime);
for(uint8_t b=255; b > 0; b--) {
for(uint8_t i = ledStart; i < ledEnd; i++) {
strip.setPixelColor(i, red * b/255, green * b/255, blue * b/255);
if(b==1){
strip.setPixelColor(i, 0, 0, 0);
}
}
strip.show();
delay(wait);
};
};
What am I missing?
Your function rgbFadeInAndOut will fade in and then fade out the specified Leds before returning control to the calling function.
If you want your desired behaviour, just split the fade In and fade Out in two separate functions: rgbFadeIn(...) and rgbFadeOut(...)
then you do:
rgbFadeIn(0..12);
delay(500); // note that 0.5 seconds is 500ms not 50
rgbFadeIn(13..26);
delay(x amount)
rgbFadeOut(0..12);
delay(500);
rgbFadeOut(13..26);
I am trying to work with this chip:
https://www.adafruit.com/products/1655? ... fgodFpsAow
+
a Attiny85
The code I am using is below, it works fine with an Arduino but not with the Attiny85 (just turns on and stays between 2 colors green and yellow). Any ideas? Thanks!
My ATtiny is set at 8 Mhz with a 800Khz data stream in the neopixel.h library.
Code is below.
#include <Adafruit_NeoPixel.h>
/*
WS2811/Neopixel pattern switcher for ATtiny85 (and Arduino)
Requires Adafruit NeoPixel Library
WS2811 Signal, Digital Pin 4
Button, Digital Pin 0
GPL v3
*/
/*
shin:random pattern selector
*/
// Define
#define NUM_LEDS 1 //60LED per strip
#define DATA_PIN 0 //output pin on ATTiny85
#define BTN_PIN 1 //input pin on ATTiny85
#define BTN_DELAY 250 //add delay for debounce
#define NUM_PATTERNS 12 //patterns avail
#define CTR_THRESH 16
// Init Vars
uint8_t j = 0;
uint8_t pattern=1;
uint8_t buttonState=0;
uint8_t lastPix=0;
uint8_t myPix=0;
uint8_t direction=1;
uint8_t counter=0;
uint8_t colors[3];
uint32_t setColor=0;
unsigned long mark;
// Start Strip
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
//pinMode(BTN_PIN, INPUT);
randomSeed(BTN_PIN);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// if button pressed, advance, set mark
//chkBtn(digitalRead(BTN_PIN));
int rand = random(1,13);//1to12
// if pattern greater than #pattern reset
//if (pattern > NUM_PATTERNS) { pattern = 1; }
if (rand > NUM_PATTERNS) { pattern = 1; }
// choose a pattern
//pickPattern(pattern);
pickPattern(rand);
// set direction
if (direction == 1) { j++; } else { j--; }
if (j > 254) { direction = 0; }
if (j < 1) { direction = 1; }
}
/* pick a pattern */
void pickPattern(uint8_t var) {
switch (var) {
case 1:
// scanner, color and delay - RGB
scanner(strip.Color(255,0,0),50);
scanner(strip.Color(200,0,100),50);
scanner(strip.Color(64,0,200),50);
break;
case 2:
// color wipe random RGB
colorWipe(strip.Color(random(255), random(255), random(255)),50);
break;
case 3:
// color wave - Hue/Sat/Bright
// hue low (0-359), high (0-359),rate,extra delay
wavey(200,240,0.06,0);
break;
case 4:
// rainbow firefly, 1px at random
colorFirefly(60);
counter++;
break;
case 5:
// rainbow solid
rainbow(10);
counter++;
break;
case 6:
// bounce in and out
// tail len, counter, delay
bounceInOut(4,counter,20);
counter++;
break;
case 7:
// color wipe from center
colorWipeCenter(strip.Color(255,0,0),100);
colorWipeCenter(strip.Color(255,64,0),100);
break;
case 8:
// solid color
colorFast(strip.Color(255,0,0),0);
break;
case 9:
// fade even or odd
// 0-359 Hue value, even/odd, delay
fadeEveOdd(200,0,20);
fadeEveOdd(300,1,20);
break;
case 10:
// show rainbow
rainbowCycle(10);
break;
case 11:
// show rainbow
theaterChaseRainbow(50);
break;
case 12:
rainbowCycle2(20);
break;
}
}
/* check button state */
boolean chkBtn(int buttonState) {
if (buttonState == HIGH && (millis() - mark) > BTN_DELAY) {
j = 0;
mark = millis();
pattern++;
return true;
}
else { return false; }
}
void colorFirefly(int wait) {
if(myPix != lastPix) {
if(counter<CTR_THRESH) {
float colorV = sin((6.28/30)*(float)(counter)) *255;
HSVtoRGB((359/CTR_THRESH)*counter, 255, colorV, colors);
strip.setPixelColor(myPix, colors[0], colors[1], colors[2]);
strip.show();
delay(wait);
} else {
lastPix=myPix;
counter=0;
colorFast(0,0);
}
} else {
myPix=random(0,strip.numPixels());
}
}
// Fill the dots one after the other with a color
// Modified from Neopixel sketch to break on button press
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
if(chkBtn(digitalRead(BTN_PIN))) { break; }
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
// color wipe from center
void colorWipeCenter(uint32_t c, uint8_t wait) {
uint8_t mid=strip.numPixels()/2;
strip.setPixelColor(mid,c);
for(uint16_t i=0; i<=strip.numPixels()/2; i++) {
if(chkBtn(digitalRead(BTN_PIN))) { break; }
strip.setPixelColor(mid+i, c);
strip.setPixelColor(mid-i, c);
strip.show();
delay(wait);
}
}
// fast version
void colorFast(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
}
strip.show();
delay(wait);
}
// Rainbow Cycle, modified from Neopixel sketch to break on button press
void rainbowCycle(uint8_t wait) {
uint16_t i;
// for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
// }
}
void rainbow(uint8_t wait) {
uint16_t i;
//for(j=0; j<256; j++) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i + j) & 255));
}
strip.show();
delay(wait);
// }
}
// scanner
void scanner(uint32_t c,uint8_t wait) {
for(int i=0; i< strip.numPixels(); i++) {
if(chkBtn(digitalRead(BTN_PIN))) { break; }
colorFast(0,0);
strip.setPixelColor(i,c);
strip.show();
delay(wait);
}
for(int i=strip.numPixels(); i>0; i--) {
if(chkBtn(digitalRead(BTN_PIN))) { break; }
colorFast(0,0);
strip.setPixelColor(i,c);
strip.show();
delay(wait);
}
}
// scanner to midpoint
void bounceInOut(uint8_t num, uint8_t start,uint8_t wait) {
colorFast(0,0);
uint8_t color=200;
for(int q=0; q < num; q++) {
if(strip.numPixels()-start >= 0 && start < NUM_LEDS) {
strip.setPixelColor(start+q, strip.Color(0,color,0));
strip.setPixelColor(strip.numPixels()-start-q, strip.Color(0,color,0));
}
color=round(color/2.0);
strip.show();
delay(wait);
}
if(counter > strip.numPixels()) { counter=0; }
}
void fadeEveOdd(int c1,byte rem,uint8_t wait) {
for(int j=0; j < CTR_THRESH; j++) {
for(int i=0; i< strip.numPixels(); i++) {
if(i % 2== rem) {
HSVtoRGB(c1,255,(255/CTR_THRESH)*j,colors);
strip.setPixelColor(i,colors[0],colors[1],colors[2]);
}
}
if(chkBtn(digitalRead(BTN_PIN))) { break; }
strip.show();
delay(wait);
}
for(int j=CTR_THRESH; j >= 0; j--) {
for(int i=0; i< strip.numPixels(); i++) {
if(i % 2== rem) {
HSVtoRGB(c1,255,(255/CTR_THRESH)*j,colors);
strip.setPixelColor(i,colors[0],colors[1],colors[2]);
}
}
if(chkBtn(digitalRead(BTN_PIN))) { break; }
strip.show();
delay(wait);
}
}
// twinkle random number of pixels
void twinkleRand(int num,uint32_t c,uint32_t bg,int wait) {
// set background
colorFast(bg,0);
// for each num
for (int i=0; i<num; i++) {
strip.setPixelColor(random(strip.numPixels()),c);
}
strip.show();
delay(wait);
}
// sine wave, low (0-359),high (0-359), rate of change, wait
void wavey(int low,int high,float rt,uint8_t wait) {
float in,out;
int diff=high-low;
int step = diff/strip.numPixels();
for (in = 0; in < 6.283; in = in + rt) {
for(int i=0; i< strip.numPixels(); i++) {
out=sin(in+i*(6.283/strip.numPixels())) * diff + low;
HSVtoRGB(out,255,255,colors);
strip.setPixelColor(i,colors[0],colors[1],colors[2]);
}
strip.show();
delay(wait);
if(chkBtn(digitalRead(BTN_PIN))) { break; }
}
}
// sine wave, intensity
void waveIntensity(float rt,uint8_t wait) {
float in,level;
for (in = 0; in < 6.283; in = in + rt) {
for(int i=0; i< strip.numPixels(); i++) {
// sine wave, 3 offset waves make a rainbow!
level = sin(i+in) * 127 + 128;
// set color level
strip.setPixelColor(i,(int)level,0,0);
}
strip.show();
delay(wait);
if(chkBtn(digitalRead(BTN_PIN))) { break; }
}
}
// helpers
uint32_t Wheel(byte WheelPos) {
if (WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
// HSV to RGB colors
// hue: 0-359, sat: 0-255, val (lightness): 0-255
// adapted from http://funkboxing.com/wordpress/?p=1366
void HSVtoRGB(int hue, int sat, int val, uint8_t * colors) {
int r, g, b, base;
if (sat == 0) { // Achromatic color (gray).
colors[0] = val;
colors[1] = val;
colors[2] = val;
} else {
base = ((255 - sat) * val) >> 8;
switch (hue / 60) {
case 0:
colors[0] = val;
colors[1] = (((val - base) * hue) / 60) + base;
colors[2] = base;
break;
case 1:
colors[0] = (((val - base) * (60 - (hue % 60))) / 60) + base;
colors[1] = val;
colors[2] = base;
break;
case 2:
colors[0] = base;
colors[1] = val;
colors[2] = (((val - base) * (hue % 60)) / 60) + base;
break;
case 3:
colors[0] = base;
colors[1] = (((val - base) * (60 - (hue % 60))) / 60) + base;
colors[2] = val;
break;
case 4:
colors[0] = (((val - base) * (hue % 60)) / 60) + base;
colors[1] = base;
colors[2] = val;
break;
case 5:
colors[0] = val;
colors[1] = base;
colors[2] = (((val - base) * (60 - (hue % 60))) / 60) + base;
break;
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle2(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
Hi all thank you very much for the help. I've ended up fixing it. See below:
"
The memory was okay. I think you were right that the clock speeds are different for the arduino and the attiny.
I ended up using the libraries found here:
https://github.com/cpldcpu/light_ws2812
Then I loaded the AVR example. I had to copy the ws2812 library into my actual code as the Arduino library wasn't able to find the library. After doing that it finally worked.
"
Thanks for all the help!
Dave
Another solution is to include:
ifdef AVR
include <avr/power.h>
endif
and change the setup:
#if defined (__AVR_ATtiny45__)
if (F_CPU == 8000000) clock_prescale_set(clock_div_1);
#endif
Code below:
// This is a demonstration on how to use an input device to trigger changes on your neo pixels.
// You should wire a momentary push button to connect from ground to a digital IO pin. When you
// press the button it will change to a new pixel animation. Note that you need to press the
// button once to start the first animation!
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define BUTTON_PIN 0 // Digital IO pin connected to the button. This will be
// driven with a pull-up resistor so the switch should
// pull the pin to ground momentarily. On a high -> low
// transition the button press logic will execute.
#define PIXEL_PIN 4 // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 8
// Parameter 1 = number of pixels in strip, neopixel stick has 8
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream
// NEO_GRB Pixels are wired for GRB bitstream, correct for neopixel stick
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
bool oldState = HIGH;
int showType = 0;
void setup() {
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny45__)
if (F_CPU == 8000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
pinMode(BUTTON_PIN, INPUT_PULLUP);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// Get current button state.
bool newState = digitalRead(BUTTON_PIN);
// Check if state changed from high to low (button press).
if (newState == LOW && oldState == HIGH) {
// Short delay to debounce button.
delay(20);
// Check if button is still low after debounce.
newState = digitalRead(BUTTON_PIN);
if (newState == LOW) {
showType++;
if (showType > 9)
showType=0;
startShow(showType);
}
}
// Set the last button state to the old state.
oldState = newState;
}
void startShow(int i) {
switch(i){
case 0: colorWipe(strip.Color(0, 0, 0), 50); // Black/off
break;
case 1: colorWipe(strip.Color(255, 0, 0), 50); // Red
break;
case 2: colorWipe(strip.Color(0, 255, 0), 50); // Green
break;
case 3: colorWipe(strip.Color(0, 0, 255), 50); // Blue
break;
case 4: theaterChase(strip.Color(127, 127, 127), 50); // White
break;
case 5: theaterChase(strip.Color(127, 0, 0), 50); // Red
break;
case 6: theaterChase(strip.Color( 0, 0, 127), 50); // Blue
break;
case 7: rainbow(20);
break;
case 8: rainbowCycle(20);
break;
case 9: theaterChaseRainbow(50);
break;
}
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
for(i=0; i< strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
}
strip.show();
delay(wait);
}
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
Troubleshooting these boards can be very challenging. My initial thought is that you might be running out of memory on the ATtiny. Have you tried a minimal amount of code with only one animation function just for testing?
Also it looks like there is a lot more activity on this topic over at the Electrical Engineering Stack Exchange:
https://electronics.stackexchange.com/questions/24269/checking-memory-footprint-in-arduino
https://electronics.stackexchange.com/questions/74872/memory-management-problems-with-attiny85
Basically, I am making an Arduino Uno project that involves creating a smart waiter that:
Will have a glass holder on top of the basic Arduino chassis. The sensors will be:
4 Infrared Sensors, one on each side
2 Line Sensors, one left and one right
Light Sensor, one the cup holder
It will also have:
2 Servo Motors, one left and right
1 LED showing cup status
It will:
Move along a black line that will be taped on the floor of the HOP
Will sense people on all sides, and pause when it senses close bodies
Will stop indefinitely if it senses that the glass has been lifted
Will start again in 15 seconds if it doesn’t sense movement of glass OR will start again when glass is put down
After glass has been put down, LED will turn from green to red
Robot will continue to move, ignoring all obstacles, until it reaches filling station
Will stop at filling station, where filler will replace glass and press Arduino hard reset button
My Code is:
#include <Servo.h>
int redLED = 5;
int yellowLED = 6;
int greenLED = 7;
int cup1 = 0;
int picked = 1;
int lineright = 0;
int lineleft = 0;
int sensorright = 0;
int sensorleft = 0;
int sensorfront = 0;
int sensorback = 0;
int sensorpinright = 1;
int sensorpinleft = 2;
int sensorpinfront = 3;
int sensorpinback = 4;
Servo servoright;
Servo servoleft;
void setup ()
{
servoright.attach (9);
servoleft.attach (10);
pinMode (redLED, OUTPUT);
pinMode (greenLED, OUTPUT);
pinMode (greenLED, OUTPUT);
}
void loop()
{
sensorright = digitalRead (sensorpinright);
sensorleft = digitalRead (sensorpinleft);
sensorfront = digitalRead (sensorpinfront);
sensorback = digitalRead (sensorpinback);
lineleft = analogRead (1);
lineright = analogRead (2);
cup1 = analogRead (3);
if (sensorright < 0 && sensorleft < 0 && sensorfront < 0 && sensorback < 0)
{
digitalWrite (led1, GREEN);
startfresh:
if (lineleft < 800)
{
servoleft.write (180);
servoright.write (180);
}
else
{
if (lineright < 800)
{
servoright.write (0);
servoleft.write (0);
}
else
{
servoright.write (0);
servoleft.write (180);
}
}
}
else
{
for (int i=0;i<5;i++)
{
servoright.write (93);
servoleft.write (93);
if (picked < 1)
{
while (cup1<500)
{
digitalWrite (yellowLED, HIGH);
picked = 1;
}
}
else
{
digitalWrite (yellowLED, LOW);
digitalWrite (redLED, HIGH);
goto startfresh;
}
delay (2000)
}
}
}
What I want to do with my code is to avoid the goto function at the end. However, I cannot find any way to restructure this with the limitation of only 2 functions. In this case, the goto function seems fine, but I am not sure. Is there any simple way to restructure this?
Make startfresh as function
if (sensorright < 0 && sensorleft < 0 && sensorfront < 0 && sensorback < 0)
{
digitalWrite (led1, GREEN);
startfresh();
}
else
{
for (int i=0;i<5;i++)
{
servoright.write (93);
servoleft.write (93);
if (picked < 1)
{
while (cup1<500)
{
digitalWrite (yellowLED, HIGH);
picked = 1;
}
delay (2000);
}
else
{
digitalWrite (yellowLED, LOW);
digitalWrite (redLED, HIGH);
startfresh();
}
}
}
}
void startfresh() {
if (lineleft < 800)
{
servoleft.write (180);
servoright.write (180);
}
else
{
if (lineright < 800)
{
servoright.write (0);
servoleft.write (0);
}
else
{
servoright.write (0);
servoleft.write (180);
}
}
}