How to detect button presses on a device, and how to press them?

Hi all,

I'm a software engineer who has some experience in fixing vintage equipment, but I've never actually designed a circuit. I would love to, so I'm starting relatively simple.

For this little project, I want to integrate an Arduino Pro Mini into an LCD monitor without any external modifications, where possible. The monitor has several buttons on the outside to enter an OSD menu and change settings.

I want to write a little program that will make the arduino press these buttons to change monitor settings through its OSD menu. The sequence of which buttons to press and when is known and is always the same. I just need to trigger the arduino to execute the sequence.

On to the implementation then. There are only 3 buttons that the arduino needs to press. I want to trigger the arduino by pressing 2 of these buttons simultaneously. This does nothing on the monitor, so I wouldn't need to add an extra (external) button to trigger my little progam. For this to work, not only do I need to simulate a button press, but also detect them.

I know how to figure out the software part of this. But the circuitry, not so much! Let me start by showing you the circuitry of the button PCB inside the monitor. At least that part was easy:

So 2 switches per 'data pin' in series, resistance between the pin and GND determines which button(s) are pressed. 0 ohm -> both, 5 kOhm -> 1, 10 kOhm, the other, 15 kOhm -> none.

My question is basically; what would a circuit look like to do this? I would imagine reading the button presses would involve converting the resistance between the connector pin and GND and converting it to 2 bits that I can then read on the arduino.

