История создания еще одного робота. Часть вторая, «it’s alive!»

в 20:43, , рубрики: avr, DIY, diy или сделай сам, linefollower, qt, ЛУТ, программирование микроконтроллеров, роботы, Электроника для начинающих

Продолжаю серию публикаций о создании простого колесного робота на микроконтроллере ATmega16A.
Во второй части моей публикации я опишу процесс создания и сборки своего робота. Начнем с изготовления печатной платы и закончим видео первых шагов (правильней сказать — прокручивания колес) нашего устройства. Также уделю внимание первому опыту программирования под PC в Qt, а именно созданию программы управления и обмена данными с роботом по Bluetooth.
Если хотите, можете ознакомится с первой публикацией и узнать с чего все началось, ну а всех остальных прошу под кат.

Прошлая часть закончилась на том, что перед нами красовалась готовая разводка печатной платы, а значит, пора творить и переносить нашу задумку из электронной версии в реальный осязаемый мир, разве не это желание теплится в голове у каждого радиолюбителя, инженера, изобретателя?! У меня на руках был только 1мм текстолит, так что я недолго думая начал процесс переноса на плату рисунка дорожек стандартным ЛУТом.

Извиняюсь за качество фотографий, но телефон у меня дешевый…
image

image

Следующим шагом было травление! Опробовал для себя новый способ травления с помощью перекиси водорода и лимонной кислоты, способ конечно безопасный и очень дешевый, но показался мне слишком чувствительным к пропорциям компонентов. После часа колдовских манипуляций над тарой с раствором процесс пошел с достойной силой (стоит сказать, что можно было изменить шаблон платы и тогда бы все вытравилось заметно быстрее).

image

image

80-90% дорожек на плате получились хорошо, но т.к. в основном дорожки были 0.2мм, попались протравы, которые я устранил с помощью припоя и тонких проводников, благодаря им же сделал переходные отверстия. Вообще весь процесс пайки занял 3 вечера.

image

image

Моторы пришлось перенести на нижнюю часть платы, так как понял, что мне нужен максимальный зазор между платой и поверхностью по которой нужно будет ездить, но и все равно робот получился с низкой посадкой.
И раз уж мы вспомнили про моторы, то вспомним и об идее с энкодером, так как магниты, которые я заказывал, были в диаметре буквально на пол миллиметра меньше пазов в колесе, то их нужно было как-то там зафиксировать, а как мы знаем все гениальное просто — я просто взял и загнал их туда, залив при этом из клеевого пистолета, не очень эстетично, зато быстро и практично. Главное не перепутать полярность, а то будут косяки с точностью, а она и так небольшая — 12 магнитов на колесо, т.е. 6 срабатываний за поворот, а с диаметром колес в 43мм получаем примерно 22мм пройденного колесом пути за одно срабатывание.

image

На плате, в свою очередь, с небольшим разносом по высоте поставил датчики Холла, что бы понимать в какую сторону движемся.

image

Для крепления аккумулятора, сервы и УЗ дальномера были распечатаны на 3D принтере простейшие детали.

Держатель аккумулятора.
image

Держатель сервы.
image

Держатель УЗ дальномера.
image

Немного доводки деталей напильником и все встало на свои места, в итоге робот получился вот таким.

image

image

И да, это просто бусина, бусина на толстой проволоке, и это пока единственная нерешенная «проблема» конструкции. На самом деле не брался за решение вопроса о третьем колесе, ибо загорелся подрыгать колесами, повертеть сервой и т.п.
Из за использования 1мм текстолита робот кажется хлюпким, но так как масса у нас небольшая это никак не влияет на его прочность и маневренность.
Ну и первым делом захотелось прокатиться по линии, так сказать первый опыт с автоматизированным управлением.
Сразу скажу, что я не программист по профессии и это наверно моя самая слабая точка в хобби, так что прошу не сильно критиковать код, в любом случае я уверен, что нужно будет переписывать всю программу в будущем.

Была написана тестовая программа, которая реализовывала PD алгоритм. Она состояла из обработчика прерываний АЦП и собственно основного цикла работы с данными.

Обработчик прерывания

#define FIRST_ADC_INPUT 2
#define LAST_ADC_INPUT 7

unsigned int real_adc[8]={0,0,0,0,0,0,0,0};
unsigned char sample_adc;
volatile unsigned char adc_ready = 0;
unsigned char leds[8]={0x21,0x41,0x61,0x63,0x23,0x43};
unsigned char adc_inputs[8]={0,1,2,4,6,7,3,5};

