WS2812B LED (NeoPixel) Control: Part 1 – Serial Control via 8-bit ATmega (Arduino)

INTRODUCTION

I’ve been laying the groundwork for doing some projects using remote controlled RGB LEDs. My first attempt was Lampduino, which used discrete RGB LEDs, and an ITEAD Colorduino as a controller. In that project, I ran into several pitfalls:

  • though inexpensive, assembly of the LED matrix was very labor intensive
  • the LED’s were rather dim, due to the limited drive capability of the Colorduino
  • the frame rate was slow, due to limited baud rate and RAM
  • while it was scalable, I didn’t like the idea of having to use a separate Colorduino for every 64 LEDs

A few years have passed, and WS2812B LEDs have dropped enough in price enough to get into the range that I feel is affordable. They can be found on eBay and AliExpress very cheaply. Also, they can be controlled without any specialized hardware – all that is needed is one GPIO pin. There are libraries available for many of the popular microcontrollers. Some examples are Arduino, ESP8266, Teensy 3.x, and Raspberry Pi.

HOST SOFTWARE

The other piece of the puzzle is control software. For Lampduino, I hacked uRaNGaTaNG’s mtXcontrol Processing sketch into rgbMtx, but I found Processing to be a very limiting platform, which was hard to debug. This time around, I found a couple of interesting free LED control programs, which are both quite powerful. The first one is Jinx! LED Matrix Control, which runs on Windows only, and the second is Glediator, which is a Java app. Both programs, while free, are not open source. However, they are both powerful enough to do some interesting things.

HARDWARE

I decided to start my experiments with an Arduino Pro Mini clone, because they have a tiny footprint, are cheap (clones are <$2 shipped from China on eBay), and I happened to have some laying around. Also, the Arduino Pro Mini’s ATmega 328P MCU runs at 5V, so no level shifting is required when interfacing to WS2812Bs. Glediator’s creator, Solderlab, has barebones, fast serial client Arduino sketch which can be downloaded at: WS2812-Glediator-Interface. It can run on any 8-bit ATmega-based Arduino such as the Mega, UNO, Deumilanove, etc. The code that outputs the data to the LEDs is written in assembly language, and is thus, very fast & compact. Also, rather than using Arduino’s Serial library, it contains its own very compact serial code. At the expense of a little bit of speed, I decided to generalize it a bit, and add my own packet protocol. My code is on github at: WS2812Remote. The main changes that I made in my version of the code are:

  • Since I didn’t understand the Glediator example’s serial code, I reverted to using Arduino’s built-in Serial library. I’ve tested it with baud rates up to 1000000 and an FTDI cable on a Windows PC, and it works fine
  • I added support for my own packet protocol. Glediator’s serial protocol is extremely simple. Each frame starts with 0x01, followed by the pixel data stream. My simple packet protocol adds an XOR check byte, as well as a few simple commands such as color fill and blanking of the LEDs.

I also wrote a C++ program, called pkt_test, which demonstrates usage of my packet protocol.

Hookup of the WS2812B LED strand to the Arduino is quite simple. You can use any 8-bit Arduino. First, you must select a data pin to drive the strand. I arbitrarily decided to use pin PD2. For speed and compactness, instead of using Arduino functions to access the data pin, the code refers to the ATmega port and pin numbers, rather than Arduino’s rather arbitrary digital pin numbers. On the Arduino Pro Mini, digital pin 2 = PD2, as can be seen from the following pin mapping diagram:

FIRMWARE CONFIGURATION

So WS2812Remote.h is configured as follows:

#define DATA_PORT PORTD
#define DATA_DDR DDRD
#define DATA_PIN 2

Next, PIXEL_CNT needs to be set to the number of LEDs in your strand. I tested with an Adafruit NeoPixel ring containing 16 LEDs:

#define PIXEL_CNT   16

Connect your the data input pin of the first LED of your WS2812B strand to your selected data pin. Adafruit recommends a 300-500 ohm inline resistor to protect from voltage spikes. The NeoPixel ring I used already has a resistor onboard, so I didn’t need it. I connected the +5V and GND pins directly to the corresponding pins on the Arduino. To protect against current inrush when powering it up, Adafruit also recommends connecting a 100uf capacitor between the +5V and GND pins. However, it’s not necessary if you’re just going to power it from USB, which is what I did, since I was only powering 16 LEDs. For large strands, you will need an external power supply to supply sufficient current, as each LED can draw up to 60mA at full brightness. If using an external power supply, make sure to always apply power to the WS2812B strand before the data pin!

HOST SOFTWARE CONFIGURATION

I used the same FTDI cable that I used for programming the Arduino as a virtual com port for sending data to it. When configuring Jinx! or Glediator, select Glediator protocol. For speed, the sketch just receives raw pixel data, and dumps it out to the LED strand, so the data format is in native GRB order.

When configuring Jinx! or Glediator, select Glediator as the device type (Jinx!) or output mode (Glediator). Make sure that the baud rate of the corresponding com port matches BAUD_RATE as defined in your sketch. I tested 115200 and 1000000 bps with my FTDI cable, and both worked fine with both programs. It failed at 1250000 bps.

If you want to play around with my packet protocol, the pkt_test code is self explanatory. I tested it with Visual Studio 2015 in Windows 8.1, and g++ in Debian linux 8.2.0. Prior to compilation, set COMM_PORT to correspond to your Arduino’s serial port. Also, confirm that BAUD_RATE in ../WS2812Remote.h matches the value that was used when loading the Arduino sketch. To compile and run pkt_test in linux, use:

g++ pkt_test.cpp serialib.cpp -o pkt_test
sudo ./pkt_test

WIRELESS CONTROL

My first inclination for wireless control was to use Bluetooth, due to its simplicity. The Bluetooth SPP (Serial Port Profile) makes it easy to construct a wireless virtual serial interface between a host computer and the Arduino. This allows you to use exactly the same host software configuration that you would for a direct serial connection to the host. I had an Elechouse EHB Serial Bluetooth Module in my parts bin (very similar to the ubiquitous HC-05), so I decided to try it out.

Before using the EHB module can be used, it must be configured with a series of simple AT commands. I hooked it up to my Windows PC with my FTDI cable, and used PuTTY as a serial terminal to configure it. Connecting the EHB module to the Arduino is quite straightforward:

Arduino -> EHB

5v -> VCC
GND -> GND
RXD -> TXD
TXD -> RXD

Pairing the EHB to a host computer creates a virtual serial port for the host software to access. Unfortunately, I was using Windows 8.1 as my host computer, and its handling of Bluetooth SPP clients is rather flaky. Every time I powered down the LED controller, I had to unpair/pair the Bluetooth in order to get the virtual serial port to work properly. While it worked flawlessly when the virtual serial port was functional, ultimately, I abandoned Bluetooth due to the flakiness of Windows’ Bluetooth SPP support. Perhaps Linux can handle it better.

Next: WS2812B LED (NeoPixel) Control: Part 2 – WiFi Control via ARTnet on ESP8266

HowTo: Fix AVRDUDE 6.3/Arduino 1.6.10+ Compatibility Issues with USBasp Clones

