B4R Question Can pins be stored in global array ?

peacemaker

Expert
Licensed User
Longtime User
Hi, All

If to make some separate code module for working with pins:

B4X: Copy
Sub Process_Globals
Type ButtonState (pin As Pin, lastState As Boolean, currentState As Boolean, lastDebounceTime As ULong, pressStartTime As ULong, pressDuration As ULong, eventGenerated As Boolean, periodicCounter As UInt, pressEventTime As ULong, lastPeriodicTime As ULong)
Private buttons(5) As ButtonState

when i try to add the pin and next get it back:

B4X: Copy
Public Sub AddButton(gpio_num As Byte, pin_mode As Byte)
    Dim p As Pin
    p.Initialize(gpio_num, pin_mode)
    buttons(ButtonsIndex).pin = p
End sub


Private Sub ProcessButton(btn As ButtonState)
    Dim reading As Boolean = btn.pin.DigitalRead

pin is always empty, with zero GPIO, not saved.

Impossible to have pins in array ?
 
Is ButtonState your class module?
Can you share your current project?
 
Upvote 0
I am getting this when uploading to my NodeMCU Board

B4X: Copy
[IDE message - 11:51:20]
An error occurred.
Le fichier spécifié est introuvable
 
Upvote 0
I tried with a ESP2866 and it had similar error, but refered to a py (python) missing file....
 
Upvote 0
Also OK to run v0.13.

Button(13) event: press (0ms)
Button(13) event: short_click (180ms since press)
Button(12) event: press (0ms)
Button(12) event: short_click (200ms since press)
Button(12) event: press (0ms)
Button(12) event: short_click (460ms since press)
Button(12) event: press (0ms)
Button(12) event: long_click (920ms since press)
Button(13) event: press (0ms)
Button(13) event: long_click (880ms since press)

1751971174172.png
 
Upvote 0
today I won't have the time, but I will give it a try tomorrow..;

BTW, why don't you pass the number of buttons in the initalize method, instead of having to go to the class and explicitly set them in the array?
 
Upvote 0
don't you pass the number of buttons in the initalize method
Not clear. GPIO number is passed.
But the length of the array is anyway must be set by digit in B4R, no idea how dynamically declare and re-declare the arrays.
 
Upvote 0
you can declare the array as having only 1 element and then redeclare it in the iniatilize method with a variable int
Something like

B4X: Copy
Private buttons(1) As ButtonState

Public Sub Initialize(BtnQty as int)
    Dim buttons(BtnQty) As ButtonState
    ButtonsIndex = 0
    timer1.Initialize("CheckButtons_Tick", POLL_INTERVAL)
    timer1.Enabled = True
    Log("Buttons initialized")
End Sub
 
Upvote 0
I see.... moreover types can only be declared inside process Globals.... too bad!
 
Upvote 0
Maybe a new whish for @Erel to think about... a B4R update would be nice!
 
Upvote 0
But question is about the pin objects.
I don't think the issue is the pin object, but the type not keeping the same reference throughout the code
maybe replace the type declaration with an array of Map... that should work!
 
Upvote 0
It can be solved so:

B4X: Copy
Sub Process_Globals
.....
  
    Type ButtonState (index As Byte, lastState As Boolean, currentState As Boolean, lastDebounceTime As ULong, pressStartTime As ULong, pressDuration As ULong, eventGenerated As Boolean, periodicCounter As UInt, pressEventTime As ULong, lastPeriodicTime As ULong)
  
    Private buttons(2) As ButtonState   'setup exactly needed qty to avoid crash!
    Private pins(2) As Pin    'setup exactly needed qty to avoid crash!
End Sub

' Add new button
Public Sub AddButton(gpio_num As Byte, pin_mode As Byte)
    pins(ButtonsIndex).Initialize(gpio_num, pin_mode)
    buttons(ButtonsIndex).index = ButtonsIndex
    buttons(ButtonsIndex).lastState = True
....

' Process single button state
Private Sub ProcessButton(btn As ButtonState)
    Dim gpio_num As Byte = pins(btn.index).PinNumber
    Dim reading As Boolean = pins(btn.index).DigitalRead

Two separate arrays are ... OK. Works.
 
Upvote 0
Back
Top