Hello again,
As many of you know, we had a Robo-rock festival arranged in our college. And ofcource the event was a great success. Thank you D.N.A. for covering our event. The event was of total 3 days. First day with a rock concert and other 2 days with a robotics workshop. And to showcase our work skills we made a Human size wall-e robot. ( we love wall-e a Lot,dont you? ) And yeah everyone loved it too. So i thought why not Document it.
Our first task was what motions should we include in Wall-e.
So we had total 9 motions.
we used a Couple of 24V 300rpm as a base motors. We used them in a sync with other pulleys and a belt drive to make wall-e’s belt driven base motion.
Then we had the hand movements. To use that at first we thought about using motors. But we do had a few pneumatic cylinders from Janatics pneumatics here in our lab so we thought why not use them instead of motors. so we used them almost everywhere 😛 like in the hand motions hand extensions and also in our lap jack extensions and then for head motion we used a Motor for horizontal movement and another cylinder for neck. (well, since last year our team has been totally turned into pneumatics freaks 😛 cant help it lol. )
Again our power source was 21V LiPo Battery and a couple of Lead acids of 12V. As the wall-e being human size, it sure eats up a lot of juice.
As we published last week the way to communicate serially without using a Microcontroller. We had a module of RF 433MHz module linked through a serial link by the use of our very favorite HT12E and HT12D ICs. So we firstly thought why not to make it wireless? yeah it was fine idea but there was only one problem. HT12D can provide only 4 data bits and as you can see we needed a lot more than that. so what we did is, we formed a combination of data bits and we made a total possibility of 2^4 that is 16 combinations of I/o’s. It did limit our simultaneous usage but it was totally fine because a simultaneous motion wasn’t needed.
So we desiggned a remote with 3 DPDT switches for motors and 5 toggle switches for the pneumatics. And thats where our tansmitter module resides. and our receiver was inside the WALL-E.
On transmitter side we converted the I/O’s combinations into 4 bits of data and gave it to the HT12E. (refer code below) and again on receiver side we took the data interpreted the outputs and then the output was given to the Motor drivers and pneumatic relays. and as expected it worked totally fine. Here is the code if you would like to make use of HT12E and HT12D to provide more than 4 I/O’s to your application. The data formatting was done using atmega 8 at transmitter side and at receiver it was Atmega16. (Atmel we love you for giving us free AVR samples, thanks a ton 😉 )
P.S. the circuitry and pneumatics pipe lining sure looks lousy 😛
Transmitter side :
#include #include #include "PORT.h" #define del _delay_ms(0) void modes() { if(bit_is_clear(PINB, 6) && bit_is_set(PINB, 7) && bit_is_clear(PIND, 5) && bit_is_set(PIND, 6) ) { PORTD |= 1<<0; //move fwd 1001 PORTD &= ~(1<<1); PORTD &= ~(1<<2); PORTD |= (1<<3); } else if(bit_is_clear(PINB, 7) && bit_is_set(PINB, 6) && bit_is_clear(PIND, 6) && bit_is_set(PIND, 5) ) { PORTD &= ~(1<<0); //move back 1010 PORTD |= (1<<1); PORTD &= ~(1<<2); PORTD |= (1<<3); } else if(bit_is_clear(PINB, 6) && bit_is_set(PINB, 7) && bit_is_clear(PIND, 6) && bit_is_set(PIND, 5)) { PORTD |= (1<<0); PORTD |= (1<<1); PORTD &= ~(1<<2); PORTD |= (1<<3); //right fwd left back 1011 } else if(bit_is_clear(PINB, 7) && bit_is_set(PINB, 6) && bit_is_clear(PIND, 5) && bit_is_set(PIND, 6)) { PORTD &= ~(1<<0); PORTD &= ~(1<<1); PORTD |= (1<<2); PORTD |= (1<<3); //right back left forward 1100 } /*else if(bit_is_clear(PINB, 2) && bit_is_clear(PINB, 1)) { PORTD &= ~(1<<0); //head pneu open and meteor poster out 0100 PORTD &= ~(1<<1); PORTD |= (1<<2); PORTD &= ~(1<<3); }*/ else if(bit_is_clear(PINC, 1) && bit_is_set(PINC, 0) ) { PORTD |= 1<<0; //head left 0101 PORTD &= ~(1<<1); PORTD |= (1<<2); PORTD &= ~(1<<3); } else if(bit_is_clear(PINC, 0) && bit_is_set(PINC, 1) ) { PORTD &= ~(1<<0); //head right 0110 PORTD |= 1<<1; PORTD |= (1<<2); PORTD &= ~(1<<3); } else if(bit_is_clear(PIND, 5) && bit_is_set(PIND, 6) ) { PORTD |= 1<<0; //left motor fwd 0111 PORTD |= (1<<1); PORTD |= (1<<2); PORTD &= ~(1<<3); } else if(bit_is_clear(PINB, 6) && bit_is_set(PINB, 7) ) { PORTD &= ~(1<<0); //right motor fwd 1000 PORTD &= ~(1<<1); PORTD &= ~(1<<2); PORTD |= (1<<3); } else if(bit_is_clear(PINC, 3) && bit_is_set(PINC, 2)) { PORTD |= 1<<0; PORTD &= ~(1<<1); PORTD |= (1<<2); PORTD |= (1<<3); //winding string motor 1101 } else if(bit_is_clear(PINC, 2) && bit_is_set(PINC, 3)) { PORTD &= ~(1<<0); PORTD |= (1<<1); PORTD |= (1<<2); PORTD |= (1<<3); //unwinding string motor 1110 } else if(bit_is_clear(PINB, 0)) { del; PORTD &= ~(1<<0); //pneu 1 left & RIGHT hand open 0000 PORTD &= ~(1<<1); PORTD &= ~(1<<2); PORTD &= ~(1<<3); } else if(bit_is_clear(PINB, 1)) { PORTD |= 1<<0 ; //head pneu open 0001 PORTD &= ~(1<<1); PORTD &= ~(1<<2); PORTD &= ~(1<< 3); } else if(bit_is_clear(PINB, 2)) { PORTD &= ~(1<<0) ; PORTD |= (1<< 1); PORTD &= ~(1<< 2); PORTD &= ~(1<<3); //pneu 3 meteor poster open 0010 } else if(bit_is_clear(PINB, 3) ) { del; PORTD |= 1<<0; //pneu 4(mic) open & left hand up 0011 PORTD |= 1<<1; PORTD &= ~(1<<2); PORTD &= ~(1<<3); } else { PORTD |= 1<<(PIND, 0) ; //else all high 1111 PORTD |= 1<<(PIND, 1); //retract all PORTD |= 1<<(PIND, 2); PORTD |= 1<<(PIND, 3); } } int main(void) { DDRB =0x00; PORTB = 0xFF; DDRD = 0b00001111; PORTD = 0b11110000; DDRC = 0x00; PORTC = 0xFF; //pb0 - pb3 pneumatics //pb6- pb7 pd5- pd6 manual //pc0 - pc3 head while(1) { modes(); } }
Receiver side:
#include #include #define cb(x,b) x&b #define bit(x) (1<<(x)) #define del _delay_us(10) //INITIALISATION void pneu() { switch (PINB) { case 0b11110000: { PORTA |= (1<<4); //pneu 1 left UP & RIGHT hand DWN open 0000 PORTA &= ~(1<<3); } break; case 0b11110001: { PORTA |= (1<<6);//head pneu open 0001 } break; case 0b11110010: { PORTA |= 1<<7;//pneu 3 meteor poster open 0010 } break; case 0b11110011: { PORTA |= 1<<4;//pneu 4(mic) open & left hand up 0011 PORTA &= ~(1<<3); PORTA |= 1<<0; } break; /* case 0b11110100: { PORTA |= (1<<6);//head pneu open & meteor poster 0100 PORTA |= 1<<7; } break; */ case 0b11110101: { OCR2 = 80;//head left 0101 PORTD &= ~(1<<6); PORTD &= ~(1<<0); //left motor off PORTD &= ~(1<<2); //right motor off } break; case 0b11110110: { OCR2 = 80;//head right 0110 PORTD |= 1<<6; PORTD &= ~(1<<0); //left motor off PORTD &= ~(1<<2); //right motor off } break; case 0b11110111: { PORTD |= 1<<0;//left motor fwd 0111 PORTD &= ~(1<<1); } break; case 0b11111000: { PORTD |= 1<<2;//right motor fwd 1000 PORTD &= ~(1<<3); } break; case 0b11111001: { PORTD |= 1<<0;//left motor fwd 0111 PORTD &= ~(1<<1); PORTD |= 1<<2;//right motor fwd 1000 PORTD &= ~(1<<3); //move fwd 1001 } break; case 0b11111010: { PORTD |= 1<<0;//left motor BACK 0111 PORTD |= (1<<1); PORTD |= 1<<2;//right motor BACK 1000 PORTD |= (1<<3); //move back 1010 } break; case 0b11111011: { PORTD |= 1<<2;//right motor fwd 1000 PORTD &= ~(1<<3); PORTD |= 1<<0;//left motor BACK 0111 PORTD |= (1<<1); //right fwd left back 1011 } break; case 0b11111100: { PORTD |= 1<<0;//left motor fwd 0111 PORTD &= ~(1<<1); PORTD |= 1<<2;//right motor BACK 1000 PORTD |= (1<<3); //right back left forward 1100 } break; case 0b11111101: { PORTC |= 1<<0; PORTC &= ~(1<<3);//winding string motor 1101 } break; case 0b11111110: { PORTC |= 1<<3; PORTC |= (1<<0);//unwinding string motor 1110 } break; case 0b11111111: { PORTA &= ~(1<<4); //LEFT DOWN del; PORTA |= (1<<3); //RIGHT UP del; PORTA &= ~(1<<6); //HEAD DOWN del; PORTA &= ~(1<<7); //METOR CLOSE del; PORTA &= ~(1<<0); //MIC CLOSE del; OCR2 = 0; //STOP HEAD del; PORTD &= ~(1<<0); //LEFT MOTOR STOP del; PORTD &= ~(1<<2); //RIGHT MOTOR STOP del; PORTC &= ~(1<<0); //WINDING STOP del; PORTC &= ~(1<<3); del; PORTD &= ~(1<<6); //stop head motor del; //else all high 1111 //retract all } break; } } int main(void) { DDRA = 0xFF; PORTA = 0x00; DDRB = 0x00; PORTB = 0xFF; DDRC= 0xFF; PORTC = 0x00; DDRD =0xFF; PORTD= 0x00; TCCR1A |= 1<<COM1A1 | 1<<WGM11 | (1<<COM1B1); TCCR1B |= 1<<CS10 | 1<<WGM13 | 1<<WGM12; TCCR2 = 0x68 | 0<<CS21 | 0<<CS22 | 1<<CS20; ICR1= 20000; OCR2 = 0; while(1) { pneu(); } }
Pingback: Man Sized WALL-E Robot - Hackalizer