element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Build a Present
  • Challenges & Projects
  • Project14
  • Build a Present
  • More
  • Cancel
Build a Present
Blog Robot Santa: Merry Xmas
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: fmilburn
  • Date Created: 17 Dec 2021 3:05 AM Date Created
  • Views 41164 views
  • Likes 16 likes
  • Comments 14 comments
  • Arduino 33 IOT
  • jq6500
  • led
  • neopixel
  • ws2812
  • buildapresentch
  • arduino
  • Robot Santa
  • 3d print
Related
Recommended

Robot Santa: Merry Xmas

fmilburn
fmilburn
17 Dec 2021

Good news everybody.  With the help of Professor Farnsworth, I have rehabilitated Robot Santa and brought him back from the future to help us in 2021.  His anger limiting module has been updated and his naughty/nice detector recalibrated into a more normal range.

Robot Santa

Background:

Robot Santa is a 4-ton robot that was built by Friendly Robot Company in the year 2801.  His purpose is to judge whether people are naughty or nice and to deliver presents accordingly.  I suspect this was a labor-saving endeavor.  Rather than living at the North Pole, he is based on Neptune and flies to Earth on a sled pulled by rocket-powered reindeer.  Unfortunately, due to a programming error, his standards are so high that essentially everyone is judged naughty.  Worse, he carries out murder and mayhem on anyone he sees on the streets on "Xmas" eve while flying around the Earth.  

Professor Farnsworth

Credit: Professor Hubert J. Farnsworth as drawn by Matt Groening in the television series Futurama

Thus the reasoning behind the reprogramming effort that Professor Farnsworth and I undertook.

Mechanical Fabrication:

Robot Santa was designed in Fusion 360 by me and fabricated using PLA in a 3D printer.  An exploded-view is shown below.

Exploded View

Starting upper-right, the hat consists of a ring, the hat itself, and the mace-like ball that was glued together with epoxy.  The two ears were glued to the head with hot glue.  This was a mistake as it cooled quickly and didn't allow easy adjustment such that they are slightly out of alignment.  The nose, teeth, and eyes were also attached with hot glue.  The beard was glued to the head with epoxy.  The base features a light diffusing screen behind the teeth and attachment locations for the speaker, microcontroller, and LEDs.  The base attaches and detaches easily to the head using a bayonet-style assembly.

Electronics - Arduino Inside

An Arduino Nano 33 IOT provides Artificial Intelligence suitable for an advanced robot of this type with communication over WiFi.  Additional capabilities are provided by the following:

  • 1 x Speech Unit: JQ6500
  • 1 x Speaker: 4cm OD, 8-ohm, 2W
  • 6 x WS2812 "Neopixel" LEDs on custom PCBs
  • 1 x USB external power

The schematic is given below.

Schematic

Assembly:

The electronic assembly was tested first on a breadboard as I was not familiar with the Nano 33 IOT.

Breadboard Testing

A prototyping board was then soldered with headers for the microcontroller and JQ6500 sound board.  DuPont-style pins crimped to the wires so that they could be easily reassembled inside the robot.

Wiring Assembly

The speaker, LEDs, and microcontroller assembly were then ready for placement.

Ready for Final Assembly

This is by far the tidiest assembly of the animatronic robots I have made.

Code:

The code is similar to my previous animatronic robots.  Rather than listing all commands in the user interface, the associated number for a command is sent over WiFi using the following interface.

User Interface

I am not particularly proud of the code and didn't make any attempt to perfect it.  Further, I am going to assume you don't want me to lead you through poorly written code. But it appears to work and is posted below for those who care to peruse it.

/* Robot Santa V0_4
 * developed on Arduino Nano 33 IOT
 *    
 * Controls Robot Santa using a simple webserver
 * Lights eyes and mouth with six WS2812 LEDs
 * Speech using JQ6500 and JQ6500_Serial library
 * 
 * by fmilburn December 2021
 * 
 * This code is in the public domain
 */
 
#include <Arduino.h>
#include <JQ6500_Serial.h>
#include "Secrets.h"
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include <Adafruit_NeoPixel.h>
#include "SpeechData.h"

// WiFi
char ssid[] = SECRET_SSID;        // network SSID (name)
char pass[] = SECRET_PASS;        // network password
int status = WL_IDLE_STATUS;
WiFiServer server(80);            // server socket
WiFiClient client = server.available();
String inputString;               // web server input

// Pixels
const int PIXELPIN  =  6;
const int NUMPIXELS =  6;

