Raspberry Pi: IDE, Java, and GPIO

It is not often that I throw my hands up and stop trying to get something to work. This is one of those cases. The basic problem is that the GPIO chip changed between the Raspberry Pi 4 and Raspberry Pi 5. Given that my background was working for a large computer companies, Sun Microsystems/Oracle/IBM, and I have a Masters degree in Computer Engineering and another in Electrical Engineering, I am very unsettled that a simple chip change causes software to break between hardware releases. What should happen is that the operating system should hide these changes. A new device driver should be written to keep the user interfaces, both at the command line and libraries for various languages, the same and functional between chip changes.

Just to set this in time, it is the first of August in 2024 and I can not get Java libraries to work on the Raspberry Pi because pieces and components don’t exist to allow for a simple download. I can get both Eclipse and Microsoft Visual Studio working on a Raspberry Pi 5 but no Java libraries that work with the GPIO exist. I am struggling to get Studio to work properly on a Raspberry Pi 4 because there is not enough memory on the 2MB model that I have. The IDE loads and starts to run. When I try to install Java or C/C++ as a language extension the operating system “wedges” and stops working. The net result is that I can’t get an IDE, Java, and the GPIO libraries to work on a Raspberry Pi 4 or a Raspberry Pi 5.

The https://www.pi4j.com/ website says that the Java libraries on the site support the Raspberry Pi 5 but the libraries are dependent upon the http://wiringpi.com/ WiringPi interfaces. When you go to the WiringPi website it says that

“As of the end of 2023, you’ll not find anything here anymore. It’s gone.

Email if you want – if you know my email address. Work it out.

-Gordon

This is unfortunate and breaks the only Java GPIO library that states that it works with the Raspberry Pi 5.

In theory, you can download a fully baked operating system that contains an older version of the Pi4J library as well as the WiringPi interfaces but I am hesitant to download any code that no longer has support.

The fundamental problem is that not only has the chip changed but the numbering of the GPIO pins has changed. According to http://git.munts.com/muntsos/doc/AppNote11-link-gpiochip.pdf the basic problem is how the devices are presented from the operating system.

The Raspberry Pi 5 introduced an unfortunate breaking API change for manipulating GPIO pins. For all previous Raspberry Pi boards, you needed to use /dev/gpiochip0 to manipulate the expansion header GPIO pins. On the Raspberry Pi 5, the GPIO controllers enumerated differently, and you must now use /dev/gpiochip4. Furthermore, the
Raspberry Pi engineering staff have indicated that the enumeration order may change in the future as well. This change has broken many Raspberry Pi GPIO libraries…

Given that the way that the operating system presents the definition of the GPIO pins has changed and will probably change again, my recommendation is to use something else. If you have to use the GPIO pins, expect to change your code again in a year or two and know that at some point it will break again. Unfortunately, driving motors, LEDS, and meters are done easily using the GPIO pins. These changes not only effect the GPIO pins but the IC2 and other pins that can be used to drive input and output for the Raspberry Pi. I will continue to go through tutorials using Python, C/C++, and Java where it makes sense. Realize at some point these tutorials will break and the libraries that are used to show functionality will probably break and an alternate solution might be needed.

What we have that is working is as follows

LanguageIDEGPIO
Command LineNoPi4 – gpio, raspi-gpio
Pi5 – pinctl
PythonEclipse, Visual StudioPi5 with IDE
Pi4 with no IDE
C/C++Eclipse, Visual StudioPi5 with IDE
Pi4 with no IDE
JavaEclipse, Visual StudioPi4 with no IDE

Raspberry Pi: working with GPIO from C/C++

There are a variety of libraries available for the C and C++ compilers that allow you to talk to the GPIO on a Raspberry Pi. Unfortunately, most do not support the Raspberry Pi 5. The Raspberry Pi 5 uses a different chip than the Raspberry Pi 4 to control the GPIO pins. This means that most libraries that worked on a Pi4 do not work on the Pi5. Again, unfortunately, there are similar problems with the Pi3 and Pi2 because the chips that control the GPIO pins are different between all of the boards. Fortunately, the older boards have been around a while and most libraries support upto the Pi4.

GPIO differences

If we look at the history of the GPIO controller chip and pinouts, function and operation have changes with each board release

Type 1 – Model B (original model)

  • 26 pin header (P1).
  • Hardware revision numbers of 2 and 3.
  • User GPIO 0-1, 4, 7-11, 14-15, 17-18, 21-25.
GPIOpinpinGPIO
3V3125V
SDA0345V
SCL156Ground
47814TXD
Ground91015RXD
ce117111218ce0
211314Ground
22151623
3V3171824
MOSI101920Ground
MISO9212225
SCLK1123248CE0
Ground25267CE1

