# Museum Interactive: LED Help

Greetings,

I am fairly new at figuring out something like this so would appreciate some help...
We are in the middle of planning out an interactive at a museum that would highlight certain areas on a map with LED lights. There will be 5-6 push buttons, and each button will control a certain group of lights (categories of natural areas). There are 66 total lights (natural areas). Certain lights will fall under multiple button categories (for example, one LED will light up if button 1 or 2 is pressed). Lights will turn off after a certain number of seconds.

Layout:

The assistance I have received so far has been very helpful in getting the parts list and general schematic, and arduino code together. I am now seeking help in calculating what number resistor to attached to each LED. Below are the two LEDs I have to test out (will choose one type). Other supplies being used are also listed.

• Arduino Mega 2560

• 5V 7A 35W Power Supply, for Arduino, and Relays.

• Relays 5vDC activated by Arduino (x10)

• Terminal Strip for ground distribution

• Push buttons

• Resistors TBD

• Bright White LED 10mm:
Forward Current: 80 mA
Peak Forward Current: 120 mA
Suggestion Using Current: 65-75 mA
Forward Voltage: Min. 3 Max. 3.4 V
or

• Diffused White LED 10mm:
Forward Current: 20 mA
Peak Forward Current: 30 mA
Suggestion Using Current: 16-18 mA
Forward Voltage: Min. 3 Max 3.4 V

So my question is, based on this information, what number of resistor should I attached to the LEDs? Would they all have the same kind? or would some be different?

EDIT:
Now exploring an alternative setup, using Neopixels.

Subtract the forward voltage from your supply voltage and divide by the suggested (desired...) current giving the resistance for one LED.

You can use an on line calculator

May be late in the game, but have you considered building a LED strip (Neopixels or APA102)? They would be easier to drive from Arduino, requires only one data pin and no resistor at all and a small arduino would do (Uno, Nano, ...) as you do not requires lots of pins for each LED. Bonus you get color and are no longer limited by the number of LEDs your board can support, you can have multiple hundreds if you want to

Side note... there is a typo in the text... (acquire)

2 Likes

The Bright White LED 10mm Forward Current: 80 mA cannot be driven directly by an Arduino output. It will need a transistor driver like this for each LED:

Or if you up the supply voltage you can drive several in series (number depending on supply voltage).

I agree with @J-M-L in that for this application LED strips may be a great alternative. I like the WS2812 (comparable with Neopixels). They do require a capable power supply as each pixel (3 color LED) can take up to 60mA at full brightness white.

1 Like

Thanks for your help. To clarify when you said to divide by the (desired) current, should I put the "Forward Current" (80 mA) or the "Suggested Using Current" (65-75 mA) in the calculation?

Depends. As does everything.

Calculate a few resistors for a number of currents, never exceeding the 80, and going as low as 15 or 20, drive them with the circuit you are going to use, and see what they look like.

LEDs vary quite a bit from one to the next, even but less so within a batch purchased at first prices.

Then there is how they will function in your deployment context, bare bulb, behind frosted glass or whatever, so basically get empirical.

But I agree that smart LEDs, which have been suggested here and in you earlier inquiry this year, might be better in some ways.

a7

1 Like

@alto777 @groundFungus @DrDiettrich
Thank you all for the suggestion in using Neopixels.
We explored this option when we wanted to use multiple colored lights, but for some reason switched when we knew we only needed white lights.

If I were to go down that route, I would need to figure out how to hook that up and what supplies would be needed, and a different code... So it is a good option I just not have as much direction for that type and would welcome that.

Given the project is for a museum I think you'll find happy volunteers to help with the code.

The wiring is pretty simple. (look here for details)

you basically daisy chain the LEDs (and bring power at both ends for stability)

1 Like

For the WS2812 (and other) RGB LED strips there is the FastLED library that makes using the strips easier.

2 Likes

TBC smart LEDs can be had in a variety of physical forms, some of which may be just right, like long linear strips, small numbers in a row on a little PCB, rings, matrices and individually.

