RigoHoward / groove-coaster-printable-shell

A nice 3D printable frame/shell to build a DIY Groove Coaster controller
GNU General Public License v3.0
3 stars 0 forks source link

cannot get WS2812 ledstrip to light up #1

Open k1darklord opened 4 weeks ago

k1darklord commented 4 weeks ago

Firstly thank you for your design it is fantastic! I am however having a problem in getting the WS2812 ledstrip to light, I have wired it up to the 5v, gnd and pins a2 and a3 separate data but daisy chained power and ground.

Am I doing something wrong, won't lie I am not very familiar with using an Arduino leonardo so its all very new to me if you could provide any help and if I have posted this in the wrong area sorry.

Thanks for any help you may be able to provide.

RigoHoward commented 4 weeks ago

Hey there, so youre building your own GC con?!, very nice!

Are you using an arduino leonardo board right? If so, the pins for the ledstrips are digital pin 2 (D2/PD1) and 3 (D3/PD0):

imagen

The analog pins A2 (PF5) and A3 (PF4) were not used originally.

Here is the complete pinout i used for my con:

/* PINOUT (follows Nintendo naming (X=up, B=down)) */
#define PIN_UP    4
#define PIN_DOWN  5
#define PIN_LEFT  6
#define PIN_RIGHT 7
#define PIN_A     11          //XBOX B
#define PIN_B     9           //XBOX A  
#define PIN_X     8           //XBOX Y
#define PIN_Y     10          //XBOX X     
#define PIN_L     0           //XBOX LB
#define PIN_R     1           //XBOX RB
// Not used
//#define PIN_ZL    -         //XBOX LT
//#define PIN_ZR    -         //XBOX RT
//#define PIN_LS    -         //XBOX LS (left analog click)
//#define PIN_RS    -         //XBOX RS (right analog click)
#define PIN_PLUS  13          //XBOX START
#define PIN_MINUS A0          //XBOX BACK
#define PIN_HOME  A1
#define PIN_L_LED  2
#define PIN_R_LED  3
#define PIN_PLUS_LED 12

If you still want to use A2 and A3 pins, you could change the pin assignation for PIN_L_LED and PIN_R_LED defined pins before flashing the code to your board:

#define PIN_L_LED  A2
#define PIN_R_LED  A3

I hope that helps you to finish up your build!

k1darklord commented 4 weeks ago

Thank you so much for replying to me, I am building the controller and it looks amazing (all my 3d prints are done so its onto the wiring). I tried plugging the Arduino leonardo into my pc with the 5v going to pin +5v ground going to the GND below +5v data going to pin D2 They where the only pins populated on the board to test. The Pc sees it as a switch controller (pokken) and still no lighting. They are 5v WS2812. Are the lights meant to come on when the arduino is plugged into a computer (or switch) or do they come on with a button press? I have no idea why these wont work and thank you for your assistance.

k1darklord commented 3 weeks ago

I finished it, I still cannot get the led strips to light (the start button works how it should and lights when pressed).

groove1 groove2

I did have one problem the inputs where being dropped on quick button presses so I looked into the code and changed this:

define MILLIDEBOUNCE 0 //Debounce time in milliseconds changed from 1 to 0

Now its really responsive just need to tinker with the fastled code to see if I can make it shine!

RigoHoward commented 3 weeks ago

Oh its looking fantastic!, well done!

Yes the code its adapted to work as a pokken controller to get nswitch compatibility.

About the led strips, the lights are reactive only (they should light up when you move any of the sticks or press the top buttons on them)

BTW do you have another Leonardo board to test a little script for the leds? (i experienced issues when using with cheap aliexpress led strips in the past, so since then i always test them before using it on any of my diy projects) At any means i will be openong my controller to check the led strip connections to be sure what pins i used at the end (maybe i changed some of them and didnt update the code properly)

I'm not an experienced GC player myself, but i didnt notice any dropped input but if i get better maybe i could start to notice it.

k1darklord commented 3 weeks ago

Thanks, I'm really pleased with how it has come out and for a 3d print it feels substantial and not like its about to break! Fantastic design on your part and thank you again for sharing.

I checked for dropped inputs using a Joypad test program and for me there was dropped inputs until I changed that debounce setting, it could well be caused by the microswitches I am using but its sorted spot on now no delay or dropped inputs!

