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 & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • 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
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • 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
Fun & Games
  • Challenges & Projects
  • Project14
  • Fun & Games
  • More
  • Cancel
Fun & Games
Projects The RC Rubber Duck with a Hammer
  • News
  • Projects
  • Forum
  • Leaderboard
  • More
  • Cancel
  • New
Join Fun & Games to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: robogary
  • Date Created: 26 Jan 2026 2:40 AM Date Created
  • Views 217 views
  • Likes 7 likes
  • Comments 3 comments
  • robogary
  • robotics
  • Fun & Games
  • arduino
Related
Recommended

The RC Rubber Duck with a Hammer

robogary
robogary
26 Jan 2026

PREAMBLE:  For STEM events in the community and schools, I build novel electronic projects, often robotic vehicles of some sort, to engage kids first to have fun playing with them, and along the way inspire their imagination for being creative, start building gadgets and contraptions of their own (secretly awakening the subconscious KNACK & aiming folks down the path of engineering) .  

This is one of those unusual projects, built for a robotics program at a for fun nerdy scifi/mystery convention. This convention focuses on fantasy discussion panels, fiction book authoring, film writing and production, and cosplay. The robotics program is a rich complement to the other convention programs as ours includes alot of hands on items. 

Our theme this year was Ducks with Hammers, as 10 years ago, our robotics club did a presentation with alot of amazing autonomous robots. For fun, the club founder had thrown together an RC robot in about 10 minutes with spare parts. The robot was radio controlled using two continuous servos and a meat tenderizer mounted on another servo, with a rubber duck glued on top. That robot was by far the favorite of every youngster who attended our program that year. We celebrated that discovery this year by using it as our theme.     

THE PROJECT: 

The RC Hammering Duck in the Tub is a radio controlled truck chassis using an Arduino Nano to translate the radio receiver's throttle PWM signal to a 100% duty PWM signal & direction bits to control the H bridge. 

The Arduino Nano also controls a DFPlayer Mini for the sound effects. 2 hidden pushbuttons can play "Rubber Duckie" or "Disco Duck."

When the Duck throttle is engaged, the duck quacks by looping a DFPLayer audio track.

When the hammer swings, a tilt switch wired back to the Nano will fire the HAMMER IMPACT audio file on the DFPlayer. 

The Hammer servo is controlled by a third channel on the RC transmitter/receiver.  

An IR receiver sits in the bullseye of a duck target. If an IR 38kHz burst is detected, the white LED ring under the duck shuts off, and a flashing red LED turns on. The DFplayer audio sounds an alarm and the H bridge is locked out for 10 seconds. 

The design includes a main fuse, a main power switch, and a motor power switch so the Duck can be turned on without any chance of the wheels turning. There will be several buck P.S. for 11V to 6V for servos and 11V to 5V for DFplayer. 

The  OPERATIONAL PROJECT VIDEOS: 

https://youtube.com/shorts/bxuNUurVbYg    this video was taken at the scifi convention with a youngster playing/controlling the the Duck with Hammer while Im explaining some features.  I didnt get a ton of video as we got busy with the crowds in attendance. This video is totally unedited as I have Codec issues between different video platforms.

https://youtu.be/wvT1RfBScMA      this short video was taken at the homeschoolers robotics class where I was the special guest speaker demonstrating and explaining the RC Duck with a Hammer as one type of robot project.   

RC Rubber Duck with a Hammer photos: 

image   

image

image

The Rubber Duck With Hammer wiring schematics: 

image

image

image

image

image

image

image

image

The  Arduino Code:

// ---------------------------------------------------------------------------
//RCDuckThrottleControl.ino  
// Rememeber to set the IDE Tools/Board = Arduino Nano, 
// and set the IDE Tools/Processor = ATMega328P(old bootloader)
//
// This code assumes the RC channels have no mixing, strictly reflecting the position of the joystick.
// if an airplane transmitter - The RC transmitter is selected for MODE 2 , right hand side joystick controls speed (RC receiver Channel 2) and direction (RC recevier channel 1).
// The approach allows the signals to be zeroed and also scaled, since the joystick output doesnt go full scale. 
// Use the Arduino serial monitor to get CH1_PWMtime and CH2_PWMtime center and endpoint value to normalize values.
// 
// *** MEASURED DATA ****from GR3E receiver and GT3B transmitter 
// channel 2 is used for speed reference
// CH2_PWMtime center = 1475 to 1480 usec pulsewidth with trigger at home position  and offset trim at max B30  
// CH2_PWMtime full fwd = 2041, usec pulsewidth  ideal should be 2000
// CH2_PWMtime full back = 980, usec pulsewidth  ideal should be 1000
// added an SW offset adjustment 
//
// This program and Nano interfaces the L298N H bridge to a FlySky FS=GT3B 
//---------------------------------------------------------------------------