interrupt [ADC_INT] void adc_isr(void) //////////////ADC_INT
{
static unsigned char input_index=0;

if (adc_ready == 0){
if (sample_adc == 0) {
real_adc[input_index]=(signed int)(ADCW);
if (input_index < LAST_ADC_INPUT-FIRST_ADC_INPUT){
input_index++;
} else {
input_index = 0;
PORTB=leds[input_index];
sample_adc = 1;

}
ADMUX=(ADC_VREF_TYPE & 0xff)+adc_inputs[(FIRST_ADC_INPUT+input_index)];
ADCSRA|=0x40;

} else {
if (adc_ready==0) {
if (ADCW > real_adc[input_index]){
real_adc[input_index]=(signed int)(ADCW);
} else {
real_adc[input_index]=(signed int)(real_adc[input_index]);
}

if (input_index < (LAST_ADC_INPUT-FIRST_ADC_INPUT)){
input_index++;
PORTB=leds[input_index];
} else {
input_index = 0;
adc_ready = 1;
PORTB&=~(1<<0);
}

ADMUX=(ADC_VREF_TYPE & 0xff)+adc_inputs[(FIRST_ADC_INPUT+input_index)];

}

if (adc_ready == 0){
ADCSRA|=0x40;
}
}
}
}

Реализация PID

if (adc_ready == 1) {
adc_l = (real_adc[1]+real_adc[2]);
adc_r = (real_adc[3]+real_adc[4]);

error = (adc_l-adc_r);
delta_error = error — old_error;
//sum_error += error;
PID = Kp*error + Kd*delta_error + Ki*sum_error;
old_error = error;

if (PID > 0) {
pwr_l += (signed int)PID;
pwr_r -= (signed int)PID;
} else {
pwr_l += (signed int)PID;
pwr_r -= (signed int)PID;
}

for(i=0; i < (LAST_ADC_INPUT-FIRST_ADC_INPUT)+1; i++){
real_adc[i]=0;
}

ADCSRA |= 0x40;
adc_ready = 0;
sample_adc = 0;
}

Как же я был рад видеть, что робот выполняет возложенную на него функцию, не так конечно как на крутых видеороликах с абсолютно плавными и быстрыми linefolower'ами, но для меня даже такой результат был достижением.

После этого я немного успокоился с частью программирования самого микроконтроллера и понял, что в будущем нужно будет реализовать программу управления роботом с ПК и принялся за изучение Qt, а так как последнюю программу для ПК я писал только в университете (на паскале) и это была какая-то стандартная лабораторная по информатике, то мои знания были в районе нуля.

оффтоп, о моих грандиозных планах управления роботом с смартфона и о том как я сдался и забил на эту идею

Вообще я изначально загорелся желанием написать программу для мобильного телефона на Android, но изучать Java не захотел, вернее не хотел уходить от Си, да и есть у меня друг, который шарил в Qt и у него можно было много чего спросить. Сначала я сам пытался постичь дзен работы с Qbluetooth и попытками состыковаться с HC-05 с помощью моего китайского Jiayu g3, но каждый раз натыкался на проблему, которая не позволяла HC-05 и Jiayu дружить. Сначала грешил на Qbluetooth и тем, что он не воспринимает HC-05, но в интернете нашел информацию о том, что люди запускают обмен данными через линейку блютуз модулей HC с помощью QBluetooth или пишут свои библиотеки, после жалоб другу о своей тяжелой жизни, друг за один день написал программу и все же смог обмениваться данными с роботом, но к сожалению через свой планшет. В итоге обосновав все тем что, мой китаец не поддерживает rfcomm, я сдался и решил писать все для ПК.

Программа должна была переключать режимы работы робота (следование по линии, управление с клавиатуры, автономный режим) и выдавать(задавать) данные со всех интересующих датчиков (сервы, датчики линии, УЗ дальномер, моторы, энкодеры).
После пары недель, была написана первая версия программы контрольной панели управления роботом. Очень понравилась работа с GUI в Qt — удобно.

image

Код программы лучше не буду вставлять, дабы меня не забанили за издевательство над Си. Вкратце скажу, что программа просто по сигналу наличия данных в QSerialPort берет их и рассовывает по лэйблам и виджетам, в ответ по таймеру, если нужно, отправляет задающие данные, такие как положение сервы и скорость моторов. Зеленое поле в программе это в мечтах — будущая карта локации перед роботом.

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

В будущем хочется реализовать грандиозные планы, которые немного стопорятся пониманием того что нужно переделывать обе программы на МК и ПК полностью, так как я сделал большую ошибку и начал писать обе программы как раздутый слоеный пирог где один тестовый модуль соседствует с другим, а не как строгую структурированную систему. Но главное не опускать руки и творить дальше, пока то, что ты задумал в голове не будет реализовано в материальном мире ведь в этом и есть смысл хобби.

П.С. В будущем постараюсь написать еще одну часть публикации, так сказать по мере продвижений в программной части.

Автор: AlexBolm

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js