0

Is there a switch-case syntax in CircuitPython?
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Is there a switch-case syntax in CircuitPython?

by chipnod2020 on Fri Jun 04, 2021 11:44 am

I am translating a script I have that is written in C++ to CircuitPython - Raspberry Pi Pico. One place I'm getting stuck with is the current switch-case setup I have.

Is there a CircuitPython equivalent?

Code: Select all | TOGGLE FULL SIZE
#include <ezButton.h>
#include <Adafruit_DotStar.h>
#include <SPI.h>         // COMMENT OUT THIS LINE FOR GEMMA OR TRINKET
//#include <avr/power.h> // ENABLE THIS LINE FOR GEMMA OR TRINKET

#define EFFECT_STATE_NONE 0
#define EFFECT_STATE_MOVE 1
#define EFFECT_STATE_FADE 2

#define NUMPIXELS 30 // Number of LEDs in strip

// Hardware SPI is a little faster, but must be wired to specific pins
// (Arduino Uno = pin 11 for data, 13 for clock, other boards are different).
Adafruit_DotStar strip(NUMPIXELS, DOTSTAR_BRG);
ezButton button(7);  // create ezButton object that attach to pin 7;

unsigned long EFFECT_TIME_ALL  = 5000;// Length of the entire process
unsigned long EFFECT_TIME_FADE = 1000;// How long do you want them to flicker when they meet in the middle
unsigned long EFFECT_TIME_MOVE = EFFECT_TIME_ALL - EFFECT_TIME_FADE;
int EFFECT_FADE_NUM = 4; // fade 4 time between 200 and 255, you can change this value

int    lengthA = NUMPIXELS;
int      headX = 0;
int      headY = NUMPIXELS;
int    randomN = 0;
uint32_t color = 0xFFA500;

unsigned long timeMoveStart;
unsigned long timeFadeStart;
unsigned long progress;
unsigned long brightness = 0;
int fadeCount = 0;
int effectState = EFFECT_STATE_NONE;

void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
  clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif
  strip.begin(); // Initialize pins for output
  strip.show();  // Turn all LEDs off ASAP
  button.setDebounceTime(50); // set debounce time to 50 milliseconds
}


void loop() {
  button.loop(); // MUST call the loop() function first

  switch (effectState) {
    case EFFECT_STATE_NONE:
      if (button.isPressed()) {
        effectState = EFFECT_STATE_MOVE;
        timeMoveStart = millis();
        randomN = random(0, lengthA); // The min is 0 and max is lengthA - 1
      }
      break;

    case EFFECT_STATE_MOVE:
      progress = millis() - timeMoveStart;
      brightness = map(progress, 0, EFFECT_TIME_MOVE, 0, 200);
      headX = map(progress, 0, EFFECT_TIME_MOVE, 0, randomN);
      headY = map(progress, 0, EFFECT_TIME_MOVE, lengthA, randomN);

      if (headX >= randomN) {
        headX = randomN;
        headY = randomN;
        effectState = EFFECT_STATE_FADE;
        timeFadeStart = millis();
        fadeCount = 0;
      }

      break;

    case EFFECT_STATE_FADE:
      progress = millis() - timeFadeStart;

      if ((fadeCount % 2) == 0) { // fade up
        brightness = map(progress, 0, EFFECT_TIME_FADE / EFFECT_FADE_NUM, 200, 255);
        if (brightness > 255) {
          fadeCount++;
          timeFadeStart = millis();
        }
      } else {// fade down
        brightness = map(progress, 0, EFFECT_TIME_FADE / EFFECT_FADE_NUM, 255, 200);
        if (brightness < 200) {
          fadeCount++;
          timeFadeStart = millis();
        }
      }

      if (fadeCount > EFFECT_FADE_NUM) {
        effectState = EFFECT_STATE_NONE;
        brightness  = 0; // turn off all
      }

      break;
  }

  strip.setBrightness(brightness);
  for (int i = 0; i <= lengthA; i++) {
    if (i == headX || i == headY)
      strip.setPixelColor(i, color);
    else
      strip.setPixelColor(i, 0); // turn off
  }
  strip.show();
}

chipnod2020
 
Posts: 29
Joined: Wed Jul 15, 2020 9:59 am

Re: Is there a switch-case syntax in CircuitPython?

by dastels on Fri Jun 04, 2021 3:05 pm

No. You would use somethign like:
Code: Select all | TOGGLE FULL SIZE
if effectState == EFFECT_STATE_NONE:
    ...
elif effectState == EFFECT_STATE_MOVE:
    ...

and so on.

If there's any complexity to the structure, I usually switch to a polymorphic subclass-per-state approach. See https://learn.adafruit.com/circuitpython-101-state-machines.

Dave

dastels
 
Posts: 6830
Joined: Tue Oct 20, 2015 3:22 pm

Re: Is there a switch-case syntax in CircuitPython?

by chipnod2020 on Fri Jun 04, 2021 4:54 pm

Thanks dastels!

Is it correct that there isn't a map function in CP?

chipnod2020
 
Posts: 29
Joined: Wed Jul 15, 2020 9:59 am

Re: Is there a switch-case syntax in CircuitPython?

by dastels on Fri Jun 04, 2021 8:19 pm

There's map. See https://learn.adafruit.com/circuitpython-101-list-and-things-iterators-generators. A list comprehension is the more idiomatic way to do it, though. E.g.

Code: Select all | TOGGLE FULL SIZE
>>> a = range(20)                                           
>>> list(map(lambda x: x**2, a))                                               
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324
, 361]                                                                         
>>> [x**2 for x in a]                                                           
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324
, 361] 

Dave

dastels
 
Posts: 6830
Joined: Tue Oct 20, 2015 3:22 pm

Please be positive and constructive with your questions and comments.