Arduino: Driving more advanced LEDs

In previous posts, we looked at driving an LED using an Arduino and Raspberry Pi. For a quick review, an LED is short for a light emitting diode. The light emitting part is obvious. When you put a voltage across an LED it will shine a light. If you put too much voltage the LED will melt and burn out. Typically a resistor is put in series with the LED to limit the voltage. The diode part of the LED only allows a voltage to be places in one direction. Typically, the anode or positive leg of the diode is attached to the positive voltage and the cathode is attached to ground.

There are two ways to limit the intensity of the LED. You can either increase/decrease the resistor or increase/decrease the voltage. To change the resistance a potentiometer or variable resistor is needed. Most potentiometers are mechanical and not programmable. Voltages usually can’t be changed for the Arduino or Raspberry Pi. The output pins are either 3 volts or 5 volts. What you can do is change how long the voltage is on in relation to how long it is off.

As long as the cycle is less than 60 cycles per second, the human eye typically can’t see the light turn on and off. If you use a 25% duty cycle, the light will be dimmed to a quarter of the maximum brightness. A duty cycle of 50% will dim the LED to half the maximum brightness.

More complex LEDs

More complex LEDs are available to provide additional functionality. Typical LEDs allow for single colors. The traditional colors are red, green, and blue. If you need something like yellow or orange you typically have to combine two colors together. This is difficult to do with LEDs that are one color. What you want is a single LED that has all three colors built into a single lens so that you can control the different colors at the same time and have them blended in the LED. Multicolored LEDs are available and have multiple leads for the different colors.

The key difference from our previous example with one LED is that we now need to drive three output pins from the Arduino or Raspberry Pi. We also need to know how to combine the colors of red, green, and blue to get the color that we want.

If we turn on the red and green at the same time, the light should be yellow. If we want orange, we need to have a little more red than we do green.

If we apply a 25% duty cycle or intensity on the green and a 75% duty cycle or intensity on the red we will have a color more orange than yellow. If we apply a 50% duty cycle or intensity on the green and a 50% duty cycle or intensity on the red we will have more yellow than orange. It is important to calibrate the resistors according to the voltage drop for the different color LEDs.

Note that green ranges from 2 volts to 3 volts while red ranges from 1.8 volts to 2 volts. What we should do is put a much larger resistor on the red LED to get more of a voltage drop on the resistor and less on the Red LED. If we put the same size resistor, 330 Ohms for example, the green LED will shine brighter than the red. TO correct for this we need to reduce the green intensity by half or two thirds to get yellow when both are turned on.

// Define Pins

#define BLUE 3

#define GREEN 5

#define RED 6

void setup()

{

pinMode(RED, OUTPUT);

pinMode(GREEN, OUTPUT);

pinMode(BLUE, OUTPUT);

digitalWrite(RED, HIGH);

digitalWrite(GREEN, LOW);

digitalWrite(BLUE, LOW);

}

// define variables

int redValue;

int greenValue;

int blueValue;

// main loop

void loop()

{

#define delayTime 100 // intensity time factor to change brightness

// yellow is half red and half green

redValue = 255  ; // choose a value between 1 and 255 to change the color.

greenValue = 255 / 3 ; // set to 2/3 brightness to compensate for using 330 Ohm resistor on both red and green

// to get orange change the greenValue = 255 / 9;

blueValue = 0;

#define delayTime 100

// this is unnecessary as we’ve either turned on RED in SETUP

for(int i = 0; i < 1000; i += 1) // fades out red bring green full when i=255 {

analogWrite(RED, redValue);

analogWrite(GREEN, greenValue);

delay(delayTime);

}

}

If we want an orange light we simply change the greenValue to 255/9 which adds more red than green. If we want to change the brightness of the light we add an analogWrite(RED, 0) and analogWrite(GREEN, 0) after the delay(delayTime). We will also need to add a delay(delayTime) after the write of zeros to create a duty cycle. In the code example we have a delayTime of 100 resulting in a 100 microseconds that the light is on and 100 microseconds that the light is off. Adding a multiplication factor changes the mix to 2 milliseconds on and 1 millisecond off.

