probonopd
9/23/2017 - 6:40 PM

Orange Pi Zero

Orange Pi Zero

Orange Pi Zero

Ideas

  • Port HomeServer to it
  • Read-only thanks to overlayroot
  • Native serial for Viessmann w/o USB-to-Serial
  • Native 433 MHz sending w/o Arduino
  • Native Audio output w/o USB dongle; can attach small amp board
  • Webcam via USB with motion
  • Could play webradio and possibly Spotify Connect
  • https://github.com/gravaigu/doorphone/blob/master/src/doorphone.py SIP door phone (written in Python - extend to full phone)
  • No analog to digital converter

Features

  • sudo nmtui to join WLAN networks (at least in the Debian version of Armbian)
  • The device acts as a USB gadget by default(!) which means one can access the serial port over USB which is also used to power the device. So to develop, just attach it to e.g., the Mac USB and it will be powered and accessible with screen /dev/tty.usbmodem1a121 115200 (to also see the early boot messages of the bootloader, need to use a real serial adapter though)
  • Can boot (at least u-boot) from built-in Flash (not tried yet)
  • Can be used with Allwinner USB based flashing tool
  • Can boot from SD card. I used Raspbian Ubuntu Xenial. Made read-only using the overlayroot package
  • Using u-boot can also boot from USB
  • SPIF (yay, BOSE!)

Make it announce itself in the network

First things first. This should be the default. Incredibly it still isn't.

apt install -y avahi-daemon
cd /etc/avahi/services/
wget -c https://raw.githubusercontent.com/lathiat/avahi/master/avahi-daemon/sftp-ssh.service
wget -c https://raw.githubusercontent.com/lathiat/avahi/master/avahi-daemon/ssh.service
cd -
service avahi-daemon restart

Now it can be accessed, e.g., by Linux desktops under Network as a "file share".

Make it read-only

This package seems to exist only in the Ubuntu version of Armbian, not in the Debian one. On Debian, fsprotect or bilibop-lockfs can probably be used instead.

# On Debian I COULD NOT GET IT TO WORK USING THIS SO FAR, only on Ubuntu
# On Debian I get:
# Failure: overlayroot: missing kernel module overlayfs
# in early boot
# The "solutions" in
# https://forum.armbian.com/topic/1526-armbian-in-read-only-mode/
# are not really convincing/clean...
wget http://mirrors.kernel.org/ubuntu/pool/main/c/cloud-initramfs-tools/overlayroot_0.27ubuntu1_all.deb
sudo apt install busybox-static
dpkg -i overlayroot_0.27ubuntu1_all.deb
dpkg -f install
sudo apt update
apt-get remove unattended-upgrades
mv /usr/lib/apt/apt.systemd.daily /usr/lib/apt/apt.systemd.daily.DISABLED
apt-get install overlayroot
echo 'overlayroot="tmpfs"' > /etc/overlayroot.conf

Use overlayroot-chroot to make edits to the system:

cd /media/root-ro
mount -t proc proc proc/
mount -t sysfs sys sys/
mount -o bind /dev dev/
overlayroot-chroot

Check and minimize space in RAM used by overlay files

df -h /media/root-rw
rm -rf /media/root-rw/overlay/var/

433 MHz remote controlled outlets

git clone https://github.com/zhaolei/WiringOP.git -b h3
cd WiringOP/
sudo bash build 
gpio readall