I have tried the LED strip on another Arduino using FastLED example code that animated them no problem. I was playing around with the code as I realised if I mess it up then I can always just put it back to stock really easily and not hurt anything so my plan is to have the lights animated in a circular motion from it being plugged in.

I have a few hours today so time to dip my toe back into coding which I have always found so difficult to understand but if I take my time I may get somewhere. Should I succeed I shall post back to let you know.

I did manage to make it so the start button is illuminated until it is pushed I wonder if it would be possible to make it pulse on and off???

RigoHoward commented 3 weeks ago

Okay i check my wiring and this is how should you go using my code...

Digital pins 2 & 3: for the led on the left and right top buttons on top of the sticks. Digital pin 12: for the led on the start button on top. Analog pins A2 & A3: are for the left and right led strips DIN point (both led strips should have 8 single leds on it)

So thats its how it goes (sorry for my earlier comment with a wrong pinout indication)

k1darklord commented 3 weeks ago

Success! After literal hours of playing around and having close to zero idea what I was doing I managed to junk together working code, I have 16LEDs on each strip (set to low brightness so just in the limit for the Leonardo) and I have managed to get the lights animated spinning and looking all pretty! I could not figure out how to get the start button to pulse which would have been nice but I'm thrilled at where it is from having no lights to really nice lighting.

Here is the code if you want to have a look for yourself at any point and thank you again for such a good project! -