I recently upgraded to Arduino 1.6.13, and found that I could no longer program my boards with my Chinese USBasp clone programmer. When the Arduino IDE tried to load the firmware with my USBasp, AVRDUDE couldn’t find my USBasp, and gave this error:

avrdude: error: could not find USB device with vid=0x16c0 pid=0x5dc vendor=’www.fischl.de’ product=’USBasp’

It turns out that the that AVRDUDE 6.3, which is bundled with Arduino 1.6.10+, has timing issues with USBasps. The fix is to replace your libUSB-win32 driver with libusbK v3.0.7.0. An easy way to install libusbK v3.0.7.0 is to use zadig. Download the zadig from

http://zadig.akeo.ie/

Plug your USBasp into your PC.

Launch zadig, and from the menubar, select Options->List All Devices

Next, from the top listbox, select USBasp.

From the Driver selector box, click the up or down arrow key until libusbK (v3.0.7.0) appears.

Finally, click the Replace Driver button.

The screen should look like this:

zadig

You do not have to reboot or disconnect/reconnect your USBasp. After Zadig finishes installing libusbK, AVRDUDE 6.3 will start working correctly with your USBasp.

NOTE: the version of AVRDUDE that Arduino 1.6.x uses is actually controlled by the Boards Manager (Tools->Board->Boards Manager). Even if you have a version of Arduino 1.6.x prior to 1.6.10, if your Arduino AVR Boards by Arduino is version 1.6.10+, it will use AVRDUDE 6.3.

HowTo: Clean Hydration Bladder Hose/Tubing

If you use a hydration pack, sooner or later, your hose is going to get gunked up with disgusting biofilms or other residues. Biofilms tend to be resistant to disinfectants such as bleach and hydrogen peroxide, so how can you clean the junk out of your hose? I didn’t feel like spending the $$ for a Camelbak cleaning kit, so I found a simple and cheap solution. Simply use a pair of shoelaces.

The shoelaces have to be longer than the length of your hydration hose/tubing. Make sure to use round laces, rather than flat laces. The diameter of the laces has to be smaller than the inside diameter of your hose, in order for them to easily pass through. I happened to have a pair of dress shoe laces I got from a $.99 store.

Small diameter paracord will work, as well, but it doesn’t have the nicely finished ends, which are easier to thread. If you use paracord, wrap the end with a bit of tape to simulate the plastic end of a shoelace, and it will pass through your hose more easily.

First, soak your hose until the gunk inside it softens up. Next, get out the excess water by holding the hose on one end, and cracking it like a whip. Tie the shoelaces together with a knot that’s small enough to pass through the hose, but big enough to be a tight fit to scrub the walls of the tube clean:

img_8719

In the photo above, the knot has white slime on it, because I’ve already used it to scrub out my hose. I just used a basic overhand knot. Next, thread one end of a shoelace through the tube:

img_8718

You may need to remove the attachments from the ends of your hose, in order to get access (especially on the bite valve end). Often, the attachments are very difficult to separate from the hose. Simply dip end of the hose and attachment into hot water to soften up the hose. When the hose is sufficiently softened, you should be able to easily pull off the attachment.

It’s easiest to thread the shoelace through the hose if you clamp the hose between your legs, straighten the hose vertically, and let gravity help you push the shoelace through the top. Finally, just alternately pull ends of the shoelaces to work the knot back and forth through the tube, wiping the junk out of the hose. Wash the gunk off the knot and repeat the process until the hose is clean. Wash the shoelaces, and then soak the hose and shoelaces in some water with a bit of bleach, in order to kill the bacteria and mold.

If you find it hard to get the knot to fit through the hose, try a square knot, which is a bit smaller: http://www.netknots.com/rope_knots/square-knot

You can also get away with using just 1 shoelace. Just tie an overhand knot at one end. However, you will have to re-thread the shoelace through the hose after each pull.

I find that hanging the hose to air dry doesn’t work very well, even if I leave it for a few days. The quickest way to dry it is to first crack it like a whip to expel as much water as possible, and then use forced air to dry out the remaining moisture. I have sleep apnea, so I use my CPAP to blow air through the hose:

img_8720

If you have a fish pump, you can attach the air hose to the hydration tube, and use that to blow air through until it’s completely dry.

How to R&R Pentalobe Screws Without a Special Screwdriver

Apple likes to use annoying pentalobe screws on their devices. While it’s relatively easy to buy a pentalobe screwdriver, why bother, when you probably already have a substitute in your house? Anyone who uses x-acto knives should have a pile of blades with broken off tips. These blades are a quick and dirty surrogate for a pentalobe screwdriver. The tool:

xacto

Simply stab the tip of the x-acto knife into the pentalobe screw, and carefully twist:

pentalobe

The screws are so tiny that there isn’t much friction, so even though the knife blade isn’t a perfect fit, I’ve never stripped a screw. The same method works on small Torx and Philips screws. I’ve used this technique on many different devices over the years.

iPhone 6 Over Temperature after Replacing Battery

I just replaced the battery in my iPhone 6. When I attempted to power it up with the new battery, I was greeted with this ominous screen:

iphone_temperature_cool_down_en

which is strange, because there’s no way that it was too hot, since it was just booting up, and it wasn’t even warm in the room where I was doing the work. I was worried that maybe I had broken something during the battery swap, but luckily, it was just bad contact in the battery connector.  It turns out that there is a temperature sensor in the battery, and if it has a bad connection, then the iPhone will think that the battery is overheating. I tried pressing down on the battery connector, but that didn’t work. Next, I simply disconnected/reconnected the battery connector, and it booted up normally. Whew!

So, if you replace your iPhone battery, and it suddenly gets the over temperature warning screen, first check the battery connection. If the warning still won’t go away, but it goes away when you reconnect your old battery, then your new battery probably has a bad temperature sensor.

To replace the battery, I mostly followed the procedure in: iPhone 6 Battery Replacement. However, I slightly modified the procedure:

  1. To remove the screen, I simply attached a suction cup at the end of the screen near the button. Then, while pulling up on the suction cup just enough to make a gap between the bottom of the screen and the back, I slid a guitar pick into the gap, starting at the bottom, and working my way down the edges of the phone, pushing it in gently. You can feel the clips releasing as you push the guitar pick in, and the screen will start to pop out, clip by clip. In Step 6 of the iFixIt instructions, they don’t emphasize the need to release the clips. If you just pull up, you’ll probably damage some or all of them.
  2. I didn’t bother disconnecting the screen. In iFixIt’s instructions, they ask you to unscrew the screen connectors and completely remove the screen. Presumably, this is so that you don’t risk damaging the screen connector, lest you let it swivel back more than 90 degrees from the back. I didn’t bother disconnecting the screen, and instead, held it ajar with my left hand while doing everything else with my right hand. This is because the tiny connectors are very fragile in the iPhone, and I didn’t want to damage the screen connector when disconnecting it, or losing the screws (I had a very bad experience when I was trying to change the battery of my iPhone 4 a few years ago.. the replacement came with a connector that was very tight.. and when I tried to disconnect it, the whole socket broke off the PCB, rendering the iPhone useless).
  3. I don’t have a pentalobe screwdriver, and I don’t intend to buy one. I’ve successfully removed/replaced the screws at the bottom of several iPhones using a Xacto knife as a screwdriver. The tips of my #11 Xacto blades always break off, and the broken off tip fits perfectly into the pentalobe screws.

