RGB color, arduino

Good afternoon, please advise!

The code is designed for three pieces of tape with 12 in each.
two pieces for the players and one for demonstrating the sequence to be memorized.

at the start 12 LEDs turn on, the sequence to be remembered (4 colors: white, black, blue, red).
after 10 seconds the sequence is switched off
players by pressing keys must repeat the sequence (12 buttons and a piece of tape with 12 LEDs for each player)

the problem is that there was no tape 30 LEDs per meter, was used tape 60 LEDs per meter, what to change in the code so that 2, 4, 6, 8 and so on are not used, respectively the first button should control the first LED, the second the third and so on

#define NUM_LEDS 36       //количество светдиодов в ленте
#include "FastLED.h"      //подключаем библиотеку для работы с WS2812
#define PIN 2             //указываем PIN к которому подключена лента
#define LIMIT 10          //пределы измерений напряжения с кнопки (analogRead) 
#define BUTTON_RESET 9    //PIN кнопки перезапуска игры
#define TIME_DELAY 10000  //время на запоминание последовательности

//значения АЦП для каждой кнопки
int buttonAnalogVal[12] = {1023, 769, 610, 514, 440, 385, 341, 307, 279, 255, 236, 219};
byte led36[24];               //массив для хранения информации о цвете каждого светодиода
byte rowLed[12];              //массив для запоминания рандомных последовательностей светодиодов
bool checkButton = 0;
unsigned long timerLoop = 0;
bool playAllowed = 1;

CRGB leds[NUM_LEDS];

void setup() 
{
  FastLED.addLeds<WS2811, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(100);
  Serial.begin(9600);
  pinMode(BUTTON_RESET, INPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A5, INPUT);
  randomSeed(analogRead(A5));
  playStart();
  timerLoop = millis();
}

void loop() 
{
  if((millis() - timerLoop) >= 200) //каждые 200 мс проверяем кнопку (антидребезг)
  {
    timerLoop = millis();
    if(digitalRead(BUTTON_RESET) == 1) //если кнопка нажата
    {
      if(checkButton == 0) //проверяем предыдущее состояние кнопки
      { 
        //запускаем сравнение массивов игроков и компьютера
        checkButton = 1;
        playAllowed = 0;
        compare();
      }
      else
      {
        //запускаем игру заново
        checkButton = 0;
        playAllowed = 1;
        playStart();    
      }  
    }
    if(playAllowed == 1)
    {
      //считываем кнопки
      int analogButtonRight = analogRead(A1);
      int analogButtonLeft = analogRead(A0);
      //если заметили нажатие
      if(analogButtonRight > 5)
      {
        byte reverse = 23;
        for(int i = 0; i < 12; i++) //узнаем какую кнопку нажали и запоминаем цвет
        {
          if(((buttonAnalogVal[i] - LIMIT) < analogButtonRight) && (analogButtonRight < (buttonAnalogVal[i] + LIMIT)))
          {
            
            if(led36[i+12] < 3)
            {
              led36[i+12]++;  
            }
            else
            {
              led36[i+12] = 0;
            } 
            Serial.println("Кнопка: " + String(i) + " Состояние: " + String(led36[i+12]));
            setColor(reverse, led36[i+12]); //передаем номер светодиода и его цвет
          }
          reverse--;
        }
      }
    
      if(analogButtonLeft > 5)
      {
        for(int i = 0; i < 12; i++)
        {
          if(((buttonAnalogVal[i] - LIMIT) < analogButtonLeft) && (analogButtonLeft < (buttonAnalogVal[i] + LIMIT)))
          {
            
            if(led36[i] < 3)
            {
              led36[i]++;  
            }
            else
            {
              led36[i] = 0;
            } 
            Serial.println("Кнопка: " + String(i) + " Состояние: " + String(led36[i]));
            setColor(i, led36[i]); //передаем номер светодиода и его цвет
          }
        }
      }
    }
  }
}

void setColor(byte numLed, byte color) //функция включения светодиода в определенный цвет
{
    switch(color)
    { 
        case 0: leds[numLed].setRGB( 255, 255, 255); break; //белый
        case 1: leds[numLed].setRGB( 255, 0, 0); break;     //красный
        case 2: leds[numLed].setRGB( 0, 0, 255); break;     //синий
        case 3: leds[numLed].setRGB( 0, 0, 0); break;       //выкл.
        case 4: leds[numLed].setRGB( 255,255,0); break;     //желтый
        default: leds[numLed].setRGB( 0, 0, 0);             //по умолчанию - выкл.
    }  
    FastLED.show();
}


void start(byte R, byte G, byte B) //стартовые бегущие огни
{
  int j = 24;
  for(int i = 0; i < 12; i++)
  {
    j--;
    leds[i].setRGB( R, G, B);
    leds[j].setRGB( R, G, B);
    leds[i+24].setRGB( R, G, B);
    FastLED.show();
    delay(100);
    leds[i].setRGB( 0, 0, 0);
    leds[j].setRGB( 0, 0, 0);
    leds[i+24].setRGB( 0, 0, 0);
    FastLED.show();
  }    
}

