CONNECTING WITH BUTTON

In this example we are going to connect the Raspberry Pi with a button, and then make Xojo program which will do 
asynchronous listening for events on the button.

At end of the guide then we will test the same with some other boards:

DISCLAIMER

We do not take any responsibility for possible errors in the guide or errors that you might do wiring it up. Incorrect wiring can result in damaged sensor or damaged Raspberry Pi.

Pieces we use:

Raspberry Pi 2, 3, 4 or 5.
Cobbler and Cobbler cable.
Bread board.
1 K-ohm resistor.
A button.
Gpiod Plugin for Xojo to use libpgiod in Xojo. The plugin you can get download here.  Or if you are interested in its source code then you can go here.

If you are not familiar with working with a breadboard or on how to place a cobbler on the breadboard then click here bellow

Breadboard

If you don’t know resistor color coding's to find correct resistors then you can click the link bellow

Resistor color coding

First thing is understanding the wiring of the button:

My button looked like this:

The button had 4 pins, 2 and 2 are same. At first I was not sure how its internal wiring was, as in which two poles were the same and which were the opposite. So I used digital multimeter to get to know its internal wiring.

Do not worry if you don’t know which pins are what on your button, if you get it wrong then worst thing that can happen is the reading of your application will just be always pressed down.

You will want to protect the GPIO pin from mistakes, like if you were to program it as output instead of input then without protection you likely would damage the Raspberry PI. So we use 1KΩ resistor to protect the pin.

1 KΩ resistor in 4 stripe system =  Brown – Black – Red (Read towards the golden stripe)

If you have 5 or 6 stipe system on your resistors then you can 5 and 6 stripe resistors to get help on reading their values if you do not know how.

Now once the resistor is in place then if doing programming error it should not damage the pin.

On the breadboard it looked like this:



Raspberry Pi pin layout

If you need more information about the GPIO headers on Raspberry Pi or other boards then click bellow.

Raspberry Pi Pin guideOrange Pi One Pin guideOrange Pi Pin guide for most H3 modelsOrange Pi Zero 3 Pin  guideOrange Pi 5 Plus Pin guideRock 64 Pin guide

So basically red is connected to 3,3 V on the Cobbler, and the other end to the button.
From the output of the button we connect the 1 KΩ resistor, and from the other end of the button we connect Green which goes from the resistor to the GPIO 6 (which is pin 31) which we choose to use for this example.

The Xojo code to to asynchronous monitoring of the button:

An input gpio will float between 0 and 1 if it’s not connected to a voltage. So we will need to take care of that by giving it determined state. We do that by using the Gpiod.LineBias.PULL_DOWN down in the code bellow.

// We add Opening event to a window:
Sub Opening() Handles Opening
  try
    using Gpiod
    
    var chip as Chip = Chip.Open("/dev/gpiochip0")
    
    var lineRequest as LineRequest = RequestInputLine(chip, 6, "watch-line-value")
    
    lineRequest.RequestReadEdgeEventsAsync(10, true, AddressOf LineMonitorCallback)
    
  catch e as GpiodException
    MessageBox(e.Message)
  end try
End Sub

// Helper function to set up the line request
Public Function RequestInputLine(chipHandle as Gpiod.Chip, lineOffset as UInt32, consumer as String) As Gpiod.LineRequest
  using Gpiod
  
  // Exceptions will be caught by the caller method
  
  var reqCfg as RequestConfig = nil
  
  var setting as new LineSetting()
  setting.Direction = Gpiod.Direction.INPUT
  setting.EdgeDetection = Gpiod.LineEdge.BOTH
  setting.Bias = Gpiod.LineBias.PULL_DOWN
  setting.DebouncePeriod = 10000
  
  var lineCfg as new LineConfig()
  lineCfg.AddLineSetting(array(lineOffset),setting)
  
  if consumer <> "" then
    reqCfg = new RequestConfig()
    reqCfg.Consumer = consumer
  end if
  
  return chipHandle.RequestLines(reqCfg, lineCfg)
End Function
// Callback method to get the button events
Public Sub LineMonitorCallback(edgeEvent as Gpiod.EdgeEvent)
  lstEvents.AddRow(if(edgeEvent.EventType = Gpiod.EdgeEventType.RISING_EDGE, "Rising", "Falling"))
  lstEvents.CellTextAt(lstEvents.LastRowIndex, 1) = edgeEvent.LineOffset.ToString()
  lstEvents.CellTextAt(lstEvents.LastRowIndex, 2) = edgeEvent.LineSequenceNumber.ToString
  lstEvents.CellTextAt(lstEvents.LastRowIndex, 3) = edgeEvent.TimestampNs.ToString()
End Sub

Under the hood the plugin set up native Thread for us to monitor the line, making sure we do not miss events.

Getting the full code

You can find this example code at Example code for GPIO guides.


Doing the same on Orange Pi One

I proceeded to do same on old Orange Pi one board which was running Armbian.

Everything works the same except the GPIO pinout is different.  And for the Application to get access to GPIO I had to run the application as sudo. (This is because of different default security setup between Armbian and Raspbian).

So basically what needed to be done was to wire it correctly up on Orange Pi One, making sure we connect to PA6 for GPIO 6, then I used same Xojo code as I used for the Raspberry Pi without any modifications.

Same example also has been tested with old Orange Pi 2 (see pin guide for Orange Pi H3 models). Note also the Pin formula in the guide there, like if you choose pin PG9 then it will be pin number 201. (The example will work in same way for all of the models listed in the H3 model pin guide).


Things got a bit more tricky when testing on Rock64
Rock 64 has multiple chips, so very different GPIO number system. 
Additionally I had a problem where the built in pull down resistor does not work on the Rock64 board on the pin I had chosen.

First, see the pin guide for Rock64 to learn how to calculate the GPIO pin number and know which chip to connect to.

I did chose GPIO3_A4 which is physical pin 15. 

GPIO3_A4 translates to Chip number 3 which we need to connect to and pin number 4.  Where A gives zero for group number making pin number on chip 3 be: (0 x 8) + 4 = 4.

// We had to change the Xojo code to account for different chip and different Pin number.
Sub Opening() Handles Opening
  try
    using Gpiod
    
    var chip as Chip = Chip.Open("/dev/gpiochip3")
    
    var lineRequest as LineRequest = RequestInputLine(chip, 4, "watch-line-value")
    
    lineRequest.RequestReadEdgeEventsAsync(10, true, AddressOf LineMonitorCallback)
    
  catch e as GpiodException
    MessageBox(e.Message)
  end try
End Sub

To deal with the 2nd problem where the boards on board pull down resistor for the chosen pin would not work then we added 2KΩ betwen ground and our pin, making the change of the circuit end like this:


Orange Pi 5 Plus is no problem.
On Orange Pi 5 Plus then we just had to pay attention to the very different GPIO number system. 

First, see the Orange Pi 5 Pin guide to learn how to calculate the GPIO pin number and know which chip to connect to.

I did chose GPIO3_A5 which is physical pin 36. 

GPIO3_A5 translates to Chip number 3 which we need to connect to and pin number 5.  Where A gives zero for group number making pin number on chip 3 be: (0 x 8) + 5 = 5.
Internal pull down resistor worked on the Orange Pi 5 so no change to the circuit was needed.


Orange Pi Zero 3 is also no problem.
On Orange Pi Zero 3 then we just had to pay attention to the very different GPIO number system for the H618 CPU.

First, see the Orange Pi Zero 3 Pin guide to learn how to calculate the GPIO pin number and know which chip to connect to.

I did chose PC9 which is physical pin 7. 

PC9 translates to GPIOD pin ID 73.