Как построить робототехническое оборудование

Как построить робототехническое оборудование
Как построить робототехническое оборудование
Anonim

Как построить робот - тестирование оборудования

Часть третья из серии статей о создании робота, который может следовать за линиями или стенами и избегать препятствий!

Статьи по Теме

Как построить робот:

Часть 1: Дизайн и схема

Часть 2. Дизайн печатной платы

Часть 4: Линейный последователь

Часть 5: Предотвращение препятствий

Часть 6: Настенный робот

обзор

Это часть 3 серии статей о моем опыте создания робота, который может делать разные вещи. Я думал, что было бы аккуратно создать робота, который легко было бы собрать вместе с одним паяльником и был бы также доступным. Я выполнил следующие требования для своего робота:

  • Многие комплекты стоят дорого, поэтому они должны быть относительно недорогими.
  • Его необходимо легко собрать без специального оборудования.
  • Он должен быть легко программирован без сложной среды разработки или программиста.
  • Он должен быть достаточно мощным для расширяемости.
  • Он должен работать от простого источника питания.
  • Он должен иметь возможность следовать по линии или стене и избегать препятствий.

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

Сбор компонентов

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

Image
Image

Сборка механических компонентов

Ball Caster

Шлем заклинателя пришел как комплект, который нужно было собрать. Он предлагал различные варианты размера. Это было не слишком сложно, поэтому я не делал никаких снимков процесса сборки.

двигатель

Мотор также появился как комплект и был намного сложнее. Моторный комплект предлагает 4 различных передаточных числа. В итоге я выбрал 38: 1 для большого соотношения, потому что я не хотел, чтобы робот был слишком медленным, но все же справлялся с тяжестью. Более высокие передаточные отношения были бы ненужным количеством крутящего момента. Единственный реальный вес на роботе - это батареи. Передаточное отношение всегда можно отрегулировать после сборки, но это будет немного больно. Скорость двигателя можно отрегулировать, изменив рабочий цикл PWM на контроллер двигателя, поэтому, если передаточное отношение будет слишком высоким, его можно снизить с помощью программного обеспечения.

Вот все различные части из набора. Я использовал разделочную доску для сборки, потому что у маленьких винтов есть привычка откатываться от стола.

Image
Image

Полностью собранный робот-мотор и шестерни. Комплект поставляется со всем необходимым, включая смазку. Единственный инструмент, в котором я нуждался, был отверткой.

Image
Image

Прикрепленный к печатной плате, он действительно хорошо сочетается с шелковым экраном!

Image
Image

Пайка компонентов

Я использовал заголовки для женщин, если бы захотел поменять компоненты позже. Пайка всех мужских заголовков на доски DIP была немного утомительной, но намного легче, чем паять все компоненты поверхностного монтажа! Мне пришлось использовать кучу заголовков, соединенных вместе, чтобы датчик линии был достаточно близко к земле, чтобы быть аффективным. Если бы я начал с нуля, я предпочел бы более чистый способ установки линейного датчика.

Image
Image

Тестирование двигателей

Сначала я просто подключил двигатели непосредственно к батареям 2AA, чтобы убедиться, что шестерни были правильно смазаны. Я также измерил ток, чтобы убедиться, что он был в спецификации. Убедившись, что двигатели могут быть повернуты вперед и назад, я подключил их к двигателю. Я написал несколько тестовых программ, которые двигали двигатели вперед и назад в течение пяти секунд. Это подтвердило связь между Teensy, контроллером двигателя и двигателем сразу. Это приятный результат, когда вам не нужно устранять проблемы с подключением на первой ревизионной плате! Следующий код управляет роботом вперед в течение 5 секунд с половиной мощности, а затем назад в течение 5 секунд. Я написал драйвер под названием «robot.ino», который заботится о поворотах и считывании сенсора. См. Конец статьи для водителя. Чтобы запрограммировать Teensy, загрузите дополнение Teensyduino для платформы Arduino. Программирование тогда точно так же, как с использованием Arduino.

