Can this code be smaller

Hello,

IM busy with some leds which turn to a side by using a potmeter.
it works fine but I find the code a little long.

Code so far :

const uint8_t ledPins[] = { 9, 11, 10, 6, 3, 5 };

byte Potpin = A3;
int Potvalue;

byte currentLed = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start"));
  for (uint8_t cnt = 0; cnt < sizeof(ledPins); cnt++)
  {
    digitalWrite(ledPins[cnt], HIGH);
    pinMode(ledPins[cnt], OUTPUT);
  }
}


void loop()
{
  Potvalue = analogRead(Potpin);

   if (Potvalue < 512)
  {
    ////////////////////////
    // aansturen LEDs
    ////////////////////////
    Serial.print(F("Aan: "));
    Serial.println(currentLed);
    digitalWrite(ledPins[currentLed], LOW);
    Serial.print(F("Uit: "));
    if (currentLed == 0)
    {
      Serial.println(sizeof(ledPins) - 1);
      digitalWrite(ledPins[sizeof(ledPins) - 1], HIGH);
    }
    else
    {
      Serial.println(currentLed - 1);
        digitalWrite(ledPins[currentLed - 1], HIGH);
    }

    ////////////////////////
    // aanpassen currentLed
    ////////////////////////
    currentLed++;
    if (currentLed == sizeof(ledPins))
    {
      Serial.println(F("Overflow"));
      currentLed = 0;
    }
  }

  if (Potvalue > 512)
  {
    ////////////////////////
    // aansturen LEDs
    ////////////////////////
    Serial.print(F("Aan: "));
    Serial.println(currentLed);
    digitalWrite(ledPins[currentLed], LOW);
    Serial.print(F("Uit: "));
    if (currentLed == sizeof(ledPins) - 1)
    {
      Serial.println(ledPins[0]);
      digitalWrite(ledPins[0], HIGH);
    }
    else
    {
      Serial.println(currentLed + 1);
      digitalWrite(ledPins[currentLed + 1], HIGH);
    }

    ////////////////////////
    // aanpassen currentLed
    ////////////////////////
  
    if (currentLed == 0)
    {
      Serial.println(F("Overflow"));
      currentLed = sizeof(ledPins) - 1;
    } else {
        currentLed--;
    }
  }

  delay(500); 
}

Now I wonder if the code could be smaller without losing the functionallilty.

Next step will be to make it work like knight rider so some leds will burn a little less bright to make that effect.

something like this ? (without the Serial prints)

const uint8_t ledPins[] = { 9, 11, 10, 6, 3, 5 };
const uint8_t pinsCnt = sizeof ledPins / sizeof * ledPins;
const uint8_t Potpin = A3;
byte currentLedIndex = 0;
unsigned long chrono = 0;

void setup() {
  for (byte led : ledPins) {
    pinMode(led, OUTPUT);
    digitalWrite(led, HIGH);
  }
}

void loop() {
  if (millis() - chrono > 500) {
    digitalWrite(ledPins[currentLedIndex], HIGH);
    currentLedIndex = analogRead(Potpin) < 512 ? (currentLedIndex == 0 ? pinsCnt - 1 : currentLedIndex - 1) : (currentLedIndex + 1) % pinsCnt;
    digitalWrite(ledPins[currentLedIndex], LOW);
    chrono = millis();
  }
}

(this is assuming you don't want to stop if the pot is exactly at 512)

Thanks

the only problem is that the code is not working the wrong way around.

And can you explain this line :

const uint8_t pinsCnt = sizeof ledPins / sizeof * ledPins;

this might be easier to read

const byte Npin = sizeof(ledPins);

and

        int pot = analogRead (Potpin);
        idx = pot > 512 ? (! idx ? Npin-1 : --idx) : ++idx % Npin;
        digitalWrite (ledPins[idx], LOW);

Sorry, I find this part more confusing

(! idx ? Npin-1 : --idx)

what does the !idx do ?

NOT. so the condition is TRUE if 0 == idx

I like also this code you posted on a earlier chat

const byte Potpin    = A3;
const byte PinLeds[] = { 9, 11, 10, 6, 3, 5 };
const int  Nled      = sizeof(PinLeds);

enum { Off = HIGH, On = LOW };

byte currentLed = 0;

// -----------------------------------------------------------------------------
void setup()
{
    Serial.begin(115200);
    Serial.println(F("Start"));
    for (uint8_t cnt = 0; cnt < Nled; cnt++) {
        digitalWrite (PinLeds[cnt], Off);
        pinMode      (PinLeds[cnt], OUTPUT);
    }
}


void loop()
{
    if (512 <  analogRead(Potpin)) {
        digitalWrite (PinLeds[currentLed], Off);

        if (Nled <= ++currentLed)
            currentLed = 0;
        digitalWrite (PinLeds[currentLed], On);

        Serial.print   (F("Aan: "));
        Serial.print   (currentLed);
        Serial.print   (F(" Uit: "));
        Serial.println (PinLeds[currentLed]);
    }
    delay(500);
}

but I have then to think well how to adapt that so it also turns out the other way

see Ternary Operator

not tested,

uint8_t ledPins[] = { 9, 11, 10, 6, 3, 5 };

byte Potpin = A3;
int Potvalue;

byte currentLed  = 1;
byte previousLed = 0;


void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start"));
  for (uint8_t cnt = 0; cnt < sizeof(ledPins); cnt++)
  {
    digitalWrite(ledPins[cnt], HIGH);
    pinMode(ledPins[cnt], OUTPUT);
  }
}


