Having corrupted my SD card again (deep sigh), it’s time for a complete rebuild again. I thought this would be an opportunity to update these notes.
The first task is to download an image and write to an SD card. Previously I downloaded Raspbian (Kernel 3.12, Release 2014-12-24) from raspberrypi.org. I used Win32DiskImager to write this to an 8GB SD card. This time I used the Noobs image and selected Raspian OS (although, having done this, I would not recommend Noobs because the two stage boot makes things rather more difficult to set up. If you are starting from scratch, I would recommend using the vanilla Raspbian image as I did originally).
I’m using a Raspberry Pi Model A, 2nd revision board. After hooking it up to a TV with HDMI, I connected a USB keyboard and wireless USB dongle to the single USB port on the Pi, and powered on.
First time I did this, the Pi booted up with a configuration menu. I expanded the file-system to fill the SD card, over-clocked to 900Mhz, changed the root password and host-name. More recently, using Noobs, I was able to do this same configuration under X windows.
The Pi was set to boot to CLI, without automatic log on, both SPI and I2C were enabled in the configuration.
The next step is to configure wireless networking. I’m using an Edimax USB adapter (EW-7811Un) apparently based on Realtek RTL8188CUS chipset.
The contents of /etc/network/interfaces were left with the Raspbian defaults. However, the settings in /etc/wpa_supplicant/wpa_supplicant.conf needed to be changed to suit my own network, as shown below:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
scan_ssid=1
ssid="yourssid"
psk=2a1f2e3c8d7f5e4a35c6f4e3d...
proto=WPA
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
}
The PSK above is generated by using wpa_passphrase as follows:
wpa_passphrase <ssid> <password>
Since my SSID is hidden, I had to add the scan_ssid setting to make it find the network. Without this, it gives loads of errors about DHCP discover failing.
Another problem I have had a few times is that if you make small typo in the wpa_supplicant file, it will fail to start with error 1.
Having changed the settings, I restarted the wireless network as follows:
sudo ifdown wlan0 sudo ifup wlan0
This got it up and running on the network, and then I was able to SSH into the Pi.
Next I decided to try an update as follows:
sudo apt-get update sudo apt-get upgrade
As a quick check at this stage:
uname -r 4.1.13+
Configuring FBTFT for the HY28.
Next, I decided to install the FBTFT drivers for the LCD display. These are apparently now included in the Raspberry Pi Foundation kernel, so let’s try updating that:
sudo rpi-update sudo reboot
Check the version:
uname -r 4.1.15+
Having connected the HY28A TFT LCD to the Pi via the SPI bus, I tried loading the drivers (using the same settings I had backed up from my previous working installation):
# load the driver: the panel goes black sudo modprobe fbtft_device name=hy28a rotate=270 gpios=reset:25 fps=20 # map console to LCD for testing con2fbmap 1 1
Having done this, the console appeared on the LCD, confirming that it works. I then made it permanent by loading the module from /etc/modules-load.d/fbtft.conf
spi-bcm2835 fbtft_device
The options are set in /etc/modprobe.d/fbtft.conf
options fbtft_device name=hy28a rotate=270 gpios=reset:25 txbuflen=32768 fps=20
For reference only, the touchpanel driver settings used to be the following in /etc/modules (and haven’t yet been corrected for systemd as I don’t use them currently):
# Touchpanel driver ads7846_device pressure_max=255 y_min=190 y_max=3850 gpio_pendown=17 x_max=3850 x_min=230 x_plate_ohms=60 ads7846
To make the console appear during boot, I added the following to the end of /boot/cmdline.txt. This font seemed the best of the few that I tried.
fbcon=map:10 fbcon=font:Acorn8x8
After about 30 minutes, the LCD screen goes blank. To disable this, I changed the BLANK_TIME and POWERDOWN_TIME to zero in /etc/kbd/config:
# prevent screen blanking BLANK_TIME=0 POWERDOWN_TIME=0
Installing the ADS1015 ADC board
For Raspbian, we first have to enable I2C by adding the following lines to /etc/modules:
# I2C drivers for ADC board i2c-bcm2708 i2c-dev
After a reboot, I installed i2c-tools for convenience:
sudo apt-get install python-smbus sudo apt-get install i2c-tools
Having done this, the following can be used to detect I2C devices:
sudo i2cdetect -y 1 # for older Raspberry Pi boards: # sudo i2cdetect -y 0
For my Pi, the ADS1015 appears as address 0x48 on /dev/i2c-1. Having confirmed this, I wrote a small command-line test program to check that the ADC was working and returning voltage readings.
With my buttons wired to the ADC via a resistor ladder, this was an opportunity to check that they worked as planned. With various button combinations, I obtained the following readings:
- No buttons = 3.30V
- Lower button = 2.18V
- Upper button = 1.65V
- Both buttons = 1.31V
Problem 1 (solved?): Wireless disconnects
After using this for a while, I started having problems with the wireless going down, usually half-way through editing a file over SSH. I seem to remember having this issue before and fixing it with some changes to disable power management in the boot command-line… but couldn’t remember the details.
Based on something I read here, I decided to try adding this to /etc/network/interfaces:
wireless-power off
After some time, it became evident that this hadn’t solved the problem. I’m pretty sure it’s not the power supply, as it worked fine on this PSU for about a year until the re-install.
Anyway, in desperation I added a 100uF low ESR electrolytic between 5V and GND (can’t hurt!), and also tried re-positioning the wifi adapter to have a clear line of sight to the router.
This didn’t solve the problem either, although it did stop the Pi from rebooting when the wifi dongle is inserted (the network doesn’t come back up if you do this though..)
For my next attempt, I tried setting the USB speed down to V1 to see if that helped (better to have a slow connection than an unreliable one…)
dwc_otg.speed=1
This seemed to improve matters at first, but after extended use it still seems unreliable. The next thing I tried was this suggestion to create a configuration file at /etc/modprobe.d/8192cu.conf to disable power management:
options 8192cu rtw_power_mgnt=0 rtw_enusbss=0
For good measure, I’ve also added this to /boot/cmdline.txt (which actually seems familiar, and might be what solved this problem before):
smsc95xx.turbo_mode=N
Finally, I’ve increased the minimum reserve virtual memory in /etc/sysctl.conf as I seem to remember doing that last time:
vm.min_free_kbytes = 16384
This is really starting to become annoying now. I’ve spent more time rebooting and messing with the wireless than working on the project.
Update: this seems more stable now. I think one of the last two steps must have been the real solution!
Installing LIBSDL
I’m using the SDL 1.2 library for graphics on the TFT display, as well as the SDL TTF library for font rendering, and SDL image library. These are installed as follows:
sudo apt-get update sudo apt-get install libsdl1.2-dev libsdl-ttf2.0-dev libsdl-image1.2-dev
Installing pigpio
Es(pi)resso used to use kernel mode drivers for the TSIC 306 Temperature Sensor and the HCSR-04 Ultrasonic Range Finder. The problem is that these needed to be rebuilt when the kernel was updated, and this isn’t easy to do on the Pi (I only managed to build these via cross-compilation from Ubuntu on a PC).
Having recently discovered the PIGPIO library, I decided to move to user mode drivers implemented with pigpio. This is obviously more convenient as it avoids the need to rebuild kernel modules and makes a self contained project.
The first step is to install pigpio as follows:
wget abyz.co.uk/rpi/pigpio/pigpio.zip unzip pigpio.zip cd PIGPIO make make install
Having done this, I rewrote the code to use PIGPIO. In the first instance, I tried using the functions directly from pigpio.h. However, I ran into all sorts of mysterious crashes at start up. After some debugging, my theory was that this might be due to the use of static variables in both pigpio and in my own code, potentially resulting in undefined order of initialisation at start up. Consequently, I rewrote the code to use the PIGPIOD daemon instead (via the pigpiod_if functions), and this works fine.
Almost all the GPIO is now moved to PIGPIOD, with the exception of the hardware PWM which has been retained for the boiler power regulation (primarily because of the very low PWM frequency used).
Check out and configure the Es(pi)resso software
Now we have the dependencies, the software needs to be checked out from Subversion:
sudo apt-get update sudo apt-get install subversion mkdir sandbox cd sandbox svn checkout https://github.com/jam3sward/espiresso.git/trunk gaggia
There is no configuration, so the software should just build like this:
make
It can be installed to /usr/local/bin as follows:
sudo make install
Every time it runs, the controller software creates log files at /var/log/gaggia. This folder must be created manually as follows:
sudo mkdir /var/log/gaggia
There is also a configuration file with the PID controller parameters and other settings. From the project directory, this is copied to /etc/gaggia.conf as follows:
sudo cp gaggia.conf /etc
There are some PNG images (used to display icons on the LCD) which need to be installed in /etc/gaggia as follows:
sudo mkdir /etc/gaggia sudo cp images/*.png /etc/gaggia ls /etc/gaggia
At this point, the software can be started in interactive mode by adding the -i parameter. This displays output in the console and allows the software to be stopped by pressing a key.
sudo ./gaggia start -i
Assuming this works, the LCD display should show the current temperature, water level etc.
Problem 2 (solved): GPIO initialisation at boot time
The Raspberry Pi was initialising GPIO15 (RXD) as pull-up at power on. In early testing, this resulted in the pump being switched on when the system was powered up!
To fix this, I used the device tree pin configuration to change the GPIO pin initial state to an input with pull-down at power on. The pin is later changed to an output by the control software.
First, we check that the Raspberry Pi firmware is later than July 15th 2014:
vcgencmd version
Then we install the device tree compiler:
sudo apt-get update sudo apt-get install device-tree-compiler
Then the device tree source file is needed. This is located in the source code tree here: gaggia/dt-blob/dt-blob.dts
Finally, the device tree source file is compiled to a binary blob, and copied to the /boot partition:
sudo dtc -I dts -O dtb -o /boot/dt-blob.bin dt-blob.dts
Note: on NOOBS this file apparently has to be on the recovery partition.
When the system is rebooted, the GPIO pin comes up as a pull-down, and the pump sits idle until the controller is ready to power it on.
Faster boot times
In an attempt to make it boot up faster and reduce writes to the SD card, I made the following changes to /boot/cmdline.txt:
- Removed console=tty1
- Added noatime nodiratime
- Added quiet
The current /boot/cmdline.txt looks like this:
dwc_otg.lpm_enable=0 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline noatime nodiratime fsck.repair=yes rootwait quiet smsc95xx.turbo_mode=N fbcon=map:10 fbcon=font:Acorn8x8
Running the controller automatically at start up
To make the software run automatically at start up, I created two scripts under /etc/init.d. One, called pigpiod is used to start the pigpio daemon. The other, called gaggia, is used to start the controller.
These are installed as follows:
# copy the executable to /usr/local/bin sudo cp gaggia /usr/local/bin # copy the scripts into /etc/init.d sudo cp scripts/gaggia /etc/init.d/gaggia sudo cp scripts/pigpiod /etc/init.d/pigpiod sudo chmod +x /etc/init.d/gaggia sudo chmod +x /etc/init.d/pigpiod # install the scripts sudo update-rc.d gaggia defaults sudo update-rc.d pigpiod defaults
When the machine starts, the pigpiod daemon is initialised first, followed by the gaggia controller. This enables the machine to automatically start when powered on.
Button 2 on the front panel can later be used to safely shut down the Pi (by pressing for more than 2 seconds).
Another way to shut down the controller is to log in remotely, and type:
sudo /etc/init.d/gaggia stop
Furthermore, holding Button 2 as the system boots will prevent the controller from starting up. This is useful when the machine is being powered on for maintenance or development.
Installing Samba
Installing Samba makes it possible to access the log files over the local network, and is also generally useful for transferring files. The first step is to install Samba itself:
sudo apt-get update sudo apt-get install samba samba-common-bin
Make a backup of the original smb.conf configuration file, and edit the file:
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.$(date +%F) sudo nano /etc/samba/smb.conf
In my case, I commented out the [printers] section and the [print$] section, and added the following section to make the log files visible:
[logs] comment = Logs path = /var/log/gaggia browseable = yes only guest = yes read only = yes public = yes
Finally, the configuration can be tested, and the Samba service restarted as follows:
testparm sudo service smbd restart sudo service nmbd restart
Installing Samba has the added bonus of making it possible to SSH to the Pi using the host name, rather than having to use the IP address.
Problem 3 (solved?): SD card corruption
Having got everything working really well… it just stopped booting. Connecting the Pi to my TV with HDMI, I found that it was failing early in the boot process with a kernel panic, complaining over a missing file-system. Turns out the SD card was corrupted. No idea how that happened.
After some initial panic, I managed to repair the SD card from a PC running Ubuntu using fsck.ext4 something like this:
NOTE: mmcblk0p2 will probably need to be changed on your PC
sudo fsck.ext4 -v /dev/mmcblk0p2
After rebooting the Pi, fsck ran again. It actually seemed to crash fsck itself and streamed out pages and pages of junk on-screen. I just left it to see what happened and it eventually came up and started working again.
I’m now thinking of making the SD card read only and moving the file system to USB to improve reliability.
Problem 4 (solved?): Display reliability
Although the display has been running fine for several months, I recently found it started behaving erratically. The first issue was that it would sometimes randomly shift the display vertically (i.e. as if it was scrolled, with wrap around). Eventually, I found that I just got a white screen at boot.
Having eliminated the obvious things like checking the settings in /etc/modules and the wiring, I decided to try reducing the speed from 32MHz to 16MHz, which seemed to cure the white screen:
fbtft_device name=hy28a rotate=270 gpios=reset:25 speed=16000000 fps=20
Since the display was working fine at 32MHz for a long time, I can only conclude that this might be due to poor contact in the connectors or wiring (I’ve removed and reconnected the headers many times), or it could be related to FBTFT competing with PIGPIO, which is running a lot of DMA and using 9% CPU. Either way, I’ll see how well the display performs at 16MHz, in the absence of a better solution.
Disable swapfile
How to disable the swap file:
sudo swapoff --all sudo apt-get remove dphys-swapfile
Installing Busybox syslogd
I decided to install Busybox syslogd (which logs to a circular buffer), hopefully reducing SD card activity:
sudo apt-get install busybox-syslogd sudo dpkg --purge rsyslog logread
Hi!
I have a raspberry pi application requiring determinate state of the GPIO at boot. I saw your dt-blob.dts, but I´m not sure if I need all the code, because I only need to change behavior of 2 pins. Could you maybe help me customize a .dts?
PS: Sorry that I write this here, but I didn´t know how to contact you.
Hi David
Did you get my e-mail of 28 August?
Regards
James
There are some 1.2mpa flow sensors on amazon uk. If correct that’s 12bar so could be put after the pump. Some are on prime. 0.15L/min and others.
I have a Sage machine where the meter is on the feed from the water tank. The opv output messes it up if it opens. Could try adding the T. Assume that goes between the meter and the pump but scratch my head a little on how well that will work.
Thanks for the ideas.
Hi, replied to this comment here:
http://int03.co.uk/blog/project-coffee-espiresso-machine/#comment-75323