Build a 3D printed light up tombstone with an animated eye! Use the HalloWing M4 and NeoPixels to make a backlit sign with a custom message or spooky face! 

HalloWing M4

Use the HalloWing M4 with it's pumpkin spiced silkscreen to make this years projects really pop! Features the crispy IPS display, gobs of on-board sensors, and a nice assort of expansion ports. Create your own eye graphics and change them by swap out bitmap images.

3D Prints, Acrylic & Vinyl

The parts are designed to snap fit together and for support-free 3D printing! Use black LED acrylic to make a panel with vinyl graphics. The design features Victorian style aesthetic with floral ornaments and chamfered edges.


Angled shot of Adafruit HalloWing M4 Express.
This is Hallowing..this is Hallowing... Hallowing! Hallowing!  Following up on 2018's
Adafruit NeoPixel LED Strip with 3-pin JST PH Connector lit up rainbow
Plug in and glow, this Adafruit NeoPixel LED Strip with JST PH Connector has 30 total LEDs in a "60 LED per meter" spacing,...
LED RGB matrix 10.2" x 5.1" with "Adafruit Industries LED Matrix" text showing, and LED acrylic slowly covering to make it nicely diffused
 nice whoppin' rectangular slab of some lovely black acrylic to add some extra diffusion to your LED Matrix project. This material is 2.6mm (0.1") thick and is made of...
Lithium Ion Battery Pack with two round cells 3.7V 4400mAh with JST PH connector
Need a big battery for your project? This lithium-ion pack is made of 2 balanced 2200mAh cells for a total of 4400mA capacity! The cells are connected in parallel and spot-welded to a...
USB cable - USB A to Micro-B - 3 foot long
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or...
1 x JST Cable with On/Off Switch
JST PH2 2-pin Extension Cable

The diagram below provides a visual reference for wiring of the components. This diagram was created using the software package Fritzing.

Adafruit Library for Fritzing

Use Adafruit's Fritzing parts library to create circuit diagrams for your projects. Download the library or just grab individual parts. Get the library and parts from GitHub - Adafruit Fritzing Parts.

Wired Connections

NeoPixel Strip

  • DIN to NeoPixel Port on HalloWing M4
  • 5V to NeoPixel Port on HalloWing M4
  • GND to NeoPixel Port on HalloWing M4


  • 2-pin JST cable to On/Off Switch with JST


  • 2-pin JST cable to battery port on HalloWing M4


The Adafruit board can be powered via USB or JST using a 3.7v lipo battery. In this project, a 4400mAh lipo battery is used. The battery is rechargeable with the USB port on the Feather board. The switch features 2-pin JST connector for connecting the battery to the Feather.

Adafruit boards that use ATSAMD21 ("M0") or ATSAMD51 ("M4") chips are easy to get working with the Arduino IDE. Most libraries (including the popular ones like NeoPixels and display) will work with those boards, especially devices & sensors that use I2C or SPI.

Now that you have added the appropriate URLs to the Arduino IDE preferences in the previous page, you can open the Boards Manager by navigating to the Tools->Board menu.

Once the Board Manager opens, click on the category drop down menu on the top left hand side of the window and select All. You will then be able to select and install the boards supplied by the URLs added to the preferences.

Remember you need SETUP the Arduino IDE to support our board packages - see the previous page on how to add adafruit's URL to the preferences

Install SAMD Support

First up, install the latest Arduino SAMD Boards (version 1.6.11 or later)

You can type Arduino SAMD in the top search bar, then when you see the entry, click Install

Install Adafruit SAMD

Next you can install the Adafruit SAMD package to add the board file definitions

Make sure you have Type All selected to the left of the Filter your search... box

You can type Adafruit SAMD in the top search bar, then when you see the entry, click Install

Quit and reopen the Arduino IDE to ensure that all of the boards are properly installed. You should now be able to select and upload to the new boards listed in the Tools->Board menu.

