Машинка на Arduino
- Войдите на сайт для отправки комментариев
Втр, 19/05/2015 - 15:17
Добрый день всем.я сразу скажу что не прошу писать код за меня,я просто прошу обьяснить кто может в коде.
задумка такая: платформа должна проверить все стороны и потом вычеслить в какую сторону должна ежать.сервопривод не должен постоянно вращаться и не тратить по просто питания.я не могу понять как правильно соединять прогрумму сервопривода потом HC SR04 и когда он сделает вычеслени и потом уже ехать в правильном направлении.
задумка по программе
включаю платформу
HC SR04 проверяет стороны
делает вычисление
выбирает нужное направление
двишаеться в выбронном направлении
// Редактируеться
#include <Servo.h>
#include "Ultrasonic.h"
Servo myservo; // создаём объект для контроля сервы
#define dead_zone 30
#define go to left 40
#define go to right 50
#define Trig A1
#define Echo A2
// sensor connected to:
// Trig - 2, Echo - 3
int pos = 0; // переменная для хранения позиции сервы
int IN1 = 2; // движение вперед правый движок
int IN2 = 3; // движение назад левый движок
int IN3 = 4; // движение назад правый движок
int IN4 = 5; // движение вперед левый движок
int EN1 = A0;
int EN2 = 9;
void setup()
{
myservo.attach(9); // серва подключена к 9-му пину
pinMode(Trig, OUTPUT);
pinMode(Echo, INPUT);
pinMode (EN1, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (EN2, OUTPUT);
pinMode (IN4, OUTPUT);
pinMode (IN3, OUTPUT);
}
unsigned int impulseTime=0;
unsigned int distance_sm=0;
void loop()
{
for(pos = 0; pos < 180; pos += 1) // от 0 до 180 градусов
{ // с шагом в 1 градус
myservo.write(pos); //
delay(15); // ждём 15ms пока серва займёт новое положение
}
for(pos = 180; pos>=1; pos-=1) // от 180 до 0 градусов
myservo.write(pos);
delay(45);
digitalWrite(Trig, HIGH);
/* Подаем импульс на вход trig дальномера */
delayMicroseconds(10); // равный 10 микросекундам
digitalWrite(Trig, LOW); // Отключаем
impulseTime=pulseIn(Echo, HIGH); // Замеряем длину импульса
distance_sm=impulseTime/58; // Пересчитываем в сантиметры
if (distance_sm < dead_zone)
{
// движение назад
digitalWrite (IN1, HIGH); // движение вперед правый движок
digitalWrite (IN2, LOW); // движение назад левый движок
digitalWrite (IN3, HIGH); // движение назад правый движок
digitalWrite (IN4, LOW); // движение вперед левый движок
analogWrite(EN1, 215);
analogWrite(EN2, 215);
delay(20);
// остановка
digitalWrite (IN1, LOW); // движение вперед правый движок
digitalWrite (IN2, LOW); // движение назад левый движок
digitalWrite (IN3, LOW); // движение назад правый движок
digitalWrite (IN4, LOW); // движение вперед левый движок
analogWrite(EN1, 0);
analogWrite(EN2, 0);
for(pos = 0; pos < 180; pos += 1) // от 0 до 180 градусов
{ // с шагом в 1 градус
myservo.write(pos); //
delay(15); // ждём 15ms пока серва займёт новое положение
}
for(pos = 180; pos>=1; pos-=1) // от 180 до 0 градусов
myservo.write(pos);
delay(45);
digitalWrite(Trig, HIGH);
/* Подаем импульс на вход trig дальномера */
delayMicroseconds(10); // равный 10 микросекундам
digitalWrite(Trig, LOW); // Отключаем
impulseTime=pulseIn(Echo, HIGH); // Замеряем длину импульса
distance_sm=impulseTime/58; // Пересчитываем в сантиметры
}
else if (distance_sm<50)
{
// движение вперед
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite(EN1, 215);
analogWrite(EN2, 215);
}
else
{
digitalWrite (IN1, LOW);
digitalWrite (IN2, LOW);
digitalWrite (IN3, LOW);
digitalWrite (IN4, LOW);
analogWrite(EN1, 215);
analogWrite(EN2, 215);
}
}
Отличная тема! Вы нам простыню, а мы Вам:
Вот видео работы машинки
http://www.youtube.com/watch?v=7l6YK-FRkJc
Вот ПО:
/* Программа управления машинкой с ультразвуковым датчиком рассояния на сервомоторе и двумя сервомоторами на колесах. */ #include<avr/io.h> // Просто мигаем светодиодом const int led_pin = 5; // PB5 номер выхода, подключенного к светодиоду // Variables will change: volatile long startMks = 0; volatile long stopMks = 0; // храним время последнего переключения светодиода volatile boolean dist_m = false; byte scanSpeed = 1000; // интервал между включение/выключением светодиода (1 десятая секунды) // скорость машинки signed short int w_speed = 15; #include <Servo.h> Servo LeftServoMotor; // create servo object to control a left servo Servo RightServoMotor; // create servo object to control a left servo Servo USMMotor; // create servo object to control a left servo // Pin 3 - сигнальная ножка мотора правого колеса #define rightMotorPin 3 // Pin 5 - сигнальная ножка мотора левого колеса #define leftMotorPin 5 // Pin 6 - сигнальная ножка мотора который вращает ультразвуковой датчик #define usdMotorPin 6 // блок констант для измерения расстояния #define trig_Pin 1 //PINB1 ножка под триггер УЗ датчика #define echo_Pin 2 //PINB2 ножка под эхо УЗ датчика //массив сектора расстояний unsigned int sector_distance[6] = {1,1,1,1,1}; // расстояние в текущем направлении volatile unsigned int distance_sm=0; // нулевая точка правой и левой сервы int right_Servo_Zero_Point = 68; int left_Servo_Zero_Point = 72; // как припаяны провода на моторчиках (вращаются в одну сторону или в разные) boolean motorSinc = false; // the setup routine runs once when you press reset: void setup() { DDRB = B0100010; // выход на триггер (B1) и LED-диод (B5) эхо (В2) на ввод DDRD = B01101000; //выходы на сервы (D3) и (D5) и на серву глаза D6 //настраиваем прерывание под установку PB в ноль (триггер) /*The External Interrupt 0 is activated by the external pin INT0 if the SREG I-flag and the corresponding interrupt mask are set.*/ EICRA = B10; // External Interrupt Control Register A . The falling edge of INT0 generates an interrupt request. /* When the PCIE0 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt 0 is enabled. */ // EIMSK = B1; // EIMSK – External Interrupt Mask Register. Bit 0 – INT0: External Interrupt Request 0 Enable PCICR = B1; //PCICR – Pin Change Interrupt Control Register. Any change on any enabled PCINT7..0 pin will cause an interrupt. Глобально разрешает/запрещает прерывания INT2/1/0 PCMSK0 = B100; //PCMSK0 Bit 7..0 – PCINT7..0: Pin Change Enable Mask 7..0 Включаем прерывание на эхе (по спаду сигнала - это определено выше) pinMode(rightMotorPin, OUTPUT); pinMode(leftMotorPin, OUTPUT); pinMode(usdMotorPin, OUTPUT); // LeftServoMotor.attach(leftMotorPin); // attaches the servo RightServoMotor.attach(rightMotorPin); // attaches the servo USMMotor.attach(usdMotorPin); // attaches the servo // initialize serial: Serial.begin(9600); // останавливаем колеса stop_mashine(); // выставляем глаз перед собой USMMotor.write(100); delay(3000); distance_sm =0; } // the loop routine runs over and over again forever: void loop() { terrain_scan(); //заполняет массив препятствий на пути byte alfa = path_select(); // возвращает угол поворота 0, -30, -60, 60, 30 Serial.print(alfa); Serial. print("\n"); rotate(alfa); move_forvard(); while(look_arraund()){ delay(100); }; stop_mashine(); } void stop_mashine(){ int lms = left_Servo_Zero_Point; int rms = right_Servo_Zero_Point; LeftServoMotor.write(lms); RightServoMotor.write(rms); } boolean look_arraund(){ ultrasonic(); delay(100); if (distance_sm > 15){ Serial.print(distance_sm); Serial.print("\n"); return true; } else return false; } byte path_select(){ byte k=0; unsigned int j=0; for (byte i=0;i<5;i++){ if (j<=sector_distance[i]) { k = i; j=sector_distance[i]; } } return k; } void terrain_scan(){ for (byte i = 0; i < 5; i++){ USMMotor.write(100-60+i*30); delay(scanSpeed); ultrasonic(); sector_distance[i] = distance_sm; } // второй проход for ( byte i = 5; i >0; i--){ USMMotor.write(100-60+(i-1)*30); delay(scanSpeed); ultrasonic(); sector_distance[i] = (distance_sm+sector_distance[i])/2; } for(byte i = 0; i<5; i++) { Serial.print(sector_distance[i]); Serial. print("|"); } Serial.print("\n"); USMMotor.write(100); } // поворот машинки void rotate(byte dir){ int lms = left_Servo_Zero_Point; int rms = right_Servo_Zero_Point; if (!motorSinc) { if(dir>2){ //надо повернуть влево lms -= dir*dir; rms -= dir*dir; } if(dir<2){ // надо повернуть вправо lms += 16-dir*7; rms += 16-dir*7; } } // крутим моторчики некоторое время LeftServoMotor.write(lms); RightServoMotor.write(rms); delay(500); LeftServoMotor.write(left_Servo_Zero_Point); RightServoMotor.write(right_Servo_Zero_Point); } // // движение void move_forvard(){ int lms; int rms; if (!motorSinc) { lms = left_Servo_Zero_Point + w_speed; rms = right_Servo_Zero_Point - w_speed; } else { lms= left_Servo_Zero_Point - w_speed; rms= right_Servo_Zero_Point - w_speed; } // крутим моторчики LeftServoMotor.write(lms); RightServoMotor.write(rms); } /* замер расстояния */ ISR(TIMER2_COMPA_vect) { } void ultrasonic(){ if(dist_m){ dist_m = false; // сбрасываем флаг подтверждения расстояния PORTB |= 1<<trig_Pin; delayMicroseconds(10); PORTB &= ~(1<<trig_Pin); startMks = micros(); } } // вычисляем задержку по спаду эха ISR(PCINT0_vect ){ //cli(); stopMks = micros(); PORTB ^= 1<<led_pin; distance_sm=(stopMks-startMks)/(29*2); dist_m= true; //sei(); } /**/ void serial_print(){ Serial.print("TCNT2 "); Serial.print(TCNT2); Serial.print("\n"); // byte xx[]={OCR1AL,OCR1AH}; // unsigned int *y = (unsigned int *)&xx; // Serial.print("OCR1A"); // Serial.print(y[0]); Serial.print("OCR2A "); Serial.print(OCR2A); Serial.print("\n"); Serial.print("OCR2B "); Serial.print(OCR2B); Serial.print("\n"); Serial.print("TCCR2A "); Serial.print(TCCR2A); Serial.print("\n"); Serial.print("TCCR2B "); Serial.print(TCCR2B); Serial.print("\n"); // PRR |=1<<PRTIM0; // запрет таймера Т1 // PRR |=1<<PRTIM2; // запрет таймера Т2 Serial.print("EICRA "); Serial.print(EICRA); Serial.print("\n"); Serial.print("PCICR "); Serial.print(PCICR); Serial.print("\n"); delay(1000); if (Serial.available()){ Serial.print("\n"); Serial.print("\n"); Serial.print("\n"); } }Как видите все работает. Разбирайтесь. По писал сын -10 лет, корпус резал я.
Сыну огромное спасибо за ПО которое он написал.Да и корпус не плохо сделан. Получилось у вас очень не плохо.
мне бы не плохо было разбраться бы со своим кодом. меня сейчас больше всего интересует как программно по очереди запускать серво мотор , ультразвуковой и делать проверку местности.