`` /* Groove Coaster Controller Code for Arduino Leonardo and clones

/ in case you want to disable one type of gamepad / //#define DISABLE_XINPUT

define DISABLE_NSWITCH

//use real analog sticks //#define WITH_ANALOG

define DEADZONE 50

// Enable on-the-fly SOCD config. If disabled, itll lock in // the default configuration but still use the SOCD resolution code. // #define ENABLE_SOCD_CONFIG

//make it so holding start+select triggers the HOME button //#define HOME_HOTKEY //delay in ms for start+select to become HOME in HOME_HOTKEY mode

define HOME_DELAY 1000

/ PINOUT (follows Nintendo naming (X=up, B=down)) /

define PIN_UP 4

define PIN_DOWN 5

define PIN_LEFT 6

define PIN_RIGHT 7

define PIN_A 11 //XBOX B

define PIN_B 9 //XBOX A

define PIN_X 8 //XBOX Y

define PIN_Y 10 //XBOX X

define PIN_L 0 //XBOX LB

define PIN_R 1 //XBOX RB

// Not used //#define PIN_ZL - //XBOX LT //#define PIN_ZR - //XBOX RT //#define PIN_LS - //XBOX LS (left analog click) //#define PIN_RS - //XBOX RS (right analog click)

define PIN_PLUS 13 //XBOX START

define PIN_MINUS A0 //XBOX BACK

define PIN_HOME A1

define PIN_L_LED 2

define PIN_R_LED 3

define PIN_PLUS_LED 12

ifdef WITH_ANALOG

define PIN_LANALOGX MOSI

define PIN_LANALOGY MISO

define PIN_RANALOGX MOSI

define PIN_RANALOGY MISO

typedef struct point_s { int x; int y; } point_t;

typedef struct range_s { point_t min; point_t max; point_t center; } range_t;

range_t g_range_l = {{400, 400}, {600, 600}, {511, 511}}; range_t g_range_r = {{400, 400}, {600, 600}, {511, 511}};

bool g_calibrating = false;

endif

/ Buttons declarations /

define MILLIDEBOUNCE 0 //Debounce time in milliseconds

unsigned long startAndSelTime = 0; unsigned long currTime = 0;

byte internalButtonStatus[4];

Bounce joystickUP = Bounce(); Bounce joystickDOWN = Bounce(); Bounce joystickLEFT = Bounce(); Bounce joystickRIGHT = Bounce(); Bounce buttonA = Bounce(); Bounce buttonB = Bounce(); Bounce buttonX = Bounce(); Bounce buttonY = Bounce(); Bounce buttonL = Bounce(); Bounce buttonR = Bounce(); // Not used //Bounce buttonZL = Bounce(); //Bounce buttonZR = Bounce(); //Bounce buttonLS = Bounce(); //Bounce buttonRS = Bounce(); Bounce buttonPLUS = Bounce(); Bounce buttonMINUS = Bounce(); Bounce buttonHOME = Bounce();

/ MODE DECLARATIONS / typedef enum { RIGHT_ANALOG_MODE, ANALOG_MODE, DIGITAL, } State_t; State_t state;

typedef enum { NEUTRAL, // LEFT/UP + DOWN/RIGHT = NEUTRAL NEGATIVE, // LEFT/UP beats DOWN/RIGHT POSITIVE, // DOWN/RIGHT beats LEFT/UP LAST_INPUT, //Last input has priority; not a valid state if being used for initial_input } Socd_t; Socd_t x_socd_type = NEUTRAL; // controls left/right and up/down resolution type Socd_t y_socd_type = NEGATIVE; Socd_t x_initial_input, y_initial_input = NEUTRAL;

/ mode selectors / bool xinput; bool modeChanged;

define DATA_PIN1 A3

define DATA_PIN2 A2

//#define CLK_PIN 4

define LED_TYPE WS2812

define COLOR_ORDER GRB

define NUM_LEDS 18

CRGB leds[NUM_LEDS];

define BRIGHTNESS 20

define FRAMES_PER_SECOND 60

void checkModeChange() { if (buttonStatus[BUTTONSTART] && buttonStatus[BUTTONSELECT]) {

ifdef ENABLE_SOCD_CONFIG

if (buttonStatus[BUTTONL3] && buttonStatus[BUTTONR3])
{
  if (!modeChanged)
  {
    // read inputs at time of press
    bool up = !joystickUP.read();
    bool down = !joystickDOWN.read();
    bool left = !joystickLEFT.read();
    bool right = !joystickRIGHT.read();

    if (up && down)
      y_socd_type = LAST_INPUT;
    else if (up)
      y_socd_type = NEGATIVE;
    else if (down)
      y_socd_type = POSITIVE;
    else if (!up && !down)
      y_socd_type = NEUTRAL;

    if (left && right)
      x_socd_type = LAST_INPUT;
    else if (left)
      x_socd_type = NEGATIVE;
    else if (right)
      x_socd_type = POSITIVE;
    else if (!left && !right)
      x_socd_type = NEUTRAL;

    EEPROM.put(4, x_socd_type);
    EEPROM.put(6, y_socd_type);
    modeChanged = true;
  }
}
else 

endif

if ( !modeChanged )
{
    bool need_update = true;
    if (internalButtonStatus[BUTTONLEFT])
      state = ANALOG_MODE;
    else if (internalButtonStatus[BUTTONRIGHT])
      state = RIGHT_ANALOG_MODE;
    else if (internalButtonStatus[BUTTONUP])
      state = DIGITAL;
    else need_update = false;

    if (need_update) EEPROM.put(0, state);
    modeChanged = true;
}
else
{
  modeChanged = false;
}

} }

void setupPins() { joystickUP.attach(PIN_UP, INPUT_PULLUP); joystickDOWN.attach(PIN_DOWN, INPUT_PULLUP); joystickLEFT.attach(PIN_LEFT, INPUT_PULLUP); joystickRIGHT.attach(PIN_RIGHT, INPUT_PULLUP); buttonA.attach(PIN_A, INPUT_PULLUP); // XBOX B buttonB.attach(PIN_B, INPUT_PULLUP); // XBOX A buttonX.attach(PIN_X, INPUT_PULLUP); // XBOX Y buttonY.attach(PIN_Y, INPUT_PULLUP); // XBOX X buttonL.attach(PIN_L, INPUT_PULLUP); // XBOX LB buttonR.attach(PIN_R, INPUT_PULLUP); // XBOX RB // Not used //buttonZL.attach(PIN_ZL, INPUT_PULLUP); // XBOX LT //buttonZR.attach(PIN_ZR, INPUT_PULLUP); // XBOX RT //buttonLS.attach(PIN_LS, INPUT_PULLUP); // XBOX LS //buttonRS.attach(PIN_RS, INPUT_PULLUP); // XBOX RS buttonPLUS.attach(PIN_PLUS, INPUT_PULLUP); // XBOX START buttonMINUS.attach(PIN_MINUS, INPUT_PULLUP); // XBOX BACK buttonHOME.attach(PIN_HOME, INPUT_PULLUP);

joystickUP.interval(MILLIDEBOUNCE); joystickDOWN.interval(MILLIDEBOUNCE); joystickLEFT.interval(MILLIDEBOUNCE); joystickRIGHT.interval(MILLIDEBOUNCE); buttonA.interval(MILLIDEBOUNCE); buttonB.interval(MILLIDEBOUNCE); buttonX.interval(MILLIDEBOUNCE); buttonY.interval(MILLIDEBOUNCE); buttonL.interval(MILLIDEBOUNCE); buttonR.interval(MILLIDEBOUNCE); // Not used //buttonZL.interval(MILLIDEBOUNCE); //buttonZR.interval(MILLIDEBOUNCE); //buttonLS.interval(MILLIDEBOUNCE); //buttonRS.interval(MILLIDEBOUNCE); buttonPLUS.interval(MILLIDEBOUNCE); buttonMINUS.interval(MILLIDEBOUNCE); buttonHOME.interval(MILLIDEBOUNCE);

pinMode(PIN_L_LED, OUTPUT); pinMode(PIN_R_LED, OUTPUT); pinMode(PIN_PLUS_LED, OUTPUT); pinMode(DATA_PIN1, OUTPUT); pinMode(DATA_PIN2, OUTPUT); }

void setup() {

modeChanged = false; EEPROM.get(0, state); EEPROM.get(2, xinput);

ifdef ENABLE_SOCD_CONFIG

EEPROM.get(4, x_socd_type); EEPROM.get(6, y_socd_type);

endif

setupPins(); delay(500);

ifdef DISABLE_NSWITCH

warning "NSWITCH mode is disabled, will act only as an XInput controller"

/ force Xinput / xinput = true;

else

ifdef DISABLE_XINPUT

warning "XINPUT mode is disabled, will act only as a Nintendo switch controller"

/ force nswitch / xinput = false;

else

/ set xinput mode according to held button / // if select is held on boot, NSWitch mode int value = digitalRead(PIN_MINUS); if (value == LOW) { xinput = false; EEPROM.put(2, xinput); } // if start is held on boot, XInput mode else { value = digitalRead(PIN_PLUS); if (value == LOW) { xinput = true; EEPROM.put(2, xinput); } }

endif

endif

ifdef WITH_ANALOG

// if (digitalRead(PIN_LS) == LOW) && digitalRead(PIN_RS) == LOW) // { // g_calibrating = true; // }

g_range_l.center.x = analogRead(PIN_LANALOGX); g_range_l.center.y = analogRead(PIN_LANALOGY); g_range_r.center.x = analogRead(PIN_RANALOGX); g_range_r.center.y = analogRead(PIN_RANALOGY);

if (!g_calibrating) { EEPROM.get(8, g_range_l.min.x); EEPROM.get(10, g_range_l.min.y); EEPROM.get(12, g_range_l.max.x); EEPROM.get(14, g_range_l.max.y);

EEPROM.get(16, g_range_r.min.x);
EEPROM.get(18, g_range_r.min.y);
EEPROM.get(20, g_range_r.max.x);
EEPROM.get(22, g_range_r.max.y);

}

endif

SetupHardware(xinput); GlobalInterruptEnable();

FastLED.addLeds<LED_TYPE,DATA_PIN1,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); FastLED.addLeds<LED_TYPE,DATA_PIN2,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip); //FastLED.addLeds<LED_TYPE,DATA_PIN,CLK_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);

// set master brightness control FastLED.setBrightness(BRIGHTNESS); }

typedef void (*SimplePatternList[])(); SimplePatternList gPatterns = { rainbow, confetti, sinelon, juggle, bpm };

uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current uint8_t gHue = 0; // rotating "base color" used by many of the patterns

void loop() {

currTime = millis();

ifdef WITH_ANALOG

axisRead();

endif

buttonRead(); checkModeChange(); convert_dpad(); send_pad_state(); }

ifdef WITH_ANALOG

void axisRead() { point_t curr;

// left analog X curr.x = analogRead(PIN_LANALOGX); curr.y = analogRead(PIN_LANALOGY);

if ((curr.x - g_range_l.center.x < DEADZONE) && (curr.x - g_range_l.center.x > -DEADZONE)) buttonStatus[AXISLX] = 127; else if (curr.x < g_range_l.min.x) { g_range_l.min.x = curr.x - 10;

if (g_calibrating)
  EEPROM.put(8, g_range_l.min.x);

buttonStatus[AXISLX] = 0;

} else if (curr.x > g_range_l.max.x) { g_range_l.max.x = curr.x + 10; if (g_calibrating) EEPROM.put(12, g_range_l.max.x); buttonStatus[AXISLX] = 255; } else if (curr.x > g_range_l.center.x) { buttonStatus[AXISLX] = map(curr.x, g_range_l.center.x, g_range_l.max.x, 127, 255); } else if (curr.x < g_range_l.center.x) { buttonStatus[AXISLX] = map(curr.x, g_range_l.min.x, g_range_l.center.x, 0, 127); } buttonStatus[AXISLX] *= -1;

if ((curr.y - g_range_l.center.y < DEADZONE) && (curr.y - g_range_l.center.y > -DEADZONE)) buttonStatus[AXISLY] = 127; else if (curr.y < g_range_l.min.y) { g_range_l.min.y = curr.y - 10; if (g_calibrating) EEPROM.put(10, g_range_l.min.y); buttonStatus[AXISLY] = 0; } else if (curr.y > g_range_l.max.y) { g_range_l.max.y = curr.y + 10; if (g_calibrating) EEPROM.put(14, g_range_l.max.y); buttonStatus[AXISLY] = 255; } else if (curr.y > g_range_l.center.y) { buttonStatus[AXISLY] = map(curr.y, g_range_l.center.y, g_range_l.max.y, 127, 255); } else if (curr.y < g_range_l.center.y) { buttonStatus[AXISLY] = map(curr.y, g_range_l.min.y, g_range_l.center.y, 0, 127); } buttonStatus[AXISLY] *= -1;

// right analog

curr.x = analogRead(PIN_RANALOGX); curr.y = analogRead(PIN_RANALOGY);

if ((curr.x - g_range_r.center.x < 50) && (curr.x - g_range_r.center.x > -50)) buttonStatus[AXISRX] = 127; else if (curr.x < g_range_r.min.x) { g_range_r.min.x = curr.x - 10; if (g_calibrating) EEPROM.put(16, g_range_r.min.x); buttonStatus[AXISRX] = 0; } else if (curr.x > g_range_r.max.x) { g_range_r.max.x = curr.x + 10; if (g_calibrating) EEPROM.put(20, g_range_r.max.x); buttonStatus[AXISRX] = 255; } else if (curr.x > g_range_r.center.x) { buttonStatus[AXISRX] = map(curr.x, g_range_r.center.x, g_range_r.max.x, 127, 255); } else if (curr.x < g_range_r.center.x) { buttonStatus[AXISRX] = map(curr.x, g_range_r.min.x, g_range_r.center.x, 0, 127); } buttonStatus[AXISRX] *= -1;

if ((curr.y - g_range_r.center.y < 50) && (curr.y - g_range_r.center.y > -50)) buttonStatus[AXISRY] = 127; else if (curr.y < g_range_r.min.y) { g_range_r.min.y = curr.y - 10; if (g_calibrating) EEPROM.put(18, g_range_r.min.y); buttonStatus[AXISRY] = 0; } else if (curr.y > g_range_r.max.y) { g_range_r.max.y = curr.y + 10; if (g_calibrating) EEPROM.put(22, g_range_r.max.y); buttonStatus[AXISRY] = 255; } else if (curr.y > g_range_r.center.y) { buttonStatus[AXISRY] = map(curr.y, g_range_r.center.y, g_range_r.max.y, 127, 255); } else if (curr.y < g_range_r.center.y) { buttonStatus[AXISRY] = map(curr.y, g_range_r.min.y, g_range_r.center.y, 0, 127); } buttonStatus[AXISRY] *= -1;

}

endif

void convert_dpad() { byte cleanButtonStatus[4] = {0}; // Prevent SOCD inputs (left+right or up+down) from making it to the logic below. clean_all_socd(internalButtonStatus, cleanButtonStatus, x_socd_type, y_socd_type);

ifdef WITH_ANALOG

// force digital mode for dpad (TODO: allow the other modes as well) buttonStatus[BUTTONUP] = cleanButtonStatus[BUTTONUP]; buttonStatus[BUTTONDOWN] = cleanButtonStatus[BUTTONDOWN]; buttonStatus[BUTTONLEFT] = cleanButtonStatus[BUTTONLEFT]; buttonStatus[BUTTONRIGHT] = cleanButtonStatus[BUTTONRIGHT]; return;

endif

switch (state) { case DIGITAL: buttonStatus[AXISLX] = 128; buttonStatus[AXISLY] = 128; buttonStatus[AXISRX] = 128; buttonStatus[AXISRY] = 128; buttonStatus[BUTTONUP] = cleanButtonStatus[BUTTONUP]; buttonStatus[BUTTONDOWN] = cleanButtonStatus[BUTTONDOWN]; buttonStatus[BUTTONLEFT] = cleanButtonStatus[BUTTONLEFT]; buttonStatus[BUTTONRIGHT] = cleanButtonStatus[BUTTONRIGHT]; break;

case RIGHT_ANALOG_MODE:
  buttonStatus[AXISLX] = 128;
  buttonStatus[AXISLY] = 128;
  buttonStatus[BUTTONUP] = 0;
  buttonStatus[BUTTONDOWN] = 0;
  buttonStatus[BUTTONLEFT] = 0;
  buttonStatus[BUTTONRIGHT] = 0;

  if ((cleanButtonStatus[BUTTONUP]) && (cleanButtonStatus[BUTTONRIGHT])) {
    buttonStatus[AXISRY] = 0;
    buttonStatus[AXISRX] = 255;
  }
  else if ((cleanButtonStatus[BUTTONUP]) && (cleanButtonStatus[BUTTONLEFT])) {
    buttonStatus[AXISRY] = 0;
    buttonStatus[AXISRX] = 0;
  }
  else if ((cleanButtonStatus[BUTTONDOWN]) && (cleanButtonStatus[BUTTONRIGHT])) {
    buttonStatus[AXISRY] = 255;
    buttonStatus[AXISRX] = 255;
  }
  else if ((cleanButtonStatus[BUTTONDOWN]) && (cleanButtonStatus[BUTTONLEFT])) {
    buttonStatus[AXISRY] = 255;
    buttonStatus[AXISRX] = 0;
  }
  else if (cleanButtonStatus[BUTTONUP]) {
    buttonStatus[AXISRY] = 0;
    buttonStatus[AXISRX] = 128;
  }
  else if (cleanButtonStatus[BUTTONDOWN]) {
    buttonStatus[AXISRY] = 255;
    buttonStatus[AXISRX] = 128;
  }
  else if (cleanButtonStatus[BUTTONLEFT]) {
    buttonStatus[AXISRX] = 0;
    buttonStatus[AXISRY] = 128;
  }
  else if (cleanButtonStatus[BUTTONRIGHT]) {
    buttonStatus[AXISRX] = 255;
    buttonStatus[AXISRY] = 128;
  }
  else {
    buttonStatus[AXISRX] = 128;
    buttonStatus[AXISRY] = 128;
  }

  break;

case ANALOG_MODE:
/* fallthrough */
default:
  buttonStatus[AXISRX] = 128;
  buttonStatus[AXISRY] = 128;
  buttonStatus[BUTTONUP] = 0;
  buttonStatus[BUTTONDOWN] = 0;
  buttonStatus[BUTTONLEFT] = 0;
  buttonStatus[BUTTONRIGHT] = 0;

  if ((cleanButtonStatus[BUTTONUP]) && (cleanButtonStatus[BUTTONRIGHT])) {
    buttonStatus[AXISLY] = 0;
    buttonStatus[AXISLX] = 255;
  }
  else if ((cleanButtonStatus[BUTTONDOWN]) && (cleanButtonStatus[BUTTONRIGHT])) {
    buttonStatus[AXISLY] = 255;
    buttonStatus[AXISLX] = 255;
  }
  else if ((cleanButtonStatus[BUTTONDOWN]) && (cleanButtonStatus[BUTTONLEFT])) {
    buttonStatus[AXISLY] = 255;
    buttonStatus[AXISLX] = 0;
  }
  else if ((cleanButtonStatus[BUTTONUP]) && (cleanButtonStatus[BUTTONLEFT])) {
    buttonStatus[AXISLY] = 0;
    buttonStatus[AXISLX] = 0;
  }
  else if (cleanButtonStatus[BUTTONUP]) {
    buttonStatus[AXISLY] = 0;
    buttonStatus[AXISLX] = 128;
  }
  else if (cleanButtonStatus[BUTTONDOWN]) {
    buttonStatus[AXISLY] = 255;
    buttonStatus[AXISLX] = 128;
  }
  else if (cleanButtonStatus[BUTTONLEFT]) {
    buttonStatus[AXISLX] = 0;
    buttonStatus[AXISLY] = 128;
  }
  else if (cleanButtonStatus[BUTTONRIGHT]) {
    buttonStatus[AXISLX] = 255;
    buttonStatus[AXISLY] = 128;
  }
  else {
    buttonStatus[AXISLX] = 128;
    buttonStatus[AXISLY] = 128;
  }

  break;

} // Call the current pattern function once, updating the "leds" array gPatterns[gCurrentPatternNumber]();