root@orangepizero:~/WiringOP# gpio readall
 +-----+-----+----------+------+---+-Orange Pi+---+---+------+---------+-----+--+
 | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 |     |     |     3.3v |      |   |  1 || 2  |   |      | 5v       |     |     |
 |  12 |   8 |    SDA.0 | ALT3 | 0 |  3 || 4  |   |      | 5V       |     |     |
 |  11 |   9 |    SCL.0 | ALT3 | 0 |  5 || 6  |   |      | 0v       |     |     |
 |   6 |   7 |   GPIO.7 | ALT3 | 0 |  7 || 8  | 0 | ALT3 | TxD3     | 15  | 13  |
 |     |     |       0v |      |   |  9 || 10 | 0 | ALT3 | RxD3     | 16  | 14  |
 |   1 |   0 |     RxD2 | ALT3 | 0 | 11 || 12 | 0 | ALT3 | GPIO.1   | 1   | 110 |
 |   0 |   2 |     TxD2 | ALT3 | 0 | 13 || 14 |   |      | 0v       |     |     |
 |   3 |   3 |     CTS2 | ALT3 | 0 | 15 || 16 | 0 | ALT3 | GPIO.4   | 4   | 68  |
 |     |     |     3.3v |      |   | 17 || 18 | 0 | ALT3 | GPIO.5   | 5   | 71  |
 |  64 |  12 |     MOSI | ALT4 | 0 | 19 || 20 |   |      | 0v       |     |     |
 |  65 |  13 |     MISO | ALT4 | 0 | 21 || 22 | 0 | ALT3 | RTS2     | 6   | 2   |
 |  66 |  14 |     SCLK | ALT4 | 0 | 23 || 24 | 0 | ALT4 | CE0      | 10  | 67  |
 |     |     |       0v |      |   | 25 || 26 | 0 | ALT3 | GPIO.11  | 11  | 21  |
 |  19 |  30 |    SDA.1 | ALT3 | 0 | 27 || 28 | 0 | ALT3 | SCL.1    | 31  | 18  |
 |   7 |  21 |  GPIO.21 | ALT3 | 0 | 29 || 30 |   |      | 0v       |     |     |
 |   8 |  22 |  GPIO.22 | ALT3 | 0 | 31 || 32 | 0 | ALT3 | RTS1     | 26  | 200 |
 |   9 |  23 |  GPIO.23 | ALT3 | 0 | 33 || 34 |   |      | 0v       |     |     |
 |  10 |  24 |  GPIO.24 | ALT3 | 0 | 35 || 36 | 0 | ALT3 | CTS1     | 27  | 201 |
 |  20 |  25 |  GPIO.25 |  OUT | 1 | 37 || 38 | 0 | ALT3 | TxD1     | 28  | 198 |
 |     |     |       0v |      |   | 39 || 40 | 0 | ALT3 | RxD1     | 29  | 199 |
 +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 +-----+-----+----------+------+---+-Orange Pi+---+------+----------+-----+-----+
 
git clone https://github.com/r10r/rcswitch-pi
cd rcswitch-pi/
sed -i -e 's|-lwiringPi|-lwiringPi -lpthread|g' Makefile # Need to patch so that it compiles
# Edit send.cpp to set the wPi pin (wPi 0 by default)
make
strip send

./send 4 2 1 # Works; switches Conrad RSL366 DIP IV key 2 on

NOTE: If you get a segfault, you are running into the issue solved here, need to change send.cpp to:

(...)
int systemCode = atoi(argv[1]);
(...)
printf("sending systemCode[%i] unitCode[%i] command[%i]\n", systemCode, unitCode, command);
(...)

patchelf

git clone https://github.com/NixOS/patchelf
cd patchelf/
./bootstrap.sh 
./configure 
make
sudo make install

sunwait

wget http://www.risacher.org/sunwait/sunwait-20041208.tar.gz
tar xfv sunwait-20041208.tar.gz 
cd sunwait-20041208/
make
strip sunwait 

From http://www.risacher.org/sunwait/: For example, consider this line from my crontab:

01 00 * * * sunwait civ start 38.794433N, 77.069450W ; br b6 off

This line executes at at one minute after midnight, waits until the start of civil twilight, then runs the command br b6 off (which turns off my carriage light).

Audio

Check overlays at https://docs.armbian.com/User-Guide_Allwinner_overlays/

Need to enable audio overlay

nano /boot/armbianEnv.txt
# Make sure to have these two lines as separate lines
overlay_prefix=sun8i-h3
overlays=analog-codec i2c0 spi-spidev uart1 uart2 usbhost2 usbhost3

Reboot and set the volume using alsamixer. Known to work in both versions of Armbian.

