Project tutorial
Hertzian Armor

Hertzian Armor

Hertzian Armor is a shoulder armor made to visually illustrate the ubiquity of WiFi; a resouce that we constantly use but never see.

  • 17 respects

Components and supplies

Our original intention was to use leather to build this, but we opted for Neoprene because of it's interesting texture and flexibility.
Ard lilypadmain
Arduino LilyPad Main Board
We used a LilyPad Arduino 328 Main Board for this project. We wanted to use an Arduino that we could sew into the material, but this proved to be arduous. We also chose the main board over the LilyPad Simple Board as it has more pins.
LilyPad FTDI Basic Breakout - 5V
The main board needs this to load and compile Arduino code on it.
1469 00
Adafruit HUZZAH CC3000 WiFi Breakout with Onboard Antenna - v1.1
The pins are connected to the LilyPad as suggested on the Adafruit instructable. It is suggested to use at least a 1 amp external power supply to power this properly.
Adafruit NeoPixel Digital RGB LED Strip - White 30 LED - 1m - WHITE
We cut and removed the white housing from around the LED strip. We used Velcro to attach and to secure the lights to the neoprene.
LilyPad LiPower
This converts our 3.7 volts received from the battery to 5 volts to power everything! Yea!
Polymer Lithium Ion Battery - 2000mAh
We were concerned with powering the LilyPad, CC3000, and NeoPixels so we opted for the 2 amp battery. This thing worked great!
1000uF 10V Capacitor
This capacitor helps smooth out the voltage across the NeoPixel strip. It is the recommended capacity as Adafruit states on their NeoPixel instructable.
330 ohm resitor
This resistor aids in preventing spikes that could damage the NeoPixel strip. It is hooked up to the strip's digital input.
Velcro works great to secure things in a pinch.
Alligator Test Leads - Multicolored (10 Pack)
For quick testing and prototyping on the Lilypad.

About this project

Hertzian Armor

Making the invisible visible

What is Hertzian?

Hertzian space, as described by Dunne and Raby, is a holistic view of the electronic object and its cultural interactions, and is the interface between electromagnetic waves and human experiences. Using Hertzian Armor we can now begin to see some of these invisible interactions that happen all around us.


Our initial approach to this assignment was to create an object that allows us to see the unseen. In this way we could begin to explore how we interact with the invisible world around us, and start a conversation about something we may come in contact with everyday, but not fully understand. 

We initially started looking at alcohol sensors and pollution sensors, two things we are affected by but never see. While brainstorming how to implement this technology in the wearable, we stumbled on a larger goal, how can we make WiFi visible?

WiFi exists in the Hertzian space and is constantly around us. We use it almost every time we interact with an electronic device, but only understand it through the generic signal strength icon seen on most devices. We wanted to create a wearable device that could explicitly visualize WiFi, and did so using a WiFi sensor and LEDs.


WiFI Signal Strength and LED Output Color

