TinyPhoto: Embedded Graphics and Low-Fat Computing

Spread the love

TinyPhoto is a small rotating photobook embedded graphics project that uses the low-power ATtiny85 microcontroller (3mA) and a 128×64 pixel OLED display (c.5-10mA typical, 15mA max). This combination can deliver at least 20 hrs of continuous play on a 3V coin cell battery (225mAh capacity). TinyPhoto can be readily built from a handful of through-hole electronic components (12 parts, £5) organized to fit onto a 3cm x 7cm single-sided prototype PCB. The embedded software is c.150 lines of C code and uses less than 1,300 bytes of on-chip memory. TinyPhoto rotates through five user-selectable images using a total of 4,900 bytes (yes, bytes!) stored in the on-chip flash RAM. The setup produces crisp photos on the OLED display with a real-time display rate that is instantaneous to the human eye with the Tiny85 boosted to run at 8MHz. A custom device driver (200 bytes) sets up the OLED screen and enables pixel-by-pixel display. Custom Forth code converts a 0-1 color depth image into a byte-stream that can be written to the onboard flash for rapid display. It is a reminder of what can be accomplished with low-fat computing

The magic, of course, is in the software. This article describes how this was done, and the software that enables it. Checkout the TinyPhoto review on Hackaday!

Tiny Photo – 3cm x 7cm photo viewer powered by ATTiny85 8-bit microcontroller sending pixel level image data to OLED display (128×64 pixels), powered by 3V coin cell battery. Cycles through 5 images stored in 5kB of on-chip Flash RAM. (Note, this is 1 million times less memory than on a Windows PC with 8GB RAM). The magic is in the software.

*New!* (24 Jul 2021) – TinyPhoto V3 is available! Includes fixed-width font driver for OLED (700 bytes), one-time startup screen, and SSD1306 command constants.

Simple Hardware

The electronics are quite simple as you can see from the image, schematic, and PCB layout. Total of 12 components are used, with a bit of hookup wire, which allows it all to fit handily onto a 3cm x 7cm PCB, at a total parts cost of c.£5 including microcontroller (£1.50) and display (£2.50). I used an 8-pin DIL socket to hold the ATtiny85 controller to allow the controller chip to be easily removed, reprogrammed and then re-inserted to display a new set of 5 images, or a different display order for the images. It took 30 minutes to draw the schematics / PCB layout, 90 minutes to solder and test the board, and 60 minutes to prepare the 5 images, including touch-up, for the rotating display.

The Magic is in the Software.

Transformation of a large color image to a 0-1 matrix with 8k pixels or less, for display to a 128×64 pixel OLED display

The first algorithm resizes e.g. a 1.7 megapixel color image (225kB JPG, 24-bit color) into a crisp 128×64 pixel color image (25kB BMP, 24-bit color, 90% shrinkage, IrfanView).

A second algorithm converts the color image to grayscale (Rec 601 luma formula Y=0.2989R+0.5870G+0.1140B, i.e. 30% red, 60% green, 10% blue) and applies a user selectable threshold (say 25) to produce a 0-1 matrix (binary image) with 1=black, 0=white, Image Binarizer).

128×64 OLED displays are built for easy display of text. The smallest font size is 8 pixels high, so the OLED display RAM is segmented into 8 text rows, each 8 pixels high, with 128 columns. Image data is displayed by sending a byte stream, with each vertical byte code containing the 8 pixels from a given text row, with least significant bit at the top.

Converting 0-1 matrix to an OLED/LCD display byte code. Each vertical byte code holds 8 pixels from a single column, LSB at the top, MSB at the bottom.

The last step is post-processing this 0-1 matrix and extracting the vertical byte codes (1 byte holding 8 pixels from a single row) needed to display the image onto the OLED display. As an example in the image above, the three vertical byte codes in the red boxes are 0x00, 0x03, and 0x30 respectively. A macro gets the text 0-1 matrix into the right format to load directly into Forth as an image-map in memory ready for extraction of byte codes. The vertical byte code calculation is done in a few lines of Forth code (see Code section below — 3iArt.fs)