root@orangepizero:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Codec [H3 Audio Codec], device 0: CDC PCM Codec-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
  
root@orangepizero:~# aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
default
sysdefault:CARD=Codec
    H3 Audio Codec, 
    Default Audio Device
dmix:CARD=Codec,DEV=0
    H3 Audio Codec, 
    Direct sample mixing device
dsnoop:CARD=Codec,DEV=0
    H3 Audio Codec, 
    Direct sample snooping device
hw:CARD=Codec,DEV=0
    H3 Audio Codec, 
    Direct hardware device without any conversions
plughw:CARD=Codec,DEV=0
    H3 Audio Codec, 
    Hardware device with all software conversions

I think I would want plughw:CARD=Codec,DEV=0 to be the default for the system but how can I do this?

Radio

For a very simplistic radio player, add to /etc/rc.local before the exit 0 line:

echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6

ifconfig wlan0 up
sleep 2 ### FIXME
ifconfig wlan0 up
sleep 3 ### FIXME

wget http://swr-swr3-live.cast.addradio.de/swr/swr3/live/mp3/128/stream.mp3  -O - | mpg321 - & 

SIP

I want to make this into a proper SIP client desk phone using a speaker as well as a proper handset.

python-pjsip

If we can get this to work, we could eventually write it in C like http://www.pjsip.org/pjsip/docs/html/page_pjsip_sample_simple_pjsuaua_c.htm

In the Debian version:

sudo apt install -y python-pjproject

RUNS - I can use this with the example scripts! https://svn.pjsip.org/repos/pjproject/trunk/pjsip-apps/src/python/samples/ but when I try to change the sound device, I get

10:33:20.305    pjsua_aud.c  .Unable to open sound device: Unknown error from audio driver (PJMEDIA_EAUD_SYSERR) [status=420002]
Exception: Object: Lib, operation=set_current_sound_devices(), error=Unknown error from audio driver (PJMEDIA_EAUD_SYSERR)

Others seem to have had the same issue, https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=854188 - unfortunately there is no resolution but someone suggested "I was able to use PJSIP 2.5.5 by compiling the sources. pjsystest and pjsua showed no issue with sound device". So we may need to compile this from source. And indeed, when cross-compiled from source, it works! I am using https://github.com/probonopd/pjsua-static/releases

In the Ubuntu version this only seems to exist starting with artful, but we have xenial. Argh! https://packages.ubuntu.com/search?keywords=python-pjproject

Using the sample code from https://trac.pjsip.org/repos/wiki/Python_SIP/Hello_World I can use

python test.py sip:music@iptel.org

Eventually I would want to use a loop like in https://raw.githubusercontent.com/hanshuebner/node-pjsip/master/pjsip-test.py to be like a real phone, and use a dialpad and display etc.

Cross-compiled pjsua

Cross-compilation works on Xubuntu 16.04 as the compile host and Ubuntu Xenial Raspbian on the device. I am providing a cross-compiled version at https://github.com/probonopd/pjsua-static.

# https://www.acmesystems.it/arm9_toolchain

sudo apt-get -y install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf

# http://theo.cc/blog/2012/04/04/compile-pjsip-and-pjsua-voip-client-for-the-kindle-3/

wget ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.25.tar.bz2
tar xf alsa-lib-1.0.25.tar.bz2
cd alsa-lib-1.0.25
CC=arm-linux-gnueabihf-gcc ./configure --prefix=/ --host=arm-linux-gnueabihf
make
sudo make install DESTDIR=/usr/arm-linux-gnueabihf/
cd ..

wget http://www.pjsip.org/release/1.12/pjproject-1.12.tar.bz2
tar xf pjproject-1.12.tar.bz2
cd pjproject-1.12
CC=arm-linux-gnueabihf-gcc  ./configure --host=arm-linux-gnueabihf --prefix=/usr
make dep
make
find pjsip-apps/bin -type f -executable -exec arm-linux-gnueabihf-strip {} \;
tar cfvj ../pjsip-apps.tar.bz2 pjsip-apps/bin/
cd ..

