Начитавшись в интернете и в том числе на хабре о создании разнообразных роботов, я решил сделать своего. Тем более, что у меня давно без дела валяется arduino.

За неименеем денег на шасси для робота, решил сделать самое дешевое и простое. В качестве органов чувств был выбран ультразвуковой дальномер.

Мне хотелось собрать дешевую и простую в изготовлении платформу для моей ардуины.
Я попытался использовать свой радиоуправляемый джип, но мощности motorshield'а не хватало для нормального движения(я даже случайно спалил драйвер двигателя).Был необходим h-мост, состоящий из 4х транзисторов. Разбираться в схеме игрушки было лень(да и ломать не хотелось), а для пайки своего надо было рыться в закромах родины и искать транзисторы.
В моем распоряжении было несколько моторчиков, обрезки алюминевых листов и советский металлический конструктор.
Путешествуя по интернету я часто натыкался на beam-роботов, которые не имели ни колес, ни гусениц, а главное не имели редукторов.
Весь секрет состоял в моторах, которые были расположены под углом к полу. Робот стоял прямо на валах.

Это позволяет не заботиться о передаточных числах, мощностях моторов. Сами двигатели являются редукторами за счет малого диаметра вала.
Из алюминевого листа вырезал держатель моторов, прикрепил его к раме из конструктора и привинтил держатель arduino. Вроде ничего сложного, дремель, отвертка и максимум 15 минут времени.
Как упомянул выше, arduino управляет моторами через motorshield, питание у них раздельное, чтобы не спалить микропроцессор. Позже я добавил кнопку выключения. К платам подключен ультразвуковой дальномер SRF05. Он умеет работать в 2х режимах, подробно останавливаться не буду, скажу лишь, что в 1ом режиме необходимо задействовать 2 контакта(один тригер на посылку звука, второй прием данных), а 2ой соответственно 1, за что и был выбран. ��ля сенсора был спаян переходник, включающий сенсор во второй режим(заземляет один контакт).
На видео ниже будет показан простейший алгоритм-увидел стенку, поверни. Здесь же я приведу более содержательный код. В комментариях есть пояснения.
Алгоритм следующий:
1) повращаться вокруг своей оси и найти максимальную дистанцию
2) повернуться по направлению к максимальной дистанции
3.1) если смогли повернуться едем прямо до некоторого момента
3.2) если не смогли едем вперед
4.1) если застряли(едем вперед, а расстояние не меняется) отъезжаем назад и возращаемся к пункту 1
4.2) если доехали до стенки, останавливаемся и возвращаемся к пункту 1
Исходник:
За один вечер реально построить простейшего робота. Конечно же есть недоделки, например сенсор стоит повесить на сервомотор и провода следует привести в нормальный вид. Надеюсь вам понравится такой робот.

За неименеем денег на шасси для робота, решил сделать самое дешевое и простое. В качестве органов чувств был выбран ультразвуковой дальномер.

Задумка
Мне хотелось собрать дешевую и простую в изготовлении платформу для моей ардуины.
Я попытался использовать свой радиоуправляемый джип, но мощности motorshield'а не хватало для нормального движения(я даже случайно спалил драйвер двигателя).Был необходим h-мост, состоящий из 4х транзисторов. Разбираться в схеме игрушки было лень(да и ломать не хотелось), а для пайки своего надо было рыться в закромах родины и искать транзисторы.
В моем распоряжении было несколько моторчиков, обрезки алюминевых листов и советский металлический конструктор.
Проектирование
Путешествуя по интернету я часто натыкался на beam-роботов, которые не имели ни колес, ни гусениц, а главное не имели редукторов.
Весь секрет состоял в моторах, которые были расположены под углом к полу. Робот стоял прямо на валах.

