Introduction
This article is intended to help beginners to get started with setting up development environments and programming a Raspberry Pi with both Python and C.
Below are the things we will cover today about Raspberry Pi, Python and C.
Background
An article written previously about setting up the Raspberry Pi itself and an over view of what a Raspberry Pi may help you get a better start for this article. Below is the link
Programming Raspberry Pi
To getting your raspberry Pi setup and running please refer to the below article about setting up your Raspberry Pi for the first time.
Once your Pi has been setup and you have booted into the LXDE which is our Lightweight GUI for Raspian.
Let us quickly tour some of the important things on this Operating system that we would be using while programming our device.
This is a file explorer/manager equivalent to Windows explorer on your windows operating system. The File manager can be located under the Accessories menu and help you move files around without using the command line. The File manager allows us to browse the file system using icons and folders similar to other operating systems with GUI.
The default web browser is Midori which is designed to be lightweight and to work with smaller processors with limited processing power. The usual web browsers like Chrome, IE, Safari are too heavy as they do a lot of work in the background which we tend to forget these days. Due to its size we cannot expect all the features to be available on these browsers.
For example :
- Midori cannot run Flash.
- Midori cannot run a Java plugin
- Midori doesn’t support all the HTML5 tags, example no Video
- The other browser option that comes with the Raspbian OS is Netsurf.
Leafpad is our notedpad for Raspian OS and Leafpad is the default text editor. Traditional editors like VIM and emacs can by installed later as they don’t come preloaded
Most of the tasks we perform on Pi are from the commandline. We run commands from the commandline using the LXTerminal program. The LXTerminal provides access to the shell a.k.a. commandline. The default shell on the Raspbian OS is the Bourne Again Shell or in Short BASH.
However we can change the shells with chsh command.
As mentioned earlier we shall use Command line extensively while working on the Pi. The command line is accessed using the LXTerminal program by default. There are 2 important tricks that can make our life easier woking with the commandline.
Autocomplete: Many a times we can just type few letters of a command or a file name and hit tab, this will let the shell know that we are asking the shell to autocomplete our text. The shell will attempt to autocomplete the string based on the current context such as current directory or programs in frequently used directories like /bin and /usr/bin.
Command history: This is another trick where we could reuse the commands ran earlier. To do so we will have to use the up arrow key to browse through our previous commands with latest commands being the first to appear. This is especially useful if you made a small mistake in a looong command and need to correct it, using history you will not be needing retype the whole command.
Noted below are some of the frequently used directories in the file system. Most of these follow the Linux structure and some are specific to Pi. The/sys has all the hardware on the pi and can be access from this directory.
Directory
| Description
|
/boot
| Folder for Linux Kernel and other packages necessary to booth/start the Pi
|
/bin
| The Raspian related binary files including those for required to run the GUI of the OS
|
/dev
| This is one of those virtual directories and this is used for accessing all the connected devices including the storage
|
/etc
| Misc config files like encrypted passwords are put in this
|
/home
| This is like My documents and each username will get a separate directory under this
|
/lib
| Lib= libraries, code required by various applications
|
/lost+found
| Dump of pieces of files are stored here when the system crashes
|
/media
| Dir for removable storage dives like USB and CD
|
/mnt
| Used to mount external hard drives and similar storage devices manually
|
/opt
| Optional software directory, any apps that are not part of the OS will go here
|
/proc
| Another Virtual directory, this contains info about running processes (programs)
|
/selinux
| Security utilities originally developed by our beloved NSA and these are related to Security Enhanced Linux
|
/sbin
| System maintenance binaries typically used by the root/superuser
|
/sys
| Operating system files
|
/tmp
| Temporary files
|
/usr
| This is used as storage for user accessible programs
|
/var
| Virtual directory that a program can use to persist data
|
We do see our current directory always displayed on the command line just before the prompt. In Linux ~ is used to represent our home directory and hence when we first open the command line below is what we see.
pi@raspberrypi ~ $
The meaning of the text is as below
Text
| Description
|
pi
| My user name followed by an @ symbol
|
raspberrypi
| The name of the device or the computer. The default name is Raspberry pi
|
~
| The current working directory of the shell. As we saw earlier ~ stands for Home directory, by default we start command prompt in our Home directory.
|
$
| $ is the shell prompt and all our commands would be displayed next to this. To execute the command we will press enter or return key after typing the command
|
Let us look at programming on your Raspberry Pi using a C and Python.
Python is considered one of the best First Programming languages due the ease and clarity for any beginner to start coding in the language. Since the Python developer community has grown huge we always will have someone to help out in times of need.
Python is an interpreted language. Meaning we don’t need to compile the code before running as the program executed directly without being compiled to a machine level language. These kind of languages are a bit quicker to program with. There are also some hidden benefits with the interpreted languages like elimination of the need to declare variable types. For example we need not tell the program explicitly if my variable is a string or a number or a list, these are figured out by the interpreter during execution.
The Python interpreter can be invoked in two different ways:
- We can run python interpreter as an interactive shell, where we execute individual commands
- We can also run as a command line program to execute standalone scripts written in Python.
The IDE for Python on Raspian OS is called the IDLE. See below image to find out where to locate the same.
Hello World in Python:
As we saw earlier a program can be run or executed in two different ways with Python. Lets say “Hello world” in both ways.
Method 1:
- Open IDLE3 by clicking on the icon from the desktop or from the program menu
- This might take a little while to load the IDE
- Once the IDE loads it would load a Python shell window.
- On the Python shell window type the below command
-
Print ("Hello World")
- Press Enter and you will see the Hello World printed below
Method2:
- Open IDLE3 by clicking on the icon from the desktop or from the program menu
- This might take a little while to load the IDE
- Once the IDE loads it would load a Python shell window.
- On the Python shell window click on the new Window from the file menu
- Type the below code into the new window
-
Print ("Hello World")
- Save the file as HelloWorld.py
- Now open LX terminal and type the below to execute the program in the file
-
Python HelloWorld.py
Bit more of Python:
Some of us come from the Arduino world and are used to the way of writing setups and loops and call them sketches.
Here in Python we call the sketches as Scripts and below is how a Setup and loop can be written in Python.
#Setup part
initNum = 0
#repeating loop
While True:
initNum=initNum+1
if((initNum%2)==0):
print(n)
The above program just keeps printing all the even numbers. To run this from IDLE, you can select Run Module from the run menu and saving the file, below is a image about the same.
You can press Control +C to stop the infinitely running program on the shell.
If you notice above in the program we are not using braces instead we are using white spaces to separate the code blocks. The spaces are 4 white spaces each and in IDLE pressing a TAB will insert 4 white spaces.
Functions in Python:
As mentioned earlier white spaces play an important role in Python as it is a highly structured language in which white space play the deterministic role. White spaces are used to separate out chunks of code form main program as functions which can be called from anywhere in the program.
Below is an example of the same program written as functions and function calls from the main.
#global var declaration
i=0
#Define Setup function
def setup():
global i
i = 100
#Define the loop function
def loop():
global i
i = i + 1
if((i%2)==0):
print(i)
#Main program
setup()
while True:
loop()
As you can see above we are doing things a bit differently, let us look at them one by one
- We are declaring I as our global variable even before we define our functions.
- Define setup function but not executing it
- Define loop function but not executing again
- In both the functions we are accessing the global variable by typing global keyword before the variable, this will avoid creating a local variable with the same name that only has a scope that is limited within the function
- The main part of the program them calls setup() function once and calls loop() functions inside a infinite While loop
Conditional Keywords
Keywords used in conditional statements are listed below with a quick description
Conditionals
| Description
|
if
| used to determine, which statements are going to be executed.
|
else
| is optional. The statement after the else keyword is executed,
unless the condition is True
|
elif
| stands for else if.
If the first test evaluates to False,
then it continues with the next one
|
not
| negates a boolean value
|
or
| at least one condition must be met.
|
and
| all conditions in a boolean expression must be met
|
is
| tests for object identity
|
TRUE
| Boolean True value
|
FALSE
| Boolean False Value
|
Loop Keywords
Keywords used in loops are listed below with a quick description
loops
| Description
|
for
| iterate over items of a collection in order that they appear
|
while
| controlling the flow of the program
|
break
| interrupt the (loop) cycle, if needed
|
as
| if we want to give a module a different alias
|
continue
| Used to interrupt the current cycle, without jumping out of the whole cycle.
New cycle will begin.
|
Built-in function keywords
Keywords that are the names of built in functions are listed below with a quick description
Built in functions
| Description
|
print
| print to console
|
pass
| does nothing
|
del
| deletes objects
|
Classes, modules related keywords:
Keywords realated to Classes, modules are listed below with a quick description
classes, modules and functions
| Description
|
class
| used to create new user defined objects
|
def
| used to create a new user defined function
|
global
| access variables defined outside functions
|
lambda
| creates a new anonymous function
|
exec
| executes Python code dynamically
|
yield
| is used with generators
|
import
| import other modules into a Python script
|
return
| exits the function and returns a value
|
from
| for importing a specific variable, class or a function from a module
|
Error Handling Keywords
Keywords related to Error Handling are listed below with a quick description.
Error Handling
| Description
|
try
| specifies exception handlers
|
except
| catches the exception and executes codes
|
finally
| is always executed in the end. Used to clean up resources.
|
raise
| create a user defined exception
|
assert
| used for debugging purposes
|
Install VIM
Most of us are familiar with Vi editor. The VIM editor is just a extended version of the Vi and has the similar functionality as the Vi editor, however with a lot of additional features and improvements.
Below is the command to install vim
sudo apt-get install vim
to edit a file vim we need a command like below
vim mynewProgram.py
Vim also comes with a GUI version and can be installed separately. This version opens in a new window with mouse support
sudo apt-get install vim-gnome
Install Python
In most cases you will already have the latest version of Python on the Pi. But if not below is the command to install or update Python.
sudo apt-get install python-dev
Install RPi.GPIO
The module RPi.GPIO is a python module which can be installed after Python installation and it provides us with methods to access the General Purpose Input Output(GPIO) pins on the Pi.
Below is the command to install or update the module.
$sudo apt-get install python-rpi.gpio
Debuggin in Python:
Once we start writing programs we are sure to encounter troubles at some point of time and will be in need to debug the program to find the root cause.
The IDLE interactive mode is the best tool for this situation. The Debug menu has several tools to analyse our code/program and also has the stepping through option to look at variables at each step of the program just like in any other high level languages and IDE.
Types of erros:
Error Type
| Description
|
Syntax errors
| : The most common errors would be the syntax errors and they are also the easiest to fix. These are usually the mistyped or misunderstood keywords.
|
Symantic errors
| : These are the logical errors, meaning the program is well formed but is not working as expected. These are usually harder to follow and our IDLE debugger will help us step through the program and pin point the root cause.
|
Just like good programming, good debugging skills are very important and takes years of practice and experience. However below are some best practices that will help us debug a program in Python on Pi.
Debuggin best practices:
- Use print() function often to show the program execution point in a given control flow
- Use _preint()+ to print variable values during program execution
- Make sure whitespaces are placed appropriately
- Syntax errors are sometimes introduced before the line that the interpreter reports, hence we need to go back and check for syntax errors when reported
- Be sure of the global and local variables and their use
- If there are parentheses used, make sure they match
- Use parentheses to enforce order of operation if you are not sure of the order.
- For example: 5 + 8 * 3 is not same as (5+8) * 3
Install BCM2835 – C
A C library for Raspberry Pi which can be downloaded from the below link
http://www.airspayce.com/mikem/bcm2835/
Below is the quoted explanation from airspyace about the library.
“This is a C library for Raspberry Pi (RPi). It provides access to GPIO and other IO functions on the Broadcom BCM 2835 chip, allowing access to the GPIO pins on the 26 pin IDE plug on the RPi board so you can control and interface with various external devices.
It provides functions for reading digital inputs and setting digital outputs, using SPI and I2C, and for accessing the system timers. Pin event detection is supported by polling (interrupts are not supported).
It is C++ compatible, and installs as a header file and non-shared library on any Linux-based distro (but clearly is no use except on Raspberry Pi or another board with BCM 2835).”
Below are the steps to install the same. Execute each command one after the other in the same sequence
Get the tar file from the website
wget <a href="http://www.airspayce.com/mikem/bcm2835/bcm2835-1.35.tar.gz">http:
unzip or untar your library
tar xvzf bcm2835-1.35.tar.gz
change to untarred directory
cd bcm2835-1.35
run configure command
./configure
Build the library
Make
Check the compilation
sudo make check
Install Library
sudo make install
To test the installation you can run the below program to blink the LED on the board every 500 milli seconds
#include <bcm2835.h>
#define MY_PIN RPI_GPIO_P1_11
BOOLEAN main(int argc, char **argv)
{
if (!bcm2835_init())
return FALSE;
bcm2835_gpio_fsel(MY_PIN, BCM2835_GPIO_FSEL_OUTP);
while (1=1)
{
bcm2835_gpio_write(MY_PIN, HIGH);
bcm2835_delay(700);
bcm2835_gpio_write(MY_PIN, LOW);
bcm2835_delay(700);
}
bcm2835_close();
return TRUE;
}
Then compile the code
gcc -o blink blink.c -lbcm2835
Now run the code as admin
sudo ./blink
Install Wiring Pi
Below is the link for the open source project WiringPi and te quoted text about the project
“WiringPi is a GPIO access library written in C for the BCM2835 used in the Raspberry Pi. It’s released under the GNU LGPLv3 license and is usable from C and C++ and many other languages with suitable wrappers (See below) It’s designed to be familiar to people who have used the Arduino “wiring” system1”
Steps to install WiringPi
sudo apt-get update
sudo apt-get upgrade
apt-get install git-core
git clone git:
cd wiringPi
git pull origin
cd wiringPi
./build
Test wiringPi whether or not is installed successfully.
gpio -v
gpio readall
Light sensing program in C
Below is a program that reads the light intensity and prints the same on screen.
#include <wiringPi.h>
#include <stdio.h>
#define G_1 0
#define G_2 1
#define G_3 2
typedef unsigned char gchar;
gchar get_Result(void)
{
gchar i;
gchar dat1=0, dat2=0;
digitalWrite(G_1, 0);
digitalWrite(G_2,0);
digitalWrite(G_3,1);
delayMicroseconds(2);
digitalWrite(G_2,1);
delayMicroseconds(2);
digitalWrite(G_2,0);
digitalWrite(G_3,1);
delayMicroseconds(2);
digitalWrite(G_2,1);
delayMicroseconds(2);
digitalWrite(G_2,0);
digitalWrite(G_3,0);
delayMicroseconds(2);
digitalWrite(G_2,1);
digitalWrite(G_3,1);
delayMicroseconds(2);
digitalWrite(G_2,0);
digitalWrite(G_3,1);
delayMicroseconds(2);
for(i=0;i<8;i++)
{
digitalWrite(G_2,1);
delayMicroseconds(2);
digitalWrite(G_2,0);
delayMicroseconds(2);
pinMode(G_3, INPUT);
dat1=dat1<<1 | digitalRead(G_3);
}
for(i=0;i<8;i++)
{
dat2 = dat2 | ((gchar)(digitalRead(G_3))<<i);
digitalWrite(G_2,1);
delayMicroseconds(2);
digitalWrite(G_2,0);
delayMicroseconds(2);
}
digitalWrite(G_1,1);
if(dat1==dat2)
{
return dat1 ;
}
else
return 0;
}
int main(void)
{
gchar rawValue;
gchar calculate_Value;
if(wiringPiSetup() == -1){
printf("Failure with calling a wiringPi method!");
return 1;
}
pinMode(G_1, OUTPUT);
pinMode(G_2, OUTPUT);
while(1){
pinMode(G_3, OUTPUT);
rawValue = get_Result();
calculate_Value = 210 - rawValue;
printf("Current calculate_Valueination : %d\n", calculate_Value);
delay(500);
}
return 0;
}
Below is the connection on my breadboard.
Now that we have seen how to program the device in both Python and C, let me know which one you prefer the most and why in the comments.