Saturday, January 3, 2015


V-USB is some very interesting software by Objective Development that allows many AVR microcontrollers to emulate a USB 1.1 port with only two data lines and 3 resistors.  V-USB can be licensed freely under the GNU General Public License or alternatively under a commercial license.

There's good documentation on their wiki and they link to a number of projects which demonstrate using the software.  Many of the listed projects are using the ATmega8, as the software has been around a number of years.

The Adafruit Trinket and Pro Trinket Arduino compatible boards use V-USB as firmware to download user programs from the Arduino Integrated Development Environment (IDE).  Adafruit has long-standing code in the Arduino IDE to program AVRs using the USBtiny protocol.

Adafruit has also published open source code which demonstrates use of the Trinket as a USB 1.1 human interface device (HID) including mouse and keyboard emulation.  Soon they will publish the same for Pro Trinket.  This is done, again leveraging V-USB code and Adafruit's USB identifiers, to 'bitbang' USB protocols through the data lines connected to the USB connections on the boards (the Trinkets do not have dedicated USB hardware on-board).

Even though the code has been around for awhile, it is still very pertinent for building inexpensive USB interface devices for today's computers. Much of the promise of computer interaction has yet to be realized but is now coming about through the Maker movement and the Internet of Things (IoT).  A large part of achieving this acceleration is low device cost and mass availability.  The Objective Development license scheme and inexpensive AVR processors meet the growing need.

Until such time as anyone can buy $1 chips with a good size ARM core and built-in peripheral functions, designers will still use smaller components and design creativity.

Sunday, December 28, 2014

Soldering Iron Tips

An easy pun, but if you have a new soldering iron or just a replacement soldering tip, how do you take care of it?

Google and Adafruit are my friends as usual.  Ladyada posted awhile back a sheet of tips from Hakko on how to take care of your soldering iron tips.

I am guilty of several bad habits mentioned.  My old Hakko tip had oxidized rather badly and increasing the temperature on the iron only makes things worse.

Hakko tips are not inexpensive, they can be obtained from Adafruit, Amazon, and others.  I don't recommend third party tips as you would not want your nice iron or your work to suffer.

Friday, December 26, 2014

New Video

A new video is posted on my Amazon author page at  It is distilled from my appearance on the Adafruit Ask an Engineer show on September 17th, 2014.  The video covers my discussions with Ladyada and PT on the Adafruit Trinket and writing the book Getting Started with Adafruit Trinket just before Maker Faire 2014.

Saturday, October 11, 2014

Comparing Adafruit's Pro Trinket to Trinket and Uno

A few weeks before Getting Started with Adafruit Trinket went to press, Adafruit introduces the Pro Trinket.  It hits a sweet spot in terms of price, performance, and size between the Trinket and the Arduino Uno.  In my comparison chart in the book it was a bit late to add the Pro Trinket so I'll do it here. First, sizing them up visually:
Adafruit Trinket (top), Pro Trinket (middle) and Arduino Uno (bottom) (source: Adafruit)

The Pro Trinket is closer to Trinket's size than an Arduino Uno.   It's smaller than an Arduino Micro or Nano I believe but not by a lot.

Adafruit Trinket

Adafruit Pro Trinket
Arduino Uno

Surface Mount
ATmega328P QFN package
DIP Package
Digital Pins
Analog Pins
3 (shared)
Pulse Width Modulated Pins
Pin Voltage
3.3 or 5 volts
3.3 or 5 volts
5 Volts
Board Voltage
3.3 or 5 volts
3.3 or 5 volts
5 Volts (3.3 on a pin)
Regulated Current Out
Power via 3.7V LiPo
USB Chip Onboard
No (but has FTDI header)
USB Plug Type
USB Programmable
512 / 512 bytes
2048 / 1024 bytes
2048 / 1024 bytes
Flash Memory (free)
8K (5,130 free)
32K (28,672 bytes free)
32K (32K free)
Add-on Shields
Board Size
31mm x 15.5 x 5mm
38mm x 18mm x 2mm
75.14 x 53.51 x 15.08mm
Approximate Cost

In terms of Pro Trinket compatibility with Uno, the Pro Trinket does not have digital pins 2 and 7 exposed to pins (they are permanently used for USB, although you could hack into the USB resistors with very fine wire to get them).  Sketches that use pins 2 and 7 may most likely be modifiable to use other pins.

Like some Uno clones, the Pro Trinket adds analog pins 6 and 7 which could be very useful in some applications.

