Black Lives Matter - Action and Equality. ... Adafruit joins the Stop Hate for Profit campaign.
0

led code getting stuck in loop & cycling too fast
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Re: led code getting stuck in loop & cycling too fast

by adafruit_support_bill on Sat Sep 14, 2019 2:35 pm

You read the button and do the animation mode switching in the serial read section. The code we added in the rainbow loop is just a quick way to exit the loop when a button is pressed.

adafruit_support_bill
 
Posts: 77885
Joined: Sat Feb 07, 2009 10:11 am

Re: led code getting stuck in loop & cycling too fast

by dionnesimone on Sat Sep 14, 2019 2:47 pm

adafruit_support_bill wrote:You read the button and do the animation mode switching in the serial read section. The code we added in the rainbow loop is just a quick way to exit the loop when a button is pressed.


I'll keep chugging in the serial section.

dionnesimone
 
Posts: 28
Joined: Wed Feb 27, 2019 9:37 pm

Re: led code getting stuck in loop & cycling too fast

by dionnesimone on Sat Sep 14, 2019 3:44 pm

I've tried the following... but none is working.

Code: Select all | TOGGLE FULL SIZE
for (;;) {
    t = micros();                                // Current time
    if ((t - prevTime) >= (1000000L / FPS)) {    // 1/30 sec elapsed?
      prevTime = t;
      break;                                     // Yes, go update LEDs
    }                                            // otherwise...
    if ((c = ser.read()) == '!') {               // Received UART app input?
      while ((c = ser.read()) < 0);              // Yes, wait for command byte

        if (ser.available()> 0) {
          c = ser.read();
          //switch (animMode);
           //pixels.clear ();
            //ser.print(c);
             //pixels.show();
              //update.switch (c);
               //update (c);
                //switch (c);
                 //void buttonPress(char c);
                  //ser.print(animMode);
                   //pixels.clear ();
                    //switch (animMode);
                     //void buttonPress(char c);   
                      //switch (c);
                       //digitalWrite(CTS_PIN, HIGH);
     
    }
                  //digitalWrite(CTS_PIN, HIGH);
   

dionnesimone
 
Posts: 28
Joined: Wed Feb 27, 2019 9:37 pm

Re: led code getting stuck in loop & cycling too fast

by adafruit_support_bill on Sat Sep 14, 2019 4:03 pm

What about the button code you started with? viewtopic.php?f=47&t=148230#p732221

adafruit_support_bill
 
Posts: 77885
Joined: Sat Feb 07, 2009 10:11 am

Re: led code getting stuck in loop & cycling too fast

by dionnesimone on Sat Sep 14, 2019 8:42 pm

That helped a nice bit!! :-) Now, I can switch back to the other modes, but the button presses (registers both the down and release, and shows my default color in between the presses.) that trigger change are inconsistent. I am hitting the button multiple times and eventually it changes if i press them fast enough. I changed the button press buf and that seemed to make it more responsive but I can't get a consistent change with button presses.

I would like the change to happen after 1 press.

ALMOST THERE! <3

BTW, once the issues are resolved, I will post the full working code for anyone interested in it.

Code: Select all | TOGGLE FULL SIZE
 for (;;) {
    t = micros();                                // Current time
    if ((t - prevTime) >= (1000000L / FPS)) {    // 1/30 sec elapsed?
      prevTime = t;
      break;                                     // Yes, go update LEDs
    }                                            // otherwise...
    if ((c = ser.read()) == '!') {               // Received UART app input?
      while ((c = ser.read()) < 0);              // Yes, wait for command byte

        if (ser.available()> 0) {
          while ((c = ser.read()) >0);
            pixels.show();
            switch (animMode);
               buttonPress(buf[1/4]);

dionnesimone
 
Posts: 28
Joined: Wed Feb 27, 2019 9:37 pm

Re: led code getting stuck in loop & cycling too fast

by dionnesimone on Sat Sep 14, 2019 9:56 pm

I'm gonna try to debounce the button.

dionnesimone
 
Posts: 28
Joined: Wed Feb 27, 2019 9:37 pm

Re: led code getting stuck in loop & cycling too fast

by dionnesimone on Sun Sep 15, 2019 7:55 pm

This code is by no means perfect but it functions. (I will be editing down anything that is unneccessary, tweaking a couple of things and getting it to react to a single button press).

I can exit the rainbowCycle's with a double press of another button.

I'm using the Flora Bluefruit, an Atmega 328 micro controller and Neopixels.

This sketch uses 7174 bytes (23%) of program storage space. Maximum is 30720 bytes.
Global variables use 353 bytes (17%) of dynamic memory, leaving 1695 bytes for local variables. Maximum is 2048 bytes.

Here is my working code for anyone that might be interested.

Code: Select all | TOGGLE FULL SIZE
// Bluetooth shoes --

// Works in conjunction with Bluefruit LE Connect app on iOS or Android --
// pick colors or use buttons to select modes.
// if space is VERY tight...helps to use Arduino IDE
// 1.6.4 or later; produces slightly smaller code than the 1.0.X releases.

// BLUEFRUIT LE UART FRIEND MUST BE SWITCHED TO 'UART' MODE

#include <SoftwareSerial.h>
#include <Adafruit_NeoPixel.h>
#include <string.h>
#include <Arduino.h>
#include <SPI.h>

#ifdef __AVR_ATtiny85__         
#endif

#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#include "BluefruitConfig.h"

#define RX_PIN    2             // Connect this pin to BLE 'TXO' pin
#define TX_PIN    1
#define LED_PIN   3             // Connect NeoPixels to this pin
#define NUM_LEDS 73             // Number of led lights
#define FPS      30             // Animation frames/second (ish)
#define CTS_PIN  -1             // Connect this pin to BLE 'CTS' pin
#define RTS_PIN  -1
#define BLUEFRUIT_UART_MODE_PIN -1


SoftwareSerial    ser(RX_PIN, -0);
Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN);

void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
                                          // MUST do this on 16 MHz Trinket for serial & NeoPixels!
  clock_prescale_set(clock_div_1);
#endif

  // Stop incoming data & init software serial
  pinMode(CTS_PIN, OUTPUT);
  digitalWrite(CTS_PIN, HIGH);


unsigned long t = 5;                      // the debounce time; increase if the output flickers
unsigned long prevTime = 0;               // the last time the output pin was toggled
 
  pixels.setBrightness(255);               // set LED brightness here
  ser.begin(9600);
  pixels.begin();                         // NeoPixel init
 
  // Flash space is tight on Trinket/Gemma, so setBrightness() is avoided --
  // it adds ~200 bytes.  Instead the color picker input is 'manually' scaled.
}

uint8_t  buf[3],                         // Enough for RGB parse; expand if using sensors
         animMode = 2,                   // Current animation mode
         animPos  = 0;                   // Current animation position
uint32_t color    = 0x400000,            // Current animation color (red by default)
         prevTime = 0L;                  // For animation timing

void loop(void) {
  int      c;
  uint32_t t;

  // Animation happens at about 30 frames/sec.  Rendering frames takes less
  // than that, so the idle time is used to monitor incoming serial data.
 
  digitalWrite(CTS_PIN, LOW);                    // Signal to BLE, OK to send data!
  for (;;) {
    t = micros();                                // Current time
    if ((t - prevTime) >= (10000000L / FPS)) {   // 1/30 sec elapsed?
      prevTime = t;
      break;                                     // Yes, go update LEDs
    }                                            // otherwise...
    if ((c = ser.read()) == '!') {               // Received UART app input?
      while ((c = ser.read()) < 0);              // Yes, wait for command byte

        if (ser.available()> 0) {
          while ((c = ser.read()) >0);
          pixels.clear ();
            pixels.show();
             buttonPress (buf[1/4]);
              switch (animMode);
    }
                 
      switch (c) {
       
        case 'B':                     // Button (Control Pad)
          if (readAndCheckCRC(255 - '!' - 'B', buf, 2) & (buf[1] == '1')) {
            buttonPress(buf[0]);      // Handle button-press message
          }
          break;
         
        case 'C':                    // Color Picker
          if (readAndCheckCRC(255 - '!' - 'C', buf, 3)) {
            // As mentioned earlier, setBrightness() was avoided to save space.
            // Instead, results from the color picker (in buf[]) are divided
            // by 4; essentially equivalent to setBrightness(64).  This is to
            // improve battery run time (NeoPixels are still plenty bright).
            color = pixels.Color(buf[0] / 4, buf[1] / 4, buf[2] / 4);
          }
          break;
         
        case 'Q':                   // Quaternion
          skipBytes(17);             // 4 floats + CRC (see note below re: parsing)
          break;
         
        case 'A':                   // Accelerometer
#if 0
          // The phone sensors are NOT used by this sketch, but this shows how
          // they might be read.  First, buf[] must be delared large enough for
          // the expected data packet (minus header & CRC) -- that's 16 bytes
          // for quaternions (above), or 12 bytes for most of the others.
          // Second, the first arg to readAndCheckCRC() must be modified to
          // match the data type (e.g. 'A' here for accelerometer).  Finally,
          // values can be directly type-converted to float by using a suitable
          // offset into buf[] (e.g. 0, 4, 8, 12) ... it's not used in this
          // example because floating-point math uses lots of RAM and code
          // space, not suitable for the space-constrained Trinket/Gemma, but
          // maybe you're using a Pro Trinket, Teensy, etc.
          if (readAndCheckCRC(255 - '!' - 'A', buf, 12)) {
            float x = *(float *)(&buf[0]),
                  y = *(float *)(&buf[4]),
                  z = *(float *)(&buf[8]);
          }
          // In all likelihood, updates from the buttons and color picker
          // alone are infrequent enough that you could do without any mention
          // of the CTS pin in this code.  It's the extra sensors that really
          // start the firehose of data.
          break;
#endif
        case 'G':            // Gyroscope
        case 'M':            // Magnetometer
        case 'L':            // Location
          skipBytes(13);      // 3 floats + CRC
      }
    }
  }
  digitalWrite(CTS_PIN, HIGH);    // BLE STOP!

  // Show pixels calculated on *prior* pass; this ensures more uniform timing
  pixels.show();

  // Then calculate pixels for *next* frame...
  switch (animMode) {
   
    case 0:     // chasing mode
      for(uint8_t i = 0; i < NUM_LEDS / 1; i++) {
          uint32_t c = 0;
             if (((animPos + i) & 15) < 4) c = color;    //16 total pixels, 4 lit at a time
                pixels.setPixelColor(   i, c);
      }
      animPos++;
      break;
     
    case 1:    // Sparkle mode
      pixels.setPixelColor(animPos, 0);          // Erase old dot
          animPos = random(NUM_LEDS);                // Pick a new one
             pixels.setPixelColor(animPos, color);      // and light it
      break;   

    case 2:    //solid mode
      for(uint8_t i = 0; i < NUM_LEDS; i++) {
          uint32_t c = 0;
             if (((animPos) & 15) < 15) c = color;       // all pixels lit
                pixels.setPixelColor(   i, c);             
      }
      break;
   
    case 3:    //blinking mode
      for(uint8_t i = 0; i < NUM_LEDS / 1; i++) {
          uint32_t c = 0;
             if (((animPos + 1) & 15) < 2) c = color;   // all pixels lit
                pixels.setPixelColor(   i, c);
      }
      animPos++;
      break;
     
    case 4:    // Up = rainbowCycle
      {
      uint16_t i, j;
         for(j=0; j<256 * 1; j++) { // cycles of all colors on wheel
            for(i=0; i< pixels.numPixels(); i++) {

              if (ser.available()>0){
              pixels.clear ();
               return;}
             
               pixels.setPixelColor(i, Wheel(((i * 256 / pixels.numPixels()) + j) & 255));
      }
      pixels.show();
        }
       }
      break;



    case 5:    // Down = theaterChaseRainbow
     {
      for(int j=0; j < 255; j++) {     // cycle all 256 colors in the wheel
         for(int q=0; q < 3; q++) {
            for(uint16_t i=0; i < pixels.numPixels(); i=i+3) {

              if (ser.available()>0){
              pixels.clear ();
               return;}
               
              pixels.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      pixels.show();
     
        for(uint16_t i=0; i < pixels.numPixels(); i=i+3) {
            pixels.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}
     
      break;

     
         
    case 6:    // left button - rainbow
      {
      uint16_t i, j;
        for(j=0; j<255; j++) {
           for(i=0; i<pixels.numPixels(); i++) {

            if (ser.available()>0){
              pixels.clear ();
               return;}
               
             pixels.setPixelColor(i, Wheel((i+j) & 255));
    }
    pixels.show();
  }
}
     
      break;

     

     case 7:   // right button - rainbow sparkle mode
       {
       uint16_t i, j;
         for(j=0; j<256; j++) {
            for(i=0; i<pixels.numPixels(); i++) {
              if (random(pixels.numPixels()) == i)
                 pixels.setPixelColor(i,255, 255, 255);
                  else
                     pixels.setPixelColor(i, Wheel((i+j) & 255));
                     
                     if (ser.available()>0){
              pixels.clear ();
               return;}
    }
    pixels.show();
  }
}
     
      break;
     
  }
}

boolean readAndCheckCRC(uint8_t sum, uint8_t *buf, uint8_t n) {
  for (int c;;) {
    while ((c = ser.read()) < 0);      // Wait for next byte
    if (!n--) return (c == sum);       // If CRC byte, we're done
    *buf++ = c;                        // Else store in buffer
    sum   -= c;                        // and accumulate sum
  }
}

void skipBytes(uint8_t n) {
  while (n--) {
    while (ser.read() < 0);
  }
}

void buttonPress(char c) {
  pixels.clear();         // Clear pixel data when switching modes (else residue)
  switch (c) {
    case '1':
      animMode = 0;       // Switch to chase mode
      break;
    case '2':
      animMode = 1;       // Switch to sparkle mode
      break;
    case '3':
      animMode = 2;       // Switch to solid mode
      break;
    case '4':
      animMode = 3;       // Switch to blinking mode
      break;
    case '5':           
      animMode = 4;       // Up = rainbowCycle
      break;
    case '6':             
      animMode = 5;        // Down = theaterChaseRainbow
      break;
    case '7':             
      animMode = 6;        // Left =
      break;
    case '8':             
      animMode = 7;        // Right = rainbowSparkle
      break;
  }
}

// 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 pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

dionnesimone
 
Posts: 28
Joined: Wed Feb 27, 2019 9:37 pm

Please be positive and constructive with your questions and comments.