Now, I’m waiting for the replacement battery to charge up, to see if it’s any good. I always have trouble finding replacement batteries that actually work better than the broken old batteries that they replace. There are a lot of shady suppliers out there who sell used or low quality batteries. I used the free Battery Life app to check the charge cycle count:

IMG_6798

The vendor I bought the battery from claimed that it would have zero charge cycle count, and it has one, but that’s close enough, so I’ll let it slide for now. The capacity is also at 1752/1752, as expected. Of course, these stats could be faked, but at least they appear to be OK, which is some piece of mind. Only usage testing will reveal whether or not I managed to buy a good replacement battery, or another dud.

Update 20160804: So, it turns out that my phone was constantly running hot with the “hand picked” replacement battery I bought on Amazon. I highly recommend that anyone who replaces their battery on an iOS product check it with the free Battery Life app. I found out that the controller chip in the replacement battery was fake. The only stats that would change were the battery voltage and charge leve. The discharge current, temperature, capacity, and cycle count were fixed. After a month of using the battery, the Cycles were still 1! I contacted the seller, and they quickly refunded my money without asking me to send back the defective battery. Buyer beware!

Hacking a Proform 12.0TT Treadmill with iFit Live

I recently bought a Proform 12.0TT treadmill from Costco. One of the major reasons I picked this particular treadmill was because it supports iFit Live, which is supposed to allow you to make custom workouts with google maps. Unfortunately, iFit Live has turned out to be complete garbage. My first frustrations started when I tried to connect my treadmill to my iFit account. I spent a couple of hours and got nowhere, because it kept complaining that it wasn’t able to contact the iFit server. I thought maybe it was that my WiFi wasn’t configured correctly, even though the treadmill was able to obtain a valid IP address. I tried submitting a support ticket, and was completely appalled by the horrible total lack of support. They didn’t even bother to respond to my ticket for more than a week, and by that time, I’d figured out that there server had gone down for a few days… one day, it finally just started talking to their server.

iFit Live, which is the only way to make custom workouts is quite expensive, and the treadmill doesn’t even come with so much as a free trial. It costs $9.99/mo or $99/yr. I was thinking of trying it out, but with their crappy support, I don’t want to give them my money. The worst part is that there’s this really cool iFit app that runs on iOS and Android that lets you visualize your workouts in realtime, but it only works on a handful of treadmills, and mine is not included on the list. Of course, they don’t tell you this, so I didn’t figure it out until I’d already bought the treadmill. Doing the workouts on the treadmill’s rather ugly and primitive display isn’t nearly as cool as via google Street View, or at least tracking it on a live google map.

The treadmill’s controller is garbage, too. It doesn’t let you customize the built-in workouts, and doesn’t even let you input things such as age/gender/weight, so the calorie calculations are completely worthless. I started thinking about hacking my own controller for the treadmill, but then decided to first see what could be done via software.

It turns out the treadmill has a built in telnetd, and if you telnet to its IP number, you can log in as root without using any password. ssh is also supported, but it requires the root password. Once you telnet in, it’s readily apparent that it’s running embedded Linux of some sort on an ARM processor. The treadmill control stuff is all in directory /icon/bin. Here is a list of the running processes:

# ps
PID Uid VSZ Stat Command
1 root 652 S init
2 root SWN [ksoftirqd/0]
3 root SW< [events/0]
4 root SW< [khelper]
5 root SW< [kthread]
16 root SW< [kblockd/0]
19 root SW< [khubd]
50 root SW [pdflush]
51 root SW [pdflush]
52 root SW [kswapd0]
53 root SW< [aio/0]
666 root SW [sdioeventd]
667 root SW [sdiod0]
669 root SW [mtdblockd]
709 root SW [nandeventd]
710 root SW [nandthread]
713 root SW< [scsi_eh_0]
739 root 3148 S /usr/bin/syslogd -S -b 10 -D -s 32 -O /tmp/logfile.tx
753 root 2292 S /usr/bin/dropbear
783 root SW [RtmpTimerTask]
784 root SW [RtmpMlmeTask]
785 root SW [RtmpCmdQTask]
786 root SW [RtmpWscTask]
792 root 3124 S /usr/bin/httpd -f -p 8080 -h /icon/bin/html
793 root 3020 S sslwrap -cert /usr/bin/sslwrap.cert -accept 443 -port
794 root 2880 S ./utwatch
795 root 652 S init
796 root 652 S init
798 root 652 S init
800 root 652 S init
810 root 2740 S utaudio
811 root 6476 S utcompete
812 root 2864 S utcontrol
813 root 2744 S utdevcom
814 root 2764 S utinput
815 root 2740 S utlog
816 root 6940 S utnetstatus
817 root 2200 S utuserlog
819 root 2740 S utvalues
820 root 2888 S utwifi
826 root 2872 S utwpl
827 root 2272 S utdisplay
828 root 2740 S utworkout
831 root 4640 R N web_serv
928 root 652 S udhcpc -i apcli0 -a -n -t 4
974 root 664 S telnetd
7348 root 764 S /bin/sh
26665 root 764 S /bin/sh
14635 root 656 R ps
14636 root 648 R sh -c iwconfig
#

From dmesg, I found that it’s running on a NuMicro NUC950 MCU running at 200MHz with 32MB RAM and 130MB of NAND flash. Here is the entire output of dmesg after bootup:

# dmesg
Linux version 2.6.17.14 (sbarton@sbarton-VirtualBox) (gcc version 4.2.1) #95 PREEMPT Thu Nov 21 10:08:23 MST 2013
CPU: ARM926EJ-Sid(wb) [41069265] revision 5 (ARMv5TEJ)
Machine: NUC950
Memory policy: ECC disabled, Data cache writeback
On node 0 totalpages: 8192
DMA zone: 8192 pages, LIFO batch:1
CPU NUC950 (id 0x02900910 system clock:200MHZ)
CPU0: D VIVT write-back cache
CPU0: I cache: 8192 bytes, associativity 4, 32 byte lines, 64 sets
CPU0: D cache: 8192 bytes, associativity 4, 32 byte lines, 64 sets
Built 1 zonelists
Kernel command line: root=/dev/ram0 console=ttyS0,115200n8 initrd=0xa00000,4000000 mem=32M
PID hash table entries: 256 (order: 8, 1024 bytes)
Console: colour dummy device 80×30
selected clock e4e1c0 quot 7
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 32MB = 32MB total
Memory: 26440KB available (1676K code, 309K data, 80K init)
Calibrating delay loop… 99.73 BogoMIPS (lpj=498688)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
checking if image is initramfs…it isn’t (no cpio magic); looks like an initrd
Freeing initrd memory: 3906K
NET: Registered protocol family 16
********************************************
* You selcet NUC950,Start Init NUC950EVB *
********************************************
SCSI subsystem initialized
usbcore: registered new driver usbfs
usbcore: registered new driver hub
NET: Registered protocol family 2
IP route cache hash table entries: 256 (order: -2, 1024 bytes)
TCP established hash table entries: 1024 (order: 0, 4096 bytes)
TCP bind hash table entries: 512 (order: -1, 2048 bytes)
TCP: Hash tables configured (established 1024 bind 512)
TCP reno registered
NetWinder Floating Point Emulator V0.97 (double precision)
io scheduler noop registered (default)
NUC900 uart driver has been initialized successfully!
nuc900-uart.0: nuc900_serial0 at MMIO 0xb8000000 (irq = 7) is a NUC900
nuc900-uart.1: nuc900_serial1 at MMIO 0xb8000100 (irq = 8) is a NUC900
nuc900-uart.2: nuc900_serial2 at MMIO 0xb8000200 (irq = 9) is a NUC900
RAMDISK driver initialized: 16 RAM disks of 8192K size 1024 blocksize
loop: loaded (max 8 devices)
Card0 Detect !!!
NUC900 SD driver has been initialized successfully!
CFI: Found no nuc900nor device at location zero
probe failed
NUC900 USB host driver has been initialized successfully!
nuc900-ehci nuc900-ehci: Nuvoton nuc900 EHCI Host Controller
nuc900-ehci nuc900-ehci: new USB bus registered, assigned bus number 1
nuc900-ehci nuc900-ehci: irq 15, io mem 0xb0005000
nuc900-ehci nuc900-ehci: USB 2.0 started, EHCI 0.95, driver 10 Dec 2004
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
nuc900-ohci nuc900-ohci: Nuvoton nuc900 ohci Host Controller
nuc900-ohci nuc900-ohci: new USB bus registered, assigned bus number 2
nuc900-ohci nuc900-ohci: io mem 0xb0007000
usb usb2: configuration #1 chosen from 1 choice
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 2 ports detected
Initializing USB Mass Storage driver…
usb 1-2: new high speed USB device using nuc900-ehci and address 2
usb 1-2: configuration #1 chosen from 1 choice
usbcore: registered new driver usb-storage
USB Mass Storage support registered.
ts: Compaq touchscreen protocol output
i2c /dev entries driver
nuc900-i2c-p0 nuc900-i2c-p0: bus frequency set to 100 KHz
nuc900-i2c-p0 nuc900-i2c-p0: i2c-0: nuc900 I2C port0 adapter
client [NAU882] registered with bus id 0-001a
NUC900 Audio driver has been initialized successfully!
TCP bic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
RAMDISK: Compressed image found at block 0
VFS: Mounted root (romfs filesystem) readonly.
Freeing init memory: 80K
selected clock e4e1c0 quot 7
selected clock e4e1c0 quot 7
selected clock e4e1c0 quot 7
gnand: module license ‘Nuvoton’ taints kernel.
NAND: nand_init!!!!!
1. ===> write SMCSR
scsi0 : Nuvoton NUC900 GNAND DRIVER!
nand card init
1. ===> write SMCSR
Card0 Removed
card reset4. ===> write SMCSR
6. ===> write SMCSR
fmiCheckInvalidBlock pSM0->uLibStartBlock=2
Valid P2LN 577, block 1022

===> nand total sectors 253696 <size 129892352>
Vendor: NUVOTON Model: GNAND DRIVER Rev: 2.00
Type: Direct-Access ANSI SCSI revision: 00
SCSI device sda: 253696 512-byte hdwr sectors (130 MB)
sda: Write Protect is off
sda: Mode Sense: 03 00 00 00
sda: got wrong page
sda: assuming drive cache: write through
SCSI device sda: 253696 512-byte hdwr sectors (130 MB)
sda: Write Protect is off
sda: Mode Sense: 03 00 00 00
sda: got wrong page
sda: assuming drive cache: write through
sda: sda1 sda2 sda3 sda4 < sda5 >
sd 0:0:0:0: Attached scsi removable disk sda
EXT2-fs warning: mounting unchecked fs, running e2fsck is recommended
rtusb init rt3070AP —>
=== pAd = c2804000, size = 778504 ===

RTMPAllocTxRxRingMemory, Status=0
RTMPAllocAdapterBlock, Status=0
usbcore: registered new driver rt3070AP
(Efuse for 3062/3562/3572) Size=0x2d [2d0-2fc]
RTMP_TimerListAdd: add timer obj c2893b98!
RTMP_TimerListAdd: add timer obj c2861ed0!
RTMP_TimerListAdd: add timer obj c2861eb8!
RTMP_TimerListAdd: add timer obj c2861ea0!
RTMP_TimerListAdd: add timer obj c28081a8!
RTMP_TimerListAdd: add timer obj c2807dc4!
RTMP_TimerListAdd: add timer obj c280818c!
RTMP_TimerListAdd: add timer obj c2808414!
RTMP_TimerListAdd: add timer obj c2808394!
RTMP_TimerListAdd: add timer obj c280b240!
RTMP_TimerListAdd: add timer obj c280ae5c!
RTMP_TimerListAdd: add timer obj c280b224!
RTMP_TimerListAdd: add timer obj c280b4ac!
RTMP_TimerListAdd: add timer obj c280b42c!
RTMP_TimerListAdd: add timer obj c280e2d8!
RTMP_TimerListAdd: add timer obj c280def4!
RTMP_TimerListAdd: add timer obj c280e2bc!
RTMP_TimerListAdd: add timer obj c280e544!
RTMP_TimerListAdd: add timer obj c280e4c4!
RTMP_TimerListAdd: add timer obj c2811370!
RTMP_TimerListAdd: add timer obj c2810f8c!
RTMP_TimerListAdd: add timer obj c2811354!
RTMP_TimerListAdd: add timer obj c28115dc!
RTMP_TimerListAdd: add timer obj c281155c!
RTMP_TimerListAdd: add timer obj c2814408!
RTMP_TimerListAdd: add timer obj c2814024!
RTMP_TimerListAdd: add timer obj c28143ec!
RTMP_TimerListAdd: add timer obj c2814674!
RTMP_TimerListAdd: add timer obj c28145f4!
RTMP_TimerListAdd: add timer obj c28174a0!
RTMP_TimerListAdd: add timer obj c28170bc!
RTMP_TimerListAdd: add timer obj c2817484!
RTMP_TimerListAdd: add timer obj c281770c!
RTMP_TimerListAdd: add timer obj c281768c!
RTMP_TimerListAdd: add timer obj c281a538!
RTMP_TimerListAdd: add timer obj c281a154!
RTMP_TimerListAdd: add timer obj c281a51c!
RTMP_TimerListAdd: add timer obj c281a7a4!
RTMP_TimerListAdd: add timer obj c281a724!
RTMP_TimerListAdd: add timer obj c28380c0!
RTMP_TimerListAdd: add timer obj c2837cdc!
RTMP_TimerListAdd: add timer obj c28380a4!
RTMP_TimerListAdd: add timer obj c283832c!
RTMP_TimerListAdd: add timer obj c28380dc!
RTMP_TimerListAdd: add timer obj c28380f8!
RTMP_TimerListAdd: add timer obj c2838114!
RTMP_TimerListAdd: add timer obj c286a7e4!
RTMP_TimerListAdd: add timer obj c286a854!
RTMP_TimerListAdd: add timer obj c286a7fc!
RTMP_TimerListAdd: add timer obj c283864c!
RTMP_TimerListAdd: add timer obj c28056c8!
RTMP_TimerListAdd: add timer obj c2808760!
RTMP_TimerListAdd: add timer obj c280b7f8!
RTMP_TimerListAdd: add timer obj c280e890!
RTMP_TimerListAdd: add timer obj c2811928!
RTMP_TimerListAdd: add timer obj c28149c0!
RTMP_TimerListAdd: add timer obj c2817a58!
RTMP_TimerListAdd: add timer obj c2838378!
RTMP_TimerListAdd: add timer obj c28623d0!
–>RTUSBVenderReset
RTUSBVenderReset
Key1Str is Invalid key length(0) or Type(0)
Key2Str is Invalid key length(0) or Type(0)
Key3Str is Invalid key length(0) or Type(0)
Key4Str is Invalid key length(0) or Type(0)
1. Phy Mode = 9
2. Phy Mode = 9
NVM is Efuse and its size =2d[2d0-2fc]
(Efuse for 3062/3562/3572) Size=0x2d [2d0-2fc]
3. Phy Mode = 9
MCS Set = ff 00 00 00 01
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
SYNC – BBP R4 to 20MHz.l
RTMP_TimerListAdd: add timer obj c28620e8!
Main bssid = ac:a2:13:2b:a4:c4
== rt28xx_init, Status=0
0x1300 = 00064320
selected clock e4e1c0 quot 7
selected clock e4e1c0 quot 7
selected clock e4e1c0 quot 7
RTMP_TimerListAdd: add timer obj c28a97a0!
RTMP_TimerListAdd: add timer obj c28a9944!
/home/user/2011_0517_RT5370_RT5372_RT5390U_Linux_AP_V2.6.0.0_DPA_1/MODULE/os/linux/../../ap/ap_data.c:3731 assert pEntry->Aid == pRxWI->WirelessCliIDfailed
RTMP_TimerListAdd: add timer obj c28bd0ec!
Rcv Wcid(1) AddBAReq
Start Seq = 00000003
RTMP_TimerListAdd: add timer obj c28be500!
ra0 (WE) : Driver using old /proc/net/wireless support, please fix driver !

