Thoughts: duinotech Yun WiFi Shield for Arduino-based devices

I have a little fleet of IoT things that are well, Internet of Things. Right now the latest addition to my fleet is a $80 koala buck duinotech Yun WiFi Shield, which looks like the one on the right.

Basically, this seems to be a rebranded Dragino under Jaycar’s “duinotech” brand, and while the photo shows “YUN SHIELD V1.1.6”, the actual model I got has “YUN SHIELD V1” silkscreened onto it. So I don’t know if this is a copy of something, or if it’s a really old version. Read on if you’re curious to know what this thing is all about from what I dug up – just note that this is a new device to Jaycar and there is hardly a scrap of information or datasheet on the website just yet. So YMMV, but as you can read below, it seems to be compatible with the Dragino Yun Shields.

The box says:

The Yun Shield is a complete compact Linux computer based on the Open WRT firmware which can be controlled by your Arduino­ Main Board. It features WiFi, ethernet, USB and Serial interfaces. Connect a 3G dongle to provide connectivity to your Arduino on the go, or use it as a gateway for your IoT projects. Can also program the attached board via WiFi. Web Configuation Interface.

The first problem I had with the device was that after completing the first-use wizard (which is a duinotech customized setup wizard) the device after 15 minutes of usage just died. It pulsed the 4 LEDs (PWR/LAN/WLAN/SYS) and then remained silent. No WLAN light flickering to tell me it was connecting to my AP, nothing of that sort. It did after about 1 minute seem to “reset” itself and try booting again, most likely after a kernel panic or something. This was 7:30PM at night, and I was exhausted after a shopping trip with family, so I wrote it off as faulty and/or self-bricked.

Today, I checked the batteries I was running the unit off. It said about 5.5V, for 4 x 1.5V alkaline AA cells. Doing some basic math turned out that the cells were around ~1.4 volts, but I think they were getting stressed under the load – this shield requires at least 200mA current to run correctly apparently – and dipping below what the Arduino UNO R3 board could supply to the shield. Slapping some Duracell Ultra AA cells into the 4 AA Battery Holder was enough to revive it and sure enough, it came back to life.

The OS installed on the WiFi Shield looks like it’s been customized by Jaycar/Duinotech to simplify a lot of things, but if you press “LuCI advanced mode” you get the classic OpenWRT Configuration pages. Digging deeper, I noticed that the System Log and Kernel Log hadn’t been removed from the menus. Looking though them revealed that this seems to be a rebranded Dragino Yun Shield (!) as you can see from the kernel log below:

[ 0.000000] Linux version 3.3.8 (dragino@iZu1wdiognxZ) (gcc version 4.6.3 20120201 (prerelease) (Linaro GCC 4.6-2012.02) ) #1 Tue Apr 18 09:12:08 CST 2017
[ 0.000000] bootconsole [early0] enabled
[ 0.000000] CPU revision is: 00019374 (MIPS 24Kc)
[ 0.000000] SoC: Atheros AR9330 rev 1
[ 0.000000] Clocks: CPU:400.000MHz, DDR:400.000MHz, AHB:200.000MHz, Ref:25.000MHz
[ 0.000000] Determined physical RAM map:
[ 0.000000] memory: 04000000 @ 00000000 (usable)
[ 0.000000] Initrd not found or empty - disabling initrd
[ 0.000000] Zone PFN ranges:
[ 0.000000] Normal 0x00000000 -> 0x00004000
[ 0.000000] Movable zone start PFN for each node
[ 0.000000] Early memory PFN ranges
[ 0.000000] 0: 0x00000000 -> 0x00004000
[ 0.000000] On node 0 totalpages: 16384
[ 0.000000] free_area_init_node: node 0, pgdat 803836d0, node_mem_map 81000000
[ 0.000000] Normal zone: 128 pages used for memmap
[ 0.000000] Normal zone: 0 pages reserved
[ 0.000000] Normal zone: 16256 pages, LIFO batch:3
[ 0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[ 0.000000] pcpu-alloc: [0] 0 
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
[ 0.000000] Kernel command line: board=Yun console=ttyATH0,250000 mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,14656k(rootfs),1280k(kernel),64k(nvram),64k(art),15936k@0x50000(firmware) rootfstype=squashfs,jffs2 noinitrd
[ 0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.000000] Primary instruction cache 64kB, VIPT, 4-way, linesize 32 bytes.
[ 0.000000] Primary data cache 32kB, 4-way, VIPT, cache aliases, linesize 32 bytes
[ 0.000000] Writing ErrCtl register=00000000
[ 0.000000] Readback ErrCtl register=00000000
[ 0.000000] Memory: 60936k/65536k available (2565k kernel code, 4600k reserved, 650k data, 180k init, 0k highmem)
[ 0.000000] SLUB: Genslabs=9, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] NR_IRQS:51
[ 0.000000] Calibrating delay loop... 265.42 BogoMIPS (lpj=1327104)
[ 0.080000] pid_max: default: 32768 minimum: 301
[ 0.080000] Mount-cache hash table entries: 512
[ 0.090000] NET: Registered protocol family 16
[ 0.090000] gpiochip_add: registered GPIOs 0 to 29 on device: ath79
[ 0.100000] MIPS: machine is Arduino Yun
[ 0.540000] Setting DogStick2 GPIO
[ 0.560000] bio: create slab <bio-0> at 0
[ 0.570000] SCSI subsystem initialized
[ 0.570000] usbcore: registered new interface driver usbfs
[ 0.570000] usbcore: registered new interface driver hub
[ 0.580000] usbcore: registered new device driver usb
[ 0.580000] Switching to clocksource MIPS
[ 0.590000] NET: Registered protocol family 2
[ 0.590000] IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.600000] TCP established hash table entries: 2048 (order: 2, 16384 bytes)
[ 0.600000] TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.610000] TCP: Hash tables configured (established 2048 bind 2048)
[ 0.620000] TCP reno registered
[ 0.620000] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 0.630000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 0.630000] NET: Registered protocol family 1
[ 0.660000] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.660000] JFFS2 version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[ 0.670000] msgmni has been set to 119
[ 0.670000] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
[ 0.680000] io scheduler noop registered
[ 0.680000] io scheduler deadline registered (default)
[ 0.690000] Serial: 8250/16550 driver, 16 ports, IRQ sharing enabled
[ 0.700000] ar933x-uart: ttyATH0 at MMIO 0x18020000 (irq = 11) is a AR933X UART
[ 0.710000] console [ttyATH0] enabled, bootconsole disabled
[ 0.720000] m25p80 spi0.0: found w25q128, expected m25p80
[ 0.720000] m25p80 spi0.0: w25q128 (16384 Kbytes)
[ 0.720000] 7 cmdlinepart partitions found on MTD device spi0.0
[ 0.720000] Creating 7 MTD partitions on "spi0.0":
[ 0.730000] 0x000000000000-0x000000040000 : "u-boot"
[ 0.730000] 0x000000040000-0x000000050000 : "u-boot-env"
[ 0.730000] 0x000000050000-0x000000ea0000 : "rootfs"
[ 0.740000] mtd: partition "rootfs" set to be root filesystem
[ 0.740000] mtd: partition "rootfs_data" created automatically, ofs=910000, len=590000 
[ 0.740000] 0x000000910000-0x000000ea0000 : "rootfs_data"
[ 0.750000] 0x000000ea0000-0x000000fe0000 : "kernel"
[ 0.750000] 0x000000fe0000-0x000000ff0000 : "nvram"
[ 0.750000] 0x000000ff0000-0x000001000000 : "art"
[ 0.760000] 0x000000050000-0x000000fe0000 : "firmware"
[ 0.780000] ag71xx_mdio: probed
[ 0.780000] eth0: Atheros AG71xx at 0xba000000, irq 5
[ 1.340000] eth0: Found an AR7240/AR9330 built-in switch
[ 2.370000] eth1: Atheros AG71xx at 0xb9000000, irq 4
[ 2.920000] ag71xx ag71xx.0: eth1: connected to PHY at ag71xx-mdio.1:04 [uid=004dd041, driver=Generic PHY]
[ 2.920000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 2.920000] ehci-platform ehci-platform: Generic Platform EHCI Controller
[ 2.930000] ehci-platform ehci-platform: new USB bus registered, assigned bus number 1
[ 2.960000] ehci-platform ehci-platform: irq 3, io mem 0x1b000000
[ 2.980000] ehci-platform ehci-platform: USB 2.0 started, EHCI 1.00
[ 2.980000] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[ 2.980000] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 2.980000] usb usb1: Product: Generic Platform EHCI Controller
[ 2.990000] usb usb1: Manufacturer: Linux 3.3.8 ehci_hcd
[ 2.990000] usb usb1: SerialNumber: ehci-platform
[ 2.990000] hub 1-0:1.0: USB hub found
[ 2.990000] hub 1-0:1.0: 1 port detected
[ 3.000000] Initializing USB Mass Storage driver...
[ 3.000000] usbcore: registered new interface driver usb-storage
[ 3.000000] USB Mass Storage support registered.
[ 3.000000] input: gpio-keys-polled as /devices/platform/gpio-keys-polled/input/input0
[ 3.010000] sdhci: Secure Digital Host Controller Interface driver
[ 3.010000] sdhci: Copyright(c) Pierre Ossman
[ 3.010000] usbcore: registered new interface driver ushc
[ 3.010000] TCP cubic registered
[ 3.020000] NET: Registered protocol family 17
[ 3.020000] Bridge firewalling registered
[ 3.020000] 8021q: 802.1Q VLAN Support v1.8
[ 3.030000] VFS: Mounted root (squashfs filesystem) readonly on device 31:2.
[ 3.030000] Freeing unused kernel memory: 180k freed
[ 4.950000] Error: Driver 'gpio-keys-polled' is already registered, aborting...
[ 6.170000] Registered led device: ds:green:usb
[ 6.170000] Registered led device: ds:green:wlan
[ 9.480000] JFFS2 notice: (510) jffs2_build_xattr_subsystem: complete building xattr subsystem, 1 of xdatum (1 unchecked, 0 orphan) and 16 of xref (0 dead, 6 orphan) found.
[ 38.050000] Loading modules backported from Linux version master-2014-05-22-0-gf2032ea
[ 38.050000] Backport generated by backports.git backports-20140320-37-g5c33da0
[ 38.220000] cfg80211: Calling CRDA to update world regulatory domain
[ 38.220000] cfg80211: World regulatory domain updated:
[ 38.220000] cfg80211: DFS Master region: unset
[ 38.220000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[ 38.230000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[ 38.230000] cfg80211: (2457000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[ 38.230000] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
[ 38.240000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[ 38.240000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[ 38.240000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[ 39.160000] ath: EEPROM regdomain: 0x0
[ 39.160000] ath: EEPROM indicates default country code should be used
[ 39.160000] ath: doing EEPROM country->regdmn map search
[ 39.160000] ath: country maps to regdmn code: 0x3a
[ 39.160000] ath: Country alpha2 being used: US
[ 39.160000] ath: Regpair used: 0x3a
[ 39.170000] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
[ 39.180000] Registered led device: ath9k-phy0
[ 39.180000] ieee80211 phy0: Atheros AR9330 Rev:1 mem=0xb8100000, irq=2
[ 39.180000] cfg80211: Calling CRDA for country: US
[ 39.180000] cfg80211: Regulatory domain changed to country: US
[ 39.190000] cfg80211: DFS Master region: FCC
[ 39.190000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[ 39.190000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 3000 mBm), (N/A)
[ 39.200000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), (N/A, 1700 mBm), (N/A)
[ 39.200000] cfg80211: (5250000 KHz - 5330000 KHz @ 80000 KHz), (N/A, 2300 mBm), (0 s)
[ 39.200000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 3000 mBm), (N/A)
[ 39.210000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 4000 mBm), (N/A)
[ 39.630000] NTFS driver 2.1.30 [Flags: R/O MODULE].
[ 39.680000] Error: Driver 'gpio-keys-polled' is already registered, aborting...
[ 39.700000] loop: module loaded
[ 39.840000] PPP generic driver version 2.4.2
[ 39.890000] ip_tables: (C) 2000-2006 Netfilter Core Team
[ 40.020000] NET: Registered protocol family 24
[ 40.050000] nf_conntrack version 0.5.0 (954 buckets, 3816 max)
[ 40.500000] i2c /dev entries driver
[ 40.540000] Linux video capture interface: v2.00
[ 40.660000] fuse init (API version 7.18)
[ 50.340000] cfg80211: Calling CRDA to update world regulatory domain
[ 50.340000] cfg80211: Invalid regulatory domain detected:
[ 50.340000] cfg80211: Regulatory domain: 00
[ 50.340000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[ 50.350000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.350000] cfg80211: (2457000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.360000] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.360000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.360000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.370000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[ 50.370000] cfg80211: Calling CRDA to update world regulatory domain
[ 50.370000] cfg80211: World regulatory domain updated:
[ 50.380000] cfg80211: DFS Master region: unset
[ 50.380000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[ 50.380000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.390000] cfg80211: (2457000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.390000] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.390000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.400000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[ 50.400000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[ 53.500000] cfg80211: Calling CRDA to update world regulatory domain
[ 53.500000] cfg80211: World regulatory domain updated:
[ 53.500000] cfg80211: DFS Master region: unset
[ 53.500000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[ 53.510000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[ 53.510000] cfg80211: (2457000 KHz - 2482000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[ 53.510000] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
[ 53.520000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[ 53.520000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
[ 53.520000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[ 54.360000] wlan0: authenticate with <wifi AP mac>
[ 54.370000] wlan0: send auth to <wifi AP mac> (try 1/3)
[ 54.370000] wlan0: authenticated
[ 54.390000] wlan0: associate with <wifi AP mac> (try 1/3)
[ 54.390000] wlan0: RX AssocResp from <wifi AP mac> (capab=0x431 status=0 aid=3)
[ 54.390000] wlan0: associated

It seems the core functionality of OpenWRT has not been tampered with – it’s mainly a slightly customized with vendor addons “virgin” or “vanilla” install of OpenWRT. It also pulls it’s packages from the following URL:

http://www.dragino.com/downloads/downloads/motherboards/ms14/Firmware/Yun/Packages--v2.x/ <...>

There is 16MB of NAND Flash and 64MB of RAM, a USB2 port for connecting various things, 10/100 LAN Port with the possibility of running POE into the device to boot it without needing the Arduino below it to provide the 5V DC it requires. The antenna is optional, but I recommend it as the first-start wizard allows you to connect to it via WiFi in AP mode. From there, you can choose if you want it to be an AP or a Wireless Client to your existing AP.

For $80 koala bucks you get a complete working MIPS IoT device. It ain’t bad, apart from the issue I had with power supply. That was my fault, but it seems to be pretty stable from what I can see. And if you do fuck up the firmware, there is a way to access the emergency failsafe uBoot to TFTP a new kernel and rootfs. Just ensure you don’t nuke the whole NAND while in uBoot – I hope I don’t have to use the emergency failsafe mode during normal usage. It may not win any awards, but hey, for $80… It’s not that bad… could be worse.