Introduction: Arduino King Cobra Game

When is the last time that an electronic device impaled you?
For me, it had been far too long.

Enter... The Arduino King Cobra! (TM, R, Copyright, Patent Pending... not really).
I had some new parts and wanted to build something during my lunch hour recently. This is what I came up with.
I call these sessions "One Hour Hackathons". Only, it's just me, and I rarely time them, and yes, they are lonely.

Enjoy! You will find no schematics here, as I'm an artist. But you WILL find poorly shot and annotated photos! Yahoo!



DISCLAIMER: I recommend building this without the thumb-tack fangs, kids. Blood born illness is no laughing matter, and neither is a lawsuit. I hammered the end of my tack so that it was dull (spoiler, I know). Some have suggested great ideas such as a red marker nib, a sponge dipped in paint and electro-shock wires. Arguably all better than the thumb-tack. Be safe!

Step 1: The Search for Serpent Parts

A list of bits and pieces required to make your wildest dreams come true:

1. One Arduino Whatever (any model should work). I used a Micro
2. One analog servo motor. Mine is a Tower Pro SG90 with 180 degree sweep
3. One PING ultrasonic distance sensor
4. One battery holder with batteries. Mine is 6V total, but Arduino recommends 7-12 volts for stability
5. A bread board or PCB for wiring
6. Wiring
7. One small zip-tie
8. One snake head
9. Some tape

Step 2: Snake Brains

My snake runs on an Arduino Micro. You can use any Arduino though, just adjust your pins accordingly.
The way it works is the following:

1. Ping ultrasonic sensor reads the distance of your hands or objects in front of it 50 times per second
2. If close enough, the servo motor is rotated down towards your hand.

As the code works now, the "Cobra head" does not sit and wait for your hand to get too close, but instead it moves based on your distance. So the closer you get, the lower it drops to get you.

Step 3: Snake Eyes

The "eyes" are actually an ultrasonic distance sensor. These are available in Radio Shack and online.
They work by sending a high pitched "ping" out and then measuring how long it takes to hear it bounce back. Since the speed of sound is known, it can determine within a cm or so how far away the object is that it hit. Cool!

It has 3 pins:
A ground pin (GND)
A 5 volts in pin (5V)
A signal pin (SIG)

The first two power it. The signal pin is responsible for sending out the ping and then listening for it to return.

Step 4: Snake Muscle

This is a typical hobby mini servo motor. They are great to use when you have to rotate a motor to an exact position.
They are pretty fast and have a good amount of torque, but be careful not to yank on them or the gears can strip over time.

They have three wires:
brown/black: ground -
red/orange: positive voltage +
yellow: signal (typically sends a value between 0-180 degrees)

Step 5: The Cobra Code (not Python) HAH!

Here is the Arduino code that I'm running. It's a modification of their Ping ultrasonic sensor sample.
Adjusting the variable "numReadings" to a higher value will result in less noisy readings, but also a larger lag in reaction time.
Enjoy!

//Copy from here...

#include <Servo.h>
Servo myservo;                             // create servo object to control a servo
int val;                                             // range-mapped value for servo control

const int pingPin = 7;                   // Parallax ping sensor's signal pin
const int numReadings = 5;       // set higher to smooth more, also causes more latency
int readings[numReadings];      // the readings from the analog input
int index = 0;                                 // the index of the current reading
int total = 0;                                   // the running total
int average = 0;                            // the average
int lastValue = 0;

void setup() {
  // initialize serial communication:
  Serial.begin(9600);

  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

  //clear the smoothing value buffer
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;
}

void loop()
{
  // establish variables for duration of the ping,
  // and the distance result in inches and centimeters:
  long duration, inches, cm;
  int fadeValue = 0;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  //smoothing code starts here
  // subtract the last reading:
  total= total - readings[index];        
  // read from the sensor: 
  readings[index] = cm;//analogRead(inputPin);
  // add the reading to the total:
  total= total + readings[index];      
  // advance to the next position in the array: 
  index = index + 1;                   

  // if we're at the end of the array...
  if (index >= numReadings)             
    // ...wrap around to the beginning:
    index = 0;                          

  // calculate the average:
  average = total / numReadings;
  //smoothing code ends here 

  //remap value range and move the servo
  val = average;
  val = map(val, 10, 40, 0, 179);     // scale value to use it with the Tower Pro half turn analog servo (value between 0 and 180)
  if(average < 25)
      {myservo.write(val);}     // sets the servo position according to the scaled value if within a certain distance
  delay(10);  //let the servo cool down, or something
}

long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}

//To here...

Arduino Contest

Participated in the
Arduino Contest

Toy Contest

Participated in the
Toy Contest