analogWrite(RED, redValue);

analogWrite(GREEN, greenValue);

delayMicroseconds(delayTime * 20  );

analogWrite(RED,0);

analogWrite(GREEN,0);

delayMicroseconds(delayTime * 10 );

For this example we use delayMicroseconds() rather than delay() to reduce flicker but give us a duty cycle that we can change by changing the multiplication factor. This the example above we are on 2/3 of the time and off 1/3 of the time thus reducing the brightness of the yellow or orange light.

7 segment LED

A more complex LED is the seven segment LED to display numbers and letters. The key difference between the multi-color LED and the 7 segment LED is that the 7 segment is arranged to light up bars that can combine to make a letter. The multi-color LED has three cathode leads. The 7 segment LED has seven cathode leads.

To display the number “1” segments b and c need to be turned on. To display the number “2” segments a, b, g, e, and d need to be turned on. A table can be created correlating which segments need to be turned on for what number and letter you want to display.

If we connect the Arduino directly to the 7 segment LED it requires resistors to limit the voltage across the 7 segment LED.

The code to drive the 7 segment LED is a little more complex in that it introduces something called arrays. For each number that can be represented, the table of which segment needs to be turned on can be defined in an array.

// make an array to save Sev Seg pin configuration of numbers

int num_array[10][7] = { { 1,1,1,1,1,1,0 }, // 0
{ 0,1,1,0,0,0,0 }, // 1
{ 1,1,0,1,1,0,1 }, // 2
{ 1,1,1,1,0,0,1 }, // 3
{ 0,1,1,0,0,1,1 }, // 4
{ 1,0,1,1,0,1,1 }, // 5
{ 1,0,1,1,1,1,1 }, // 6
{ 1,1,1,0,0,0,0 }, // 7
{ 1,1,1,1,1,1,1 }, // 8
{ 1,1,1,0,0,1,1 }}; // 9

//function header
void Num_Write(int);

void setup()
{
// set pin modes
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);


}

void loop()
{

//counter loop

for (int counter = 10; counter > 0; –counter)
{
delay(1000);
Num_Write(counter-1);
}
delay(3000);
}

// this functions writes values to the sev seg pins
void Num_Write(int number)
{
int pin= 2;
for (int j=0; j < 7; j++) {
digitalWrite(pin, num_array[number][j]);
pin++;
}
}

In the code we define num_array as a two dimensional array. The second part of the array defines the segments that need to be turned on or off. Note that there are seven values for the second part of the array. The first part of the array defines the number to be displayed. Note that there are ten values for the first part of the array. Arrays start indexing with a zero rather than a one. If we talk about num_array[0][0] we are talking about the first row of the array that contains all “1”‘s and one zero and specifically the first 1 in the second part of the array. The subroutine Num_Write takes an input of a number that should range from 0 to 9 (although it is not checked in the subroutine which can cause errors) and walks through the each segment value and outputs it to the output pin to drive the 7 segment LED. If the input number is a 0 then num_array[0][0] through num_array[0][6] are all “1”‘s. The num_array[0][7] value is a “0” and gets written to the output pin. Note that we start with pin 2 which correlates to the “a” segment and walks through all seven segments that correlate to pins 2-8 on the Arduino.

4 digit 7 segment LED

To make this more complex, we can attach to a 4 digit 7 segment LED by adding four additional control lines to select which of the 7 segment LEDs we are talking to.

Wiring for this example looks like

TM1637 4 digit 7 segment LED

Alternatively we can use a chip between the Arduino and the LEDs to reduce the number of output lines that are needed. The TM1637 4 digit 7 segment LED is a combination of LEDs and a controller chip that know how to “clock” in data rather than driving the LEDs with 12 lines. With this chip we only need two output lines along with power and ground. One output line, CLK, is a clock that strobes the values into the LEDs. The second line, DIO, contains commands that sequence through the segments on the LEDs and which digit is being addressed.

