Hoe maak ik deze voor 16 leds in plaats van 6

Hoi,

Op dit moment heb ik dit voor 6 leds

bool tweeKeer(int potVal)
{
  LED0 = !LED0;

  digitalWrite(ledPins[0], LED0);
  digitalWrite(ledPins[1], LED0);
  digitalWrite(ledPins[2], !LED0);
  digitalWrite(ledPins[3], !LED0);
  digitalWrite(ledPins[4], LED0);
  digitalWrite(ledPins[5], LED0);

  return true; 
};

Nu wil ik hetzelfde effect maken voor de 16 leds die aan de led-ring (ws 2812) zitten.

Hoe kan ik dit het beste aanpakken.

ik kan alle 16 leds aanschrijven maar dat lijkt me niet goed programmeren.

Wat ik bereiken wil is dit effect

 leds   ronde 1   ronde 2
    
1          aan       uit
2          aan       uit
3          uit       aan
4          uit       aan
5          aan       uit
6          aan       uit
7          uit       aan
8          uit       aan
9          aan       uit
10         aan       uit
11         uit       aan
12         uit       aan
13         aan       uit
14         aan       uit
15        uit        aan
16        uit        aan  

Zo alle oneven rondes zijn hetzelfde als ronde 1
Alle even rondes zijn hetzelfde als ronde 2

Waarom niet? Kun je een voorbeeld geven hoe je dat ziet.

leds[0]=CRGB::Black;
leds[1]=CRGB::Black;
...
leds[15]=CRGB::Black;

Is inderdaad niet echt geweldig. Je kunt beter for-loops gebruiken om alle LEDs te zetten

for(uint8_t cnt = 0; cnt < NUM_LEDS; cnt++)
{
  leds[cnt]=CRGB::Black;
}

oke

maar hoe zie ik het dan welke aan en uit moeten met het schema dat ik gemaakt hebt in dezelfde post ?

OK, ik denk dat LED0 een int is (misschien een uint8_t of zo).

De initiële waarde is 0 (denk ik). Als dat zo is kun je iets gebruiken in de geest van

// determine PWM value
if(LED0 == 0)
{
  LED0 = 255;
}
else
{
  LED0 = 0;
}

En dan iets als

// change red
led[0] = CRGB(LED0, 0 ,0);

Ga ik eens proberen.

Ben jaloers dat jij zo makkelijk dit soort zaken kan oplossen

Ik had je eigenlijk moeten vragen of je LED0 = !LED0 op een andere manier kunt schrijven met if / else?

Als dat gelukt was had dan misschien zelf kunnen uitvogelen hoe je bij mijn oplossing had kunnen komen; nu te laat.

Leerpunt voor ons allebeide. :slight_smile:

Ander idee

Zou dit kunnen werken.

bool tweeKeer(int potVal)
{

   // alle leds uit 
  for(uint8_t cnt = 0; cnt < NUM_LEDS; cnt++)
  {
      leds[cnt]=CRGB::Black;
  }
  
  if (led0 == 0) { 
    leds[0] = CRGB::Red; 
    leds[1] = CRGB::Red;
    leds[5] = CRGB::Red;
    leds[6] = CRGB::Red;
    leds[9] = CRGB::Red;
    leds[10] = CRGB::Red;
    leds[13] = CRGB::Red;
    leds[14] = CRGB::Red;
   } else { 
     leds[2] = CRGB::Red; 
    leds[3] = CRGB::Red;
    leds[7] = CRGB::Red;
    leds[8] = CRGB::Red;
    leds[11] = CRGB::Red;
    leds[12] = CRGB::Red;
    leds[15] = CRGB::Red;
    leds[16] = CRGB::Red;
 }
  Led0 = !LED0; 
   return true; 
};

Nog steeds niet handig als er meer leds komen, maar ik denk wel dat het kan werken.

Je hebt hier twee patronen die elkaar afwisselen. Je kunt overwegen die patronen als arrays in het geheugen te zetten en als LED0 nul is één patroon te kopiëren naar het leds array en als LED0 1 is het andere patroon te kopiëren. Je hebt in je "meneer van dalen" onderwerp al gebruik gemaakt van memcpy(); dat kun je nu ook gebruiken.

Als je het slim aanpakt ga je een twee-dimensionaal array gebruiken voor de patronen; dan kun je LED0 gebruiken als de index (er even van uitgaande dat LED0 een int-achtig type is).

Er moet me wel iets van het hart. Ik snap dat je dit in kleine stapjes wilt doen maar waarom gebruik je nog steeds leds[X] = ...?

In al je testen (om een effect werkend te krijgen met de NeoPixel ring) zou je gebruik moeten maken van bestaande functionaliteiten (in dit geval wat in de output bestanden zit van je LCD/knoppen/LEDs programma); je hebt deze al herschreven als ik me niet vergis. Als je dat niet doet bezorg je jezelf hele stapels werk.

Er zijn twee pwm functies in output, pwmLed() en pwmAll(). Het zou dus eenvoudig moeten zijn om wat je nu hebt om te zetten naar het gebruik van pwmLed(); iets als

bool tweeKeer(int potVal)
{
   // alle leds uit 
  for(uint8_t cnt = 0; cnt < NUM_LEDS; cnt++)
  {
      leds[cnt]=CRGB::Black;
  }
  
  if (led0 == 0) { 
    pwmLed(0, CRGB::Red);
    pwmLed(1, CRGB::Red);
    pwmLed(5, CRGB::Red);
    pwmLed(6, CRGB::Red);
    pwmLed(9, CRGB::Red);
    pwmLed(10, CRGB::Red);
    pwmLed(13, CRGB::Red);
    pwmLed(14, CRGB::Red);
   } else { 
     ...
     ...
   }
  Led0 = !LED0; 
   return true; 
};