Во время тестирования я использовал перемычку как переключатель включения / выключения.

Image
Image

Оно живое!


#include "robot.h" void setup() { Serial.begin(38400); Serial.println("Boot"); rbt_init(); rbt_move(FWD, 100); delay(5000); rbt_move(REV, 100); delay(5000); rbt_move(BRAKE, 0); } void loop() { }

Скачать код

Тестирование датчиков

Чтобы проверить датчики, я написал программу, которая печатала исходное значение с датчиков. Я узнал, что не мог использовать настенные датчики одновременно, или все они будут активироваться в течение 100% времени. Причина этого в том, что ИК-приемники имеют широкий угол, и они подбирают сигналы от соседних передатчиков. Я написал библиотеку так, чтобы она поочередно считывала каждый датчик, пользуясь опорным штырем на датчике. Настенные датчики также должны быть слегка наклонены, или они поднимают землю как объект.

Функция считывания датчика выполняется в 1 мс, предлагая скорость 1 кГц для обработки довольно сложных алгоритмов управления, если это необходимо. Тест-код также показал, что линейный датчик должен быть очень близко к земле, чтобы эффективно определять разницу между цветами. Если робот находится в паре дюймов от земли, линейные датчики максимальны при показании 1000. Это действительно может быть полезно для того, чтобы робот переставал двигаться, когда его перевозили.

Датчик линии очень близко к земле, но не касается!

Image
Image

#include "robot.h" void setup() { Serial.begin(38400); Serial.println("Boot"); rbt_init(); } uint16_t lleft, lmid, lright; boolean wleft, wmid, wright; void loop() { rbt_sns(&lleft, &lmid, &lright, &wleft, &wmid, &wright); Serial.print("Line left: "); Serial.print(lleft); Serial.print("Line mid: "); Serial.print(lmid); Serial.print("Line right: "); Serial.print(lright); Serial.print("Wall left: "); Serial.print(wleft); Serial.print("Wall mid: "); Serial.print(wmid); Serial.print("Wall right: "); Serial.println(wright); }

Скачать код

Вывод

В этой статье я показал процесс сборки робота и тестирования компонентов по отдельности. Это важно сделать, когда вы впервые получаете доски, потому что вы никогда не знаете, какие ошибки могли быть сделаны в дизайне или изготовлении печатной платы. Если вы приступите к дизайну приложения, вы можете пропустить что-то, что вызывает проблемы в будущем. В следующей статье я расскажу о том, как превратить робота в последователя линии, отредактировав простой алгоритм, чтобы оставаться в центре черной линии.

Библиотека роботов

robot.h

#ifndef _ROBOT_H #define _ROBOT_H #include "Arduino.h" /*DRV8835*/ const int BPHASE = 5; const int APHASE = 3; const int AEN = 4; const int BEN = 6; const int DRV_MODE = 2; #define MOTOR_REV LOW #define MOTOR_FWD HIGH /*reflection sensor interface*/ const int OUT1 = 33; const int OUT2 = 32; const int OUT3 = 31; /*wall sensor interface*/ const int WALL_LEFT_EN = 15; const int WALL_LEFT = 14; const int WALL_RIGHT_EN = 19; const int WALL_RIGHT = 18; const int WALL_MID_EN = 17; const int WALL_MID = 16; /*robot interface*/ typedef enum{ LEFT, RIGHT, FWD, REV, BRAKE, }direction_t; void rbt_move(direction_t new_dir, uint8_t speed); void rbt_sns(uint16_t *line_left, uint16_t *line_mid, uint16_t *line_right, boolean *wall_left, boolean *wall_mid, boolean *wall_right); void rbt_init(); #endif /*_ROBOT_H*/

Скачать код

robot.ino