Type 2 – Model A, B (revision 2)

  • 26 pin header (P1) and an additional 8 pin header (P5).
  • Hardware revision numbers of 4, 5, 6 (B), 7, 8, 9 (A), and 13, 14, 15 (B).
  • User GPIO 2-4, 7-11, 14-15, 17-18, 22-25, 27-31.
    GPIOpinpinGPIO
    3V3125V
    SDA2345V
    SCL356Ground
    47814TXD
    Ground91015RXD
    ce117111218ce0
    271314Ground
    22151623
    3V3171824
    MOSI101920Ground
    MISO9212225
    SCLK1123248CE0
    Ground25267CE1
    GPIOpinpinGPIO
    5V123V3
    SDA283429SCL
    305631
    Ground78Ground

    Type 3 – Model A+, B+, Pi Zero, Pi Zero W, Pi2B, Pi3B, Pi4B

    • 40 pin expansion header (J8).
    • Hardware revision numbers of 16 or greater.
    • User GPIO 2-27 (0 and 1 are reserved).
    GPIOpinpinGPIO
    3V3125V
    SDA2345V
    SCL356Ground
    47814TXD
    Ground91015RXD
    ce117111218ce0
    271314Ground
    22151623
    3V3171824
    MOSI101920Ground
    MISO9212225
    SCLK1123248CE0
    Ground25267CE1
    ID_SD027281ID_SC
    52930Ground
    6313212
    133334Ground
    miso19353616ce2
    26373820mosi
    Ground394021sclk

    Type 4 – Pi5

    • 40 pin expansion header (J8).
    • Hardware revision numbers of 16 or greater.
    • User GPIO 2-27 (0 and 1 are reserved).
    GPIOpinpinGPIO
    3V3125V
    SDA2345V
    SCL356Ground
    47814TXD
    Ground91015RXD
    ce117111218ce0
    271314Ground
    22151623
    3V3171824
    MOSI101920Ground
    MISO9212225
    SCLK1123248CE0
    Ground25267CE1
    ID_SD027281ID_SC
    52930Ground
    6313212
    133334Ground
    miso19353616ce2
    26373820mosi
    Ground394021sclk

    Even though the pinouts remain the same between the Raspberry Pi 4 and Raspberry Pi 5, the functionality changes between the two and how you program them internally is different. If you are using the command line on a Raspberry Pi 4 the raspi-gpio is the command that has traditionally been used. The operating systems takes care of talking to the controller chip and everything works as expected. When the Raspberry Pi 5 came out, the raspi-gpio command was no longer supported.

    $ raspi-gpio help

    raspi-gpio is not supported on Pi 5 – use pinctrl

    The pinctrl command replaces raspi-gpio and uses a different kernel call and process to talk to the GPIO. Fortunately pinctrl accepts the same arguments as raspi-gpio so little if any changes will be needed for command line programs.

    Pigpio

    The pigpio library, https://abyz.me.uk/rpi/pigpio/index.html , is a library that supports Python, C/C++, and Java with some extensions. Unfortunately, this library only works with the older versions and has not been ported to the Raspberry Pi 5. The authors of the library have stated that the port is not insignificant and will require some work to get things working as with previous versions.

    Libgpiod

    An alternate is to have a common user call given that the command lines have changed from hardware version to hardware version. The libgpiod, https://github.com/brgl/libgpiod , is designed to be a common user interface that hides the hardware dependencies between hardware and operating system flavors. On a grander scale, this would also work on an Arduino using the same or similar code that runs on the Raspberry Pi.

    RPi.GPIO

    The RPi.GPIO library, https://pypi.org/project/RPi.GPIO/ , is a Python only library and does not work with C/C++ or Java.

    WiringPi

    The WiringPi, https://github.com/WiringPi/WiringPi/ , library appears to be one of the first GPIO libraries that support the Raspberry Pi. To install WiringPi, use git to download the source and build to build the library

    $ sudo git clone https://github.com/WiringPi/WiringPi.git
    $ cd WiringPi
    $ sudo ./build

    If we look in the examples folder there is a blink.c file that writes to an LED on GPIO pin 17.

    // LED Pin – wiringPi pin 0 is BCM_GPIO 17.

    #include <stdio.h>

    #include <wiringPi.h>

    #define LED 0

    int main (void) {
    printf (“Raspberry Pi blink\n”) ;

    wiringPiSetup () ;
    pinMode (LED, OUTPUT) ;

    for (;;) {
    digitalWrite (LED, HIGH) ; // On
    delay (500) ; // mS

    digitalWrite (LED, LOW) ; // Off
    delay (500) ;

    }
    return 0 ;
    }

    The Makefile has one significant change with the compile in that it pulls in the libwiringPi library that gets installed in /usr/local/lib

    LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt

    $ gcc -o blink blink.c -L/usr/local/lib -lwiringPi

    The -L/usr/local/lib command tells the compiler to look in the /usr/local/lib folder the the libraries. The -lwiringPi tells the compiler to look for the libwiringPi.so or libwiringPi.a library. These libraries contain the routines wiringPiSetup(), pinMode(), and digitalWrite(). The wiringPiSetup() routine initializes the GPIO chip and linkages that are needed for the connection. The pinMode(<pinNumber>,<mode>) routine programs the pin number as an input or an output. It is important to note that the GPIO pins do not necessarily match with the library pin numbers. For example, pin 0 with the library correlates to pin 17 on the GPIO pins.

    If you type gpio readall it will show the pin mappings

    If you look at the BCM column, that corresponds to the GPIO label. Looking at the right of the table, physical pin 12 corresponds to the name GPIO.1, GPIO pin 18, or wPi library number 1. All of this is confusing but works. My suggestion would be to define your own labels. For example, I would define gpio_pin_17 as 0 and gpio_pin_18 as 1 rather than using the wPi library names GPIO.0 and GPIO.1.

    In summary, we do have one solution that allows us to use C/C++ to read and write GPIO pins. The code is not optimal but it does function. Mapping of the GPIO pin labels to the wPi library labels is a little more complex than needed. If you have code previously developed on the Raspberry Pi 4 or older versions the same code might or might not work on a Raspberry Pi 5 based on what library was selected and if the library is available on the new board. In time, the other libraries should be ported to the Raspberry Pi 5 and less complex solutions will be available.

    Raspberry Pi: Python LED Blink

    In this post we will look at what it takes to blink an LED on the Raspberry Pi using the GPIO pins and Visual Studio. We will use Visual Studio to show the process of software development. We will discuss the electrical components needed to attach an LED and resistor to the Raspberry Pi. We will also dive into the code required to turn the LED on and off.

    Start connecting to your Raspberry Pi using a keyboard/mouse/computer screen or through VNC from your desktop computer. From the top left of the screen select the Visual Studio IDE.

    Visual Studio restarts where we left off when we last worked in the environment.

    From here we click on File -> New File

    Note that we now have an option to start a Python file since we have developed at least one Python file in the IDE.

    We are now ready to start development. Note that the file is Untitled. We can save it as a file with the “.py” extension of just start typing code.

    If we start typing the IDE will suggest what we might want to finish. In this instance we want to include the gpiozero module so that we can talk to the GPIO pins from our program.

    You do need to know a little about the module and interfaces/routines that are available in the module. In this example, we are pulling in the gpiozero module and talking to an LED method.

    The import command says pull in the LED method from the gpiozero module and make it available to use. We want to pull in the sleep command as well so that we can loop and delay between turning on and off the LED. When we call the LED() method the IDE tells us what parameters are needed to call the method.

    In this instance we are using pin 17 as an output to drive the LED. We need to assign the LED to a variable. We select “led” as the variable and call then turn on (with the led.on() call) or off (with the led.off() call). The sleep function allows us to sleep for a number of seconds. The while True statement says anything that is indented below that command will be executed in a loop.

    Now that we have the code ready to run, we can save the file with File -> Save File

    We call the file gpio_led.py and can now debug the code as desired using the IDE. Before we can debug we need to attach the external LED and resistor to pin 17 and ground.

    We connect a wire from GPIO pin 17 to the long side of the LED. The short side of the LED is attached to a resistor. The other side of the resistor is attached to ground on the Raspberry Pi.

    When selecting a resistor it is important to note that different color LEDs need different size resistors. Given that the resistor and LED are in series it creates a voltage division between the two elements. The GPIO pin will output 5 volts across both elements.

    Putting a small resistor in series with the LED will cause the LED to be brighter. A larger resistor will take more voltage from the LED can cause it to not be as bright.

    You need to make sure that the resistor is not too small because it will burn out the LED. If the resistor is too large the LED will never turn on. To calculate the resistor size, we need to know the voltage drop across the LED (which we can get from the chart above) and subtract that number from 5 volts.

    In this example we have a 1.8 volt drop from the LED and a 3.2 volt drop needed across the resistor. If we assume 20 milliAmps of current we can either calculate the resistor needed

    or look up in a table what minimum resistor value is needed.

    In this example we would use a 150 Ohm resistor to get a 2 volt drop across the LED. Note that this would work for most LEDs but not the blue or white LEDs since it would need a 2 volt Vf drop. These LEDs would need a smaller resistor since there would be less voltage across the resistor given that the blue or white LEDs create a 3 volt drop rather than a 2 volt drop. Calculating the resistor size is a bit complex but starting with an LED in the 200 to 330 Ohm range and going up to 1K to 2K are good starting points to keep the LED from burning out. If you use too small of a resistor you risk driving too much voltage across the LED and melting it.

    It is also important to note that the LED has two leads, one long and on short.

    The long lead connects to the GPIO pin in our example and the short lead connects to the resistor. The other side of the resistor connects to ground. The gpiozero module assumes that you are driving the GPIO pin high to turn on the LED. This assumes that you are driving the anode (long side) and not the cathode (short side). If you put 5 volts on the cathode and ground the anode nothing will happen. The LED will stop current from flowing and will not light up. If you put voltage on the anode and ground the cathode the LED will turn on. By calling the led.on() routine, 5 volts is driven through GPIO pin 17 to go across the LED and resistor.

    Running the code from the IDE will start driving pin 17 high and low with a second delay between turning on and turning off.

    Note that there is no output in the console since we don’t print anything to the console. To stop the program click on the red outlined box at the top of the code.

    Note that the console shows that we are ready to execute more code and is no longer running our Python code. If we want to run the code with a breakpoint we can set a breakpoint by clicking to the left of the line number.

    When we try to run again we can only run with Debugger since we have a breakpoint. When we run the code stops at the breakpoint.

    At this point we should have the LED shining brightly. Clicking on the Step Over button will execute the led.off() method.

    This should turn off the LED and get ready to sleep again. Clicking on the Continue button will run the program until we hit the breakpoint again.

    Once we understand how the program works to this point we might want to clear the breakpoint. To do this, right click on the breakpoint and either clear, disable, or edit the breakpoint.

    If we had variables defined in the code we could look at the values stored in the code as it runs. Setting a breakpoint at a critical point can help with unknown values or logic associated with code. This is one of the critical improvements that an IDE brings over just developing at the command line. Unfortunately, the IDE does not help with timing issues in code because the IDE introduces a delay into the code as it steps through everything. The code runs much faster without a debugger. The IDE collects data as it debugs so that you can look at variables and state inside your code.

    In summary, we can use Visual Studio to create, develop, and debug code on the Raspberry Pi. Using Python we can pull in the gpiozero module and control things like an LED attached to the GPIO pins. We can use the time modules to create delays so that we can see the lights blink on and off. We can change the delay with this code and in future posts we will look at changing the brightness of the LED using different parts of the gpiozero code.

    IDE:Visual Studio development environment for Raspberry Pi

    In our last post we looked at Eclipse as a development environment on the Raspberry Pi. In this post we will look at Microsoft Visual Studio as an alternative. We picked these two to focus on because they are what most professional developers use in other environments. If you are planning on learning tools that will help with a career or job, there are the two that are recommended.

    The key benefits for Visual Studio are that it works on multiple platforms (Windows, MacOS, and Linux), supports multiple languages ( C++, C#, Go, Java, Python ), supports multiple tools (ESLint, JSHint , PowerShell ), supports complex searching and multi-screen editing, and more.

    Visual Studio is easily installed with an sudo apt-get install code command.

    Instructions can be found at https://code.visualstudio.com/docs/setup/raspberry-pi on how to install and configure the environment.

    Once the code is installed it appears on the pull-down menu from the top of the screen.

    When the environment is first installed, a welcome window appears that walks you through the configuration. The first option is to select the languages that will be supported in the development environment.

    We select Python first.

    After a couple of minutes we can install C/C++ support.

    Finally, we can select Java as our third language to support.

    We will start with a Java Project. To create a new project, go to Files -> New File

    Select New Java Project.

    with no build tools

    We select a folder to work in, HelloWorld

    In this folder we create a new file

    Adding the .java extension to the file name automatically classifies it as a Java file.

    As we start typing Visual Studio start suggesting ways of completing the statement. In this example, the code suggested is for the main() routine to start the program.

    As we type Visual Studio shows options for calls to the call you are using. In this example we started typing System. The IDE showed us multiple options including the out method call. Once we select out we have the option of various ways of outputting data. We select the printf() routine to print a string to the console.

    If your code had errors or warnings they would appear on the left side of the line in question and hovering over the red or yellow icon will give more detail on what the problem could potentially be.

    At this point we have the option of setting breakpoints, debugging the code, or simply running the code and looking at the console output.

    Selecting the Run option we can see the output to the console

    In the console window we see the compilation steps required and command line needed to run the code along with the output from the program to the console.

    To build a Python file, click on File -> New File

    We want to select a Text File type.

    The IDE then asks what language we want the file to be.

    If we save the file with a “.py” extension it automatically defaults to Python. Alternatively, we can click on Select a language to go to a pull-down menu and define the language type.

    In this example, we can add the print() statement and run the program as a Python program.

    If we wanted to do something similar with C/C++ we start with File -> New File

    We then click to get a pull-down for language selection

    From the Select a language link we get a list of potential programming languages.

    We select C or C++ and get an option on what compiler to use

    We select the default install gcc which will generate our C file.

    From here we can Select Run which will compile and run the code. We can look at the compile output by clicking on the C/C++ header on the bottom right corner or look at the console output by clicking on the cppdbg header in the same area.

    In summary, we have a professional development environment that supports Python, Java, and C/C++ in our Raspberry Pi environment. The installation was easy. The addition of additional languages was simple. The editing and debugging of the code is much better than the default IDE tools installed by default on the Linux operating system. At this point we can truly start developing applications using either the Eclipse IDE or Visual Studio IDE using tools and processes that professional developers use.

    IDE:Eclipse – development environment for Raspberry Pi

    Before we dive into what is an IDE, it is important to note that there are a variety of development environments available for the Raspberry Pi. We will not be covering more than a couple of them because so much goes into picking a development environment. Many of the tools that are available are specific to a programming language are good for that language but are not very good with other languages.

    An IDE, or Integrated Development Environment, is a software application that combines various tools for software development into a single program. IDEs help programmers be more productive by making it easier to edit, build, test, and package software code.

    It is important to note that building a program can be done with a simple editor, a compiler, and simple test procedures. In theory, and IDE will help with all phases of this development. Given the large number of tools available on the Raspberry Pi, we will focus on two which are generic and “mainstream” for professional programmers (Eclipse and Microsoft Studio) and work with Python, C/C++, and Java. In this posting we will focus on Eclipse getting it to work with all three languages.

    Eclipse (https://www.eclipse.org/) is an integrated development environment (IDE) used in computer programming. It contains a base workspace and an extensible plug-in system for customizing the environment. The Eclipse Foundation helps develop and distribute the code as free and publicly available.

    Unfortunately, you can’t use apt-get to install the eclipse IDE. To install the software package you need to download the software then execute an installer. The software can be downloaded from https://www.eclipse.org/downloads/packages/ using the Linux AArch64 framework.

    From a VNC or console connection into your Raspberry PI, launch a web browser and download the code

    Once the tar.gz file is downloaded it can be extracted so that we can execute the installer.

    The eclipse-installer/eclipse-inst can be executed to begin the installation.

    Executing the eclipse-inst gives us the option of what development language to install initially. We will choose the C/C++ environment.

    Launching the IDE brings up the development environment. From here we can create our hello world example as we did from the command line.

    We can create a new C/C++ project

    With an IDE we have other options available to us. A Makefile, for example, allows us to automate building our binary from one or multiple source files. From the New project we select Make and Makefile Project then Next.

    We name the project and select create sample code and sample Makefile.

    When we click Finish we get two new files created, HelloWorld.cpp and Makefile.

    Some differences from the code generated are the use of iostream rathern than stdout.h and using the “<<” rather than printf(). In this exampke, argc and argv are included in the main() function definition to accept input parameters from the command line.

    For our example we will change the iostream and way we print to the standard way using printf(). Selecting Project -> Build All allows us to build the binary.

    Running the Build All will compile the HelloWorld.cpp file and show any problems or errors in the code. If we jump out of the development environment we note that there is a build folder that contains the compiled cod and runnable binary.

    We can run the binary from the IDE and see the output in the console.

    Note that we can run or single-step into the code the see what each instruction performs. You can also set breakpoints to stop when you get to a specific place to look at things like variables or parameters that exist or are passed into a specific point in the code. An IDE makes this happen very easily and significantly helps with debugging.

    Now that we have a stable C/C++ development environment we can do the same for Java by going to the Install Software and searching for Java.

    Clicking Next downloads a JDK and the Java development environment. The IDE needs to be restarted to provide the new environment.

    To create a Java project, Create New Project.

    From there, select Java Project.

    Enter a name and click Next

    Now that we have a project, we need to create a Java class that will contain our main() function. File -> New -> Class.

    We define the java class HelloWorldJ and check create a main routine.

    We add the System.out.printf() line to print our comment.

    We can then select Run or Debug as a Java class file. If we set breakpoints as discussed before we can look at variables and runtime conditions at specific points in our code.

    Note that the output appears in the console at the bottom of the IDE.

    Python is installed and configured similarly. We go to Help -> Marketplace and search for Python.

    Click on Install and restart the IDE. To create a Python project, click on New Project and select PyDev Project.

    Before the first creation you must configure the interpreter and support libraries.

    Clicking on the configure an interpreter allows us to select the Python 3 default installed on the operating system.

    Select Choose from list and the IDE will look at all Python binaries on the system.

    We will select the python3 in the default /usr/bin directory.

    along with the 3.11 support libraries.

    I had to resize the popup screen to get to the Finish button at the bottom. This creates the Python project.

    We create a new PyDev module and add the print option to the file created.

    Now that we have the code available we can run it as a Python binary.

    At this point we have an IDE on the Raspberry Pi that can develop C/C++, Java, and Python code. The IDE allows us to develop, debug, and compile all of these languages. We barely covered the surface of what you can do with an IDE but will look at more features in future posts.

    Adding programming languages to Raspberry Pi

    One of the nice things about a Raspberry Pi (any version) is the ability to program from the command line or a development environment (IDE). In this posting we will look at some of the programming languages that are pre-installed with the default operating system and how to add a couple more as desired.

    Python

    Python is a relatively simple programming language. From https://www.python.org/doc/essays/blurb/ the language is

    “Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. Its high-level built in data structures, combined with dynamic typing and dynamic binding, make it very attractive for Rapid Application Development, as well as for use as a scripting or glue language to connect existing components together. Python’s simple, easy to learn syntax emphasizes readability and therefore reduces the cost of program maintenance. Python supports modules and packages, which encourages program modularity and code reuse. The Python interpreter and the extensive standard library are available in source or binary form without charge for all major platforms, and can be freely distributed.”

    What this means in a nutshell is that Python is easy for building complex things from simple constructs. You can create a description of something like a vehicle and assign a number of wheels to. You can write routines to drive each wheel and potentially turn each wheel simply and easily. The modules and packages allow you to take work of others and use them without having to write everything for yourself. Documentation on Python can be found at https://docs.python.org/3/contents.html and chapter 6 details how to define and import modules https://docs.python.org/3/tutorial/modules.html# so that you can leverage the work of others or share with others.

    To test what version of Python is installed on your system, open a command prompt and type

    python –version

    The command prompt should return a version of level 3 or higher with a sub-version following the dots. To execute a program you can type python to invoke the interpreter and type python commands into the interpreter. The code will be executed as you type it.

    The command print() prints to the console what is between the quotes. The exit() command exits the interpreter and takes you back to the command line. Alternatively, you can enter the print and exit commands into a file and type python filename to execute the stored program. Traditionally a python file uses the “.py” extension so if we called our file Hello.py we would type

    python Hello.py

    It is important to note that capitalization is important on a Linux (or Raspberry Pi) system so make sure the file name and what you load into python match exactly. It is important to note that Hello.py and hello.py are two different files.

    C and C++

    The C and C++ programming languages are a little more structured than Python and is more useful when trying to define something as an object rather than a thing. If, for example, we wanted to describe a vehicle and the vehicle could be a bicycle, a tricycle, a car, a boat, or a rocket ship we could define how to make it go or make it turn using a common subroutine. The subroutine could then determine that the vehicle is a rocket ship and cause the engines to ignite as opposed to turning a motor on the back wheel to get the bicycle to go. C and C++ are higher level programming languages than Python and a little more difficult to program and learn. Fortunately, they are also more powerful and can do more things. Most operating systems are written in C and C++ allowing you to do things like addressing physical devices on the computer and easily controlling them. The GPIO (general purpose I/O) on the Raspberry Pi can be controlled from a command line using the pinctrl command. This command written in C and talks to the operating system to manage the GPIO pins.

    Programs written in C and C++ must be compiled from a source file, typically ending in a “.c” extension. The tool that compiles these programs is default installed on the Raspberry Pi in the form of the gcc compiler.

    Compiling a program either generates an object file or an executable. We will start with a simple example as we did with Python but save it as Hello.c instead of Hello.py to tell the compiler that this is a C or C++ file.

    #include <stdio.h>

    int main() {
    printf(“Hello World!”);

    return 0;
    }

    Note the first statement is an include of the stdio.h file. The “.h” extension defines things for the compiler. In this instance it defines that we are looking for a subroutine called main() and will be calling a subroutine called printf(). The main routine is the entry point for our code when we execute our compiled code. We can call it as an integer (the int prefix for main) or static void main(). Having main as an int function means that it return something to the command line when it finishes. If everything works as planned it typically returns a zero as shown in the code. If there is an error something else is returned and the shell language at the command line can do something different on a non-zero return. The printf() subroutine can take a string or combination of strings and variables and print it to the console. In this case we print a simple string.

    Compiling the code typically takes two phases. The first phase generates an object file that can be combined with other object files to generate an executable. The -c option for gcc generates a “.o” file extension. If we had multiple object files, as in the case with multiple subroutines or object definitions, we can string them together and generate an executable. If, for example, we wanted to define how to drive a bicycle we might have a file called bicycle.c, turn.c, go.c, and stop.c. The turn subroutine would exist in the turn.c file and get compiled into a turn.o object definition. The same to generate a go.o and stop.o object definitions. We would then use the -o option to tell the compiler to generate a bicycle executable from all four object files.

    In this example we compile all of the source files to object files using the “-c” option then combine all of the object files into an executable using the “-o” option. If we type file followed by the file names the operating system shows us what type of file is generated. The “.c” file is a C source file. The “.o” file is a relocatable object compiled for the Raspberry Pi. Finally, the bicycle file is an executable file ready to run on the Raspberry Pi.

    The benefit of putting the go, stop, and turn modules in a separate file is that we can define how to make a bicycle go in the go file and this same file can then be used again to make a tricycle go or a car go by expanding the way that the go function operates. Given that a bicycle and tricycle are started by peddling the code can be “reused” for a different object. For a car we have to turn on the engine, put the car in gear, and press the accelerator so the go operation is a little more complex but can be defined in the same file to make development and reusability easier in the long run.

    Java

    The Java programming language was developed many years after the C and C++ languages and was written to overcome some of the problems with those languages. Java is an object oriented language but the intent is that code is portable from one machine to another. If something is written for a Macintosh it can run on a Windows PC or on a Raspberry Pi with little or no modification.

    Unfortunately, Java is typically not installed on the Raspberry Pi and needs to be installed.

    To install java the apt-get command can be executed as root to install the compiler and java execution foundation on the Raspberry Pi.

    The sudo command allows you to run as root. Your username needs to be in the /etc/sudoers file to allow you to run commands as root. The apt-get command tells the operating system that you are doing something with packages for the operating system. The install option says that you want to install a software package from the internet. The default-jdk tells the command that you want to install the latest java development kit onto your computer. Once you type Y the installation begins.

    Once the installation is finished we should be able to type in java –version and see what version of the java development kit was installed.

    Using our previous example, we will print Hello World! from java using the following code

    class HelloWorld {
    public static void main( String []args ) {
    System.out.println( “Hello World!” );
    }
    }

    In C/C++ we defined a main routine that was the start of our program. In Java we do the same thing but need to define it a little differently. In Java we have to define main() as a public subroutine that can be called from the operating system and have it accept input variables so that we can pass in parameters from the command line. Rather than using the printf() routine we use the System.out.println() routine. This routine prints a string or a combination of strings and variables to the console (System.out) then exits. Note that there is no return value as there was in our other program because we defined the routine as a static void which means that it does not return anything. We also did not include the stdio.h definition to understand the print subroutine. Java makes assumptions that you will be reading and writing from the system and don’t need to include those definitions. The java interpreter takes care of going form the compiled code to the proper operating system.

    To compile Java code we type in javac Hello.java. This generates a “.class” file which can be taken to other machines and executed. We don’t need to recompile our java code for a different operating system or chip architecture. Note that the output of our javac is HelloWorld.class even though we had everything stored in Hello.java. This is caused by our class definition of HelloWorld. Had we named it HelloMom it would have written a HelloMom.class file. To execute the code we type java HelloWorld which reads in the HelloWorld.class file and jumps to the main() function definition.

    Note that the .java extension is listed as a C++ source file but is really a Java source file. The .class extension is the compiled object that can be executed from the command line with the java command. Also note that there is no binary generated as there was done with Python or C/C++. If you have multiple files that are needed as we did with the bicycle example we would list all of the class files behind the java command to include all of the class files.

    In summary, the default languages that can be used to program your Raspberry Pi include:

    • shell programming language
    • Python
    • C/C++
    • (optional) Java

    The first three are default installed and Java can be installed with the apt-get command. Other programming languages are available so this is not a complete list. Most are installed as we did with Java. Moving forward we will look at all four of these languages for program examples and the Raspberry Pi.

    driving an LED using a Raspberry Pi

    Today we will look at what it takes to turn on and off a light that is not part of the Raspberry Pi. The LEDs have changed between the Pi4 and Pi5 so we will not look at using the on-board LEDs but an LED attached through the GPIO (General Purpose I/O) ports.

    Before we get into the GPIO pin assignments, let’s review what an LED is and how it works. If you read the blog posting on driving an LED using an Arduino UNO R3 you can skip to the picture of the Raspberry Pi GPIO ports.

    The LED design is very simple. When you put a voltage across an LED it emits light. Unfortunately, if you put 5 volts with almost any amperage across the LED it will melt and become unusable. To prevent the LED from melting a resistor is typically placed between the Raspberry Pi and the LED to limit the voltage going into the LED.

    To begin our discussion let’s look at an electrical schematic of an LED.

    When a voltage is places across the LED it emits light. The long leg of the LED is the positive lead and the short leg is the negative lead. Putting a positive voltage on the negative lead and grounding the positive lead will not do anything. Putting a positive voltage on the positive lead and grounding the negative lead will cause the LED to “light up” and emit light.

    It is important to note that different LEDs require different voltages to emit light. The higher the voltage, the brighter the light shines. A red LED, for example, needs at least 1.63 volts before it begins emitting light and will burn out if you put more than 2.03 volts across it. A green LED, on the other hand needs at least 1.9 volts and can go as high as 4.0 volts before it overheats.

    Fortunately, we can use a resistor in series with the LED to control the brightness. The higher the resistor value, the less light the LED will emit. In the picture below a yellow LED is combined with different resistor values.

    Note that a 330 Ohm resistor, which has the least amount of resistance of all resistors shown, caused the LED to be brighter. The 100K Ohm resistor, which is about 1000 times more powerful than a 300 Ohm resistor, barely causes the yellow LED to turn on. Note in this diagram the red wire coming in from the left is supplying a 5 volt DC power and the black wire is providing a ground connection. With the breadboard (the white board that everything is plugged into) the two outer rows provide a connection to all of the holes along the blue line. The ground line is the row on the right of the board and the 5 volt line in the next row in line designated with a red stripe

    In the diagram above a 220 Ohm resistor is used to limit the voltage going across the green LED. We put 3.3 volts on the red bus on the left and ground on the blue bus on the right. By putting a resistor in hole 17 on the red bus, it connects one end of the resistor to the 3.3 volt supply. By putting the other end of the resistor in the left most pin in row 16 we can then put the positive lead of the LED in any of the holes on row 16 to connect the resistor to the LED. We then put the negative end of the LED in tow 16 on the other side of the air gap and tie it to ground with a wire running from any of the 16 pin holes to any pin on the blue line running up and down. Off screen we connect a voltage supply (or battery) to the red and blue lines with wires somewhere on the breadboard.

    To calculate the resistor needed for an LED, we need to know the voltage drop across the LED and the voltage of our supply. For an Raspberry Pi the voltage supply is 5 volts.

    To calculate the resistor value we use Ohm’s Law which basically is voltage is the product of current and resistance. If we have multiple voltage drops (as with a resistor and an led in series) the equation to calculate the resistance can be expressed as …

    A good website to calculate this is available at https://ohmslawcalculator.com/led-resistor-calculator . If we assume a 5 volt source and a 2 volt drop across the LED with 1 milliamp of current going through the LED and resistor we get a 3000 Ohm resistor (otherwise known as a 3K resistor). If we have a 4 volt drop (as is the case with a green LED) we would use a 1K resistor. In this example we would place a 3K resistor in series with a red LED and a 1K resistor in series with a green LED to have them with the same brightness. It is important to note that putting the resistor closer to the 5 volt power or closer to the ground line makes no difference. The only important thing is to put the resistor in series with the LED which means that they share one common plug in point on the breadboard.

    In the above diagram the blue wire is attached to ground on the Raspberry Pi and the purple wire is attached to GPIO pin 14. For the Raspberry Pi 5 the GPIO pinout is the same as previous versions of the Raspberry Pi.

    Note that the GPIO lines are arranged on both sides of the connector block and are numbered from 0 through 27. Some of these pins have special functions like pulse width modulation (PWM) or serial transmission (TXD/RXD) while others are generic input and output pins. Pins 5, 6, 16, 17, 22, 23, 24, 25, 26, and 27 are generic pins and can be programmed to be digital input or output lines. When a line is programmed to be an output line it is either enabled to be HIGH (or 5 volts) or LOW (or zero volts).

    Let’s start by driving one LED using GPIO pin 17 as shown in the diagram

    In this example we are going to use the command line to turn on and off the LED. To do this we will ssh into the Raspberry Pi and execute the pinctrl command. This command allows us to set a pin high or low with a simple command.

    $ pinctrl set 17 op

    defined GPIO pin 17 as an output pin

    $ pinctrl set 17 dh

    turns on the LED by driving GPIO pin 17 with 5 volts.

    $ pinctrl set 17 dl

    turns off the LED by driving GPIO pin 17 to zero volts.

    We can program this in a shell command by creating an infinite loop, turning on the LED, sleeping for a while, turning off the LED, and sleeping again before repeating

    pinctrl set 17 op

    while true

    do

    pinctrl set 17 dh

    sleep 1

    pinctrl set 17 dl

    sleep 1

    done

    The first pinctrl command defined GPIO pin 17 as an output only pin. The while true creates the infinite loop. Everything between the do and done statements will be executed over and over. The second pinctrl command sets pin 17 to high with the dh option. The sleep 1 sleeps for a full second. The third pinctrl command sets pin 17 to low followed by another sleep function for another second.

    We could change this program to drive multiple LEDs of different colors as is done with a traffic light by using multiple GPIO pins.

    In this example we are driving the Red LED with GPIO pin 17, the yellow with pin 18, and the green with pin 22 (with an extra blue LED on pin 23). We can change the code by repeating the pinctrl commands directing the different pins to turn on and off the lights

    # define GPIO pins as outputs

    # loop through turning on and off lights

    while true
    do
    pinctrl set 17 dh # turn on red LED
    sleep 1
    pinctrl set 17 dl # turn off red LED
    sleep 1


    done

    The lines in red are the added lines to drive the two additional LEDs. Using the command line can have some difficulties and is not the best way of performing this operation. To perform the pinctrl command you might need to be a root or super user. Not everyone has the rights or privileges to perform this function. In the next post we will look at using a programming language rather than a command line to drive the LEDs.

    Raspberry Pi install

    This is the start of a tutorial to help build a simple platform for robotic control and simple display options. We will start with a Raspberry Pi 4 and Raspberry Pi 5 as the initial platform. In the future we will look at an Arduino board using the Elegoo.com super starter kit Uno R3 Project kit.

    This kit contains a bunch of electronic projects as well as an Arduino UNO R3 microcontroller.

    Raspberry Pi

    The Raspberry Pi 5 is the latest release of a microprocessor board release from raspberrypi.com.

    This processor board was released in October of 2023 and is now generally available with 4 GB or 8 GB of memory for between $60 and $100 depending upon where you purchase the memory options.

    The Raspberry Pi 4 is a lower power system with similar memory configurations starting at $35 and was released in June 2019.

    The main difference between the Raspberry Pi 4 and Raspberry Pi 5 are processing power, display options, and expansion options

    Both require a memory card to help boot the operating system and either a WiFi connection, ethernet connection, or keyboard/mouse/HDMI monitor to configure and setup the system.

    The first key difference that will be obvious between the two boards is how they get power. The Pi4 gets power from a USB-C power adapter that is limited to 15 Watts (5 Volt/3 Amp minimum). The Pi5 needs a different power supply adapter that can power upto 27 Watts of power (5 Volt/5 Amp maximum).

    The microSD memory card is inserted into the back of the Raspberry Pi. This memory card contains the operating system and file system that controls the microcomputer.

    The only limitation for the microSD card size is the filesystem size for Linux. The physical size is restricted by definition so the size that we are talking about is the storage capacity. As of this posting in 2014, a 2 TB microSD card is the largest available on the market. The ext4 filesystem on Linux is 256 TB so there is plenty of room for larger microSD cards when they are available.

    To get the operating system on the memory card, another operating system like Windows 10 or MacOS are needed to copy the OS image from the internet to the memory card. A USB to memory card adapter is needed.

    Not all USB to card adapters can handle a microSD card and might need an adapter to handle the larger card slot.

    A good place to start for imaging the operating system is https://www.raspberrypi.com/documentation/computers/getting-started.html which details the parts and software needed for both the Raspberry Pi 4 and 5. The software for Windows can be found at https://www.raspberrypi.com/software/ and is relatively easy to install but does require admin rights to allow you to communicate with the USB port/memory card. The software is relatively simple to use and has three options for installation.

    The first option is to select the device (Raspberry Pi 4 or Raspberry Pi 4 or older models) .

    The second option is which flavor of the operating system to install. The initial recommendation would be to install a full desktop that allows for connection via keyboard/mouse/HDMI monitor or remote connection across the WiFi network or ethernet network. At some point you might want to install a “headless” system that can only be connected to through a network connection and is typically only a terminal connection and not a full desktop experience. This configuration requires a bit more knowledge of Linux command line options and how to manipulate/configure your system.

    You can install a 64 bit or 32 bit operation. The recommendation is to install the 64-bit configuration initially until you find a need for the 32-bot configuration or an application that requires 32-bit only.

    The final configuration option is to select the microSD card that gets mounted on the Windows operating system. The drive name and device type will typically be different than this screen shot.

    The final option is to configure the WiFi adapter, user/password, and hostname as part of the installation. This is done by clicking on the Edit Settings which gives you access to the optional configuration screens.

    In this example we configure the network, add a user, and define the hostname. You will typically need to modify each of these entries to fit your needs.

    It is suggested that you configure SSH at this point by going to the services tab and enabling the SSH option.

    The simplest recommendation is to use password authentication until you are more familiar with secure shell and using secure communications without a password.

    Once all options are defined, write the operating system to the memory card and eject it from your computer.

    The copy operation will take a few minutes and write then verify the operation.

    Take the microSD card and insert it into the back of the Raspberry Pi. The slot is the same for the Raspberry Pi 4 and Raspberry Pi 5.

    Attach the power supply, ethernet cable (if used), keyboard, mouse, and HDMI connector to the Raspberry Pi.

    At this point you should see a desktop screen on your monitor/TV and have a successful operating system installation.