// Miscellaneous
const int DEBUG = false;
int commandNumber;               // Command (speech track) to play

// Instantiation
JQ6500_Serial mp3(Serial1);
Adafruit_NeoPixel pixels(NUMPIXELS, PIXELPIN, NEO_GRB + NEO_KHZ800);

// ------------------------------------------------------------------------
// setup
// ------------------------------------------------------------------------
void setup() {

  if (DEBUG == true){
    Serial.begin(115200);
    while(!Serial){
      // wait for serial
    }
  }

  // JQ6500 speech
  Serial1.begin(9600);
  mp3.reset();
  mp3.setVolume(VOLUME);
  mp3.setLoopMode(MP3_LOOP_NONE);

  // WiFi
  startWiFi();

  // WS2812 / neopixels
  pixels.begin();                            
  pixels.clear();
  flashEyes(track[0]);
}

// ------------------------------------------------------------------------
// loop
// ------------------------------------------------------------------------
void loop() {

  if (WiFi.status() != WL_CONNECTED) {
    startWiFi();
  }
  client = server.available();
  if (client){
    doWebPage();
    if (DEBUG == true){
      Serial.print("Inside loop, Track: ");
      Serial.println(commandNumber);
      Serial.print("Track Length: ");
      Serial.println(track[commandNumber]);
    }
  }

  if ((commandNumber >= 0) && (commandNumber < TRACKS)) {
    // if currently speaking, let it complete
    if (mp3.getStatus() != MP3_STATUS_PLAYING) {
      speak(commandNumber);
      commandNumber = -1;
    }
  }
}

// ------------------------------------------------------------------------
// showPixels
// ------------------------------------------------------------------------
void showPixels(int redEye, int greenEye, int blueEye,
                int redMouth, int greenMouth, int blueMouth){
                  
  pixels.setPixelColor(0, pixels.Color(redMouth, greenMouth, blueMouth));
  pixels.setPixelColor(1, pixels.Color(redMouth, greenMouth, blueMouth));
  pixels.setPixelColor(2, pixels.Color(redMouth, greenMouth, blueMouth));
  pixels.setPixelColor(3, pixels.Color(redMouth, greenMouth, blueMouth));
  pixels.setPixelColor(4, pixels.Color(redEye, greenEye, blueEye));
  pixels.setPixelColor(5, pixels.Color(redEye, greenEye, blueEye));
  pixels.show(); 
}

// ------------------------------------------------------------------------
// flashEyes
// ------------------------------------------------------------------------
void flashEyes(unsigned long flashLength){
  
  unsigned long stopFlash = millis() + flashLength;
  while (millis() < stopFlash){
    showPixels(255, 0, 0, 100, 50, 0);      // bright red eyes, dim yellow mouth
    delay(200);
    showPixels(90, 0, 0, 100, 50, 0);      // dim red eyes, dim yellow mouth
    delay(200);
  }
}

// ------------------------------------------------------------------------
// speak
// speach from JQ6500 and neopixel output to eyes and mouth
// ------------------------------------------------------------------------
void speak(int speechTrack){

  if (speechTrack > 0 & speechTrack < TRACKS){
    mp3.playFileByIndexNumber(speechTrack);
  
    unsigned long stopSpeech = millis() + track[speechTrack];
    if (anger[speechTrack] == false){
      while (millis() < stopSpeech){
        showPixels(90, 0, 0, 255, 50, 0);      // dim red eyes, bright orange mouth
        delay(200);
        showPixels(90, 0, 0, 100, 50, 0);      // dim red eyes, dim yellow mouth
        delay(200);
      }
    }
    if (anger[speechTrack] == true){
      while (millis() < stopSpeech){
        showPixels(255, 0, 0, 255, 50, 0);      // bright red eyes, bright orange mouth
        delay(200);
        showPixels(90, 0, 0, 100, 50, 0);      // dim red eyes, dim yellow mouth
        delay(200);
      }
    }
  }

  if (speechTrack == 0){
    flashEyes(track[0]);
  }
}

// -----------------------------------------------------------------
// startWiFi
// -----------------------------------------------------------------
void startWiFi(){

  if (DEBUG == true){
    Serial.print("\nConnecting to: ");
    Serial.println(ssid);
  }

  while ( WiFi.status() != WL_CONNECTED) {
    WiFi.begin(SECRET_SSID, SECRET_PASS);
  }

  if (DEBUG == true){
    Serial.println("\nWiFi connected");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }

  server.begin();
}