Als je de benadering met de twee patronen gaat gebruiken kun je pwmAll() gebruiken; deze moet mogelijk nog enigszins aangepast worden omdat we deze nog niet gebruikt hebben en dus niet getest.

Dat van de twee-dimimensionale array is een idee wat ik eens ga uitproberen.

Nee, led0 is een bool

zie effects.cpp regel 8

static bool LED0 = 0; 

Waar ik aan dacht is

bool tweeKeer(int potVal)
{
  LED0 = !LED0;
  for (uint8_t i = 0; i < NUM_LEDS; i++) {
    uint8_t x = i / 2;
    x = x % 2;  // en deze 2 kunnen in 1 keer x = (i / 2) % 2;
    if (x == 0) {   // of if(x) { of dus zelfs if ((i / 2) % 2) {
      digitalWrite(ledPins[i], LED0);
    }
    else {
      digitalWrite(ledPins[i], !LED0);
    }
  }
  return true;
};

Het gebruik van een (for) loop is bij het roteren door meer dan 2 velden van de array al aan te raden, maar bij 6 zeker. Het gebruik van wiskundige berekening is de manier om dan te bepalen wat er moet gebeuren.

@Deva_Rishi

Ik heb net de code aangepast aan mijn situatie en er branden twee om twee maar er is geen beweging (dus ronde 1 wordt wel uitgevoerd maar ronde 2 niet).

Heb je een vorm van debug ingebouwd om te kunnen zien wat er gebeurt ?

nee, maar probeer nu wel de code te bouwen die @sterretje voorstelde

maar dan krijg ik deze compile error :

/sketch/effects.cpp: In function 'bool tweeKeer(int)':
/sketch/effects.cpp:132:40: error: cannot convert 'CRGB::HTMLColorCode' to 'CRGB*' for argument '1' to 'bool pwmAll(CRGB*, uint8_t)'
   pwmAll(CRGB::Blue, leds_working[LED0]); 

                                        ^
Error during build: exit status 1

Code :

bool tweeKeer(int potVal)
{
  
  LED0 = !LED0;
  int leds_working[2][8] = {
    {0,1,5,6,9,10,13,14},
    {2,2,7,8,11,12,15,16},
  } ;

  pwmAll(CRGB::Blue, leds_working[LED0]); 
  return true;
};

Code pwmAll :

bool pwmAll( CRGB *colours, uint8_t size) {
  for (uint8_t cnt=0; cnt < size; cnt++) {
    leds[cnt] = colours[cnt];
   
  }
  FastLED.show(); 
  return true; 
}

't is allemaal een beetje verwarrend, je probeert een code voor individuele leds aan te passen aan een ledstrip, maar in principe zou je opnieuw moeten beginnen.
Dit is ook een beetje een probleem met al die verschillende bestanden. Er is voor mij totaal geen overzicht meer tenzij ik de gehele code opzoek op wokwi, maar dan kan ik weer niet inzoomen.

Maak gewoon per idee een voorbeeld sketch en ga daarna deze implementeren. Dan weet je of iets werk en kan je zonder link eenvoudig gehele werkende (of niet werkende) sketches plaatsen.

Je laat niet zien wat je veranderd hebt, en je laat niet zien waar vanuit je iets aanroept en hoe. Dus 'het werkt niet' is gewoon heel vaag. Of het werkt of niet is dan niet te zien. @sterretje Dit soort berekenmatige bewerkingen en loop berekeningen zijn wat mij btreft echt veel meer van belang dan hoe je dat in allemaal verschillende bestanden zet.

Beschrijf het eerste argument van pwmAll().
Beschrijf wat CRGB::Blue is.

Is er een verschil?

Dacht het al

Het eerste argument van pwmAll is een array
En CRGB::Blue is een item uit een enum.

Dus ik moet ook een array maken met 8 keer de kleur.

Dit is een voorbeeld dat werkt, zo moet je het doen

#include <FastLED.h>

#define NUM_LEDS 16
#define DATA_PIN 3

CRGB leds[NUM_LEDS];

void setup() { 

 FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);  
}

void loop() { 
  static bool LED0 = true;
  LED0 = !LED0;
  for (uint8_t i = 0; i < NUM_LEDS; i++) {
    uint8_t x = i / 2;
    x = x % 2;  // en deze 2 kunnen in 1 keer x = (i / 2) % 2;
    if (x == 0) {   // of if(x) { of dus zelfs if ((i / 2) % 2) {
      if (LED0) leds[i] = CRGB::Blue;
      else leds[i] = CRGB::Red;
    }
    else {
      if (!LED0) leds[i] = CRGB::Blue;
      else leds[i] = CRGB::Red;
    }
  }
  FastLED.show();
  delay(500);
}

Je zou zelfs de waarde van x & LED0 kunnen combineren

wordt even gek

bool tweeKeer(int potVal)
{
  
  LED0 = !LED0;
  int leds_working[2][8] = {
    {0,1,5,6,9,10,13,14},
    {2,2,7,8,11,12,15,16},
  } ;

  CRGB colors [1][8] = {
    {CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue}
  };

  pwmAll(colors[0] ,leds_working[LED0]); 
  return true;
};

en nu krijg ik geen error maar ook geen led gaat uit of aan.