Jonathan Thomson's web journal

Project Ouroboros Update February 20, 2019

Filed under: Electronics — jethomson @ 11:48 pm
Tags: , , , , , ,

 

I reworked the code and the article for Project Ouroboros. You can see the update by clicking here. When I originally wrote the article in 2011 a USBasp programmer was around $6 on eBay, but now you can buy one in 2019 for about $1.50; pretty amazing.

 

Here’s some code I wrote for the USBasp programmer board I played around with in Project Ouroboros. A bit surprisingly I had no trouble powering a WS2812B strip with just 3.3V. If you run this code on a 5V board you should change LED_STRIP_VOLTAGE to 5, although it’s not strictly necessary because that number doesn’t actually control the voltage. If you do change it to 5 then the power allotted to the LEDs will increase and they will get brighter. I tested the board with 100mW for the LEDs and I had no problems.

 


#include <FastLED.h>

#define NUM_LEDS 8
#define DATA_PIN 12 // MISO pin
#define FRAMES_PER_SECOND  125
#define LED_STRIP_VOLTAGE 3.3
#define LED_STRIP_MILLIAMPS 20

CRGB leds[NUM_LEDS];

void setup() { 
    FastLED.setMaxPowerInVoltsAndMilliamps(LED_STRIP_VOLTAGE, LED_STRIP_MILLIAMPS);
    FastLED.setCorrection(TypicalSMD5050);
    FastLED.addLeds(leds, NUM_LEDS);

    pinMode(14, OUTPUT);  // green LED, LOW == ON
    digitalWrite(14, HIGH);  // turn green LED off
}


void blink() {
    static uint8_t i = 0;
    uint8_t brightness_bool = i++/128;
    digitalWrite(14, !brightness_bool);   // green on board LED, LOW is ON
    leds[0] = CHSV(0, 255, 255*brightness_bool);
}


void breath() {
    const uint8_t min_brightness = 2;
    static uint8_t delta = 0; // goes up to 255 then overflows back to 0

    // for the LEDs in the current state setting the brightness higher than max_brightness will not actually increase the brightness displayed
    uint8_t max_brightness = calculate_max_brightness_for_power_vmA(leds, NUM_LEDS, 255, LED_STRIP_VOLTAGE, LED_STRIP_MILLIAMPS);
    uint8_t b = scale8(triwave8(delta), max_brightness-min_brightness)+min_brightness;

    FastLED.setBrightness(b);

    delta++;
}


void loop() {
    static uint8_t dynamic_hue = 0;

    //blink();
    //fill_solid(leds, NUM_LEDS, CHSV(dynamic_hue, 255, 255));
    fill_rainbow(leds, NUM_LEDS, dynamic_hue, 21);

    //breath();  // breath isn't meant to be run by itself. combine it with one of the functions above.
    
    EVERY_N_MILLISECONDS(100) { dynamic_hue+=6; }
    FastLED.delay(1000/FRAMES_PER_SECOND);
}

 

Code
Project Ouroboros GitHub Repo

Advertisements
 

A smooth breath effect while using FastLED’s power management February 6, 2019

Filed under: Electronics — jethomson @ 9:01 pm
Tags: , , , ,

If using a FastLED function (e.g. FastLED.setMaxPowerInVoltsAndMilliamps()) to manage how much power your LEDs use FastLED limits the maximum brightness that can be set to a value that does not exceed the requested power draw. So if FastLED determines your power limited maximum brightness is M then calling setBrightness() with a value greater than M will result in FastLED setting the brightness to exactly M.

A breath effect ramps the brightness up until it reaches the maximum brightness then ramps the brightness back down to a minimum brightness then starts the whole cycle over again. A naive approach would be to use a triangle wave that goes from 0 to 255 and back down to 0 as the input for setBrightness(), but if the power limited maximum brightness M is less than 255 then the brightness will plateau at M, and the brightness will remain fixed until the triangle wave input falls below M again. My breath() function achieves a continually changing brightness by setting the peak of the triangle wave to M. However, M changes based on the number of LEDs currently lit and their colors, so breath() recalculates M before setting a new brightness value.

 
Snippet from the breath code example available on GitHub:

void breath(uint16_t interval) {
    const uint8_t min_brightness = 2;
    static uint8_t delta = 0; // goes up to 255 then overflows back to 0

    static uint32_t pm = 0; // previous millis
    if ( (millis() - pm) > interval ) {
        pm = millis();

        // for the LEDs in the current state setting the brightness higher than max_brightness will not actually increase the brightness displayed
        uint8_t max_brightness = calculate_max_brightness_for_power_vmA(leds, NUM_LEDS, 255, LED_STRIP_VOLTAGE, LED_STRIP_MILLIAMPS);
        uint8_t b = scale8(triwave8(delta), max_brightness-min_brightness)+min_brightness;

        FastLED.setBrightness(b);

        delta++;
    }
}

 
 
