Introduction: ITSY BITSY SPIDER (Arduino)

This is a simple Arduino project to make a spider walk up and down on a wall. In oder to define the upper and lower limit of the spider walk, it uses a sensor and a timer which is programmed during the setup step, when Arduino power is turned on. The motion is provided by a servo which turns a pulley with a rope connected to the spider. The servo holder is 3D printed and the pulley is from a sewing machine. Very simple, but effective. I used this at a party of my 3 year old children and they liked very much, the spider walks like in the song.

The spider is not very pretty, because is the one made by my son, of course you can showcase your abilities and make a good looking spider to make all this very scary, eventually could be a good tool for the next Halloween.

HOW IT WORKS

1) turn on by using the on/off switch
2) press the button to start the setting process for the lower limit of the movement

3) the spider first go up until it reach the upper limit, then it moves down

4) press again the button to inform that the spider reached the lower limit

5) all set. from now on the spider goes up and down forever by random time, but always keeping itself between the upper and lower limits initially set.

You can see better in the following video:

Step 1: What You Need

Beside an Arduino or something compatible, you need small amount of material, as showed in the picture.

  1. a continuos servo motor, I have in house the FS90 micro servo
  2. a battery adapter
  3. a pulley, I used one from a sewing machine, but you can 3D print your own
  4. some screws
  5. a switch sensor
  6. a push button
  7. a wooden base large enough to assemble all pieces
  8. optional, a protoboard to make tests

All 3d printed parts are printed in PLA filament with 10% infill and no support.

Step 2: Servo Holder

The Servo holder is a 3D print object, the STL file is available for download. It works with a FS90 micro servo, which is very common to find in shops.

Step 3: Servo Shaft

I used a pulley from a sewing machine and I 3D designed a shaft to attach it with 4 screws to one of the servo standard shafts. The final result should be something like in the photo.

Step 4: End of Rope Sensor

I used a micro-switch and I attached to it a 3d printed piece used to guide the rope.

Step 5: Coding

Basically the code is composed by two C++ classes which makes all the stuff, while Arduino standard setup and loop functions are minimal. Notice that all sensor are declared INPUT_PULLUP to avoid resistors and make the project simple. Recap then when using INPUT_PULLUP, the HIGH and LOW signals of the Arduino Pin are inverted.

Spider.ino

#include<Arduino.h>
#include<Servo.h>
#definePINSNSEOR4// PIN used for End of Run detection
#definePINSNSBUT6// PIN used by reset button
#definePINSERVO10// PIN used to command the servo
#defineSERVODROP80// clockwise rotation
#defineSERVOPULL100// counter-clockwise rotation
#defineSERVOSTOP90// stop servo
#defineSNSFIRED LOW
#defineSNSIDLE HIGH
classSpider {
private:
byte pinServo;
Servo myServo;
byte pinSensor;
public:
Spider(byte servoPin, byte sensorPin);
boolMoveUp(unsignedlong time = -1);
boolMoveDown(unsignedlong time);
boolWait(unsignedlong time);
};
classWeb {
private:
Spider* mySpider;
byte pinButton;
byte pinServo;
int moveCounter;
unsignedlong ropeTmLenght;
unsignedlong dropTime;
unsignedlong pullTime;
public:
Web(byte sensorPin,byte servoPin,byte suttonPin);
voidZeroSpider(void);
voidLoop(void);
};
voidWeb::ZeroSpider(void) {
mySpider->MoveUp();
dropTime = ropeTmLenght;
pullTime = 0;
}
Web::Web(byte sensorPin,byte servoPin,byte buttonPin) {
mySpider = newSpider(servoPin,sensorPin);
pinButton = buttonPin;
pinServo = servoPin;
ropeTmLenght = -1;
moveCounter = 0;
pinMode(sensorPin,INPUT_PULLUP);
pinMode(pinButton,INPUT_PULLUP);
pinMode(13,OUTPUT);
}
voidWeb::Loop(void) {
if(ropeTmLenght == (unsignedlong)-1) {
if(digitalRead(pinButton) == SNSFIRED) {
while(digitalRead(pinButton) == SNSFIRED) ;
digitalWrite(13,HIGH);
mySpider->MoveUp();
delay(2000);
unsignedlong tmpRope = millis();
unsignedlong tmp = 1;
Servo tsr;
tsr.attach(pinServo);
tsr.write(SERVODROP);
while(digitalRead(pinButton) == SNSIDLE) ;
tsr.write(SERVOSTOP);
tsr.detach();
while(digitalRead(pinButton) == SNSFIRED) ;
delay(2000);
ropeTmLenght = millis() - tmpRope;
dropTime = ropeTmLenght;
pullTime = 0;
digitalWrite(13,LOW);
mySpider->MoveUp();
}
}
else {
randomSeed(millis());
int rn = random(100);
int direction;
unsignedlongtime;
if(rn>=0 && rn < 34) { direction = SERVOSTOP; time = random(3000,ropeTmLenght); }
if(rn>=34 && rn < 66) { direction = SERVODROP; time = random(3000,dropTime); }
if(rn>=66 && rn <= 100) { direction = SERVOPULL; time = random(3000,pullTime); }
if(time>1000) {
if(direction==SERVODROP) { mySpider->MoveDown(time); mySpider->Wait(time); dropTime-= time; pullTime += time; }
if(direction==SERVOPULL) { mySpider->MoveUp(time); mySpider->Wait(time); dropTime += time; pullTime -= time; }
if(direction==SERVOSTOP) mySpider->Wait(time);
if(moveCounter++ >= 5) {
ZeroSpider();
moveCounter = 0;
}
}
}
}
Spider::Spider(byte servoPin, byte sensorPin) {
pinServo = servoPin;
pinSensor = sensorPin;
}
boolSpider::Wait(unsignedlong time) {
delay(time);
}
boolSpider::MoveUp(unsignedlong time) {
if(digitalRead(pinSensor) == SNSIDLE) {
unsignedlong tmp = millis();
myServo.attach(pinServo);
myServo.write(SERVOPULL);
while(true) {
if(time != -1 && tmp+time<millis()) break;
if(digitalRead(pinSensor) == SNSFIRED) break;
}
myServo.write(SERVOSTOP);
myServo.detach();
returntrue;
}
returnfalse;
}
boolSpider::MoveDown(unsignedlong time) {
unsignedlong tmp = millis();
myServo.attach(pinServo);
myServo.write(SERVODROP);
while(!(time != -1 && tmp+time<millis())) ;
myServo.write(SERVOSTOP);
myServo.detach();
returntrue;
}
// ======================================================================
Web *myWeb;
voidsetup() {
myWeb = newWeb(PINSNSEOR,PINSERVO,PINSNSBUT);
}
voidloop() {
myWeb->Loop();
}
view rawSpider.ino hosted with ❤ by GitHub