int CH2_PWMoffset = 90; //offset counts to CH2 transmitter to zero throttle = 1500 ms 
int CH2_PWM_SpdRef_raw = 0; // declare SPD ref raw counts
int CH2_PWM_MAX_counts=200; // max PWM counts for throttle 255 is 100% 
int CH2_PWM_MAX_countsFWD=220; 
int CH2_PWM_MAX_countsREV=220; 

int THROTTLE_RUNNING=LOW;  //initialize
int THROTTLE_RUNNINGlastscan=LOW; //initialize
int DFPlayer_NOT_BUSYlastscan=HIGH; // initialize

int HammerUpTiltSwitch=HIGH; // initialize
int HammerUpTiltSwitchLastScan=HIGH; // initialize

int CannonFireCycle=HIGH;
int CannonCycleCounter=1;
int NoCannonFireLastScan=HIGH;
int NoCannonFire=HIGH; 

unsigned long CH2_PWMtime; //pulsewidth time of Channel 2 (into pin 4) RC in microseconds, 1000 = full REV (or -90 degress), 1500=zerospeed or 0 degrees, 2000=full FWD (or +90 degrees)
unsigned long timeout = 23000; //timeout of PWM , set timeout for reading a pulsewidth at 15% moree than max expected 20ms (tried 2300 and caused problems)

int CH2_PWMtime_int; // CH2_PWMtime is an unsigned long, convert it to integer

int LHSFWD=0; // LHS forward bit  driver side the H bridge uses a FWD and REV signal
int LHSREV=0; //LHS reverse bit driver side the H bridge uses a FWD and REV signal

int RHSFWD=0; // RHS forward bit  passenger side  the H bridge uses a FWD and REV signal
int RHSREV=0; //RHS reverse bit   passenger side the H bridge uses a FWD and REV signal

int LHS_PWM_REF_usec ; // magnitude of microseconds pulse width from 1500 usec centerpoint 
int RHS_PWM_REF_usec ; // magnitude of microseconds pulse width from 1500 usec centerpoint
int CH2_PWM_REF_usec ; // magnitude of microseconds pulse width from 1500 usec centerpoint
int CH1_PWM_REF_usec ; // magnitude of microseconds pulse width from 1500 usec centerpoint

int LHS_PWM_SpdRef ; // RHS speed reference scaled for 255 = 100% 
int RHS_PWM_SpdRef ; // RHS speed reference scaled for 255 = 100%
int CH2_PWM_SpdRef ; // RHS speed reference scaled for 255 = 100%
int CH1_PWM_SpdRef ; // RHS speed reference scaled for 255 = 100%

int LHS_Spd_Ratio=100; // RHS speed reference scaled for 100 = 100%
int RHS_Spd_Ratio=100; // RHS speed reference scaled for 100 = 100%

int Joystick_Right_Pos = 1500; // 
int Joystick_Left_Pos = 1500; //


int FWD=LOW; // direction of Channel 2 speed ref 
int REV=LOW; // direction of Channel 2 speed ref

int DFPlayer_NOT_BUSY = HIGH; 
int DFPlayerToldToRun=LOW;

void setup() {

pinMode(2, INPUT_PULLUP); // from VS1838 IR receiver 
pinMode(3, INPUT_PULLUP); // normally open tilt switch, goes LOW when hammer lowered to play hammer sound effect.
pinMode(4, INPUT); // RC receiver Channel 2 motor speed control input

pinMode(5, OUTPUT); // pilot relay to DFPlayer input ADKEY1 with 6.3k resistor. PU relay to PLAY audio track 3
pinMode(6, OUTPUT); // FET driver for red LED module
pinMode(7, OUTPUT); // pilot relay to DFPlayer input ADplay2. LOW picks up relay 
pinMode(8, OUTPUT); // FET driver for white ring LED

pinMode(9, OUTPUT); // PWM motor FWD to H Bridge IN3, output forced low in reverse 
pinMode(10, OUTPUT);  // PWM motor REV to H Bridge, IN4 output bit forced low in FWD
pinMode(11,OUTPUT); // DFPlayer ADKEY1 LOW SIGNAL PLAYS audio with a one shot
pinMode(12, INPUT); //DFPLAYER BUSY pin LOW is BUSY

digitalWrite(8,HIGH);   // boot up with Rubber Duck light ring on 

//Serial.begin(115200);
  
}