# Make sure that the string "alsa" appears in the built binaries,
# otherwise we will get PJMEDIA_EAUD_INVDEV later

To run on the target machine:

With the built-in sound using

 ./pjsip-apps/bin/pjsua-arm-unknown-linux-gnueabihf --capture-dev=0 --playback-dev=0 sip:thetestcall@sip.linphone.org

or with an attached Polycom CX300 or another USB sound device and

 ./pjsip-apps/bin/pjsua-arm-unknown-linux-gnueabihf --capture-dev=1 --playback-dev=1 sip:thetestcall@sip.linphone.org

it works, I hear the music play. And I can adjust the volume (real loud) using the "V" key.

linphone-nogtk

linphonec -s sip:music@iptel.org

Unfortunately this stays entirely silent.

ALSA lib control.c:1373:(snd_ctl_open_noupdate) Invalid CTL default:0
ALSA lib conf.c:4974:(snd_config_expand) Unknown parameters 0
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default:0
ALSA lib conf.c:4974:(snd_config_expand) Unknown parameters 0
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default:0
ALSA lib conf.c:4974:(snd_config_expand) Unknown parameters 1
ALSA lib control.c:1373:(snd_ctl_open_noupdate) Invalid CTL default:1
ALSA lib conf.c:4974:(snd_config_expand) Unknown parameters 1
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default:1
ALSA lib conf.c:4974:(snd_config_expand) Unknown parameters 1
ALSA lib pcm.c:2495:(snd_pcm_open_noupdate) Unknown PCM default:1
Ready
Warning: video is disabled in linphonec, use -V or -C or -D to enable.
linphonec> Establishing call id to <sip:music@iptel.org>, assigned id 1
Contacting <sip:music@iptel.org>
linphonec> Call 1 to <sip:music@iptel.org> in progress.
Call 1 with <sip:music@iptel.org> connected.
Call answered by <sip:music@iptel.org>.
linphonec> Media streams established with <sip:music@iptel.org> for call 1 (audio).
linphonec> Call 1 with <sip:music@iptel.org> ended (No error).

WS2812B Neopixels driven by Python

Connect the data line of the WS2812B Neopixels to pin SPI1_MOSI/PA15. In /boot/armbianEnv.txt we need:

overlays=spi-spidev
param_spidev_spi_bus=1
param_spidev_max_freq=100000000

We can successfully compile the needed Python libraries on the device itself:

git clone https://github.com/doceme/py-spidev.git
cd py-spidev
make -j4
make install
cd ..
git clone https://github.com/joosteto/ws2812-spi.git
find ws2812-spi/ -type f -name '*.py' -exec sed -i -e 's|spi.open(0,0)|spi.open(1,0)|g' {} \;
find ws2812-spi/ -type f -name '*.py' -exec sed -i -e 's|tx=\[\]|tx=\[0x00\]|g' {} \;

Make sure to use spi.open(1,0); we need to use SPI bus 1 since the internal SPI Flash is connected to SPI bus 0.

# Make 16 LEDs red
./ws2812-spi/ws2812.py -c "[[0,255,0]]" -n 16

# Make 16 LEDs white
./ws2812-spi/ws2812.py -c "[[255,255,255]]" -n 16

# Switch 16 LEDs off
./ws2812-spi/ws2812.py -c "[[0,0,0]]" -n 16

Infrared (LIRC)

When I add cir overlay like this:

overlays=analog-codec i2c0 spi-spidev uart1 uart2 usbhost2 usbhost3 cir

then I get in dmesg:

[   10.441267] rc rc0: sunxi-ir as /devices/platform/soc/1f02000.ir/rc/rc0
[   10.441439] input: sunxi-ir as /devices/platform/soc/1f02000.ir/rc/rc0/input0
[   10.445043] rc rc0: lirc_dev: driver ir-lirc-codec (sunxi-ir) registered at minor = 0
[   10.445225] sunxi-ir 1f02000.ir: initialized sunXi IR driver
apt-get -y install lirc

To test, install a TSOP, run mode2 -d /dev/lirc0 and see signals coming in!

