Home > Allwinner H-Series, Hardware, Linux, Linux 4.x, Testing, Ubuntu > NanoPi Duo Quick Start Guide – Ubuntu, Breadboard, Mini Shield & mSATA SSD

NanoPi Duo Quick Start Guide – Ubuntu, Breadboard, Mini Shield & mSATA SSD

As far as I know NanoPi Duo is the only quad core ARM Linux development board that can fit on a breadboard. We’ve already seen it’s much smaller than Raspberry Pi Zero, and the company offer a mini shield exposing USB ports, Ethernet, a few I/Os, and an mSATA slot in in NanoPi Duo Starter Kit Review – Part 1: Unboxing and Assembly.

I’ve finally played with it this week-end, and will report what I had to do to blink a LED when connected to breadboard, and my experience using the mini shield with  an mSATA SSD, WiFi connectivity, and cooling under load.

Flashing Ubuntu 16.04.2 firmware image to NanoPi Duo

As with many other Allwinner development boards, you should first check if Armbian is available for the board. NanoPi Duo is not supported, but it’s said to work with Orange Pi Zero image minus support for WiFi. Since the latter is rather important if you’re going to use the board standalone, I instead went with FriendlyELEC’s Ubuntu Xenial image (nanopi-duo_ubuntu-core-xenial_4.11.2_20170908.img.zip) shared on the company’s Wiki.

I flashed the (compressed) image with Etcher – available for Windows, Linux, Mac OS, on a 8GB micro SD card (Sandisk Ultra).

Using NanoPi Duo as a Breadboard-friendly Development Board

Once this is done, insert the micro SD into the board, insert it into a breadboard, and connect your circuit (in my case a 5V LED connected to GPIOG11 via a transistor). Most other breadboard-friendly WiFi boards include either a USB to TLL chip allowing to access the board’ serial console over USB (e.g. ESP32 boards), or firmware that setups the board as an access point for initial configuration (e.g. LinkIt Smart 7688 Duo). So you just need to connect power and you’re good to go.

Click to Enlarge

But NanoPi Duo’s board has no serial to USB chip, and the current firmware does not setup an access point by default, so I’ll need to connect a USB to TLL debug board too, as shown above. I then started minicom with 115200 8N1 configuration, and connected the board to one of the USB port of my computer for power, and the boot worked just fine.  See complete boot log for reference:

The system will autologin, and show a welcome boot message similar to what is found in Armbian build.

Let’s check some of the relevant info:


The image is based on Ubuntu 16.04.2 with a recent Linux 4.11.2 although apparently not updated with the latest patchsets found in Linux 4.11.12. The rootfs has been automatically resized at boot time so I have 5.9GB free on the partition, and 497MB RAM is accessible from Linux.

There are some useful pre-loaded modules for WiFi, USB mass storage, and IPv6:


Most people will want to use WiFi in this configuration (breadboard use), and nmtui text user interface is normally recommended, but the UI was really messy in the serial console, so I reverted to use nmcli instead as explained in the Wiki. First let’s list the network devices:


WiFi is disabled, so we’ll enable it and scan nearby routers:


I repeated the last command three times, but my main (2.4 GHz) router was not listed. So let’s attach a u.FL antenna…

Click to Enlarge

… to see if I can get a stronger signal for the already detected access points, and find my main router (CNX-TRANSLATION):


Success! I can now see CNX-TRANSLATION SSID, and CNX-SOFTWARE SSID signal is much stronger. However, I lost sonoff-office (which I did not plan to use).  We can connect to the access point of your choice as follows:


Oops. I did not work out as expected. Listing the access points again:


That’s crazy… All my APs are gone! But after persevering a few more times, I was finally able to connect and get an IP address:


We can now update the system to make sure it has the latest packages:


The board could download all the ~150 packages without issues, so once the connection is up it looks fairly stable. The update will take a while, so you may want to try a few other features of the firmware. For example, the company pre-installed NanoPi-Monitor, a fork of RPi-monitor, which allows you to monitor CPU and memory usage, temperature, up time, etc.. directly from a web browser via http://board_IP:8888.

Click to Enlarge

I was also be able to connect via SSH using either pi/pi or root/fa username and password.

The last step of this section of our tutorial is to control GPIOs. Since the board runs Linux 4.11, we may have hoped the new GPIO subsystem might be implemented, but lsgpio is not installed, and instead the company recommends to use WiringNP, a fork a WiringPi. It’s pre-installed, so we can use it right away to list GPIOs:


I’ve connected the LED to GPIOG11 (mapped to pin 16 in WiringNP), and it’s on by default, so let’s pull it down:


The LED turns off, and we can turn it back on with:


Let’s write blink.c to blink our LED every 500 ms:


We can now build and run it, and the LED will blink as expected:


You need to run blink as root as it is required by wiringPiSetup() function: “wiringPiSetup: Must be root. (Did you forget sudo?)”, but there are workarounds roughly explained in the Wiki. The user key/switch on NanoPi Duo board is connected to “GPIOL3/K1” pin, but is not listed by gpio readall command, so this would have to be looked into.

Other modes such as PWM,  I2C, SPI, UART, PWM should also be supported, but out of the scope of this quick start guide.

Beside “GPIOs”, Ethernet, USB, composite video, and various audio signal are also exposed, so it can make for some very interesting DIY projects.

NanoPi Duo with mini Shield and SSD

I took out the micro SD card, and inserted in my other NanoPi Duo board connected to the mini shield with an mSATA SSD. This time I connected the board through a 5V/2A power supply, and added an Ethernet cable.

Getting started is much easier since we are using Ethernet here. Just find your board IP address in your router’s DHCP client list, or via tools like arp-scan, and connect over SSH with pi user:


We can see the SSD is detected (sda – 59GB):


but not mounted:


So I formatted the drive with EXT-4…


and mounted it in a temporary directory to check it out:


In theory the SSD should have much better performance than the micro SD card, even though it’;s connected through a USB to SATA chip. But let’s no assume anything, and first run iozone on the 8GB micro SD provided by FriendlyELEC:


and repeat the same test on the SSD:


We can see that both sequential performance, and especially random I/O are much better on the SSD drive, so it would make perfect sense to move the rootfs from the micro SD card to the SSD.

But before going there, I’ve been asked to check run smartctl on the drive:

There are many parameters reported, and one of them is the drive temperature which apparently went up to 52°C, and as low as 19°C. The latter could not have happened my location, since temperature never went below 24°C.

Time to move the rootfs to the SSD, and to do so I’ll adapt the instructions for CubieTruck, another Allwinner development board.

As we’ve seen above, the roofs is mounted to /dev/mmbblk0p2, so let’s mount it in another directory, and copy the content to the SSD:


We need to let the boot partition know our rootfs has moved. Let’s go to /boot directory, and edit boot.cmd text file (used to be uEnv.txt in CubieTruck) by changing root from /dev/mmcblk0p2 to /dev/sda in the bootargs with all other parameters unchanged:


The final step to create boot.scr binary file using the command below, and reboot.


After a few seconds, we should be able to use login and verify the rootfs has now moved to sda.


Success! The boot partition is still in the micro SD card since Allwinner platform can’t boot from USB. You can reclaim mmcblk0p2 partition on the SD card to do something else. Eventually we should be able to do away completely with the micro SD card by booting from the SPI flash in the board, but I think this is still work in progress (TBC).

Stress Testing & WiFi Performance

Such small board is not designed for heavy load, as even with an heatsink, heat dissipation does not work as well as on larger boards (with a large ground plane). To demonstrate that I ran stress on all 4 cores, and monitored temperature and CPU with NanoPi-Monitor.


Click to Enlarge

Stress was started at 19:32, on based on the chart above the CPU cores ran at 1008 MHz for about two minutes with the CPU temperature quickly increasing from around 50 to 70°C, and after the CPU frequency oscillates between 624 MHz and 1008 MHz to keep the temperature in check. Ticking “active CPUs” would show 4 cores are used at all times during stress. Performance does not completely collapses but the system cannot run at 1008 MHz at all times without additional cooling. Whether this is an issue or not depends on your specific load/use case.

NanoPi Duo relies on Allwinner XR819 WiFi module, and while it’s working decently on my Orange Pi Zero, I had reports of poor peformance and issues in the past, and as we’ve seen above I had some troubles finding and accessing my access points with NanoPi Duo. So it might be good to have a look at WiFi performance too.

As a side note, nmtui is usable while connecting via SSH instead of minicom / serial connection, so if you prefer a user interface you may want to use this tool instead of nmcli when using the mini shield.

That time I could also list all my local access points even with no external antenna attached:


But I could not ssh to the board via the WiFi interface (192.168.0.115) from my computer:


So I rebooted the board, and could login again. All good, so I ran iperf with chip antenna (only):

  • upload:

  • download:


The board was located in my usual (TV box, development board) test location about 4 meters from the router (+ wall), and results are rather poor, so I tried again with an external antenna:

  • upload:

  • download:


Not fantastic, but still about twice as fast, and with much better signal strength so loss of connection should be less likely improving reliability.

  1. tkaiser
    October 30th, 2017 at 18:42 | #1

    Just a few notes:

    – by putting something like this to /etc/rc.local the SSD will perform better (both in benchmarks and real world)

    – nmtui and serial console: Have you checked how $TERM env is defined or tried to set export TERM=linux for example?

    – ‘Active CPUs’ in RPi-Monitor is useless here since mainline kernel throttling strategies differ from Allwinner’s legacy Android kernel (no idea why FriendlyELEC did a 1:1 copy&paste of my template that was developed to understand thermal behaviour of this platform 1.5 years ago). At least your testing shows that there is a huge need to improve throttling settings with mainline kernel since currently they’re not optimized at all

    – referencing the rootfs with device paths (‘root=/dev/sda’ above) is dangerous since these can change. Better use UUID instead 🙂

  2. tkaiser
    October 30th, 2017 at 19:09 | #2

    And I forgot to ask: Is there a SPI NOR flash chip already soldered on the lower PCB side next to DRAM?

  3. October 30th, 2017 at 19:13 | #3

    @tkaiser
    Yes, see first part of review.

  4. October 30th, 2017 at 19:42 | #4

    @tkaiser
    About terminal:

    changed that to linux:

    But the result is the same.

  5. tkaiser
    October 30th, 2017 at 19:55 | #5

    @cnxsoft
    Misunderstanding. I meant checking how $TERM is set when you’re connected through SSH (eg. this will read ‘xterm’) and then use exactly this over the serial connection either by telling your tool of choice or defining $TERM later on the remote host (there the ‘export TERM=’ should happen). Maybe this already works:

  6. October 30th, 2017 at 21:01 | #6

    @tkaiser
    OK.. Got it… But still not luck.
    I can see serial is only black & white, while connecting over ssh is in color.
    I think I may have to change some settings in minicom too.

  7. tkaiser
    October 30th, 2017 at 21:29 | #7

    BTW: On those boards with low amounts of DRAM using zram (instead of swap) is always a good idea. In Ubuntu it’s just an

    followed by a reboot and then half of the physical DRAM will be used as zram. In which situations depends on vm.swappiness setting (can be checked with sysctl command) so to activate zram only for emergency situations the following would be sufficient:

  8. Paul
    October 31st, 2017 at 00:12 | #8

    @cnxsoft
    Thanks for testing the poor WiFi performance, which sadly even with external antenna is no better than for ESP32 modules, or in previous boards that use XR819 chip. I look forward to when you test some SBC’s with WiFi able to reliably transfer 30 Mbits/sec to their Ethernet port.

  9. tkaiser
    November 1st, 2017 at 16:35 | #9

    @cnxsoft
    Yesterday a user submitted NanoPi Duo bits to Armbian’s build system as pull request, we switched to ‘officially supported’ status and a Debian Stretch image has been generated: https://forum.armbian.com/topic/5430-armbian-for-nanopi-duo/?do=findComment&comment=42503

    Wi-Fi ‘performance’ is said to be +20 Mbits/sec over a short distance but I’m more curious how mSATA performance would look like comparing Armbian’s settings with the one from the official OS image 🙂

  10. Ext4
    November 8th, 2017 at 18:07 | #10

    When I type following code:
    setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/sda rootfstype=ext4 rw rootwait fsck.repair=${fsck.repair} panic=10 ${extra} fbcon=${fbcon}

    Bash returns the following error:
    fsck.repair=${fsck.repair}: bad substitution

    What’s wrong here?

  11. tkaiser
    November 8th, 2017 at 19:03 | #11

    Ext4 :
    What’s wrong here?

    Trying to execute u-boot code (bootscript) in a Linux shell.

  12. November 8th, 2017 at 19:03 | #12

    @Ext4
    Maybe some spaces or other character issue?
    Try to only modify the part with root= from the original file.

  1. No trackbacks yet.