What do you think?  Does the Pro Trinket fit in well in the spectrum of available microcontrollers?  Capability, price, size?  

Trinket / ATtiny85 Internal Temperature and Voltage Sensing

Here is some info that was considered for Getting Started with Adafruit Trinket but was left on the cutting room floor.

The ATtiny85 on Trinket has the ability to sense the voltage applied to it.  This can be useful to determine if a battery is getting a bit too low.  The ATtiny85 also has a built-in temperature sensor.  Some say they don't use it due to a perceived lack of sensitivity.  But the sensor is fairly accurate if calibrated and if a bit of decimal math is used to adjust the temperature values read.

The temperature calibration is discussed in the Atmel document AVR122 - Calibration of the AVR's internal temperature reference at You may need to take some readings and adjust some values in the code to dial-in the most accurate values over a temperature span.

The reading of voltage and temperature requires reading two values using the ATtiny85 analog to digital converter.  Unlike using the analogRead function on external pins, the voltage and temperature are in special areas that are read in similar method to analogRead.  ATtiny85 internal registers are polled to get the values.

Floating point arithmetic is used which adds considerable code overhead to the compiled program.

The sketch below reads the voltage and temperature and outputs the values over a software serial link.  An FTDI cable or FTDI friend connected to Trinket Pin #0 will output the values to a USB port which may be viewed by a terminal emulator.

 * Trinket / ATtiny85 Temperature and Voltage Measurement
 * Adapted from
 *, and
// Values will be output to Trinket pin #0 via software serial for this example.  
// The library SendOnlySoftwareSerial by Nick Gammon is used to save a pin over
// using the SoftwareSerial library 

#include <SendOnlySoftwareSerial.h>
SendOnlySoftwareSerial Serial(0);       // Output values via serial out on Pin #0

