Are A2 (or A1) Application Class SD cards marketing BS?

People often misunderstand the speed ratings of SD cards. They are built cheaply, and historically have primarily targeted digital cameras. That meant they emphasized sequential IO performance, because that’s how pictures and video are handled. When we plug an SD card into a Raspberry Pi, however, most of our applications will use random reads and writes, which is often abysmal on these cards.

Enter the A1 and A2 speed ratings. These were created by the SD Card Association to guarantee a minimum random IO performance, which is exactly what we want for single board computers.

There’s been a blog post floating around about how the A2 class is marketing BS. In some cases, I’ve seen this cited as evidence of the A1 class also being marketing BS. After all, the top cards on the chart for random IO, the Samsung Evo+ and Pro+, don’t have any A class marks on them.

This misunderstands what these marks are for and how companies make their cards. Your card has to meet a minimum speed to have a given mark. You are free to exceed it. It just so happens that Samsung makes some really good cards and have yet to apply for the mark on them.

Samsung could change the underlying parts to one that still meets its certification marks for the model, but with far worse random IO performance. I don’t think Samsung would do that, but they would technically be within their rights to do so. This kind of thing has happened in the storage industry before. Just this past year, Western Digital put Shingled Magnetic Recording on NAS drives (SMR is a hard drive tech that craters random write performance, making them completely unsuitable for NAS usage). XPG swapped out the controller on the SX8200 Pro to a cheaper, slower one invaliding the praiseworthy reviews they got at launch.

Even if Samsung wouldn’t do that, it’s still something where you have to go out of your way to find the best SD card. Well-informed consumers will do that, but the Raspberry Pi serves a broad market. Remember, its original purpose was education. You can’t expect people to even know what to research when they’re just starting out. It also doesn’t help that major review sites don’t touch on SD cards. Benchmarking can be a tricky thing to do right, and most hobbyist bloggers don’t have the resources to do a good, controlled test, even if they mean well.

What the A class marks do is give a clear indication of meeting a certain minimum standard, at least in theory. Independent reviews are always good in order to keep everyone honest, but if you don’t have time to look at them, you can grab an A1 card and put it in your Pi and you’ll be fine.

As the blog post noted above states, A2 cards don’t always live up to their specs. According to a followup post, this appears to be due to things the OS kernel needs to support, rather than the card itself. It’s also possible for a company to try to pull a fast one, where they launch with a card that meets spec, and then quietly change it. However, if they do, they don’t just have consumer backlash to contend with, but the SD Card Association lawyers. Since they hold the trademark on the A class marks, they have the right to sue someone who is misusing it.

Marketing isn’t just about making people into mindless consumers. It can also be about conveying correct information about your product. That’s what the A classes are intended to do. Nobody knew that Samsung Evo and Pro cards were good until somebody tested them independently. With the A class marks, we have at least some kind of promise backed up with legal implications for breaking it.

Doorbot.ts – Let me in the building, with Typescript

A common issue with makerspaces is letting people in the door. Members sign up and should have access immediately. Members leave and should have their access dropped just as fast. Given the popularity of the Raspberry Pi among makers, it makes sense to start there, but how do you handle the software end?

Doorbot.ts is a modular solution to this problem. It’s split into three parts:

  • A Reader takes input from some device. It could be a USB key reader, or a Wiegand RFID reader
  • An Authenticator checks if the given input credentials are allowed
  • An Activator does something if the input passes

A basic setup might read a keyfob from the reader, authenticate against an API held on a central server, and then (assuming everything checks out) activate a GPIO pin on the Raspberry Pi for 30 seconds. This pin could be connected to a solenoid or magnetic hold to unlock the door (usually with a MOSFET or relay, since the RPi can’t drive the voltages for either of those).

The parts that interface to a Raspberry Pi (such as a Wiegand reader or activating a GPIO pin) are in a separate repository here: https://github.com/frezik/rpi-doorbot-ts

Security

The system can be compromised in quite a few ways. RFID tags can be copied. Cheap 10 digit keys can be brute forced. If you buy cheaply in bulk, there’s a good chance those RFIDs are sequential or otherwise predictable. The Raspberry Pi can be compromised. The database can be compromised.

Which is not to say it’s hopeless. That is, it’s no more hopeless than what security you already have. An attacker can put a rock through any window. Physical locks can be picked, often without much skill at all. If you’re like many makerspaces, you’ll give a keyfob to anyone who shows up with membership dues, and you probably don’t even check their ID.

So no, it’s not the most secure system in the world, but it’s also not the weakest point in the chain, either.

This isn’t to say security should be ignored. Take basic precautions here, like using good passwords, and keeping the systems up to date.

Wiegand

Wiegand is a common protocol for RFID readers. There are cheap readers that work like a USB keyboard, “typing” the numbers of the fob. However, they’re usually not built for outdoor mounting. There are cheap Wiegand options that are.

