B4R Question Using A0 as a button input on ESP-12E

Kevin

Well-Known Member
Licensed User
Longtime User
I need to add a push button to my project and decided that using the analog pin was the way to go so I don't tie up another digital pin in case I need one for something else.

I followed the example here but I can't get an event to fire.

I have a timer that displays temperature readings every 5 seconds and I added a line to show the input value of A0:
  • When wired exactly as shown in the example (Grnd to switch, switch to A0), no event fires, and A0 reads around 8 whether the button is pressed or not.
  • When wired 3v3 to switch, switch to A0, no event fires but A0 does read 1024 when the button is pressed (8 when not pressed).

Why doesn't the button press event fire? When connected as shown in the example, why does it read 8 either way? I'm certain that Erel's tutorial works on that particular board, so do I need to do something different with the ESP-12E?

I am considering adding a Looper to monitor the value of A0 but isn't that the point of adding a listener? Could doing that affect performance of the program overall? :confused:

B4X:
' Only showing the relevant parts here...
Private Sub AppStart
    btnHeatToggle.Initialize(btnHeatToggle.A0, btnHeatToggle.MODE_INPUT_PULLUP) 'Using the internal pull up resistor to prevent the pin from floating.
    btnHeatToggle.AddListener("btnHeatToggle_StateChanged")
End Sub

Sub btnHeatToggle_StateChanged (State As Boolean) ' <------- This event never fires
    Delay(20) 'wait for 20 milliseconds - should help to minimize switch bounce
    Log("Button state: ", State)
    If State = False Then    'False means button pressed.
        HeatPumpRun = Not(HeatPumpRun)
        hpRelay.DigitalWrite(HeatPumpRun)
        UpdateDisplay
        If Logging Then
            Dim sText As String
            sText = JoinStrings(Array As String("HeatPumpRun = ", HeatPumpRun))
            WriteLog(sText, True)
        End If
    End If
End Sub
 

Kevin

Well-Known Member
Licensed User
Longtime User
I haven't tried it on any other pins but I may have time tonight. If not then definitely in a couple days.

I had thought about trying a digital pin but it seemed to me that A0 should have been working and that was the one I would prefer to use for the switch. I figured I must just be missing something, hence the post.

I'll reply back once I get a chance to experiment with other pins.
 
Upvote 0

Kevin

Well-Known Member
Licensed User
Longtime User
I tried it on D1 and it worked as expected. I'm not sure why it isn't working on A0.
 
Upvote 0

BillMeyer

Well-Known Member
Licensed User
Longtime User
In my opinion (and anyone who feels so may correct me without fear of retribution :cool:)

The difference is between Analogue and Digital.

Analogue (A0 in your Case) is a voltage that is measured and will never be 100% accurate because there are various things that cause different readings for example, a relay that is on, a percentage variance on a resistor that causes different voltage drops etc, whilst a Digital input is 1 or 0 - On or Off essentially, so a button on a Digital Input would react like you would expect - On or Off whilst on the Analogue input it would be a voltage that it is reading, so in your case, 1028 (1023 ?)* would be sightly more than the 3.3 volts you are giving it (so 8 would be so negligible as to not make a difference and could be some type of noise on the circuit or the floating voltage present on ATMega Analogue pins)

So, to illustrate the point, you could have 5 buttons on an Analogue pin (by using a voltage divider), that with some If statements in your program you could sense each one and react to it - whereas on a Digital input you could only have one BECAUSE it is On (1) or Off (0) essentially.

I trust that this will somewhat explain.

Enjoy !!

* An Arduino has a 10-bit analog to digital converter. This means that it will map input voltages between 0 and 5 volts into integer values between 0 and 1023. This yields a resolution between readings of: 5 volts / 1024 units or, .0049 volts (4.9 mV) per unit, similarly 3.3v/1024 = 0.0032 or 3.2mV
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
In my opinion (and anyone who feels so may correct me without fear of retribution :cool:)
No fear at all!

