Raspberry Pi Drivers and Driving

Optical Device Drivers and Their Devices

Light-Emitting Diode

The light-emitting diode also called LED is a special type of diodes which emits light, unlike the other diodes. LED has a completely different body which is made of transparent plastic that protects the diode and lets it emit light. Like the other diodes LED conducts the current in only one way, so it is essential to connect it to the scheme correctly. There are two safe ways how to determine the direction of the diode:

  • in the cathodes side of the diode its side is chipped,
  • anodes leg usually is longer than the cathodes leg.
Figure 1: White LED [1].

The LED is one of the best light sources. Unlike incandescent light bulb LED transforms most of the power into light, not warmth; it is more durable, works for a more extended period and can be manufactured in a smaller size.

The LED colour is determined by the semiconductors material. Diodes are usually made from silicon then LEDs are made from elements like gallium phosphate, silicon carbide and others. Because the semiconductors used are different, the voltage needed for the LED to shine is also different. In the table, you can see with which semiconductor you can get a specific colour and the voltage required to turn on the LED.

When LED is connected to the voltage and turned on a huge current starts to flow through it, and it can damage the diode. That is why all LEDs have to be connected to current limiting resistor.

Current limiting resistors resistance is determined by three parameters:

  • I_D – current that can flow through the LED,
  • U_D – Voltage that is needed to turn on the LED,
  • U – combined voltage for LED and resistor.

To calculate the resistance needed for a diode, this is what you have to do.

  1. Find out the voltage needed for the diode to work UD; you can find it in the diodes parameters table.
  2. Find out the amperage needed for the LED to shine ID; it can be found in the LEDs datasheet, but if you can’t find it then 20 mA current is usually a correct and safe choice.
  3. Find out the combined voltage for the LED and resistor; usually, it is the feeding voltage for the scheme.
  4. Insert all the values into this equation: R = (U – U_D) / I_D.
  5. You get the resistance for the resistor for the safe use of the LED.
  6. Find resistors nominal that is the same or bigger than the calculated resistance.
Figure 2: Raspberry Pi and LED control schematic.

The example of the blinking LED code:

#Raspberry Pi Python sample code
import RPi.GPIO as GPIO
import time
LED = 18    #GPIO04 port
print ("LED on")
print ("LED off")


Using display is a quick way to get a feedback information from the device. There are many display technologies compatible with Arduino. For IoT solutions low power, easy to use and monochrome displays are used:

  • Liquid-crystal display (LCD),
  • Organic light-emitting diode display (OLED),
  • Electronic ink display (E ink).
Liquid-Crystal Display (LCD)

LCD uses modulating properties of liquid crystal light to block the incoming light. Thus when a voltage is applied to a pixel, it has a dark colour. A display consists of layers of electrodes, polarising filters, liquid crystals and reflector or back-light. Liquid crystals do not emit the light directly; they do it through reflection or backlight. Because of this reason, they are more energy efficient. Small, monochrome LCDs are widely used in devices to show a little numerical or textual information like temperature, time, device status etc. LCD modules commonly come with an onboard control circuit and are controlled through parallel or serial interface.

Figure 3: 16×2 LCD display [2].
Figure 4: Raspberry Pi and LCD screen schematics.

The example code:

#Raspberry Pi Python sample code
#Example using a character LCD connected to a Raspberry Pi
import time
import Adafruit_CharLCD as LCD
#Raspberry Pi pin setup
lcd_rs = 25
lcd_en = 24
lcd_d4 = 23
lcd_d5 = 17
lcd_d6 = 18
lcd_d7 = 22
lcd_backlight = 2
#Define LCD column and row size for 16x2 LCD.
lcd_columns = 16
lcd_rows = 2
lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, 
                     lcd_d7, lcd_columns, lcd_rows, lcd_backlight)
#Wait 5 seconds
text = raw_input("Type Something to be displayed: ")
#Wait 5 seconds
Organic Light-Emitting Diode Display (OLED)

OLED display uses electroluminescent materials that emit light when the current passes through these materials. The display consists of two electrodes and a layer of an organic compound. OLED displays are thinner than LCDs, they have higher contrast, and they can be more energy efficient depending on usage. OLED displays are commonly used in mobile devices like smartwatches, cell phones and they are replacing LCDs in other devices. Small OLED display modules usually have an onboard control circuit that uses digital interfaces like I2C or SPI.

Figure 5: OLED I2C display [3].
Figure 6: Raspberry Pi and OLED I2C schematics.
1. git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git
2. cd Adafruit_Python_SSD1306
For Python 2:
3. sudo python setup.py install
For Python3:
4. sudo python3 setup.py install
cd examples
Choose one of existing examples:
  - animate.py
  - buttons.py
  - image.py
  - shapes.py
  - stats.py
Electronic Ink Display (E-ink)