// send the "leds" array out to the actual LED strip FastLED.show();
// insert a delay to keep the framerate modest FastLED.delay(1000/FRAMES_PER_SECOND);

// do some periodic updates EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow EVERY_N_SECONDS( 10 ) { nextPattern(); } // change patterns periodically }

define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))

void nextPattern() { // add one to the current pattern number, and wrap around at the end gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE( gPatterns); }

void rainbow() { // FastLEDs built-in rainbow generator fill_rainbow( leds, NUM_LEDS, gHue, 7); }

void confetti() { // random colored speckles that blink in and fade smoothly fadeToBlackBy( leds, NUM_LEDS, 10); int pos = random16(NUM_LEDS); leds[pos] += CHSV( gHue + random8(64), 200, 255); }

void sinelon() { // a colored dot sweeping back and forth, with fading trails fadeToBlackBy( leds, NUM_LEDS, 20); int pos = beatsin16( 13, 0, NUM_LEDS-1 ); leds[pos] += CHSV( gHue, 255, 192); }

void bpm() { // colored stripes pulsing at a defined Beats-Per-Minute (BPM) uint8_t BeatsPerMinute = 62; CRGBPalette16 palette = PartyColors_p; uint8_t beat = beatsin8( BeatsPerMinute, 64, 255); for( int i = 0; i < NUM_LEDS; i++) { //9948 leds[i] = ColorFromPalette(palette, gHue+(i2), beat-gHue+(i10)); } }

void juggle() { // eight colored dots, weaving in and out of sync with each other fadeToBlackBy( leds, NUM_LEDS, 20); uint8_t dothue = 0; for( int i = 0; i < 8; i++) { leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255); dothue += 32; } }

void buttonRead() { // for SOCD cleaning to work properly we need directions to update // on any change instead of on fall joystickUP.update(); joystickDOWN.update(); joystickLEFT.update(); joystickRIGHT.update(); if (joystickUP.changed() || joystickDOWN.changed() || joystickLEFT.changed() || joystickRIGHT.changed()) { internalButtonStatus[BUTTONUP] = !joystickUP.read(); internalButtonStatus[BUTTONDOWN] = !joystickDOWN.read(); internalButtonStatus[BUTTONLEFT] = !joystickLEFT.read(); internalButtonStatus[BUTTONRIGHT] = !joystickRIGHT.read(); }
if (buttonA.update()) { buttonStatus[BUTTONA] = buttonA.fell(); } if (buttonR.update()) { buttonStatus[BUTTONRB] = buttonR.fell();
digitalWrite(PIN_R_LED, LOW); } if (buttonR.fell()) {
digitalWrite(PIN_R_LED, HIGH); } if (buttonB.update()) { buttonStatus[BUTTONB] = buttonB.fell(); } if (buttonX.update()) { buttonStatus[BUTTONX] = buttonX.fell(); } if (buttonY.update()) { buttonStatus[BUTTONY] = buttonY.fell(); } if (buttonL.update()) { buttonStatus[BUTTONLB] = buttonL.fell();
digitalWrite(PIN_L_LED, LOW); } if (buttonL.fell()) {
digitalWrite(PIN_L_LED, HIGH); }

// Not used
// if (buttonZL.update()) { // buttonStatus[BUTTONLT] = buttonZL.fell(); // } // if (buttonZR.update()) { // buttonStatus[BUTTONRT] = buttonZR.fell(); // } // if (buttonLS.update()) { // buttonStatus[BUTTONL3] = buttonLS.fell(); // } // if (buttonRS.update()) { // buttonStatus[BUTTONR3] = buttonRS.fell(); // }

if (buttonPLUS.update()) { buttonStatus[BUTTONSTART] = buttonPLUS.fell(); digitalWrite(PIN_PLUS_LED, HIGH);

} if (buttonPLUS.fell()) {
digitalWrite(PIN_PLUS_LED, LOW);

}

if (buttonMINUS.update()) { buttonStatus[BUTTONSELECT] = buttonMINUS.fell(); }

if (buttonHOME.update()) { buttonStatus[BUTTONHOME] = buttonHOME.fell(); }

ifdef HOME_HOTKEY

if (buttonStatus[BUTTONSTART] && buttonStatus[BUTTONSELECT]) { if (startAndSelTime == 0) startAndSelTime = millis(); else if (currTime - startAndSelTime > HOME_DELAY) { buttonStatus[BUTTONHOME] = 1; } } else { startAndSelTime = 0; buttonStatus[BUTTONHOME] = 0; }

endif

}

void clean_all_socd(byte internalButtonStatus, byte cleanButtonStatus, Socd_t x_socd_type, Socd_t y_socd_type) { clean_socd(internalButtonStatus[BUTTONLEFT], &cleanButtonStatus[BUTTONLEFT], internalButtonStatus[BUTTONRIGHT], &cleanButtonStatus[BUTTONRIGHT], x_socd_type, &x_initial_input); clean_socd(internalButtonStatus[BUTTONUP], &cleanButtonStatus[BUTTONUP], internalButtonStatus[BUTTONDOWN], &cleanButtonStatus[BUTTONDOWN], y_socd_type, &y_initial_input); } /** Cleans the given (possible) simultaneous opposite cardinal direction inputs according to the preferences provided.

@note Given two simultaneous opposite cardinal direction inputs, clean_socd will make sure that both are not actually sent. The method used to resolve this conflict is determined by input_priority. The x (LEFT/RIGHT) and y (UP/DOWN) axes can be handled with the same logic as long as the negative and positive inputs are correctly arranged, so pointers are used to make the same function handle both.

@param[in] negative_in The LEFT/UP input variable. @param[out] negative_out The LEFT/UP resulting value. @param[in] positive_in The DOWN/RIGHT input variable. @param[out] positive_out The DOWN/RIGHT resulting value. @param[in] input_priority Determines the SOCD resolution method used. @see Socd_t for how each resolution method works. @param[in,out] initial_input If input_priority = LAST_INPUT and SOCD cleaning is needed, this is used to determine which input was made last. If only one input is made, this variable is set to that input, even if input_priority != LAST_INPUT. / void clean_socd(byte negative_in, byte negative_out, byte positive_in, byte positive_out, Socd_t input_priority, Socd_t initial_input) { if (negative_in && positive_in) // SOCD that needs to be resolved { switch (input_priority) { case NEUTRAL: negative_out = positive_out = false; break; case NEGATIVE: negative_out = true; positive_out = false; break; case POSITIVE: negative_out = false; positive_out = true; break; case LAST_INPUT: // Check which input was made first to figure out which input was made last, which wins. switch (initial_input) { case NEGATIVE: negative_out = false; positive_out = true; break; case POSITIVE: negative_out = true; positive_out = false; break; // This is a fallback case for when there hasnt been an input since starting up. case NEUTRAL: negative_out = positive_out = false; break; } } } else // no SOCD to resolve, which means our current input (if any) can be output as is, but also should be remembered as the initial input. { positive_out = positive_in; negative_out = negative_in; if (negative_in && !positive_in) initial_input = NEGATIVE; if (positive_in && !negative_in) *initial_input = POSITIVE; } } ``

RigoHoward commented 3 weeks ago

Hey, you should post a video on how your leds are going on now, i like the idea of having different led light effects :)

u didnt understand what you want tonachieve with the start button led :o

k1darklord commented 3 weeks ago

dont know if this works for a video of the lights or not https://github.com/user-attachments/assets/a674686f-6b66-4e67-bfb0-e8b1f1a4883d