The protocol runs over two wires (plus power/ground). There is a Reader module in rpi-doorbot-ts for handling it directly. I don’t recommend using it. The issue is that reading the data over GPIO pins means using tight timing, and doing this in Node.js is often unreliable. It often resulted in needing to scan fobs two or three times before getting a clean read.

Instead, you can use a C program who’s only job is to read Wiegand, interpret the bits, and spit out the number. Doorbot.ts then has as Reader that can read a filehandle. So you launch the C program, pipe its stdout into the Reader, and there you go. From practical testing, this has been far more reliable in scanning fobs the first time.

Installing the System

I recommend creating a directory in your home dir on your Raspberry Pi:

$ mkdir doorbot-deployment
$ cd doorbot-deployment

And then create a basic package.json:

{
  "name": "doorbot",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@frezik/doorbot-ts": "^0.13.0",
    "@frezik/rpi-doorbot-ts": "^0.6.0"
  }
}

Be sure typescript is installed globally, and then install all the dependencies:

$ sudo npm install -g typescript
$ npm install

Next, make an index.ts to run the system:

import * as Doorbot from '../index';

const INPUT_FILE = "database.json";


let reader = new Doorbot.FHReader(
    process.stdin
);
let auth = new Doorbot.JSONAuthenticator( INPUT_FILE );
let act = new Doorbot.DoNothingActivator( () => {
    console.log( "Activate!" );
});

Doorbot.init_logger();
Doorbot.log.info( "Init" );
reader.setAuthenticator( auth );
auth.setActivator( act );
reader.init();

Doorbot.log.info( "Ready to read" );
reader
    .run()
    .then( () => {} );

This code creates a reader that works from STDIN, and authenticates against a JSON file, which would have entries like this:

{
    "1234": true,
    "5678": true,
    "0123": false
}

It then hooks the reader, authenticator, and activator together and starts it running. You can type the key codes (“1234”, “5678”, etc.) in to get a response.

I’ll be following up with some more advanced usages in future posts.

“Programming the Raspberry Pi with Perl” is now released

The eBook was released on Monday, and coupon codes to backers were sent out on Tuesday. After a glitch with the first batch of coupons, the second batch was sent out and seems to be all good.

The book assumes you have some knowledge of Perl, but little knowledge of electronics or the Raspberry Pi. It goes through the tools you’ll need, walks through the basic setup of the RPi, and then gets into programming. Starting out with blinking an LED, it later gets into facial recognition and controlling a garage door over the web.

I had hoped that we were releasing on time, and completely forgot that we originally promised a date in August, not September. Oops. Well, a month late still isn’t bad for a crowdfunded project.

Expecting to get some of the coupon codes caught in spam filters. That’s just the nature of sending out a lot of emails that say “here’s your free coupon code!”. Spammers ruin the Internet. Backers, if you don’t see your code at this point, check your spam filter, and then message the campaign directly if you still don’t see it.

This is the first time I’ve done a crowdfunded campaign that worked out. It’s a modest start–not about to retire on that money–but it’s good to have a track record. I tend to be picky about projects I back, and an established track record from the campaign members is one of the things I look at. I expect a lot of other people do the same. I’ll likely have other projects in the future, and this is a good stepping stone.

Perl Raspberry Pi ebook sample chapter: intro

With the campaign for the Perl Raspberry Pi ebook underway, we’re releasing a few sample chapters. First one for today is a short intro chapter. Tomorrow, we’ll be releasing one with more meat, covering the basics of the Raspberry Pi range and some other tools you might need to get started. For now, here’s the intro:


Introduction

Welcome! If you’re reading this, you’ve probably been using Perl for a while
and heard about the wonderful Raspberry Pi. If you haven’t programmed Perl
before, I suggest starting with Learning Perl by Randal L. Schwartz, brian d
foy, and Tom Phoenix. With that said, we try to keep the examples in this book
as simple and concise as possible, sticking to the most basic of expressions
wherever possible. Even without previous Perl experience, you
should be able to grasp the concepts we’ve presented within if you’ve done
any programming in other languages.

No previous electronics experience is necessary. We’ll be covering some of the
basics where appropriate. Most of the projects can be completed without any
soldering. In others, minimal soldering skills may be necessary. However,
being able to solder is a valuable skill to have if you are to grow further
in the field of electronics.

About the Raspberry Pi

In 2012, the Raspberry Pi Foundation was started by employees of Broadcom,
intending to use one of Broadcom’s inexpensive System on a Chip (SoC) fabs
to create a low-cost computer for education. Hobbyists quickly grabbed them
up and started hacking away. Today, the line has expanded to several models,
ranging from the $5 Pi Zero, to the $35 Pi3 (most recently, the Pi3B+).

