Earth Notes: On Setting Up a Raspberry Pi Off-grid PV-Powered Server (2014)
Updated 2023-03-21.(The RPi B and B+ have been steps on the road from power-hungry rack of Sun SPARC server boxes to a sun-powered off-grid RPi 2 all-in-one. 512MB memory proved still to be a bit of a squeeze at this stage of the journey, though...)
Having bought a "Raspberry Pi Kit" (R45PI) aka RPi from Maplin, on 2014-06-22 I attempted to get it set up and working with the family TV. (Using the HDMI lead worked just fine.) The keyboard was broken (keys not responding or were sticking) but my local Maplin exchanged it the same day.
(I had, a couple of days before, observed consumption of the Pi, a Model B with 512MB RAM, 2 USB ports and Ethernet, without any keyboard (etc) attached. I measured it to be drawing <3W with just the SD card in and after booting likely finished, so less than the SheevaPlug.)
It booted happily once the keyboard was sorted, and after changing the password, I briefly had my daughter try out "Scratch" which she'd used at school, running under X windows as started with startx
.
I set up WiFi which worked immediately, and followed instructions on the printed getting-started sheet to sudo apt-get update
and sudo apt-get upgrade
, which did not take too long and gets me (uname -a
) to:
Linux XXXXX 3.12.22+ #691 PREEMPT Wed Jun 18 18:29:58 BST 2014 armv6l GNU/Linux
I also got the official Oracle Java JDK7 with an sudo apt-get install oracle-java7-jdk
. This is not the smaller-footprint 'embedded' version that I'm running on the SheevaPlug, but at least it should not require funny licensing arrangements.
I gave my RasPi a static IP address, changed its name, and added it to my published DNS records so that it could become a server, and enabled incoming ssh
(ie sshd
) so that I could run it headless and without monopolising the family TV! (Note that as a security matter, in /etc/ssh/sshd_config
, PermitRootLogin
should be no
and indeed the only allowed login should probably be by key ie PasswordAuthentication
should be no
. I see bad actors attempting to get in regularly, so I make it harder.)
At the comfort of my own desk, and powering the RPi from my off-grid system, I used apt-get
to fetch a few more favourite packages such as tcpdump
and tcsh
.
I won't leave the RPi connected all the time until I have spent some time securing/hardening it, though an initial inspection of the output of netstat -n
does not suggest too much insecure junk is running, thankfully.
Initial Plans
Some initial thoughts:
- (Done) I am expecting get a 128GB SD card for this unit so that I can move all my data on to it and do without the external thumb-drive that I need on the SheevaPlug saving complexity and power. I'll probably stick with Raspbian.
- (Done) I'll get a hardware battery-backed RTC to that I can sensibly continue to provide NTP service (and then set up NTP properly). (Ordered 2014-06-22 RTC Pi simple DS1307-based RTC.)
- (Done) Ensure that the
sunnybeamtool
works on (or can be built for) the RPi. (Plugging Sunny Beam in seems to reset the RPi. Draws ~30mA/150mW presumably for keeping the screen active.) - I'll use the GPIO UART lines to talk to an OpenTRV unit if possible to avoid the need for an FTDI cable and the wakeup-hungry RXTX library.
- (Done) I'll possibly use the GPIO and some SPI ADC to replace the current k8055 to reduce power consumption, though I'll measure to see what works best. If the k8055 continues to work with the RPi then I may stick with it even though lots of details of the scripts will probably change.
- (Done) I'll want to turn off swap or at least reduce the system's desire to swap (since swapping will kill the SD card and make servers unresponsive) or maybe use something like
zram
instead. - (Done) I'll enable
iptables
to kill some dangerous traffic early, as for the SheevaPlug. - (Done) I'll want to transfer the various HTTP/SMTP/DNS/NTP/etc services across, though I can run them in many cases as 'secondaries' first to ensure that RPi performance is adequate as for example is a slower clock than the SheevaPlug.
- (Done) Adjust logging and other apps to minimise disc write traffic as per SheevaPlug (though already good out of the box), and enable full log rotation.
- (Done) Use /proc/sys/vm/block_dump to check sources of file write traffic.
- (Done) Set the system timezone to UTC (easy using raspi-config).
2014-06-24: RTC
The RTC Pi RTC arrived very promptly!
Power consumption was measured before fitting the RTC, with Ethernet connected and the stock 4GB SD card but no USB/keyboard/mouse/TV, via an RS mains adapter 726-3069 and Maplin N67HH power meter, as 3.2W after boot had completed. (Note that the mains adapter data sheet claims typical 71% efficiency, so that 3.2W of power shown may be nearer 2.3W in reality.)
I fitted the RTC board with a battery and then plugged it into the RPi. Steady-state power consumption after boot is still 3.2W.
Setting up the RPi to talk to the RTS over i2c following these generic instructions...
I commented out the 'blacklist' line for the i2c driver in /etc/modprobe.d/raspi-blacklist.conf
#blacklist i2c-bcm2708
(the SPI driver blacklisting is already commented out).
I then added the following to the end of /etc/modules to load modules at boot:
i2c-bcm2708 i2c-dev rtc-ds1307
and installed i2c-tools:
sudo apt-get install i2c-tools
To verify that the RTC board is detected on my Model B I ran:
sudo i2cdetect -y 1
which output:
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
which shows the address '68' which is promising.
As a temporary set up I ran (as root, suitable for my Model B):
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-0/new_device
and running:
sudo hwclock -r
shows:
Sat 01 Jan 2000 00:01:07 GMT -0.168507 seconds
which shows that the kernel can see the clock but it is not set yet.
Setting the clock initially with:
sudo hwclock --systohc -D --noadjfile --utc
outputs:
hwclock from util-linux 2.20.1 Using /dev interface to clock. Assuming hardware clock is kept in UTC time. Time elapsed since reference time has been 0.394304 seconds. Delaying further to reach the new time. Setting Hardware Clock to 18:08:52 = 1403633332 seconds since 1969 ioctl(RTC_SET_TIME) was successful.
which looks good!
Now to have time restored from the hardware RTC in start-up I have added these to the end of /etc/rc.local (before the exit):
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device hwclock -s
It might be better to get this done earlier in the boot sequence, eg before logging starts.
I disabled the default 'fake clock' that stops time going backwards if the network is not connected:
update-rc.d -f fake-hwclock remove
(I reinstated this to help ensure sensible timestamps on files touched during boot before the hwclock is read, eg files in /var/log.)
To power cycle to check that everything works I issue:
sudo halt
and after a short while power consumption drops to 1.0W.
To ensure that the NTP-maintained system clock is periodically saved to the hardware RTC to stop it drifting, I have created in /etc/cron.daily a file called hwRTC:
pi:/etc/cron.daily# cat hwRTC #!/bin/sh /sbin/hwclock --systohc -D --noadjfile --utc > /tmp/hwClock.log 2>&1 pi:/etc/cron.daily# ls -al hwRTC -rwxr-xr-x 1 root root 79 Jun 24 20:17 hwRTC
which should ensure once per day that the RTC time is forced to be correct.
A DS3231 may be a good drop-in replacement for the DS1307 running directly at 3V3 and so not needing level converters for a start, and working with the same software drivers... Also look at DS1338 and DS1337.
2014-06-24: Initial Adventures in Power Reduction
Attempting to turn off the unused HDMI with:
/opt/vc/bin/tvservice -o
actually raised reported consumption to 3.3W, and turning it on again with:
/opt/vc/bin/tvservice -p
apparently drops it back to 3.2W!
When re-measured with my bench supply, /opt/vc/bin/tvservice -o
appears in fact to drop consumption by ~20mA ie 100mW. (Putting this in rc.local risks making the system unrecoverable by plugging into the TV. I could possibly start this after a delay to give myself change to kill it manually in such a case.)
The consumption claimed by the mains monitor is not always linearly related to that measured by my bench supply, and the bench supply is likely to be more accurate for a number of reasons.
Various sources on-line suggest that replacing the 3V3 on-board linear regulator which actually supplies most of the board power (5V is for USB mainly) might save 25%+ consumption, maybe as much as 1W, though the USB and Ethernet alone are actually heavy users at ~0.5W and the only power control in software affects both at once.
Replacing the the 3V3 linear regulator with a RECOM R-783.3-0.5 is reported to save ~15%.
The same guide suggests editing /boot/config.txt to insert:
force_turbo=0 #turns on frequency scaling arm_freq=700 #sets max frequency arm_freq_min=100 #sets min frequency
installing cpufrequtils with:
sudo apt-get install cpufrequtils cpufreq-set -g ondemand
but even after a reboot and with the CPU nominally running at 100MHz I'm still seeing 3.2W consumption!
I may want in future to change the threshold for changing CPU frequency from the default 95%* to (say) 60% when battery levels are good to improve responsiveness with:
echo 60 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold
for example. (*Reportedly: seems to default to 70 after reboot on my RPi 20140708.)
Note that in /boot/config.txt I have set (c/o raspi-config):
gpu_mem=16
to minimise GPU memory allocation since I shall be running headless.
$ cat /proc/meminfo | grep Mem MemTotal: 496764 kB MemFree: 432672 kB
Note that MemTotal is 513392kB on the SheevaPlug, so I may strain to fit everything in without swap...
Perversely, if I try to waste CPU cycles, eg with:
while true; do true; done
I see consumption apparently drop to 3.0W!
Note that the k8055 board that is used with my SheevaPlug nominally draws 350mW, quite a lot of the gap between the Pi 3.2W and the nominal ~4W minimum of the SheevaPlug, so using some direct ADC/DIO may help with system savings. In fact the idle of the SheevaPlug without a USB hub is nearer ~2.5W, so although the RPi gives a lot of benefits of a supported mainstream distribution, and a less complex and fragile set-up, I may need to work harder to save much juice...
I have ordered a couple of ~80% efficient 3V3 switching regulators and a spare Model B board (and 128GB SD card!) to experiment with, eg replacing the reg and testing other energy-saving mods.
Attempting to get a more accurate power measurement by using my bench supply connected (naughtily) to the appropriate GPIO pins at 5V, shows an idle consumption of 380mA or 1.9W (logged in over ssh
), rising to 420mA (2.1W) with a CPU-busy loop (while true; do true; done
as above). Compared to the 3.2W reported by the mains power monitor this suggests a mains adapter efficiency of ~60% at this load.
Running a large "find" raised consumption to 440mA (2.2W).
After halt
ing, consumption dropped to 110mA (0.55W).
Later I borrowed some tuning tips from my SheevaPlug set-up, adding these lines to /etc/sysctl.conf:
# DHD20140628: further tweaks to reduce SD card traffic. vm.dirty_background_ratio=20 vm.dirty_ratio=40 vm.dirty_writeback_centisecs=12011 vm.dirty_expire_centisecs=12101
I am using some prime timings to hope to decouple different activities.
I also adjusted /etc/logrotate.conf to by default compress logs.
I also replaced each commented-out line from /etc/rsyslog.conf below with the uncommented one to try to reduce log traffic a little:
#*.*;auth,authpriv.none -/var/log/syslog *.*;auth,authpriv.none,cron.none -/var/log/syslog
but I can't do this and have fail2ban
still work for banning ssh
attacks:
#auth,authpriv.* /var/log/auth.log auth,authpriv.notice /var/log/auth.log
I also turned off debug logging.
Following the advice to quieten PAM (also this) by adding:
session [success=1 default=ignore] pam_succeed_if.so service in cron quiet use_uid
just above:
session required pam_unix.so
in /etc/pam.d/common-session-noninteractive
may also help reduce unwanted chatter/writes.
Note also a simple debugging/monitoring aid in the 'ACT' LED on the RPi board.
echo mmc0 > /sys/class/leds/led0/trigger
(which is the default) will have the LED come on for each SD card access, and:
echo cpu0 > /sys/class/leds/led0/trigger
will have the LED come on with CPU activity for example!
echo none > /sys/class/leds/led0/trigger
turns it off saving a tiny bit of juice, presumably!
The llctl code can be used to (for example) turn off the LAN "100" and "FDX" lights which don't convey a huge amount of information, or use them for other purposes.
lltcl f0 ls d0
leaves the "LNK" LED flickering on activity and turns off "100" and "FDX".
Turning off the "ACT", "FDX", "LNK" and "100" LEDs appears to reduce current draw at 5V on my unmodified Model B from 380mA to 370mA (1.85W), according to my bench supply that reads in units of 10mA so may be less, but suggests that up to 50mW of extra power savings are available this way. This may be worth doing when (very) low on battery. (After halt, current draw now drops to 100mA, cf usual 110mA, with LEDs off.)
This is a sufficiently convincing win that I've moved llctl to /usr/local/bin
and I've added this to the end of /etc/rc.local to cut the LAN LEDs by default:
/usr/local/bin/llctl f0 l0 d0
With the LAN LEDs off and:
/opt/vc/bin/tvservice -o
current draw drops to 350mA (1.75W).
To let this happen automatically, though not if anyone is logged in in case they are using TV and keyboard login for example to recover the system, the following is added to /etc/rc.local
# Power down the TV output after a while to save 100mW after warning users. # Happens after a delay to allow system recovery using TV/keyboard. # Not done if anyone appears to be logged in. # COMMENT OUT THE FOLLOWING LINE TO KEEP THE TV OUTPUT RUNNING. (sleep 180 && if [ "X" = "X`w -h`" ]; then logger -p user.emerg "TV service off in 2 mins; see /etc/rc.local" && sleep 120 && /opt/vc/bin/tvservice -o; else logger -p user.emerg "TV service not being turned off; do it manually to save power"; fi) &
This waits three minutes and if no one appears to be logged in sends a warning and then after a further two minutes and turns off TV service, saving 100mW. If someone does appear to be logged in then the TV service is left on, with a warning to turn it off manually. Thus, a few minutes after a normal unattended boot TV service will be turned off and the extra power savings will be taken.
2014-06-27: Backup and new 128GB Card
As a practice run if nothing else I'm taking a backup of the 4GB SD card with the work done on it so far.
Having halted the RPi and removed the SD card, I can plug the SD card directly into the SD slot of my MacBock Air (running 10.9.3) and the leading FAT partition is mounted automatically.
See here (see also here) the following suggested dd command to make a backup copy from the SD card:
sudo dd bs=1m if=/dev/rdisk1 of=RPi.img
But before doing that I have unmounted the FAT partition to avoid conflicts:
[sudo] umount /dev/disk1s1
The dd command gave the following output:
3765+0 records in 3765+0 records out 3947888640 bytes transferred in 250.045586 secs (15788676 bytes/sec)
suggesting that indeed 4GB had been transferred. Follow with a:
diskutil eject /dev/rdisk1
before physically removing the SD card from the Mac.
I have copied the RPi.img file to 20140627-RPi.img and compressed it with the best-available tool easily available on my Mac to save space, bzip2, since most of the file space is not even used.
sh-3.2# bzip2 -9 20140627-RPi.img sh-3.2# ls -alrt ... -rw-r--r-- 1 root staff 3947888640 27 Jun 09:15 RPi.img -rw-r--r-- 1 root staff 1017288117 27 Jun 09:23 20140627-RPi.img.bz2 ...
I will then try cloning that to another 4GB SD card and see if I can boot and run the RPi with that, then to an 8GB card, expanding the partition or creating a new one for data beyond it, then repeat the exercise with the new 128GB card that I have just received.
I shall attempt to clone the 4GB image onto another 4GB card with:
dd bs=1m if=RPi.img of=/dev/rdisk1
having made sure no partitions are being mounted from the card first, in this case requiring:
diskutil unmount /dev/disk1s1
With the destination class 4 card (x150) dd took about 3 minutes.
Success! The RPi boots off the clone card all working as before! Power consumption is apparently as before also.
I am now attempting to dd the 4GB image onto an 8GB card, to see if it bootable and if I can create a new (ext4?) partition beyond the existing ones as data space.
The RPi boots happily from the 8GB card with the 4GB image on it, and with power consumption unchanged.
I ran up parted, and:
(parted) print all Model: SD SD08G (sd/mmc) Disk /dev/mmcblk0: 8196MB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 1 4194kB 62.9MB 58.7MB primary fat16 lba 2 62.9MB 3948MB 3885MB primary ext4 (parted) print free Model: SD SD08G (sd/mmc) Disk /dev/mmcblk0: 8196MB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 32.3kB 4194kB 4162kB Free Space 1 4194kB 62.9MB 58.7MB primary fat16 lba 2 62.9MB 3948MB 3885MB primary ext4 3948MB 8196MB 4248MB Free Space (parted) mkpart primary ext3 3948MB 8196MB (parted) print all Model: SD SD08G (sd/mmc) Disk /dev/mmcblk0: 8196MB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 1 4194kB 62.9MB 58.7MB primary fat16 lba 2 62.9MB 3948MB 3885MB primary ext4 3 3948MB 8196MB 4248MB primary
Thus creating a new partition filling all the trailing free space.
Inspecting with fdisk shows:
%fdisk -l /dev/mmcblk0 Disk /dev/mmcblk0: 8195 MB, 8195670016 bytes 4 heads, 16 sectors/track, 250112 cylinders, total 16007168 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000280b3 Device Boot Start End Blocks Id System /dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA) /dev/mmcblk0p2 122880 7710719 3793920 83 Linux /dev/mmcblk0p3 7710720 16007167 4148224 83 Linux
which suggests that this is not particularly laid out to minimise wear and increase write performance.
On the SheevaPlug for the Gallery images partition I used:
mkfs -t ext3 -i 131072 -L galleryDB -O ^resize_inod,dir_index,sparse_super /dev/sda2
That data will be in the new partition, along with a fair amount of other stuff, plus I should probably use ext4 these days. Even though a dir_index,sparse_super are defaults, I'll leave them for clarity, so my command to create a new ext4 filesystem should look something like this for the final create:
mkfs -t ext4 -i 32768 -L data -O ^resize_inode,dir_index,sparse_super /dev/mmcblk0p3
(Note the trailing 'e' on resize_inode that was insisted on by mkfs!)
Here is a test run on the 8GB card:
# mkfs -t ext4 -i 131072 -L data -O ^resize_inode,dir_index,sparse_super /dev/mmcblk0p3 mke2fs 1.42.5 (29-Jul-2012) Filesystem label=data OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 32768 inodes, 1037056 blocks 51852 blocks (5.00%) reserved for the super user First data block=0 32 block groups 32768 blocks per group, 32768 fragments per group 1024 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736 Allocating group tables: done Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done # mount /dev/mmcblk0p3 /tmp # df -h Filesystem Size Used Avail Use% Mounted on rootfs 3.5G 1.8G 1.6G 53% / /dev/root 3.5G 1.8G 1.6G 53% / devtmpfs 239M 0 239M 0% /dev tmpfs 49M 216K 49M 1% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 98M 0 98M 0% /run/shm /dev/mmcblk0p1 56M 9.5M 47M 17% /boot /dev/mmcblk0p3 3.9G 20K 3.7G 1% /tmp
This should give me the ability to back up the OS separately from bulk data, by cloning only the leading part of the SD card if I am feeling brave, for example. It should also help me move data from the SheevaPlug to the RPi later in the transition between them.
So now I repeat for the 128GB card:
- Use dd to copy the 4GB clone image on to the 128GB card on the Mac:
diskutil umount /dev/disk1s1 time bzip2 -d < 20140627-RPi.img.bz2 | dd bs=1m of=/dev/rdisk1 diskutil eject disk1
0+114029 records in 0+114029 records out 3947888640 bytes transferred in 171.268633 secs (23050856 bytes/sec) real 2m51.282s user 2m14.160s sys 0m8.577s
- Confirm that the RPi boots from the 128GB SD card and seems sane. (Yes, and power reported at 3.2W by mains meter.)
- Use parted to create a new partition using all the free space.
# parted GNU Parted 2.3 Using /dev/mmcblk0 Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) print free Model: SD (sd/mmc) Disk /dev/mmcblk0: 128GB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 32.3kB 4194kB 4162kB Free Space 1 4194kB 62.9MB 58.7MB primary fat16 lba 2 62.9MB 3948MB 3885MB primary ext4 3948MB 128GB 124GB Free Space (parted) print free Model: SD (sd/mmc) Disk /dev/mmcblk0: 128GB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 32.3kB 4194kB 4162kB Free Space 1 4194kB 62.9MB 58.7MB primary fat16 lba 2 62.9MB 3948MB 3885MB primary ext4 3 3948MB 128GB 124GB primary
- Use mkfs to make the new partition (then add to fstab).
mkfs -t ext4 -i 32768 -L data -O ^resize_inode,dir_index,sparse_super /dev/mmcblk0p3
Power rose to a peak of about 4.4W (mains), and the output was:
super /dev/mmcblk0p3 mke2fs 1.42.5 (29-Jul-2012) Filesystem label=data OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 3788800 inodes, 30300672 blocks 1515033 blocks (5.00%) reserved for the super user First data block=0 925 block groups 32768 blocks per group, 32768 fragments per group 4096 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done
- Add new partition/line to fstab with sensible mount options.
/dev/mmcblk0p3 /local ext4 defaults,noatime,commit=300 0 2
mount -a
I can see it, 109GB free:# df -h Filesystem Size Used Avail Use% Mounted on rootfs 3.5G 1.8G 1.6G 53% / /dev/root 3.5G 1.8G 1.6G 53% / devtmpfs 239M 0 239M 0% /dev tmpfs 49M 216K 49M 1% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 98M 0 98M 0% /run/shm /dev/mmcblk0p1 56M 9.5M 47M 17% /boot /dev/mmcblk0p3 115G 20K 109G 1% /local
proc /proc proc defaults 0 0 /dev/mmcblk0p1 /boot vfat defaults 0 2 /dev/mmcblk0p2 / ext4 defaults,noatime,commit=120 0 1 /dev/mmcblk0p3 /local ext4 defaults,noatime,commit=300 0 2 # a swapfile is not a swap partition, so no using swapon|off from here on, use dphys-swapfile swap[on|off] for that
I rebooted to check that all the appropriate changes 'stuck' including the new mount options. All seemed well.
Done: backup taken of RPi card as of this morning, and 128GB card cloned to and with new huge data partition!
I have re-enabled the fake-hwclock
so that log files written doing boot have more sensible timestamps!
2014-06-28: Analogue Input for Battery Voltage Monitoring
I have ordered an ABElectronics ADC-DAC Pi with two analogue input channels to enable me to monitor battery levels as I do now using the k8055. (I may not use the outputs at all.) Hat-tip for excellent customer service, by the way!
In preparation I downloaded one of their sample code files, compiled with with the gcc C compiler already present on the RPi. I ran it for sheer devilment even though the hardware is not yet here!
wget https://github.com/abelectronicsuk/adcdacpi/raw/master/adc.c gcc -O adc.c sudo ./a.out
and the output is:
0.000000 Elapsed time: 8193 milliseconds
which indicates well under 1ms per sample/reading, and that missing results in a 'safe' zero reading rather than (say) a hang.
A very small amount of code should be able to capture the two voltages and make them available to a script just like the k8055 script, though I may take the opportunity to radically revise how that works.
Given that gcc is "built-in" and that running the power management and stats code quickly saves energy, it might indeed be better to move the bulk of the logic into the C code itself. Certainly some of the arithmetic and logical operations would be clearer, and orders of magnitude faster!
One possible disadvantage of this MCP3202-based circuit is that it measures relative to the supply voltage which might easily wobble +/-10% without harm. Whereas I need to measure typically a 0.1V change in ~12V, or <1%. So I may have to switch to a different ADC card with a built-in reference. Though even there, noise/drops in the ground connection would impact accuracy.
2014-06-28: Security Tweaks
I have installed fail3ban
as a test:
sudo apt-get install fail2ban
Note that the config is in /etc/fail2ban/jail.conf
and I've added some local overrides in the jail.local
file, eg like (but not these exact values):
# Local overrides. [ssh] maxretry = 5 findtime = 800 bantime = 900
These make banning a little more aggressive than usual.
Trimming logging output too much may inhibit fail2ban
.
I've created a file /etc/network/iptables
that contains iptables
rules such as:
# Accept anything on loopback. -A INPUT -i lo -j ACCEPT # Handle normal inbound traffic not otherwise dealt with so far. -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -j tcp_inbound -A INPUT -p udp -j udp_inbound -A INPUT -j DROP -A tcp_inbound -p tcp -m tcp --dport 123 -j ACCEPT -A tcp_inbound -p tcp -m tcp --dport 80 -j ACCEPT -A tcp_inbound -p tcp -m tcp --dport 53 -j ACCEPT -A tcp_inbound -p tcp -m tcp --dport 25 -j ACCEPT -A tcp_inbound -p tcp -m tcp --dport 22 -j ACCEPT -A tcp_inbound -p tcp -j RETURN -A udp_inbound -p udp -m udp --dport 53 -j ACCEPT -A udp_inbound -p udp -m udp --dport 123 -j ACCEPT -A udp_inbound -p udp -j RETURN COMMIT
to drop any unexpected traffic, ie to ports other than we might wish to answer.
At the end of the section in /etc/network/interfaces
for eth0 add:
pre-up iptables-restore < /etc/network/iptables
to start iptables
before bringing the (wired) network up.
Since fail2ban
will also be using iptables
, I have to hope that they play nicely together...
2014-06-29: Java and SVN
I'm starting to test out some of the major components that will need to be shifted from the SheevaPlug, plus many many packages from gnuplot and optipng and svn through to some of my primary Java applications.
I notice that Java is running at about 2/3rds the speed on the SheevaPlug, which would make sense just comparing clock rates, so I could have some of that back if necessary by overclocking.
A small Java application that (re)computes GB grid carbon intensity, updates some Web pages and flag files, and posts to Twitter, works just fine. User time up from about 4s to 6s.
My largest Java application from the SheevaPlug, my Tomcat-hosted WAR, is pretty slow to start up but is possibly more efficient with memory than before (possibly because of latest JDK vs 'embedded' Java 7).
But the point is that things are working as I copy them across to try out.
To try to improve start-up time I'm trying 'modest' overclocking (to 800MHz, all other clocks and voltages unchanged) set by raspi-config and I have initial_turbo set to try to get to the cpufreq governor quickly! 700MHz is the default ARM clock speed (arm_freq
).
# Work with CPU speed governor to save some juice... # Mild overclocking for when we need it. initial_turbo=60 force_turbo=0 #turns on frequency scaling arm_freq=800 arm_freq_min=100 #sets min frequency core_freq=250 sdram_freq=400 over_voltage=0
Time to boot measured from power being supplied to the board up to when all the LAN LEDs are turned off (in rc.local) and ssh
login is possible is ~105s (and a little under 20m to settle down into a reasonably steady state) including the large Java Web app starting up.
I am also trying Oracle's Java 8 (oracle-java8-jdk
) in the hope that this is more optimised for ARM/RPi, eg to better use hard float. So far it doesn't seem to have broken anything, but I'm not holding out lots of hope! The Java 7 and 8 Oracle packages (nice to have a choice of official JDKs!):
/usr/lib/jvm/jdk-7-oracle-armhf /usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt
At least the is no longer a PermGen in 8, which saves one config headache!
2014-06-30: Performance Again
I don't need X Windows for the Pi (it can be rescued from the text console), so some RAM could be spared at runtime:
update-rc.d lightdm disable
Also I want to try to run without (slow, SD-card-wearing) swap at all, so it can be disabled entirely for now:
sudo update-rc.d dphys-swapfile disable
fail2ban
seems to take enough MB of virtual (~27MB) and resident (~6MB) memory that I may turn it off again or run it intermittently. Although it makes me feel good about detecting ssh
attackers I'm not sure that it's actually protecting me from much, and it's preventing me turning down logging in the auth.log also! I'll decide when I start bringing up other services that need (virtual) memory.
Here are the top few processes by virtual memory use:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2272 root 20 0 272m 145m 9068 S 1.6 30.0 9:55.04 java 2218 root 20 0 27976 1552 1112 S 0.0 0.3 0:00.06 rsyslogd 2361 root 20 0 27200 6048 2400 S 0.3 1.2 0:03.97 fail2ban-server 2590 root 20 0 26528 3688 2620 S 0.0 0.7 0:00.20 console-kit-dae 2657 root 20 0 23312 2932 2456 S 0.0 0.6 0:00.15 polkitd
console-kit-daemon
and polkitd
might also be destined for the chop or at least some tuning...
As per this thread, adding one line to the end of /etc/default/fail2ban
about halves VIRT usage:
ulimit -s 256
and knocks it down into fifth place:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2272 root 20 0 272m 148m 9036 S 2.9 30.5 19:26.93 java 2218 root 20 0 27976 1552 1112 S 0.0 0.3 0:00.07 rsyslogd 2590 root 20 0 26528 3700 2620 S 0.0 0.7 0:00.23 console-kit-dae 2657 root 20 0 23312 2932 2456 S 0.0 0.6 0:00.16 polkitd 3063 root 20 0 12832 6044 2396 S 0.3 1.2 0:03.66 fail2ban-server
Stack-size reduction is probably going to be needed for Apache (httpd) and others as it was for the SheevaPlug, especially in the absence of zram
. I had inserted this in the apache2 init.d script for example:
# NPTL (modern Linux threads) defaults the thread stack size to the setting # of your stack resource limit. The system-wide default for this is 8MB, # which is waaay exaggerated when running httpd. # 512kB should be more than enough (AIX manages on 96kB, Netware on 64kB). ulimit -s 512
If feeling very bold I could put the following in /etc/security/limits.conf
to reduce the default 'soft' stack size from ~8MB as above for all processes, at a significant risk of breaking things...
* soft stack 512 root soft stack 512 * hard stack 2048 root hard stack 2048
This may also adjust environment and command-line space. See also Tweaking stack size of Linux processes to reduce swapping. However, as it doesn't seem to work I'll skip that solution!
Inserting high up in /etc/init.d/rsyslog
the following:
ulimit -s 512
does make a dramatic change to rsyslog's VIRT:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3044 root 20 0 4936 1428 1084 S 0.0 0.3 0:00.02 rsyslogd
down from ~30MB to ~5MB, but I really don't want to hand-edit lots of individual init.d scripts if I can avoid doing so, and it's not even clear what to edit for console-kit-daemon and polkitd. Using /etc/initscript would be a sledgehammer...
I similarly edited /etc/init.d/dbus
with an early ulimit, and polkitd too is much improved:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2634 root 20 0 6928 2928 2456 S 0.0 0.6 0:00.16 polkitd
Now I'm getting somewhere...
# apt-get remove consolekit Reading package lists... Done Building dependency tree Reading state information... Done The following packages will be REMOVED: consolekit lightdm policykit-1 0 upgraded, 0 newly installed, 3 to remove and 4 not upgraded.
which now leaves the top VIRT users as:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2266 root 20 0 270m 148m 9012 S 98.6 30.6 8:28.94 java 2562 root 20 0 9776 3212 2588 S 0.0 0.6 0:00.22 sshd 2352 root 20 0 11328 6012 2364 S 0.3 1.2 0:03.95 fail2ban-server 2641 dhd 20 0 6724 3852 1508 S 0.0 0.8 0:01.25 bash 2667 root 20 0 4752 1824 1452 S 0.0 0.4 0:00.05 bash
which is much better! But fail2ban
may still get disabled, and Apache et al may still need individual ulimit treatment when set up.
I have removed some services that I don't need and that may consume resources and represent a mild security hazard:
apt-get remove nfs-common apt-get remove nfs-kernel-server
A couple of days later I started logging/collecting 5-minute samples of CPU temperature from /sys/class/thermal/thermal_zone0/temp
to look for evidence of overheating or patterns, but nothing much is evident from an initial graph of a little over a day. (The big spike around 8am was probably from direct sunlight on the RPi!)
2014-07-05: GPIO
I have built a very simple 'shield' for the RPi with some matrix board and a suitable socket stacks on top of the RTC board.
On that shield I currently have currently placed a pair of screw terminals connected to GND and to GPIO25 (via a 100Ω resistor for a tiny degree of protection, eg against inductance) and an LED via a 4k7 resistor to GPIO25 also so I can see when the line is on.
If not done since boot, or if subsequently 'unexport'ed, the following incantation (as root) makes GPIO25 available in the filesystem, as an output, eg for shell access:
echo 25 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio25/direction
Then turning the output on requires from the shell as root:
echo 1 > /sys/class/gpio/gpio25/value
and off:
echo 0 > /sys/class/gpio/gpio25/value
So here is a simple script to be run as root to turn my desk light on or off:
#!/bin/sh # Turn on/off the desk light (on GPIO25). # If $1 is not "on" then turn it off. # Set up GPIO if required. if [ ! -e /sys/class/gpio/gpio25/value ]; then echo 25 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio25/direction fi if [ "on" = "$1" ]; then echo 1 > /sys/class/gpio/gpio25/value else echo 0 > /sys/class/gpio/gpio25/value fi exit 0
I have wired up a 3.5A/24VDC 3V-input SSR (Solid State Relay), part CN024D05 ie RS720-3940, with its input from GPIO25 (via a longish cable run to its own box) and output in series with a nominal 4.5W 12V MR16 LED (and back-EMF fast protection diode) powered at 12V from my off-grid system, and I now have a software-controlled solar-powered desk light!
Note that I did not common the grounds, ie the signal and power are separate, which avoids setting up any ground loops or unwanted flows through the RPi.
Not quite I/O but I just installed access to the RPi's hardware RNG with:
sudo apt-get install rng-tools
and added to /etc/modules
bcm2708-rng
which provides a /dev/hwrng
binary readable device, which amongst other things I will use with my EntropyPool Web service in due course.
As an example (root) can dump a single random byte in decimal (0--255), eg for use in a shell script, with:
hexdump -n1 -e '/1 "%u\n"' /dev/hwrng
With /dev/urandom all users will likely be able to run it, and not block.
It would be possible to set up a crude randomised anti-burglar light in summer with entries in root's crontab such as:
1 22 * 4-10 * /usr/local/bin/desklightGPIO/desklight off */5 18-21 * 4-10 * if [ `hexdump -n1 -e '/1 "\%u"' /dev/urandom` -gt 50 ]; then /usr/local/bin/desklightGPIO/desklight on; fi
I added early in /etc/init.d/rng-tools
ulimit -s 512
to reduce rngd
's use of virtual memory from ~6MB to ~3MB.
ADC
To use ABElectronics' ADC Pi Version 2.x I first have to change its i2c address not to clash with the RTC at 0x68, so I've chosen the 0x6A/0x6B configuration from their datasheet.
This board is based on the MCP3424.
I'm likely to have to do something like:
echo mcp3424 0x6a > /sys/class/i2c-adapter/i2c-1/new_device echo mcp3424 0x6b > /sys/class/i2c-adapter/i2c-1/new_device
in /etc/rc.local
to tell the system that the devices are present, and then maybe C or C++ or Python or i2cget and i2cset from the shell to read and write it.
Having plugged the board in (I now have a triple-decker of RTC, ADC, and my 'shield') I ran:
# i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- UU -- 6a 6b -- -- -- -- 70: -- -- -- -- -- -- -- --
which confirms the new devices visible at 0x6a and 0x6b.
I then manually ran, and added to /etc/rc.local
:
echo mcp3424 0x6a > /sys/class/i2c-adapter/i2c-1/new_device echo mcp3424 0x6b > /sys/class/i2c-adapter/i2c-1/new_device
# ls -ald /sys/class/i2c-adapter/i2c-1/1-* drwxr-xr-x 3 root root 0 Jul 5 21:26 /sys/class/i2c-adapter/i2c-1/1-003b drwxr-xr-x 3 root root 0 Jul 5 21:26 /sys/class/i2c-adapter/i2c-1/1-004c drwxr-xr-x 4 root root 0 Jul 5 21:12 /sys/class/i2c-adapter/i2c-1/1-0068 drwxr-xr-x 3 root root 0 Jul 5 21:19 /sys/class/i2c-adapter/i2c-1/1-006a drwxr-xr-x 3 root root 0 Jul 5 21:19 /sys/class/i2c-adapter/i2c-1/1-006b
shows the devices at 0x68 and 0x6b.
As an extremely crude initial detection of ambient light levels I wired a 1M-dark LDR from 5V to input channel 8, with the expectation of getting near 0 output in dark and max in bright light. The i2c
... tools are a little crude, but:
i2cset -y 1 0x6b 0xe0; sleep 1; i2cget -y 1 0x6b
Does a one-shot maximum-speed conversion of the input on channel 4 of the ADC on 0x6b, ie channel 8 of the board, and returns the top nybble of the result, eg values ranging from 0x00 to 0x07 at my desktop at the moment by drawing the curtains or opening them. I could probably skip the sleep given the conversion speed! I can get the next 8 bits with i2cget -y 1 0x6b 0 w
but the extra data is at this stage probably not needed for, for example, a crude day/night sensor.
Thus the simple anti-burglar cron light might be crudely updated as:
1 22 * 4-10 * /usr/local/bin/desklightGPIO/desklight off */5 18-21 * 4-10 * i2cset -y 1 0x6b 0xe0 && if [ `hexdump -n1 -e '/1 "\%u"' /dev/urandom` -gt 50 -a `i2cget -y 1 0x6b` = "0x00" ]; then /usr/local/bin/desklightGPIO/desklight on; fi
See the power management C++ code, intended to be run periodically (ie every few minutes) from crontab, and which contains i2C support for the LDR amongst other things.
Next I shall take feeds from 5V and both nominal 12V battery supplies (though temporarily close to the load near the RPi) via 47kΩ resistors. Given the further 10kΩ to each ADC input, and the 6.8kΩ to ground, and a FSD of 2.048V, the full-scale should now be ~((47+10+6.8)/6.8)*2.048V = ~19.22V ie ~9.382mV/ulp. The 47kΩ resistors at ±1% tolerance, and the tolerance of the on-board 10kΩ and 6.8kΩ is unknown, so I should probably take the 19.22V as a starting point then calibrate against known values if possible for each ADC input. I may also measure the 3.3V rail. I hope to be able to measure the current draw on the 3.3V side from the 5V rail which should be the bulk of the power consumed by the RPi itself, and later into the 5V side with a high-side current-sense amplifier such as MAX4080SAUA+ or TS1101-25EG6T or INA138NA/250. Channel assignments are / may be:
- Batt1 (blue wire, red sensor wire, LA), done
- 5V supply voltage monitor
- 5V supply current sense
- Batt2 (purple wire, Li), done
- 3.3V supply voltage monitor
- 3.3V supply current sense
- LDR, done
Note that ADC1 (channels 1--4) and ADC2 (channels 5--8) can be read in parallel if required, doubling throughput.
Having wired up Batt1 and Batt1, initial calibration readings (against a cheap DMM) were:
- BATT1 1328 raw = 12.48V direct to local busbar (calc 12.46V).
- BATT2 1359 raw = 12.77V direct to local busbar (calc 12.75V).
The DMM values match very closely with calculated values, so no fudge factor will be applied per channel. (Note that when connecting to the remote sense terminals with additional in-line resistance the multiplier will need to be adjusted.)
Note that these measured voltages are ~0.6V lower than measured at the k8055, (13.0V and 13.4V) which suggests possibly at least that much voltage drop in just the +ve side of the wiring segment from the service cupboard downstairs to the desk busbar, which would be a bit sad, and a motivator to move equipment (eg WiFi and RPi) down to the service cupboard, eliminating that segment for most uses. Measuring at the Li battery (Batt2) in the with the DMM gives 13.00V, and measuring at the same junction board for Batt1 gives 12.50V, which suggests that possibly the wiring is OK and the k8055/SheevaPlug is miscalibrated, and that I've been beating my batteries up more than is wise!
2014-07-11: I have bought a number of high-side current measuring devices to play with, including the digital I2C-based Adafruit INA219 Current Sensor Breakout via oomlout with the aim of continuously and accurately monitoring power draw from the 12V nominal off-grid solar PV battery stores, for normal logging and at a higher rate for performance/consumption tuning. I may have to remove the on-board SCL/SDA 10kΩ pull-up resistors to avoid overloading the i2c bus (there are other pull-ups already).
Seeing how close the shunt inputs are to low-voltage parts of the board is making me nervous. A small slip/short could toast my RPi and everything connected, which would be particularly tiresome if the SD card was destroyed. Hmm, will have a careful think!
Having wired it up I look for signs of it appearing at address 0x40:
# i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- UU -- 6a 6b -- -- -- -- 70: -- -- -- -- -- -- -- -- # i2cget -y 1 0x40 0 w 0x9f39
and there it is: I can try some measuring once it is all wired up...
Some time later... I now have power monitoring working, currently measuring supply to the SheevaPlug. Here are some monitoring lines (5-second intervals):
AL 30 B1 12597 B2 13026 P 2581 AL 30 B1 12597 B2 13026 P 2584 AL 30 B1 12597 B2 12998 P 4250 AL 30 B1 12597 B2 12988 P 4306
The first two are ~2.5W, and the last two are ~4.3W with the CPU busy. Note that when this measurement was taken all USB devices had been unplugged, so this represents consumption by the SheevaPlug itself.
INA initial read 39 9f. INA bus voltage read 61 c2 = 12384. INA shunt voltage read 7 f3 = 0.020350V. INA current read f e6 = 0.203500A. INA power read 9 f2 = 2546mW.
ie that the voltage into the 5V regulator is 12.4V and the current 204mA.
2014-07-11: Moving Services
2014-07-11: NTP: the NTP configuration was updated with some of the features from the SheevaPlug to be more suitable for the free public service that ntp.exnet.com provides, and the two main DNS aliases were moved across in stages to the RPi. All seems satisfactory.
Even without being part of one of the NTP pools (which has proven too burdensome in the past in CPU and bandwidth terms, I think), it is clear that the NTP service is still supporting several hundred clients.
Gallery/PG2K: moved the PG2K master from SheevaPlug to RPi, copying the data from the USB thumbdrive on to the RPi SD card, then (on 2014-07-12) changing the DNS entry (with TTL of ~1d) then bringing down the old master, capturing some logs and config and history, bringing up the new master with the history, and prodding one of the mirrors to connect immediately to the new master (others will need DNS timeouts).
random.hd.org: his was a good moment to move the co-located random.hd.org across also, updating DNS and Tomcat appropriately, and random.hd.org's own config to make use of the new hardware RNG support and local environmental data.
2014-07-12: Apache: starting to set up Apache (2) to bring over the static sites by degrees:
apt-get install apache2
which yielded the error:
[....] Starting web server: apache2(98)Address already in use: make_sock: could not bind to address 0.0.0.0:80 no listening sockets available, shutting down Unable to open logs Action 'start' failed. The Apache error log may have more information. failed! invoke-rc.d: initscript apache2, action "start" failed.
because Tomcat already has one of the addresses bound. Editing /etc/apache2/ports.conf
to listen on appropriate addresses allows Apache to start. There will be plenty of tuning and tweaking to come, starting with some ulimit magic (in envvars) to reduce stack space, and cutting the number of servers/threads/runners to fit this small box!
2014-07-14: displaying the Off-Grid Power page again, this time with added live power consumption and local 12V bus volts, albeit SheevaPlug power draw initially rather than the RPi.
A small experiment indicates that plugging in the Sunny Beam via a 2-way USB hub bumps up consumption by ~1W, thought it is possible that the Sunny Beam battery is charging.
Missing out the hub seems to only cause an additional draw of ~200mW, in line with what was observed before.
Time to get sendmail set up. Always a fun one.
# apt-get install sendmail-bin
It's removed exim (which I installed just to get lockfile
, it's creating keys and all sorts of exciting stuff, and it's inviting me to run sendmailconfig
later. I will deliver mail to sendmail by tunnelling over SSH as in the old days, as I know how to do it and it's safe.
Apprently the following scary warnings from doing a make
are not fatal:
*** ERROR: FEATURE() should be before MAILER() *** MAILER(`local') must appear after FEATURE(`always_add_domain')*** ERROR: FEATURE() should be before MAILER() *** MAILER(`local') must appear after FEATURE(`allmasquerade')*** ERROR: FEATURE() should be before MAILER()
but I trimmed the offending trailing lines from sendmail.mc
anyway without apparent bad results.
And:
# apt-get install sensible-mda
I'm also going to set up a simple secure POP3 daemon, rather than tunnelling a session over SSH. Direct secure access will need a slightly more open firewall and a greater attack surface.
# apt-get install dovecot-pop3d
and I've enabled the dovecot
and sasl
jails for fail2ban
as a precaution.
Dovecot has rather intimidating configuration (and I'm used to sendmail's!). First up is to drastically trim its resource limits for the RPi and more or less my sole usage in /etc/dovecot/conf.d/10-master.conf
and enable just pop3s.
2014-07-16: the DNS primary will be BIND:
# apt-get install bind9 bind9-doc
Some tweaking of current usage was necessary, including extra care on file permissions and ownership since the daemon is now running as the user 'bind'.
2014-07-11: Services Moved from SheevaPlug
Services moved, partially moved, or yet-to-be moved:
- NTP done: 2014-07-11, all aliases pointing at re-configured RPi. Apparently there are several hundred clients...
- Gallery done: 2014-07-11.
- SVN: done: 2014-07-12.
- Apache: done 2014-07-13.
- SMTP/POP3: done: 2014-07-16.
- DNS: done: 2014-07-16.
- Dump-load control done: 2014-08-09.
- OpenTRV stats monitor done: 2014-08-11.
2014-07-16: Reboot!
As of late evening 2014-07-16 (22:30BST) the SheevaPlug is shutdown and disconnected, and the RPi is providing all services. Boot-up power for the RPi is ~2.7W vs the 2.5W--4.4W draw of the SheevaPlug (without k8055 or USB hub(s)). About 30m after boot (some services take a long time to fully start) power draw is ~2.3W and the RPi is handling 30 network packets per second.
Note that random misuse of (attacks on) exposed public services such as ssh
were pushing up system load and power consumption. A bit of tweaking of sshd
against attacks (such options as MaxStartups and AllowUsers) kept down load directly and made it possible for fail2ban
to notice the attack and shut out the IP addresses automatically with a noticeable drop in load!
Interestingly the overhead of the cron job to run the powermng sampling including power, adds ~200mW to the apparent load! Putting a 5s sleep ahead of the power measurement then logs a correct ~2.3W typical load.
2014-07-17: B+ First Experiment
I now have a RPi Model B+ and an 8GB microSD card. I'm trying to dd the 4GB image saved above onto the 8GB card (using my Mac) to see if the B+ will boot off it (though I don't actually have keyboard or screen easily to hand at this moment) and what power consumption is.
There is a slight risk that the image will not be suitable, and/or that the tweak that I use to turn off the LAN LEDs to save 50mW (not even immediately obvious on the B+ board) may damage something.
A Model B board (no USB or video or Ethernet connection), after being given a couple of minutes to get through boot, runs at ~2.5W reported drawn by my mains power supply.
The equivalent B+ steady draw, assuming that it booted correctly, is ~1.5W. That probably corresponds to ~1W drawn by the board itself, and an mains adapter efficiency of ~60%.
2014-07-19: B+ Live
I tried to dd (on my Mac) my Model B SD card to a new microSD card (SanDisk Ultra SDSDQUA-128G-G46A, Class 10 / UHS-1, ~£70 from MyMemory), both nominally 128GB. It took ~5h and did not quite work:
[79:/Users/dhd/.ssh] dhd# time dd bs=1m if=/dev/rdisk2 of=/dev/rdisk1 54879+0 records in 54878+0 records out 57543753728 bytes transferred in 7923.878570 secs (7262069 bytes/sec) dd: /dev/rdisk1: short write on character device dd: /dev/rdisk1: Input/output error 121942+0 records in 121941+1 records out 127864930304 bytes transferred in 17441.687219 secs (7330995 bytes/sec)
because it turns out that the new card is slightly smaller than the old, thus truncating the last/data partition.
So I logged on on TV console, removed the last partition with fdisk (parted just whined and stupidly refused to let me do anything at all), recreated the final partition, put in an ext4 filesystem again with previous parameters, mounted under /lmnt
, mounted the old SD on USB and that old partition (/dev/sda3) on /mnt
, and prepared to copy the data partition over.
I tried doing cp -a /mnt/* /lmnt
but it seemed to hang, so instead I did an rsync
, which worked, and took about 8h.
Note that the llctl
program still seems to work. Though I can only see two of the three LEDs (moved to the network socket). And indeed of my three stacked GPIO cards (RTC, ADC and my own hand-crafted) all worked exactly as before. Well done RPi Foundation on backwards compatibility!
Power consumption seems to be down to ~1.5W once everything is at steady state, so a reduction of ~0.8W/~30%.
(Note that the power figure includes any losses in the 12V-to-5V PT78HT205V 10W, 5V, 2A switching regulator, and any USB devices plugged in.) Max (stress) consumptions of the various RPi models are reported as Pi1B+/Pi2B/Pi3B 0.35A/0.82A/1.34A circa 2016.
2014-08-11: Power Again
With all services moved over, and a new one or two, some observations:
- The Sunny Beam monitor permanently plugged into USB to allow continuous monitoring draws ~100mW, in part apparently because it doesn't turn its graphics off, so a USB power-down arrangement might avoid some or all of that, especially at night and in winter when readings are not useful for many hours.
- The new dump-load relay (modified from the latest OpenTRV boiler control) uses about 250mW when operating/dumping, though is better than the ~1W of the previous arrangement with the 12V relay driven by the k8055. A dimmer LED (1k load resistor?) could save up to about 10% of that. (Note: seems to have stuck 'on' during evening of 2016-10-22.)
- It's not yet clear how much the RXTX library hurts power consumption; at several hundred (unnecessary) wakeups per second the effect was significant for the SheevaPlug and MacBook Air. Initial observations suggest another 100mW--200mW, possibly from stopping the CPU sleeping properly as expected.
2014-08-18: I tried lowering the network port speed to see if that made any difference to power drain (watching the reported number on my powermng tool looping) because at 10Mbps Ethernet may be able to idle more quietly, trying:
# ethtool -s eth0 autoneg off speed 10
and then:
# ethtool -s eth0 autoneg on
to switch back to a negotiated (100Mbps duplex) rate, and if there was any difference at all it was minor and 10Mbps was higher power.
2015-05-15: Device Tree
2015-05-15: an apt-get update then dist-upgrade brought me into the wonderful world of device tree, signalled by the fact that I no longer open the i2c device that I'd been using.
Following this exposition I ran:
sudo raspi-config
to enable device tree and i2c, which had the effect of adding this to the end of /boot/config.txt
:
dtparam=i2c_arm=on
To Do
- Consider adjusting /etc/default/tmpfs so that everything under /run is one tmpfs, and /tmp is also a tmpfs, possibly with reduced max size, partly to reduce SD card traffic and partly to reduce kernel/VMEM use.