Zonnestroompanelen in Nederland

duurzaamheid achter de meter

(51) Muybridge’s Zoo for the ESP32WROOM

by Floris Wouterlood – August 1, 2021


Eadward Muybridge (1830-1904) pioneered what today we would call high-speed photography: capturing successive phases of movement. The opposite: stop motion animation, is what we achieve in the current project with the aid of an ESP32-WROOM-32 microcontroller and a TFT display with parallel interface. Eleven examples of Muybridge’s 19th century performers now trot, dance, run or hop once again on screen, thanks to electronics and software. A true ‘Muybridge’s Zoo’!


After publishing his legendary 1878 photoseries ‘The Horse in Motion”, featuring the race horse ‘Sallie Gardner’ galloping along a battery of 12 photocameras with tripwire triggered shutters, Eadward Muybridge (1830-1904) decided to further engage in this entirely novel field. He moved to Philadelphia where he constructed a permanent studio equipped with a multi-camera battery and began photographing scores of moving animals as well as humans performing all kinds of action. This work resulted in 1887 in a picture book “Animal Locomotion: An Electro-Photographic Investigation of Consecutive Phases of Animal Movements”. The publication contains an amazing collection of animals and persons frozen in frames. A selection of plates is accessible via the US Library of Congress website, https://www.loc.gov/ (search for ‘Muybridge’).

Stop-motion animation

Stop-motion animation is an attempt to reverse what Muybridge originally did. Watching phases of movement in rapid succession in flickering illumination results in an illusion of motion. Muybridge commercialized his inventory of high-speed photographs by introducing the Zoopraxiscope: a mechanical device that uses the stroboscopic effect to produce the illusion of ‘moving’ objects. Image frames printed on a disk were projected onto a screen or view port in fast succession via a shutter or slit mechanism. The Zoopraxiscope can therefore be regarded as an evolutionary ancestor of the 20th century cinemascope or movie film projector.

Here comes in the Arduino and the ESP32

Disks, shutters and slit mechanisms are nowadays replaced by microcontrollers, displays and software. In several papers * , ** I have explained how to convert Muybridge’s series of photographs into sketches that can be run on an Arduino. Just like good old Eadward I started with an archetype stop motion: the horse Sallie Gardner and its jockey*. Attempting to create animations on an Arduino is very helpful to understand the importancy of issues such as memory requirements, microprocessor speed limits, interface speed and display characteristics. With an Arduino it is possible to compress 10 monochrome frames with dimensions 96*64 pixels into one electronic animation. Sallie galloping again and again in cyberspace!

In a common Arduino all the processing is done by a single 8-bit microchip equipped with 32kB program memory. The program memory holds both the image frames and the instructions necessary to decode the frames and to send them to the display. Very, very early in any animation project a desire for larger and more frames develops. Bigger frames provide better details, more frames create smoother animations. Hence the switch from the Arduino to an ESP8266 powered microcontroller board in a follow-up project: T-rex for the Wemos D1 mini**. The ESP8266 design features 4 MB of program memory and a fast processor. The successor of the ESP8266 design, the ESP32, has a 32-bit dual core processor on board running at 40 MHz. It also features a sufficient number of pins to connect parallel displays. A library with superb performance created by Bodmer (TFT_eSPI.h) makes it very attractive to start experimenting with animations that use progressively bigger chunks of memory and that need fast processing and dito display.

The Muybridge collection, US Library of Congress

It is interesting to study the amazing collection of plates and illustrations available in the Muybridge collection of the US Library of Congress. This prompted me to upgrade the existing ‘Sallie Gardner’ animation, and to add animations of several of the animals and humans documented by Muybridge. The current T-rex sketch is an update of my own previous Tyrannosaurus rex animation**. I am sure Muybridge would have loved one of these dino’s stampeding in front of his cameras. Unfortunately for Muybridge the first T-rex skeleton was discovered only two years before his death. And they were extinct of course. Muybridges’ Zoopraxiscope’ or similar technology is necessary to bring T-rex artificially back into action. 

