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.
J-M-L
May 11, 2025, 9:47am
2
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;
gcjr
May 11, 2025, 10:37am
4
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 ?
gcjr
May 11, 2025, 10:40am
6
roelofw:
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
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.
gcjr
May 11, 2025, 10:52am
11
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
gcjr
May 11, 2025, 11:20am
13
} 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" ?
J-M-L
May 11, 2025, 12:28pm
16
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
gcjr
May 11, 2025, 1:08pm
17
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
J-M-L
May 11, 2025, 3:07pm
19
clear as mud
what do you mean by "burn"? apparent brightness?