You may have read that you need to apply gamma correction or convert luminance to brightness so that the LEDs have a linear response. That is what I tried first, I never had success with that approach because of the clamping effect FastLED’s power management. After I figured out I had to determine the maximum brightness possible under power management conditions I found that the output of the LEDs looked linear to me using just a triangle wave, so I didn’t try to apply a correction curve. A point that confuses me is whether setBrightness() is actually controlling the brightness or the luminance. I couldn’t find a correction curve being applied when looking through the FastLED code.
 
 
My example breath code on GitHub
FastLED’s notes on power management
Power management functions documentation
LED Brightness to your eye, Gamma correction – No!

 

Making a Pulse Oximeter Using a TSL230R and a ATmega32u2 January 27, 2019

Filed under: Electronics,TSL230 — jethomson @ 11:07 pm

I created a pulse oximeter sensor using an ATmega32U2, a TSL230R, one red and one IR LED, and a clothes pin. The ATmega32U2 is used to read the frequency data from the TSL230R, control the LEDs, and send a stream of data to the host machine over USB. I wrote the code for the microcontroller in C and utilized the LUFA framework.

I wrote a python program called pulseox_graph.py to receive the data from the microcontroller and display the photoplethysmogram, heart beat, oxygen saturation data.

 
 

 
 
TSL230R-pulse-oximeter GitHub repository

 

Play Music Files on an AGPtek or Ruizu Player in the Right Order

Filed under: Electronics — jethomson @ 9:14 pm
Tags: , , ,

My AGPtek M20 and RUIZU X02 mp3 players have an odd way of ordering the mp3 files saved on the device. While you can save mp3s sorted into different directories onto the player it will still sort the files alphabetically as if they were all in one directory. From comments I’ve read using fatsort (or a similar program) on the device will make the files appear in the correct order, but it didn’t solve the problem for me; neither for the internal storage nor an sd card. This bash script will prefix all of your files with a unique number so that mp3s that share a directory will be listed/play next to each other by the player.

 
 

#!/bin/bash

# Copyright 2019 Jonathan Thomson
# Permission is hereby granted, free of charge, to any person obtaining a copy of 
# this software and associated documentation files (the "Software"), to deal in the 
# Software without restriction, including without limitation the rights to use, 
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 
# Software, and to permit persons to whom the Software is furnished to do so, 
# subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all 
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# rename4AGPtek.sh
# Adds a sequential prefix to every mp3 file on the AGPtek or Ruizu player so that 
# it plays them in the correct order.
#
# If you run this script on the files on your player, then add a new file to your 
# player and run the script again it will delete all of the prefixs, and add on new 
# prefixes to all the files so that your new file will put in the right place 
# alphabetically.
#
# MP3_DIR is the directory of your player. It's better to use this script to rename 
# the files after they've been copied to the player.
#
# The ZERO_PADDING variable depends on the number of files and must be set correctly 
# for files to play in the right order.
# e.g. if you have 10s of files ZERO_PADDING should be set to 2, 100s of files 
# ZERO_PADDING should be 3, 1000s of files it should be 4, etc.
#
# If the number of files on your player increases from, for example 99 to 100, you 
# will need to set REMOVE_PREFIX_ONLY to true, run the script, increase ZERO_PADDING 
# from 2 to 3 and set REMOVE_PREFIX_ONLY to false, and then run the script again to 
# get the correctly zero padded prefixes.
#

shopt -s nullglob
IFS=$'\n'
MP3_DIR="/media/jthomson/9016-4EF8"
ZERO_PADDING=4 # zero padding, e.g. 4 --> 0001)
REMOVE_PREFIX_ONLY=false

i=1

dirlist=$(export LC_ALL=C; find $MP3_DIR -type d -print | sort)

for dir in $dirlist
do
  cd $dir
  echo $dir

  # strip the prefix off and sort so when update the prefixes so the prefixes are sequential with the filenames in alphabetical order
  sorted_base_filenames=$(find -mindepth 1 -maxdepth 1 -type f -name "*.mp3" -print | sed -r 's/^\.\///' | sed -r "s/[0-9]{$ZERO_PADDING}\) //" | sort)

  for f in $sorted_base_filenames; do
    current_filename=$(find -mindepth 1 -maxdepth 1 -type f -name "*$f" | sed -r 's/^\.\///')
    base_filename=$(echo $current_filename | sed -r "s/[0-9]{$ZERO_PADDING}\) //") #stripped of the number prefix if it has one
    if [ "$REMOVE_PREFIX_ONLY" = false ]; then
        new_filename=$(printf "%0${ZERO_PADDING}d) $base_filename" "$i") # add prefix zero padded
    else
        new_filename=$base_filename
    fi
    mv -i -- "$current_filename" "$new_filename" &>/dev/null
    echo $new_filename
    i=$(expr $i + 1)
  done
  cd - 2>&1 >/dev/null