The libraries work them all, and can do using just one pin. Any conceptual grouping and/or individual handling can be done in the code variously. I use lookup tables quite a bit, fashions and habits abound.

a7

1 Like

Each button can have its own look up table (1D array) to actuate the required LEDs for that button.

And use non-blocking timing methods to make the program responsive.
Non-blocking timing tutorials:
Several things at a time.
Beginner's guide to millis().

1 Like

Just to show how not complicated it can be, here is a basic code (totally untested so might not work ) you could play with

``````#include <FastLED.h>
// For led chips like WS2812, which have a data line, ground, and power, you just need to define dataPin.
const uint8_t dataPin = 3;

// For led chipsets that are SPI based (four wires - data, clock, ground, and power),
// like the APA102, define both dataPin and clockPin
const uint8_t clockPin = 13;              // 13 is SPI SCK on UNO, use 52 on a MEGA

// Define the array of leds
const uint8_t ledCount = 66;              // How many you have
CRGB leds[ledCount];

// Define the zones on the map
const uint8_t maxLedPerZone = 10;         // this is to make our life easy with fixed size arrays even if it wastes a bit of RAM

struct t_zone {
const uint8_t   ledIDs[maxLedPerZone];  // where they are in the strip, starting at position 0
const uint8_t   ledCount;               // how many LEDs are in this area
const uint32_t  lightingDuration;       // How long the area stays lit in ms
const uint8_t   buttonPin;              // the pin of the button triggering this zone
bool            ledsAreOn;              // true if leds are on
uint32_t        startTime;              // utility for timeout
};

t_zone zones[] = {
/* leds position in strip            count    period  button    keep as is */
{{0, 1, 2, 3, 4, 5, 6}              , 7     , 20000,    7,      false, 0},
{{2, 3, 4, 7, 8, 9, 10}             , 7     , 20000,    6,      false, 0},
{{4, 5, 6, 10, 11, 12, 13, 60, 61}  , 9     , 20000,    5,      false, 0},
};
const uint8_t zoneCount = sizeof zones / sizeof zones[0];

bool ledIsOnInAnotherZone(uint8_t ledId, uint8_t currentZone)
{
bool ledIsOn = false;
for (uint8_t z = 0; z < zoneCount; z++) {
if ((z != currentZone) && zones[z].ledsAreOn) {
for (uint8_t i = 0; i < zones[z].ledCount; i++) {
if (ledId == zones[z].ledIDs[i]) {
ledIsOn = true;
break;
}
}
}
}
return ledIsOn;
}

void zoneOn(uint8_t zoneID) {
for (uint8_t i = 0; i < zones[zoneID].ledCount; i++)
leds[zones[zoneID].ledIDs[i]] = CRGB::White;
FastLED.show();
zones[zoneID].startTime = millis();
zones[zoneID].ledsAreOn = true;
}

void zoneOff(uint8_t zoneID) {
for (uint8_t i = 0; i < zones[zoneID].ledCount; i++)
if (!ledIsOnInAnotherZone(zones[zoneID].ledIDs[i], zoneID))   // only turn it off if it does not belong to another zone that is ON
leds[zones[zoneID].ledIDs[i]] = CRGB::Black;
FastLED.show();
zones[zoneID].ledsAreOn = false;
}

void checkButtons() {
for (uint8_t z = 0; z < zoneCount; z++)
if ((!zones[z].ledsAreOn) && (digitalRead(zones[z].buttonPin) == LOW))
zoneOn(z);
}

void checkTimeout() {
for (uint8_t z = 0; z < zoneCount; z++)
if (zones[z].ledsAreOn && (millis() - zones[z].startTime > zones[z].lightingDuration))
zoneOff(z);
}