The vertical byte codes are then burned to the onboard Flash memory of the ATtiny85 microcontroller (4,900 bytes for 5 images). I use a 4 field datastructure per image to hold the image parameters (metadata) to ensure the images are displayed correctly (image size, packet transmission size over I2C, number of packets before adding a newline, etc.).

The ATtiny85 microcontroller runs the 150 lines of C code (c.1,300 bytes) in a tight loop that generates one by one the five images and sends the image data via I2C to the 128×64 pixel OLED display.

Get the code.

Size Matters on the Tiny85

In order to get all this to fit on the ATtiny85 (512 bytes SRAM, 8kB Flash), I wrote my own simple display driver code (c.200 bytes Flash) for the SSD1306 display driver IC integrated into the OLED display. It removes all the frills and preserves only what is needed to initialize the OLED display, set its contrast (high brightness) and orientation, and directly send image data for display. This removes the dependency on the 35x larger (7kB Flash) software drivers provided by e.g. Adafruit which would have left no room on the Tiny85 for the images. It also removes the need for a 1kB SRAM software buffer duplicating the OLED’s display RAM, but which is double the 512 bytes that the Tiny85 has. The result is a low-fat graphics driver for the OLED SSD1306 chip.

Communicating to the Display

Since the ATtiny85 does not come with built in I2C capability, I used the TinyWireM drivers from BroHogan that use Atmel’s USI (universal serial interface) in hardware to emulate I2C. This reduced the max packet size that worked to 8 bytes (from 32 bytes with Atmega328P controller that does have I2C in hardware), but even so, the display was smooth, and able to generate all 8k pixels (128×64) within the 60Hz framerate that allows the human eye to see it as instantaneously generated.

Important: To get snappy display performance, the ATtiny85 must be running at 8MHz or faster. The default fuses for the chip are likely set at 1MHz, which is not fast enough to refresh the screen within the 60Hz the human eye can detect. You’ll need to select 8MHz (internal) clock and burn the bootloader using an ISP programmer. This will set the fuses on the chip correctly to run at the faster setting.

Programming the Chip

The final step is programming the chip using the Arduino IDE. You will need to have ATtiny board definitions loaded and the TinyWireM I2C drivers for ATtiny (get both here).

To do this, you can use a commercially available ISP programmer (less than £20), or if you have a spare Arduino Nano or Uno lying around, you can use this (see Programming Microcontrollers for details).

Low Power

The components of TinyPhoto are selected for low power. The ATtiny85 sips power, at 3mA. The OLED display draws 5mA while displaying a 64×64 pixel photo, and 10mA displaying a 128×64 photo (full screen). With an average total draw of 10mA, TinyPhoto can provide 22 hrs of operation on the 3V CR2032 coin cell battery (225mAh capacity).

Result!

You can see the result in the 10-second video clip below.

Hackaday’s review of TinyPhoto, by Tom Nardi (July 19, 2021)

As noted by one of the readers, the two-color yellow/blue OLEDs that I had in my parts box at the time are not ideal, and the final vibe would have been better with the all-white or all-blue OLED displays.


Details

Specifications:

  1. Microcontroller – Tiny85, 8-pin DIP, 8-bit microcontroller (1kB SRAM, 8kB Flash), running at 8Mhz
  2. Small Hardware – PCB is 3cm x 7cm
  3. Low Power – less than 10mA power consumption
  4. Long battery life – powered by single 3V 2032 coin cell battery (225mAh capacity), expect 20+ hrs of operation
  5. Low Memory usage: 300 bytes SRAM, 1.3kB core program. Max 1kB per image.
  6. Display – OLED 128×64 pixel display with integrated SSD1306 controller chip and I2C communication
  7. I2C driver – BroHogan 2011: TinyWireM.avr

