Turn Signals - Multiple switch inputs solved!

I’ve just completed a usermod that provides for binary encoded input and thought that I’d share the idea here. If it’s good enough, I’ll submit it to Github as a regular usermod.

Use case: This project adds fancy turn signals to my ATV. It’s a Can-Am side-by-side that seats 6 and has a regular 12V automotive system (sans alternator).

There are 4 light positions on the vehicle: Front Left, Front Center, Front Right, and Rear Strip. The front right and left positions blink during turns and run steady driving lights otherwise. The front center strip is for decoration (behind the grille, like Knight Rider), and in the rear is a 1 Meter strip of 60 WS2815 pixels mounted in an aluminum channel with a clear cover. The strip is mounted horizontally in the back.

I wired up a 4-channel optocoupler (12v → 3.3v) to take 12v input signals from the vehicle. At first, I tried using the Button settings that are built into the latest Wled and which provide for 4 independent buttons. I had an immediate problem: Sometimes, inputs come into different channels simultaneously. Sure, the stock button interface does a good job of firing off a macro when a button state changes, but there is no way to detect and trigger on two buttons being active at the same time. Think of making a left turn. First, suppose the driver turns the left signal on and then, he hits the brakes. Both are inputs to the process, but neither is exclusive. Just because the brakes are pressed, it doesn’t mean that the blinker stops.

The problem here is that when you load one preset (for example blink left), it is canceled when you load another preset (for example brake light). So, I needed more macros. By the time I was done, I need to trigger one of 7 different macros depending on the state of the vehicle. These include Drive (idle, no inputs), Hazard (4-way flashers), Brake, Left Signal, Left Signal with Brake, Right signal, and Right Signal with Brake. This wasn’t going to work with the stock 4 input buttons.

So, I decided to write a usermod. The overall strategy is very simple, and not nearly as elegant as the code others have written, but it works. First, I picked 4 input pins and I wired the 4 optocouplers to it, and attached these to the vehicle inputs. Then, in the usermod, I set up the pins for input. At runtime, the usermod loop is called which reads all four pins and then combines the result into a 4-bit value. This value, normalized to 1-16, is then used to select a preset.

So, whenever you press the brake, work the turn signals, or just drive, the state condition evaluates to a particular macro and changes the output accordingly.

Here’s a look at the code:

void loop() {
pin_state = digitalRead(PIN_BRAKE);
pin_state = pin_state << 1;
pin_state |= digitalRead(PIN_LEFT);
pin_state = pin_state << 1;
pin_state |= digitalRead(PIN_RIGHT);
pin_state = pin_state << 1;
pin_state |= digitalRead(PIN_HAZARD);
pin_state++; // presets are 1-based

  if (pin_state != last_preset) {
    last_preset = pin_state;
    applyPreset(pin_state & 15);
  }

}

So, with this setup, any of 16 macros can be triggered depending on the combined state of 4 pins.

In parting, some may note that no attempt was made to de-bounce the input signals. In the wled code, buttons must be held for at least 50ms to avoid false triggering. This didn’t seem necessary for this application.

Overall, the setup works well with a minimum of fuss.

6 Likes

Well done! Definitely post pull request on WLED GitHub and best if you could add some simple explanation how your usermod is working, for users who don’t really know how to write a line of code.

2 Likes

Clever. Thanks for sharing. I should WLED up my motorcycle.

Makes me think the buttons could be replaced with accelerometer or similar widget for an automatic brake light (no button required), and maybe a button overlay so a single button presses the WLED signal and physically activates the motorcycle’s turn signal button (times 2). That would be useful so you get invisible “WLED” integration - from the driver’s perspective.

I think it is a really nice concept too.

Well aa7bq tapped in to the turn signal and brake lines to determine state. No need for accelerometer or bottoms unless you were doing this for something that had no existing indicators.

This in fact can be achieved by carefully crafted presets. No need to change the code. :wink:

1 Like

[blazoncek] Can you explain how?

Do not use “Save state” but enter JSON API commands directly.
You need to modify the segment in question only into that particular preset.

E.g.:
{"seg":[{"id":0,...}]}will only affect Segment 0 and set whatever you want it to set in segment API.
You can then map Segment 0 to i.e. front left light, Segment 1 to front center light, etc.

This only solves half of the problem I believe.
For instance, if you want 2 turn signals to equal brake, this does not solve the problem.
Example,
button 1= left turn
button 2= right turn
button 1 + 2= brake

because it uses the same segment (rear light on SxS)?

Then you have to do it yourself in your usermod.
This is the case where one button serves 2 (or more functions). You cannot develop universal solution that will solve such problem.

1+2=3, +1=4, so preset 4 would be brake. :smiley:

How do you handle double- and long- presses in such cases?

My take: You don’t for this.

I actually have them set as a switch.
Can current firmware handle switch 1 and switch 2 depressed simultaneously equals new effect?

No. That’s what the user mod is for.

Agreed. What does this comment mean?

Reference to first post that describes what it does. :wink:

I checked the button handling code and if you are clever you can write a usermod that will override default button behaviour allowing you to do whatever you choose with any number of button presses.

It may require an out-of-the-box thinking as each button is handled separately.

Hi. I am currently trying to implement the same. but my knowledge is not so great. do you have this project on github
Thank you

I’m new to all this, I’m trying to figure out which file needs to be edited and what the code should be. I’m basically doing the same thing, wiring turn signals and brake light. I can get the them to work individually but I can’t get the brake and turn signals to work together. Thanks for the help in advance!