Это позволяет не заботиться о передаточных числах, мощностях моторов. Сами двигатели являются редукторами за счет малого диаметра вала.
Постройка
Рама
Из алюминевого листа вырезал держатель моторов, прикрепил его к раме из конструктора и привинтил держатель arduino. Вроде ничего сложного, дремель, отвертка и максимум 15 минут времени.
Электроника
Как упомянул выше, arduino управляет моторами через motorshield, питание у них раздельное, чтобы не спалить микропроцессор. Позже я добавил кнопку выключения. К платам подключен ультразвуковой дальномер SRF05. Он умеет работать в 2х режимах, подробно останавливаться не буду, скажу лишь, что в 1ом режиме необходимо задействовать 2 контакта(один тригер на посылку звука, второй прием данных), а 2ой соответственно 1, за что и был выбран. ��ля сенсора был спаян переходник, включающий сенсор во второй режим(заземляет один контакт).
Программирование
На видео ниже будет показан простейший алгоритм-увидел стенку, поверни. Здесь же я приведу более содержательный код. В комментариях есть пояснения.
Алгоритм следующий:
1) повращаться вокруг своей оси и найти максимальную дистанцию
2) повернуться по направлению к максимальной дистанции
3.1) если смогли повернуться едем прямо до некоторого момента
3.2) если не смогли едем вперед
4.1) если застряли(едем вперед, а расстояние не меняется) отъезжаем назад и возращаемся к пункту 1
4.2) если доехали до стенки, останавливаемся и возвращаемся к пункту 1
Исходник:
#include <AFMotor.h> #define MaxRange 23 // Как близко подъезжать к препятствиям #define MaxTries 3 // Сколько раз пытаться найти максимум int srfPin = 16; // Pin for SRF05 int ledPin = 2; // AF_DCMotor motorL(2); AF_DCMotor motorR(1); boolean isInRange(int value,int leftBorder,int rightBorder){ return (value>leftBorder && value<rightBorder); } //Забрать показания сенсора int getDistance(){ delay(50); int duration=0; //сюда кладем время ответа pinMode(srfPin, OUTPUT); digitalWrite(srfPin, LOW); // заземляем контакт, перед посылкой delayMicroseconds(2); digitalWrite(srfPin, HIGH); // Посылаем 10микросекундный сигнал начала измерений delayMicroseconds(10); digitalWrite(srfPin, LOW); // Опять заземляем перед приемом ответа pinMode(srfPin, INPUT); duration = pulseIn(srfPin, HIGH); // Считаем время ответного сигнала return duration/58; //возвращаем дистанцию в сантиметрах } //Функции движения void goForward(){ motorL.setSpeed(255); motorR.setSpeed(255); motorL.run(FORWARD); motorR.run(FORWARD); } void goBackward(){ motorL.setSpeed(255); motorR.setSpeed(255); motorL.run(BACKWARD); motorR.run(BACKWARD); } void turnLeft(){ motorL.setSpeed(255); motorR.setSpeed(255); motorL.run(BACKWARD); motorR.run(FORWARD); } void turnRight(){ motorL.setSpeed(255); motorR.setSpeed(255); motorL.run(FORWARD); motorR.run(BACKWARD); } void stopMovement(){ motorL.run(RELEASE); motorR.run(RELEASE); } // функция поиска максимума вокруг int getMaxDistanseAround(){ unsigned long timeStart=millis(); int maxFound=0; // выбор направления поворота случаен if(random(100)<50){turnLeft();}else{turnRight();} // крутимся некоторое время и ищем максимум while(millis()-timeStart<3000){ int curDistance=getDistance(); if( curDistance > maxFound ){ maxFound=curDistance; } } return maxFound; } // функция возвращения на максимум boolean turnToDistance(int distance){ unsigned long timeStart=millis(); // опять случайное направление if(random(100)<50){turnLeft();}else{turnRight();} // крутимся некоторое время while(millis()-timeStart<3000){ // учитывая погрешность сравниваем текущее растояние перед роботом // и то, на которое надо выровняться if( isInRange(getDistance(),distance-5,distance+5)){ // Пишем в usb сообщение об удаче Serial.print("Turned to "); Serial.println(getDistance()); // немного отступаем(так видно что нашли дистанцию) goBackward(); delay(200); stopMovement(); blinkLed(); return true;// возвращаем 1, т.к. сумели выполнить задачу } } Serial.println("distance not found"); return false;// возвращаем ложь в случае неудачи } //это тестовая функция, узнаем какая скорость у робота float getMySpeed(){ int secToMeas=2; float firstDistance=getDistance(); goForward(); delay(secToMeas*1000); stopMovement(); float newDistance=getDistance(); return (firstDistance-getDistance())/secToMeas/100; } //моргаем светодиодом void blinkLed(){ digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); } float mySpeedSm=0;//скорость в см/c float mySpeedM=0;// и в м/c void setup() { Serial.begin(9600); // set up Serial library at 9600 bps // т.к. на этот пин ничего не подключено мы получаем шум // в качестве зерна генератора randomSeed(analogRead(0)); // иницилизируем сенсор и моторы, делаем проверку pinMode(ledPin, OUTPUT); Serial.println("Testing systems"); blinkLed(); // настраиваем сенсор getDistance(); if(getDistance()>0){ Serial.println("Ultrasonic sensor ready"); } delay(1000/4); // настраиваем моторы motorL.setSpeed(255); motorR.setSpeed(255); stopMovement(); blinkLed(); delay(1000/3); Serial.println("Getting averange speed"); blinkLed(); mySpeedSm=getMySpeed(); mySpeedM=mySpeedSm/100; blinkLed(); blinkLed(); blinkLed(); } int tries=MaxTries; // основной цикл работы робота void loop(){ // ищем максимум вокруг int maxDist=getMaxDistanseAround(); Serial.print("Found max distance"); Serial.println(maxDist); delay(500); // пробуем повернуться на него if(turnToDistance(maxDist)){ tries=MaxTries;// обнуляем счетчик попыток int lastDistance=getDistance(); // едем до некого растояния вперед while(lastDistance>MaxRange){ goForward(); delay(500); // Проверка застряли или нет int newDist=getDistance(); if(isInRange(newDist,lastDistance-2,lastDistance+2)){ goBackward(); delay(1000); lastDistance=0; } else{ lastDistance=newDist; } } }else{ // в случае невозможности выхода на максимальную // уменьшаем счетчик попыток tries--; if(tries==0){// если попыток не осталось пробуем поехать хоть куда-нибудь if(getDistance()>MaxRange*2){ goForward(); delay(1000); } else{ goBackward(); delay(1000); } } } stopMovement(); delay(500); }
Видео
Заключение
За один вечер реально построить простейшего робота. Конечно же есть недоделки, например сенсор стоит повесить на сервомотор и провода следует привести в нормальный вид. Надеюсь вам понравится такой робот.