As for pressing..I have no idea. Can I wire this into the circuitry somehow, or do I have to use relays and push the buttons with those? Reading ditto..do I just hook up the reading circuit in parallel to the GND and connector pin? The idea is to power the arduino itself using a voltage rail on that button PCB (I think there's a +5V there to power some leds). With the low power it draws I assume that would be ok, but please do tell if it's a horrible idea.

Relays would be the simplest way to do it. Otherwise you are looking at opto coupled FETs.

To read the state of the switches then you need to connect the side opposite the ground to an analogue input and enable the internal pull up resistor.
This assumes that the device outputs no more than 5V on the pins 5&6.

Thanks. Can I also write the button presses out again? In that case I'm just going to intercept the buttons and wire them into the arduino, and proxy any pressed on the output pins back into the circuit.

If you are going to do that then just wire the switches up conventionally.

Right, so I have hooked up the buttons directly to the arduino analog input A0, set it to INPUT_PULLUP, and I can read the buttons. I don't know how to send the button presses to the monitor though. I need to be able to generate my own button events, as well as pass through the button presses that I read on A0.

I attempted to send the button values to a digital output with PWM modulation, and used a low-pass filter to smoothen the output. This, then I hooked up to the original signal pin of the monitor's connector, hoping it would then be able to 'see' the button presses. The monitor doesn't respond to anything though.

If I connect the output from the low-pass filter back into another analog input of the arduino (A2), I can read the values just fine though.

Any idea on how to approach this?

I don't know how to send the button presses to the monitor though.

Serial.println(value);

Thought..... What monitor are we talking about. That answer was from the serial monitor.

I attempted to send the button values ........

Did you have a common ground between the Arduino and the monitor (if "the monitor" is your other device).

Any idea on how to approach this?

Have you measured what voltages trigger actions on your device? If so what were they and did you reproduce them with the smoothed PWM?

For the test where I hooked up the output from the low-pass filter to A2 I printed the value to the serial monitor. A2 was configured as INPUT without pullup as there is always a close circuit (right?) The values looked okay, though they were a bit jumpy with a variation of about 10%. E.g. I read 380-420 when no buttons were pressed, where 400 is about the expected value (20% of the max of 1023, which shoul correspond to 2V (see below)).

I measured the butons in-circuit for the LCD monitor as it was originally without any modifications, and I measured a 2V voltage drop when no buttons were pressed. This is what I based the output after the low-pass filter on. Max is 2V (40% duty cycle of the 5V output pin). Pressing the buttons gives 1/3rd or 2/3rd of that value.

I created an RC low-pass filter according to an online calculator tool that showed a delta of about 0.2V at 2V output. This would explain he 'jumpiness' I suppose. Is 10% variance too much for something that reads button presses? I can use a bigger capacitor to reduce the ripple, but then it takes longer before it reaches a stable state. Using the online calculator below I created a low-pass filter with R=2kOhm and C=6.8uF (fPWM=495Hz). I replaced the cap with a 22uF one but the (LCD) monitor still wouldn't respond to any button presses.

I did indeed create a common ground between the arduino and the LCD monitor.

Calculator: (Sample)RC Low-pass Filter Design for PWM - Result -

Am I on the right track? Is it a question of fine-tuning the filter or the values I write to A2?

Am I on the right track?

Yes I think so.

Is it a question of fine-tuning the filter or the values I write to A2?

No.

Do you have the switches and resistors connected up when you try this?

Have you tried measuring the voltage on the device with a multimeter both with the resistors connected up and with voltages being sent from the PWM? It could be a matter of impedance meaning that the voltage you think you are delivering are actually being sent?

Why do you want to replicate the button signals, instead of passing them on as they are?

Grumpy_Mike:
Do you have the switches and resistors connected up when you try this?

Yes. So switches + resistors as in the schematics of post #1 between pin5 of CON801 and GND are connected to arduino on pin A0 + GND.

Have you tried measuring the voltage on the device with a multimeter both with the resistors connected up and with voltages being sent from the PWM? It could be a matter of impedance meaning that the voltage you think you are delivering are actually being sent?

So, that part is indeed not clear to me how that is supposed to work. That's where I am definitely lacking an understanding of how the circuit works. So here's my thought on that:

I guess that pin 5 and pin 6 on CON801 in the schematics are also connected to some microprocessor inside the lcd monitor. I cannot verify this as it's really hard to get to the mainboard in this screen. So I figured, if that is the case, it should be pretty much the same as if I were to connect my output (after the RC filter) back into an analog pin (A2). When I did that I did indeed get input that corresponds to 2V (400-ish, with the 10% variation). I didn't configure it as INPUT_PULLUP as now it is always connected.

I'm not sure what you mean by "could be a matter of impedance meaning that the voltage you think you are delivering are actually being sent". I didn't have time to measure today but I will do this when I get back to it. I do wonder though, if the 10% variation might be a killer. When I read the buttons from the button pcb the values are consistent and don't vary by much at all. Perhaps the lcd monitor's microprocessor is very strict. My implementation though was pretty simple.. values > 270? No buttons pressed. > 210? Button 1 pressed. > 150? Button 2 pressed. Else, both pressed. That would work even with the 10% variation but who knows how this is implemented by the lcd monitor.

DrDiettrich:
Why do you want to replicate the button signals, instead of passing them on as they are?

The end goal is to be able to write my own 'virtual' button presses to execute a sequence of events to 'program' the monitor's OSD menu. Additionally I want to be able to detect the physical button presses so I can trigger executing that sequence when 2 buttons are pressed simultanously. All this because the monitor stupidly does not remember any image setting changes after they have been made, meaning I have to go into the menu and make the same exact changes every time I turn it on. Very tedious, hence the desire to automate it.

Yes. So switches + resistors as in the schematics of post #1 between pin5 of CON801 and GND are connected to arduino on pin A0 + GND.

That is why it is not working.
First from that description there seems no connection between a PWM pin and your unit to do the pressing.

Can you draw a circuit of what you have including all the Arduino connections please. And then post the code you are using.

I got it working. I think you were right about the impedance. I guess the monitor's processor also supplies a voltage through a pullup resistor, and thus the voltages sent from my PWM output pin + low-pass filter were off. With the multimeter hooked up I was able to calibrate it so that it now does register the button presses, and now I can also generate my own fake button presses!

It's not super reliable yet though. I'll probably have to find the ranges that work and choose the averages. If that doesn't work, maybe a simple dac might be necessary? Anyway, the concept works and I learned a lot. Thanks!

I guess the monitor's processor also supplies a voltage through a pullup resistor, and thus the voltages sent from my PWM output pin + low-pass filter were off.

Yes that was it.

Glad you got it going. :slight_smile:

Fixed the reliability issues now as well! The low default PWM frequency was the culprit; the low-pass filter could not be tweaked such that button presses would reliably register. I bumped the frequency to the maximum value for ouput pin 9 and 10 and now it works flawlessly. Super cool. Thanks so much!

Excellent :slight_smile:

Great you got it working reliably, it must have been the ripple on the signal.

Indeed. Either too big of a ripple or timing issues with a longer delay. This was a very fun first project, learned a lot. Thanks so much for your help.