Select the matching board, the current options are:

  • Feather M0 (for use with any Feather M0 other than the Express)
  • Feather M0 Express
  • Metro M0 Express
  • Circuit Playground Express
  • Gemma M0
  • Trinket M0
  • QT Py M0
  • ItsyBitsy M0
  • Hallowing M0
  • Crickit M0 (this is for direct programming of the Crickit, which is probably not what you want! For advanced hacking only)
  • Metro M4 Express
  • Grand Central M4 Express
  • ItsyBitsy M4 Express
  • Feather M4 Express
  • Trellis M4 Express
  • PyPortal M4
  • PyPortal M4 Titano
  • PyBadge M4 Express
  • Metro M4 Airlift Lite
  • PyGamer M4 Express
  • Hallowing M4
  • MatrixPortal M4
  • BLM Badge

Windows 7 and 8.1

Windows 7 and Windows 8.1 have reached end-of-life and are no longer supported. They required driver installation. A limited set of drivers is available for older boards, but drivers for most newer boards are not available.


Now you can upload your first blink sketch!

Plug in the SAMD21 M0 or SAMD51 M4 board, and wait for it to be recognized by the OS (just takes a few seconds). It will create a serial/COM port, you can now select it from the drop-down, it'll even be 'indicated' as Trinket/Gemma/Metro/Feather/ItsyBitsy/QT Py/Trellis or whatever the board is named!

A few boards, such as the QT Py SAMD21, Trellis M4 Express, and certain Trinkey boards, do not have an onboard pin 13 LED. You can follow this section to practice uploading but you won't see an LED blink!

Now load up the Blink example

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second

And click upload! That's it, you will be able to see the LED blink rate change as you adapt the delay() calls.

If you are having issues, make sure you selected the matching Board in the menu that matches the hardware you have in your hand.

Successful Upload

If you have a successful upload, you'll get a bunch of red text that tells you that the device was found and it was programmed, verified & reset

After uploading, you may see a message saying "Disk Not Ejected Properly" about the ...BOOT drive. You can ignore that message: it's an artifact of how the bootloader and uploading work.

Compilation Issues

If you get an alert that looks like

Cannot run program "{}\bin\arm-non-eabi-g++"

Make sure you have installed the Arduino SAMD boards package, you need both Arduino & Adafruit SAMD board packages

Manually bootloading

If you ever get in a 'weird' spot with the bootloader, or you have uploaded code that crashes and doesn't auto-reboot into the bootloader, click the RST button twice (like a double-click)to get back into the bootloader.

The red LED will pulse and/or RGB LED will be green, so you know that its in bootloader mode.

Once it is in bootloader mode, you can select the newly created COM/Serial port and re-try uploading.

You may need to go back and reselect the 'normal' USB serial port next time you want to use the normal upload.

At this point you should be able to upload code (such as the “Blink” sketch) to the board, the basics are confirmed working. If not, work though the prior two pages.

Source Code

Source code for this project is found in the Adafruit_Learning_System_Guides repository on Github, specifically in the M4_Eyes subdirectory. Here’s a direct download link:


The following libraries are used by the eye code (or are referenced indirectly by libraries used). These can be installed through the Arduino Library Manager (SketchInclude LibraryManage Libraries…)

  • Adafruit_Arcada
  • Adafruit_GFX
  • Adafruit_BusIO
  • Adafruit_ImageReader
  • Adafruit_LIS3DH
  • Adafruit_MSA301
  • Adafruit_NeoPixel
  • Adafruit_Seesaw
  • Adafruit_Sensor (Adafruit Unified Sensor in Library Manager)
  • Adafruit_SPIFlash
  • Adafruit_ST7789
  • Adafruit_TinyUSB
  • Adafruit_TouchScreen
  • Adafruit_ZeroDMA (Adafruit Zero DMA in Library Manager)
  • Adafruit_ZeroPDM (Adafruit Zero PDM in Library Manager)
  • Adafruit_ZeroTimer
  • ArduinoJson (not Arduino_JSON)
  • SdFat - Adafruit fork (not the standard SdFat fork)

