Машина за управление Arduino. Машина на Arduino: как да направите радио управление със собствените си ръце

Машина за управление Arduino.  Машина на Arduino: как да направите радио управление със собствените си ръце
Машина за управление Arduino. Машина на Arduino: как да направите радио управление със собствените си ръце

Да не купуваме лоши играчки от китайците, а да купим от тях евтин конструктор на шаси, няколко модула и да се сложим на ръце!

Ето какво получих в крайна сметка: проходимо шаси, контролирано - ТА-ДА !!! - от моя смартфон с Android.


"Аз съм прав, аз съм настрани,
С завой и със скок,
И от бягане, и на място,
И два крака заедно ... "

Днес ще сглобим забавна кола с дистанционно управление чрез Bluetooth. Включени са източници на контролната програма за Android.

Достоен пример за играчка

Имам две деца, дъщеря и син. И двамата получават играчки за рождените си дни. Това, което дъщеря ми дава, като правило, не предизвиква моите негативни реакции. И на сина, както се очаква, се дават всякакви коли, танкове и друга техника. От цялата тази китайска бездна, само играчка резачка, която аз самият представих, не предизвиква никакви оплаквания.

Защо така? Вероятно защото този трион се продаваше в магазина за инструменти на STIHL. Смятам, че STIHL са направили играчка аналог на своите продукти в малък рекламен тираж. В резултат на това се роди напълно разумна играчка, много подобна на по-големия си брат. Гумената верига се върти, 80 процента от контролите са изпълнени. Има дори жило с дръжка за навиване на триона, ключ, бутон за газ. Предлага се с резервна верига и инструмент за смяна на верига.


Ето една играчка трион

за какво говоря О, да, архитектура! Имам предвид, че ако желаете, можете да направите страхотна играчка. И има какво да очакваме.

Ние ще направим машина с дистанционно управление!

Радиоуправляемите играчки представляват практически и технически интерес. Въпреки това, на дете на възраст 4-6 години няма да се дават играчки с пропорционално управление "за възрастни". Най-вероятно играчката ще бъде счупена и парите ще бъдат изхвърлени.
В резултат на това те обикновено дават нещо евтино. От всичко това - "евтини" - колите са или много бързи, или спирачки; резервоарите са крехки; и други явни и скрити недостатъци. И със сигурност няма пропорционален контрол.

Един прекрасен ден една от колите спря да върти дясното колело. Демонтиран, проверен мотора - изправен.
На контролната платка има три микросхеми - Китай е голем, не можах да намеря разумна документация. Единият чип е приемник на радиосигнал с логически изходи и два драйвера на мостови двигатели. Един от драйверите е повреден. Не успях да натрупам моторен драйвер за мост от отделни компоненти веднага.

В местния магазин за радиочасти нямаше нищо подходящо. Така че отидох в далечни страни за чудодейни микросхеми. Опаковах вещите си, натъпках джобовете си с крекери, налях си едно кафе, пуснах браузъра и отидох ... .
Намерих драйвер за двигател, подходящ за параметрите, поръчах два наведнъж. За всеки случай, изведнъж някой ще се окаже дефектен или ще се изгоря. Тогава започва да се заражда идеята за неговата пишеща машина. След като пакетът пристигна от славния Китай, успешно смених драйвера и машината беше ремонтирана.

без забавяне в дълга кутияидеята за моята машина, отново се насочих към избора на основата - шасито на бъдещата машина. Шаситата са различни, за сухопътен транспорт: верижни, колесни, с две, три, четири колела и др.

Как избрах шасито

Първо, избрах наземен вид транспорт, което означава, че ще имам наземно шаси. Верижните шасита обикновено са по-скъпи и не много бързи. Дву-триколесните ми се струват лошо проходими, такова шаси може да се движи само по равна повърхност.
Спрях се на . Според мен такова шаси ще има отлична проходимост и скорост.


Включено шаси:
две акрилни плочи с куп технологични отвори за монтиране на всички възможни сензори, контролни платки и други компоненти
4 колела
4 пълни задвижвания (мотор + скоростна кутия)
4 диска с гнезда за датчици за скорост по един за всяко колело
крепежни елементи
Да, пак е Китай. Да, евтино. Да, доста добро качество. НО! Първо бихме искали да го опитаме. В края на краищата „възрастното“ шаси също стои по възрастен начин, все още не сме израснали до него.

Блато от мисли и Техническо задание

Когато държиш нещо обещаващо в ръцете си, например по отношение на възможностите за монтиране на модел с всякакви сензори, серво и т.н., започваш да се давиш в блато от мисли и блато от перспективи. Но нека си кажем – СТОП! И ние ще си направим мини-TOR за прототип с Кратко описаниевсички възли.
Трябва да получим RC модел на наземно превозно средство, управлявано чрез Bluetooth, с възможност за реверс и плавен контрол на скоростта на въртене на колелата.

Какво ни трябва, за да сглобим машината?

.


Няма въртящи се колела, което означава, че управлението ще бъде като на верижен автомобил. Тоест, за движение напред/назад дясната и лявата страна на задвижващите механизми се въртят с еднаква скорост. И за да направите завой, скоростта на въртене на една от страните трябва да бъде по-малка или по-голяма.


