Robotarakan Petya por dez dólares

Conheça Petya, os três servos de seis pernas


Continuo publicando artigos da série Arduino Brain. Petya é um hexapods muito barato (cerca de dez dólares). Pode ser um projeto maravilhoso para um dia chuvoso de folga, que entreterá adultos e crianças. Já que estamos falando de entretenimento, aqui está um vídeo com Petya dançando ao funk:



É claro que não fiz nenhuma análise sonora, simplesmente programei Petya para dançar em um certo ritmo. Aqui está outro vídeo no qual Petya mostra seu desprezo por bolas de malabarismo:



Em sua forma atual, Petya só pode andar, mas ao mesmo tempo pode ver (medir a distância até) obstáculos próximos. Seus cérebros, no entanto, são produtivos o suficiente para poder digerir dados de muitos outros sensores, envie suas sugestões!


Como clonar Petya


Lista de compras


3 , / . , :



, , . (, ), . . — . , ;)


NB: 9g , . . , , , SketchUp . , , , .




, 3 , hardware/body/. - ::



1, . - :



3 . , . :





. hardware/motherboard/. :



ATMega8 , . :



, , , . :



N.B. , ATMega8A 2.7-5.5, 6. — NiMH 1.2V . (6.4 ), , . , , !


( ):




, . ; . , , . , , , :



:



; , Q3 Q4 "" Vcc, , . :



, , , R6. 47 55 , ( ). , , (910 )!


( ). , CR2032, . ( , [] , , )
, , Q3 Q4 . , , , , , .


, . , . 2n3904, , , . , , .


, , , , :



.


, , :


  • isf471 2n3904.
  • Sharp GP2Y0A21YK0F:
  • LM393:


, , , ATMega8. :


  • -

-


50 ; 1 (0 ), 2 (90 ). , 16 (timer1), (timer2). , Servo.h , , fast PWM.


8 , timer1 1 ( 8).
ICR1 TOP (20000), , 20 , 50 . OCR1A OCR1B ( ) .


. timer2, , , ICR1, , . , 50 , , - :


  • timer2 128, , 4.096 ms = 256 * 128/(8 * 10^6).
  • timer2, , .
  • capture interrupt timer1 timer2 ( ).

4 2 , , 20 . , (1.5 ), :


OCR1A = 1500;    // left servo
OCR1B = 1500;    // right servo
OCR2  = 1500/16; // center servo


-, :


const uint8_t  zero[3] = {45, 50, 40};     // zero position of the servo (degrees)
const uint8_t range[3] = {25, 25, 20};     // the servos are allowed to move in the zero[i] +- range[i] interval

zero[3] , (. ). , 45° ( ), 45° , . , range[3] . , i zero[i]-range[i] zero[i]+range[i].



( , 0°-90°) uint8_t pos[3]. update_servo_timers() - . pos[i]=zero[i]+range[i] i=0,1,2.


. pos_beg[3], pos_end[3], time_start[3] duration[3]. , . :


  • pos[0] pos_beg[0], , ;
  • pos_end[0] (- );
  • time_start[0] (, );
  • , , duration[0] ( ). , (pos_end[0]-pos_beg[0])/duration[0] /.

movement_planner(), pos[] , update_servo_timers(), - pos[].



, , , ( ) . , . , . , :


  • 1: {zero[0]-range[0], zero[1]-range[1], zero[2]+range[2]}
  • 2: {zero[0]-range[0], zero[1]-range[1], zero[2]-range[2]}
  • 3: {zero[0]+range[0], zero[1]+range[1], zero[2]-range[2]}
  • 4: {zero[0]+range[0], zero[1]+range[1], zero[2]+range[2]}

2 ( ):


const int8_t advance_sequence[4][3] = {{-1, -1,  1}, {-1, -1, -1}, { 1,  1, -1}, { 1,  1,  1}};

, i step zero[i] + range[i]*advance_sequence[step][i].
:


    uint8_t step = steps_per_sequence-1; // at the initialization stage the (previous) movement is considered to be complete, thus the next movement will be planned starting from the step 0
    while (1) {
        if (is_movement_finished()) {
            step = (step + 1) % 4; // if previous movement is complete, then perform the next step; this variable loops as 0,1,2,3.
            plan_next_movement(step, advance_sequence); // execute next movement
        }
        movement_planner(); // update the servos position according to the planning
        _delay_ms(1);
    }


, , 4 5 . , ( , ), adc_left_eye adc_right_eye , :


        adc_left_eye  = adc_left_eye *.99 + adc_read(5)*.01; // low-pass filter on the ADC readings
        adc_right_eye = adc_right_eye*.99 + adc_read(4)*.01;

_delay_ms() , .99 1-.99 .


:


        uint8_t lobst = adc_left_eye  < distance_threshold; // obstacle on the left?
        uint8_t robst = adc_right_eye < distance_threshold; // obstacle on the right?

(, ) :


        if (is_movement_finished()) {
            if (!lobst && !robst) {
                sequence = advance_sequence; // no obstacles => go forward
            } else if (lobst && robst) {
                sequence = retreat_sequence; // obstacles left and right => go backwards
            } else if (lobst && !robst) {
                sequence = turn_right_sequence; // obstacle on the left => turn right
            } else if (!lobst && robst) {
                sequence = turn_left_sequence; // obstacle on the right => turn left
            }
            step = (step + 1) % steps_per_sequence; // if previous movement is complete, then perform the next step
            plan_next_movement(step, sequence); // execute next movement
        }

, !



! , , :


:


  • "", . , , . , ?
  • ( !) , , .
  • , , avr-gcc . , - .

:


, V2 , ! , // :


  • — , ;
  • , RC- ;
  • ;
  • R6 ;
  • ( ) ;
  • — . — , ;
  • Mova o eletrólito levemente. Eu tive que inclinar, porque caso contrário, a perna esquerda central o machuca;
  • Adicione locais de teste com fácil acesso a eles com um osciloscópio;
  • Adicione um par de LEDs de depuração para depuração sem um osciloscópio;
  • Adicione placas de solda para todas as pernas do microprocessador não utilizadas para depuração e expansão adicional do robô.

Conclusão


Petya é uma diversão terrível!



All Articles