Fun facts:

  • Tiny85 uses a meagre 6kB of memory (1kB code, 5kB data), 1 million times less memory than the 8GB RAM used by a typical PC.
  • TinyPhoto powers up and displays first picture instantaneously (within 200ms) after applying power.
  • The refresh rate is fast enough (within 60Hz) that delays are imperceptible by the human eye.

Summary of Steps (see Code below):

  1. Select any photo image to display, no limitations on size or color-depth.
  2. Use IrfanView to resize to a 128×64 pixel color bitmap
  3. Use Image to Binary to convert to hex codes intended for SSD1306 driver
  4. Test the image display using 3iForth
  5. If correct, store hex codes into Flash and read from Flash
  6. Initialize OLED by sending right commands to SSD1306 driver chip (no need to use the bloated AdaFruit SSD1306/GFX drivers)
  7. Setup I2C for communication between the uC and the SSD1306 driver IC integrated into the OLED display. Use for Attiny85/84 processors. Can use the built-in library for Atmega328P-based processors.
  8. Burn images and code to the Tiny85 controller using an ISP programmer.
  9. Run the hardware at 8MHz to display the graphics (pixels) in a tight loop.

Parts List

TOTAL: £5.09 for 12 parts count
(prices given as at purchase, current prices continually fluctuate, further searches can find lower prices)

  1. ATtiny85 microcontroller (£1.50)
  2. OLED display 128×64 pixels (£2.50, all-white or all-blue)
  3. 2x 0.1uF caps to power smooth the Tiny85 and the OLED display (1p)
  4. 8-pin DIL IC socket for holding Tiny85 (6p)
  5. 3V CR2032 coin cell battery (22p)
  6. CR2032 coin cell battery holder (5p)
  7. Green LED 3mm standard (2p)
  8. 1k ohm current-limiting resistor for the LED (1p)
  9. Slide switch SPDT (2p)
  10. Proto PCB board 3cm x 7cm (30p)
  11. 4x M2 standoffs M/F 8mm/6mm (5p ea, 20p)
  12. 4x M2 nuts F/F 6mm (5p ea, 20p)

Code / Instructions

More details can be added based on reader interest (feel free to use comments to request).

    Image Examples: butterfly and jaguar images to test with

  1. butterfly_sm.bmp (this is the resized butterfly color file, 114×64 pixels)
  2. jaguar.bmp (this is the resized butterfly color file, 114×64 pixels)

    Forth code:
    Instructions: This GForth code loads the 0-1 pixel data from the butterfly image and converts to vertical byte codes which are stored in TinyPhoto_data.avr which Tiny85 controller sends to the OLED display.
    include 3iArt_rel.fs
    include 3iArt-butterfly_rel.fs
    butterfly

  3. 3iArt_rel.fs (GForth) (this file has the Forth code to extra image bytecode data from 0-1 pixel matrix)
  4. 3iArt-butterfly_rel.fs (this file has the 0-1 pixel matrix input data for butterfly.bmp)

    C code for Tiny85 microcontroller (Arduino):
    Instructions: Compile TinyPhoto.avr in Arduino IDE using ATtiny board files and BroHogan I2C TinyWireM driver. Upload to Tiny85 microcontroller using ISP Programmer.

  5. TinyPhoto.avr (compile this in Arduino, change path to include *_data.avr)
  6. *New!* (24 Jul 2021) 3iFonts.avr (this file has fixed width font definitions 8hx5w for display to OLED)
  7. TinyPhoto_data.avr (this file has the image bytecode data, must be included)
  8. ATtiny_ArduinoBoardFiles.zip
  9. ATtiny_I2C_driver_BroHogan2011.zip

    ISP Programmer:
    NEW (July 2021) – For programming the chips using the Arduino IDE, I have built a simple three-chip Atmel programmer that has sockets to receive the ATtiny85 (DIP-8), ATtiny84 (DIP-14), or Atmega328P (DIP-28) microcontrollers, and which uses an Arduino Nano running the ArduinoISP code to act as the in-system programmer (ISP) to write the compiled code to the target chips. It is easy to assemble on a 4cm x 6cm PCB and less than a dozen through-hole components. Total parts cost, including the Nano, is c.£5. If interested, ask in the comments.