void compare() //функция сравнения массивов двух игроков и компьютера
{
  byte reverse = 23;
  for(int i = 0; i < 12; i++)
  { 
    setColor(i+24, rowLed[i]);
    delay(1000);  
    if(led36[i] != rowLed[i])
    {        
      setColor(i, 4);  
    }
    if(led36[i+12] != rowLed[i])
    {
      setColor(reverse, 4);  
    }   
    reverse--;
  }  
}

void playStart() //функция начала игры
{
  for(int i = 0; i < 24; i++)
  {
    led36[i] = 0; //обнуляем массив с предыдущими значениями светодиодов
  }
  start(255,0,0);
  start(255,255,255);
  start(0,0,255);
  for(int i = 24; i < 36; i++) //включаем рандомную последовательность цветов светодиодов
  {    
    byte randomLed = random(0,3);
    rowLed[i-24] = randomLed;
    setColor(i, randomLed);
    delay(500);
  }
  unsigned long timerPrev = millis();
  while((millis() - timerPrev) < TIME_DELAY) //ждем 10 сек на запоминание цветов
  {
    if(digitalRead(BUTTON_RESET) == 1) //если во время этого нажали на кнопку - запускаем игру заново
    {
      playStart();
    }   
  }
  for(int i = 24; i < 36; i++) //гасим верхние светодиоды
  {
    setColor(i, 3);
  }
  for(int i = 0; i < 24; i++) //включаем белый цвет на светодиодах игроков
  {
    setColor(i, 0);
  } 
}

An Arduino Uno ?
Do 12 buttons go to a single analog pin ? Can you show a schematic ?
Are there 4 ledstrips of 9 leds each ?
Sorry, but I don't understand your question.

Yes, arduino uno
Here is the schematic:

The tape should have 12, 12, 12 LEDs (30 LEDs per meter), and it has twice as many (60 LEDs per meter)
24, 24, 24 LEDs

Mathematics will do all kndsa stuff, here simply

void setColor(byte numLed, byte color) { 

   numLed *= 2;

// what was 0,1,2... will now be written to 0,2,4…

In other places where you directly assign to the LED buffer array, just again double the index.

If there are a crap ton of those, and you only have one or a few places where the buffer is shipped out, you could apply to the buffer a process of spreading them out, start at the far end and move pixels to where they "shoukd" be, and write zeros in the places that are emptied.

Or use two buffers, one that you write into as usual, and the other that gets the spread out version before it is published.

a7

Can you please tell me how to do this?

Which what? If what I described makes no sense, I can help, but I need to know what is confusing you.

Any of these

              led36[i+12]++;  

just needs the same treatment

              led36[(i + 12) * 2]++;  

If you mean the shuffle, with one or with two arrays, that will have to wait until I can test any code I would share.

And I can say

    leds[i].setRGB( R, G, B);
    leds[j].setRGB( R, G, B);
    leds[i+24].setRGB( R, G, B);
    FastLED.show();
    delay(100);
    leds[i].setRGB( 0, 0, 0);
    leds[j].setRGB( 0, 0, 0);
    leds[i+24].setRGB( 0, 0, 0);
    FastLED.show();
//  delay(100);  // or you never see them being off

You either need another delay to show the LEDs in their off state, or you can just lose writing them to be off and publishing them, because you immediately write real colours.

The good thing is that you don't have the show() method scattered all ovcer, making a one place to handle this available. That would be my recommendation, and as I say, w/o being able to test it, it's just a loop over the strip that moves 0 to 0, 1 to 2, 2 to 4 and so forth, which is why... you have to go backwards.

a7

Do you need to change everything here, where highlighted, or only in one place?

If you do it as you go, then yes, every single reference to an array element [x] would need to refer instead to [2 * x].

But that will get old pretty fast, no fun, prone to overlooking here or there and so forth.

Easier: write into a dummy array half the size of the real LED array, then just before you call the show() method, copy the dummy array to the real array.

To save typing, let the name of the dummy be leds and make the real array be realLEDs.

# define NUM_LEDS 18
# define REAL_LEDS 36

CRGB realLEDs[REAL_LEDS];
CRGB leds[NUM_LEDS]

// in setup
  FastLED.addLeds<WS2811, PIN, GRB>(leds, REAL_LEDS).setCorrection( TypicalLEDStrip );

// elsewhere 
// before you show, spread them over to the real LED buffer

  for (int ii = 0; ii < NUM_LEDS; ii++)
    realLEDs[ii * 2] = leds[ii]:

  fastLED.show();

I'd put that in a function and call it instead wherever you call the show() method, viz:

void myShow()
{
  for (int ii = 0; ii <NUM_LEDS; ii++)
    realLEDs[ii * 2] = leds[ii]:

  fastLED.show();
}

I've said I can't test this. If it doesn't make complete and total sense to you, I wouldn't suggest trying it. The concept is simple, my code should work or be very close, but I may have missed a detail in the rest of your code.

HTH

a7

Wrong, sry. I had not read much of the code.

The only array to double the index used is the one fastLED will see, in your code leds[...]

Which would be not problem with the replacement function as it mentioned only leds.

a7