There are a bunch of shell scripts in there to do various things. When the machine boots up, it runs go.sh, which in turn runs loadapp.sh, and then runapp.sh. This loads a bunch of utXXX processes, which are all ELF binaries, unfortunately, and run the core functions of the treadmill. download.sh downloads the latest scheduled workout in your iFit account into /icon/bin/iFit/download/wpl2. It uses http downloads from iFit’s server, machines.iconfitness.com. The server host name is stored in the IFIT_SERVER environment variable, so it’s quite easy to redirect it to download from a different server. I envision writing a local http server to emulate some of the iFit server’s functionality. It’s easy to follow what the script does by just typing bash -x download.sh in the shell. The server uses SOAP for its API (templates contained in /icon/bin/iFit/network), and downloads are handled via a binary called soap_get.
It turns out that the workouts are consist of 2 files: layout.fit, and a file with .wpl extension, which is the actual workout data. the name of the .wpl file is the first field in layout.fit. Unfortunately, wpl is a proprietary binary format, so it will take some effort to figure it out, but once that is done, it will be possible to create your own custom workouts without using ifit.com! The built-in workouts are all stored in /icon/bin/iFit/builtin/builtin.xx where xx is a number.

To get the files off of the machine for easy examination, all you have to do is launch the built-in ftpd command to get an anonymous ftp server. Even though it’s already configured in inetd.conf, the server won’t start unless you launch it manually on the command line:

# tcpsvd -vE 192.168.1.111 21 ftpd /
tcpsvd: listening on 192.168.1.111:21, starting

Substitute your treadmill’s IP number where I have 192.168.1.111. I dumped out the whole /icon/bin directory for perusal. I used the Filezilla ftp client on MS Windows.

One final thing… download_firmware.sh checks for and downloads the latest firmware. The firmware updates are in the form of a .tgz file. You can take a look at the contents by looking at /icon/restore/app.tgz, which is a copy of the firmware that’s probably for recovering from a botched update..

That’s all for now. I’m surprised that iFit left the system so wide open. It’s possible that when they find out that people are hacking their systems that they will close the telnet backdoor, so if you want to play, it’s probably a good idea not to update your firmware.

If you play around with your iFit, please share your discoveries in the comments below.

 

Update 2016-04-04: Thanks to Stefano Livi’s uber hacking skillz, I’ve created a github repo: iFitWPL. Using information provided by Stefano, I wrote a C++ program to (mostly) decode WPL files. I have not yet had time to write code to create new WPL files, but there is a file where Stefano shows code in an obscure programming language to create a new WPL: Notes_on_wpl.txt. Please contribute to the github repo, and feel free to discuss any progress in the comments below.

Update 2017-01-10: My Proform treadmill’s motor crapped out. The treadmill never lived up to my expectations, and Costco is letting me return it, so I’m not going to be doing any more hacking on this. Believe it or not, Costco sent a truck to pick up the treadmill, even though I’d had it over a year. Now looking for a better quality treadmill to replace it!

HowTo: Upgrade Scosche Rhythm+ Firmware

rhythmplus

The Scosche Rhythm+ is an optical BLE/ANT+ armband heart rate monitor that’s highly recommended by DC Rainmaker. There are many posts around the Internet which claim that it doesn’t have updateable firmware, but that’s not always the case. Prior to firmware V2.5, the Rhythm+ had to be sent back to Scosche for firmware updates, but if you’re lucky to have firmware 2.5+ installed, you can update the firmware yourself with your phone and Scosche’s Fitness Utility.

*** WARNING WARNING READ BEFORE UPDATING: Read all of the updates at the bottom of this article before attempting a firmware update. Sometimes, a unit has gotten bricked by the procedure, but apparently, it has been fixed in Version 2 of the app. Also, read the comments left by other users. It seems that the data in the newer firmware 3.0+ also causes issues with data corruption in certain apps.  Before starting a firmware update, make sure that your device is fully charged, because it can be rendered unusable if the battery dies during the procedure ***

The procedure is quick and easy. Pair the Rhythm+ to your phone and launch the Fitness Utility. You will be presented with the Attributes screen, which lists the current firmware version:

IMG_4795

If you have Firmware Revision 2.5 or higher, tap the Commands button, and you’ll be presented with this screen:

IMG_4794

Tap the Firmware Update Start button, and the utility will update you to the latest firmware.

I got a nice new feature when I upgraded mine to firmware 2.62. Now, after setting my HR Zone Min and HR Zone Max via the Fitness Utility, the LED on the Rhythm+ blinks blue when my HR is below HR Zone Min, purple when I’m between HR Zone Min & Max, and red when I’m above HR Zone Max. I guess if you only use ANT+, and want to save some battery life, you can turn off the BLE Radio as well, but I haven’t tried playing with any of the other functions yet, and I have no idea how you would turn BLE on again, since the app communicates via BLE.

Update 2016-07-11: Reader Atle posted below that v2.62 adds another function for iOS users … click the button on the unit once to start/stop music, and double click to advance tracks in the playlist. I wonder if this works on Android, as well.