void setup() {
  // Setup the Analog to Digital Converter -  one ADC conversion
  //   is read and discarded

  ADCSRA &= ~(_BV(ADATE) |_BV(ADIE)); // Clear auto trigger and interrupt enable
  ADCSRA |= _BV(ADEN);                // Enable AD and start conversion
  ADMUX = 0xF | _BV( REFS1 );         // ADC4 (Temp Sensor) and Ref voltage = 1.1V;
  delay(100);                         // Settling time min 1 ms, take 100 ms

  Serial.begin(9600);                 // set up serial output

void loop() {
  int i;
  int t_celsius; 
  uint8_t vccIndex;
  float rawTemp, rawVcc;
  // Measure temperature
  ADCSRA |= _BV(ADEN);           // Enable AD and start conversion
  ADMUX = 0xF | _BV( REFS1 );    // ADC4 (Temp Sensor) and Ref voltage = 1.1V;
  delay(100);                    // Settling time min 1 ms, wait 100 ms

  rawTemp = (float)getADC();     // use next sample as initial average
  for (int i=2; i<2000; i++) {   // calculate running average for 2000 measurements
    rawTemp += ((float)getADC() - rawTemp) / float(i); 
  ADCSRA &= ~(_BV(ADEN));        // disable ADC  

  // Measure chip voltage (Vcc)
  ADCSRA |= _BV(ADEN);  // Enable ADC
  ADMUX  = 0x0c | _BV(REFS2);    // Use Vcc as voltage reference,
                                 //    bandgap reference as ADC input

  delay(100);                    // Settling time min 1 ms, there is
                                 //    time so wait 100 ms

  rawVcc = (float)getADC();      // use next sample as initial average
  for (int i=2; i<2000; i++) {   // calculate running average for 2000 measurements
    rawVcc += ((float)getADC() - rawVcc) / float(i);
  ADCSRA &= ~(_BV(ADEN));        // disable ADC
  rawVcc = 1024 * 1.1f / rawVcc;
  //index 0..13 for vcc 1.7 ... 3.0
  vccIndex = min(max(17,(uint8_t)(rawVcc * 10)),30) - 17;   

  // Temperature compensation using the chip voltage 
  // with 3.0 V VCC is 1 lower than measured with 1.7 V VCC 
  t_celsius = (int)(chipTemp(rawTemp) + (float)vccIndex / 13);  
  Serial.print("Temp: ");
  Serial.print("Vcc: ");

// Calibration of the temperature sensor has to be changed for your own ATtiny85
// per tech note:
float chipTemp(float raw) {
  const float chipTempOffset = 272.9;           // Your value here, it may vary 
  const float chipTempCoeff = 1.075;            // Your value here, it may vary
  return((raw - chipTempOffset) / chipTempCoeff);

// Common code for both sources of an ADC conversion
int getADC() {
  ADCSRA  |=_BV(ADSC);          // Start conversion
  while((ADCSRA & _BV(ADSC)));    // Wait until conversion is finished
  return ADC;

The calibration methods used – voltage compensation, along with user testing for values placed in the chipTemp function, can get the accuracy of measurements to within one degree Celsius.

If you wish to keep parts and pin usage to a minimum, reading the temperature with the onboard sensor may provide the capability you need.

In addition, there are several benefits to being able to measure the supply voltage.  If the project is run on battery, Trinket or connected devices could be turned off if power reaches a predetermined lower limit.

Wednesday, October 8, 2014

Select One From Several Inputs

Yesterday, we selected one of many outputs with only 4 pins from an Adafruit Trinket microcontroller.  Here is the mirror project.  Say you have 8 digital data lines in and only few microcontroller lines (Adafruit Trinket only has 5 I/O pins).  You can use a circuit like the one below:

The chip used is the 74XX151 8 input multiplexer.  The binary address of the line you want is sent on Trinket Pins #0, #1, and #2.  Then the data line selected is read in on Trinket Pin #3.  This leaves Pin #4 as an output for serial data or other use.  The code would similar to the sample code below if we only wanted to read the 74151 input pin 3:

void setup() {

void loop() {
   digitalWrite(0, HIGH);
   digitalWrite(1, HIGH);
   digitalWrite(2, LOW);
   int mydata = digitalRead(3);

For a robust program, you'd probably cycle through each 74151 pin address and read the values you want. 

If you only want to multiplex 4 inputs, you can use a smaller multiplexer or just ground S2 low, freeing Trinket Pin #2.

Tuesday, October 7, 2014

Triggering Ten Pins with Four Outputs

A common issue in microcontrollers: what do you do when the pins on your controller do not match well with the outputs to your controlled items?  This is something I wanted to write about in Getting Started with Adafruit Trinket but I was over on page count as it was, so I'll post it here for you.

What the designer may not normally think about is using TTL logic chips.  Often called 74 series after the original numbering by Texas Instruments, there are hundreds of pre-existing integrated circuits to help make outstanding projects.  A number of years back it was one of the only ways to make circuits.... anyway...

Take Trinket.  There are only 5 I/O pins.  What if you want to use some sensor or serial input to output one of ten outputs (say to the delicious Adafruit Audio FX Sound Board that just came out).  You could be satisfied triggering only 4 of the sound board's trigger pins. But we want more!

So 4 binary digits can actually represent 16 different outputs (0 to 15 or 0 to F in hexadecimal).  Would one create a bunch of 7400 series logic (AND, OR, NAND) gates to change a number to one of several outputs?  You could, but it takes alot of gates;

Gates to decode 4 digital signals to 10 outputs
There is a way to reduce this down to one 16-pin DIP chip - use the 7442 BCD to decimal decoder IC.  All the logic above is already pre-wired into one easy to use chip!  So how would we wire Trinket to use the 7442 to the Adafruit Audio FX Sound Board which wants one of many pins to trigger a file to be played?  See the wiring diagram below:

If you set the right 4 bit number on Trinket pins 0 to 3, it will trigger one of ten outputs to the sound board, triggering the playing of up to ten sounds.  The code to trigger output 5 would include:

void setup() {

void loop() {
   digitalWrite(0, HIGH);
   digitalWrite(1, LOW);
   digitalWrite(2, HIGH);
   digitalWrite(3, LOW);

If you hooked a transmitter like an Adafruit Bluefruit or other receiver to Trinket Pin #4, you could use Trinket to set the right combination of 4 states on Pins #0-3 to trigger the right sound output. (Note: if you connect to pins #3 and #4 on Trinket, be sure to disconnect these when you use the USB programming connection, then reconnect when programming is done). And the Sound Board can hold alot of WAV file sound compared to a tiny bit on Trinket itself.

Note the data sheet I link to is the 74HC42.  The letters in the middle (if any) designate different types of logic (some improvements have been made in these chips over the years.  I'm partial to LS logic, although nearly any will do that I'm aware of, just be sure if you use 5 volt logic you are consistent).

You can see the usefulness of older chips in making the most of newer microcontrollers and modules.  With a bit of study of the 74 series chips, I'm sure you can find some that will help you in projects on your drawing board.