void loop() {
  
    
//   Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds. Gives up and returns 0 if no pulse starts within a specified time out.
// Works on pulses from 10 microseconds to 3 minutes in length.
  
   CH2_PWMtime = pulseIn(4, HIGH, timeout); // pulseIn(pin, value, timeout)  value is HIGH or LOW, timeout and value are long int 
//   Serial.print("CH2 Time: ");
//   Serial.println(CH2_PWMtime); 
 
     
//  The cast operator translates one variable type into another and forces calculations to be performed in the cast type.
// Syntax (type)variable   Parameters: type: any variable type (e.g. int, float, byte) 
     
     CH2_PWMtime_int = (int) CH2_PWMtime + CH2_PWMoffset; //convert unsigned long to int
 //      Serial.print("CH2 Time: ");
 ////     Serial.println(CH2_PWMtime_int); 
     
     /// create fwd and reverse direction bits    
     
  if ((CH2_PWMtime_int - 1500) >= 50 ){ FWD = HIGH; } else {(FWD=LOW);} // 10 allows some deadband switching bridges
  if ((CH2_PWMtime_int - 1500) <= -50 ){ REV = HIGH; } else {(REV=LOW);} // -10 allows some deadband switching bridges
  if (CH2_PWMtime_int==0) {FWD = LOW; REV =LOW;} // 0 is a missed scan , zero directions
  
//      Serial.print("FWD = ");
//    Serial.println(FWD); 
//     Serial.print("REV= ");
//    Serial.println(REV);    
     
 /// create a speed reference in microsends
 CH2_PWM_REF_usec = abs(CH2_PWMtime_int - 1500); // zero to 500usecs = 0 to 100 % speed 
 CH2_PWM_SpdRef_raw = (CH2_PWM_REF_usec/2); // cheap and dirty way to make speed reference, top = 500 microseconds, which corresponds to an analogWrite value 255. divie by 2 makes it just a tad slower.
//     Serial.print("255 is top speed reference, raw count before clamp");
//     Serial.println(CH2_PWM_SpdRef_raw);                   

///// logic for which speed ref clamp to use  
if (FWD==HIGH)
  { CH2_PWM_MAX_counts = CH2_PWM_MAX_countsFWD; }
if (REV==HIGH)
  { CH2_PWM_MAX_counts=CH2_PWM_MAX_countsREV; }   

if (CH2_PWM_SpdRef_raw > CH2_PWM_MAX_counts)
    { CH2_PWM_SpdRef = CH2_PWM_MAX_counts; }        
    else 
     { CH2_PWM_SpdRef = CH2_PWM_SpdRef_raw; }     
 //   Serial.print("CH2 max sped PWM reference after MAX clamp");
 //   Serial.println(CH2_PWM_SpdRef);                   
             
 // output logic for the H Bridge              
             
      if (FWD==HIGH) 
      {
      analogWrite(9, (CH2_PWM_SpdRef));  // analogWrite values from 0 to 255
      analogWrite(10, 0);
       } 
    else if (REV==HIGH) 
      {
      analogWrite(9, 0) ;  // analogWrite values from 0 to 255
      analogWrite(10,(CH2_PWM_SpdRef));
       } 
      else 
      {
      analogWrite(9, 0);  // analogWrite values from 0 to 255
      analogWrite(10, 0) ;
       } 

/////// END OF THROTTLE SPEED REF PWM CODE
 
// START OF DFPLAYER CODE --- play audio tracks using inputs ADPLAY1 and ADPLAY5 
//DFPlayer play trigger has to be a one shot. BUSY signal takes too long responding to use as a one shot

// AUDIO TRACK SITUATION 1:  if throttle is pressed either direction, start playing Audio track 1 the first time
if ((FWD==HIGH) || (REV==HIGH)) // see if throttle is pressed either direction
    { THROTTLE_RUNNING=HIGH; }
    else 
    { THROTTLE_RUNNING=LOW; } 

if ((THROTTLE_RUNNING==HIGH) && (THROTTLE_RUNNINGlastscan==LOW))
    { digitalWrite(11,LOW) ; /// LOW causes realy to pick up and clsoe the N.O. contact
    delay (60); 
    digitalWrite(11,HIGH);}
    else 
    { digitalWrite(11,HIGH); } 
    
THROTTLE_RUNNINGlastscan=THROTTLE_RUNNING;

//
// AUDIO TRACK SITUATION 2:  if throttle is running, and 1st track has played, when DFPLAYER BUSY signal picks back up, play it again
// 

DFPlayer_NOT_BUSY=digitalRead(12); // BUSY == LOW when playing

if ((THROTTLE_RUNNING==HIGH)&&(DFPlayer_NOT_BUSY==HIGH)&&(DFPlayer_NOT_BUSYlastscan==LOW)) // means the DFPlayer just finished a track  
        { digitalWrite(11,LOW) ; /// LOW causes realy to pick up and clsoe the N.O. contact
    delay (60); 
    digitalWrite(11,HIGH);}
    else 
    { digitalWrite(11,HIGH); } 
    
DFPlayer_NOT_BUSYlastscan=DFPlayer_NOT_BUSY;

//////////// code to play hammer clang audio track when tilt switch closes and TILT SWITCH input goes LOW /////

  HammerUpTiltSwitch=digitalRead(3); /// hammer Tilt switch LOW = Hammer Down , HIGH=Hammer UP position
  
  if ((HammerUpTiltSwitch==LOW)&& (HammerUpTiltSwitchLastScan==HIGH))    // edge detect HammerUpTiltSwitch going down
      { digitalWrite(7,LOW) ; /// LOW causes realy to pick up and close the N.O. contact
      delay (60);   
      digitalWrite(7,HIGH);}
      else 
      { digitalWrite(7,HIGH); } 
  
  HammerUpTiltSwitchLastScan=HammerUpTiltSwitch; 

//// END Hammer Audio Play relay //////////////
    
/////  receiver DISABLE DUCK routine seeing a BurstPulse via the VS1838.         
// turn off white LED ring , turn on RED LED module, STOP H Bridge ///


NoCannonFire=digitalRead(2); // VS1838 sensor == HIGH if no 38kHz pulses seen, LOW when a pulse train is seen
//  Serial.print("VS1838 input is high except when a pulse burst is seen");
//  Serial.println(NoCannonFire);

if ((NoCannonFire==LOW)&&(NoCannonFireLastScan==HIGH)) // edge detect falling edge input from high to low to change state 
{
    digitalWrite(5,HIGH);  // 1st toggle pilot relay to play sound effect 0003.mp3 
    delay(80);
    digitalWrite(5,LOW); 
        // disable H bridge - turn on ALERT LED 
    digitalWrite(8,LOW); //turn off white LED ring
    digitalWrite(6,HIGH); // turn on red LED flasher
    digitalWrite(9,LOW); //forced H Bridge to zero in FWD
    digitalWrite(10,LOW); //forced H Bridge to zero in REV

    delay(10000);  // 10 seconds disable H bridge 
    // return to normal operating conditions
    digitalWrite(8,HIGH); //turn on white LED ring
    digitalWrite(6,LOW); // turn off red LED flasher
  }

NoCannonFireLastScan=NoCannonFire;    
 

}  /// END of LOOP