// -----------------------------------------------------------------
// doWebPage
// Updates the commandNumber using a simple web server
// -----------------------------------------------------------------
void doWebPage() {

  WiFiClient client = server.available();
  if (client) {
    
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char the HTTP request
        if (inputString.length() < 100) {
          //store characters to string 
          inputString += c; 
        } 

        //if HTTP request has ended
        if (c == '\n') {

          if (DEBUG == true) {
            Serial.print("Inside doWebPage: ");
            Serial.println(inputString);
          }

          // response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println();

          // web page
          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Robot Santa</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<H1>Robot Santa Entry Commands</H1>");
          // FIX THIS!   FIX THIS!       FIX THIS!       FIX THIS!
          client.println("<FORM ACTION=\"http://10.0.0.202\" method=get >");

          client.println("Enter Command Number (0 to 59): <INPUT TYPE=TEXT NAME=\"COMMAND\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\">");
          client.println("<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"SUBMIT\">");
          client.println("</FORM>");
          client.println("");
          client.println("</BODY>");
          client.println("</HTML>");

          // find start of the integer command
          int i;
          for (i = 0; i < inputString.length(); i++) {
            if (isdigit(inputString[i]) == true){
              break;
            }
          }

          // remove preceeding characters to integer command
          inputString = inputString.substring(i);

          // convert string to integer
          commandNumber = inputString.toInt();

          delay(1);
          //stop client
          client.stop();

          //clear string for next read
          inputString="";

        }
      }
    }
  }
}

In all, there are 60 commands for the robot.  The speech unit uses my voice lowered in frequency with Audacity software and stored on the JQ6500.  Additional personality is given to the robot by flashing the LEDs in his eyes and inside his mouth.  This turned out very good in my opinion - the effect is very much like that in the Futurama series.

Why, Oh Why, Did You Do This:

It needed to be done.  Children everywhere are unable to visit Santa Claus (Father Christmas, Kris Kringle, Père Noël, Weihnachtsmann, Babbo Natale, and so on) this season due to pandemic restrictions.  With my creation, a mall Santa Claus can set up a one-way camera so that they can see and hear the child while controlling Robot Santa from the comfort of their own home.  Thus protecting both Santa's helper and the child.

Before going commercial I tried it out in the lab on my other robots as shown in the short 2-minute video below.

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Looks like a bit more adjustment is needed on the anger limiting module before using it with children.

Conclusion:

I am pleased with how it came out. 

The design was drawn by eye and if making it again I would make the base wider.  The proportions in the cartoon series change depending on the scene and angle and the intent of the artist so proportions are somewhat subjective.  Tabs on the ears for alignment to the head would be a good idea.  Other than that there is not a whole lot I would change.

For those who prefer more traditional gifts, I created "Flower Pot for a Cat Lover" here.

Thanks for reading.  Your thoughts and comments are always welcome.

Related Links

make robot friend.  Bender

The Tin Man - Conclusion

Flower Pot for a Cat Lover

  • Sign in to reply

Top Comments

  • genebren
    genebren over 3 years ago +1
    The animated robot collection continues to grow! I am really enjoying following along on your robot builds.
  • Andrew J
    Andrew J over 3 years ago +1
    Futurama was one of those comedy programmes that had me in stitches pretty much every episode. I still laugh at the thought of Bender's pet robot dog: "I will now commence a 2-hour yipping session. Yip…
  • fmilburn
    fmilburn over 3 years ago in reply to genebren +1
    One of the things they did in Futurama that I thought was funny was to have celebrities and politicians come back as heads in jars. Maybe I should put the robots on display in bell jars.
  • feiticeir0
    feiticeir0 over 3 years ago

    ooohhh, I may be 41 years old, but loved Futurama since the very beginning. Still have all the episodes and watch them once in a while. It has been a roller coaster for the series until they canceled it.

    I'm definitely going to build Robot Santa !

    Thank you  !

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fmilburn
    fmilburn over 3 years ago in reply to DAB

    Thanks!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB over 3 years ago

    Great project.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fmilburn
    fmilburn over 3 years ago in reply to genebren

    One of the things they did in Futurama that I thought was funny was to have celebrities and politicians come back as heads in jars.  Maybe I should put the robots on display in bell jars.

    image

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fmilburn
    fmilburn over 3 years ago in reply to robogary

    Yes, there must some sort of commercial opportunity here somewhere Grinning

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube