Wednesday 15 March 2017

Gambas: command-line programming

I must have been using Gambas for small projects since I fully switched to Linux for my home computing needs almost 10 years ago.


Gambas was a natural choice for me as I'd spent several years in industry using Visual Basic, Delphi and Turbo Pascal.


But up until quite recently, it had not occurred to me that there might be some benefit in using Gambas for command-line programming.


a word about event-driven programming


One thing these "visual" languages have in common, is their support for event-driven programming.

While you can write event-driven applications in most software languages, all "visual" languages (like VB, Delphi & Gambas) have structures and components which take care of some of the details for you.

For example, when you drag a button onto a Form in the visual designer, an instance of the button class is created and some skeleton code created.

Public Sub Button1_Click()

  'your code goes here!

End


All you then have to do is write the code to be executed when the user clicks on your button. This means that you create a program without a program loop. There still is a loop, but its hidden, and not your responsibility.

Event driven programs respond quickly to any events raised, and in any order. The language and development environment are designed such that you can quickly create an application with windows, buttons, text boxes and other controls like timers.

command-line programs


This is where many people start out programming. You write a program, often using just a text editor, maybe starting with "hello world!"

These programs run by entering a terminal command, and any output is also displayed on the terminal.

In Python 3, the program may look like this:-

import time

while True:
    print ("Hello world!")
    time.sleep(5)


...and would be run from the terminal using the command:-

python /{path to file}/helloWorld.py

In Gambas it may look like this:-

Public Sub Main()

  Do
    Print "Hello world"
    Wait 5
  Loop
 
End


...and run using the command:-

  /{path to file}/helloWorld.gambas

In both examples, the program runs around a loop outputting "Hello world!" every 5 seconds until you stop it.

Obviously run-time support is required for each language (i.e. Python 3.x and Gambas3). The Python example runs from the text (source) file via the Python3 interpretor.



The Gambas example will run in the Gambas IDE and/or from the executable created by the IDE.

I'm not planning on getting into a discussion on which language is best. As hobbyists, we have the luxury of being able to pick and use whatever tools we fancy. This post just happens to be about Gambas.

To stop a Gambas command-line program we can just use the "Quit" instruction.

Public Sub Main()
Dim iCounter as Integer


  Do 

    Print "Hello world"
    Wait 5

    Inc iCounter
    If iCounter > 10 Then
      Quit
    Endif
  Loop
 
End


...or even easier:-

Public Sub Main()
Dim iCounter as Integer


  Do 

    Print "Hello world"
    Wait 5

    Inc iCounter
  Loop Until iCounter > 10
 
End



In fact most things you can do for GUI programing, you can still do with command-line programming, except you won't have a GUI interface. However, this also means you don't have to run a desktop GUI on your system.

Raspberry Pi & the gpio


Programming for the gpio on the Pi is the same for command-line programming as it is for GUI applications, using either wiringPi or the pigio libraries. For example, with wiringPi:-

Library "/usr/local/lib/libwiringPi"

Public Extern wiringPiSetup() As Integer      
Public Extern pinMode(pin As Integer, pud As Integer)   

Public Extern digitalWrite(pin As Integer, value As Integer)

Public Const PIN_OUTPUT As Integer = 1
Public Const PIN_INPUT As Integer = 0

Public Sub Main()

  wiringPiSetup()
  pinMode(22, PIN_OUTPUT)
  

....'do stuff

End




back to events


Lets take a more complex example than our initial "Hello world!" program, where we want to output additional strings at different times.

Public Sub Main()
Dim iCounter As Integer

  Do
    Inc iCounter
    Wait 1
    If icounter Mod 5 = 0 Then  'another 5s has passed
      Print "Hello world!"
    Endif
    If iCounter Mod 16 = 0 Then 
'another 16s has passed
       Print "please shut up!"
    Endif
    If icounter Mod 22 = 0 Then 
'another 22s has passed
       Print "Brexit means Brexit!"
    Endif
  Loop
 
End


All we have here is a program that runs a continuous loop printing messages at 5, 16 and 22 second intervals. As the program complexity increases, so does the size of the loop.

Another approach is to use event timers (just like the timer in the graphical environment) to raise events when each time interval has expired.

'timer declarations
Public hTimer1 As Timer
Public hTimer2 As Timer
Public hTimer3 As Timer

Public Sub Main()

  hTimer1 = New Timer As "Timer5sec"
  hTimer1.Delay = 5000
  hTimer1.start
 
  hTimer2 = New Timer As "Timer16sec"
  hTimer2.Delay = 16000
  hTimer2.start
 
  hTimer3 = New Timer As "Timer22sec"
  hTimer3.Delay = 22000
  hTimer3.start
End



'event handlers

Public Sub Timer5sec_Timer()
  Print "Hello world!"
End

Public Sub Timer16sec_Timer()
  Print "please shut up!"
End

Public Sub Timer22sec_Timer()
  Print "Brexit means Brexit!"
End


Although there are more lines of code in this version, I prefer it, as it looks clearer to me. I guess I've got so used to event timers, I'd be lost without them!

conclusion


I think I will be using Gambas command-line programming a lot more in the future for headless Pi projects, as its a natural choice for someone with more experience of BASIC than Python. I have already fixed a problem with my recent bird box system by adding a small Gambas command-line program that runs as the system is booting via /etc/rc.local.

I also think Gambas is overlooked by many people (including educators) who are looking for a suitable BASIC environment with a good IDE for the Raspberry Pi.

No comments:

Post a Comment