The Challenges and improvements: 

Scope creep and spec changes haunted the RC Hammering Duck.

• Murphy's Law - plenty of spare IOs to start out => digital IO is used up.
• No matter how many power distribution points are provided for power supplies and grounds to eliminate daisy chains, there arent enough. Add more, not enough again. Put some daisy chains in the wire harnesses, still run out. arrgghh
• In spite of strategically placed blocking diodes, when I downloaded new code with main battery power on, opps, the electrons found a sneak path thru the IO and buck power supplies and the Arduino Nano let out a nice cloud of smoke. Luckily only the Arduino suffered as a sacrifice to the project gods.

The Rubber Duck is too heavy. The poor little 7V motor is running at 3A to rotate at 11.3V.  The 11.1V Lipo battery doesnt last long as its full charge volts are about 12.4 , and quickly drops to the nominal. The batteries have alot of their power left when the voltage hits motor stall.   It will go on a diet before next year's event. 

The RC Rubber Duck with Hammer had a shark chase vehicle. I'll publish that as a second project in this competition.  

  • Sign in to reply
  • robogary
    robogary 2 days ago in reply to veluv01

    No need to upgrade the wheels, it has an old RC truck chassis which I replaced the DC steering motor with a hi torque servo. I need a bigger drive motor on the rear or reduce the weight. I may end up replacing the entire chassis with a metal tank chassis.   

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • veluv01
    veluv01 2 days ago

    Unique and fun robot. Any plans to add a mechanum-wheels and upgrade to a more durable bath tub? I love the model! it's great to see it in action.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • robogary
    robogary 2 days ago

    Finally got it done and shown to the world, only to put it on the 2026 project list for updates.  :-)   

    • 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 © 2026 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