Recent versions of the Arduino IDE install dependent automatically, so installing Adafruit_Arcada should cover most if not all of this.

Additionally, depending on which of the “user” code tabs is active, you might need:

  • Adafruit_AMG88xx (used by user_watch.cpp)

Project Settings

  • Tools→CPU Speed→180 MHz (overclock) (200 MHz is a bit too much for some boards and may lock up, but you can give it a try. We use 180 MHz for our prepackaged .UF2 files since it’s likely to work on more boards in the wild.)
  • Tools→Optimize→Faster (-O3) (do not use higher settings for this code, it may corrupt the flash filesystem requiring a complete wipe)
  • Tools→USB Stack→TinyUSB (the code will not compile without this selected!)

Additional Features

By default, the M4 eyes code only runs the eye animation. You'll need to turn on a setting in the code in order to enable NeoPixel animations alongside the eye animation.

Enable NeoPixels

In the M4_eyes Arduino sketch, look in the tabs for the user_neopixel.cpp sketch. In the top of the code, change the 0 to a 1. This will enable the NeoPixel rainbow cycle code to run while the eye is animating.

Update the LED_PIN to 3 and change the LED_COUNT to 30 or however many you'd like to use in your build.

Adjust any of the parameters you see fit. For example, the brightness of the NeoPixels (default is 50, 255 is the max).

Set LED_PIN to 8 if you'd like to use the four built-in NeoPixel LEDs.

Re-upload the code to the HalloWing M4 using the recommended profile and configuration. 

Parts List

STL files for 3D printing are oriented to print "as-is" on FDM style machines. Parts are designed to 3D print without any support material. Original design source may be downloaded using the links below.

File names

  • face-plate.stl
  • face-frame.stl
  • front-frame.stl
  • back-frame.stl
  • back-cover.stl
  • base-box.stl
  • base-cover.stl
  • eye-ring.stl

CAD Assembly

The HalloWing M4 is secured to the face plate. The face plate is secured to the frame with M3 screws. A piece of black LED acrylic snap fits onto the face plate. The back frame attaches to the frame. The back cover snap fits onto the back frame. The base is secured to the front and back frames with M3 screws and hex nuts. The bottom cover snap fits onto the base.

Attach Frames

The face-frame.stl part to the front-frame.stl part. These two are attached together using either super glue adhesive or strong double-sided tape. The mating surfaces should be the side that was on the printer build plate.

Assembled Frame

The frame was split into two pieces to avoid 3D printed support material. The mounting holes are M3 sized. These can be optionally threaded with an M3 screw tap.

Vinyl for Face Plate

Decals were applied to the surface of the face-plate.stl part. The design is a vector file that can be used with a vinyl cutter. Excess vinyl was weeded out to isolate the desired graphics. Transfer tape is then used to apply the matte black vinyl onto the face-plate.stl part. 

Applied Vinyl on Face Plate

Alignment can be tricky. A light table can be used to better see the vinyl when positioned over the part. The surface of the part should be wiped cleaned before applying vinyl. The texture makes the surface look like cracked desert sand or peeling dried paint.

Acrylic Plate

The acrylic plate was cut from a 12x12 sheet using a scoring tool. Use the SVG file of the template. Optionally use a laser cutter or CNC mill to cut out the plate.

  • Plate Dimension: 80mm x 104mm

Acrylic Plate Vinyl

Vinyl decals were applied to the acrylic plate. SVG files of the graphics are linked below. Matte black vinyl was used to mask out desired areas in the artwork.

Installing Acrylic Plate

The acrylic plate is press fitted onto the back of the face-plate.stl part. The edge of the acrylic is inserted at an angle and fitted under the tabs. Flex the face plate slightly to allow the other side to snap fit over the acrylic plate.