За дистанционноИзползваме Bluetooth канала с машината. Модулът "HC-06" е Bluetooth мост, сериен интерфейс, който позволява прехвърляне на данни в двете посоки. На входа - TTL-сигнали на серийния интерфейс "RxD" и "TxD" за връзка с микроконтролера (целева платка).
Ще служи като дистанционно управление клетъчен телефонс android. Нека напишем нашата програма!



Водачът е двуканален, за лява и дясна двойка колела. Драйверът има логически входове за промяна на полярността на изхода (посока на въртене) и PWM вход, ще бъде възможно да се контролира скоростта на въртене.


Тази дъска е избрана, защото лежеше в чекмедже и е напълно подходящ за нашата цел. Има дискретни входове / изходи, извеждат се MK сигнали "RxD" и "TxD", където ще бъде свързан "HC-06".
Гледайки напред, ще кажа, че продуктът Olimex MOD-IO е тежък провал. Ще бъде напълно възможно да приложите обичайния, който ще бъде обсъден в продължението на историята!

Обща сума:шаси + контролна платка + Bluetooth модул + Android програма за управление.

Обща схема на свързване

Не верига в чист вид, а схема на свързване, тъй като всички платки, които имаме, са готови и остава да ги свържем заедно.

Схема в Протей


Няма да описвам какво и къде свързах. Най-вероятно ще имате различен контролен панел. Прилагам изходните кодове, за да можете да редактирате фърмуера. Е, ако някой не може да компилира фърмуера за своята платка, моля да се свърже с мен - ще помогна с колкото имам свободно време.

програма за микроконтролер

Програмата MK може да получава команди чрез сериен интерфейс от Bluetooth модул.
И в съответствие с командите управлявайте лявата и дясната двойка задвижвания. Реверсът и управлението на скоростта работят с ШИМ.

Кодът е добре коментиран. Искам да се спра отделно на моята реализация на обмен на данни.
Внедрил съм приемане на данни чрез пръстен буфер. Нещото не е ново и има много реализации.

Моите функции на буфера за пръстен са преместени в отделна библиотека, състояща се от:
заглавен файл ring_buffer.hи файл за изпълнение на функцията ring_buffer.c
За да използвате библиотеката, трябва да я включите в main.c
#include "ring_buffer.h"

След това, в заглавен файлтрябва да конфигурирате библиотеката. За да конфигурирате, трябва да посочите само четири директиви:
#define RX_PACKET_SIZE 7 // Размер на RxD пакета #define BUFFER_SIZE 16 // Размер на буфера за получаване. Трябва да бъде два пъти RX_PACKET_SIZE #define START_BYTE "s" // Начален байт #define STOP_BYTE "e" // Stop Byte

Всъщност няма какво повече да конфигурирате.

Използване на кодаВ main.c конфигурираме USART на микроконтролера.
Извикване на функцията за настройка на USART
USART_Init(MYUBRR);

#define BAUD 9600 #define MYUBRR F_CPU/16/BAUD-1 void USART_Init(unsigned int ubrr) ( /* Задаване на скорост на предаване */ UBRRH = (unsigned char)(ubrr >> 8); UBRRL = (unsigned char)ubrr; /* Разрешаване на приемник и предавател */ UCSRB = (1<< TXCIE) | (1 << RXCIE)| (1 << TXEN) | (1 << RXEN); /* Set frame format: 8data, 2stop bit */ UCSRC = (1 << URSEL) | (0 << USBS) | (3 << UCSZ0); }

Получаване на пакет данни

