B4R Code Snippet Measure Analog Sensor on Digital Pin


Active Member
Licensed User
Explanation is in the code. "Resistive Sensors" examples include Photocells (light sensor), Flex sensors, Thermistors (temperature reading).

' This example can be used to read a resistive sensor (a sensor that acts like a resistor) on a digital pin by using a capacitor.

' The basic concept is this:  The capacitor fills but, because there is a resistor (for those sensors that acts like one),
'    it fills rather slowly depending on the resistance of that sensor.  We count how long that takes.  The more resistance,
'    the slower (more cycles) the capacitor fills until it reads "HIGH".  NOTE: You are NOT measuring voltage here. You are measuring
'    how long it takes to half-fill a capacitor.  You'd need to either an analog pin or use an AnalogDigitalConverter (ADC) to do that.

' The (V) line connects to one of the sensor legs.
' One leg of the ceramic (C)apacitor (.001 to 1 microF depending on your reading range) goes to the other leg of the sensor.
' The (G)rnd line connects to the free leg of the capacitor.
' The (D)igital line connects to the combined legs of the sensor and capacitor and goes to your microcontroller.
' V
' SS
'  CC
'   G
'  D
' See: https://learn.adafruit.com/assets/467 for a Fritzing of the circuit

' Good things:  Wide range of values depending on your choice of capacitor and any other resistors, etc. you put in-line.
' Bad things:  Charging a capacitor isn't linear.  It'll often start off charging very quickly and then slow as it gets 'full'.

#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Private ReadPin1 As Pin
    Private ReadGPIOPin1 As UInt = 0
    Private tmr1 As Timer
    Private CyclesMax As UInt = 1000
End Sub

Private Sub AppStart
    ReadPin1.Initialize(ReadGPIOPin1, ReadPin1.MODE_OUTPUT)
    tmr1.Initialize("tmr1_Tick", 1000)                            ' Read values every 1 seconds
    tmr1.Enabled = True
End Sub

Sub tmr1_Tick
    tmr1.Enabled = False
    Private CyclesToRecharge As UInt
    CyclesToRecharge = RCTime(ReadPin1)
    If CyclesToRecharge = CyclesMax Then
        Log("Check your Connection. Too much Resistance")
    End If
    tmr1.Enabled = True
End Sub

Sub RCTime (RCPin As Pin) As UInt
    ' The code below, drains the capacitor and then counts how long it takes (not "Time" but cycles) for the capacitor
    '    to fill half way up (ie it reads "HIGH").
    Private Cycles As UInt = 0                ' Init the counter
    RCPin.Mode = RCPin.MODE_OUTPUT            ' Set pin to Output/Write
    RCPin.DigitalWrite(False)                ' Set pin to "LOW" (because GRND is connected to the capacitor end)
    Delay(1)                                ' Waiting for the capacitor to discharge

    RCPin.Mode = RCPin.MODE_INPUT            ' Set pin to Input/Read
    Do While RCPin.DigitalRead = False        ' Keep reading the pin until it reads "HIGH" (ie not False) which should be 1/2 of the input voltage
        Cycles = Cycles + 1
        If Cycles = CyclesMax Then
            ' Something is wrong. Resistance is too high. Probably a bad connection
            Return CyclesMax
        End If
    Return Cycles
End Sub