About Perl

Perl was released by Larry Wall in 1987 inspired by a combination of several
other programming languages. A major revision to Perl 5 was done in 1994. Work
on Perl 6 began in 2000 as a completely separate language from Perl 5 (often
referred to as its “sister” language). Since then, work on Perl 5 has
continued. We’ll be using Perl 5 in this book. We recommend ensuring the most
recent version of Perl is installed before attempting the projects outlined in
this book, that version being 5.26 at the time of writing.

The language was important for the early web, being used in many of the first
CGIs, a simple way to write server applications. Since then, it has evolved
with the rest of the web and is still used by several large companies today.

It also continues as popular language for managing systems, and is installed
by default on the Raspberry Pi.

Low Latency FPV Streaming with the Raspberry Pi

One of the biggest challenges in running my local quadcopter racing group has been overlapping video channels. The manual for the transmitters list a few dozen channels, but in practice, only four or five can be used at the same time without interference.

The transmitters being used right now are analog. Digital video streams could make much more efficient use of the spectrum, but this can introduce latency. Of late, I’ve been noticing a few posts around /r/raspberry_pi about how to do an FPV stream with an RPi, and I’ve been doing some experiments along these lines, so I thought it was a good time to share my progress.

It’s tempting to jump right into HD resolutions. Forget about it; it’s too many pixels. Fortunately, since we’re comparing to analog FPV gear, we don’t need that many pixels to be competitive. The Fatshark Dominator V3s are only 800×600, and that’s a $600 set of goggles.

You’ll want to disable wireless power management. This will tend to take the wireless interface up and down a lot, introducing a delay each time. It’s not saving you that much power; consider that an RPi takes maybe 5 watts, while on a 250-sized quadcopter, the motors can easily take 100 watts or more each. So shut that off by adding this anywhere in /etc/network/interfaces:

wireless-power off

And reboot. That should take care of that. Check the output of iwconfig to be sure. You should see a line that says “Power Management:off”.

You’ll want to install GStreamer 1.0 with the rpicamsrc plugin. This lets you take the images directly off the RPi camera module, without having to use shell pipes to have raspivid to go into GStreamer, which would introduce extra lag.

With GStreamer and its myriads of plugins installed, you can start this up on the machine that will show the video:

gst-launch-1.0 udpsrc port=5000 \
    ! gdpdepay \
    ! rtph264depay \
    ! avdec_h264 \
    ! videoconvert \
    ! autovideosink sync=false

This will listen on UDP port 5000, waiting for an RTSP h.264 stream to come in, and then automatically display it by whatever means works for your system.

Now start this on the RPi:

gst-launch-1.0 rpicamsrc bitrate=1000000 \
    ! 'video/x-h264,width=640,height=480' \
    ! h264parse \
    ! queue \
    ! rtph264pay config-interval=1 pt=96 \
    ! gdppay \
    ! udpsink host=[INSERT_IP_ADDR] port=5000

Modify that last line to have the IP address of the machine that’s set to display the stream. This starts grabbing 640×480 frames off the camera with h.264 encoding, wraps them up in the RTSP protocol, and sends them out.

On a wireless network with decent signal and OK ping times (80ms average over 100 pings), I measured about 100ms of video lag. I measured that by displaying a stop watch on my screen, and then pointing the camera at that and taking a screenshot:

rpi_cam_latency

This was using a RPi Model 2, decoding on a fairly modest AMD A8-6410 laptop.

I’d like to tweak that down to the 50-75ms range. If you’re willing to drop some security, you could probably bring down the lag a bit by using an open WiFi network.

I’ll be putting together some estimates of bandwidth usage in another post, but suffice it to say, a 640×480@30fps stream comes in under 2Mbps with decent quality. There will be some overhead on that for things like frame and protocol headers, but that suggests a 54Mbps wireless connection will take over 10 people no problem, and that’s on just one WiFi channel.

Keep WiFi Alive on Raspberry Pi

So solving my connection problems to a Pi by turning off power savings didn’t work. I’m now using a crude but effective method where the Pi pings the gateway every 2 minutes.

Start by adding this script to /etc/keepalive.sh:

#!/bin/bash

PING_HOST="10.0.0.1"
SECONDS_BETWEEN_PINGS=120


while :
do
    ping -c 1 ${PING_HOST} > /dev/null
    sleep ${SECONDS_BETWEEN_PINGS}
done

This script works in an infinite loop, sending a single ping every 120 seconds. Call chmod 755 /etc/keepalive.sh to make it executable. Next, call it from /etc/rc.local:

/etc/keepalive.sh &

Which will run the script on the next reboot. Call /etc/keepalive.sh & in a shell to start it running, and you’re done.

So far, this seems to make ssh connections start immediately every time. I’d like to figure out what the actual problem is, but this will do.