/*
LED bar graph
Turns on a series of LEDs based on the value of an analog sensor.
This is a simple way to make a bar graph display. Though this graph uses 10
LEDs, you can use any number by changing the LED count and the pins in the
array.
This method can be used to control any series of digital outputs that depends
on an analog input.
The circuit:
- LEDs from pins 2 through 11 to ground
created 4 Sep 2010
by Tom Igoe
modified 2024-01-02 by Dave X
This example code is in the public domain.
https://www.arduino.cc/en/Tutorial/BuiltInExamples/BarGraph
https://github.com/arduino/arduino-examples/blob/main/examples/07.Display/barGraph/barGraph.ino
https://wokwi.com/projects/385842521990633473
*/
// these constants won't change:
const int analogPin = A0; // the pin that the potentiometer is attached to
// create an enum for choosing a scale calculation
enum Scale {CUSTOM, BY100S, LINEAR, LOG,LOGalt,LOGalt10} scaling = LOGalt;
// setup a lookup table with pin numbers and custom thresholds
struct LedPin {
byte pin;
unsigned int threshold;
} ledPins[] = {
{2, 10},
{3, 20},
{4, 50},
{5, 450},
{6, 500},
{7, 550},
{8, 600},
{9, 650},
{10, 700},
{11, 0}
};
const unsigned int numThresh = sizeof(ledPins)/sizeof(ledPins[0]);
void setup() {
Serial.begin(115200);
// loop over the pin array and set them all to output,
// and calculate the thresholds
for (auto &ledPin : ledPins) {
byte index = &ledPin - &ledPins[0]; // https://stackoverflow.com/questions/10962290/how-to-find-the-index-of-current-object-in-range-based-for-loop
pinMode(ledPin.pin, OUTPUT);
switch (scaling) {
case CUSTOM:
break;
case BY100S:
ledPin.threshold = 100 + 100 * index; // override 50, 150,...
break;
case LINEAR:
ledPin.threshold = (index * 1023) / (sizeof(ledPins) / sizeof(ledPins[0])); // override even
break;
case LOG:
ledPin.threshold = 2 * pow(2, index); // override log scale
break;
case LOGalt10:
ledPin.threshold = exp(log(1023)/10 * (1+index)); // override log scale
break;
case LOGalt:
ledPin.threshold = exp(log(1023)/numThresh * (1+index)); // override log scale
break;
default:
break;
}
Serial.print("id:");
Serial.print(index);
Serial.print(" Threshold:");
Serial.println(ledPin.threshold);
}
}
void loop() {
// read the potentiometer:
int sensorReading = analogRead(analogPin);
static int lastReading = -1;
if (abs(sensorReading - lastReading) > 0) { // if changed...
// set all leds based on thresholds:
for ( auto &pin : ledPins) {
digitalWrite(pin.pin, sensorReading >= pin.threshold ? HIGH : LOW);
}
Serial.print(sensorReading);
Serial.print(" ");
lastReading = sensorReading;
}
}