Stop, blink and roll*

 On 2013-05-13 and filed under: timelapse attiny buspirate contest bb313 buspirate3


A little bit of the cat got out of the bag some time ago:

6 seconds of AVR flashing

You’re looking at ~24 hours of continuous AVR flashing compressed down into 6 seconds.

While I won’t be releasing the connecting PCB just yet (i’m still beating down a few issues and refining the BOM), I thought it would be good to supply the scripts I used to do the actual time lapse since it was non-obvious from a “oh dear, the contest entry is due in <48 hours isn’t it..” point of view.

Parts and Materials

  • Teensy3: Attached to the system doing the programming

  • SSD1306: OLED display showing how many times the AVR has been programmed

  • Bus Pirate 3: Acting as an AVR programmer

  • Avrrrinator Rev B: Bus Pirate to 2x AVR ISP adapter (this is the super secret “prototype” I mentioned in the YouTube post)

  • BB313 boards: Breakouts for easily attaching AVR ISP cables

  • ATtiny4313: tiny AVR for programming

  • ATtiny85: tiny AVR for programming

  • Assorted LEDs: Status indicators/Lighting

  • Logitech C920 Webcam: Takes all the pictures

Taking a picture

The small bash script invoking the gstreamer toolchain (without reading the documentation this is pretty much magic) took on the duty of taking a picture every minute. It then copied everything out via rsync to another machine with tons of spare space.

This is not properly done since my start time edged uncomfortably close to when I had to stop, edit and ship (24 hours later).

Note that this constantly writes over the same file. It stops the local disk from being clogged up by continuous snapshots. It also does not check and do anything reasonable if the rsync transfer fails.. like move the file aside/retry.

In my case, losing a few minutes worth of snapshots wasn’t a big deal for 24 hours compressed down to 6 seconds. I actually deleted quite a few frames before rendering out to video to eliminate periods of darkness (they show up as jarring sub-millisecond transitions to darkness).

#!/bin/bash

while true; do
gst-launch -e v4l2src ! video/x-raw-yuv,format=\(fourcc\)YUY2,width=1920,height=1080,framerate=5/1 \
! ffmpegcolorspace ! pngenc snapshot=true ! filesink location="frame.png"

# Yup, this is talking to an actual rsyncd daemon on a NAS
RSYNC_PASSWORD="super_secret" rsync -avP frame.png rsync:[email protected]/frame-`date '+%s'`.png

sleep 60;
done

Video out

After all the frames were assembled, I manually went in and pruned a bunch that were completely dark due to the lights being off. Compressing the video down a bunch to 6 seconds took a bit of playing around, mostly with the framerate:

mencoder 'mf://*.png' -mf fps=145:type=png -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell -oac copy -o ~/Desktop/output-yt.avi

At this point, the video quality kind of sucked, but I had to ship it.

Here is the completed video:

Code doing the programming

This is the script that refreshes the display you see. It calls avrdude to flash the AVRs and records the return code.

If it is zero, then the success counter for the AVR is incremented.

From there counts are then written to the serial port where the Teensy 3 can handle persisting the display and refreshing it with new results.

#!/usr/bin/env python
# requires pyserial (pip install pyserial)
import subprocess
import serial

counter_4313 = 0
counter_85 = 0

failures_4313 = 0
failures_85 = 0

ser_port = serial.Serial(port='/dev/tty.usbmodem12341', baudrate=9600)

while True:
    try:
        ret_4313 = subprocess.check_call(['avrdude', '-v', '-p', 'attiny4313', '-c', 'buspirate', '-P',
        '/dev/tty.usbserial-AE01J4Q7', '-U', 'flash:w:blinky313.hex', '-x', 'reset=aux'])
    except subprocess.CalledProcessError:
        ret_4313 = 1

    if ret_4313 == 0:
        print "ATtiny4313"
        counter_4313 += 1
    else:
        failures_4313 += 1

   # Report statistics to the LCD screen
    report = "313:%s\n\n85:%s" % (counter_4313, counter_85)
    ser_port.write(report)
    try:
        ret_85 = subprocess.check_call(['avrdude', '-v', '-p', 'attiny85', '-c', 'buspirate', '-P',
        '/dev/tty.usbserial-AE01J4Q7', '-U', 'flash:w:blinky45.hex', '-x', 'reset=cs'])
    except subprocess.CalledProcessError:
        ret_85 = 1

    if ret_85 == 0:
        print "ATtiny85"
        counter_85 += 1
    else:
        failures_85 += 1

   # We do this twice to make it look more live
    report = "313:%s\n\n85:%s" % (counter_4313, counter_85)
    ser_port.write(report)

On the Teensy 3, the data is received and pumped out to the display. Not the greatest code, but decent enough to run for 24 hours without much of a hiccup.