Във функцията за обработване на прекъсвания за получаване на байт на USART трябва само да поставим получения байт в пръстенния буфер. Ще анализираме пакета по-късно.
ISR(USART_RXC_vect) ( uint8_t данни = UDR; RB_push_char(данни); // Добавяне на получения байт към пръстенния буфер)
Да, пренебрегнах всички проверки на рамката досега.

Сега остава да проверяваме буфера си от време на време. За да направя това, стартирах таймер, в който зададох флага, за да разреша проверка на буфера за пръстен
ISR(TIMER0_OVF_vect) (TCNT0 = 0x64; ReadRingBuffer = 1; )

В основния цикъл добавяме условие за проверка на флага.
if (ReadRingBuffer) ( if (RB_read_buffer((uint8_t*)&RxPacket) == 1) Четене на буфера ( // Анализирайте пакета, направете нещо) ReadRingBuffer = 0; )

функция RB_четен_буферпроверява пръстенния буфер, ако размерът на пакета, началните и стоп байтовете са на местата си - пакетът се счита за валиден, функцията връща "1". Като аргумент функцията приема указател къде да добави получения пакет.
За по-голяма надеждност пакетът може да бъде снабден с контролна сума, в един от моите търговски проекти направих точно това. Тоест, за да проверите размера, стартирането / спирането на байтовете, се добавя проверка на контролната сума. Но засега нека се справим без него.

Как да разопаковам пакет?

Сега най-интересното е как разглобявам опаковката. Данни, по-големи от байт, данни за знаци, данни с плаваща запетая могат да се предават в пакет.
Ще обясня на примера на пакет за управление на шасито. В допълнение към байтовете за стартиране и спиране, в моя пакет трябва да изпратя една команда и две стойности на ШИМ за лявата и дясната страна на устройствата. За команда един байт ми е достатъчен и за всяка стойност на ШИМ изпращам int16- 16 бита, тип със знак. Тоест, не предавам флаг за посока (байт/функция). За да променя посоката, предавам положителна или отрицателна стойност на ШИМ.

Получаващият пакет е организиран под формата на структура.
struct RxPacket ( uint8_t StartByte; uint8_t команда; int16_t Left_PWM; int16_t Right_PWM; uint8_t StopByte; ) RxPacket;

Извикване на функция RB_read_buffer ((uint8_t*)&RxPacket), като аргумент подаваме указател към структурата на приемащия пакет. Тоест, когато се получи пакет, всичко ще бъде сортирано в собствени рафтове в структурата на RxPacket. След това остава да прочетете тези данни от структурата, например така:
lCmd = RxPacket.Command; lLPWM = RxPacket.Left_PWM; lRPWM = RxPacket.Right_PWM;

Изпращане на пакет данни

Въпреки че трансферът все още не се използва в моята програма, въпреки това възможността за трансфер е реализирана. Прехвърлянето на данни е по-лесно. По същия начин, както при получаването на пакета, нека създадем структура:
struct TxPacket ( uint8_t StartByte; uint8_t Rc5System; uint8_t Rc5Command; uint8_t StopByte; ) TxPacket;

Където има начален и стоп байт и информационна част. Вече сме инициализирали USART приемника.
За да инициираме предаването на пакет, извикваме функцията
void send_packet() ( // Записване на начален байт в UDR регистър UDR = START_BYTE; )
В този пример, в тази функция записвам само началния байт в UDR регистъра. Изглежда не е много, но в същата функция можете да приложите подготовката на пакет или нещо друго полезно. И това според мен е по-логично. Логично е от гледна точка на самодокументиращ се код. Тоест, ако съм в кода, просто записвам стойността в UDR регистъра, това може да се възприеме като прехвърляне само на един байт и извикване на самоговореща функция send_packet()- Говоря за това, че изпращам пакет данни.

Освен това, когато предавателят USART изпрати целия байт от UDR регистъра, ще бъде извикан манипулаторът за прекъсване на предаването.
ISR(USART_TXC_vect) ( unsigned char *Pointer = (unsigned char *)&(TxPacket); статичен unsigned char TxIndex = 1; if (TxIndex< sizeof(TxPacket)) { UDR = *(Pointer + TxIndex); TxIndex++; } else TxIndex = 1; }

В манипулатора декларирам променлива указател и й присвоявам адреса на структурата TxPacket. След това се декларира статична променлива - индексът на предавания байт, на който при деклариране се присвоява стойността 1 . Започваме с един, защото вече сме изпратили първия байт от структурата. По принцип можете да правите без началния байт в структурата, така или иначе, аз го изпращам отделно, но декларацията на този байт остава в структурата, за да разберете как изглежда пакетът.

условие if (TxIndex< sizeof(TxPacket)) проверяет, что индекс меньше чем размер пакета. Если условие верно, то записываем байт в регистр UDR: UDR = *(Pointer + TxIndex);
увеличаване на TxIndex. Когато USART изпрати следващия байт, ние отново ще влезем в манипулатора, но следващият байт от структурата ще бъде прехвърлен и така всички байтове от структурата ще бъдат прехвърлени. Когато TxIndex е по-голям от размера на структурата, условието няма да е вярно и ще завършим в else TxIndex = 1; Когато TxIndex ще бъде инициализиран, но вече нищо не е записано в UDR регистъра, съответно манипулаторът вече няма да бъде извикан, докато не бъде инициирано следващото предаване на пакет. По този начин процесът на прехвърляне е напълно автоматичен и дори да променим структурата на пакета, манипулаторът няма да трябва да се пренаписва.

Като част от описанието на програмата MK, остава да говорим за внедряването на управление на драйвери. Драйверът се управлява от три сигнала: A1 (B1), A2 (B2) и PWMA (PWMB). A1 и A2 са за включване/изключване на драйвера и за промяна на поляритета на изхода. PWM сигнал от MK се прилага към PWMA входа - можете да контролирате скоростта на въртене. За PWM сигнала използвах две хардуерни PWM таймер 1.
#define _WGM13 0 #define _WGM12 1 #define _WGM11 0 #define _WGM10 1 // Таймер 1 init TCCR1A = (1<< COM1A1) | (0 << COM1A0) | (1 << COM1B1) | (0 << COM1B0) | (_WGM11 << WGM11) | (_WGM10 << WGM10); TCCR1B = (0 << CS12) | (0 << CS11) | (1 << CS10) | (_WGM13 << WGM13) | (_WGM12 << WGM12); TCNT1 =0x0000; OCR1A = 0; OCR1B = 0;

Таймерът е 16 бита, но ШИМ се инициализира на 8 бита. И както вероятно вече сте забелязали, в пакета за получаване имам две стойности за настройка на ШИМ, съответно за левия и десния диск. Променливи със 16-битов знак.
Нека обясня защо го направих.

Първо, тръгна от програмата за Android. Факт е, че в Java няма неподписани типове и аз вече стъпих на този рейк. И за да прехвърля число от 0 до 255, ще трябва да се измъкна някак. Реших да измина по-прост начин - изпращам подписано 16-битово число. В същото време 16 бита от подписан тип са от -32786 до 32768, това е достатъчно за нас.

Второ, така че според мен е по-прозрачно - скоростта на въртене и посоката се описват само с една променлива.

И трето, каквото и да се каже, за нашите цели е невъзможно да се спазим в рамките на по-малко от три байта. Нека пожертваме още един байт, но всичко става ясно, положителна стойност на ШИМ е въртене напред, отрицателна стойност е въртене назад.

За да контролирам устройствата, написах функция устройство (int leftPWM, int rightPWM);.
void drive(int leftPWM, int rightPWM) ( // Преместете лявото колело НАПРЕД ако (leftPWM > 0)( ClearBit(A2_PORT, A2_PIN); SetBit(A1_PORT, A1_PIN); ) // Преместете лявото колело НАЗАД ако (leftPWM< 0){ ClearBit(A1_PORT, A1_PIN); SetBit(A2_PORT, A2_PIN); } // Движение ВПЕРЁД правое колесо if (rightPWM >0)( ClearBit(B2_PORT, B2_PIN); SetBit(B1_PORT, B1_PIN); ) // Движение НАЗАД дясно колело if (rightPWM< 0){ ClearBit(B1_PORT, B1_PIN); SetBit(B2_PORT, B2_PIN); } // Остановка if (leftPWM == 0){ ClearBit(A1_PORT, A1_PIN); ClearBit(A2_PORT, A2_PIN); } // Остановка if (rightPWM == 0){ ClearBit(B1_PORT, B1_PIN); ClearBit(B2_PORT, B2_PIN); } set_PWM((uint8_t)(abs(leftPWM)), (uint8_t)(abs(rightPWM))); }
Според стойността на PWM сигналите A1 (B1), A2 (B2) се управляват и стойността на PWM се задава чрез извикване на функцията set_PWM(лява ШИМ, дясна ШИМ).

Фу, поеми дъх...
За да обобщим: получихме пакета, анализирахме го, предадохме стойността на ШИМ на функцията шофиране.

Android приложение за автомобили

Не, няма да анализирам толкова подробно като програма за MK. Все още съм нов в разработването на софтуер за Android и не съм готов да говоря достатъчно компетентно и задълбочено.

Основната функция на програмата- предаване на данни към модула HC-06 чрез Bluetooth. Програмата има неусложнен интерфейс.

По-горе има падащ списък със сдвоени Bluetooth устройства за избор на модул. Първоначално този списък не съществуваше, но до края на работата по статията реших да го направя човешки, защото не всеки ще може да разбере изходните кодове.

След това бутонът "Изключено" - активира / деактивира комуникацията с "HC-06". Долу отляво надясно: предаваната стойност на ШИМ на левия канал, типът на сензора, стойността на десния канал. По-долу има два плъзгача за регулиране на чувствителността на скоростта и завоя.

Програмата реализира два вида управление на машината. За да превключите типа на сензора, трябва да докоснете надписа на името на сензора: "Накланяне" или "Разбъркване".

1. Управлявайте машината, като накланяте телефона си.Нулевата позиция на телефона е хоризонтална. Когато телефонът е наклонен напред, стойността на ШИМ се увеличава пропорционално на наклона, като варира от 0 до 255. Когато телефонът е наклонен назад, стойността на ШИМ намалява пропорционално на наклона в диапазона от 0 до -255


За да завъртите наляво или надясно - трябва да наклоните телефона напред или назад и съответно наляво или надясно. Да, както при истинска кола, докато не настъпите газта, завоят не се извършва.

2. Сензорно управление.Търговското ми наименование на такъв контрол е "разбъркване".


Може да се възприеме като тъчпад. При докосване в сив квадрат стойността на ШИМ се увеличава / намалява в зависимост от мястото на докосване, колкото по-далеч от центъра надолу или нагоре, толкова по-голяма / по-малка е стойността.

Няма "хубави неща" или звънци и свирки. Изглежда това е всичко.

Малко катран върху "ските"

Има задръстване на телефона ми. Да, ски телефонът е LG G2 mini. На него Bluetooth връзката не е установена адекватно. Връзката се установява нормално само ако Bluetooth е бил включен непосредствено преди стартирането на приложението.
Направих така: когато стартирам приложението, проверявам дали Bluetooth е включен, ако е изключен, правя заявка за включване. И когато „сгъвам“, затварям приложението, принудително изключвам Bluetooth.
И още нещо, когато промените ориентацията на екрана, Bluetooth се изключва и се иска да го включите отново, трябва да изключите автоматичното превключване на въртенето на екрана.

Резюме

Мисля, че постигнах целта си! Без много усилия създадох RC модел с разумно пропорционално управление. Машината може да се играе с ентусиазъм дори от възрастен, като прави обратни завои на място, пише сложни пируети, забавя и ускорява, ако е необходимо.
И лесно се поправя, ако се счупи.

Все още има поле за дейност, има място за растеж. Можете да "навиете" шасито, можете да надградите и подобрите софтуера за телефона.
И това ще продължи!

Подробна история за това как машина Arduino е сглобена от три двигателя, управлявани от Android устройство чрез Bluetooth. В няколко десетки параграфа ще се опитам да обясня възможно най-стъпка по стъпка къде да свържа всеки от проводниците, как да напиша собствено приложение и на какъв детски рейк трябваше да скоча повече от седмица.

Малко за нивото, автора и предупрежденията

Аз, авторът, момче на 16-17 години от село близо до Москва, специализирам в писането на приложения за android (и е по-трудно да запиша нещо там), така че поемам отговорност за оптималния подход към решаването на проблеми.

Задача

Най-лесната задача е да накарате колата да се управлява от Arduino и да замените дистанционното управление с android. Но в повечето моменти трябваше да преоткрия колелото, защото в интернет не беше намерено подходящо решение.

Ще взема

  1. Ардуино
  2. Моторен щит (два в моя случай)
  3. Bluetooth
  4. Android
  5. Проводниците са обикновени

Дизайнерска основа

За основа беше взета колата Lego Outdoor Challenger (в действителност изглежда по-малко патетична). Всичко, което е останало от него: корпусът (свалени всички декорации) и три двигателя.

Машината имаше собствена дъска, но една от задачите предполагаше гъвкавост: аз го направих, други могат да го повторят. Извадих мозъка, сложих Arduino Uno.

Инсталация на Arduino

По някаква причина създателите не са предвидили място за Arduino, така че го фиксират на винтове чрез пробиване на пластмасата. Сложих шперплат под дъската, така че нищо да не е късо. По-добре е да пъхнете нещо пластмасово под винтовете (парче от бутилка), защото платката не е защитена от железни болтове.

Веднага сложих два моторни екранирани отгоре на дъската, така че е необходимо. За да контролирате втория, ще трябва да прекарате един проводник от който и да е цифров порт към H1 (посока), а вторият от щифт с подложка (отбелязан с „~“, обикновено 10, 11) към E1 (скорост).

Определяне на ъгъла на завъртане

Изненадващо, не серво задвижване, а обикновен двигател, отговаря за завъртането на машината. Възниква проблем: би било хубаво да не го изгаряте, защото ъгълът на въртене е ограничен и двигателят може да се върти колкото е необходимо.

Методът на мушкане е изключен, тъй като при различни нива на батерията количеството ток, подаван към двигателя, ще се променя, което води до постоянно променящ се ъгъл. Не можете да го завъртите докрай, рано или късно зъбните колела ще се разпаднат.

Решение на проблема: проследяване на ъгъла през затваряне. Снимката показва малко нещо, което е прикрепено близо до въртящия се механизъм. Гребен с железни контакти е прикрепен към частта, която се върти с колелата наляво/надясно от двигателя.

Принцип на работа: към всяка линия е запоен проводник (общо са четири), долният е свързан към плюса (винаги се затяга с гребен, вижте снимката), останалите проводници отиват към минуса . Когато зъбът на гребена удари и долния ред, и да речем третия ред, възниква късо съединение, тече ток, това се забелязва от Arduino.

Благодарение на различните комбинации от трите ивици могат да бъдат дефинирани до седем ъгъла. Например, когато има ток по всички линии, колелата се въртят в крайна дясна позиция, когато има ток само отгоре, колелата се въртят максимално наляво. Таблицата показва всички опции.

Ъглова връзка и код

За всяко ниво е избран различен цвят: долният е зелен, първият отдолу е червен, вторият е черен, третият е бял. В началния етап бяха използвани макет и светодиоди за визуално отстраняване на грешки.

Схемата на свързване е показана на фигурата. Плюс дърпаме до зелено, останалите разтягаме до минус. Чрез резистор, инсталиран за елиминиране на смущения и липса на късо съединение, свързваме проводниците към изходите A0-A2. Те се избират просто от запазването на останалите портове.

Кодът е даден с коментари. Свързваме щифтовете и ги анкетираме чрез digitarRead(). Ако има напрежение, ще бъде върнато true. След това гледаме, ако резултатът означава, че колелата са в крайни позиции, забраняваме по-нататъшно въртене в тази посока.

Малък трик: тъй като в бъдеще ще са необходими изходи 5V и 3.3V, можете да поставите плюс на един от цифровите щифтове. Преди всяка проверка на ъгъл, изведете ток през digitalWrite(whitePin), след това проверете ъгъла и премахнете тока.

int speedTurn = 180; // скорост на завъртане, от 0 до 255 // пинове за определяне на завоя int pinRed = A0; int pinWhite = A1; int pin Черен = A2; int pinAngleStop = 12; //извежда ток към светодиода, ако е достигнат максималният ъгъл, необходим //само за отстраняване на грешки void setup() ( //завъртане на щифтове за четене pinMode(pinRed, INPUT); pinMode(pinBlack, INPUT); pinMode(pinWhite, INPUT); //LED pinMode(pinAngleStop, OUTPUT); //пинове на драйвера на двигателя, посока и скорост pinMode(angleDirection, OUTPUT); pinMode(angleSpeed, OUTPUT); Serial.begin(9600); ) //функция, извикана от цикъл (), когато команда идва от android void turn(int angle) ( digitalWrite(pinAngleStop, HIGH); //подайте ток на проводника, свързан към плюса delay(5); //изчакайте малко токът да "има време" за достигане на if(angle > 149 ) ( if(digitalRead(pinWhite) == HIGH && digitalRead(pinBlack) == LOW && digitalRead(pinBlack) == LOW) ( //ако е достигната крайната дясна позиция, излезте от функция без прилагане на ток, за да се избегне //изгаряне на връщането на двигателя; ) //ако ъгълът не е максимален, завъртете digitalWrite(angleDirection, HIGH); analogWrite(angleSpeed, speedTurn); ) else if (angle< 31) { if(digitalRead(pinRed) == HIGH && digitalRead(pinBlack) == HIGH && digitalRead(pinWhite) == HIGH) { //если достигнуто крайне левого положение, выйти из функции не подавая ток, чтобы не //сжечь мотор return; } //если угол не максимальный, поворачиваем digitalWrite(angleDirection, LOW); analogWrite(angleSpeed, speedTurn); } digitalWrite(pinAngleStop, LOW); //убираем ток с определителя угла delay(5); }

Паралелизиране на ходовите колела

Първоначално два задвижващи двигателя са свързани заедно. Изключих ги по две причини: завиването е по-ефективно, ако колелата се въртят в различни посоки и два мощни двигателя не могат да бъдат извадени от една дъска.

Проблем: Екранът на двигателя има два изхода, всеки от които извежда до 2 ампера. Всеки двигател яде 0,7А. Изглежда по-малко, но не при максимални натоварвания. Да предположим, че машината е заседнала в пясъка или е в покой, токът се увеличава над ампера. Не критично, но потенциално опасно.

Но се оказа критично, че платката се нагрява. Минута и половина след състезанието моторният щит загря и започна да работи безобразно: токовете не бяха същите, колелата не се въртяха и т.н.

Решението и на двата проблема: един мотор, свързан към един моторен щит, вторият към другия. Колкото и да е странно, помогна. Температурата е паднала, няма прегряване. Можеше да се сложи радиатор, но трудно се оправя.

Bluetooth връзка

Използвах модела HC-05, което ми изигра фатална шега. Всички bluetooth са свързани по същия начин: един проводник за 3.3V (понякога започва да работи само от 5V), вторият за минус, още два за порт 0 и 1 (съответно четене и изпращане). Кабелът, подписан с RXD на bluetooth, е включен в arduino TXD, а TXD в RXD (ако го смесите, няма да видите данните).

Има едно предупреждение: портове 0 и 1 се използват по подразбиране от Serial, през който се качва скицата. Тоест, докато блутутът е включен, скицата няма да бъде качена. Има два изхода: премахнете bluetooth за времето на запълване или преназначете входовете и изходите на bluetooth. Вторият вариант се изпълнява в два реда

#включи \\SoftwareSerial библиотека връзка BTSerial(8, 9); \\ настройка на щифтове 8 и 9 вместо 0 и 1
Клопката, която изяде трите ми дни работа, е скоростта на комуникация. По навик инсталирах 9600 и отидох да пробвам. Или данните не идваха, тогава имаше бъркотия от знаци. И в крайна сметка отговорът е - моделът HC-05 комуникира на 38400! Забележете много силно, че в Setup() ще изпълня BTSerial.begin(39400), въпреки че Serial.begin(9600).

Система за изпращане на команди

Статията става твърде дълга, така че ще отделя разглеждането на кода на Arduino и Android в отделна втора част, а сега ще опиша принципа.

Android устройството има джойстик (кръг, чието изпълнение също е във втората част). Android чете показанията от него и ги преобразува в числа, подходящи за arduino: превръща скоростта от пиксели в стойност от -255 до 255 (отрицателна - обратна), а също така определя ъгъла. Съзнателно дадох тази задача на телефона, тъй като той е много по-мощен и може лесно да се справи с броенето на няколкостотин стойности в секунда.

След установяване на сокета, данните се изпращат в следния формат: @скорост#*ъгъл#. @ - показва, че следващите цифри съдържат скорост, # - уведомява за края на стойността на скоростта, * - началото на стойността на ъгъла, # - край на записа на ъгъла. Цикълът е безкраен, командите се изпращат на всеки 100 милисекунди (цифрата е оптимална). Ако нищо не се натисне на android, тогава нищо не се изпраща.

Алгоритъмът за получаване на данни е описан подробно в кода на скицата. Той кореспондира повече от веднъж и, що се отнася до мен, работи перфектно.

Заключение на първата част

В тази статия се опитах да разкрия всичко свързано с физическата част на машината. Най-вероятно съм пропуснал нещо, така че не забравяйте да попитате.

Но най-интересното, за мен, остава за второто - програмата Arduino и приложението за Android, там се случва истинска магия, поне за мен млада.

Ако не намерите отговора на някоя част и искате лично да ме бръкнете в недостатъците, чакам - [имейл защитен], .

UPD: втората част вече е излязла -

В статията ще разгледаме свързването и управлението на Arduino чрез bluetooth.

Широко разпространеният hc-06 ще се използва като bluetooth модул.

В нашия проект ще включваме и изключваме светодиода, свързан към порт 13 чрез bluetooth.

Нека започнем с написването на приложение за Android смартфон. Приложението ще бъде написано в удобна и проста среда за програмиране App Inventor. Програмите ще бъдат компилирани онлайн.

Следвайте връзката http://ai2.appinventor.mit.edu/. Там ще бъдете помолени да влезете в акаунт в Google, който ще трябва да създадете, ако все още нямате такъв.

След като влезете, ще бъдете отведени до програмата, където можете да създадете проект, като щракнете върху „стартиране на нов проект“. Ще трябва да въведете име на проект. Нека го наречем led_control.

Ще се отвори празен прозорец на приложението.

Тук ще поставим необходимите компоненти. Изберете ListPicker в прозореца вляво и го поставете в проекта.

За компонента ListPicker в прозореца вдясно намерете свойството Text и променете „Text for ListPicker1“ на „Select BT Device“.

Отворете раздела Layout в прозореца отляво, поставете компонент HorizontalArrangement в приложението, променете свойството му Width на „Fill parent“. Добавете 2 бутона към HorizontalArrangement, като всеки от тях зададе свойството Width на „Fill parent“. Трябва да се получи така:

Нека променим етикетите на бутоните: първият ще бъде написан LED ON, вторият - LED OFF.

По-долу добавяме етикет и изчистваме неговия текст.

Остава да добавите компонент, който организира пренос на данни чрез bluetooth. Отворете раздела Свързване и го поставете в проекта BluetoothClient. Този компонент няма да бъде на екрана на телефона, а под него, т.к. не е визуално.

Сега можете да започнете да пишете програмата. В горната дясна част на програмата изберете режим Блокове.

Тук програмата ще бъде компилирана от графични блокове. Кликнете върху компонента ListPicker1 отляво и изберете ListPicker1.BeforePicking.

Щракнете отново върху ListPicker1 и изберете set ListPicker1.Elements to

Поставете го като на екранната снимка.

Това ни дава списък със сдвоени bluetooth устройства. Сега нека се свържем с избраното устройство. Напишете блок като на екранната снимка по-долу.

Розовото поле с етикет Свързан е първото поле в раздела Текст. Въведете Connected в празното поле.

Сега нека напишем манипулатора на бутоните. Щракването върху първия бутон ще изпрати текста „led_on“, а щракването върху втория бутон ще изпрати текста „led_off“. Надписът в Label1 също ще се промени.

Остава да изтеглите проекта на вашия смартфон. Щракнете върху Създаване и изберете метод за изтегляне.

За първия вариант ще ви е необходим интернет и четец на QR кодове. Щракнете и изчакайте сглобяването на проекта да завърши и QR кодът да бъде генериран, след това отворете четеца на QR код на вашия смартфон и прочетете кода. Остава само да изтеглите и инсталирате файла.

Във втория вариант проектът във формат .apk ще бъде записан на вашия компютър и можете да го изтеглите на вашия смартфон по всеки удобен начин (например чрез USB).

Сега нека започнем с програмата Arduino.

Приемането и предаването на данни се извършва през COM порта, така че ще използваме Serial. Ще получаваме сигнали символ по символ, ще формираме низ и след това ще сравняваме генерирания низ с командите led_on и led_off.

Ардуино

Stringval = ""; void setup() ( Serial.begin(9600); pinMode(13, OUTPUT); ) void loop() ( while (Serial.available()) ( //докато идват данни char c = Serial.read(); / / прочете ги val += c; //и формира низ delay(3); ) if (val != "") ( Serial.println(val); ) if (val == "led_on") ( digitalWrite(13 , HIGH ); ) else if (val == "led_off") ( digitalWrite(13, LOW); ) val = ""; )

String val = "";

void setup()(

Сериен. начало (9600);

pinMode(13, ИЗХОД) ;

void loop()(

докато (Сериен . наличен () ) ( // докато данните идват

char c = Сериен. Прочети(); //прочетете ги

val += c ; //и образуват низ

забавяне (3);

}

Качване на код в Arduino.

Сега можете да свържете Bluetooth модула HC-06. Свързва се много просто:

Vcc 5v (може да бъде 3.3v)

АКО СЕ ОПИТВАТЕ ДА КАЧИТЕ ПРОГРАМАТА В ARDUINO СЪС СВЪРЗАН МОДУЛ, ТОГАВА ЩЕ СЕ ПОЯВИ ГРЕШКАТА, Т.К. КАКТО МОДУЛЪТ, И ИЗТЕГЛЯНЕТО НА СОФТУЕР ИЗПОЛЗВАТ RX И TX ПОРТОВЕ!

Включете Arduino. Светодиодът на bluetooth модула трябва да мига, което означава, че той чака връзка. Вземете смартфон, намерете bluetooth в настройките, включете го и започнете търсенето. Намерете устройство с име hc-06 и се свържете с него. Може да не работи от първия път. След едно успешно сдвояване можете да стартирате програмата на вашия смартфон.

Първо щракнете върху „Избор на BT устройство“ и изберете модула от сдвоените устройства. След това натиснете бутоните за включване и изключване на светодиода. Ако всичко е направено правилно, тогава всичко ще работи.

Направихме много просто приложение с помощта на Bluetooth, без никакъв дизайн или дори проверка дали сме свързани към модула или не. В следващите уроци ще създаваме по-сложни приложения и ще се запознаем по-добре с App Inventor.

Много често във вашите проекти има нужда от дистанционно управление или пренос на данни от джаджите на вашия телефон.

Един от най-популярните и разпространени методи за обмен на данни чрез Bluetooth .

Днес ще анализираме прости примери за това как можете да свържете Bluetooth. модул към Arduino и настройте дистанционно управление от вашия телефон.

Ще ни трябва:

  • Комплект проводници БАЩА-МАМА
  • HC-06 Bluetooth

Свържете Bluetooth модулът към микроконтролера Arduino най-удобно използва окабеляването PAPA-MAMA.

Ардуино Bluetooth
Пин 1 (TX) RXD
Пин 0 (RX) TXD
GND GND
5V VCC

Внимавайте, трябва да се свържете TX -> RXD ,RX -> TXD .

Сега трябва да напишете тестов програмен код:

При качване на скицата е необходимо Bluetooth модулът да е изключен от микроконтролера arduino. В противен случай скицата няма да бъде записана, тъй като връзката с Bluetooth модул се появява на същия RX и TX порт като USB.

intval; int LED = 13; void setup() ( Serial.begin(9600); pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); ) void loop() ( if (Serial.available()) ( val = Serial.read(); / / При знака "1" включете светодиода if (val == "1") ( digitalWrite(LED, HIGH); ) // При знака "0" изключете светодиода if (val == "0") ( digitalWrite(LED, LOW ); ) ) )

След скицата се записва и Bluetooth модулът е свързан към Arduino, можете да продължите към следващата стъпка.

Bluetooth връзка към телефона

Препоръчително е да използвате не USB като източник на захранване за arduino, а външно 9 V захранване.

  1. Включете Bluetooth на телефона си и потърсете нови устройства
  2. Намираме в списъка с разстройства " HC-06" и се свържете с него.
  3. Телефонът ще поиска пин код. трябва да въведете " 1234 " или " 0000 "
  4. Ура. Устройството е свързано.

Сега трябва да изтеглите bluetooth терминала на телефона си. Ще разгледаме примера на платформата Android.



Можете да инсталирате различни bluetooth терминали, като правило те се различават само в различни дизайни, функционалността не се променя от това. Можете също така да намерите терминал за ios продукти.

След като инсталираме терминала, стартираме го, избираме нашия bluetooth модул HC-06 и се свързваме с него.

Време е да изпробвате проекта в действие. Пишем числото "0" в терминала и изпращаме. Светодиодът L до пин 13 на платката arduino трябва да се изключи. Сега ще изпратим числото "1" през терминала и светодиодът L трябва да светне.

Работна демонстрация:


Домашна работа:

  • Променете скицата, така че светодиодът да се включва и изключва с една и съща команда, например "G".
  • Добавете скица и го научете как да конвертира текстови данни, идващи през bluetooth, в цифрови данни и да внедри димер, включете светодиода с помощта на PWM, до дадена яркост от 0 до 254, идваща през bluetooth.

Широкото разпространение и ниска цена на платформата Arduino и различни роботизирани платформи позволиха на любителите да създават радиоуправляеми коли за всеки вкус. А широкото разпространение на смартфоните направи възможно използването им като контролери за тези машини. Основният проблем за много ентусиасти на Arduino е липсата на опит в програмирането на Android. Днес ще ви кажа как лесно да разрешите този проблем с помощта на средата за визуална разработка App Inventor 2 за Android приложения.



Конструкцията на всяка пишеща машина трябва да започне с хардуер, така че ще опиша накратко какво използвах за моята пишеща машина:
ардуино нано
bluetooth модул HC-05
Z-Mini Motor Sensor Shield L293D
2WD моторно шаси
Хардуерната конфигурация не играе голяма роля в този проект, така че шасито, щитът и самият arduino могат да бъдат заменени с всякакви аналози.

Сега нека да преминем към създаването на приложение за Android. App Inventor е визуална среда за разработка на Android приложения, която работи от браузър. Отиваме на сайта, разрешаваме достъп до вашия акаунт в Google, натискаме бутона „създаване“ и създаваме нов проект. В новия проект по метода "Drag and Drop" създаваме 4 бутона за избор на посоката на движение и един за свързване с нашия bluetooth модул. така:

Сега остава да компилирате приложението, като кликнете върху бутона "Изграждане".

Мисля, че феновете на Arduino няма да имат проблеми с написването на скица, мога само да кажа, че можете да избирате от готови скици, където машината се управлява от компютър през sireal порт. Използвах това

скица

int стойност;
int IN1 = 4;
int IN2 = 7;
int EN1 = 6;
int EN2 = 5;

Празна настройка()
{
Serial.begin(9600);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(EN1, ИЗХОД);
pinMode(EN2, ИЗХОД);

}
void loop()
{
if(Serial.available())
{
val = Serial.read();

// Задайте движение напред
if (val == "W") // Когато се натисне клавишът "W".
{
// Пиновете се конфигурират според работата на Motor Shield
// Двигателите се въртят напред
digitalWrite(EN1, HIGH);
digitalWrite(EN2, HIGH);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH);
}

// Възстановяване на движението
ако (val == "S")
{
digitalWrite(EN1, HIGH);
digitalWrite(EN2, HIGH);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}

// Задайте движение надясно
ако (val == "D")
{
digitalWrite(EN1, HIGH);
digitalWrite(EN2, HIGH);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
}

// Задайте движение наляво
ако (val == "A")
{
digitalWrite(EN1, HIGH);
digitalWrite(EN2, HIGH);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
}

// Режим на спиране
// Когато ключовете се освободят в програмата, "T" се изпраща към порта
if (val == "T") // При натискане на клавиша "T".
{
// РАЗРЕШАВАНЕ на щифтове, изтеглени отрицателно, двигателите не работят
digitalWrite(EN1, LOW);
digitalWrite(EN2, LOW);
}
}
}


И така, ето как изглежда моята машина:

Тези, които харесват дизайна в приложенията, могат да променят малко. Няма да описвам подробно как да направите това, не е трудно да го разберете сами. Нека само да кажа, че за това основно трябва да използвате .png файлове вместо .jpeg, които не поддържат прозрачен фон. Например всеки неподготвен човек може да направи такъв дизайн за половин или час:

P.S. За тези, които не са имали опит с разработката на приложения в App Inventor 2, направих по-подробно ръководство за разработката на това приложение (трябва да отидете в YouTube, за да го видите).

P.P.S. Колекция от над 100 уроци по arduino за начинаещи и професионалисти