The LED output color is defined by type of WiFi in the area:

  • red value = ( # of restricted networks / total networks ) x 255
  • green value = ( # of open networks / total networks ) x 255
  • blue value = ( # of Hotspots / total networks ) x 255

The number of lit LEDs is determined by the average Wi-Fi signal strength (RSSI) in the area: 

  • all 3 strips lit: RSSI > 60 
  • 2 strips: 50 <= RSSI <= 60 
  • 1 strip: RSSI < 50

Design Process:

Design Iterations

Our Methodology:

We started out the design process by deciding who we wanted to design for and in what setting. We decided on creating shoulder armor because we wanted a wearable that would be bold enough to display at Burning Man or an event like Silicon Valley Fashion Week, but also simple enough to be worn around Berkeley.

We began with paper prototypes to understand the initial form. Iterating quickly with cardboard, brass fasteners, duck tape, and canvas, we were able to hone in on a form factor that would fit on most shoulders and cleanly house our electronics.

Initially we wanted to use leather for the final prototype. After visiting Discount Fabrics, we realized that leather is fairly expensive and difficult to work with, so we decided instead to use neoprene. Neoprene is a forgiving material that is soft but easily holds its shape, which gave us the flexibility we needed while finalizing our design.

The final prototype uses Chicago screws to hold the neoprene pieces together along with canvas strips which allow the device to drape down the wearers shoulder. We used Velcro to hold the LED strips in place under the flaps, and an adjustable leather belt to attach the device to the wearer.

Technology Used:

Wi-Fi Scanning:

In order to scan local WiFi, we used Adafruit CC3000 WiFi Breakout with the on-board antenna. For best hardware-to-software compatibility, it is recommended to use Arduino software 1.0.6 as opposed to the current version available, 1.6.4. The Adafruit CC3000 library conveniently has a function in the buildtest example to list the SSID (service-set identifier) results that we adapt for our purposes.

More about SSID:

  • SSID is an unique 32 bit character identifier attached to the header of packets which are sent over a wireless local area network (WLAN) that acts as a password when a device tries to connect to the basic service set - standards imposed by IEEE 802.11 standards.

Wi-Fi stands for Wireless Fidelity, and it is a term trademarked to brand products that belong to a category of WLAN devices. SSID differentiates one WLAN from another such that all access points and all devices connecting to a specific WLAN, or Wi-Fi network, must use the same SSID.

Scanning SSID and Averaging RSSI:

  1. We initialize our CC3000.
  2. We begin a SSID scan and compute the following:
  • The number of secured networks using the WPA2 protocol.
  • The number of unsecured networks.
  • The CC3000 does not have an easy way to distinguish Wi-Fi hotspots from other access points so we used the number of networks using the WPA and WEP protocols for now.

   3.  Disconnect the CC3000.


In order to represent the overall Wi-Fi strength around us, we used Adafruit NeoPixel Strip as it is wonderfully bright, and it is supported by the Adafruit NeoPixel library which makes working with RGB values simple.

Mapping Wi-Fi RSSI to Lights:

  1. We initialize the NeoPixel strip.
  2. We use the values saved from our SSID scan and map them as we have described before:
  • All 3 strips lit: avgRSSI > 60
  • 2 strips lit: 50 <= avgRSSI <= 60
  • 1 strip lit: avgRSSI < 50

Mapping Network Security to Pixel Color:

We simultaneously determine how many pixels we want to activate in order to represent the signal strength of Wi-Fi around us, and we choose a RGB color value to light the NeoPixel strip based on the types of Wi-Fi networks detected.

The color chosen is mapped from the total number of each type of security network found divided by the total number of networks multiplied by 255. We map RGB as the following percentages:

  • : WPA2 → Red   
  • f : (WPA, WEP) → Green 
  • f : Unsecured → Blue

Library Dependencies:

  • Arduino 1.0.6 IDE
  • Adafruit CC3000
  • Adafruit NeoPIxel


wearables.inoPlain text
Arduino code. We scan for local WiFi, take the average RSSI to determine the number of pixels to light, and we map RGB values to the WPA2, Unsecured, and WPA security protocols, respectively.
  Arduino code for Provocation 3: Hertzian Armor -
  Critical Making Spring 2015

  Designed specifically to work with the following Adafruit products:

  Modified code sample implemented by Kevin Townsend & Limor Fried for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
  Author: Corey Short
  Date: 05/05/2015

#include <Adafruit_CC3000.h>
#include <Adafruit_NeoPixel.h>
#include <avr/power.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"

#define NUM_PIXELS 21             // The number of NeoPixels in our strip

/* These are the interrupt and control pins */
#define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!
#define STRIP_PIN             6  // NeoPixel strip pin
#define ADAFRUIT_CC3000_VBAT  5  // VBAT can be any digital pin
#define ADAFRUIT_CC3000_CS    10 // CS can be any pin

int *lightShowData = 0;          // Pointer to WiFi scan results. Used to map RGB values to NeoPixel colors

/* Use hardware SPI for the remaining pins
 * On an UNO, SCK pin = 13, MISO pin = 12, and MOSI pin = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER); // you can change this clock speed but DI
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, STRIP_PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

/* Our setup code:
 * Initialization   - Initialize our CC3000 WiFi Breakout
 * SSID Scan        - We compute a scan for WiFi connections around us
 * Compute Averages - Compute RSSI, and Security type averages
 * Disconnect       - Disconnect CC3000
 * Initialization   - Initialize NeoPixel strip
void setup(void) {
  initCC3000();                  // Initialize CC3000
  lightShowData = scanWiFi();    // & computeAverages. uint16_t list = scanWiFi() ?
  disconnectCC3000();            // Clean up after yourself and disconnect the CC3000
                                 // It would be nice to power down the CC3000 between scans


/* Our loop code:
 * startLightShow   - Start our NeoPixel light show. Repeat until delay over.
 * delay            - This will continue for 5 minutes before doing another WiFi scan.
void loop(void) {
  initNeoPixelStrip();           // Initialize NeoPixel strip

/* Light up our NeoPixel strip based on scanWiFi() results */
void startLightShow(int *p) {
  Serial.print(F("P        : "));
  uint32_t red = 255 * (p[1] / 100.0);
  uint32_t green = 255 * (p[2] / 100.0);
  uint32_t blue = 255 * (p[3] / 100.0);
  Serial.print(F("Colors        : "));
  if (p[0] > 60) {
    colorWipe(strip.Color(red, green, blue), 100);
  else if (p[0] >= 50 && p[0] <= 60) {
    colorWipe2(strip.Color(red, green, blue), 100);
  else {
    colorWipe3(strip.Color(red, green, blue), 100); 

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  uint16_t length = strip.numPixels();
  for (uint16_t i=length-1; i > 0; i--) {
      strip.setPixelColor(i, c);;

// Fill the dots one after the other with a color
void colorWipe2(uint32_t c, uint8_t wait) {   
  uint16_t length = strip.numPixels();
  for (uint16_t i=length-1; i >= length-14; i--) {
      strip.setPixelColor(i, c);;

// Fill the dots one after the other with a color
void colorWipe3(uint32_t c, uint8_t wait) {   
  uint16_t length = strip.numPixels();
  for(uint16_t i=length-1; i >= length-7; i--) {
      strip.setPixelColor(i, c);;

/* Get the SSID list. We use this to compute the average WiFi strength around us. */
int * scanWiFi() {
#ifndef CC3000_TINY_DRIVER
  int *result = listSSIDResults();
  return result;

/* Initialize CC3000 WiFi Breakout */
void initCC3000() {
  Serial.println(F("Hello, CC3000!\n"));
  /* Display the driver */
  Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
  /* Initialise the CC3000 module */
  Serial.println(F("\nInitialising the CC3000 ..."));
  if (!cc3000.begin()) {
    Serial.println(F("Unable to initialise the CC3000! Check your wiring?"));
  /* Check firmware */
  uint16_t firmware = checkFirmwareVersion();
  if (firmware < 0x113) {
    Serial.println(F("Wrong firmware version!"));
  /* display MAC Address */

/* Disconnect CC3000 WiFi Breakout */
void disconnectCC3000() {
  Serial.println(F("\n\nClosing the connection"));

/* Initialize Adafruit NeoPixel strip */
void initNeoPixelStrip() {
//; // Initialize all pixels to 'off'
/*! @brief  Displays the driver mode (tiny of normal), and the buffer size if tiny mode is not being used
    @note   The buffer size and driver mode are defined in cc3000_common.h */
void displayDriverMode(void) {
  Serial.print(F("RX Buffer : "));
  Serial.println(F(" bytes"));
  Serial.print(F("TX Buffer : "));
  Serial.println(F(" bytes"));

/*! @brief  Tries to read the CC3000's internal firmware patch ID */
uint16_t checkFirmwareVersion(void) {
  uint8_t major, minor;
  uint16_t version;
#ifndef CC3000_TINY_DRIVER  
  if(!cc3000.getFirmwareVersion(&major, &minor)) {
    Serial.println(F("Unable to retrieve the firmware version!\r\n"));
    version = 0;
  else {
    Serial.print(F("Firmware V. : "));
    Serial.print(major); Serial.print(F(".")); Serial.println(minor);
    version = major; version <<= 8; version |= minor;
  return version;

/*! @brief  Tries to read the 6-byte MAC address of the CC3000 module */
void displayMACAddress(void) {
  uint8_t macAddress[6];
  if(!cc3000.getMacAddress(macAddress)) {
    Serial.println(F("Unable to retrieve MAC Address!\r\n"));
  else {
    Serial.print(F("MAC Address : "));
    cc3000.printHex((byte*)&macAddress, 6);

/*! @brief  Begins an SSID scan and prints out all the visible networks */
int * listSSIDResults() {
  uint32_t index = 0;
  uint8_t valid = 0;
  uint8_t rssi = 0;
  uint8_t sec = 0;
  char ssidname[33];
  uint16_t rssiTotal = 0;
  int unsecTotal = 0;
  int secWPATotal = 0;
  int secWPA2Total = 0;
  int rssiAvg = 0;
  static int result[100];
  int numNetworks = 0;

  if (!cc3000.startSSIDscan(&index)) {
    Serial.println(F("SSID scan failed!"));
    return false;

  Serial.print(F("Networks found: ")); Serial.println(index);
  numNetworks = (int) index;
  while (index) {

    valid = cc3000.getNextSSID(&rssi, &sec, ssidname);
    Serial.print(F("SSID Name    : ")); Serial.print(ssidname);
    Serial.print(F("RSSI         : "));
    Serial.print(F("Security Mode: "));
    rssiTotal += rssi;
    if (sec == 3) {
      secWPA2Total += 1;
    if (sec == 2 || sec == 1) {
      secWPATotal += 1;
    if (sec == 0) {
      unsecTotal += 1;
  Serial.print(F("RSSI Total        : "));
  Serial.print(F("Security Mode WP2A: "));
  Serial.print(F("Security Mode WPA : "));
  Serial.print(F("Unsecured Mode    : "));
  Serial.print(F("(int) RSSI total    : "));
  Serial.println((int) rssiTotal);
  Serial.print(F("(int) index    : "));
  Serial.println((int) index);
  rssiAvg = ((int) rssiTotal) / numNetworks;
  Serial.print(F("RSSI Avg    : "));
  int red = ((float) secWPA2Total / (float) numNetworks) * 100;
  int green = ((float) unsecTotal / (float) numNetworks) * 100;
  int blue = ((float) secWPATotal / (float) numNetworks) * 100;

  result[0] = rssiAvg;
  result[1] = red;
  result[2] = green;
  result[3] = blue;

  Serial.print(F("Result        : "));
  return result;

Custom parts and enclosures

3D hertzian armor .stl file


Similar projects you might like

Voronoi101: Light Your Lamp!

Project tutorial by Gregory O. Voronin

  • 29 respects


Project tutorial by 5 developers

  • 1 comment
  • 11 respects

Colors of Photons

Project showcase by Eva Konya and Janos Magyar

  • 27 respects

Stylish IoT Neck Warmer Controlled from Mobile Browser

Project tutorial by Dr. Charif Mahmoudi

  • 31 respects

RR Spaceship Bridge

Project in progress by Team RossumRumblers

  • 13 respects

Arduino Lightsaber

Project tutorial by Michael Darby - 314Reactor

  • 24 respects
Add projectSign up / Login