For an Arduino there is a header file called “TM1637Display.h” that defines how to talk to the libraries and TM1637 component.

Some examples of what can be done with a TM1637 component include a countdown timer, a clock showing the time of day, a temperature or humidity gauge, or anything that can be represented with numbers and some limited characters (“C” or “F” for temperature or a “:” in the middle to differentiate hours and minutes). We won’t go into a detailed example on how to use this chip but will save an example when we look at building a more complex system with inputs to create a real world example.

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.

    driving an LED using Arduino UNO R3

    Today we will look at what it takes to turn on and off a light that is not part of the Arduino board. Fortunately, this is a very simple task. In future posts we will look at driving the same circuit using a Raspberry Pi and look at a few of the different options available and how they compare to the Arduino code.

    Let’s start by talking about an LED light. The 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 Arduino 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 outermost row and the 5 volt line in the next row in line. Between these two rows is an air gap then more tows of holes. The holes above the air gap run in a different direction. The holed going up and down in this diagram are all connected.

    If we turn the board we can see that everything in row 1 is connected between the air gaps. The yellow lines are different from the green lines and different from the red or blue lines. We are trying to tie a resistor and the LED together at one end and put positive voltage and ground across the other ends.

    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 Arduino 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.

    A diagram of this configuration would look like …

    In the above diagram the black and purple lines are ground lines. The red and yellow lines are digital output lines. If we look at the pinout of the Arduino we note that there are multiple output lines available to us.

    In the wiring diagram above we use two of the GND PINS (which are fixed as ground and not programmable) for the black and purple wires. We could have used one of these going to the blue lines along the breadboard and wired from the blue line to the negative side of both LEDs. We also go from the Digital output pins 0 and 1. It is important to note that these pins are also labeled TX Pin an RX Pin because they can be used as input or output pins. In our coding example we will make these pins output to drive the LEDs.

    Let’s first begin by driving one LED using GPIO pin 13 from the Arduino board. The wiring diagram looks like …

    The code looks like …

    Let’s walk through this code. All Arduino programs start with void setup() to set the initial conditions. In this example we call the routine pinMode and set pin 13 as an output. If you wired the LED to another pin you would change the 13 to something else based on where you plugged in your wire.

    The second part of the code void loop() executes the desired code to drive the LED. The subroutine call digitalWrite writes a value to the GPIO pin. In the first line we are putting 5 volts on pin 13 with the parameters 13 and HIGH. The delay subroutine causes the computer to pause for a given amount of time in milliseconds, in this case 1000 milliseconds or one full second). The third line takes away the 5 volt signal and drops the voltage to zero on pin 13. The fourth line again delays for a second and the loop begins again.

    In the example above we would change all references to pin 13 to pin 9. We could also change the delays of 1000 to something longer or shorter to watch the LED blink on or off faster or slower.

    If we wanted to drive three LEDs (as with a traffic light) we would need to add a yellow and greed LED with the appropriate resistors to have the brightness the same as well as change the code to drive two more GPIO pins.

    // the setup function runs once when you press reset or power the board
    void setup() {
    // initialize digital pin LED_BUILTIN as an output.
    pinMode(9, OUTPUT);
    }

    // the loop function runs over and over again forever
    void loop() {
    digitalWrite(9, HIGH); // turn the LED on (HIGH is the voltage level)
    delay(1000); // wait for a second
    digitalWrite(9, LOW); // turn the LED off by making the voltage LOW
    delay(1000); // wait for a second
    }

    If we change the circuit to …

    The code changes to

    // the setup function runs once when you press reset or power the board
    void setup() {
    // initialize digital pin LED_BUILTIN as an output.
    pinMode(9, OUTPUT);

    // the loop function runs over and over again forever
    void loop() {
    digitalWrite(9, HIGH); // turn the Green LED on (HIGH is the voltage level)
    delay(1000); // wait for a second
    digitalWrite(9, LOW); // turn the Green LED off by making the voltage LOW
    delay(1000); // wait for a second


    }

    The lines in red above are the new lines of code. Copy and paste this into the Arduino IDE and upload it to the Arduino UNO R3. This should blink the green light for a second, yellow light for half a second, and red light for two seconds. In future examples we will drive a much larger number of LEDs using other chips to help minimize the number of GPIO pins to turn on and off lights.

    Arduino Install

    In last week’s blog post we talked about how to start development with a Raspberry PI. This week it will be a little different in that we will look at a much less powerful computer, the Arduino UNO R3.

    The newer version of the UNO board is the Arduino UNO R4 which was released in June 2023.

    The size, power requirements, and I/O capabilities of the R3 and R4 are similar. The R4 has a more powerful processor, more memory, and a faster USB connection. The clock speed (16 Mhz vs 48 Mhz) is the biggest difference contributing to performance but the memory sizes (32 Kb of flash memory vs 256 Kb as well as 1 Kb of EEPROM vs 8 Kb) makes a huge difference is what the processor can be programmed to do. The R4 does have higher analog input resolution in that it has 16-bit resolution vs 8-bit resolution for the six analog inputs.

    Fortunately, the power supply and form factor don’t change between the processors. The development environment (IDE) is the same with the only change being a pull down in the IDE to select the appropriate microcontroller board to program.

    To install the development environment you need a computer to interact with the Arduino. This computer can be Windows, MacOS, or Linux. A good tutorial has been written by the makers of the Arduino and is easy to follow – https://docs.arduino.cc/software/ide-v2/tutorials/getting-started/ide-v2-downloading-and-installing/

    The development environment takes a little practice to understand it but once you do it a couple of times it becomes simple. The interface allows you to develop code and upload it to the processor board. The first step is to select the board type then start developing for the board.

    Along with the board type you need to select how you will communicate with the Arduino. Newer models support WiFi communications while older models use a USB cable to connect to the board for the initial programming.

    Once you have connected to the Arduino through the WiFi or USB connection you can load a program into the development environment and upload it to the processor board. A good place to start is with the blink program which blinks the LED located on the board next to the USB connector. This will show that you not only have a good IDE configuration but a working Arduino that can be programmed from your computer. If you change the sleep time you can change the frequency of the blinking light. This is a simple way to play with the code and verify that everything is properly working.

    The blink code addresses the on-board LED and loops with a sleep command between turning on the turning off the light.

    The statement “int led = 13;” defines which pin you are addressing on the board. The statement “pinMode(led, OUTPUT)” defines pin 13 as an output pin. The loop command says repeat this operation forever with no limits until power is lost or a new program is uploaded. The “digitalWrite(led, HIGH)” command turns on the LED light. The “delay(1000)” command sleeps for 1000 milliseconds (otherwise known as one second) before executing the next command. The “digitalWrite(led, LOW);” command turns off the LED light. The second delay sleeps for a second as well before looping back to turn the light back on.

    If you want to play with this, change the second delay function to 500 which will sleep for a half a second before turning the light back on. If you then change the first delay to 500 as well the light will blink twice as fast. This is a good way to test the development environment and connection to the Arduino.

    It is important to note that the Upload function at the top left of the development environment is what is used once you change the code to change the operation of the Arduino. The upload writes your new code to the computer and executes the code as designed. For the blink program it can be loaded by going to the Files pulldown and loading the code from the Examples menu path.

    The blink program is located under the 01.Basics menu and comes default with the IDE installation. In future posts we will look at changing this code to control an external LED and not an LED that is on-board. This is useful for showing status or the user in a change of status. A very simple example of that would be attaching three LEDs to the computer with the colors red, yellow, and green to simulate a traffic light. Alternately we would read a volume level or battery charge level and go from green (full) to yellow (half-full) to red (almost empty). This is a more complex example because it requires reading data from a sensor and writing to three different output ports. With the Arduino we could also write an analog output or a pulse width output and change the brightness and color of a more complex LED. We will not only look at doing this with the Arduino but with the Raspberry PI as well.