Attach Eye Ring

An extra embellishment was created to bring attention to the eye. It is fitted over the cutout on the face-plate.stl part. This can be super glued or secured with strong double-sided tape.

NeoPixel Setup

To achieve the best lighting effect, the NeoPixel strip was split into two sections. The two strips are daisy chained together with data in going into data out and both sharing power and ground. 

Connect Switch to HalloWing M4

This On/Off switch features a JST extension cable that makes cutting the power from the battery easy. It's got a chonky button with a solid tactile feel. The length of the cable is just right for this project.

Connect Strip to HalloWing M4

The NeoPixel strip features a 3-pin JST connector that plugs into the NeoPixel port on the side of the HalloWing M4.

Attach Strip to Cover

The two strips of NeoPixel are attached to the back cover using double-sided Nitto tape. The strips are positioned in the center with equal spacing between them. Optionally use hot glue or mounting tack.

Screws for HalloWing M4

The HalloWIng M4 is secured using M3 x 6mm long flat head machine screws. Short screws are used in order tightly secure the PCB to the face-plate.stl part.

Secured HalloWing M4

Place the HalloWing M4 over the built-in standoffs on the face-plate.stl part. Fit the bottom standoffs through the mounting holes on the PCB. Line up the mounting holes near the USB port with the built-in standoffs. Insert and fasten 2x M3 screws to secure the PCB.

Screws for Face Plate

The face plate is secured to the frame using 4x M3 x 6mm long machine screws. Place the face plate down into the recess in the frame. The screws are inserted into the four tabs on the side of the face plate. Fasten the screws to secure the face plate to the frame.

Installing Back Frame

The back frame snap fits onto the front frame. Insert the lip near the top into the frame. The edges on the side of the frame grab onto the nubs on the frame.

Installed Back Frame

The back frame allows the LED strip to sit further behind the acrylic plate. This makes the acrylic diffuse the light from the NeoPixels much more evenly. Without the additional back frame the effect is not as bright or illuminated.

Installing Base

The base enclosure is secured to both the front and back frame using M3 screws and hex nuts. This makes the build sturdy and keeps the two frames together.

Secure Base to Frame

Place the base enclosure under the two frames and line up the mounting holes. Insert and fasten 2x M3 x 6mm long machine screws two the mounting holes.

Secure Back Frame

Use 2x  M3 x 10mm long screws and hex nuts to secure the base enclosure to the back frame. Note, the hole in the base enclosure is for passing the JST battery cable through.

Install Switch Cable

The On/Off switch is disconnected from the HalloWing M4 and passed through the hole in the bottom of the base. Fit the JST connector through and reconnect it to the HalloWing M4. The On/Off switch will be accessible through the opening on the base's bottom cover.

Connect Battery to Switch

Plug in the JST cable from the battery to the JST connector on the other end of the On/Off switch.

Circuit Test

Use the On/Off switch to test the circuit before closing everything up. Take a moment to adjust the cables to better fit them inside the framing of the tombstone.

Install Back Cover

The back cover snaps fits over the back frame. Make sure to fit all of the wiring into the framing before closing the back cover.

Snap Fit Back Cover

Double check the wiring is inside the tombstone and not being kinked. Check all of the edges to make sure the cover is fully secured and in place.

Fitting Battery in Base

The battery and cable from the On/Off switch are neatly fitted and adjusted inside the base. Double-sided tape is used to secure the On/Off button. Mounting tack can be used to keep the battery in place.

Install Base Cover

The bottom cover is press fitted into the base. It features snap fit edges that grab onto the nubs built into the base. The openings in the cover allow access to the On/Off button.

Final Build

And there we have it! A light up tombstone with an animated eye. Spooky yet elegant ey? I hope you enjoy your HalloWing M4 and make more projects with it!

This guide was first published on Oct 19, 2020. It was last updated on Jun 10, 2024.