i2c OLED display

I am using a 128 X 32 i2c OLED.

Kernel

TODO. miZy has the required kernel module. IT WORKS THERE, the display shows something right from the start of the boot! (However it seems to be configured for a 128 x 64 OLED.)

wget https://github.com/hyphop/miZy-linux-kernel/releases/download/light/miZy.linux.kernel.light.modules.all.tar.gz -O /tmp/modules.tar.gz
tar -tf /tmp/modules.tar.gz | grep ssd130
modules.all/fb_ssd1306.ko

Try this:

https://github.com/notro/fbtft/issues/313

Userland (C)

https://github.com/rm-hull/luma.oled/wiki/Usage-&-Benchmarking#091-i2c-oled

With overlays=analog-codec i2c0

apt-get -y install libi2c-dev
git clone https://github.com/hallard/ArduiPi_OLED
cd ArduiPi_OLED/
echo "BananaPI" > hwplatform
./autogen.sh
# Select "bananapi"
# but edit bcm2835.c to use /dev/i2c-0 instead of /dev/i2c-2
sed -i -e 's|i2c-2|i2c-0|g' bcm2835.c
make
cd examples/
make
./oled_demo -o 2 -v

Works.

Userland (Python)

The Python way of doing this seems to be bloated and exceeds the capabilities of the device:

apt install i2c-tools
i2cdetect -y 0

sudo apt-get install python-dev python-pip libfreetype6-dev libjpeg-dev build-essential
sudo -H pip install --upgrade luma.oled

# Installing Luma.Examples brings the system to a crawl when installing Pillow...
sudo apt install python-setuptools
git clone https://github.com/rm-hull/luma.examples.git
cd luma.examples
sudo -H pip install -e .

  File "/usr/share/python-wheels/CacheControl-0.11.7-py2.py3-none-any.whl/cachecontrol/serialize.py", line 87, in dumps
    ).encode("utf8"),
MemoryError

256 MB not enough?

miZy

miZy is based on OpenWrt DESIGNATED DRIVER (Bleeding Edge, 50015) and busybox, and hence is so tiny that it can be flashed to a suitable SPI Flash chip (in addition to being runnable from microSD).

When attached via USB, it opens an Ethernet port, and you can automatically access it w/o a password at

ssh root@10.1.1.1

More information: https://github.com/hyphop/miZy/wiki

Can even install (some) openWrt packages:

opkg update
opkg_nodeps install announce

Unsuccessful

Compiling pjsip on the device

Installing pjsip from Debian wants to install way too many dependencies, so I am building it from source. Unfortunately, this fails too. Needs too much RAM or CPU to compile? Maybe we need to cross-compile this!

apt -y install libasound2-dev

wget http://www.pjsip.org/release/2.7.2/pjproject-2.7.2.tar.bz2
tar xf pjproject-2.7.2.tar.bz2 
cd pjproject-2.7.2/

cat > pjlib/include/pj/config_site.h <<\EOF
#define PJMEDIA_AUDIO_DEV_HAS_ALSA      1
#undef PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO
#define PJMEDIA_AUDIO_DEV_HAS_PORTAUDIO     0
#include <pj/config_site_sample.h>

#define PJMEDIA_RESAMPLE_NONE   1
#define PJMEDIA_HAS_SPEEX_AEC   1
#define PJMEDIA_HAS_VIDEO   0
#define PJMEDIA_CONF_USE_SWITCH_BOARD 1
EOF

./configure LIBS=-ldl LIBS=-lasound --disable-sdl --disable-ffmpeg --disable-openh264 --disable-libwebrtc
time make dep -j4
time make -j4

### json.o takes more than 30 minutes on this file alone...
### with -j4
### after hours(!) we get
### g++: internal compiler error: Killed (program cc1plus)
### So maybe we need to cross-compile this!

aplay -L # Get the numbers of the sound cards
./pjsua-armv6l-unknown-linux-gnueabihf --capture-dev 4 --playback-dev 0

TODO:

Nextcloud