*** 20170327: WARNING: I HAVE RECEIVED MULTIPLE REPORTS OF THEIR UNITS WITH NEWER FIRMWARE GETTING BRICKED BY APPLYING THE FIRMWARE UPDATE. IF YOU HAVE A UNIT WITH NEWER FIRMWARE >2.62, APPARENTLY, THE UTILITY IS BADLY DESIGNED, OR HASN’T BEEN UPDATED IN A LONG TIME, AND CAN CORRUPT UNITS WITH NEWER FIRMWARE. AT THIS TIME, I *DO NOT* RECOMMEND UPDATING YOUR UNIT IF IT HAS NEWER FIRMWARE. IF YOUR UNIT GETS BRICKED, CONTACT SCOSCHE CUSTOMER SUPPORT … IT IS THEIR FAULT IF THEIR SOFTWARE BRICKS YOUR UNIT ***

** 20170509: A reader below said: “If you see blinking Red-blue led so seems like bricked but don’t be upset just put on charge unit and the device will be reset.” Please leave a comment below if it works to resurrect your bricked unit ***

Update 2017-06-16: As reader Occamsrazor states below, the Fitness Utility has been updated to Version 2. The description on iTunes shows that it has some new features, but it’s rather cryptic. I was able to use it to update my 2.62 FW to 3.01. You no longer have to press a firmware upgrade button. If your unit is eligible for updating the firmware, it will automatically prompt you when you connect your device. The new app has several new undocumented functions. I tried to enter my birthday, height, etc, but it doesn’t seem to work. If anyone figures out the advanced features, please post below. Apparently, it’s possible to record a workout in the band itself, and then export a CSV file, but I can’t get any of the functionality to work. Also, there are some reports that the new version is a lot less likely to brick your unit, but YMMV. It worked OK for me.

Update 2018-01-09: 1) I’m not absolutely certain, but I feel that my Rhythm+ has gotten flaky since updating to v3.01 firmware. The heart rate is often very low or very high. I decided to try downgrading my firmware. If you are having issues, and want to try a different version of firmware, I have documented how to downgrade in a new article: HowTo: Downgrade Scosche Rhythm+ Firmware. 2) I was wrong above. You don’t need v2.62 firmware to get the feature that setting the Min & Max heart rates make your LED flash purple/blue/red when the heart rate is below Min/in between Min & Max/Max HR. v2.4 firmware actually supports that feature.

 

Next article: HowTo: Downgrade Scosche Rhythm+ Firmware

Mini Review: Linksys WRT1900AC

It infuriates me how so many WiFi routers are designed with inadequate cooling. I have a whole pile of routers that got flaky or crapped out after a few years due to overheating. The only ones that are still rock solid after years of continuous service are my WRT54Gs. My Linksys E4200 has been getting long in the tooth lately. On hot days, I need to blow a fan on it, and lately, even colder weather, it slows down to a crawl at random times and needs a reboot. I could try installing a big heatsink in it, but I thought maybe it was time for an upgrade to one of the fancier new technology routers. What most people don’t realize about the latest crop of router technology, such as AC3200, is that unless you upgrade your clients, you’re not going to get performance anywhere close to what these things can do. Most of the devices in my house are 2.4GHz 802.11n and can’t even handle MIMO, but smallnetbuilder had an article which showed that you can get a speed boost with 802.11n on a 802.11ac router. I figured I might as well future proof myself and look for a midrange AC router.

linksys-li-WRT1900AC-9-a

After lots of research on smallnetbuilder’s site, I settled on the Linksys WRT1900AC. This router, built by Belkin, is a nod to the venerable WRT54G, and is designed to be hacked with open source firmware. The specs are pretty good, even in the 2.4GHz band, which is often neglected these days, and I was particularly impressed with the speed of its NAS function, which vastly outperforms anything out there. It has a USB 3.0 port + a combo USB3.0/eSATA port on the back, and lightning fast storage performance. When I received it, I was impressed with the build quality. This thing is a beast! It looks like a WRT54G on steroids, and makes its predecessory look like a toy. Big & beefy and heavy. I specifically got the V1 because it has a built in cooling fan which kicks in only when necessary (which isn’t very frequent, due to its gigantic heatsinks). The later V2, also known as the WRT1200ACS, no longer has a fan. This is not going to be a full review of the WRT1900AC, but only a synopsis of my experiences trying to get decent 2.4GHz throughput out of it.

I really wanted to like the WRT1900AC. It is a thing of beauty, and I spent quite a few hours trying to tweak it, but to no avail. Despite the 90Mbps 2.4GHz LAN to WAN downlink throughput measured by smallnetbuilder, I was not able to get more than about 30Mbps downlink out of any of the devices in my house, even when sitting only a few feet from the WRT1900AC. This is only about half what I get out of my old E4200, which works as fast wirelessly as it does through Ethernet, maxing out at almost 60Mbps, which is the speed of my Time Warner cable service. No amount of tweaking over two days (about 6 hours of mucking with it) could speed up the 2.4GHz downlink performance. I scoured google for tweaks and even tried OpenWRT. I figured that I could figure out to get more speed out of it with OpenWRT’s tweakability, but it actually got slightly slower.

Although the speed with a very strong signal was only half as fast as my E4200, at the edges of my house, where the signal was weak, the WRT1900AC performed admirably, giving not only better throughput, but also being able to actually function at distances where the E4200 signal was completely dead. This left me in a dilemma, because the extended range is actually pretty useful to me. Also, for some reason, the storage performance came up quite short of what was tested by smallnetbuilder. I have a Seagate 2TB USB 3.0 drive, which is normally connected to a hacked Pogoplug E02 running Debian linux. The Pogoplug only supports USB 2.0, and doing a file copy across the network on Windows 8.1, I the maximum throughput I get is about 11MBps. Disappointingly, when attached directly to the USB 3.0 port on the WRT1900AC, the throughput topped out at a measly 4MBps. This was the last straw for me.

The 5GHz wireless performance on the other hand, was terrific. It easily saturated my 60Mbps downlink. But I can’t just switch to 5Ghz, because its range is too short in my house, and the signal drops out in some of my bedrooms. Also, not all of my devices support the 5GHz band. So, with a heavy heart, I decided to return the WRT1900AC. Just as I suspected, upgrading to the fancy 802.11ac router doesn’t necessarily help performance with 802.11n clients. In fact, looking at smallnetbuilder’s testing, lots of the latest and greatest routers put less emphasis on 2.4GHz performance, so if like me, you don’t have any 802.11ac clients, you should save your money and buy something cheaper. As for me, I’m going to try hacking a temperature-controlled fan into my old E4200, and see if that makes it more stable.

Review: Mobility Rev Bluetooth Heart Rate Monitor

I recently discovered the PCD Mobility Rev Bluetooth HRM on Amazon.com, for the ridiculously low price of $7.95 including shipping (currently also available on eBay for $9.95). This is a Bluetooth 4.0 (Bluetooth Smart/Bluetooth Low Energy) HRM with strap, for half the price of a replacement strap for a Garmin or Polar HRM! Despite the 1 star reviews on Amazon, I figured that if the HRM was total trash, I would still have a decent spare HRM strap. It arrived a few days ago, and I put it through its paces on a couple of workouts. I wasn’t expecting much, given the bad reviews, and was pleasantly surprised to find that it’s actually a decent piece of hardware.