#include "robot.h" void rbt_init() { pinMode(BPHASE, OUTPUT); pinMode(APHASE, OUTPUT); pinMode(AEN, OUTPUT); pinMode(BEN, OUTPUT); pinMode(DRV_MODE, OUTPUT); pinMode(WALL_LEFT_EN, OUTPUT); pinMode(WALL_MID_EN, OUTPUT); pinMode(WALL_RIGHT_EN, OUTPUT); pinMode(WALL_LEFT, INPUT); pinMode(WALL_MID, INPUT); pinMode(WALL_RIGHT, INPUT); digitalWrite(WALL_LEFT_EN, LOW); digitalWrite(WALL_MID_EN, LOW); digitalWrite(WALL_RIGHT_EN, LOW); /*simplified drive mode*/ digitalWrite(DRV_MODE, HIGH); } void rbt_move(direction_t new_dir, uint8_t speed) { if(speed) { switch(new_dir){ case LEFT: digitalWrite(BPHASE, MOTOR_FWD); digitalWrite(APHASE, MOTOR_FWD); analogWrite(AEN, speed); analogWrite(BEN, speed-speed/2); break; case RIGHT: digitalWrite(BPHASE, MOTOR_FWD); digitalWrite(APHASE, MOTOR_FWD); analogWrite(AEN, speed-speed/2); analogWrite(BEN, speed); break; case FWD: digitalWrite(BPHASE, MOTOR_FWD); digitalWrite(APHASE, MOTOR_FWD); analogWrite(AEN, speed); analogWrite(BEN, speed); break; case REV: digitalWrite(BPHASE, MOTOR_REV); digitalWrite(APHASE, MOTOR_REV); analogWrite(AEN, speed); analogWrite(BEN, speed); break; default: analogWrite(AEN, 0); analogWrite(BEN, 0); break; } } else { analogWrite(AEN, 0); analogWrite(BEN, 0); } } /*function takes 1ms to run*/ #define LOOP_ITER_CNT 2 void rbt_sns(uint16_t *line_left, uint16_t *line_mid, uint16_t *line_right, boolean *wall_left, boolean *wall_mid, boolean *wall_right) { *line_left=0; *line_mid=0; *line_right=0; uint16_t usec_timer=0; /*line sensor*/ /*charge lines*/ pinMode(OUT1, OUTPUT); pinMode(OUT2, OUTPUT); pinMode(OUT3, OUTPUT); digitalWrite(OUT1, HIGH); digitalWrite(OUT2, HIGH); digitalWrite(OUT3, HIGH); delayMicroseconds(3); /*set to Hi-Z to let cap discharge*/ pinMode(OUT1, INPUT); pinMode(OUT2, INPUT); pinMode(OUT3, INPUT); /*enable first wall sensor*/ digitalWrite(WALL_LEFT_EN, HIGH); while(1){ /*each loop is about 2us at 48MHz*/ usec_timer+=LOOP_ITER_CNT; /*increment counts for line sensors every us to track the decay of the capacitor*/ if(digitalRead(OUT1) == 1) { (*line_left)+=LOOP_ITER_CNT; } if(digitalRead(OUT2) == 1) { (*line_mid)+=LOOP_ITER_CNT; } if(digitalRead(OUT3) == 1) { (*line_right)+=LOOP_ITER_CNT; } /*take turns reading wall sensors because they interfere with each other*/ if(usec_timer == 300) { *wall_left = (digitalRead(WALL_LEFT) ? false:true); digitalWrite(WALL_LEFT_EN, LOW); } if(usec_timer == 400) { digitalWrite(WALL_MID_EN, HIGH); } if(usec_timer == 700) { *wall_mid = (digitalRead(WALL_MID) ? false:true); digitalWrite(WALL_MID_EN, LOW); } if(usec_timer == 700) { digitalWrite(WALL_RIGHT_EN, HIGH); } if(usec_timer>=1000) { *wall_right = (digitalRead(WALL_RIGHT) ? false:true); digitalWrite(WALL_MID_EN, LOW); return; } } }

Скачать код

Следующая статья в серии: как построить робота - последователь линии