figure 1. From photo to display. A, One frame of ‘Elephant Ambling’, photoseries nr. 27 by Eadward Muybridge (source: https://commons.wikimedia.org/wiki/File:Elephant_walking.jpg). B, Overlay in vector drawing program. Note that I added tusks, C, Bitmap export. D, Display after conversion of the bitmap into a char array. 320*240 parallel interface TFT screen wired to a ESP32WROOM-32 microcontroller board***. The elephant’s char array dimensions are 220*128 pixels and the animation consists of 8 frames. Note that this display is commercially available as an Arduino TFT shield, ready to be used with an Arduino Uno.

The zoo: a variety of animal species, frame sizes and frame numbers

Note that all these animations run on the ‘standard’ assembly consisting of a ESP32-WROOM32 board connected in a proper way to a 320*240 TFT display with parallel interface***. The microcontroller is mounted on a bench that has a socket header that accommodates various Arduino parallel TFT shield models. The shield used for the present paper (and sketches) has the reliable ILI9341 controller on board.

The population of Zoo members is listed in the following table.

animation frame size (w*h) bytes per frame number of frames
camel 184*28 2,048 8
cat 288*128 4,608 20
dog 288*128 4,608 10
elephant 220*128 3,530 8
horse 192*128 3,072 9
human (small) 128*28 2,048 10
human (big) 200*220 5,500 12
kangaroo 220*128 3,530 9
ostrich 128*128 2,048 8
penguin 80*128 1,280 10
T-rex 240*128 3,840 7

 Note that all members of the zoo except the kangaroo, penguin and T-rex, are based on original Muybridge photoseries. At the base of the kangaroo and penguin are animated GIFs acquired on the internet and reproduced, ‘Muybridge tradition’. All subjects are intentionally running, walking or trotting with their nose pointing left (Muybridge forced all his animals to run left to right; this may have had a technical cause, I suspect the triggering sequence of his camera battery). Scientific depiction of animals is traditionally ‘nose left’.

Conversion of an original Muybridge motion photograph series to an Arduino sketch

As this process has been described in detail previously* a brief survey is sufficient here. Several methods are available. Here is my favorite procedure.

Step 1: grayscale bitmap via vector to monochrome bitmap

A digital copy of a Muybridge photoseries is imported in a vector-based drawing program. Next the contour of the subject is drawn in overlay on each image frame. Then the photograph is hidden, the contours of successive frames aligned and frame after frame exported as monochrome bitmap. At the end of this step we have as many monochrome bitmaps as there are image frames in Muybridge’s photoseries.

Step 2: creation of hexadecimal c-array image code

In a separate program each monochrome bitmap is converted into C-array image code that is ascii formatted. A C-array image contains the original image hexadecimally coded in groups of bytes. Conversion from original bitmap to hexadecimal C-array code is done with the program lcd-image-converter (freely available at https://sourceforge.net/projects/lcd-image-converter/). Output of lcd-image-converter is a C-array file that, because it is in plain ascii text format, is accessible with an ascii editor, e.g., Notepad or Gedit. The C-array format is supported by the Arduino interface and can be imported into a sketch by simple copy-paste action.

Structure of all Muybridge Zoo Arduino sketches

Like any sketch a series of definitions and declarations need to be made. Thanks to Bodmer’s versatile TFT_eSPI library suite this section can be kept very short. Notice that the library was originally written to support displays with SPI interface and has been expanded by Bodmer with support of displays with parallel interfaces, most successfully to TFTs equipped with ILI 9341, ILI9481 and ILI9486 controllers. The sketch structure is illustrated here by the example ‘Muybridge’s elephant’

// Muybridge’s elephant

#include <TFT_eSPI.h> // hardware-specific library
TFT_eSPI tft = TFT_eSPI(); // invoke custom library

int frametime; // slows down the animation
int x_pos; // positions animation on screeen
int y_pos;

#define BLACK 0x0000 // give human names to 16-bit colors
#define AFRICA 0xAB21
#define WHITE 0xFFFF

The variable named ‘frametime’ dictates the time between two successive image frames. A high number means a slower animation. Variables ‘x_pos’ and ‘y_pos’ control the position of the upper left corner of the image frames. Colors are defined hexadecimally in the RGB565 color space

Next come the image frames which are stored as char arrays in program memory:

static const unsigned char elephant_000 [ ] PROGMEM = { 0x00, 0x00, ……. };

and so forth, up to frame ‘elephant_007’.

After this, the setup () section starts. Serial Monitor output is enabled to document progress:

The ‘floor’ line is the surface on which the elephant ‘walks’. Such a bottom line visually enhances the animation. Note that the background is painted in the same color (‘AFRICA’) as the body color of the image frames. Only part of the available screen surface is used by the bitmap; this to minimize flickering.

And then follows the loop ():

void loop (){

Serial.println (“run baby run”);
tft.drawBitmap (x_pos, y_pos, elephant_000, 220, 128, WHITE, AFRICA);
delay (frametime);
tft.drawBitmap (x_pos, y_pos, elephant_001, 220, 128, WHITE, AFRICA);
delay (frametime);
tft.drawBitmap (x_pos, y_pos, elephant_002, 220, 128, WHITE, AFRICA);
delay (frametime);
tft.drawBitmap (x_pos, y_pos, elephant_003, 220, 128, WHITE, AFRICA);
delay (frametime);
tft.drawBitmap (x_pos, y_pos, elephant_004, 220, 128, WHITE, AFRICA);
delay (frametime);
tft.drawBitmap (x_pos, y_pos, elephant_005, 220, 128, WHITE, AFRICA);
delay (frametime);
tft.drawBitmap (x_pos, y_pos, elephant_006, 220, 128, WHITE, AFRICA);
delay (frametime);
tft.drawBitmap (x_pos, y_pos, elephant_007, 220, 128, WHITE, AFRICA);
delay (frametime);
Serial.println (“next iteration”);

figure 2. The population of Muybridge’s Zoo: The library function drawBitmap is instructed to position the left upper corner of each bitmap on x_pos and y_pos. The name of the frame char array is declared and the size of the bitmap in pixels is provided (220*128) as well as the foreground and background colors. Foreground color is the white body contour with enhancements that improve the animation. The elephant steps along happily in 8 consecutive frames. Complete sketches for all the members of Muybridge’s Zoo are supplied at the end of this document. All sketches contain the hexadecimal C-array description for each frame. I have added for each frame a series of commented lines consisting of empty and black characters that provide a visual impression of how the frame looks like.

Results and discussion

Almost all of the work necessary to produce an animation is usually invested in the preparation of animation frames. The challenge is – as explained in the previous animation projects – to add subtle enhancements to the animals’ contour to provide a realistic suggestion of movement of the legs, tail, head and skin. Through continuous experimentation the smoothest and most elegant animation prevails. Refinement can be done by preparing in the Fiji imaging progran an animated GIF from the bitmap frames, judge the animation, make minute changes in frames with a bitmap editor, prepare a new animated GIF, and so forth.

Image manipulation software used in this project


All sketches are inside ESP32_WROOM32_muybridge_zoo.zip

Upon uncompressing the zip file you will see:

A folder named ESP32_WROOM32_muybridge_zoo that contains:


ESP32_WROOM32_muybridge_zoo.zip can be downloaded here


*Stop-motion of Eadward Muybridge’s galloping horse on Arduino 12864 LCD, OLED and TFT displays. Floris Wouterlood, TheSolarUniverse, May 23, 2020.

**The T-rex project: animations for Arduino and Wemos D1 mini – Floris Wouterlood, TheSolarUniverse, November 12, 2020.

***ESP32-WROOM-32 and Uno-shield parallel TFT displays – Floris Wouterlood, TheSolarUniverse, June 1, 2021.