Home » 2012
Yearly Archives: 2012
My ultimate aim is to wirelessly network several Arduino based platforms with a centralized Raspberry Pi controller or gateway. There is much for me to learn to get this operational, not the least of which is the selection of the radio device platform I plan to use. After reviewing other devices, I have settled on the XBee, in part because of its popularity, its mesh capabilities, and it power management. To get up to speed on the Xbee, I found the tutorials at Adafruit, Sparkfun, and Parallax helpful. Some additional good references are listed at the end of this post.
As I did in the post Raspberry Pi Serial Communication: What, Why, and a Touch of How, I have a desire (obsessive need?) to do some extensive researching before diving into implementing a project. What is listed below are my research findings.
XBee Series 1 vs. Series 2
Digi’s XBee website gives you a confusing set of options for selecting radios but after reviewing multiple sources, it boils down to the XBee Series 1 vs. Series 2 for the DIY type applications I would do.
- XBee Series 1 Module (Freescale technology with 802.15.4 firmware) have a 250 kbps RF data rates and operate at 2.4 GHz. These radios use the IEEE 802.15.4 networking protocol and can perform point-to-multi-point networking. You can also do peer-to-peer networking (a form of mesh network) but this will require a firmware upgrade called DigiMesh designed specifically for the Series 1 hardware.
- XBee Series 2 Module (Ember/Silicon Labs technology with ZigBee firmware) are similar to the Series 1 in many respects but use the ZigBee standard, and therefore, have the potential for interoperability with devices made by different vendors.
Mesh networking (topology) is a type of networking where each node must not only capture and disseminate its own data, but also may serve as a relay for other nodes, that is, it must collaborate to propagate the data in the network. This gives the network self configuring, self healing, dynamic routing, and other capabilities. Wireless mesh networks can be implemented with various wireless technology including 802.11, 802.15, 802.16, cellular technologies or combinations of more than one type. The mesh enabling capability for these technologies is the routing protocol being used. There are many routing protocols being used by mesh networks today for many different types of products, but I will concern ourselves with just the XBee Series 1 and Series 2 products.
The Zigbee Alliance is a group of more than 300 companies who is responsible for publishing and maintaining the Zigbee specification. In the ZigBee network topology, there are different node types in the network (Coordinator, Router, End Device). DigiMesh is a proprietary peer-to-peer networking using a simplified topology (no need to define and organize coordinators, routers or end-nodes). Digi has a white paper that does a nice comparison of the two types of meshing products.
To further clarify the similarity/difference between Series 1 & 2, see the table below:
XBee Series 1 / 802.15.4
XBee Series 2 / ZigBee
Price shouldn’t be a driver but If you are looking for a simple point-to-point configuration, you should go with the Series 1. The Series 2 requires considerable setup and configuration.
Transmit Power Output
1 mW (0dbm)
up to 100 ft.
up to 300 ft.
2 mW (+3dbm)
up to 133 ft.
up to 400 ft.
The additional power of the Series 2 give you a ~25% increase in range.
Comes standard with 802.15.4 firmware for point-point or star topology. Requires DigiMesh firmware to mesh.
does not offer any 802.15.4-only firmware; it is always running the XBee ZB ZigBee mesh firmware
DigiMesh, while proprietary, appears to have less overhead and easier to configure
Point-to-Point, Star, and Mesh (with DigiMesh firmware)
Point-to-Point, Star, and Mesh
With a closer reading of the specs, you’ll find that the Series 1 with DigiMesh has a peer-to-peer topology but the Series 2 is hierarchical. I believe peer-to-peer is superior.
Ad hoc On-Demand Distance Vector (AODV) Routing + Hierarchical Tree Routing as last resort
Ad hoc On-Demand Distance Vector (AODV) Routing
I suspect there are more differences here but couldn’t uncover them.
RF Data Rate
RF data rate doesn’t have much practical meaning
Practical Maximum Throughput
ZigBee is significantly slower than the 802.15.4
ZugBee is a full OSI stack, and as a result, has significant overhead.
Series 2 was built for low power consumption.
After pondering this all for a bit, I believe the choose boils down to two questions:
- Is the interoperability of ZigBee important to you?
- What are the benefits of ZigBee vs. DigiMesh?
The answer to the first question is “no”. While I find ZigBee’s interoperability seductive, the practical matter is that I just don’t see that many applications that I could envision integrating into a project. Maybe some day, but not within my planning horizon. As to the second question, I don’t see any advantages to ZigBee’s imposed topology of coordinators, routers, and end-nodes. I believe the homogeneous types of nodes will give my applications the flexibility I may need. Of course, there are many other things one might want to consider, but I think this analysis is sufficient for my needs. I’m going with the XBee Series 1 Module and I’ll install DigiMesh firmware when it comes time to build meshed networks.
AT Mode vs. API Mode
XBee modules support two modes of operation – AT mode and API mode. In API mode, you communicate with the radio by sending and receiving packets. In AT (transparent) mode, the XBee radio simply relays serial data to the receiving XBee, as identified by the DH+DL address. Series 1 radios support both AT and API modes with a single firmware version, allowing you switch between the modes with the X-CTU software.
To create simple point-to-point links, XBee works nicely in AT mode without much coding. However, if your goal is to build a network consisting of more than two devices, AT mode becomes too difficult to bear. You will spend almost all the time switching in and out of AT mode, wasting time and draining batteries in the process. On the other hand, in API mode commands and data travel in specially formatted frames and no switching is necessary. Another advantage of API mode is that serial speed on transmitters doesn’t have to match – one can be configured for 115,200bps, another for 2400bps, third left with default 9600bps. There is another nice feature called remote command; you can remotely request the state of XBee module pins, for example, or change an output pin level.
It’s clear that I’ll want to work in API mode, but judging from the examples of XBee API mode code, it sure would be nice to have a library package that has designed in some basic utilities that I can leverage. That is the next topic.
One of the first packages I discovered was the Xbee Network Protocol (XNP). I was impressed by the volume and quality of the documentation. Never the less, I passed on it for two reasons. First, it isn’t as mature as other packages I discovered (and not widely used), and most importantly, it appears to be implementing mesh networking in software. Ether the author didn’t recognize that the Series 1 modules can mesh via the DigiMesh firmware (not a surprise since many websites wrongfully report that the Series 1 do not mesh) or he just wants to roll-his-own (what better way to learn about mesh routing protocols).
xbee-arduino is a C++ Arduino library for communicating with XBees in API mode, with support for both Series 1 and Series 2. Judging from the documentation, it appears that it could be ported to Raspberry Pi but it would be far easier to use something targeted for the RPi (see below). With the latest beta software, the XBee’s serial communications can be handle via SoftwareSerial, freeing up the Arduino USB for debugging. It also appears to that the author is experimenting if not already supporting DigiMesh. The package is well documented, actively maintained, and equally important, appears to be popular.
Another possibility for the Raspberry Pi is the python-xbee. This Python package is not as well documented as the xbee-arduino but does appear to be actively used and supported. The fact that its on the Python Organization’s web site as a listed package gives it some additional credibility. See this and this with respect to DigiMesh support.
libxbee is another C++ library but targeted at Linux and Windows. Fewer users and the author states “development is coming to an end” may mean this platform isn’t as strong as the others.
While not a very rigorous analysis, I believe I’ll place my bets on xbee-arduino for Arduino development and python-xbee for Raspberry Pi development. Using Python is intriguing in part because it appears to be the preferred software language for the RPi. But what if you have some C++ code, a popular language for Linux, and that you want to use some existing libraries? There are tools that could make this happen. You could use Python’s C/C++ extension modules. Also, there is the Simplified Wrapper and Interface Generator (SWIG), which is a software development tool that connects programs written in C/C++ with a variety of high-level programming languages. SWIG is used with different types of target languages including common scripting languages such as Perl, PHP, Python, Tcl and Ruby.
An unspoken consideration in my analysis is documentation availability/quality, example implementations for learning, and the availability of software libraries I could potential use. Here are some of the more interesting things I uncovered.
Tutorials (ZigBee but can be generalized to the XBee)
- XBee Series 1 Manuals – multiple document covering the Series 1 modual
- The Unofficial XBee FAQ – answers to issues that maybe getting in the way
- XBee Cookbook for Series 1 – sort of companion document to the The Unoffical XBee FAQ
- Libelium.com Development Documentation – while targeted for the meshlium device, this does have good general documenation
I started exploring how to get a LCD display operational with a Raspberry Pi (RPi). I checked out two hardware configurations: the bare bone LCD 16×2 display driven by the HD44780 chip set, which takes 6 wires to operate, and another configuration that uses a Adafruit shield that requires only 2 wires. It quickly became clear to me that I knew very little about how the LCD display works (maybe not an important topic for me) and I didn’t fully understands the RPi’s serial communications capabilities (something I must fully understand). Adafruit does give some nice tutorial that provide instructions on how to get both configurations work on the RPi, but I don’t like blindly follow tutorials without having a deeper understanding of my options and the underlining hardware. So what are the serial communication options supported by the Raspberry Pi, under what situations would you use them, and how do you use them?
So I did my research, and for the moment, I’m not going to concern myself about LCD displays but I will dive neck deep into understanding RPi serial communications. I’ll return to the LCD display topic later.
The Raspberry Pi Board
As our first step, lets take a quick scan of the interfaces we have on RPi for moving data in and out. The picture below labels the most prominent components on the RPi board.
Of course, the “lead actor” on the RPi board is the Broadcom BCM2835, System on a Chip (SoC). Broadcom bills this chip as a “multimedia applications processor for advanced mobile and embedded applications that require the highest levels of multimedia performance”. Maybe more importantly for the DIY/Hacker community is that all the firmware running on the chip is now open source.
There is another big chip, that being the SMSC LAN9512/LAN9512i USB Hub & Ethernet Controller. This is the major work horse in getting data in/out of the RPi for USB peripheral devices and IP networking.
Now note that most of the board’s other large components are for data I/O. Specifically, the HDMI, RCA Video, and Audio Out (3.5mm jack) are output only (at least for general purpose data communication perspective), and therefore, not part of our discussion. On the other hand, the USB and Ethernet ports, are powerful and widely supported serial communication devices, but I will only lightly touch the USB. I want to focus on serial communication with simple/bare-bone devices, like an LCD 16×2 display, which generally are not interface via something as sophisticated at USB or Ethernet. But the USB can be used to some for some types of device interfacing, so I will cover that as a final topic.
There are three other board components that concern themselves with data communications but will not be covered in this post:
- JTAG Header: The JTAG Header is used as a debug port. Embedded systems developer relies on debuggers communicating with chips via the JTAG to perform operations like single stepping and break-pointing. In time, I suspect people will find ways to exploit these pins for both good & evil, but for now, this is for the RPi hardware development community to use.
- CSI Camera Connector: The Camera Serial Interface (CSI) specification is a standard interface between a camera and a host processor for mobile device applications. This will be where you’ll connect cameras and video devices to the RPi.
- DSI Display Connector: The Display Serial Interface (DSI) is a specification aimed at reducing the cost of display sub-systems in a mobile device. This is commonly targeted at LCD and similar display technologies. RPi may be able to interface to some of these. Some graphical LCD/OLED displays might be attached to it. DSI would seem like a good candidate for implementing my LCD display but there is a problem. It appears the DSI isn’t supported at this time.
This leaves one remaining board input/output component standing, that be the General Purpose Input/Output (GPIO). On some electronics boards, GPIO pins have no special purpose defined, and some pins go unused by default. The RPi developer has identified a handful of digital control lines and provided services on them for you to use. By having these available can save you the hassle of having to arrange additional circuitry to provide them or implement functionality in software.
Raspberry Pi’s GPIO as a Data Bus
The first thing to get your head around, is how is data moved around the RPi, or in any general purpose computer. In the most general sense in electronics, a bus or data bus is used to move data words of any type from one place to another. Computing is based on data words made up of collections of data bits. These “words” can contain as few as four data bits and often much larger.
- Serial Bus: The least expensive method in terms of wire cost is to send the bits one at a time over a single pair of wires. This is called serial data transmission. Data words start as sets of bits that exist in parallel. In order to ship these words on a serial basis they must be converted to a serial stream of bits at the transmit end and then reconverted to a parallel word at the receive end. The common name for the circuitry that does this conversion is a SerDes circuit which stands for serializer/deserializer. Integrated circuits are more expensive when they have more pins. To reduce the number of pins in a package, many ICs use a serial bus to transfer data when speed is not important. Some examples of such low-cost serial buses include Serial Peripheral Interface (SPI), Inter-Integrated Circuit (I²C), UNI/O, and 1-Wire.
- Parallel Bus: At some point, it is more cost effective to add a wire for each bit in the word and send it in parallel on a data bus. Parallel buses have a limited data rate and distance at which they can be reliably run (more so than a serial bus). Some widely used parallel bus standards are Parallel Bus Interface (PBI), Peripheral Component Interface (PCI), Small Computer Systems Interface (SCSI), the VMEbus used in instrumentation, the Rambus interface used in memories, and others.
As the name implies, GPIO pins can be configured through software to provide some specific function or purpose within the hardware device design. The GPIO pins connect directly into the core of the processor, and the Raspberry Pi developers implemented several alternate functions for the GPIO pins. Several are desirable because of the multiple standards and types of devices you may wish to interface. On boot-up, the RPi board GPIO is in alternate function state “ALT0” and will support I2C, SPI, and UART. This is shown below:
While PCM isn’t a topic for this posting, in the figure above, you’ll also see references to PCM on pins 18 & 21. PCM stands for Pulse-code modulation and is s a method used to digitally represent analog signals. It is often used to control light intensity or motors. RPi’s native PCM capabilities are not well documented but it appears that people have has some success. Generally, to do anything useful, you need multiple PCM channels so people have resorted to adding hardware or software to get the desired functionality from the RPi. My guess is these RPi pins don’t have much of a future.
I2C, SPI, UART … Say what?
Much has been lightly covered so far, including terms like I2C, SPI, and UART. So what is the significance? Well, I2C, SPI, and UART are the heart of our quest to understand RPi’s serial communications capability. Via their exposure on the GPIO pins, these capabilities are what can be used to integrate things like LCD displays to the RPi. Now lets dive deeper into each one of them.
Universal Asynchronous Receiver/Transmitter (UART)
The Universal Asynchronous Receiver/Transmitter (UART) takes bytes of data and transmits the individual bits in a sequential fashion. The device changes processor’s parallel information to serial data which can be sent on a communication line. A second UART (maybe on another processor) can be used to receive the serial information. The UART performs all the tasks, timing, parity checking, etc. needed for the communication. The only extra devices attached are line driver chips capable of transforming the TTL level signals (0/5 volts) to line voltages (on RS-232 line this could be as +/- 25 volts) and vice versa.
Each UART contains a shift register, which is the fundamental method of conversion between serial and parallel forms. Serial transmission of digital information (bits) through a single wire or other medium is much more cost effective than parallel transmission through multiple wires. The UARTs transmit/receive one bit at a time at a specified data rate (i.e. 9600bps, 115,200bps, etc.). This method of serial communication is sometimes referred to as TTL serial communications.
Asynchronous transmission allows data to be transmitted without the sender having to send a clock signal to the receiver. Instead, the sender and receiver must agree on timing parameters in advance and special bits are added to each word which are used to synchronize the sending and receiving units. When a word is given to the UART for Asynchronous transmissions, a bit called the “Start Bit” is added to the beginning of each word that is to be transmitted. The Start Bit is used to alert the receiver that a word of data is about to be sent, and to force the clock in the receiver into synchronization with the clock in the transmitter.
For a further description of synchronous and asynchronous line communications, check out this tutorial.
Raspberry Pi’s Mini-UART
Warning: Misleading information ahead – See Warren Gay’s comments.
The Raspberry Pi actually has two UARTs. One UART is part of the internal ARM architecture of the Broadcom BCM2835 chip, in the core of the Raspberry Pi and not accessible externally. The other UART is sometimes called the RPi’s “Serial Port” (even thou the USB supports serial communications, and therefore a serial port). The serial port being reference here is serviced by a UART, sometime refereed to as the “Mini-UART” since it doesn’t appear to be very rich in functionality. It is basically be used as a console port for access to the Raspberry Pi. The serial console is a convenient way to interact with the Raspberry Pi for debugging or your network is down and it is the destination of console messages (including boot-up messages). From the Raspberry Pi pinout and the eLinux wiki, I can see that the serial port (aka Mini-UART) on the Pi is on GPIO Pin 14 (TX) and GPIO Pin 15 (RX):
Since the GPIO pins give access to the Mini UART, you can establish a serial console, which can be used to log in to the Pi, and many other things. However, normal console device communicate with -12V (logical “1″) and +12V (logical “0″) RS-232, which may just fry something in the 3.3V Pi. Even “TTL level” serial at 5V runs the same risk. See this tutorial for one example on how to build 3.3V to RS-232 levels converter with a MAX3232CPE and a few passive components.
You can reconfigure the RPi so that the Mini UART isn’t acting as a serial console and use it for outer purposes (e.g. communicate with an attached Arduino or Xbee). Using the Raspberry Pi’s serial port requires some Linux reconfiguration and the abandonment of the serial console, and potentially some level conversion, but it could be useful. The Mini-UART pins to provide access to Linux’s /dev/ttyAMA0 serial port. To be able to use the serial port to connect and talk to other devices, the serial port console login needs to be disabled and the post “Raspberry Pi and the Serial Port” shows you how.
Again, keep in mind that RX and TX lines are available on the GPIOs but operate at 3.3 volts. You’ll need a board or cable to level convert 3.3 volt UART signals to connect with other devices (e.g. RS-232, USB).
Serial Peripheral Interface Bus (SPI) — aka 4-Wire Serial Bus
The Serial Peripheral Interface Bus or SPI (pronounced as either S-P-I or spy) bus is a synchronous serial data link standard, named by Motorola, that operates in full duplex mode. SPI is much simpler than I2C. Master and slave are linked by three data wires, usually called MISO, (Master in, Slave out), MOSI (Master out, Slave in), the SCLK clock line (sometimes called M-CLK), and an optional SS (Slave Select; sometimes known as the Chip Select or CS line or Chip Enable or CE line) is the slave select or chip select line. Its optional only if you have one slave, otherwise one or more SS lines are provided. The Raspberry Pi has two Slave Select lines: CE0 and CE1.
Usually the transfer sequence consist of driving the SS line low, sending X number of clock signals with the proper polarity and phase, then driving the SS line high to end the communication. As the clock signals are generated, data is transferred in both directions, therefore in a “transmit only” system the received bytes have to be discarded and in a “receive only” system a dummy byte has to be transmitted.
Many SPI-enabled ICs and Microcontrollers can cope with data rates of over 10MHz, so transfer is much faster than with I2C. Since it is synchronous communications, it is not limited to 8-bit words so you can send any message sizes with arbitrary content and purpose. The SPI interface does not require pull-up resistors, which translates to lower power consumption. The downside is that SPI normally has no addressing capability; instead, devices are selected by means of a SS signal which the master can use to enable one slave out of several connected to the SPI bus. If more than one slave exists, one chip select line is required per device, which can use precious GPIO lines on the Master.
Inter-Integrated Circuit (I2C) — aka 2-Wire Serial Bus
Inter-Integrated Circuit or I2C (pronounced as either I-squared-C or I-2-C) is generically referred to as a “two-wire interface”. It’s a multi-master serial single-ended computer bus invented by Philips that is used to attach low-speed peripherals to a motherboard, embedded system, cellphone, or other electronic device.
I2C can be used to connect up to 127 nodes via a bus has two data wires, called SCL and SDA. SCL is the clock line. It is used to synchronize all data transfers over the I2C bus. SDA is the data line. Of course, there is a third wire being ground. There may also be a 5 volt wire to distribute power to the devices. Both SCL and SDA lines are “open drain” drivers. What this means is that the chip can drive its output low, but it cannot drive it high. For the line to be able to go high you must provide pull-up resistors to the 5v supply. There should be a resistor from the SCL line to the 5v line and another from the SDA line to the 5v line. The value of the resistors is not critical. Anything from 1800 ohms to 47K ohms used (1.8K, 47K and 10K are common values). You only need one set of pull-up resistors for the whole I2C bus, not for each device, as illustrated below:
In theory the I2C bus can support multiple masters, but most micro-controllers can’t. A master is usually a microcontroller, although it doesn’t have to be. Slaves can be ICs or microcontrollers. When the master wishes to communicate with a slave it sends a series of pulses down the SDA and SCL lines. The data that is sent includes an address that identifies the slave with which the master needs to interact. Addresses take 7 bits out of a data byte; the remaining bit specifies whether the master wishes to read (get data from a slave) or write (send data to a slave).
Some devices have an address that is entirely fixed by the manufacturer; others can be configured to take one of a range of possible addresses. When a micro-controller is used as a slave it is normally possible to configure its address by software, and for that address to take on any of the 127 possible values. The address byte may be followed by one or more byes of data, which may go from master to slave or from slave to master.
When data is being sent on the SDA line, clock pulses are sent on the SCL line to keep master and slave synchronised. Since the data is sent one bit at a time, the data transfer rate is one eighth of the clock rate. The original standard specified a standard clock rate of 100KHz, and most I2C chips and micro-controllers can support this. Later updates to the standard introduced a fast speed of 400KHz and a high speed of 1.7 or 3.4 MHz. The Arduino and Raspberry Pi can support standard and fast speeds.
The fast rate corresponds to a data transfer rate of 50K bytes/sec which is too slow for some control applications. One option in that case is to use SPI instead of I2C.
1-Wire — aka 1-Wire Serial Bus
On a 1-Wire bus (sometime refered to as a “MicroLan”), a single master device communicates with one or more 1-Wire slave devices over a single data line, which can also be used to provide power to the slave devices. Devices drawing power from the 1-wire bus are said to be operating inparasitic power mode. When operating in parasite power mode, only two wires are required: one data wire, and ground. At the master, a 4.7k pull-up resistor must be connected to the 1-wire bus. With an external supply, three wires are required: the bus wire, ground, and power. The 4.7k pull-up resistor is still required on the bus wire.
Each 1-Wire device contains a unique 64-bit code, consisting of an 8-bit family code, a 48-bit serial number, and an 8-bit CRC. Before sending a command to a slave device, the master must first select that device using its code.
How do you use I2C, SPI, UART, or 1-Wire on the Raspberry Pi?
Now that we know the what & why for serial communications options on the Raspberry Pi, how do we use them? This topic deserves technical details and examples but this post has already run too long. I’m likely to do some specific implementation in the future, but for now I’ll reference some sources of information on the web.
First, lets be clear about the RPi software distribution I’m using, since not all will be supporting all these serial communications options. I’m using Adafruit’s Occidentalis distribution (based on “Wheezy”) which comes with hardware SPI, I2C, and 1-wire support. In the Occidentalis distribution, Adafruit has included in the Linux kernel the needed drivers. SPI and I2C has been implement on the GPIO pins as outline above. RPi doesn’t have a predetermined GPIO pin assignment for 1-Wire, but Adafruit choose GPIO pin 4 for 1-Wire. Note that this unassigned GPCLK0 (General Purpose Clock Voltage) function.
Given you have the Occidentalis distribution, you can check on the installation of I2C, SPI, and 1-Wire via the following:
- To validate I2C, connect any I2C device to power, ground, SDA and SCL. Then run
sudo i2cdetect -y 0to detect which addresses are on the bus.
i2cdetectis a program to scan an I2C bus for devices. Also, you can list the I2C device drivers via the command
ls /dev/*i2c*. This illustrates that RPi supports two I2C buses, 0 and 1.
- To validate SPI, the command
ls /dev/*spi*will list two SPI devices, one each for the 0 & 1 SS lines. To go further, use the spidev_test.c tool described in Getting SPI working on the Raspberry Pi.
- Occidentalis implementation of 1-Wire isn’t done via a kernel installed driver but bitbanged. Adafruit states that the implementation is “flakier than SPI or I2C” and they don’t have any tutorials. Maybe 1-Wire should be shelved for now.
There are some good RPi SPI & I2C tutorials on Adafruits. There are others on personal blogs but generally they are scares right now.
Attach Peripherals to the Raspberry Pi
Now that we know the in’s & out’s of serial communications with the RPi, what can be done to make the physical aspects of interfacing the board easier. Dealing with the GPIO pins on the board can be a pain. One solution is the Pi Cobbler which plug the GPIO pins into a solderless breadboard via a ribbon cable. My personal favorite is the Pi Crust. In this case, the confusing layout of GPIO pins are much more clearly organized and supplied with more useful female headers. A whole development environment will be supplied via PiFace Digital and Gertboard … when they become available.
The USB Serial Ports
As promised, the final topic is the USB port. The USB can be used for some types of device interfacing, particularly if you make it look like a simple serial port to the device. The conventional serial port (not the newer USB port) is a very old I/O (Input/Output) port. It’s slow compared to newer Universal Serial Bus (USB) serial devices, but conventional serial ports are still in use and many devices you’ll hook to your RPi will want to use them. Until around 2006, most new desktop PC’s had one but has been largely replaced by the USB. Conventional serial ports are still widely used in embedded systems, but the RPi choose to use the USB. Never the less, it is possible to put a conventional serial port device on the USB bus by using a Serial to USB Adapter hardware or cables. This could be necessary for some of the hardware hacking you’ll do with an RPi. (For example, I’ll be posting a project where I’ll use the RPi’s USB to talk to a XBee radio.)
USB does synchronous communications (synchronous means that bytes are sent out at a constant rate one after another in step with a clock signal tick) and transmits in special packets like a network. Conventional serial ports are typically asynchronous (i.e. “not synchronous”). Just like a network, USB can have several devices physically attached to it, including serial ports. Each device on it gets a time-slice of exclusive use for a short time. A device can also be guaranteed the use of the bus at fixed intervals. One device can monopolize it if no other device wants to use it.
Under Linux, each and every hardware device, including USB ports, are treated as a file and call a device file. A device file allows a user to access hardware devices, but shields the users from the technical details about the hardware. (This is unlike what we’ll see for the RPi GPIO interfaces where hardware level technical details must be address directly.) Under Linux, a conventional serial port will typically have a device file such as
/dev/ttyS0, /dev/ttyS1, etc. but the USB serial ports will appear as
/dev/ttyUSB0, /dev/ttyUSB1, etc. When your device is plugged in, Linux assigns the filename as it sees fit and isn’t always predicable (it doesn’t have to be this way). If you need to know what device file your serial device is connected too (and your software often needs to know), using a combination of the commands
grep, plus some basic insight, will often do the trick.
lsusb command can show you the hubs connected to your system, but you won’t necessarily see any entries in /dev until you plug something into it, and what that entry may be will be dependent upon the type of device you are plugging in. The system doesn’t recognize new USB devices right away. It can take from a couple of seconds to as much as a minute. If I plug my Serial to USB Adapter cable, using the
lsusb command I can identify the cables . Now using
dmesg, and grepping for the “Manufacturer”, I can get the “FTDI”. Now I
grep again for “FTDI” to get the device file name “
ttyUSB0“. This is all illustrated below:
Now that I can get sound out of my Raspberry Pi (RPi), the next logical step for me is speech synthesis … Right? I foresee my RPi being used as a controller/gateway for other devices (e.g. RPi or Arduino). In that capacity, I want the RPi to provide status via email, SMS, web updates, and so why not speech? Therefore, I’m looking for a good text-to-speech tool that will work nicely with my RPi.
The two dominate free speech synthesis tools for Linux are eSpeak and Festival (which has a light-weight version called Flite). Both tools appear very popular, well supported, and produce quality voices. I sensed that Festival is more feature reach and configurable, so I went with it.
To install Festival and Flite (which doesn’t require Festival to be installed), use the following command:
sudo apt-get install festival
sudo apt-get install flite
To test out the installation, check out Festival’s man page, and execute the following:
echo "Why are you in front of the computer?" | festival --tts
date '+%A, %B %e, %Y' | festival --tts
festival --tts Gettysburg_Address.txt
Text, WAV, Mp3 Utilities
Festival also supplies a tool for converting text files into WAV files. This tool, called
text2wave can be executes as follows:
text2wave -o HAL.wav HAL.txt
MP3 files can be 5 to 10 times smaller than WAV files, so it might be nice to convert a WAV file to MP3. You can do this via a tool called
lame HAL.wav HAL.mp3
Flite (festival-lite) is a small, fast run-time synthesis engine developed using Festival for small embedded machines. Taking a famous quote from HAL, the computer in the movie “2001: A Space Odyssey”
flite "Look Dave, I can see you're really upset about this. I honestly think you ought to sit down calmly, take a stress pill, and think things over."
Depending how the software was built for the package, you find that flite (and festival) has multiple voices. To find what voices where built in, use the command
To play a specific voice from the list, use the
-voice parameter in the command
flite -voice kal "I'm now speaking kal's voice. By the way, please call me Dr. Hawking."
In my case, the default voice appears to be “kal”, which sounds somewhat like Stephen Hawking. “slt” appears to be a female version of the “kal” voice.
flite_time is a talking clock that can speak things like “The time is now, exactly two, in the afternoon.”
flite_time `date +%H:%M`
The documentation for Festival and Flite isn’t all that great but there does seem to be multiple sources. Here is what I found most useful:
I want to deliver sound from my Raspberry Pi’s (RPi) Audio Output 3.5mm jack. I’ll need to get audio drivers working on Audio Out, and to test it, I’ll need some sound files and players. I’m choosing the Advanced Linux Sound Architecture (ALSA) drivers because its widely supported and because ALSA not only provides audio but Musical Instrument Digital Interface (MIDI) functionality to Linux. I’ll also be using the popular command line MP3 players, mpg321 and the WAV player that comes with ALSA, aplay.
To get things going, I installed ALSA, a MP3 tools, and a WAV to MP3 conversion tool via the following commands:
sudo apt-get install alsa-utils
sudo apt-get install mpg321
sudo apt-get install lame
Enabling the Sound Module
Reboot the RP and when it comes back up, its time to load the Sound Drivers. This will be done via loadable kernel module (LKM) which are object file that contains code to extend the Linux kernel.
lsmod is a command on Linux systems which prints the contents of the
/proc/modules file. It shows which loadable kernel modules are currently loaded. In my case,
lsmod gives me:
snd-bcm2835 module appears to be already installed. RPi has a Broadcom BCM2835 system on a chip (SoC) which is a High Definition 1080p Embedded Multimedia Applications Processor.
snd-bcm2835 is the sound driver. If
lsmod doesn’t list the
snd-bcn2835 module, then it can be installed via the following command:
sudo modprobe snd-bcm2835
Enabling Audio Output
By default, the RPi audio output is set to automatically select the digital HDMI interface if its being used, otherwise the analog audio output. You can force it to use a specific interface via the sound mixer controls.
amixer allows command-line control of the mixer for the ALSA driver.
You can force the RPi to use a specific interface using the command
amixer cset numid=3 N where the
N parameter means the following: 0=auto, 1=analog, 2=hdmi. Therefore, to force the Raspberry Pi to use the analog output:
amixer cset numid=3 1
With this done, you should be ready for a simple test. Plug a speaker into the (RPi) Audio Output 3.5mm jack. I used a simple battery powered iHM60 iHome speaker. The jack will not deliver much power, so the speaker needs to be powered.
To test the RPi audio, you can play a WAV file (download this … excellent for user-error notification) with
mpg321 for MP3 files, or use the
speaker-test command if you don’t have a WAV/MP3 file.
speaker-test -t sine -f 440 -c 2 -s 1
mpg321 "Mannish Boy.mp3"
More on the ALSA Sound Drivers and Utilities
While ALSA is a powerful tool, it documentation appears is very weak. Also, it appears that the capabilities of ALSA drivers and utilities are very dependent on the hardware used. The best sources of documentation that I found include Advanced Linux Sound Architecture (ALSA) project homepage, archlinux Advanced Linux Sound Architecture, and ALSA-sound-mini-HOWTO.
You can find useful information in the directory /proc, which is a “virtual” file system (meaning that it does not exist in real life, but merely is a mapping to various processes and tasks in your computer).
/proc/modulesgives information about loaded kernel modules. The command
lsmod | grep sndwill list modules relevant to the sound system.
- You can check the existence of a soundcard by looking at
amixer command can provide useful information (sometimes):
- You can look at the mixer settings by typing
amixerwithout any arguments. This command lists the mixer settings of the various parts of the soundcard. The output from
amixercan greatly differ from card to card. Unfortunately you can’t find much documentation on how to interpret the out.
- The RPi doesn’t have a “Master” control only “PCM”. So commands like
amixer set Master...will not work. You must use
amixer set PCM ...
- You can mute /unmute the sound via these commands:
amixer set PCM muteand
amixer set PCM unmute
- As of August 2012, there appears to be a known bug in RPi ALSA driver that ignores volume settings at the start of playback and always plays at max volume. Therefore, commands like
amixer set PCM 50% unmutewill not set the volume to 50%, at least until this bug is fixed. Maybe this isn’t really a bug but a limitation of the hardware because there is a workaround for this …. see below.
The RPi built-in sound chips don’t have a “master volume” control, and as a result, you must control the volume via software. I guess the RPi views itself as a preamplifier (preamp) and volume controls would be supplied down stream. ALSA provides a software volume control using the softvol plugin.
/etc/asound.conf file is a configuration files for ALSA drivers (system-wide). The main use of this configuration file is to add functionality. It allows you to create “virtual devices” that pre or post-process audio streams. Any properly written ALSA program can use these virtual devices as though they were normal devices. My RPi
/etc/asound.conf file looks like this:
For most changes to
/etc/asound.conf you will need to restart the sound server (ie.
sudo /etc/init.d/alsa-utils restart) for the changes to take effect.
I attempted to implement the software volume controls outline in a softvol how-to that I found, but I couldn’t get it to work. I did some additional digging, and I found a solution buried within a python script for a Adafruit project. The following works for controlling the volume (in this case, reducing the volume to 80% of maximum):
amixer cset numid=1 -- 80%
Note that you can use this command to change the volume while sound is being played an its effect takes place immediately. Also, I noticed that once the volume has been adjusted, its effect remains even after a reboot.
WAV and MP3 Conversion
- To convert from WAV to MP3:
lame input.wav output.mp3
- To convert from MP3 to WAV:
mpg321 -w output.wav input.mp3
While you can get ALSA working on the Raspberry Pi, it appears only partly supported, maybe buggy, and poorly documented. If you just want to simply get sound out of the device (like I do), you’ll be fine. But if you have some desire to do some sound processing with ALSA, your likely to be very frustrated.
This specific post has gotten about 25% of all the viewings of my blog. I’m not sure why this is the case but I speculate that there are many people tying to make RPi into a Media Player and looking for answers to their technical problems.
At this point in time, others have done some additional postings and they are more instructive than my post. You should check out:
I’m presently using Dropbox as a service for quick & easy movement of files between multiple PCs I use. Its copy & paste operation is very intuitive on a Windows PC. I would like the same on the Raspberry Pi (RPi), particularly for moving files from my PC to the RPi. I wanted the same utility on my RPi, but at the same time, I want the Linux command line paradigm supported and not be force to run X Windows on the RPi.
I did some searching and found things like Dropbox’s Linux distribution (which I wasn’t confident would work “out of the box” for the RPi’s ARM architecture, but source is provided), GoodSync or Owncloud (which wouldn’t access my existing Dropbox files but instead create an alternative), python or bash shell based up/down loaders (appears to behave like a simplified FTP tool), or the Secure SHell File System (SSHFS) based approach (the PC’s Dropbox directory is mounted on the RPi).
While the Dropbox’s Linux distribution is likely the ultimate way to go, I didn’t want to commit myself to the effort it would potentially require. I settled on the SSHFS based approach. I’m running my RPi headless and access it via my PC using Cygwin/X and Secure Shell (ssh). With the SSHFS approach, I could make the Dropbox directory available for mounting at boot-up or mount it at will. I only envision using the RPi-based Dropbox when I’m doing development and I will be doing that from my PC. So this SSHFS approach seems fine for the way that I operate.
The SSHFS approach means files will not really be replicated on the RPi, like Dropbox does. The files will reside within my PC’s Dropbox folder (and replicated on my other PCs via the Dropbox service) but accessible by the RPi via the SSHFS file mount. This means I can’t have any applications I run on the RPi depend on files located in its Dropbox directory since it may not be always mounted. I’m OK with this limitation, and in fact is consistent with the ad-hoc purpose I have for the Dropbox directory.
Installation Required on the PC
For me, nothing needs to be done here. I already have Dropbox running on my PC, and via Cygwin/X, I have the foundations required for the host side of the SSHFS solution. If you need help with this, signup for Dropbox here and find out how I’m using Cygwin/X here.
Installation Required on the RPi
On the client side of the solution, you’ll need to install SSHFS and FUSE. FUSE is the user-space filesystem framework and is the foundation on which SSHFS resides. FUSE allows user-space software, SSH in this case, to present a virtual file system interface to the user; something generally only done by the Linux kernel. SSHFS connects to the remote system and provide the look and feel of a regular file system interface for remote files. On the RPi, install SSHFS via the command:
sudo apt-get install sshfs
FUSE appear to be already installed on the RPi or maybe comes with SSHFS. Next you need to add required users to the FUSE usergroup. In my case, that is the user pi. You can see the existing groups pi is part of via the command
groups pi. You can validate that the FUSE user group has been created by using the command
cat /etc/group | grep fuse. To add pi to the FUSE user group, use the command:
sudo gpasswd -a pi fuse
The fuse group lets you limit which users are allowed to use FUSE-based file systems, in my case the Dropbox. This is important because FUSE installs setuid programs, which always carry security implications.
Configuring the Dropbox File System
Now its time to make your Dropbox directory on the RPi, and mount it to the PC’s instance of Dropbox. On the RPi, use this command to create the Dropbox:
The next thing to do is to make sure that you can connect to the PC via ssh. When I installed Cygwin, my focus was on using it as an X Server and making ssh connections from the PC to RPi. I never tried the inverse (connect from the RPi to the PC) and that is what SSHFS is effectively doing. So check for two things:
- Is the ssh server running on the PC? You can check for its status via the command
cygrunsrv -Q sshd. In my case it was running, so its fine.
- Is the port used by the ssh server on the PC open? You’ll need to open SSH port 22 for ssh services to work. You can check its status by attempting to use it. In my case, this was
ssh Jeff@HomePC.home. If this command appears to hang or time out (as it did for me), the port is likely blocked. You’ll need to go to your Windows Firewall and open port 22.
There is another Cygwin sublimity that has to be taken into consideration. When using the Cygwin, Windows drive letters are mapped to a special directory. In my case, the Dropbox directory appears to Cygwin to have the following path:
With this all addressed, reboot the RPi, and then you can now fire up you RPi Dropbox via:
sshfs Jeff@HomePC.home:/cygdrive/c/Users/Jeff/Dropbox ~/Dropbox
After you supply the PC’s password, you should now be able to access the Dropbox directory on the PC. If you wish, you can remove the file system connection to the PC via the command:
fusermount -u ~/Dropbox
This connection will stay established as long as you don’t do the
fusermount -u or reboot the RPi. If you wish to mount the file system upon boot-up, and avoid executing the
sshfs when you log-in, you can follow the procedure outline in the article that initially inspired me: Dropbox on Raspberry Pi via SSHFS
Something to Keep in Mind
While for the most part, moving between Windows/DOS and the Linux file systems isn’t a problem, there is one thing to remember. Windows-based text editors put one set of special characters at the end of lines (i.e. carriage return and line break = ‘\r\n’), while Unix/Linux puts other characters (i.e. line break = ‘\n’). This odd anomaly is normally harmless, but some applications on a Linux cannot understand these characters and can cause Linux to not respond correctly.
The best example of Linux behaving badly (and the only one I know) is the execution of “shebang” or the “#!…” at the top of a bash, python, perl, etc. script. If you edit these files in DOS, then move them to Linux, shebang will stop working. Editing them under DOS is the origin of the problem, since a DOS based text editor will inject the extra carriage return character at the end of the text line.
To fix this problem, you can quickly convert an ASCII text file from DOS format (carriage return and line break) to the Unix format (line break), you can use the tool
dos2unix. Run this utility on the effected file and shebang should work once again.
At its foundation, SSH functions as a protocol for authenticating and encrypting remote shell sessions. SSH can be thought of as much more than just a secure shell. Using SSH’s foundation, SSHFS creates a new capability. To learn more, check out the link SSH: More than secure shell.
Key sources I consulted to write this include:
In the projects I envision for the future, I’ll be using my Raspberry Pi (RPi) as a gateway/server/controller for several other devices. There is likely to be a need to generate status reports/messages and mail them out. It could be as simple as a notification that the deck lights have been turned-on. I don’t need a full fledged mail client on the RPi to receive mail or manage a mailbox, just a command line utility to send email. Also, I would like to send short text messages via (SMS) to my cell phone. Linux does have a nice solution for this.
You do need an established email account with some email provider. I want to keep my personal email and my RPi’s email separate so I setup a special email account on gmail. This will be used only by my Raspberry Pi’s (or other intelligent devices). There exist some open SMTP relay mail servers (mail servers that will not require a login nor a password) but many open mail relays have become unpopular and closed due to their exploitation by spammers and worms.
I installed SendEmail on my RPi via this command:
sudo apt-get install sendemail
When I ran sendEmail the first time, it complained about some missing libraries. I installed the missing libraries and this cleared the error. Clearly, the sendEmail package needs some work since this dependency should have been taken care of by
I ran it again using this command:
sendEmail -f pi@RedRPi -t email@example.com -u "Test Email from RedRPi" -m "My test message." -s smtp.gmail.com:587 -o tls=yes -xu my_user_name -xp my_password
With this, sendEmail threw an error message:
invalid SSL_version specified at /usr/share/perl5/IO/Socket/SSL.pm line 332
I did a web search and found that this is a reported bug within sendEmail (bummer), but I also found a simple patch for the problem (lucky break). I applied the fix, executed the command again, and succeeded in sending the email.
One of the key parameter used here is the SMTP mail relay specified in “
-s smtp.gmail.com:587“. In this case, Gmail uses port 587 for relay email. The default port to use is 25 but not all email servers use this port.
Another key parameter is “
-o tls=yes“. This specifies that the Transport Layer Security (TLS) protocol will be used to provide communication security over the Internet. This is important since your including a plain-text password in the command.
Another messaging mechanism that I plan to use is Short Message Service (SMS). To do this, you can use a SMS gateway which will transform an email into an SMS message. The down side is that there isn’t a single gateway but one for each of the cellular carries.
Here is an example for AT&T cell phones:
sendEmail -f pi@RedRPi -t firstname.lastname@example.org -u "Test Email from RedRPi" -m "My test message." -s smtp.gmail.com:587 -o tls=yes -xu my_user_name -xp my_password
The Raspberry Pi Linux distribution I’m using is Adafruit’s Occidentalis. It supports WiFi out of the box and appears easy to configure. But as noted by Adafruit, adding peripherals to the RPi may increase the loading on the power supply to your board and this, in turn, may affect the voltage presented to the RPi.
This is clearly the case, even for the tiny OURlink WiFi (802.11b/g/n) USB Adapter (uses the RTl8192cu chip which is supported by Debian Linux) I purchased from Adafruit. When I plugged it into the RPi, it became unstable and crashed. Adafruit advises that you can over come this by attach the RPi’s USB port to a powered hub. (Note that all USB hubs aren’t powered or powered sufficient, and therefore, not all are recommended. I used a Dynex 4 Port Hub with a 5V 2.1A power adapter and all seem fine.) If you find using a using a USB hub completely unacceptable, you could make some RPi board modifications to the polyfuses, but this isn’t the “official/supported” approach for this power problem …. but first …. see the Epilogue below.
My First Attempt (Unsuccessful)
Once I got the RPi USB port properly powered, I followed the Adafruit’s instructions. I updated the
/etc/network/interfaces file with the following:
########## DID NOT WORK FOR ME ########## # The loopback network interface auto lo iface lo inet loopback # The primary (wired) network interface iface eth0 inet dhcp # The wifi (wireless) network interface auto wlan0 allow-hotplug wlan0 iface wlan0 inet dhcp wpa-ssid YOUR_SSID wpa-psk YOUR_WEP_KEY
ifconfig -a and got the following:
This tells me that Linux sees the WiFi device and assigned it device name
wlan0. It also says there isn’t an IP address assigned and no data is moving. Appears that network interface
wlan0 isn’t running so I tried bring it up with
sudo ifup wlan0 and I got the following:
No IP assigned … now what?
This Worked … But
After the typical thrashing about, it came to me that I’m not using WAP security (which is implied by the
/etc/network/interfaces file content) but I’m using WEP. I did some web searching and found a site that claimed to address Debian WiFi WEP configuration. This provided me the needed command syntax for the solution. I updated the
/etc/network/interfaces file with the following:
# The loopback network interface< auto lo iface lo inet loopback # The primary (wired) network interface iface eth0 inet dhcp # The wifi (wireless) network interface auto wlan0 allow-hotplug wlan0 iface wlan0 inet dhcp wireless-essid YOUR_SSID wireless-key YOUR_WEP_KEY
I then ran
sudo ifup wlan0 to start the wireless networking (Note: you can use
sudo ifdown wlan0 to turn-off the wireless network). This time DHCP discovery appeared to work. I then ran
ifconfig -a giving me the display below with an assigned wireless IP.
The wireless device now has an IP address and data seems to be flowing. In an effort to further convince myself that the WiFi was working, I disconnected the wired ethernet connection and attempted to re-login in via
ssh -X pi@RedRPi.local, over the wireless interface. This failed, giving the message:
ssh: Could not resolve hostname RedRPi.local: hostname nor servname provided, or not known
Working For Sure
I suspected (after more thrashing about) it was Ssh or Avahi/Bonjour or both that was getting in the way. So I did the following:
- I cleaned out the
~/.ssh/known_hostsfile on the PC from which I’m accessing the RPi (I’m using Cygwin with Openssh). With the entries in the file removed ssh keys would need to be recreated on next login.
- I then logged into the RPi in via
ssh -X pi@RedRPi.local.The login created an entry the
~/.ssh/known_hostsfile on the PC.
- Using vi, I edited the
~/.ssh/known_hostsfile. I duplicated the one existing record but changed the IP address to the wireless address.
- I restarted the openssh on the PC. (I terminated all the Cygwin window and restarted them. I could get anything else to work short of a PC reboot).
- I then logged in using
ssh -X email@example.com. Now I’m wireless!!
~/.ssh/known_hosts file looks like this:
I have found that if I don’t use a USB powered hub and I plug in the OURlink WiFi (802.11b/g/n) USB Adapter while the RPi is up and running, the RPi will crash. The good news is that, once the RPi reboots, it runs fine without the powered hub.
So, go ahead and use the WiFi USB Adapter, without the powered hub, but make sure the adapter is plugged in when you boot up …. problem solved!