Note that there are several small issues when using the SSD1306 library with the Teensy 3. I just stomped out the relevant sections after chasing down errors from the compiler (which were unrelated to SPI operation, and mostly due to i2c support).

/*********************************************************************
* Flash Counter!
* Teensy 3.0 attached to a 128x64 SPI-driven OLED display
* Vendor: Adafruit
*
* IF YOU GET COMPILE ERRORS (you likely will!)
* Stomp out the compile errors in Adafruit_SSD1306.cpp line by line
* and everything should be OK (most of them are i2c related).
*
*********************************************************************/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_DC 11      // All pin numbers correspond to
#define OLED_CS 10  // the 'gray' labels on the welcome to
#define OLED_CLK 14     // Teensy 3 card
#define OLED_MOSI 12    // SSD1306 labels this as: "Data"
#define OLED_RESET 9

Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);

  // Display setup
  display.begin(SSD1306_SWITCHCAPVCC);
  display.clearDisplay();
  display.setTextColor(WHITE,BLACK);

}

void loop() {

  // Persist the display until we have something to display
  if( Serial.available() > 0 ) {
    display.clearDisplay();
  }
  display.println("AVR Program Count");
  display.println();
  display.setTextSize(2);
  while ( Serial.available() > 0 ) {
    digitalWrite(13, HIGH);
    char c = Serial.read();

    if (c == '\n') {
      display.println();
    } else {
      display.write(c);
    }
    digitalWrite(13, LOW);
  }
  display.display();

  delay(500);
  display.setTextSize(1);
  display.setCursor(0,0);
}

And of course, blink programs. The ATtiny4313 and ATtiny85 each had their own. They’re pretty generic, (the one for the 4313 is from the BB313 website).

cheers (and drink, if thats your thing)

3D Printed Bus Pirate v3.6 Case (DP6037)

 On 2012-12-31 and filed under: printing 3d buspirate bp dp6037 stl


Bus Pirate Case, Translucent Blue, Improved

Source files and general instructions for printing can be found here.

The Bus Pirate is a pretty fantastic device for sniffing around and working with new circuits. It can even act as an AVR programmer.

After using one to fiddle with a few circuits, a case became necessary after seeing its value. While there are cases that can be purchased[1], a 3D printer was laying around waiting to be used.

Finding only a case outline (which proved to be extremely useful as a jumping off point) on Thingiverse, one needed to be made for the newer Bus Pirate.

After several hours (mostly spent re-calibrating the 3D printer, untangling filament, and playing musical notes with the timing belts), the printer popped out several iterations of cases.

The first few worked well, but were dependent on PLA ‘rods and spikes’ (scrap filament cut and heated on a hotbed to straighten) and press-fitting to hold the top and bottom halves together. The USB header was also unexposed, which caused leveling issues (since it was higher than the rest of the board).

Printed Bus Pirate Case, Reject

Going forward with several revisions, and many rejects later (about 12!), a decent case started appearing. Instead of PLA rods, a few 8mm long M3 machine screws and M3 hex nuts were used. They’re not very common, but the M3s seem to fit rather well while providing a good degree of stability.

The assembly order from the bottom: M3 screw, bottom plate, PCB, hex nut, top plate.

While the top looks unsecured, it must actually be screwed/threaded in from the bottom with a decent amount of force.

Printed Bus Pirate Case, Front

Polyimide tape was used on the back to protect the pins from being shorted out. The reason for not covering them in CAD is because they can be useful to probe with a multimeter at times.

Printed Bus Pirate Case, Back

Files are posted here (CC-BY-SA; via original author), but may change in the future if I ever get around to beating the thing into a different shape.

If you have an idea for a change, or can design a better one go for it!

Updates & Errata

1-1-13: For many printers with a perfectly flat print bed (borosilicate glass, metal, etc), it may be advantageous to mirror the output on one axis so that the top gets printed perfectly flat.

With a borosilicate glass bed:

Bus Pirate Case, mirrored shiny front

The exported STL file has been added to the GitHub repository. Look for dp6037-top-axis-flipped.stl when grabbing it (or click that link).

1-2-13: Yellow? Who prints stuff in yellow? Don’t you have blue?

After a bit of recalibrating, this is what the case looks like in translucent blue. Not very high quality, but passable:

Bus Pirate Case, Translucent Blue

1-3-13: Here is a better front panel (printed after mending the Z-axis into alignment), which will probably be the last update (in this series of days).

Bus Pirate Case, Translucent Blue, Improved

1-4-13: Added a link to source files at top and shortened/corrected more text to sound less silly.

Notes & References

[1] Note that buying an acrylic case is really the way to go. They sell for about $3).. but if you have a 3D printer, it probably needs to earn its keep anyway.

Thanks & Resources

cheers!

eh?