Specifications

  • strap length: 70-120cm
  • battery life: 1800 hrs (5 yrs x 1 hr/day)
  • battery: CR2032
  • range: ~10 meters
  • waterproof: IPX7
  • operating temperature: -10C – 50C
  • weight: 47g (transmitter+strap)
  • SKU: LHX0021Q

The company seems to be out of business, as their website is dead: http://www.pcdphones.com

The receiver is a bit chunkier and clunky looking compared to my Garmin HRM:

hrmfront

Note how it uses industry standard metal snaps, spaced that the standard distance, so the receiver and strap are compatible with Garmin/Polar/Wahoo/etc.

hrmback

The Mobility Rev uses a CR2032 battery (included). The battery door has a rubber o-ring to seal out moisture from your sweaty chest. I don’t know how water resistant it is, however, and am not going to try immersing it. Unlike the Garmin, which requires a small Philips screwdriver to replace the battery, the Mobility Rev’s battery cover easily comes off with a twist of a coin.

The Mobility Rev strap (bottom) is the same quality and of similar design to my Polar strap (top):

hrmstrapfronthrmstrapback

I use the Polar strap with my Garmin HRM, because the fancy strap that it came with has rather sharp and hard edges that chafe during a long workout.

So far, I have taken the Mobility Rev HRM out for a 1.5 hour bike ride and a 3.5 mi trail run, using the Wahoo Fitness app on an iPhone 6, and it has worked quite well. Here are the metrics I use for evaluating wireless heart rate monitors:

  1. accuracy: Since this is a cheapo HRM, I’m not going to do detailed testing with graphs. At steady state, the heart rate reading is identical to that from my fingertip SpO2 meter. On my 1.5 hour bike ride, I didn’t bother to bring another HRM to compare against, but the heart rate readings looked consistent with my experience, and there were no dropouts or spikes, even when I was riding over very bumpy pavement. On my 3.5 mi trail run, I brought along my Garmin HRM, and did concurrent recordings. I was disappointed to find that during the first minute of recording, the Mobility Rev spiked up abnormally to 144 bpm before stabilizing at my true HR of 109 bpm. This phenomenon, however, is a regular occurrence with my optical HRM’s (Wahoo Rhythm+ and Garmin Forerunner 225 built-in). Since I was wearing two heart rate straps, making the sensor placement less than ideal, it’s possible that this glitch was due to poor contact with my chest. After this initial spike, it settled down, and had identical readings to the Garmin during the rest of the workout, deviating by 1 bpm on occasion, even when my heart rate was fluctuating, due to my switching back and forth between hiking and running. My Pyle strap often spikes up to unrealistically high HR’s when there is intense vibration from my running. The Mobility Rev displayed no such aberrant behavior. For the most part, I was impressed by the accuracy and consistency of its readings.
  2. signal stability: During use, the signal was rock solid and never dropped out.
  3. range: my iPhone 6 was able to reliably receive the signal 40 feet away from the HRM even while indoors.
  4. overall fit and finish: The plastic casing seems of decent quality, and the strap is of comparable quality to the Polar HRM strap.
  5. reliability: Since I have only had it for a day, I don’t yet know if it will crap out after just a few uses. I will update this article after more testing.

Using the free LightBlue Explorer iOS app, I found that it identifies itself as BLUETOOTH SMART HRM, and reports the following device information:

bthrminfo

The manufacturer string is Maxwell Guider. It’s a nice touch that it seems to support reporting of battery status, but I don’t have any partially dead batteries to test with, so I don’t know if it actually outputs anything besides 100% [Update: see below, it always outputs 100% even with bad batteries].

One caveat of the Mobility Rev HRM is that it only outputs heart rate, so you can’t use it for HRV analysis, which requires R-R interval data. I tried to use it with the Elite HRV app on my iPhone, and it wasn’t able to read any HRV data. As a cross check, I took a look at the raw heart rate data output, and found that it indeed only reports 8-bit heart rate and nothing else.  Most people, however, are only interested in heart rate, and won’t find this to be a problem.

I have only had the Mobility Rev BT HRM for a day, so I don’t yet know if it will stop working after only a short period of use. If there are any changes to its performance, I will update this article. Even if it does fail, I’ll still be happy to have an extra $8 Garmin/Polar/Wahoo/etc compatible strap.

Update 2015-11-24: After only 3 days of use, it died. I tried putting several new CR2032’s into it, and it was still dead. I was ready to write it off as a piece of junk until I finally found one that works. Now, it’s working perfectly again. I think the people who are reporting on Amazon that it connects inconsistently or fails after a couple of days are just suffering from weak cells. This device seems to need a higher voltage than others in order to function properly. The functional cell has an open circuit voltage of 3.25V, while another that reads 3.21V doesn’t work. This makes me question the manufacturer’s claim of 1800hrs battery life. Also, during this testing, I found that the Battery Level service is fake, and always outputs 100%. Some of the weak cells would actually operate it for a few seconds at at time before cutting out, and it still outputted a Battery Level of 100%.

 

Update 2015-12-03: I’ve used the Mobility Rev HRM for at least 8 hours of cycling and running workouts now, and the readings have been absolutely rock solid. No spiking up of HR during the start of a workout, no spiking up of HR during running, and no dropouts. The HR readings are totally glitch free. One problem I’ve had, however, is that sometimes, it’s a bit difficult to get the unit to wake up. I wetting the strap contacts usually helps. One time, I had it mounted upside down on the strap, and it woke up when I inverted it. I’m surprised that it seems to be sensitive to L/R, but unit is actually labeled for left & right sides on the back. In the meantime, the price dropped to $6 on Amazon, so I ordered a 2nd one to keep as a spare.

Test & Review: GOPHERT CPS-3205 0-30V/0-5A Bench Power Supply

Banggood.com recently had a special on the Gopher Technology CPS-3205 bench power supply. After searching for reviews, which were generally favorable, I decided to get one for $42.99 including shipping. At this low price, I figured it was worthwhile if it worked at all. The unit is small, fanless, and appears well-constructed. What convinced me to try it was Voltlog’s exhaustive video review of the CPS-3205C, which is a more expensive version with active PFC:

I am not able to use the CPS-3205C, because it only works on 240V, unlike the CPS-3205, which is dual-voltage 120/240V.

Upon unboxing, my initial impression of the CPS-3205 was very good. The unit is quite compact, nicely built, and easy to use. One trivial but annoying defect, however, is that the front panel meters are mislabeled. The voltmeter (on the left) is labeled A and the ammeter (on the right) is labeled V:

cps3205

I can’t imagine how such a glaring error could have happened. The photos on Gopher’s website, and most photos from various vendors have the meters labeled correctly:

CPS-3205

I started to wonder whether Banggood was selling counterfeits, also because mine is labeled GOPHERT rather than GOPHER. However, my fears were laid to rest when I found this photo on Gopher’s own website:

CPS-6003s-F

There are definitely genuine devices out there labeled GOPHERT and with the V and A reversed.