# Nextcloud on Orange Pi Zero
# https://www.armbian.com/orange-pi-zero/

# https://dl.armbian.com/orangepizero/Ubuntu_xenial_next.7z
# Extract and then burn with Etcher (which unfortunately doesn't handle 7z yet)

# https://ollis.blog/nextcloud-installation-via-snap-und-letsencrypt-auf-ubuntu-leicht-gemacht/

apt update
apt install -y snapd
snap install nextcloud

# Now what? Which port is the server running on? How do I access it?
http://192.168.0.24/index.php
# Says "Finishing..." for a very long time; mysqld seems to eat a lot of CPU during this
# Perhaps 256 MB RAM are not sufficient?
# After a reboot http://192.168.0.24/index.php does not seem to come up anymore

top - 08:43:21 up 6 min,  1 user,  load average: 7.58, 5.39, 2.59
Tasks: 119 total,   1 running, 118 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.5 us, 27.5 sy,  0.0 ni, 21.7 id, 47.3 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   245808 total,     5424 free,   163580 used,    76804 buff/cache
KiB Swap:   122896 total,    45584 free,    77312 used.    21600 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND          
 1939 root      20   0  570840 102568      0 S  32.8 41.7   2:13.54 mysqld           
 1461 root      20   0  844612   1000      0 S   6.6  0.4   0:13.46 mdns-publisher   
 2284 root      20   0  187440  18204  15812 S   6.6  7.4   0:18.63 php-fpm          
 2342 root      20   0  190992  23296  18420 D   6.6  9.5   1:38.71 php              
   46 root      20   0       0      0      0 S   3.3  0.0   0:26.43 kswapd0          
  658 root      20   0   74632   1000      0 S   3.3  0.4   0:01.76 NetworkManager   
 2928 root      20   0    6572   1508   1052 R   3.3  0.6   0:00.08 top     

PS3 Eye Camera

I selected the PS3 Eye Camera because it has a 4 microphone array which I thought could make a good conference phone.

root@orangepizero:~# cat /proc/asound/cards
 0 [Codec          ]: H3_Audio_Codec - H3 Audio Codec
                      H3 Audio Codec
 1 [CameraB409241  ]: USB-Audio - USB Camera-B4.09.24.1
                      OmniVision Technologies, Inc. USB Camera-B4.09.24.1 at usb-1c1b000.usb-1, high 

root@orangepizero:~# cat /proc/asound/CameraB409241/usbmixer 
USB Mixer: usb_id=0x14152000, ctrlif=1, ctlerr=0
Card: OmniVision Technologies, Inc. USB Camera-B4.09.24.1 at usb-1c1b000.usb-1, high 
  Unit: 3
    Control: name="Mic Capture Volume", index=0
    Info: id=3, control=2, cmask=0xf, channels=4, type="S16"
    Volume: min=0, max=1, dBmin=0, dBmax=0

root@orangepizero:~# amixer -c 1 controls
numid=2,iface=MIXER,name='Mic Capture Volume'
numid=1,iface=PCM,name='Capture Channel Map'

root@orangepizero:~# amixer -c 1 contents
numid=2,iface=MIXER,name='Mic Capture Volume'
  ; type=INTEGER,access=rw---R--,values=4,min=0,max=1,step=0
amixer: Control hw:1 element read error: Invalid argument

numid=1,iface=PCM,name='Capture Channel Map'
  ; type=INTEGER,access=r----R--,values=4,min=0,max=36,step=0
  : values=0,0,0,0
  | container
    | chmap-fixed=FL,FR,FC,LFE

root@orangepizero:~# alsamixer -c 1 -V capture
cannot load mixer controls: Invalid argument

alsamixer crashes when selecting this device, and I can't get the recording volume louder...

The same happens when attaching the camera to a PC with Xubuntu 16.04:

me@host:~$ alsamixer 
cannot load mixer controls: Invalid argument

TODO: Check if it works on RPi using https://gist.github.com/AfzalivE/54214bf437ca1775b5b8e7934cc137db

But hey, it's usable as-is when using the "V" control inside pjsua...