7 comments to TinyPhoto: Embedded Graphics and Low-Fat Computing

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  

  

  

Your comments are valued! (Please indulge the gatekeeping question as spam-bots cannot (yet) do simple arithmetic...) - required

Optionally add an image (JPEG only)

 

Stats: 1,089,379 article views since 2010 (Aug '24 update)

Dear Readers:

Welcome to the conversation!  We publish long-form pieces as well as a curated collection of spotlighted articles covering a broader range of topics.   Notifications for new long-form articles are through the feeds (you can join below).  We love hearing from you.  Feel free to leave your thoughts in comments, or use the contact information to reach us!

Reading List…

Looking for the best long-form articles on this site? Below is a curated list by the main topics covered.

Mathematics History & Philosophy

  1. What is Mathematics?
  2. Prehistoric Origins of Mathematics
  3. The Mathematics of Uruk & Susa (3500-3000 BCE)
  4. How Algebra Became Abstract: George Peacock & the Birth of Modern Algebra (England, 1830)
  5. The Rise of Mathematical Logic: from Laws of Thoughts to Foundations for Mathematics
  6. Mathematical Finance and The Rise of the Modern Financial Marketplace
  7. A Course in the Philosophy and Foundations of Mathematics
  8. The Development of Mathematics
  9. Catalysts in the Development of Mathematics
  10. Characteristics of Modern Mathematics

Topics in Mathematics: Pure & Applied Mathematics

  1. Fuzzy Classifiers & Quantile Statistics Techniques in Continuous Data Monitoring
  2. LOGIC in a Nutshell: Theory & Applications (including a FORTH simulator and digital circuit design)
  3. Finite Summation of Integer Powers: (Part 1 | Part 2 | Part 3)
  4. The Mathematics of Duelling
  5. A Radar Tracking Approach to Data Mining
  6. Analysis of Visitor Statistics: Data Mining in-the-Small
  7. Why Zero Raised to the Zero Power IS One

Technology: Electronics & Embedded Computing

  1. Electronics in the Junior School - Gateway to Technology
  2. Coding for Pre-Schoolers - A Turtle Logo in Forth
  3. Experimenting with Microcontrollers - an Arduino development kit for under £12
  4. Making Sensors Talk for under £5, and Voice Controlled Hardware
  5. Computer Programming: A brief survey from the 1940s to the present
  6. Forth, Lisp, & Ruby: languages that make it easy to write your own domain specific language (DSL)
  7. Programming Microcontrollers: Low Power, Small Footprints & Fast Prototypes
  8. Building a 13-key pure analog electronic piano.
  9. TinyPhoto: Embedded Graphics and Low-Fat Computing
  10. Computing / Software Toolkits
  11. Assembly Language programming (Part 1 | Part 2 | Part 3)
  12. Bare Bones Programming: The C Language

Technology: Sensors & Intelligent Systems

  1. Knowledge Engineering & the Emerging Technologies of the Next Decade
  2. Sensors and Systems
  3. Unmanned Autonomous Systems & Networks of Sensors
  4. The Advance of Marine Micro-ROVs

Maths Education

  1. Maxima: A Computer Algebra System for Advanced Mathematics & Physics
  2. Teaching Enriched Mathematics, Part 1
  3. Teaching Enriched Mathematics, Part 2: Levelling Student Success Factors
  4. A Course in the Philosophy and Foundations of Mathematics
  5. Logic, Proof, and Professional Communication: five reflections
  6. Good mathematical technique and the case for mathematical insight

Explore…

Timeline