Building your own hand held gaming console Part 1

WP_20151111_23_02_12_RichSince getting involved with Arduino and other Microcontrollers, I have designed and built several ‘consoles’ with the most involved one, the HalfByte Console Computer having its own PC Board designed and fabricated.  That was a fun project, well, they all have been, but this one was special: it was my first PC board design that was ‘produced’.   I also managed to design another console, but this was a game rig that went in an old Gameboy case.  This was only partially my design, as the 328 was actually an Arduino Mini Pro.  I added a sound amp, the screen and controller circuitry. So, it wasn’t entirely my design and it was a bit less satisfying. So…

I designed my own hand held from the ground up. This one, currently, lacks sound, and has a simpler controller: three buttons which translate into an action button, a left/up and right/down set of buttons. There is also a reset switch.

This design is very simple: it is a minimalist Arduino 328 compatible with four switches and a Nokia 5110 LCD screen.

WP_20151103_22_17_58_Rich_LIThe whole thing is on a perf board (in this case, it was a freebie board from Bay Area Circuits, go to their website and request the free boards, there Is a link for the request. These are very nice boards and a cool blue color.)

I started out by placing the parts on the board to see if I had room.  I did.

Be sure to photograph the board with the parts located where you wish to place them, this way you have a record of where you put them.

WP_20151103_23_11_54_Rich (2)

My initial design had only left and right buttons, no third button. I added that and the reset button to give me a bit more flexibility.

And, one lesson learned: socket the screen.  On the 5110, the thicker part of the bezel is the TOP, not the bottom.

For this project, you will need:


Part Name



Ceramic Capacitor



16MHZ Crystal




220 ohm


AtMega 328P



28 DIP Socket

28 pin


Momentary Push Buttons



Red, LED




150 ohm


Four pin header



5110 LCD


Parts placement is up to you, but I put the crystal and two caps under the screen, but you can put them where ever you want.

HalfByteHandheld2_schemI would start by placing the 28 pin socket and header on the board first. Solder them in place, use ample solder because you will have to solder wire to the socket and header. Use tape to hold them on the board while you solder them in place.

The LED is the only part that could be soldered in wrong because the key is hard to see. It is the flat side of the LED that is soldered to the resistor.

WP_20151109_22_44_49_Rich_LIOnce everything is soldered in place, insert your 328 controller chip and apply power.  If the 328 contains the standard Arduino boot loader, the pin 13 LED should blink.  If it does, congratulations! You now have a fully functional computer in your hand.

Some things I plan to add are sound and, perhaps, two more buttons.  I may add a video out option, but this is meant to be a handheld, so the video may not happen.

Stay tuned for part two, the software.



Short Video

Getting video out from your Adafruit Trinket or DigiSpark (or ANY ATTINY85)

11224347_913681192034970_90837413382715523_oWhile pouring through some videos and posts on just what the tiny little ATTiny85 chip can do, I ran across a HackADay post about someone generating NTSC video on VHF channel 3 (US channel 3.)  I was intrigued.  So, I tried it and got mixed results and, as I have only a couple of old analog sets, I thought it was kind of impractical to pursue, but cool anyway.  So, I wondered if just composite out would be better and, to my delight, the same person who posted the video also had done composite out with an ATTiny84.  It should work on the 85 as well, and, it does.

So, I found his code and downloaded it.  Mr. Lohr is a GENIUS, plain and simple.  Thank you, sir!

The code did not work well at first. I had to tweak it a bit to work with my hardware, especially the little monitor.  It still is not perfect, the video is not centered, but is fairly steady and bright…my first attempts were not very bright and not very steady. I am guessing it needs to be tweaked for the monitor it will be used on, but I have not tested on more than one.

All you need is something like a Trinket from Adafruit or a digispark. I used both, but destroyed the digispark when I attempted to use an external power source.  It does not like more than five volts.  Specs say 3.5 to 12volts, I used 9. My mistake. 12182942_913681798701576_4759339394040268204_o