void setup() {
// sanity check delay - allows reprogramming if accidently blowing power w/leds
delay(2000);

// declare button pins
for (uint8_t z = 0; z < zoneCount; z++) pinMode(zones[z].buttonPin, INPUT_PULLUP);

// Define led arrangement, see FastLED examples for strip definition
FastLED.addLeds<APA102, dataPin, clockPin, RGB>(leds, ledCount);  // BGR ordering is typical
}

void loop() {
checkButtons();
checkTimeout();
}
``````

it's pretty short, less than 100 lines of code with some comments.

• the led count: `const uint8_t ledCount = 66;`
• the number of LEDs for the largest zone `const uint8_t maxLedPerZone = 10;`
• the definition of the mapping between buttons and which LEDs are controlled
``````t_zone zones[] = {
/* leds position in strip            count    period  button    keep as is */
{{0, 1, 2, 3, 4, 5, 6}              , 7     , 20000,    7,      false, 0},
{{2, 3, 4, 7, 8, 9, 10}             , 7     , 20000,    6,      false, 0},
{{4, 5, 6, 10, 11, 12, 13, 60, 61}  , 9     , 20000,    5,      false, 0},
};
``````

here I only defined 3 zones (and not using all the LEDs, just an example).

The first zone will impact leds at position 0, 1, 2, 3, 4, 5 and 6 which is the first array, then I say I've 7 active leds in the array, that this zone will stay on for 20s (20.000 ms) and is driven by a momentary push button on pin 7. (false and 0 and the end are for use at run time, just keep them there).

Last but not least, you need to define the right LED strip. have a look at the examples depending on which type of LED you bought.
Here I'm declaring an `APA102` type.
` FastLED.addLeds<APA102, dataPin, clockPin, RGB>(leds, ledCount);`

`dataPin, clockPin` are defined at the beginning of the code, `clockPin` is not needed if you use Neopixels.

Wiring the momentary push buttons is straightforward: Pin --- Button -- GND

daisy chain the LEDs in the order that makes physical sense (keep line short) don't worry about having the LEDs in a given zone next to each other as you define their position in the array (and some might be in multiple zones).

power the led strip from both ends with a good 5V DC power supply (Meanwell is a good brand). It needs to be able to generate 60mA x ledCount (so a 4 Amps x 5 V power supply would be necessary for your 66 LEDs -> take a bit of margin for example a MeanWell RS-25-5 25W 5V 5A would do).

1 Like

We went through this project a couple of years ago, so the answers will be much the same!

The 57 lesser LEDs could be driven by a MAX7219 chip with only its one current-setting resistor required. A Mega 2560 is entirely inappropriate - a Nano would be better.

What are the relays for?

Why do you need the brighter LEDs - what do they do?

You'll need to provide the type of LED and it's arrangement, i.e. how many in each string , for any answers to be meaningful.
For example 66 LEDs @ 3v minimum requires over 200v minimum to start with.

Drawing a circuit diagram and marking which is which component will help.

Iām not sure I get this? What type of LEDs and wiring you have in mind?

You would be well servied to read up on LED series wired and parallel wired.

You may need to light some LEDs individually.
You may have some that are always in strings.

The final product may be a combination of both styles.

The need for a sketch to help define the wiring and patterns will hep both now on design and later for trouble shooting.

who is 'you' ?

"You" would be the OP.

The OP will answer many of the questions by separating the individual LEDs from the groups.

Example a campground/park
Beach archery volleyball showers laundry are all single point LEDs
Path to lake to overlook to canoe or anything that might have multiple LEDs that act as one.

Series LEDs use a higher voltage and lower current per unit/group.
Individual LEDs use lower voltage

Lower information
increases speculation

1 Like

I think another Haiku should be built on this.

a7

1 Like

In the below document, you'll see a list of all of the Natural Areas (Lights), and to the right the categories (buttons) and what areas fall under those categories. If I'm understanding your question correctly.. the largest area string has 23 LEDs.

Natural Areas List 20210413 NatAreaList.pdf (87.3 KB)
Schematic 20210503_Schematic_NatAreasCircuitR1.pdf (357.1 KB)