Category: Raspberry Pi

Information about Raspberry Pi

  • Raspberry Pi WiFi Automatic Connection

    By default, RPi doesn’t connect to the WiFi automatically, which is annoying, especially when you don’t have keyboard/mouse/screen connected.

    You can fix this by:

    First connect to the WiFi using the WiFi app. This will include the following lines in /etc/network/interfaces:

    allow-hotplug wlan0
    iface wlan0 inet manual
    wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
    iface default inet dhcp

    Then edit /etc/wpa_supplicant/wpa_supplicant.conf

    ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
    update_config=1
    network={
            ssid="SSID"
            psk="pre-shared-key"
            proto=RSN
            key_mgmt=WPA-PSK
            pairwise=TKIP
            auth_alg=OPEN
    } 

    You can repeat the network block for other networks you’d like to automatically connect to.

  • Raspberry Pi – easier access

    For the Debian builds (Raspbian), the default username/password is pi/raspberry.

    Once logged in, you can create new users by:

    sudo adduser yourname

    You can enable the root user by (the same procedure will reset any user’s password:

    sudo passwd root

    If you’re using ssh, then setting up keys saves a lot of time.

  • RGPIO and PiBoard

    How to use RGPIO with PiBoard.
    This guide uses a PiBoard with the following components:
    • EA DOG-M LCD (on pins 17,0,11,22,23,24,25) in 3.3V mode)
    • LCD Backlight (on pin 18)
    • Buttons connecting pins 7,8,9,10 to ground when pressed
    • PCF8563 I2C Real time clock (with super-capacitor power backup)
    • DS1621 I2C Temperature device
    • DS18B20 1-Wire Temperature device
    To use RGPIO from python, we open the /dev/rgpio device as an unbuffered file in r/w mode:
    rgpio=open('/dev/rgpio','r+',0)
    # r+ means read/write; 0 means unbuffered
    we can then write to and read from this file to control the PiBoard.

    LCD – EA-DOG-M

    RGPIO does the basic initialization from the C command to get the LCD running in 4-bit mode with the appropriate pins, but the EADOG-M screens need additional initialization according to whether you run in 3.3V or 5V mode.
    \C29 – Set 4-bit mode and instruction set 1
    \C15 – Set bias for 3-line LCD
    \C55 – Booster (for 3.3V) on, Contrast in follower mode
    \C6E – Follower ccontrol
    \C72 – Set Contrast
    \C28 – Set 4-bit more and instruction set 0
    rgpio.write('L17,0,11,22,23,24,25C')
    rgpio.write('LD\C29\C15\C55\C6E\C72\C28')

    LED Backlight (EA LED55x31-G)

    The EA LEDs are coordinated with the LCDs but use completely separate pins. The PiBoard lets you choose between a 3.3V or a 5V supply using the appropriate current-limiting resistor.
    The LED is controlled through a NPN transisitor driven by pin 18. The Raspberry Pi has hardware PWM enabled on pin 18 and this can be used to control the LED brightness. RGPIO supports both software and hardware (pin 18 only) PWM, but the hardware version is much more efficient.
    #Set LED to 50%
    rgpio.write('W50,18C')

    Buttons (Tyco 6x6mm)

    When the buttons are pressed, the GPIO port is shorted to GND. For the buttons to work, they need a pull-up resistor. The PiBoard has space for a separate pull-up resistor, or we can use the CPU’s internal pull-up capability using P7U8U9U10U.
    To get the pin settings we use RGPIO’s pin change interrupt to tell us when the pin is grounded.
    rgpio.write('P7U1,7L')  # Initialize pull
    rgpio.write('P8U1,7L')  # up and get repeated notifications
    rgpio.write('P9U1,7L')  # when pin Lo
    rgpio.write('P10U1,7L')
    To see what is going on, we have two options: read in a polling loop, knowing we may get a blank line because there is nothing waiting:
    while True:
        inLine=rgpio.readline()
        # Now process the line
    Or we can get RGPIO to send us a signal to tell us something is waiting.
    import signal,os
    def IOSignal(signum,frame):
        inLine=rgpio.readline()
        # Now process the line
    
    signal.signal(signal.SIGIO,IOSignal) # call IOSignal on SIGIO
    pid=os.getpid()                      # Get PID of this process
    rgpio.write('%dS'%pid)               # tell RGPIO to send SIGIO here
    while True:
        time.sleep(1)                    # just loop asleep waiting...

    I2C Clock

    To give the Raspberry Pi a clock, you can either be connected to the internet (in which case, the very accurate internet time is available), or you need to provide an external clock. We do this with an I2C Real Time Clock chip.
    The I2C bus is a very convenient mechanism to communicate between components. It needs 4 connections: VDD, GND, SCL, SLA. Many CPUs (including the Raspberry Pi’s) have I2C communications built in. On the Raspberry Pi the I2C components are connected to I2C channel 1. Each I2C component has an Id: the DS1307 and DS1337 are on 0x68, the PCF8563 is on 0x51.
    There are device drivers for many of the available RTC chips (and other I2C chips), and you can use these if you want to, but they are not always as flexible as you might want. RGPIO provides another interface.
    To set the clock on PCF8563 from the system time, use:

    t=datetime.datetime.today()
    sec=toBCD(t.second)
    min=toBCD(t.minute)
    hour=toBCD(t.hour)
    date=toBCD(t.day)
    month=toBCD(t.month)
    year=toBCD(t.year % 100)
    day=t.weekday()
    rgpio.write("I1N0x51D2,%d,%d,%d,%d,%d,%d,%dW"%(sec,min,hour,date,day,month,year))
    To get the clock from PCF8563 and set the system time, use:
    import re, os
    rgpio.write("I1N0x51D2,7R")
    reI2C=re.compile('I2C *([^@]*)@([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*) *([^ ]*)')
    inLine=rgpio.readline()    # If using signal handling, this code goes there
    event=reI2C.search(inLine) # Use Regular expressions to unpack the input
    sec=int(g(3))&0x7f         # The PC8563 doesn't leave the unused bits zero
    min=int(g(4))&0x7f         # so we have to clear them ourselves
    hour=int(g(5))&0x1f
    date=int(g(7))&0x3f
    month=int(g(8))&0x1f
    year=int(g(9))+2000
    newDate=datetime.datetime(year,month,date,hour,min,sec)
    os.popen("date -s %s"%newDate)
    The DS13x7 series are similar but some detail differences. There are other I2C Real-time-clocks that can be used.

    I2C Thermometer (DS1621)

    The DS1621 needs initializing so it starts measuring the temperature. Thereafter the temperature can be read whenever required.
    rgpio.write('I1N0x48D0xEEW') # Command 0xEE starts conversion
    rgpio.write('I1N0x48D0xAA,2R') # Read 2 bytes to get the temperature
    inLine=rgpio.readline()
    event=reI2C.search(inLine) # Use Regular expressions to unpack the input
    temp=(event.group(3)+256*event.group(4))/256

    This temperature is accurate to 0.5C, and you can greater accuracy (about 1/16C) by reading from locations A8 and A9 and using a formula in the specification.
    Note: PiBoard has the DS1621 located next to the Timekeeping Crystal. Time Crystals typically have a fixed frequency that varies according to the temperature. This thermometer can be used to improve the accuracy of the clock.

    1-Wire Temperator sensor (DS18B20)

    The 1-Wire bus uses VDD, GND and DQ (the signal wire). (And some devices will work without the VDD connection.) Linux has 1-Wire modules available and you can use these, however, there are some problems with usability:

    1. The w1-therm module requires reading a file /sys/bus/w1/devices/28-xxxxxxxxxxxx/w1-slave. The problem is that reading this file takes a long time (about 1 second) – this is because it has to initiate a temperature conversion, and must when way for the conversion to complete – which is between 94ms and 750ms, depending on the conversion accuracy. 1 second is much too long to wait for a system with a user interface.
    2. the w1-gpio module can also be used but writing to and reading from /sys/bus/w1/devices/28-xxxxxxxxxxxx/rw. The problem here is that if the sensor goes off line, file operations to the rw file hang.
    3. The built-in support for 1-wire is only available on pin 4. You can have multiple devices on that one pin, but a single pin is still a little limiting.

    RGPIO provides an alternative interface to 1-Wire devices.

    rgpio.write('P4U')      # Set pin 4's pullup - essential for 1-wire operation
    rgpio.write('O4P')      # Set pin 4 as 1-Wire pin
    rgpio.write('O0D')      # Tell RGPIO there is only one 1-Wire device
    rgpio.write('O0x44C')   # Start temperature convertion
    rgpio.write('O0xBEC2W') # Read the temperature
    reW1=re.compile('W1(:[0-9a-fA-F\-\.]*)* *(=*) *([^ ]*) *([^ ]*) *([^ ]*)')
    inLine=rgpio.readline() # Get the result
    event=reW1.search(inLine)
    temp=(int(event.group(3),16)+256*int(event.group(4),16))/16.0

    If you have more than one device on the bus, you can do the following:

    rgpio.write('P4U')      # Set pin 4's pullup - essential for 1-wire operation
    rgpio.write('O4P')      # Set pin 4 as 1-Wire pin
    rgpio.write('OL')       # List available devices
    inLine=rgpio.readline() # Get the first found device (blank if none)
    event=reW1.search(inLine)
    w1Device=event.group(1)[1:]  # Get the device name
                                 # format is ff-nnnnnnnnnnnn.cc
                                 # ff is family, n..n is number, cc is checksum
    w1Family=w1Device[0:2]
    w1NC=w1Device[3:7]
    w1NB=w1Device[7:11]
    w1NC=w2Device[11:15]
    w1Id="%x,0x%x,0x%x,0x%xD"
    rgpio.write("O%s"%w1Id)      # Set this device as the one to use
    rgpio.write('O0x44C')        # proceed as above
    ...
  • PiBoard – an expansion board for Raspberry Pi

    PiBoard was designed to be a compact expansion for the Raspberry Pi with buttons, and LCD screen and space for time and temperature components and connectors for further expansion: PiBoard v1.0 Board, PiBoard v1.0 Schematic.

    Components

    • Full 26 pin connector
    • LCD
    • DisplayTech S162GOD with contrast potentiometer
    • Electronic Assembly EA-DOG-M with or without LED backlight in 5V or 3.3V mode
    • 4 Buttons (TYCO)
    • Reset button (not Raspberry Pi V1)
    • I2C clock chip eg DS1307, DS1337 or PCF8563
    • I2C temperature sensor eg DS1621
    • 1-Wire (eg for temperature sensor DS18B20)
    • External connector for Gnd, 5V, GPIOs 14, 15
    • Header and External connector for GPIOs 28,29,30,31
    • Zener diode protection for inputs

    V1.0 has a number of faults, but does work:

    1. Either (a) the Raspberry Pi RCA video connector needs to be trimmed; or (b) [if not using the EA-DOG-M LCD, the PiBoard need sto be trimmed.
    2. The capacitors across the buttons are best omitted
    3. The location of the 1-Wire (Gnd, 3.3V, GPIO4) connector is in the way of a PiBoard capacitor.
    4. The buttons are too close to the EA-DOG-M (placement is tricky, but not impossible)

    V1.0a is being designed to correct these and other shortcomings.

  • RGPIO – LCD Screens

    Common Character LCD Screens can be controlled with between 6 and 11 GPIO pins. RGPIO L-Mode contains simple support for a 6-pin or 7-pin solution. The 6 or 7 pins are D4,D5,D6,D7,EN,RS with an optional RW (for most uses RW can be hard-wired to GND).

    Initialize RGPIO with the ports:

    L<RS>,<RW>,<EN>,<D4>,<D5>,<D6>,<D7>D

    For the PiBoard, the initialization is (RW is hardwired to GND, and we use 0 for that pin:

    L17,0,11,22,23,24,25C

    The initialization will reset the the screen and clear it.
    Some screens need additional initialization which need to be sent to the screen separately.
    To write characters to the LCD:

    LDHello world

    To send special codes, use \Cxx or \Xxx where xx is a hexadecimal pair. \C for a command (RS=1) and \X for a character (RS=0). For example, to write to the screen’s top-left, prefix with \C80. (the beginning of row 2 is often \CA0 on a 2-line screen).
    Special positioning commands include \C01 (clear screen); \C02 (go to top left)
    When sending \ using a command shell or programming language that uses \ as an escape character, you will need to double it:

    ./p LD\\C80

    These screens usually have a built-in font with most of the characters you need, and with the ability to add your own characters at code positions 00-07 or 00-0F.
    To add an elipsis at character position 00 (6 blank rows, one row of alternate bits,1 blank row):

    LD\C40\x00\x00\x00\x00\x00\x00\x15\x00\xC80

    To print a short line of elipsis characters

    LD\x00\x00\x00\x00\xC80
  • RGPIO Port handling

    RGPIO commands for simple ports (P-mode) are:

    Command Comment Example
    P<port>+ Set port Hi (turn it on) P4+
    P<port>- Set port Lo (turn it off) P11-
    P<port>R Set port input and read value P0x12R
    P[n,]<port>L Report when port goes Lo
    Cache n events – default=0, report once only.
    P8L
    P[n,]<port>H Report when port goes Hi
    Cache n events – default=0, report once only.
    P2,8H
    P[n,]<port>L Report when port changes
    Cache n events – default=1; if n=0, once only.
    P0,8C
    P<port>l Set port Hi and time how long before it goes Lo P8l
    P<port>h Set port Lo and time how long before it goes Hi P8l
    P<port>U Turn on the internal pullup on the port P8U
    P<port>u Turn off the internal pullup on the port P8u
    Command Response
    P4R P4:on
    This reports the current state of the port.
    P8L E8:off 2013/03/15 14:21:35 (812355433)
    After an L command is sent, RGPIO watches for the port to change (using a hardware interrupt). The output will be available after the event has occured. The output can be pollled for, or a signal can be set. The output indicates the port, and state, the time and an incrementing timestamp for the event.
    P7h E7:on t=56000
    After an h command is sent, RGPIO sets the port Lo and then times how long (in nanoseconds) it takes for the port to go Hi. The output can be pollled for, or a signal can be set. The output indicates the port, and state, the elapsed time.
  • Raspberry Pi – RGPIO

    RGPIO is a Raspberry Pi installable module that provides a device driver interface GPIO (General Purpose Input/Output).

    Installing RGPIO

    Put rgpio.ko in /lib/modules/3.6.11+/kernel/drivers/rgpio
    Add rgpio to the list of modules to load at startup in /etc/modules
    Run depmod to update modprobe’s list of module dependencies.

    What RGPIO looks like

    RGPIO creates a device: /dev/rgpio

    This device is a character mode device that you can write text strings to and read text strings from. These strings tell RGPIO what to do, and tell you what RGPIO has found.

    For testing, it is useful to set up a small script – I call it p containing:

    [ -c /dev/rgpio ] && echo $@ > /dev/rgpio && cat - < /dev/rgpio

    ([ -c /dev/rgpio ] stops anything being written to a non-existent device.)

    Then you can use rgpio by entering commands as follows, and the output will be shown immediately:

    user@rpi:/home/me# ./p P14R
    RGPIO 14:on

    Help is built in:

    user@rpi:/home/me# ./p H
    {P|O|I|W|L}     set mode: PIN,One-wire,I2C,PWM,LCD
    ?               show Help
    pidS            Sending SIGIO to process when new output is added (pid=0 to cancel)
    {P|O|I|W|L}?    show Help for each mode
                    #,% can be decimal, 0x Hex or 0b Binary

    RGPIO Modes

    P mode: control the individual GPIO pins. This includes reading from and writing (Lo or Hi) to the pin, watching for changes in the read-state, and setting the internal pull-ups for each pin.

    W mode: PWM control – hardware (on Raspberry Pi, this is only on pin 18) or software modes.

    L mode: control a parallel character LCD device

    I mode: seek, query and control I2C devices

    O mode: seek, query and control 1-Wire devices

    Here are some Python examples using RGPIO on the PiBoard

  • Raspberry Pi – Setting up driver/module development environment

    Abstract: This post gives the steps required to set up a cross-compiling development environment for Raspberry Pi.
    The base platform is a Linux computer (examples are given for a SuSE 12.2 installation running as a virtual computer on SuSE 12.2 using KVM as the hypervisor).
    1. Installing some prerequisites:
      1. git (use to access the source code repositories)
        On SuSE, use YaST to install if it’s not already there
        On Debian, use apt-get git to install
      2. Create your base directory: we will use ~/Projects
    2. Installing a cross-compiler:
      1. Download and compile the latest crosstool-ng from crosstool-ng.org (you will need to be root for the final make install)
        wget crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.17.0.tar.bz2
        tar -xvz crosstool-ng-1.17.0.tar.bz2
        cd crosstool-ng-1.17.0
        ./configure
        make
        make install
      2. Configure a cross compiler
        mkdir ~/Projects/souce/ccc;cd ~/Projects/souce/ccc
        ct-ng menuconfig

        The cross compiler configuration requires the following settings:

        Section Setting
        Paths and misc [x] Try features marked as EXPERIMENTAL)
        (/tools/x-tools/${CT_TARGET}) Prefix directory
        Target options Target Architecture (arm)
        Endianness: (Little endian)
        Bitness: (32-bit)
        Operating System Target OS (linux)
        Linux kernel version (3.?.?) – use the correct value!
        Binary utilities binutils version: choose the latest not marked EXPERIMENTAL
        C Compiler [x] Show Linaro vesions (EXPERIMENTAL)
        gcc version – choose one of the Lenaro versions: 4.6-2-12.04 does work
        Exit from ct-ng menu configuration.
      3. Build a cross-compiler.
        As root (or with sudo prefix):
        ct-ng buid
        Note: if build fails with a message about Static linking impossible, edit the .config file and change CT_WANTS_STATIC_LINKING=n and try again.
        The compiler will be in /tools/x-tools/arm-unknown-linux-gnueabi
        The build takes quite a while… (42 minutes on a single core of i5-2500 at 3.3GHz)
    3. Installing the Linux Kernel Sources (which are required for compiling modules and drivers):
      1. Create a source directory ~/Projects/source an running the following commands from that directory:
      2. git clone git://github.com/raspberrypi/linux.git
      3. git clone git://github.com/raspberrypi/firmware.git
      4. git clone git://github.com/raspberrypi/tools.git
      You will now have three directories under ~/Projects/source: linux, firmware and tools.
    4. Set the right version of the Linux Kernel – which needs to be the same version you are using on the RaspberryPi.
      You can find the version RaspberryPi is running using the command:

      raspberrypi:~> uname -sr
      Linux 3.2.27+
      You can see the available versions of the Linux kernel by:
      rpidev:~> cd ~/Projects/source/linux
      rpidev:linux> git branch -r
        origin/HEAD -> origin/rpi-3.6.y
        origin/master
        origin/rpi-3.2.27
        origin/rpi-3.6.y
        origin/rpi-patches
      You can set the version to rpi-3.2.27 using:
      git checkout rpi-3.2.27
      • ARM System Type=Broadcom BCM2708 family
      • When changing the kernel version, you need to initialize it. This process will remove the .config file, so it’s a good idea to keep a copy in (eg) ../linux.config
        make mrproper
        To set the configuration, use one or more of the following
        • Copy from your backup: cp ../linux.config .config
        • Get it from the Raspberry Pi ssh root@rpi zcat /proc/config > .config
        • Check the configuration: make ARCH=arm CROSS_COMPILE=/tools/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- oldconfig
          This will prompt you to confirm any new options – use the default except for:
      • Edit the configuration: make ARCH=arm CROSS_COMPILE=/tools/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- menuconfig
        Some areas you might want to configure (especially if you’re planning to use this kernel on the device):

        • Floating Point emulation: you need one emulation set
        • Networking support (enable for more, disable for smaller)
        • Device drivers (enable for more, disable for smaller)
      • You can check the version your source code tree is at using:
        make kernelversion
      • Build the kernel using: (-j2 means use 2 core in parallel)
        make ARCH=arm CROSS_COMPILE=/tools/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- -j2
      • To compile my_module, use the following makefile:
        obj-m:=mymodule.o
        And compile with:
        make ARCH=arm CROSS_COMPILE=/tools/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- -C ~/Projects/source/linux SUBDIRS=`pwd` modules