B4J Question Raspberry Pi: Resistor Sensor Reading

AHilton

Active Member
Licensed User
Longtime User
I'm trying to test the idea of reading sensor information based on resistors at https://learn.adafruit.com/basic-resistor-sensor-reading-on-raspberry-pi?view=all for use in B4J. That Python code works well on my circuit but I'm having problems with B4J.

How do you either have both an Output and Input type on the same Pin (you really can't do that) OR Switch rapidly between the two types?

Comment inline the code below giving the error. I've tried releasing the PinXo before initializing the PinXi and vice-versa but that doesn't work. Neither does controller.shutdown and re-initializing.

Any ideas?


B4X:
'Non-UI application (console application)
#Region  Project Attributes
   #CommandLineArgs:
   #MergeLibraries: true
#End Region

Sub Process_Globals
    Dim controller As GpioController
    Dim PinXo As GpioPinDigitalOutput
    Dim PinXi As GpioPinDigitalInput
    Dim Reading As Int
    Dim Timer1 As Timer
End Sub

Sub AppStart (Args() As String)
    Reading = 0
    controller.Initialize
    PinXo.Initialize(27, False)            ' Init the Output Pin and set the pin LOW (False)
' The following line give the error ...
    ' com.pi4j.io.gpio.exception.GpioPinExistsException: This GPIO pin already exists: GPIO 27
    PinXi.Initialize("PinXi", 27)        ' Init the Input Pin
    Timer1.Initialize("Timer1",10)        ' Check the value every 10 milliseconds

   StartMessageLoop
End Sub

Sub PinXi_StateChange(State As Boolean)
    If State = True Then
        Timer1.Enabled = False
        Log("Reading: " & Reading)
           Reading = 0
        PinXo.Blink(1)                ' Set the pin LOW for 1 millisecond to reset the capacitor in order to start again
        Timer1.Enabled = True
    End If
    Log("PinX StateChange event: " & State)
End Sub

Sub Timer1_Tick
    Reading = Reading + 1
End Sub
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Please try the attached library.
It adds two new methods that allow you to change the pin mode.

You need to first initialize the pin as an input pin.
Later you can change the mode with:
B4X:
Dim out As GpioPinDigitalOutput = pin.ChangeToOutput
'later
pin = out.ChangeToInput
 

Attachments

  • jPi4J.zip
    12.6 KB · Views: 367
Upvote 0

AHilton

Active Member
Licensed User
Longtime User
I'm getting a compile error ....

B4J version: 4.00
Parsing code. (0.00s)
Compiling code. (0.01s)
Compiling layouts code. (0.00s)
Compiling generated Java code. Error
B4J line: 18
Private PinXo As GpioPinDigitalOutput = PinXi.Cha
javac 1.8.0_51
src\b4j\example\main.java:74: error: cannot find symbol
_pinxo = _pinxi.ChangeToOutput();
^
symbol: method ChangeToOutput()
location: variable _pinxi of type GpioPinDigitalInputWrapper
1 error


with the code being ...

B4X:
'Non-UI application (console application)
#Region  Project Attributes
   #CommandLineArgs:
   #MergeLibraries: true
#End Region

Sub Process_Globals
    Dim controller As GpioController
    Dim PinXi As GpioPinDigitalInput
    Dim Reading As Int
    Dim Timer1 As Timer
End Sub

Sub AppStart (Args() As String)
    Reading = 0
    controller.Initialize
    PinXi.Initialize("PinXi", 27)        ' Init the Input Pin
    Private PinXo As GpioPinDigitalOutput = PinXi.ChangeToOutput
    PinXo.Initialize(27, False)        ' Set the Pin for Output and LOW in order to reset the capacitor
    PinXi = PinXo.ChangeToInput        ' Set the Pin for Input in order to read when its' State changes to HIGH
    Timer1.Initialize("Timer1",10)        ' Check the value every 10 milliseconds

   StartMessageLoop
End Sub

Sub PinXi_StateChange(State As Boolean)
    If State = True Then
        Timer1.Enabled = False
        Log("Reading: " & Reading)
           Reading = 0
        Private PinXo As GpioPinDigitalOutput = PinXi.ChangeToOutput
        PinXo.Initialize(27, False)        ' Set the Pin for Output and LOW in order to reset the capacitor
        PinXi = PinXo.ChangeToInput        ' Set the Pin for Input in order to read when its' State changes to HIGH
        Timer1.Enabled = True
    End If
    Log("PinXi StateChange event: " & State)
End Sub

Sub Timer1_Tick
    Reading = Reading + 1
End Sub
 
Upvote 0

AHilton

Active Member
Licensed User
Longtime User
I've changed the code around a little bit (a few times) and I'm never able to get the pin state to get 'high'/true. Here's the code ...

B4X:
'Non-UI application (console application)
#Region  Project Attributes
   #CommandLineArgs:
   #MergeLibraries: true
#End Region

Sub Process_Globals
    Dim controller As GpioController
    Dim PinXi As GpioPinDigitalInput
    Dim PinXo As GpioPinDigitalOutput
    Dim Reading As Int
    Dim Timer1 As Timer
End Sub

Sub AppStart (Args() As String)
    Reading = 0
    Timer1.Initialize("Timer1", 1)
    controller.Initialize
    PinXi.Initialize("PinXi", 27)        ' Init the Input Pin
    PinXo = PinXi.ChangeToOutput
    PinXo.State = False                    ' Set the Pin to LOW in order to initially discharge the capacitor
    Timer1.Enabled = True                ' The timer provides a small delay for the capacitor to discharge
   
   StartMessageLoop
End Sub

Sub Timer1_Tick
    Timer1.Enabled = False
    Log("Here we go ...")
    PinXi = PinXo.ChangeToInput        ' Set the Pin for Input in order to read when its' State changes to HIGH
    Log("PinXi State: " & PinXi.State)
    Do While PinXi.State = False
        Log("Reading: " & Reading)
        Reading = Reading + 1
    Loop

    ' THE CODE IS NEVER GETTING HERE. PinXi.State IS NEVER GETTING 'HIGH' / TRUE

    ' PinXi State should be True (HIGH) meaning the capacitor is 'full'
    Log("PinXi State2: " & PinXi.State)
    Log("Reading2: " & Reading)
    Reading = 0
    PinXo = PinXi.ChangeToOutput
    PinXo.State = False                    ' Set the Pin to LOW in order to initially discharge the capacitor
    Timer1.Enabled = True                ' The timer provides a small delay for the capacitor to discharge
End Sub

Sub PinXi_StateChange(State As Boolean)
    Log("PinXi state changed to: " & State)
End Sub
 
Upvote 0

AHilton

Active Member
Licensed User
Longtime User
That helped. The StateChange event is firing but never gives a State = True / Pin HIGH.
Here's the code now ...

B4X:
'Non-UI application (console application)
#Region  Project Attributes
   #CommandLineArgs:
   #MergeLibraries: true
#End Region

Sub Process_Globals
    Dim controller As GpioController
    Dim PinXi As GpioPinDigitalInput
    Dim PinXo As GpioPinDigitalOutput
    Dim Timer1 As Timer
    Dim StartTime As Long
    Dim EndTime As Long
End Sub

Sub AppStart (Args() As String)
    Timer1.Initialize("Timer1", 1)
    controller.Initialize
    PinXi.Initialize("PinXi", 27)        ' Init the Input Pin
    PinXo = PinXi.ChangeToOutput
    PinXo.State = False                    ' Set the Pin to LOW in order to initially discharge the capacitor
    Private x As Int = 0
    Do While x < 10000
        ' Don't do anything here. Need to provide a pause for the capacitor to 'settle'
after discharging

        x = x + 1
    Loop
    PinXi = PinXo.ChangeToInput
    StartTime = DateTime.Now
   
   StartMessageLoop
End Sub

Sub PinXi_StateChange(State As Boolean)
'    If State = True Then
        Log("PinXi state changed to: " & State)
        EndTime = DateTime.Now
        Dim TicksDiff As Long = EndTime - StartTime
        Log("Time Difference:" & TicksDiff)
       
        PinXo = PinXi.ChangeToOutput            ' Set the pin to OUTPUT so we can discharge the capactor
        PinXo.State = False                        ' Discharge the capacitor
        Private x As Int = 0
        Do While x < 10000
            ' Don't do anything here. Need to provide a pause for the capacitor to 'settle'
after discharging

            x = x + 1
        Loop
        PinXi = PinXo.ChangeToInput                ' Set the pin to INPUT so we can read it
        StartTime = DateTime.Now
'    End If
End Sub
 
Upvote 0

AHilton

Active Member
Licensed User
Longtime User
Thanks, Erel. The B4J / Python combo works pretty well and it's good to know that that sort of interaction between the two exists. Shame that B4J can't take care of it itself, though. I'm going to add an ADC to the circuit and test SPI with these analog sensors now.
 
Upvote 0
Top