Skip to the content
PCBKitNew board
2 layers200 × 20 mmWALL E Button Board, the printed circuit board in 3D

WALL E Button Board

Acliad/WALL-E-Software

Software and some hardware files for a custom WALL-E robot.

Size
200 × 20 mm
Copper layers
2
Thickness
1.6 mm
Parts
10
Nets
5
Pads
37
Tracks, vias
19, 0
Pours
1
Routed
Yes
KiCad
KiCad 7 (file 20221018)
Created
7 Aug 2024
Updated
7 Aug 2024

Overview

WALL E Button Board is an open-source printed circuit board by Acliad, from the Acliad/WALL-E-Software repository on GitHub. It is a 2-layer board of 200 × 20 mm with 10 parts on 5 nets, routed with 19 tracks and 0 vias.

Its parts include 4 switches and 1 connector.

README

readme.md

Overview

This repo contains code, PCB files, and some 3D files for a WALL-E robot. The robot is controlled by an ESP32 microcontroller with PlayStation Navigation controllers. 3D files can be found under the Mechanical folder. The PCB files can be found under the PCB Files. The code can be found under the src folder.

This readme file contains information on setting up and using WALL-E, and there are several videos in the Docs folder that give examples.

The code is written as an Arduino sketch, but has many C++ files and classes. The custom library code is located in the src folder of the walle sketch and is organized into the following folders:

  • audio: Contains the code for the audio player.
  • display: Contains the code for the display and animations.
  • motion: Contains the code for the motion animations.
  • button: Contains the code for the button handling.
  • controller: Contains the code for the controller handling.
  • stats: Contains a simple stats class mostly used for debugging.

Additionally, the root of the src folder contains the main sketch file, walle.ino, which is the entry point for the program. It also contains several files to help configure WALL-E:

  • config.hpp: Contains the configuration for the audio player, display, and controller.
  • display_animations.hpp and display_animations.cpp: Contains code for programatically defining display animations.
  • motion_animations.hpp and motion_animations.cpp: Contains code for programatically defining motion animations.

Button Mapping

This image can be found in Docs/Images.

Setting up Arduino IDE

This project uses a special board package for the ESP32 called Bluepad32. To install it, you need to add this board to your Arduino IDE. The abreviated steps to do this are below. See this doc page for more detailed instructions.

  1. Open the Arduino IDE settings and add the following two URLs to the "Additional Boards Manager URLs" field: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json https://raw.githubusercontent.com/ricardoquesada/esp32-arduino-lib-builder/master/bluepad32_files/package_esp32_bluepad32_index.json
  2. Install the ESP32 and ESP32 Bluepad32 boards from the Boards Manager.
  3. Select the ESP32-WROOM-DA Module from the Tools > Board > esp32_bluepad32 menu.

You will also need to install the following libraries:

  • Adafruit PWM Servo Driver Library
  • DFPlayer Mini Mp3 by Makuna
  • Ramp
  • ServoESP32
  • TFT_eSPI

You will need to setup the TFT_eSPI library with the correct config. To do this, create a TFT_eSPI_Setups folder in your Arduino libraries folder (usualy in ~/Documents/Arduino/libraries/), then copy the TFT_eSPI_walle_setup.h file in src/display/ to this new folder. After that, open User_Setup_Select.h in the /TFT_eSPI/ library folder and comment out the current user config (User_Setup.h by default), then add the following line:

cpp
 #include <../TFT_eSPI_Setups/TFT_eSPI_walle_setup.h>

After this, you should be able to compile and upload the code to the ESP32. Make sure WALL-E is powered on before plugging in the USB cable to the ESP32, otherwise the USB port will attempt to power the servo motors and will likely trip your USB port's overcurrent protection.

Note that the Arduino IDE will throw some warnings related to "converting a string constant to 'char*'" as well as some bluepad and eSPI_TFT warnings. These can be ignored.

Adding new sounds

New sounds can be added to the audio player's SD card as .mp3 files. Audio tracks must be labeled as numbers with the format 0001.mp3, 0002.mp3, etc. The number of the audio track is the index that will be used to play the sound. You can configure the audio player sounds and keybindings in the config.hpp file. Here is what the folder structure on the SD card should look like:

For instance, if you add a track 0011.mp3 and you wish to bind it to the L2 + Up button, you would add the following line to the config.hpp file:

cpp
const int audio_track_selection_list[] = {
    TRACK_INDEX_EVE_1, // Up
    TRACK_INDEX_TADA, // Right
    TRACK_INDEX_SCREAM, // Down
    TRACK_INDEX_WALLE_1, // Left
    11, // L2 + Up <<<<<<<<<<<<<<<<<<<<<<<< CHANGED TRACK 
    TRACK_INDEX_EVE_3, // L2 + Right
    TRACK_DEFINE_DANCING, // L2 + Down
    TRACK_LA_VIE_EN_ROSE, // L2 + Left
};

Sounds which are bound to a button can be added to keyframes in motion animations.

Similarly, you could add it to the audio_track_random_list.

cpp
// Tracks in this array will be selected randomly by the playRandomTrack() function
const int audio_track_random_list[] = {
    TRACK_INDEX_EVE_1,
    TRACK_INDEX_EVE_2,
    TRACK_INDEX_EVE_3,
    TRACK_INDEX_WALLE_1,
    TRACK_INDEX_SCREAM,
    TRACK_INDEX_TADA,
    11 // <<<<<<<<<<<<<<<<<<<<<<<< ADDED TRACK
};

Adding solar animations

The steps to add a solar animation are as follows:

  1. Declare your variable name in display_animations.hpp:
cpp
extern AnimateLeve animate_display_startup;
...
// Add your variable name here
extern AnimateLevel my_animation;
  1. Define your vairable in display_animations.cpp:
cpp
AnimateLevel animate_display_startup = AnimateLevel();
...
// Define your variable here
AnimateLevel my_animation = AnimateLevel();
  1. Create a setup_my_animation() function in display_animations.cpp:
cpp
void setup_my_animation() {
  my_animation.addKeyframe(0, 0);
  my_animation.addKeyframe(1000, 1);
  ...
}
  1. Add your setup_my_animation() function to the setup_animations() function in display_animations.cpp:
cpp
void setup_animations() {
  setup_startup();
  ...
  // Add your setup_my_animation() function here
  setup_my_animation();
}

Now your variable my_animation will be available to use in the main sketch.

Notes

  • A keyframe with a single change will perform that change at the beginning of the keyframe. For example, if 2 bars are on and you request 3 to be on with a duration of 1 second, the 3rd bar will turn on immediately and the keyframe will wait for 1 second to complete. If you have two or more changes in a keyframe, the changes will be evenly distributed throughout the duration of the keyframe, ending with a change. For example, if 2 bars are on and you request 5 to be on with a duration of 1 second, the 3rd bar will turn on immediately, the 4th bar will turn on after 0.5 seconds, and the 5th bar will turn on after 1 second.
  • The sun's status is always evaluated at the beginning of a keyframe.

Adding motion animations

The steps to add a motion animation are as follows:

  1. Declare your variable name in motion_animations.hpp:
cpp
namespace MotionAnimations {
    // Add custom animations here:
    extern ServoAnimation my_animation;

    // Rest of namespace ...
}
  1. Define your vairable in motion_animations.cpp:
cpp
namespace MotionAnimations {
    // Define new animations here

    ServoAnimation my_animation = ServoAnimation();

    // Rest of namespace ...
}
  1. Create a setup_my_animation() function in motion_animations.cpp. Keyframes are created one at a time and then added to the previously created animation. Create a keyframe with ServoKeyframe *my_keyframe = new ServoKeyframe(duration_ms);. Add the servo positions to the keyframe with my_keyframe->add_servo_scaler(servo_ptr, position);. Add the keyframe to the animation with my_animation.addKeyframe(my_keyframe);. Servos are addressed by their name. There is a #define for each servo. E.g, to get the left eye servo you would use servos.map[SERVO_EYE_LEFT_NAME] For example:
cpp
// Create setup functions for each animation.
// NOTE: Don't forget to call these functions in setup_animations().
void setup_my_animation() {
    // Rotate eyes in opposite directions
    ServoKeyframe *my_keyframe1 = new ServoKeyframe(1000);
    my_keyframe->add_servo_scaler(servos.map[SERVO_EYE_LEFT_NAME], 0.75);
    my_keyframe->add_servo_scaler(servos.map[SERVO_EYE_RIGHT_NAME], -0.75);
    
    // Pause for 3 seconds
    ServoKeyframe *my_keyframe2 = new ServoKeyframe(3000);

    // Return the eyes to their original position
    ServoKeyframe *my_keyframe3 = new ServoKeyframe(1000);
    my_keyframe->add_servo_scaler(servos.map[SERVO_EYE_LEFT_NAME], 0);
    my_keyframe->add_servo_scaler(servos.map[SERVO_EYE_RIGHT_NAME], 0);

    // Add the keyframes to the animation
    my_animation.add_keyframe(my_keyframe1);
    my_animation.add_keyframe(my_keyframe2);
    my_animation.add_keyframe(my_keyframe3);
}
  1. Add your setup_my_animation() function to the setup_animations() function in motion_animations.cpp:
cpp
void setup_animations(ServoContext servos) {
    // This function should get called in the main setup() function. It calls all animation setup functions for use in
    // the main sketch.

    // Add setup functions for new animations here
    setup_my_animation();

    // Rest of animation setups...
}
  1. Play the animation with servo_player.play(&MotionAnimations::my_animation);. Alternatively, you can add the animation to the head_animations array in the main sketch to bind it to a button press:
cpp
ServoAnimation         *head_animations[] = {
    &MotionAnimations::my_animation, // Up
    nullptr,      // Right
    nullptr,      // Down
    nullptr,      // Left
    nullptr,      // L2 + Up
    nullptr,      // L2 + Right
    nullptr,      // L2 + Down
    nullptr       // L2 + Left
};

Parts

10
QtyValueFootprintReferences
4M4MountingHole:MountingHole_4.3mm_M4_DIN965_PadH1, H2, H3, H4
1Conn_01x05Connector_PinHeader_2.54mm:PinHeader_1x05_P2.54mm_VerticalJ1
1IREX_LOGOirex_Aesthetic:Logo_irex_10.0x11.1mm_CopperG***
1PlayPCM_Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MXSW2
1RecordPCM_Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MXSW3
1SolarPCM_Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MXSW4
1StopPCM_Switch_Keyboard_Hotswap_Kailh:SW_Hotswap_Kailh_MXSW1

Questions

How big is the WALL E Button Board PCB?

It measures 200 × 20 mm and has 2 copper layers, 1.6 mm thick.

What parts does the WALL E Button Board use?

10 parts. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the WALL E Button Board KiCad files?

From the Acliad/WALL-E-Software repository on GitHub, at the commit this page was made from: the board is PCB Files/WALL-E Button Board/WALL-E Button Board.kicad_pcb and its schematic PCB Files/WALL-E Button Board/WALL-E Button Board.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the WALL E Button Board design in my own project?

Its repository states no licence, so its author keeps all rights: ask Acliad before reusing the design.

More from Acliad/WALL-E-Software

1
  • 2 layers151.9 × 78.7 mmWALL E Carrier Board, the printed circuit board in 3D

    WALL E Carrier Board

    Acliad/WALL-E-Software

    Software and some hardware files for a custom WALL-E robot.

    23 parts

Similar boards

  • 2 layers57 × 55.2 mmLogicAnalyzer, the printed circuit board in 3D

    LogicAnalyzer

    gusmanb/logicanalyzer

    24 channel, 100Msps logic analyzer hardware and software

    10 parts5.1kGPL-3.0
  • 2 layers32.2 × 15.4 mmProtector, the printed circuit board in 3D

    Protector

    byrantech/laptop

    anyon_e, a highly integrated, high end, open source laptop. Attempt the impossible.

    10 parts4.3kMIT
  • 2 layers26 × 18 mmConn, the printed circuit board in 3D

    Conn

    yaqwsx/KiKit

    Automation tools for KiCAD

    10 parts2.1kMIT
  • 2 layers44.3 × 30.5 mmLime2-SATA RevA, the printed circuit board in 3D

    Lime2-SATA RevA

    OLIMEX/OLINUXINO

    OLINUXINO is Open Source / Open Hardware, low cost from EUR 24 Linux Industrial grade Single Board Computer capable to operate -25+85C

    10 parts1.5k
  • 2 layers17.8 × 43.2 mmNano Adapter, the printed circuit board in 3D

    Nano Adapter

    VoronDesign/Voron-Hardware

    Cool Hardware designed by the Voron Design group

    10 parts1.1kGPL-3.0
  • 2 layers53.9 × 23.2 mmBuffer, the printed circuit board in 3D

    Buffer

    hoglet67/RGBtoHDMI

    Bare-metal Raspberry Pi project that provides pixel-perfect sampling of Retro Computer RGB/YUV video and conversion to HDMI

    10 parts1kGPL-3.0