One important attribute of the CPS-3205 is that it doesn’t suffer from voltage transients at power up and power down, which can fry an attached circuit, unlike another cheap power supply I was considering, the PS-305D. Here is a test of the PS-305D’s nasty startup transient: Quick test of the PS-305D PSU. Although Voltlog’s testing shows that the CPS-3205 doesn’t suffer from startup voltage transients, there’s even a second layer of protection. By default, the outputs are disabled when it’s powered up. The ammeter displays OFF, and you must press the ON/OFF button on the front panel to enable the output. This further assures that the power is already stable by the time it reaches your attached circuit. Note that the ON/OFF button only controls the output. The main power switch is on the back of the unit. If, for some reason, you prefer to have the output enabled a power on, you can toggle this feature by holding the ON/OFF button depressed for 5 sec. If the ammeter displays dOn, then the output is enabled at power on, and if it displays dOF, then it’s disabled at power on.

The CPS-3205 has over current, over voltage, and over temperature protection, so it’s pretty robust.

I am not going to go into detail on operation of the CPS-3205, because it’s easy to read in the manual, and Voltlog demos it in his video. Suffice to say that the adjustment knob is very handy, because every time you press it, it shifts to a different digit to adjust, making it very fast to do fine or coarse adjustments. The LOCK button locks the adjustment knob and ON/OFF button from changes, and a nice feature is that it’s persistent even if you power the unit off/on.

WARNING: One attribute that’s not clearly stated in the manual is that in constant voltage (CV) mode, the current set in the constant current (CC) mode is an upper limit for the current that can be output. So, for instance, when the voltage is set to 25.00V and the current is set to 100mA, no more than 100mA can be output, so the output voltage will drop if you attempt to draw >100mA. I found this out the hard way, because mine had the current set to 000mA when I received it, so the output was zero in CV mode. I thought the unit was defective, as shown in my video:

After I played around with it some more, I realized that I had to switch it to CC mode and turn up the current before it would output any voltage.

Accuracy

I tested the accuracy of the CPS-3205 against a TES 2208 DMM. This TES meter has been my workhorse for the past 35 years or so, and has never been recalibrated. It’s no Fluke, but in my testing against other meters it’s been pretty good. That being said, I haven’t tested its accuracy in well over 15 years.

Out of the box, I tested a few random voltages in CV mode, and they were spot on. However, the ammeter displayed 5mA even when no current was flowing. Before running the tests below, I calibrated the CPS-3205 against the TES 2208 DMM, following the procedure at the bottom of this article. In the tables below, the readings are all shown to their maximum resolution.

The performance in CV mode was quite impressive, tracking to within .1V, and well within its rated spec of <=0.3% + 10mV.

Setting Panel Reading TES 2208 DMM
 00.01 00.02 .011
 00.05 00.05/00.08 .052
00.10 00.10 .101
01.00 01.01 1.006
05.00 05.00 5.01
05.25  05.25  5.26/5.27
10.00 10.00 10.03
 20.00 20.00 20.0
30.00 30.00 30.0
31.00 31.00 31.0
32.30 32.30 32.3

Generally, the voltage reacted to setting changes within a second, but when I dialed it down from 28.00V to 00.01V, it seemed like it took about a minute to ramp down and finally stabilize. Interestingly, at low voltages <=.10V, even though the panel meter displays on the high side, the actual output is actually quite a bit more accurate.

In CC mode, the performance was not as impressive, but within the rated spec of <=0.3%+20mA.

Setting Panel Reading TES 2208 DMM
001 005 5.7
005 009 9.7
10 15 14.8
20 23 25.1
50 53 55.1
55 56 66.8
60 65 66.8
70 75 77.0
80 90 87.2
100 104 105.3
180 185 187.2
190 197 197.3
200 207 .20
250 254 .25
1.00 1.00 1.00
1.20 1.20 1.20
1.21 1.21 1.21
1.22 1.22 1.22
2.25 2.25 2.25
3.25 3.25 3.25
4.00 4.00 4.00
4.05 4.05 4.05
5.00 5.00 5.00
5.10 5.10 5.10

While CC mode’s accuracy isn’t very good  it’s still within its rated spec. The .3%+20mA accuracy makes it basically useless at low currents, so  don’t use it for tiny loads, such as 20mA LED’s. The lower currents is where the PS-305D is a better performer.

I didn’t bother testing output ripple, because the accuracy of my CPS-3205 was very similar to that of Voltlog’s CPS-3205C, so I’m going to assume that the output ripple is similar. Also, I am not going to post teardown photos, because Voltlog’s video already goes over the innards of the CPS-3205C in quite some detail.

Summary

I am impressed that such an inexpensive piece of Chinese equipment is of such high quality. The CPS-3205 is well mode, easy to use, and surprisingly, comes from the factory fairly well calibrated. The user interface is well thought out.

Being a switch mode supply, it is light, compact, and quiet. Even though it’s fanless, it runs cool at the currents I tested.

One quibble I have is that the binding posts are in the rear of the unit. I wish that they were on the front panel, so I wouldn’t have to reach behind it. Also, the binding posts are lacking a hole drilled into the bolt for easy insertion of wires, and I wish the standoffs were a bit higher, so that they stood a bit farther away from the case.

The CPS-3205 not accurate enough for lab use, but for general hobby use, the performance is pretty impressive, as long as you can live with .3%+20mA accuracy on current control. It’s a great buy for the price. Currently, it can be had for <$50USD if you search around. It’s too bad that the current control isn’t better <100mA. It would have been nice to have the functionality to be able to run it between 5-25mA.

For those who want to re-calibrate the unit, it is easy to do, and the procedure is listed below.

Calibration Procedure

WARNING: ONCE YOU ENTER CALIBRATION MODE, YOU MUST COMPLETE THE ENTIRE PROCEDURE. IF CALIBRATION MODE IS ABORTED BEFORE COMPLETION, THE UNIT WILL ALWAYS DISPLAY ECP/ECP(OCP) AND BE NON-FUNCTIONAL UNTIL YOU COMPLETE A CALIBRATION CYCLE:

eclecl

A user has reported below that attempting the calibration procedure on a CPS-1610 resulted in the display getting stuck on ECL/ECL. Procede with caution and at your own risk. I myself have had no issues arise, and I have calibrated my two CPS-3205 units several times. However, !!!PROCEED AT YOUR OWN RISK!!!
1. Set V/A switch to A
2. Power on while adjustment knob is pressed in. PUSH OFF will be displayed
3. Press ON/OFF once, then LOCK twice. Display will be 03.00/001.
4. Hook up voltmeter to outputs and adjust output voltage to 3.00V with adjustment knob. Pressing the adjustment knob will toggle the sensitivity – ammeter will alternate 001/010 (001 is fine adjust, 010 is coarse adjust).
5. Press ON/OFF and display will be 30.00/001. Adjust output voltage to 30.00V
6. Hook up ammeter across outputs (dummy load is optional… the resistance in the leads is sufficient). Press ON/OFF and display will be 0001/1.00. Adjust current to 1.00A.
7. Press ON/OFF and display will be 0001/5.00. Adjust current to 5.00A.
8. Press ON/OFF and unit will return to normal operation, with OFF displayed and outputs disabled.
PDF of CPS-3205 User Manual