Stumbled upon this weirdest behavior, from time to time, my Arduino (UNO) runs gode really slow.
Searching this issue didn't clarify anything, most people have problems with IDE itself. My issue is related to actual board.
Heres a sample of my flow:
- I compile & upload my sketch, all good
- first initiation of program on the board seems to be "fast"
- when I start to "animate" the neopixels it goes 3-4 times slower than it should
- I'll touch the board, and animation goes fast again.
Here's a clip of that, at the end you'll see the "slowness"
The Touching part, is almost like if I "add" static electricity from my finger to the board, it wakes up and behaves normally.
For you who are curious about (non related) what animation I'm doing on neopixels, I'm turning on 15 pixels from 0 to 54. Like a "slide effect".
(I'm not using delay, only a delay(30) in the loop, rest of the delays are based on millis()
)
Is there any general info / explanation that would explain this behavior, like in electronics, arduino boards specifically ?
EDIT: I should also add, when printing logs into serial monitor, that slowness also affects the outputs... they appear as "slow" as the pixels flow. When all works normally, I see pixels change and logs 50 times per second (roughly), but in this slow motion, I see pixels change and logs around 20 times per second. Taking out the Serial
entirely from the code doesn't seem to have effect.
Code:
#include <Adafruit_NeoPixel.h>
#include <avr/power.h>
#define LEFT_BLINK_IN 2
#define RIGHT_BLINK_IN 3
#define PIN 6
#define NUMPIXELS 54
Adafruit_NeoPixel leftLight = Adafruit_NeoPixel(NUMPIXELS, 6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel rightLight = Adafruit_NeoPixel(NUMPIXELS, 10, NEO_GRB + NEO_KHZ800);
int leftBlinkCount = 0;
int rightBlinkCount = 0;
int PIXELTOSHOW = 20;
bool OEM_RIGHT_ON = false;
bool OEM_LEFT_ON = false;
int R_PIXEL = -1;
int L_PIXEL = -1;
int G_PIXEL = -1;
int D_PIXEL = -1;
char LAST_COMMAND;
bool DRL_ON = false;
int DRL_STARTPIXEL = 35;
uint32_t COLOR_YEL = rightLight.Color(240, 120, 0);
uint32_t COLOR_RED = rightLight.Color(255, 0, 0);
uint32_t COLOR_BLU = rightLight.Color(0, 0, 255);
uint32_t COLOR_NON = rightLight.Color(0, 0, 0);
uint32_t COLOR_WHI = rightLight.Color(255, 255, 255);
unsigned long rightPrevMillis = 0;
unsigned long leftPrevMillis = 0;
unsigned long generalPrevMillis = 0;
const long PIXEL_SWITCH_INTERVAL = 5;
int DRL_RESETER_LEFT = 0;
int DRL_RESETER_RIGHT = 0;
void welcome()
{
int totalPixels = (NUMPIXELS + PIXELTOSHOW);
while (G_PIXEL < totalPixels) {
unsigned long leftCurrentMillis = millis();
if (leftCurrentMillis - leftPrevMillis >= 12) {
leftLight.setPixelColor(totalPixels - G_PIXEL, COLOR_WHI);
rightLight.setPixelColor(totalPixels - G_PIXEL, COLOR_WHI);
if (G_PIXEL >= 10) {
leftLight.setPixelColor(totalPixels - G_PIXEL + PIXELTOSHOW , COLOR_NON);
rightLight.setPixelColor(totalPixels - G_PIXEL + PIXELTOSHOW , COLOR_NON);
}
leftLight.show();
rightLight.show();
G_PIXEL++;
leftPrevMillis = leftCurrentMillis;
}
}
G_PIXEL = 0;
while (G_PIXEL < totalPixels) {
unsigned long leftCurrentMillis = millis();
if (leftCurrentMillis - leftPrevMillis >= 12) {
leftLight.setPixelColor(G_PIXEL, COLOR_WHI);
rightLight.setPixelColor(G_PIXEL, COLOR_WHI);
if (G_PIXEL >= 10) {
leftLight.setPixelColor(G_PIXEL - PIXELTOSHOW, COLOR_NON);
rightLight.setPixelColor(G_PIXEL - PIXELTOSHOW, COLOR_NON);
}
leftLight.show();
rightLight.show();
G_PIXEL++;
leftPrevMillis = leftCurrentMillis;
}
}
}
void blinkRight()
{
//slidePixels(rightBlinkCount, R_PIXEL, rightLight);
if (rightBlinkCount > 0 && R_PIXEL > -1)
{
//Serial.println("RIGHT "+String(rightBlinkCount));
LAST_COMMAND = ' ';
unsigned long rightCurrentMillis = millis();
if (rightCurrentMillis - rightPrevMillis >= PIXEL_SWITCH_INTERVAL) {
rightLight.setPixelColor(R_PIXEL, COLOR_YEL);
if (R_PIXEL >= PIXELTOSHOW)
{
rightLight.setPixelColor(R_PIXEL - PIXELTOSHOW, COLOR_NON);
if (G_PIXEL > -1 && DRL_ON == false) {
leftLight.setPixelColor(R_PIXEL - PIXELTOSHOW, COLOR_NON);
}
}
leftLight.show();
rightLight.show();
R_PIXEL++;
rightPrevMillis = rightCurrentMillis;
}
if ( R_PIXEL >= (NUMPIXELS + PIXELTOSHOW)) {
rightBlinkCount--;
if ( rightBlinkCount > -1 ) {
R_PIXEL = DRL_RESETER_RIGHT = 0;
} else {
L_PIXEL = G_PIXEL = -1;
}
if(DRL_ON){
D_PIXEL=DRL_STARTPIXEL;
}
}
}
}
void blinkLeft() {
// slidePixels(leftBlinkCount, L_PIXEL, leftLight);
if (leftBlinkCount > 0 && L_PIXEL > -1)
{
//Serial.println("left "+String(rightBlinkCount));
LAST_COMMAND = ' ';
unsigned long leftCurrentMillis = millis();
if (leftCurrentMillis - leftPrevMillis >= PIXEL_SWITCH_INTERVAL) {
leftLight.setPixelColor(L_PIXEL, COLOR_YEL);
if (L_PIXEL >= PIXELTOSHOW)
{
Serial.print(" "+String(L_PIXEL));
leftLight.setPixelColor(L_PIXEL - PIXELTOSHOW, COLOR_NON);
if (G_PIXEL > -1 && DRL_ON == false) {
rightLight.setPixelColor(L_PIXEL - PIXELTOSHOW, COLOR_NON);
}
}
rightLight.show();
leftLight.show();
L_PIXEL++;
leftPrevMillis = leftCurrentMillis;
}
if ( L_PIXEL >= (NUMPIXELS + PIXELTOSHOW) ) {
leftBlinkCount--;
Serial.println("Count "+leftBlinkCount);
if ( leftBlinkCount > -1 ) {
L_PIXEL = DRL_RESETER_LEFT = 0;
} else {
L_PIXEL = G_PIXEL = -1;
}
if(DRL_ON){
D_PIXEL=DRL_STARTPIXEL;
}
}
}
}
/*void slidePixels(int &blinkCount, int &blinkPixel, Adafruit_NeoPixel &sideLight){
if (blinkCount > 0 && blinkPixel > -1)
{
LAST_COMMAND = ' ';
unsigned long leftCurrentMillis = millis();
if (leftCurrentMillis - leftPrevMillis >= PIXEL_SWITCH_INTERVAL) {
sideLight.setPixelColor(blinkPixel, COLOR_YEL);
if (blinkPixel >= PIXELTOSHOW)
{
if(G_PIXEL>-1){
rightLight.setPixelColor(blinkPixel - PIXELTOSHOW, COLOR_NON);
leftLight.setPixelColor(blinkPixel - PIXELTOSHOW, COLOR_NON);
}
}
rightLight.show();
leftLight.show();
blinkPixel++;
leftPrevMillis = leftCurrentMillis;
}
if ( blinkPixel >= (NUMPIXELS + PIXELTOSHOW) ) {
blinkCount--;
if ( blinkCount > -1 ) {
blinkPixel = 0;
} else {
blinkPixel = -1;
if(DRL_ON){
G_PIXEL = -1;
}
}
}
}
}*/
int switchRB = 0; // 0 = red, 1 = blue
void slideBlueRed() {
unsigned long currentMillis = millis();
if (currentMillis - generalPrevMillis >= 100) {
if (switchRB == 0) {
leftLight.setPixelColor(G_PIXEL, COLOR_RED);
rightLight.setPixelColor(G_PIXEL, COLOR_RED);
} else {
leftLight.setPixelColor(G_PIXEL, COLOR_BLU);
rightLight.setPixelColor(G_PIXEL, COLOR_BLU);
}
if (G_PIXEL >= 10) {
leftLight.setPixelColor(G_PIXEL - PIXELTOSHOW, COLOR_NON);
rightLight.setPixelColor(G_PIXEL - PIXELTOSHOW, COLOR_NON);
}
leftLight.show();
rightLight.show();
G_PIXEL++;
generalPrevMillis = currentMillis;
}
}
void drlLight(){
unsigned long currentMillis = millis();
if (D_PIXEL < NUMPIXELS) {
leftLight.setPixelColor(NUMPIXELS-DRL_RESETER_LEFT, DRL_ON == true ? COLOR_WHI : COLOR_NON);
rightLight.setPixelColor(NUMPIXELS-DRL_RESETER_RIGHT, DRL_ON == true ? COLOR_WHI : COLOR_NON);
rightLight.setBrightness(128);
leftLight.setBrightness(128);
rightLight.show();
leftLight.show();
D_PIXEL++;
//x //Serial.println(String(DRL_RESETER_LEFT) + " "+ String(NUMPIXELS - DRL_STARTPIXEL));
if(DRL_RESETER_LEFT+1 < (NUMPIXELS - DRL_STARTPIXEL)){
DRL_RESETER_LEFT++;
}
if(DRL_RESETER_RIGHT+1 < (NUMPIXELS - DRL_STARTPIXEL)){
DRL_RESETER_RIGHT++;
}
generalPrevMillis = currentMillis;
}
}
void setup() {
Serial.begin(115200);
leftLight.begin();
rightLight.begin();
pinMode(LEFT_BLINK_IN, INPUT);
pinMode(RIGHT_BLINK_IN, INPUT);
delay(50);
welcome();
}
void loop() {
if (digitalRead(LEFT_BLINK_IN) == HIGH) {
if ( OEM_LEFT_ON == false ) {
OEM_LEFT_ON = true;
leftBlinkCount++;
//Serial.println("LEFT "+String(leftBlinkCount));
if (leftBlinkCount == 1) {
L_PIXEL = 0;
}
}
} else {
OEM_LEFT_ON = false;
}
if (digitalRead(RIGHT_BLINK_IN) == HIGH) {
if ( OEM_RIGHT_ON == false ) {
OEM_RIGHT_ON = true;
rightBlinkCount++;
if (rightBlinkCount == 1) {
R_PIXEL = 0;
}
}
} else {
OEM_RIGHT_ON = false;
}
if(DRL_ON && leftBlinkCount < 1 && rightBlinkCount < 1){
drlLight();
}
blinkRight();
blinkLeft();
if(rightBlinkCount < 1 || leftBlinkCount < 1){
delay(30);
switch (LAST_COMMAND) {
case 'q':
case '?': {
for ( int gp = 0; gp < NUMPIXELS + PIXELTOSHOW; gp++) {
leftLight.setPixelColor(gp, COLOR_NON);
rightLight.setPixelColor(gp, COLOR_NON);
}
leftLight.show();
rightLight.show();
G_PIXEL = -1;
break;
}
case 's': {
slideBlueRed();
//Serial.println("bluuu");
if (G_PIXEL >= NUMPIXELS ) {
G_PIXEL = -1;
switchRB = switchRB == 0 ? 1 : 0;
}
break;
}
case 'w': {
welcome();
if (G_PIXEL >= NUMPIXELS + PIXELTOSHOW) {
G_PIXEL = -1;
}
break;
}
case 'd': {
if(DRL_ON==false){
D_PIXEL = DRL_STARTPIXEL;
DRL_ON = true;
LAST_COMMAND = '-';
}else{
D_PIXEL = 0;
DRL_ON = false;
}
break;
}
}
if (Serial.available()) {
LAST_COMMAND = '-';
while (Serial.available()) {
char command = Serial.read();
G_PIXEL=-1;
LAST_COMMAND = command;
}
}
}
}