This is my first experiment with the MakerBot. I am totally thrilled with this machine!!!
(photo by Tiago Serra)
SSS (servo suspension system) is designed to support standard servo motors and act as a basic suspension. It is still a work in progress and has not been tested yet.
Will update results as soon as possible (still waiting to have my lab back).
I’ve been working on this for a while and finally I have the courage to post the results.
I’m also testing the pololu micro serial servo controller in the hope I could achieve better results. One good thing the pololu controller has, is the ability to set the speed of the movement, I guess it is a good plus to have this extra control. And using this feature together with the filter you get really cool and smooth movements, check the end of the video.
The point I don’t like in this experience is that the robot shakes a lot, but that is due to the weak support. I will have to arrange a solution to void so much shakiness.
The low pass filter below is what makes the desaceleration while the value reaches the destination point. I’ve posted the full code below the video.
filter: 0.05; // 1 = no filter // has to be between 0.01 and 1
destinationValue = 1000;
destinationValueFiltered = destinationValueFiltered * (1.0-filter) + destinationValue * filter;
Code to move one servo directly connected to the Arduino:
// easing servo movements with low pass filter// the servo signal must be connected directly to the arduino pin 2 // Time interval, this executes one piece of code from time to time// Download Metro lybrary and instructions:// http://www.arduino.cc/playground/Code/Metro
#include <Metro.h>
int duration = 3500; // duration of the interval in milisecondsMetro intervaller = Metro (duration);
// MegaServo library// download and instructions: // http://www.arduino.cc/playground/Code/MegaServo
#include
MegaServo servos;
// servos minimum and maximum position
#define MIN_POS 800 // the minuimum pulse width for your servos
#define MAX_POS 2200 // maximum pulse width for your servos// servo pin
#define s0_pin 2
// variables to hold new destination positionsint d0; // destination0int d0_sh; // destination0 to be smoothed// the filter to be aplied// this value will be multiplied by "d0" and added to "d0_sh"float filtro = 0.05; // 0.01 to 1.0// setup runs once, when the sketch startsvoidsetup() {
// initialize serial comunicationSerial.begin(9600);
// set servo pin
servos.attach(s0_pin);
}
// main program loop, executes forever after setup()voidloop() {
// check the time interval, if it reaches limit "duration" goes back to one // and runs the codeif (intervaller.check() == 1) {
// calculate a new random position between max and min values
d0 = random(MIN_POS, MAX_POS);
// resets interval with a new random duration
intervaller.interval(random(500,2000));
}
// smooth the destination value
d0_sh = d0_sh * (1.0-filtro) + d0 * filtro;
// assign new position to the servo
servos.write(d0_sh);
// delay to make the servo movedelay(25);
}
And this is the code to use with the pololu micro serial servo controller:
// easing servo movements with a low pass filter and Pololu Micro Serial Servo Controller// Time interval, this executes one piece of code from time to time// Download Metro lybrary and instructions:// http://www.arduino.cc/playground/Code/Metro
#include <Metro.h>
int duration = 3500; // duration of the interval in milisecondsMetro intervaller = Metro (duration);
// servos minimum and maximum position
#define MIN_POS 500 // the minuimum pulse width for your servos
#define MAX_POS 5500 // maximum pulse width for your servos// variables to hold new destination positionsint d0; // destination0int d0_sh; // destination0 to be smoothed// the filter to be aplied// this value will be multiplied by "d0" and added to "d0_sh"float filtro = 0.05; // 0.01 to 1.0// set servo speed, goes from 1 to 127int servoSpeed = 120;
// setup runs once, when the sketch startsvoidsetup() {
// initialize serial comunicationSerial.begin(9600);
// set servo pin and speed
servoSetSpeed(0, servoSpeed);
}
// main program loop, executes forever after setup()voidloop() {
// check the time interval, if it reaches limit "duration" goes back to one // and runs the codeif (intervaller.check() == 1) {
// calculate a new random position between max and min values
d0 = random(MIN_POS, MAX_POS);
// resets interval with a new random duration
intervaller.interval(random(500,3000));
}
// smooth the destination value
d0_sh = d0_sh * (1.0-filtro) + d0 * filtro;
// assign new position to the servo
put(0,d0_sh);
// delay to make the servo movedelay(25);
}
// functions from this forum topic:// http://forum.pololu.com/viewtopic.php?f=16&t=745&start=60&st=0&sk=t&sd=avoid put(int servo, int angle)
{
//servo is the servo number (typically 0-7)//angle is the absolute position from 500 to 5500unsignedchar buff[6];
unsignedint temp;
unsignedchar pos_hi,pos_low;
//Convert the angle data into two 7-bit bytes
temp=angle&0x1f80;
pos_hi=temp>>7;
pos_low=angle & 0x7f;
//Construct a Pololu Protocol command sentence
buff[0]=0x80; //start byte
buff[1]=0x01; //device id
buff[2]=0x04; //command number
buff[3]=servo; //servo number
buff[4]=pos_hi; //data1
buff[5]=pos_low; //data2//Send the command to the servo controllerfor(int i=0;i<6;i++){
Serial.print(buff[i],BYTE);
}
}
void servoSetSpeed(int servo, intspeed){
//servo is the servo number (typically 0-7)//speed is servo speed (1=fastest, 127=slowest)//set speed to zero to turn off speed limitingunsignedchar buff[5];
unsignedchar speedcmd;
speedcmd=speed&0x7f;//take only lower 7 bits of speed
buff[0]=0x80;//start byte
buff[1]=0x01;//device id
buff[2]=0x01;//command number
buff[3]=servo;//servo number
buff[4]=speed;//data1for(int i=0;i<5;i++){
Serial.print(buff[i],BYTE);
}
}
This is Zezinho, a humanoid robot that likes to pose! :)
All the microservo supports where made with the amazing material Polymorph.
For now he is being controlled by 8 analog inputs, each input controls one microservo. In the future (as I hope) he will be controlled by a computer vision system where he will try copy real human poses in real time.
I’m still programming servo control functions and movements presets.
This is the analog inputs setup and a custom servo shield.
I’m using an Arduino Mega because I need more than 6 analog inputs that the regular Arduino boards have and I don’t have the time (or should I say patience) to digg around multiplexers.. I’m very lucky to have the support of InMotion.pt, they sent me the Arduino Mega for the first test drive. Thank you so much Filipe!! ;)
This robot will also be my final project for the course ‘O Som do Pensamento’. It will be an instalation where the user will be able to control his poses with physical controllers. I’ve made a controller box in acrylic and will post photos as soon as I have it with me.
Playing with movements and poses.
Testing movements and different servo speeds.
________________________________________________________________
Update (21.08.09)
Other posts related to Zezinho:
I don´t have any specific application in mind for this, the main purpose is to learn and test new concepts of mechatronic articulations, and to get used to polymoprh of what I became a big fan.
(sorry for the low light condition video, will make a better one)
Since I’ve started messing with robotics that I wanted to build a tank, and finally that moment arrived when two Tamiya thread kits and a Twin Motor Gearbox arrived.
After long research and trial and error, I´ve came up to a new walkthrough regarding this nice chip, the L293D.
Each project is one project and each one has its own unique power configurations, so you must be aware of the best battery choice and how to distribute voltage through your robot.
I strongly advice you to read the following articles:
L293D gives you the possibility to control two motors in both directions – datasheet
************************************************
The L293D Circuit:
Basic Implementation:
This is the most basic implementation of the chip.
As you can see, a 5V Voltage Regulator is between the battery and pins 1, 9, 16.
Pin 8 gets power before the VReg, if your motor needs for example 6V you should put 6V directly in this pin, all the other pins should not get more than 5V.
This will work with no problem at all, but if you want to do the right implementation take a look at the next example:
This is the correct Implementation (with the capacitors), and note that pin 8 is feeded by unregulated voltage. This means that if your motors need more than 5V, you should power this pin with that amount of voltage, and the rest of the circuit with 5V.
The capacitors stabilize the current.
The same circuit on a breadboard:
Soldered on a pcb and ready to go:
This is the back of the circuit, click for high resolution photo.
// Use this code to test your motor with the Arduino board:// if you need PWM, just use the PWM outputs on the Arduino// and instead of digitalWrite, you should use the analogWrite command// ————————————————————————— Motorsint motor_left[] = {2, 3};
int motor_right[] = {7, 8};
// ————————————————————————— Setupvoidsetup() {
Serial.begin(9600);
// Setup motorsint i;
for(i = 0; i < 2; i++){
pinMode(motor_left[i], OUTPUT);
pinMode(motor_right[i], OUTPUT);
}
}
// ————————————————————————— Loopvoidloop() {
drive_forward();
delay(1000);
motor_stop();
Serial.println(”1");
drive_backward();
delay(1000);
motor_stop();
Serial.println(”2");
turn_left();
delay(1000);
motor_stop();
Serial.println(”3");
turn_right();
delay(1000);
motor_stop();
Serial.println(”4");
motor_stop();
delay(1000);
motor_stop();
Serial.println(”5?);
}
// ————————————————————————— Drivevoid motor_stop(){
digitalWrite(motor_left[0], LOW);
digitalWrite(motor_left[1], LOW);
digitalWrite(motor_right[0], LOW);
digitalWrite(motor_right[1], LOW);
delay(25);
}
void drive_forward(){
digitalWrite(motor_left[0], HIGH);
digitalWrite(motor_left[1], LOW);
digitalWrite(motor_right[0], HIGH);
digitalWrite(motor_right[1], LOW);
}
void drive_backward(){
digitalWrite(motor_left[0], LOW);
digitalWrite(motor_left[1], HIGH);
digitalWrite(motor_right[0], LOW);
digitalWrite(motor_right[1], HIGH);
}
void turn_left(){
digitalWrite(motor_left[0], LOW);
digitalWrite(motor_left[1], HIGH);
digitalWrite(motor_right[0], HIGH);
digitalWrite(motor_right[1], LOW);
}
void turn_right(){
digitalWrite(motor_left[0], HIGH);
digitalWrite(motor_left[1], LOW);
digitalWrite(motor_right[0], LOW);
digitalWrite(motor_right[1], HIGH);
}