E-ink display uses charged particles to create a paper-like effect. The display consists of transparent microcapsules filled with oppositely charged white and black particles between electrodes. Charged particles change their location, depending on the orientation of the electric field, thus individual pixels can be either black or white. The image does not need the power to persist on the screen; power is used only when the image is changed. Thus e-ink display is very energy efficient. It has high contrast and viewing angle, but it has a low refresh rate. E-ink displays are commonly used in e-riders, smartwatches, outdoor signs, electronic shelf labels.

Figure 7: E ink display module [4].
Figure 8: Raspberry Pi and E ink display module schematics.
#Raspberry Pi Python sample code
#From https://www.instructables.com/id/Waveshare-EPaper-and-a-RaspberryPi
import time, datetime, sys, signal, urllib, requests
from EPD_driver import EPD_driver
def handler(signum, frame):
    print ('SIGTERM')
signal.signal(signal.SIGTERM, handler)
bus = 0 
device = 0
disp = EPD_driver(spi = SPI.SpiDev(bus, device))
print ("disp size : %dx%d"%(disp.xDot, disp.yDot))
print ('------------init and Clear full screen------------')
#Display part
imagenames = [] 
search = "http://api.duckduckgo.com/?q=Cat&format=json&pretty=1"
if search:
  req = requests.get(search)
  if req.status_code == 200:
    for topic in req.json()["RelatedTopics"]:
      if "Topics" in topic:
        for topic2 in topic["Topics"]:
            url = topic2["Icon"]["URL"]
            text = topic2["Text"]
            if url:
              imagenames.append( (url,text) )
              #Print topic
              url = topic["Icon"]["URL"]
              if url:
                imagenames.append( url )
              #Print topic
      print (req.status_code)
#Font for drawing within PIL
myfont10 = ImageFont.truetype("amiga_forever/amiga4ever.ttf", 8)
myfont28 = ImageFont.truetype("amiga_forever/amiga4ever.ttf", 28)
#Mainimg is used as screen buffer, all image composing/drawing is done in PIL,
#The mainimg is then copied to the display (drawing on the disp itself is no fun)
mainimg = Image.new("1", (296,128))
name = ("images/downloaded.png", "bla")
skip = 0
while 1:
  for name2 in imagenames:
    print ('---------------------')
    skip = (skip+1)%7
      starttime = time.time()
      if skip==0 and name2[0].startswith("http"):
        name = name2
        urllib.urlretrieve(name[0], "images/downloaded.png")
        name = ("images/downloaded.png", name2[1])
        im = Image.open(name[0])
        print (name, im.format, im.size, im.mode)
        im = im.convert("1") #, dither=Image.NONE)
        #Print ('thumbnail', im.format, im.size, im.mode)
        loadtime = time.time()
        print ('t:load+resize:', (loadtime - starttime))
        draw = ImageDraw.Draw(mainimg)
        draw.rectangle([0,0,296,128], fill=255)
        #Copy to mainimg
        ypos = (disp.xDot - im.size[1])/2
        xpos = (disp.yDot - im.size[0])/2
        print ('ypos:', ypos, 'xpos:', xpos)
        mainimg.paste(im, (xpos,ypos))
        #Draw info text
        ts = draw.textsize(name[1], font=myfont10)
        tsy = ts[1]+1
        oldy = -1
        divs = ts[0]/250
        for y in range(0, divs):
          newtext = name[1][(oldy+1)*len(name[1])/divs:(y+1)*len(name[1])/divs]
          #Print (divs, oldy, y, newtext)
          oldy = y
          draw.text((1, 1+y*tsy), newtext, fill=255, font=myfont10)
          draw.text((1, 3+y*tsy), newtext, fill=255, font=myfont10)
          draw.text((3, 3+y*tsy), newtext, fill=255, font=myfont10)
          draw.text((3, 1+y*tsy), newtext, fill=255, font=myfont10)
          draw.text((2, 2+y*tsy), newtext, fill=0, font=myfont10)
          #Draw time
          now = datetime.datetime.now()
          tstr = "%02d:%02d:%02d"%(now.hour,now.minute,now.second)
          #Draw a shadow, time
          tpx = 36
          tpy = 96
          for i in range(tpy-4, tpy+32, 2):
            draw.line([0, i, 295, i], fill=255)
            draw.text((tpx-1, tpy  ), tstr, fill=0, font=myfont28)
            draw.text((tpx-1, tpy-1), tstr, fill=0, font=myfont28)
            draw.text((tpx  , tpy-1), tstr, fill=0, font=myfont28)
            draw.text((tpx+2, tpy  ), tstr, fill=0, font=myfont28)
            draw.text((tpx+2, tpy+2), tstr, fill=0, font=myfont28)
            draw.text((tpx  , tpy+2), tstr, fill=0, font=myfont28)
            draw.text((tpx  , tpy  ), tstr, fill=255, font=myfont28)
            del draw
            im = mainimg.transpose(Image.ROTATE_90)
            drawtime = time.time()
            print ('t:draw:', (drawtime - loadtime))
            listim = list(im.getdata())
            #Print (im.format, im.size, im.mode, len(listim))
            listim2 = []
            for y in range(0, im.size[1]):
              for x in range(0, im.size[0]/8):
                val = 0
                for x8 in range(0, 8):
                  if listim[(im.size[1]-y-1)*im.size[0] + x*8 + (7-x8)] > 128:
                    #Print (x,y,x8,'ON')
                    val = val | 0x01 << x8
                    #Print (x,y,x8,'OFF')
                    #Print val
            for x in range(0,1000):
            #Print len(listim2)
            convtime = time.time()
            print ('t:conv:', (convtime - loadtime))
            ypos = 0
            xpos = 0
            disp.EPD_Dis_Part(xpos, xpos+im.size[0]-1, ypos, 
            ypos+im.size[1]-1, listim2) #xStart, xEnd, yStart, yEnd, DisBuffer
            uploadtime = time.time()
            print ('t:upload:', (uploadtime - loadtime))
        except IOError as ex:
          print ('IOError', str(ex))

Mechanical Drivers


Relays are electromechanical devices that use electromagnets to connect or disconnect plates of a switch. Relays are used to control high power circuits with low power circuits. Circuits are mechanically isolated and thus protect logic control. Relays are used in household appliance automation, lighting and climate control.

Figure 9: 1 channel relay module [5].
Figure 10: Raspberry Pi and 1 channel relay module schematics.

The example code:

#Raspberry Pi Python sample code
import RPi.GPIO as GPIO
import time
REL = 18    #GPIO04 port
print ("REL on")
print ("REL off")

Solenoids are devices that use electromagnets to pull or push iron or steel core. They are used as linear actuators for locking mechanisms indoors, pneumatic and hydraulic valves and in-car starter systems.

Solenoids and relays both use electromagnets and connecting them to Arduino is very similar. Coils need a lot of power, and they are usually attached to the power source of the circuit. Turning the power of the coil off makes the electromagnetic field to collapse and creates very high voltage. For the semiconductor devices protection, a shunt diode is used to channel the overvoltage. For extra safety, optoisolator can be used.

Figure 11: Long-stroke latching solenoid [6].
Figure 12: Raspberry Pi and solenoid schematics.

The example code:

#Raspberry Pi Python sample code
import RPi.GPIO as GPIO
import time
SOL = 18    #GPIO04 port
print ("SOL on")
print ("SOL off")
DC Motor (One Direction)

An electric motor is an electro-technical device which can turn electrical energy into mechanical energy; motor turns because of the electricity that flows in its winding. Electric motors have seen many technical solutions over the year from which the simplest is the permanent-magnet DC motor.

DC motor is a device which converts direct current into the mechanical rotation. DC motor consists of permanent magnets in stator and coils in the rotor. By applying the current to coils, the electromagnetic field is created, and the rotor tries to align itself to the magnetic field. Each coil is connected to a commutator, which in turns supplies coils with current, thus ensuring continuous rotation. DC motors are widely used in power tools, toys, electric cars, robots, etc.

Figure 13: A DC motor [7].
Figure 14: Raspberry Pi and DC motor schematics.
#Raspberry Pi Python sample code
import RPi.GPIO as GPIO
import time
DCM = 18    #GPIO04 port
print ("DCM on")
print ("DCM off")
Stepper Motor

Stepper motors are motors, that can be moved by a certain angle or step. Full rotation of the motor is divided into small, equal steps. Stepper motor has many individually controlled electromagnets, by turning them on or off, the motor shaft rotates by one step. Changing switching speed or direction can precisely control turn angle, direction or full rotation speed. Because of very precise control ability they are used in CNC machines, 3D printers, scanners, hard drives etc. Example of use can be found in the source [8].

Figure 15: A stepper motor [9].
Figure 16: Raspberry Pi and stepper motor schematics.

The example code:

#Raspberry Pi Python sample code
#From https://www.rototron.info/raspberry-pi-stepper-motor-tutorial/
from time import sleep
import RPi.GPIO as GPIO
DIR = 20   #Direction GPIO Pin
STEP = 21  #Step GPIO Pin
CW = 1     #Clockwise Rotation
CCW = 0    #Counterclockwise Rotation
SPR = 48   #Steps per Revolution (360/7.5)
GPIO.output(DIR, CW)
step_count = SPR
delay = .0208
for x in range(step_count):
GPIO.output(DIR, CCW)
for x in range(step_count):

This code may result in motor vibration and jerky motion especially at low speeds. One way to counter these result is with microstepping. Adding the code above avoid it:

MODE = (14, 15, 18)   #Microstep Resolution GPIO Pins
RESOLUTION = {'Full': (0, 0, 0),
              'Half': (1, 0, 0),
              '1/4': (0, 1, 0),
              '1/8': (1, 1, 0),
              '1/16': (0, 0, 1),
              '1/32': (1, 0, 1)}
GPIO.output(MODE, RESOLUTION['1/32'])

step_count = SPR * 32
delay = .0208 / 32
en/iot-open/getting_familiar_with_your_hardware_rtu_itmo_sut/raspberrypi_rpi/drivers_and_driving.txt · Last modified: 2020/07/27 09:00 by
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0