The Trinket works great. I am using the 5volt version with USB.  Any ATTiny85 based controller should work, though.

Connecting it is simple: Pin 3 to video ground, Pin 4 to video center pin.  Download the code to your device, connect it to the monitor and reset it. You should see the video demo.

Now, there are some major caveats:

  • it, so far, only does text
  • you have 13 characters by 6 lines
  • character spacing is mono
  • there’s no video memory, each frame is drawn on the fly
  • the ‘video memory’ is simply a string array
  • there is no formatting
  • the character set is stored in flash

So, why bother with such limitations? Well, for starters, cheap composite monitors are easy to get WP_20151025_11_19_10_Rich_LIand use and the Trinket/digispark are both under ten bucks, so you can have an application with video out for very little money.  If nothing else, this is a great lesson in how video works. Charles Lohr did a fantastic job with the code.  He’s a genius. Did I mention that?

Any way, the code is posted below.  Let us know if you get it working and what you do with it.



    Copyright (C) 2014 <>< Charles Lohr

    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.


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include "ntscfont.h"


void delay_ms(uint32_t time) {
  uint32_t i;
  for (i = 0; i < time; i++) {

#define NOOP asm volatile("nop" ::)

void NumToText( char * c, uint8_t a )
    c[0] = (a/100)+'0';
    c[1] = ((a/10)%10)+'0';
    c[2] = (a%10)+'0';
    c[3] = 0;
void NumToText4( char * c, uint16_t a )
    c[0] = (a/1000)+'0';
    c[1] = ((a/100)%10)+'0';
    c[2] = ((a/10)%10)+'0';
    c[3] = (a%10)+'0';
    c[4] = 0;


int main( )

    CLKPR = 0x80;    /*Setup CLKPCE to be receptive*/
    CLKPR = 0x00;    /*No scalar*/

    PLLCSR = _BV(PLLE) | _BV( PCKE );
//    PLLCSR |= _BV(LSM);

    DDRB = _BV(1);

    DDRB |= _BV(3);
    DDRB |= _BV(4);
    PORTB |= _BV(1);

    TCCR1 = _BV(CS10);// | _BV(CTC1); //Clear on trigger.
    GTCCR |= _BV(PWM1B) |  _BV(COM1B0);// | _BV(COM1B1);
    OCR1B = 2;
    OCR1C = 3;
    DTPS1 = 0;
    DT1B = _BV(0) | _BV(4);

    TCCR0A = 0;
    TCCR0B = _BV(CS01);
    TIMSK |= _BV(TOIE0);

OSCCAL = 215;

//    OSCCAL=186;

#define POWERSET

#define NTSC_HI  {    DDRB=0;}
#define NTSC_LOW {    DDRB=_BV(4); }
#define NTSC_VH  {    DDRB=_BV(3); }
#elif defined( POWERSET2 )
#define NTSC_VH  {    DDRB=0;}
#define NTSC_LOW {    DDRB=_BV(4)|_BV(3); }
#define NTSC_HI  {    DDRB=_BV(3); }
#elif defined( POWERSET3 )
#define NTSC_VH  {    DDRB=0; }
#define NTSC_HI   { DDRB=_BV(3); }
#define NTSC_LOW   {    DDRB=_BV(4)|_BV(3); }

//Experimental mechanisms for changing power. Don't work.
#define NTSC_VH  {    OCR1C = 3; TCNT1 = 0; }
#define NTSC_HI  {    OCR1C = 6; TCNT1 = 0;}
#define NTSC_LOW {    OCR1C = 0; TCNT1 = 0;}

    uint8_t line, i;

    #define TIMEOFFSET .12 //.12
    #define CLKOFS .12

    uint8_t frame = 0, k, ctll;
    char stdsr[8*13];
    sprintf( stdsr, "Fr: " );
    sprintf( stdsr+8,  "HalfByte" );
    sprintf( stdsr+16, "  Blog  " );
    sprintf( stdsr+24, "        " );
    sprintf( stdsr+32, " Trinket" );
    sprintf( stdsr+40, "AdaFruit" );
    sprintf( stdsr+48, "        " );
    sprintf( stdsr+56, "        " );
    sprintf( stdsr+64, "        " );
    sprintf( stdsr+72, "        " );
    sprintf( stdsr+80, "        " );
    sprintf( stdsr+88, "        " );

    ADMUX =/* _BV(REFS1)  |  _BV(ADLAR) | */ 1; //1 = PB2
    ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADPS2) | _BV(ADPS1);

#define LINETIME 21 //Linetime of 7..20 is barely valid. So,
//#define WAITTCNT while(TCNT0);

//#define WAITTCNT while(!(TIFR&_BV(TOV0)));
#define WAITTCNT sleep_cpu();

//#define WAITTCNT fintcnt();


    uint16_t ovax; //0..1024 = 0...5v
    uint8_t  msd;
    uint8_t  lsd;


        //H = 1./15734.264 = 63.555 / 2 = 31.7775
        for( line = 0; line < 6; line++ )
        { NTSC_LOW; _delay_us(2.3-TIMEOFFSET); NTSC_HI; _delay_us(29.5-TIMEOFFSET-CLKOFS); }
        for( line = 0; line < 6; line++ )
        { NTSC_LOW; _delay_us(27.1-TIMEOFFSET); NTSC_HI; _delay_us(4.7-TIMEOFFSET-CLKOFS); }
        for( line = 0; line < 6; line++ )
        { NTSC_LOW; _delay_us(2.3-TIMEOFFSET); NTSC_HI; _delay_us(29.5-TIMEOFFSET-CLKOFS); }

        for( line = 0; line < 39; line++ )

            //Do whatever you want.
            //sprintf( stdsr, "%d", frame );
            switch (line)
            case 0:
                NumToText( stdsr+4, frame );
            case 1:
                ovax = ADC;
                ovax = ovax * 49 + (ovax>>1);
            case 2:
                NumToText( stdsr+24, ovax/1000 );
                stdsr[27] = '.';
            case 5:
                NumToText4( stdsr+27, ovax );
                stdsr[27] = '.';



        for( line = 0; line < 2; line++ )

        for( line = 0; line < 220; line++ )
            NTSC_LOW; _delay_us(4.7-TIMEOFFSET);
            NTSC_HI; _delay_us(8-TIMEOFFSET-CLKOFS);

//#define LINETEST
            NTSC_VH; _delay_us(8-TIMEOFFSET-CLKOFS);
            NTSC_HI; _delay_us(44.5);
            ctll = line>>2;
            for( k = 0; k < 8; k++ )
      // draw the character, one pixel at a time
            uint8_t ch = pgm_read_byte( &font_8x8_data[(stdsr[k+((ctll>>3)<<3)]<<3)] + (ctll&0x07) );
            for( i = 0; i < 8; i++ )
                if( (ch&1) ) //if pixel is dark...
                    NTSC_HI;  // pixel is lit
                NOOP; NOOP; NOOP; NOOP;


            NTSC_HI; //_delay_us(4.7-TIMEOFFSET-CLKOFS);

//        NTSC_HI; _delay_us(46-TIMEOFFSET-CLKOFS);

//            NTSC_VH; _delay_us(32-TIMEOFFSET-CLKOFS);
//            NTSC_HI; _delay_us(19.8-TIMEOFFSET-CLKOFS);
    return 0;


Download the original code and the font file here. You will need the font file to make this work.

Mr. Lohr’s YouTube Channel

A Spark of Life: More DigiSpark fun

WP_20151019_22_42_59_Pro__highresI recently wrote about the cool little DigiSpark ATTiny 85 controller board. This little USB wonder, like the AdaFruit Trinket, is based on the ATTiny85 Microcontroller and has limited I/O, memory and is cheap, very cheap.

One thing it is not short on, however, is uses. This little thing can be used for a variety of things, including games and control applications.  For any use, though, you will need some kind of input and some kind of output.  In a previous post, I postulated about porting my ‘Battlestar Galactica’ game to the DigiSpark from the Trinket.  So, here are the results of that endeavor and some other things as well.

For the backstory of the game and why I wrote it, check out this post. I’ll wait.

Read it?  Cool.WP_20151019_22_44_34_Pro__highres

Ok, so there are few differences between the Trinket and the DigiSpark, other than size.  The way you program it is very similar and the pins are nearly identical.  The way you talk to things, is, however, a little different.

The Trinket needed SoftwareSerial. We don’t here, we just use DigitalRead and DigitalWrite and Serial.write to read the button and write to the screen.

The display is a 16×2 Serial LCD from Parallax.  The button is actually a ‘controller’ I built a couple of years ago for my game console. I did not use it for that, opting for the Wii Nunchuck instead.  So, the controller has three buttons that would be used for left, right and ‘fire’ or action.  Here, they just return a 0 if pressed and a 1 when ‘open’.  The code periodically polls the controller for a press and then acts on the press to evaluate a hit or miss.


Now, one of the problems I had was the lack of GROUND pins. So, I made a ground bus, a four pin strip with a wire connecting all four pins. I then connected this to ground on the DS and the button and the LCD as well are connected to this bus. I have one free ground pin.  Well, what I did not realize was that you can use any pin for ground.  While I did not change my connections, I find this pretty cool.

TIP! To use a free pin as ground:

(From the wiki)

You can use an I/O pin as a ground/+5V if you have some left and the current that flow in it is low (a few milliamps if you want the pin to stay around 0V/+5V. If you don’t care about the exact voltage you can go up to 40mA per pin according to the datasheet but it’s good to keep a safety margin).

Configure the pin as an output and set its value to either LOW or HIGH (for ground or +5V

#define button 0
#define gnd 2
void setup() {                
  pinMode (button, INPUT);
  digitalWrite (button, HIGH); // enable pullup
  pinMode(gnd, OUTPUT);
  digitalWrite (gnd, LOW); // use this pin as a ground

For much more information and tips, go to the wiki, located here.

The game code is below.

Come back for more on this cool little device.  Since it is capable of serial i/o, I’m thinking of using the Bluetooth Serial module and connecting the DS to one of my HalfByte Consoles running the graphical serial software for video display from the DS.


Game Code:

#include <TinyPinChange.h>

 // globals
 int  cylonpos;
 int  oldcylonpos;
 int  cyDirection;
 int  button;
 int  posStart;
 int  lin2Start;
 int  bsgpos;
 // special characters
 int  bsg;
 int  cylon;
 // total number of torpedos the ship has left
 int  tShots=10;
 // the setup routine runs once when you press reset:
 void waitforbutton();
 void moveCylon();
 void setup() {  // initialize the digital pin as an output.  
   //define the ship character
   // baddies

   Serial.write(uint8_t(0x0));//to handle a goofy issue with '0'
 // the button is on pin 0  
 // the initial direction is right
 } // the loop routine runs over and over again forever:
 void loop() {
  int score;
  Serial.write(12); // clear the screen and show the instructions
  Serial.println("Shoot the Cylon\n");
  Serial.println("press btn strt");
  // wait for the button
  // define somethings before we start the game loop
  lin2Start=148; // the baddies appear on line 1
  posStart=128;  // the good guys on line 2
  randomSeed(analogRead(0)); // gen a random seed
  bsgpos = 8;  // our ship starts in the middle of the sector
  cylonpos=random(0,15); // baddies warp in at a random spot
  Serial.write(12);  // clear screen
  Serial.write(17);  // turn on backlight so we can see
  Serial.write(posStart + cylonpos);  // uh oh...the Cylon appeared!
  Serial.write(bsg); // and here we are
  // begin the game 
    /* Game loop */
    int button;
    Serial.write(22); // kill the cursor
    button=digitalRead(0);  // check the button
    if(button==0){ // torpedo fired?
      if(cylonpos==bsgpos){ // Hit?
        Serial.write(132); // center 'Hit' on screen
        Serial.print("** HIT **");
        score ++;  // update score
        Serial.write(213); // noise (C at half note, 3rd scale)
        Serial.write(215); // play the note
        if(score==10){  // did we win?
           Serial.write(12); // clear screen
           Serial.write(128);// start at beginning
           Serial.print("You have saved\nthe Galactica.");
           loop();  // start game again
        delay(3000); // did not win yet
        Serial.write(12); // clear screen
        Serial.write(lin2Start); // move cursor to beginning of line
        Serial.write("Score:");  // put up score
        Serial.write(lin2Start+bsgpos); // Since we shot the Cylon, we have to leave the sector, so...
        Serial.write(0x20); // go into hyperdrive and erase the BSG
        bsgpos=random(9,15);  // calculate new position
        Serial.write(lin2Start+bsgpos); //...and, we are here
        cylonpos=random(0,15); // Damn, they found us!
      tShots --; // decrement our torpedo inventory
      if(tShots<1){ // out of ammo?
        Serial.write(12);  // clear screen
        Serial.write(posStart); // start at beginning of line
        Serial.print("The Cylons win.\n");
        int count=1;
        // show animation of our ship exploding
        while (count<10){
        loop(); // Play again
void moveCylon(){
  // sneaky Cylons...they show up anywhere!
  if (random(0,6)>3){
      //Cylon warped
  cylonpos += cyDirection; // figure out which way to move
  if (cylonpos>15){
  if (cylonpos<0){
  // erase from old spot

void waitforbutton(){
  int button;
  while(button==1){     //wait for button press

Surface Book: A true, high end laptop from Microsoft

In addition to three new phones and Band 2, Microsoft has also introduced Surface Pro 4 and Surface Book.  Today, I’m going to look at the remarkable and very expensive Surface Book.

The Surface Book is a laptop, first and foremost. It was designed to be a laptop with a touch screen that can be detached, but is not flimsy looking or feeling like many two in one devices or a tablet with keyboard that ‘clicks’ in place.  This thing has desktop class graphics, sixteen gigabytes of RAM and 128 gigs of storage which can expand up to a terabyte.  The display is 3k by 2k pixels at 267 PPI, weighs 3.3 pounds and comes with the Surface Pen (that has an eraser!)

af6b6c70-e705-4e55-b68c-0dd9077cac74The sixth gen Intel Core processors (i5 or i7) power the monster machine which also has dual graphics: i5 HD graphics in the screen and i5/i7 NVidia in the base unit.  When the display is removed, the tablet is powered by the i5 HD graphics, when you dock it to the keyboard, it becomes the monster again. You flip the screen to create a powerful tablet powered by the NVidia graphics.

It comes with a full complement of connectors, including USB 3 and the very clever hinge connector that mates the display to the rest of the unit.

The hinge uses ‘Muscle Wire’ to attach and keep the display snuggly connected.  The wire works by expanding and contracting when necessary.  When expanded, it keeps the display firmly attached and when it contracts, the display may be removed.  The mated unit is as solid as a traditional laptop.

Microsoft has clearly taken aim at Apple and, to a lesser extent, Google.  Both Apple and Google offer very high end laptops, the Mac Book Pro and the Pixel.  While the Pixel is a very nice laptop, its drawback is that it runs Android and not a true multitasking operating system like Windows or Mac OS X.  By offering this product, with its build quality, choice of features and material as well as price—it starts at $1,499—Apple is clearly the target.

Does this make Microsoft ‘cool’? I don’t know, but what I do know is this laptop is very cool and lust worthy.  If I had two grand to drop on a laptop, this would be my first and only choice.

New Lumia phones and a new Band

Lumia_950_Marketing_01_DSIM1Microsoft introduced a pandora’s box full of new devices. Among them, the new Surface Pro 4, a new Microsoft Band, new Lumia phones and a new laptop, the Surface Book. They also showed off some XBOX One stuff, which I’m not going to talk about here and a nice demo of the HoloLens, which will be available in January of 2016 in developer form for three thousand dollars.


Perhaps the most exciting part of the introduction was of the Lumia 950 and 950 XL.  These things are monster phones, with either an Octacore or Hexacore processor. They aLumia_950XL_Black_Front_SSIMre liquid cooled and smoking fast. The 950 sports a 5.2 inch OLED screen, 20MP rear cameras and triple LED Flash, capable of reproducing accurate skin tones and no red eye. The XL has a 5.7 inch OLED screen. Both devices are capable of 4k full time video (unlike the current 11 second limit.)  Both phones also double as desktop computers with full screen, keyboard and mouse ability.  You can use both the full screen HDMI desktop experience along with using the phone directly.  The demo was truly impressive and shows what Windows Mobile 10 is really capable of doing.  Both phones come with 32gb storage and are expandable to a theoretical two TERABYTES.

The 950 will sell for 549 and the XL is 649 and will be available in November.

The Lumia 550, a lower end phone, is no slouch either. It sports a nice 4.7 inch HD display, 4G LTE, 5mp camera with LED Flash and 2mp forward camera for skype.  It also features a quad core processor and, like the 950 series, is expandable via SD cards.

All three phones will ship with Windows Mobile 10, Office Mobile, Cortana integration, Skype and a suite of lifestyle apps.

The 550 will sell for about $150.


Microsoft-Band-2-image-1A new Band was introduced. This thing has every type of sensor you could possibly want, including heart rate, oxygen, caloric/carb ability, GPS, accelerometer, gyro and more.  It has a Golf mode that can tell you everything you need to know about your game.  It features Cortana integration, touch screen, a multitude of apps (including Uber!?) and full integration with Windows 10. It also works with iOS and Android.  The screen is curved, unlike the previous model, which was flat and a bit awkward.

The Band 2 is the first lifestyle type device I’m actually interested in using.  It will sell for $249. 

There’s much more to talk about, so stay tuned for more on the Surface Pro 4 and Surface Book.

Watch the Press Event.

Arduino IDE 1.6.x errors…unit16_t doesn’t name a type

Quicky post about another goofy issue with the Arduino IDE 1.6.x

While preparing a couple of demos for the HackRVA Microcontroller night, I kept getting this error in the 1.6.x Arduino IDE:

uint16_t doesn’t name a type

Well, The GCC compiler that comes with the IDE enforces many things it never had and many things have been deprecated, including uint16_t. You need to declare it now:

typedef uint16_t PROGMEM prog_uint16_t

The reference below also says:

The typedef is only visible if the macro __PROG_TYPES_COMPAT__ has been defined before including <avr/pgmspace.h> (either by a define directive, or by a -D compiler option.)

uint8_t also generates the error, so a similar declaration can made for it as well.


The Mighty ATTiny85 and DigiSpark

Microcontrollers are lots of fun to play with as well as to build useful things.  They come in all sizes, shapes and varieties.  I am always, however, intrigued with the tiny controllers, like AdaFruit’s Trinket.  Well, the latest one I’ve started to tackle is the DigiSpark.  The DigiSpark is small and comes in several types. I am using the USB flavor. This little guy is on a very small board, about the size of a nickel, and is, itself, a USB dongle.

WP_20150928_23_59_09_Pro (2)

It features six I/O lines, plus power and ground pins.  This thing is a little bit more versatile than the original Trinket, but not much more. The USB version has the added advantage of being a USB dongle itself, meaning you can build a project that plugs into a USB port and act as an external controller. You don’t need USB, once you have programmed it, the power and ground pins can be used to power the device.

The nice thing about the DigiSpark is that you can use the Arduino IDE and SOME of the libraries to program the device.  There is a nice tutorial on setting up a newer release of the IDE and add DigiSpark support.

In a nutshell:

  1. Start the IDE (Install 1.6.x if you don’t already have it installed)
  2. Click FILE, then PREFERENCES
  3. in the Additional Boards Manager URL’s box, enter:
  4. Click OK
  5. Click Tools, then BOARDS
  6. Select Board Manager and then Contributed
  7. In the dialog box that pops up, select DIGISTUMP AVR BOARDS
  8. Click Install
  9. Close the Board Manager
  10. You should now see the DigiSpark boards in the IDE

The thing that tripped me up was uploading a sketch.  I didn’t realize that you don’t need to have the device plugged in prior to uploading (you are told this, but it didn’t sink in.)  Once I unplugged the device, clicked upload and THEN plugged it in, it worked like a charm.

So, now I have to figure out what I want to do with this cool little device. 

But, wait…I still have not really said anything about the device, what it has on it, etc.

It is based on the ATTiny 85 and features six I/O pins:

Pin outs:

    • All pins can be used as Digital I/O

    • Pin 0 → I2C SDA, PWM (LED on Model B)
    • Pin 1 → PWM (LED on Model A)
    • Pin 2 → I2C SCK, Analog
    • Pin 3 → Analog In (also used for USB+ when USB is in use)
    • Pin 4 → PWM, Analog (also used for USB- when USB is in use)
    • Pin 5 → Analog In

The ATTiny 85 specs:

  • 8 Bit Data Bus
  • 20 MHz Max Clock Frequency ( w/ external crystal )
  • 8 kB Program Memory Size
  • 2.7 V to 5.5 V Operating Supply Voltage
  • 6 I/O Pins
  • 512 bytes of RAM


Two things you cannot do from the IDE: burn the bootloader and use the serial monitor. Some libraries will work, most will not.  There is no short circuit or reverse polarity protection, so be careful or you will certainly destroy the board, and, if connected via USB (which it really should not be if using external power) the computer could be damaged as well.


The IDE, as with other Arduino’s, displays the compiler and upload progress in the text area below the coding window.  Several rather bothersome messages can show, but, not to worry, it is normal. See my sample output below.

Sketch uses 668 bytes (11%) of program storage space. Maximum is 6,012 bytes.
Global variables use 9 bytes of dynamic memory.
Running Digispark Uploader…
Plug in device now… (will timeout in 60 seconds)
> Please plug in the device …
> Press CTRL+C to terminate the program.
> Device is found!
connecting: 16% complete
connecting: 22% complete
connecting: 28% complete
connecting: 33% complete
> Device has firmware version 1.6
> Available space for user applications: 6012 bytes
> Suggested sleep time between sending pages: 8ms
> Whole page count: 94  page size: 64
> Erase function sleep duration: 752ms
parsing: 50% complete
> Erasing the memory …
erasing: 55% complete
erasing: 60% complete
erasing: 65% complete
>> Eep! Connection to device lost during erase! Not to worry
>> This happens on some computers – reconnecting…
>> Reconnected! Continuing upload sequence…
> Starting to upload …
writing: 70% complete
writing: 75% complete
writing: 80% complete
> Starting the user app …
running: 100% complete
>> Micronucleus done. Thank you!

Micronucleus is the name of the bootloader.  The disconnect message was a little disturbing, but not a problem.

Maybe I’ll adapt my Battlestar Galactica LCD game to this thing…

Here is a link to the Trinket posts on the blog. It is very similar to the DigiSpark.

digiStump is the maker of the device and they have other products as well. Take a gander around their site. There is a nice Wiki page and forums.

Finally, you can purchase one from Amazon for $4.88 each.  Of course, you can support digiStump by purchasing the device from them, they sell it for $8.95, a little higher than Amazon, but you will be supporting the makers and encourage further development of the product.