done

 
 
rename4AGPtek.sh on GitHub

 

Halloween 2018 – Lilliputian Alien Abduction October 31, 2018

Filed under: Electronics,Halloween — jethomson @ 9:48 pm

IMG_20181028_012209

ufo

 
 
Construction
I made a UFO out of a pie tin and lit it up with a strip of 52 WS2812 LEDs. A ring of 24 LEDs was used to create a tractor beam effect, and a disc 7 LEDs was used to create a control panel. I scavenged parts from a busted LED controller that took commands by an IR remote control. I reused its case, IR receiver, and remote control to create an new LED controller using an Arduino Nano that I wrote custom code for. To create a base for the controller and battery pack to sit on I made a disk out of poster board with aluminum foil glued to it. The dome at the top was half a two piece Christmas ornament globe. The LEDs running around the rim were simply attached with clear tape, since I had trouble getting glue to stick to the silicone sheath over the LEDs. The tractor beam is a ring of LEDs and a plastic drinking glass glued to the pie tin lid. I drilled two holes in the glass, and ran a shoelace through them so I could wear the UFO on my head.

remote control

 
 
Code
Since FastLED disables interrupts its not the best idea to use an IR remote with FastLED. However, I was able to make them work together reliably by not using delay() and creating animation functions that returned control to main() quickly. The code can create 22 different animations (referred to as patterns in the code) on the strip of LEDs that run around the rim of the UFO. Some of the patterns can be run in both directions and have variable speed. The pattern names are orbit, theater chase, running lights, shooting star, cylon, solid, juggle, mitosis, bubbles, sparkle, matrix, weave, starship race, pac man, bouncing balls, halloween colors fade, halloween colors orbit, sound ribbons, sound ripple, sound orbit, sound blocks, and dynamic rainbow. There are also effects (called overlays in the code) that can be added to a pattern to make it more dynamic. The overlays are breath, flicker, glitter, and fade randomly. The color of a pattern can be set as a static color, a color that evolves, or a random color on every draw.

 
 

 
 
UFO LEDs controller code on GitHub

 

Halloween 2017 – Stranger Things Alphabet Wall October 31, 2017

Filed under: Electronics,Halloween — jethomson @ 11:20 am

stranger_things_halloween_2014

 
 
Construction
To create the wall I used a 22″x28″ poster board that I cut down to 22″x23″. I created a graphic of the wallpaper and alphabet, and broke it up in to six ledger size (11″x17″) pages. I recommend using a glue stick to attach the printouts to the poster board. I used glue from a squirt bottle, but that wet the paper too much and made it wrinkle, which is not so bad because it gave the wallpaper an aged look.

To attach the WS2811 LED Christmas lights to the alphabet wall I used hot glue. This doesn’t work the best though because the silicone cover around the LEDs can become unstuck from the hot glue. I believe wrapping some black ribbon around the silicone covers would make them stick to the hot glue much better.

A nylon belt was attached to the board so I could hang it around my neck. The microcontroller board and battery pack are held in a pencil box attached to the back of the board.

 
 
stranger_things_back_of_wall_halloween_2014

 
 
Electronics and Code
For the controller I used a Teensy 2.0 at 5V. I installed the Teensyduino add-on for Arduino so I could run Arduino sketches on the board. Using a Teensy specifically isn’t a requirement; it’s just what I had on hand. My sketch has several modes that can be cycled through by pressing a push button. One of the modes allows custom strings to be written by using a smart phone with a serial terminal installed and a USB OTG cable. The video demonstrates the Stranger Things themed mode.

 
 

 
 
divided up poster – color_ledger_landscape_1dot5cm_border_100dpi.pdf

Stranger Things Alphabet Wall code on GitHub

 

Halloween 2016 – Jackpot October 31, 2016

Filed under: Electronics,Halloween — jethomson @ 9:17 pm

music_box_slot_machine

 
 
Construction
I attached a nylon belt to a toy slot machine coin bank so I could hang it around my neck, and created a music box using an ATtiny861 to play sound effects. The music box uses three differently colored gumdrop LEDs that hover over mini push button switches, so that pushing down an LED results in a push button switch being depressed. The LEDs were made to spring back by bending their leads at a right angle, running them through heat shrink, and gluing the heat shrink to the board (see the picture below). If the player hit the jackpot I pressed the green button to play winning sound effects. If a jackpot wasn’t hit the red button was pressed, and a losing sound effect was played. The orange button played Halloween themed sound clips. A schematic can be found by following the link in the README.md found in the GitHub repo for the code.

 
 
gum_drop_push_buttons

 
 

 
 
Music Box Code on GitHub