void loop()
{
  int potValue = analogRead(Potpin) ;
  //  switch old off
  digitalWrite(ledPins[currentLed], LOW);
  if (potValue  < 512)
  {
    currentLed = (currentLed + 1) % sizeof(ledPins);
  }
  else
  {
    currentLed = (currentLed - 1 + sizeof(ledPins) ) % sizeof(ledPins);
  }
  //  switch new on.
  digitalWrite(ledPins[currentLed], HIGH);

  delay(500); 
}

Tested it on wokwiki and it does not work.

yes, i see that that works. good

        int pot = analogRead (Potpin);
#if 0
        idx = pot > 512 ? (! idx ? Npin-1 : --idx) : ++idx % Npin;
#else
        if (512 < pot)
            idx = ++idx % Npin;
        else
            idx = (--idx+Npin) % Npin;
#endif

        digitalWrite (ledPins[idx], LOW);

        char s [90];
        sprintf (s, " %4d  %3d %3d", pot, idx, Npin);
        Serial.println (s);

Chips

I tried myself to rewrite it

const uint8_t ledPins[] = { 9, 11, 10, 6, 3, 5 };
const byte Npin = sizeof(ledPins);
const uint8_t Potpin = A3;
byte idx = 0;
unsigned long chrono = 0;

void setup() {
  for (byte led : ledPins) {
    pinMode(led, OUTPUT);
    digitalWrite(led, HIGH);
  }
}

void loop() {
  if (millis() - chrono > 500) {
    digitalWrite(ledPins[idx], HIGH);
    int pot = analogRead (Potpin);
    if (pot > 512)  {
      idx = ++idx % Npin;
    } else {
       if (idx != 0) {
         idx = Npin -1;
       } else {
         --idx; 
       }
    }
    digitalWrite (ledPins[idx], LOW);
    chrono = millis();
  }
}

but now it does not work when turning to the left.

See Wokwi - Online ESP32, STM32, Arduino Simulator

        } else {
            if (idx == 0) {
                idx = Npin -1;

Thanks

Time for a break and then look if I can make some sort of knight rider effect on it.

@gcjr do you have hints how to make a sort of knight rider effect.

When I think of it. I see a lot of new if then's appear because you have to 1 - 6 "problem" ?

Change < 512 into > 512

That’s the way to count the number of entries in an array. It simply calculates the full size in bytes divided by the size of the first element which gives you the number of elements. (The way you wrote works because the size of each element is 1 (a byte) so it’s ok to forget the division - but in general you are better off keeping the division.)

1 Like
const uint8_t ledPins[] = { 9, 11, 10, 6, 3, 5 };
const byte Npin = sizeof(ledPins);

byte idx = 0;
int  dir = -1;
unsigned long chrono = 0;

enum { Off = HIGH, On = LOW };

void loop ()
{
    if (millis() - chrono > 250) {
        chrono = millis();

        digitalWrite (ledPins[idx], Off);
        if (0 == idx || idx == Npin-1)
            dir = -dir;
        idx += dir;
        digitalWrite (ledPins[idx], On);

        Serial.println (idx);
    }
}

void setup() {
    Serial.begin (9600);
    for (byte led : ledPins) {
        pinMode(led, OUTPUT);
        digitalWrite(led, Off);
    }
}

better than doing ledPins [currentLed -1]

Sorry that I was not clear what I mean

What I mean is this

led 4 burns on 100%
led 3 burns on 75%
led 2 burns on 50%
led 1 burns on 25%

and then make the same movement as my old code
So clockwise or anticlock wise depending on the value of the potmeter.

But the problem I see is this

led 0 100%
led -1 75 % (but that one does not exist , schould be led 5
led -2 50 % ( schould be led 4)
and so on

led 1 100%
led 0 75%
led -1 50% ( should be led 6)
and so on

I hope it is clear what I mean

clear as mud :slight_smile:

what do you mean by "burn"? apparent brightness?

yes sorry

I mean brightness