Code to run Attiny85 with WS2812 integrated with RGB LED - arduino

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

Related

issue with Arduino using FastLed with IRremote change mode

Hi I am trying to build a arduino project to control led strip and change the light pattern when pressed different button
the code i am using is
#include <IRremote.h> //include the library
#include <FastLED.h>
// How many leds in your strip?
#define NUM_LEDS 70
#define DATA_PIN 3
#define CLOCK_PIN 13
#define Button_0 0xFF9867
#define Button_1 0xFFA25D
#define Button_2 0xFF629D
#define Button_3 0xFFE21D
#define Button_4 0xFF22DD
#define Button_5 0xFF02FD
#define Button_6 0xFFC23D
#define Button_7 0xFFE01F
#define Button_8 0xFFA857
#define Button_9 0xFF906F
int receiver = 7; //initialize pin 13 as recevier pin.
IRrecv irrecv(receiver); //create a new instance of receiver
decode_results results;
CRGB leds[NUM_LEDS];
void setup() {
Serial.begin(9600);
LEDS.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
LEDS.setBrightness(84);
irrecv.enableIRIn(); //start the receiver
}
void loop() {
if (irrecv.decode(&results)) { //if we have received an IR signal
Serial.println (results.value, HEX); //display HEX results
irrecv.resume(); //next value
if (results.value == Button_0) {
RunningLightSlow();
}
else if(results.value == Button_1) {
RainbowLights();
}
// switch (results.value) {
//
// case Button_0: RunningLightSlow(); break;
// case Button_1: RainbowLights(); break;
// }
}
}
// LIGHTSHOW 0 starts --------------------------------------------------------------------------------------------------
void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }
void RunningLightSlow() {
while(1) {
static uint8_t hue = 0;
Serial.print("x");
// First slide the led in one direction
for(int i = 0; i < NUM_LEDS; i++) {
// Set the i'th led to red
leds[i] = CHSV(hue++, 255, 255);
// Show the leds
FastLED.show();
// now that we've shown the leds, reset the i'th led to black
// leds[i] = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
delay(10);
}
Serial.print("x");
// Now go in the other direction.
for(int i = (NUM_LEDS)-1; i >= 0; i--) {
// Set the i'th led to red
leds[i] = CHSV(hue++, 255, 255);
// Show the leds
FastLED.show();
// now that we've shown the leds, reset the i'th led to black
// leds[i] = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
delay(10);
}
}
}
// LIGHTSHOW 0 ends --------------------------------------------------------------------------------------------------------
// LIGHTSHOW 1 STARTS ------------------------------------------------------------------------------------------------------
void RainbowLights() {
randomSeed(millis());
int wait=random(10,30);
int dim=random(4,6);
int max_cycles=8;
int cycles=random(1,max_cycles+1);
while(1) {
rainbowCycle(wait, cycles, dim);
}
}
void rainbowCycle(int wait, int cycles, int dim)
{
Serial.println("Let's make a rainbow.");
//loop several times with same configurations and same delay
for(int cycle=0; cycle < cycles; cycle++)
{
byte dir=random(0,2);
int k=255;
//loop through all colors in the wheel
for (int j=0; j < 256; j++,k--)
{
if(k<0)
{
k=255;
}
//Set RGB color of each LED
for(int i=0; i<NUM_LEDS; i++)
{
CRGB ledColor = wheel(((i * 256 / NUM_LEDS) + (dir==0?j:k)) % 256,dim);
leds[i]=ledColor;
}
FastLED.show();
FastLED.delay(wait);
}
}
}
CRGB wheel(int WheelPos, int dim)
{
CRGB color;
if (85 > WheelPos)
{
color.r=0;
color.g=WheelPos * 3/dim;
color.b=(255 - WheelPos * 3)/dim;;
}
else if (170 > WheelPos)
{
color.r=WheelPos * 3/dim;
color.g=(255 - WheelPos * 3)/dim;
color.b=0;
}
else
{
color.r=(255 - WheelPos * 3)/dim;
color.g=0;
color.b=WheelPos * 3/dim;
}
return color;
}
Now the issue i am facing is when i press a button (for eg 0) it runs the function RunningLightSlow(); i have written the infinite loop code because i want infinite light show and when i press button 1 it does not change the light pattern ,
Root cause would be once the function goes into infinite loop it then never receives the ir signal and hence never change the light pattern
Remove all infinite loops from your program and create a simple structure in loop() where you check for IR signal and update a "state" variable with the last button pressed.
void loop() {
// create a function or add here whatever is needed to read the IR code
irCode = readIrCode();
// check if the new code is identical to a previous code
if (lastIrCode != irCode) {
// memorize the current code
lastIrCode = irCode;
/ act according to user selection
switch (irCode) {
case Button_0:
doThis(); // this could be your RunningLightSlow()
break;
case Button_1:
doThat(); // maybe RainbowLights()
break;
default:
// for cases you have not handled above
doWhatever();
}
}
}
Do not forget to remove the infinite loops from the functions that run the lights and obviously you would need to declare the variables and set the correct calls.

How to make two servos work one after another? And stop shaking?

For my project, I am trying to make a page-turner that's controlled by two servos --- one to flip (with a horn) and one to lift (with a wheel). My goal here is when I press the RIGHT button, my wheel should roll a page clockwise FIRST then my horn will swipe from left to right (the same but opposite for my LEFT button) to turn a page.
While I am trying to adjust the angles, I have my button right servo works the way I wanted to but it's shaking, on the other hand, I have my button right servo works smooth and continuously but the flip and the turn were both active at the same time.
#include <Servo.h>
const int swipservo = 8; //yellow
const int liftservo = 9; //green
Servo servo1; // create servo object to control a servo
Servo servo2;
const int leftbutton = 11; //yellow = turn left
const int rightbutton = 12; //blue = turn right
int pos1 = 0; // variable to store the servo position
int pos2 = 0;
void setup() {
servo1.attach (swipservo);
servo2.attach (liftservo);
pinMode(leftbutton , INPUT);
pinMode(rightbutton , INPUT);
}
void loop() {
test();
}
void test() {
if (digitalRead(rightbutton) == HIGH) {
for (pos2 = 0; pos2 < 350; pos2++) {
if (pos2 < 180) {
servo2.write (pos2);
delay(15);
}
if (pos1 > 180) {
servo1.write(0);
delay(15);
servo2.write(0);
delay(15);
}
else if (pos2 >= 180) {
servo1.write(pos1);
delay(15);
pos1 ++;
}
//go back to 0 for POS 2
}
}
if (digitalRead(leftbutton) == HIGH) {
for (pos2 = 160; pos2 > 0; pos2++) {
if (pos2 < 0) {
servo2.write (pos2);
delay(5);
}
if (pos1 >= 180) {
servo1.write(0);
delay(15);
servo2.write(0);
delay(15);
}
else if (pos2 > 0) {
servo2.write(pos2);
delay(15);
}
if (pos2 <= 0) {
servo1.write(pos1);
delay(15);
pos1 ++;
}
}
}
}

Control dc-motor using H-Bridge and neopixel together with Arduino UNO

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

Neopixel strip animation toggle problems

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?

Use Two Pushbuttons To Toggle Two Programs

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);
}

Resources