The difference is between Analogue and Digital.

Analogue (A0 in your Case) is a voltage that is measured and will never be 100% accurate because there are various things that cause different readings for example, a relay that is on, a percentage variance on a resistor that causes different voltage drops etc, whilst a Digital input is 1 or 0 - On or Off essentially, so a button on a Digital Input would react like you would expect - On or Off whilst on the Analogue input it would be a voltage that it is reading, so in your case, 1028 (1023 ?)* would be sightly more than the 3.3 volts you are giving it (so 8 would be so negligible as to not make a difference and could be some type of noise on the circuit or the floating voltage present on ATMega Analogue pins)

So, to illustrate the point, you could have 5 buttons on an Analogue pin (by using a voltage divider), that with some If statements in your program you could sense each one and react to it - whereas on a Digital input you could only have one BECAUSE it is On (1) or Off (0) essentially.

I trust that this will somewhat explain.

Enjoy !!

* An Arduino has a 10-bit analog to digital converter. This means that it will map input voltages between 0 and 5 volts into integer values between 0 and 1023. This yields a resolution between readings of: 5 volts / 1024 units or, .0049 volts (4.9 mV) per unit, similarly 3.3v/1024 = 0.0032 or 3.2mV

Now is my the to say... feel free to correct me, but expect retaliation...

In the Arduino world there are 2 types of Analog pins:
* with pull-down resistor: the first will make the pin read 0v if no voltage is appied to it. This eliminates those pesky residual voltages.
* with pull-up resistor: about the same as the above but instead of 0v it will normally read Vcc.
* no resistor, also known as floating pin is prone to have residual voltage if no complementary circuitry is implemented. These are also used, along with an internal reference voltage, as ADC (analog to digital converter) this your 1024 value. If you multiply it by the vref, you should get approximately vcc.
 
Upvote 0

BillMeyer

Well-Known Member
Licensed User
Longtime User
@Cableguy

Taking a closer look at the board, ESP-12E, it seems that you have hit it on the head with your 3rd description - Floating Pin - only seems like one Analogue Pin which is A0 and on the schematics I can find there seems to be no resistor or description of one - thus the tiny residual voltage.

Well Done Boet (South African for Brother !!)
 
Upvote 0

Kevin

Well-Known Member
Licensed User
Longtime User
While I used the pullup option, it certainly is possible that there is no built-in pullup resistor so I could see this as a problem when connecting the switch to ground. This clearly wouldn't work based on what I saw when reading the value of A0 as listed in my first post. I don't know exactly what the built-in function looks for, but it seems to me that it could (should?) work when connecting the switch to 3v3, even if it might read the state as opposite, which can easily be dealt with in the event code. For now, I've got it working on a digital pin, and I may want to connect a photoelectric sensor to A0 anyway, but perhaps it's something to try addressing in a B4R update?

  • When wired 3v3 to switch, switch to A0, no event fires but A0 does read 1024 when the button is pressed (8 when not pressed)./QUOTE]
 
Upvote 0

positrom2

Active Member
Licensed User
Longtime User
B4R listener reads the pin state and raises the event when it changes.
With an analog pin, what could a pin state be?
A pin state might be meaningless for an analog pin - due to fluctuations of the value events could be raised quite frequently unless there were a provision to define a threshold or a window like in some devices (I just remember this for ATXMegas).
 
Upvote 0

Kevin

Well-Known Member
Licensed User
Longtime User
If it isn't possible to check for a state change in the usual sense, I wonder if you could run a looper or timer and test for 1024 or anything under, say, 500, and just use that change to call your own state change sub.

Or perhaps just adding a pullup resistor to the wiring side of things would allow the normal state change event to fire?

At this point, I'm pretty confident that I can complete my project without the need for using A0 with a button. However, I think that coming up with a workaround and closure in this thread could potentially help someone else down the road.
 
Upvote 0
Top