В этом уроке мы научимся создавать робота на колесах Arduino Mecanum, способного двигаться в любом направлении. Эта уникальная мобильность робота достигается за счет использования колес специального типа, называемых Mecanum Wheels. Их можно как приобрести в готовом виде, так и напечатать на 3D-принтере.
Обзор проекта
Я на самом деле спроектировал и напечатал эти колеса на 3D-принтере, потому что их покупка может оказаться немного дорогой. Они работают довольно хорошо, и я должен сказать, что управлять этой роботизированной платформой очень весело. Мы можем управлять роботом по беспроводной сети, используя модули радиопередатчика NRF24L01, или, в моем случае, я использую свой RC-передатчик (пульт ДУ), который я сделал в одном из своих предыдущих проектов.
Также я сделал возможным управление с помощью смартфона через Bluetooth-связь. Я сделал специальное приложение для Android, с помощью которого мы можем управлять роботом Mecanum на колесах, чтобы он двигался в любом направлении. Также с помощью ползунка в приложении мы можем контролировать скорость передвижения.
Мозгом этой роботизированной платформы является плата Arduino Mega, которая управляет каждым колесом индивидуально. Каждое колесо прикреплено к шаговому двигателю NEMA 17, и я добавил в приложение еще одну интересную функцию, с помощью которой мы можем запрограммировать робота на автоматическое движение. С помощью кнопки «Сохранить» мы можем сохранить каждую позицию или шаг, а затем робот сможет автоматически запускать и повторять эти шаги. С помощью той же кнопки мы можем приостановить автоматическую операцию, а также сбросить или удалить все шаги, чтобы сохранить новые.
Необходимые компоненты
- Плата Arduino Mega 2560 (купить на AliExpress).
- Bluetooth модуль HC-05 (купить на AliExpress).
- Модуль nRF24L01 (купить на AliExpress).
- Шаговый двигатель NEMA 17 (купить на AliExpress).
- DRV8825 или A4988 Stepper Driver Module (модуль драйвера шагового двигателя) (купить на AliExpress).
- Li-Po аккумулятор.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
3D модель робота
Для начала я спроектировал этого робота Mecanum с помощью программного обеспечения для 3D-моделирования. Базовая платформа этого робота представляет собой простую коробку, которую я сделаю из плит МДФ толщиной 8 мм.
К этой платформе прикреплены четыре шаговых двигателя, а колеса Mecanum прикреплены к валам двигателя.
Вы можете получить эту 3D-модель, а также файлы STL для 3D-печати на сайте Cults3D.
Как работают колеса Mecanum
Колесо Mecanum представляет собой колесо с роликами, прикрепленными по его окружности. Эти ролики расположены по диагонали или под углом 45 градусов к оси вращения колеса. Это заставляет колесо прилагать силу в диагональном направлении при движении вперед или назад.
Итак, вращая колеса по определенному шаблону, мы используем эти диагональные силы, и, таким образом, робот может двигаться в любом направлении.
Здесь также следует отметить, что нам нужны два типа колес Mecanum, часто называемые левосторонними и правосторонними колесами Mecanum. Разница между ними заключается в ориентации роликов и их необходимо устанавливать в роботе в определенных местах. Ось вращения верхнего ролика каждого колеса должна указывать на центр робота.
Вот краткая демонстрация того, как робот движется в зависимости от направления вращения колес.
Если все четыре колеса движутся вперед, результирующее движение робота будет вперед, и наоборот, если все колеса движутся назад, робот будет двигаться назад. Для движения вправо правые колеса должны вращаться внутри робота, а левые колеса должны вращаться снаружи робота. Результирующая сила, возникающая из-за диагонально расположенных роликов, заставит робота двигаться вправо. То же самое, но наоборот, происходит при движении влево. С помощью этих колес мы также можем добиться движения в диагональном направлении, вращая только два колеса.
Изготовление робота Mecanum
Тем не менее, теперь позвольте мне показать вам, как я построил эту роботизированную платформу. Как я уже упоминал, для изготовления основания платформы я использую плиты МДФ толщиной 8 мм. Используя настольную пилу, сначала я вырезал все детали по размерам 3D-модели.
Затем с помощью сверла диаметром 3 мм и сверла Форстнера диаметром 25 мм я сделал отверстия на боковых панелях для крепления шаговых двигателей. Когда детали были готовы, я продолжил их сборку. Для их крепления я использовал клей для дерева и несколько шурупов. Самое главное здесь — точно сделать отверстия для двигателей, чтобы в дальнейшем все колеса равномерно соприкасались с поверхностью.
Конечно, вы также можете напечатать эту базовую платформу на 3D-принтере вместо того, чтобы делать ее из МДФ, поэтому я включу ее 3D-файл в статью на веб-сайте. Наконец, я покрасил основу и крышку из баллончика белым цветом.
Далее идут колеса Mecanum. Как я уже говорил ранее, эти колеса могут стоить достаточно дорого, поэтому я решил спроектировать и напечатать свои собственные на 3D-принтере. Колеса состоят из двух частей: внешней и внутренней, которые скреплены между собой болтами и гайками М4. Они имеют по 10 роликов каждый и муфту вала, специально разработанную для шагового двигателя NEMA 17.
Я распечатал все детали колес Mecanum на своем 3D-принтере Creality CR-10.
Итак, как только я подготовил детали, напечатанные на 3D-принтере, я приступил к изготовлению валов для роликов. Для этого я использовал стальную проволоку толщиной 3 мм. Длина стержней должна составлять около 40 мм, поэтому с помощью вращающегося инструмента я обрезал проволоку до этой длины.
Я начал сборку колеса Mecanum с закрепления двух сторон и муфты вала четырьмя болтами M4 и гайками. Длина болтов должна составлять 45 мм.
Для установки роликов сначала нам нужно слегка вставить вал через отверстия, расположенные по окружности внутренней стороны.
Затем мы можем вставить небольшую шайбу М3, вставить ролик и вставить вал до упора в прорезь на внешней стороне колеса. Я использовал одну шайбу, потому что у меня не было достаточно места, чтобы вставить вторую шайбу с другой стороны.
Я повторил этот процесс для всех 10 роликов. На самом деле собирать эти колеса легко и весело. Здесь важно то, что ролики должны иметь возможность свободно перемещаться.
В конце я нанес несколько капель клея в каждое из внутренних отверстий, чтобы убедиться, что валы не расшатываются.
Итак, когда колеса готовы, мы можем перейти к сборке всего робота. Сначала нам нужно прикрепить шаговые двигатели к базовой платформе. Для их фиксации я использовал болты М3 длиной 12 мм.
Далее нам нужно прикрепить колеса к валам двигателя. Соединитель вала, который я сделал, имеет прорезь для вставки гайки М3, через которую могут пройти болты М3 и таким образом мы можем закрепить колесо на валу.
Далее, для крепления верхней крышки к основанию, я прикрепил стержни с резьбой по двум углам основания. Я проделал отверстия в том же месте на крышке, чтобы мне было легко вставить и прикрепить крышку к основанию.
На задней стороне основания я сделал отверстие диаметром 20 мм для последующего крепления выключателя питания, а также отверстие диаметром 5 мм для крепления светодиода.
Принципиальная электрическая схема робота
Теперь можно перейти к электронике. Вот полная принципиальная схема этого проекта.
Итак, мы будем управлять четырьмя шаговыми двигателями NEMA 17, используя четыре шаговых драйвера DRV8825, или мы также можем использовать шаговые драйверы A4988. Для питания шаговых двигателей и всего робота мы будем использовать источник питания 12 В, а в моем случае я буду использовать литий-полимерную батарею 3S, которая обеспечивает напряжение около 12 В. Для радиосвязи мы используем модуль NRF24L01 , а для связи Bluetooth — модуль Bluetooth HC-05. Я также включил простой делитель напряжения, который будет использоваться для контроля напряжения батареи, и подключение светодиода для индикации, когда напряжение батареи упадет ниже 11 В.
Я также включил специальный стабилизатор напряжения 5 В, который может обеспечить ток около 3 А. Это необязательно, но в будущем видео я планирую объединить этот проект с моим проектом Arduino Robot Arm, и для этой цели мне понадобится напряжение 5 В для управления его серводвигателями.
Проектирование печатной платы для проекта
Тем не менее, чтобы сохранить порядок в электронных компонентах и избежать беспорядка в проводке, я спроектировал специальную печатную плату с помощью бесплатной онлайн-программы для проектирования схем EasyEDA. Эта печатная плата фактически будет действовать как экран Arduino MEGA, поскольку мы сможем напрямую подключить ее поверх платы Arduino Mega. Для выполнения соединений я использовал как верхний, так и нижний слой. Для тех контактов Arduno, которые я не использовал, я включил соединения с разъемами контактов, чтобы они были доступны на случай, если мы захотим использовать их для чего-нибудь в будущем. Я также включил контакты подключения 12 В, 5 В и GND, а также контакты для выбора шагового разрешения драйверов.
Вот ссылка на файлы проекта этой печатной платы. Итак, закончив проектирование, я создал файл Gerber, необходимый для изготовления печатной платы.
Заказать изготовление печатной платы вы можете в любом месте где вам это удобно. Автор проекта заказывал изготовление плат на сервисе JLCPCB и через несколько дней ему прибыли печатные платы. Качество печатных плат отличное, все точно так же, как и в дизайне.
Сборка печатной платы
Хорошо, теперь мы можем двигаться дальше и собирать печатную плату. Сначала я начал с пайки более мелких компонентов: резисторов и конденсаторов. Затем я вставил и припаял штыревые разъемы к печатной плате, которые будут использоваться для подключения к плате Arduino.
Затем я установил все гнездовые разъемы на место и также припаял их. Что касается соединений шаговых двигателей и контактов для выбора шагового разрешения, я использовал штыревые разъемы. Таким образом, мы можем напрямую подключить двигатели к печатной плате и использовать перемычки для выбора разрешения шага. Затем припаял клеммники, подстроечный резистор и стабилизатор напряжения.
И всё, печатная плата готова и можно переходить к вставке драйверов и подключению к ней моторов. Сначала я поставил перемычки для выбора разрешения шага. Я выбрал 16-ступенчатое разрешение, подключив контакты MS3 драйверов к 5 В.
Затем поверх них я разместил драйвера DRV8825, а также подключил модуль NRF24L01 и модуль Bluetooth HC-05. Теперь мы можем просто прикрепить печатную плату к плате Arduno.
Затем я подключил аккумулятор к соответствующему клеммному блоку и поместил их в базовую платформу.
Здесь я вставил выключатель питания на место и подключил его к другой клеммной колодке. Прямо над выключателем питания я также вставил светодиодный индикатор заряда батареи.
Теперь осталось подключить двигатели к печатной плате. Здесь следует отметить, что при подключении противоположных двигателей следует также подключать их разъемы противоположно. Это понадобится позже при программировании робота, чтобы, например, команда вперед перемещала оба двигателя в одном направлении, хотя на самом деле они перевернуты и один вращался по часовой стрелке, а другой против часовой стрелки.
В конце я могу просто вставить крышку сверху, и вот мы закончили сборку нашего робота.
Код Arduino для робота Mecanum
Теперь осталось только взглянуть на код Arduino. На самом деле существует два отдельных кода Arduino. Этот код предназначен для управления роботом с помощью модулей NRF24L01, а другой — для управления роботом с помощью смартфона.
Код Arduino для управления роботом с помощью модулей NRF24L01
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
/* === Arduino Mecanum Wheels Robot === Radio control with NRF24L01 by Dejan, www.HowToMechatronics.com Libraries: RF24, https://github.com/tmrh20/RF24/ AccelStepper by Mike McCauley: http://www.airspayce.com/mikem/arduino/AccelStepper/index.html */ #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <AccelStepper.h> RF24 radio(48, 49); // nRF24L01 (CE, CSN) const byte address[6] = "00001"; unsigned long lastReceiveTime = 0; unsigned long currentTime = 0; // Define the stepper motors and the pins the will use AccelStepper LeftBackWheel(1, 42, 43); // (Type:driver, STEP, DIR) - Stepper1 AccelStepper LeftFrontWheel(1, 40, 41); // Stepper2 AccelStepper RightBackWheel(1, 44, 45); // Stepper3 AccelStepper RightFrontWheel(1, 46, 47); // Stepper4 int wheelSpeed = 1500; // Max size of this struct is 32 bytes - NRF24L01 buffer limit struct Data_Package { byte j1PotX; byte j1PotY; byte j1Button; byte j2PotX; byte j2PotY; byte j2Button; byte pot1; byte pot2; byte tSwitch1; byte tSwitch2; byte button1; byte button2; byte button3; byte button4; }; Data_Package data; //Create a variable with the above structure void setup() { // Set initial seed values for the steppers LeftFrontWheel.setMaxSpeed(3000); LeftBackWheel.setMaxSpeed(3000); RightFrontWheel.setMaxSpeed(3000); RightBackWheel.setMaxSpeed(3000); radio.begin(); radio.openReadingPipe(0, address); radio.setAutoAck(false); radio.setDataRate(RF24_250KBPS); radio.setPALevel(RF24_PA_LOW); radio.startListening(); // Set the module as receiver Serial.begin(115200); } void loop() { // Check whether we keep receving data, or we have a connection between the two modules currentTime = millis(); if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone jas a throttle up, if we lose connection it can keep flying away if we dont reset the function } // Check whether there is data to be received if (radio.available()) { radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure lastReceiveTime = millis(); // At this moment we have received the data } // Set speed - left potentiometer wheelSpeed = map(data.pot1, 0, 255, 100, 3000); if (data.j1PotX > 150) { moveSidewaysLeft(); } else if (data.j1PotX < 100) { moveSidewaysRight(); } else if (data.j1PotY > 160) { moveForward(); } else if (data.j1PotY < 100) { moveBackward(); } else if (data.j2PotX < 100 & data.j2PotY > 160) { moveRightForward(); } else if (data.j2PotX > 160 & data.j2PotY > 160) { moveLeftForward(); } else if (data.j2PotX < 100 & data.j2PotY < 100) { moveRightBackward(); } else if (data.j2PotX > 160 & data.j2PotY < 100) { moveLeftBackward(); } else if (data.j2PotX < 100) { rotateRight(); } else if (data.j2PotX > 150) { rotateLeft(); } else { stopMoving(); } // Execute the steps LeftFrontWheel.runSpeed(); LeftBackWheel.runSpeed(); RightFrontWheel.runSpeed(); RightBackWheel.runSpeed(); // Monitor the battery voltage int sensorValue = analogRead(A0); float voltage = sensorValue * (5.0 / 1023.00) * 3; // Convert the reading values from 5v to suitable 12V i // If voltage is below 11V turn on the LED if (voltage < 11) { digitalWrite(led, HIGH); } else { digitalWrite(led, LOW); } } void moveForward() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void moveBackward() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void moveSidewaysRight() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void moveSidewaysLeft() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void rotateLeft() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void rotateRight() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void moveRightForward() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(wheelSpeed); } void moveRightBackward() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(0); } void moveLeftForward() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(0); } void moveLeftBackward() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(-wheelSpeed); } void stopMoving() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(0); } void resetData() { // Reset the values when there is no radio connection - Set initial default values data.j1PotX = 127; data.j1PotY = 127; data.j2PotX = 127; data.j2PotY = 127; data.j1Button = 1; data.j2Button = 1; data.pot1 = 1; data.pot2 = 1; data.tSwitch1 = 1; data.tSwitch2 = 1; data.button1 = 1; data.button2 = 1; data.button3 = 1; data.button4 = 1; } |
Описание: Итак, здесь мы используем библиотеку RF24 для радиосвязи и библиотеку AccelStepper для управления шаговыми двигателями. Сначала нам нужно определить контакты, к которым все они подключены, определить некоторые переменные, необходимые для программы ниже, а в разделе настройки установить максимальную скорость шаговых двигателей и начать радиосвязь.
В разделе цикла мы начинаем с чтения данных, поступающих от RC-передатчика. Код RC-передатчика, а также более подробную информацию о том, как работает эта связь, можно найти в моем конкретном руководстве по нему.
Таким образом, в зависимости от полученных данных, например, если левый джойстик перемещается вперед, его значение будет больше 160, и в таком случае будет вызвана пользовательская функция moveForward(). Если мы взглянем на эту функцию, то увидим, что все, что она делает, это устанавливает положительную скорость двигателей. Для движения назад скорость устанавливается отрицательной. Таким образом, для движения во всех других направлениях нам просто нужно правильно настроить вращение колес, как объяснялось вначале.
Для выполнения этих команд в разделе цикла нам нужно вызвать функции runSpeed() для всех шаговых двигателей. В секции цикла (loop) мы также считываем аналоговый вход с делителя напряжения, поступающего от батареи, и по этому значению мы можем узнать, когда напряжение батареи упадет ниже 11 В, чтобы мы могли включить индикаторный светодиод.
Код Arduino для управления роботом с помощью смартфона
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
/* === Arduino Mecanum Wheels Robot === Smartphone control via Bluetooth by Dejan, www.HowToMechatronics.com Libraries: RF24, https://github.com/tmrh20/RF24/ AccelStepper by Mike McCauley: http://www.airspayce.com/mikem/arduino/AccelStepper/index.html */ #include <SoftwareSerial.h> #include <AccelStepper.h> SoftwareSerial Bluetooth(A8, 38); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX) // Define the stepper motors and the pins the will use AccelStepper LeftBackWheel(1, 42, 43); // (Type:driver, STEP, DIR) - Stepper1 AccelStepper LeftFrontWheel(1, 40, 41); // Stepper2 AccelStepper RightBackWheel(1, 44, 45); // Stepper3 AccelStepper RightFrontWheel(1, 46, 47); // Stepper4 #define led 14 int wheelSpeed = 1500; int dataIn, m; int lbw[50], lfw[50], rbw[50], rfw[50]; // for storing positions/steps int index = 0; void setup() { // Set initial seed values for the steppers LeftFrontWheel.setMaxSpeed(3000); LeftBackWheel.setMaxSpeed(3000); RightFrontWheel.setMaxSpeed(3000); RightBackWheel.setMaxSpeed(3000); Serial.begin(38400); Bluetooth.begin(38400); // Default baud rate of the Bluetooth module Bluetooth.setTimeout(1); delay(20); pinMode(led, OUTPUT); } void loop() { // Check for incoming data if (Bluetooth.available() > 0) { dataIn = Bluetooth.read(); // Read the data if (dataIn == 0) { m = 0; } if (dataIn == 1) { m = 1; } if (dataIn == 2) { m = 2; } if (dataIn == 3) { m = 3; } if (dataIn == 4) { m = 4; } if (dataIn == 5) { m = 5; } if (dataIn == 6) { m = 6; } if (dataIn == 7) { m = 7; } if (dataIn == 8) { m = 8; } if (dataIn == 9) { m = 9; } if (dataIn == 10) { m = 10; } if (dataIn == 11) { m = 11; } if (dataIn == 12) { m = 12; } if (dataIn == 14) { m = 14; } // Set speed if (dataIn >= 16) { wheelSpeed = dataIn * 10; Serial.println(wheelSpeed); } } if (m == 4) { moveSidewaysLeft(); } if (m == 5) { moveSidewaysRight(); } if (m == 2) { moveForward(); } if (m == 7) { moveBackward(); } if (m == 3) { moveRightForward(); } if (m == 1) { moveLeftForward(); } if (m == 8) { moveRightBackward(); } if (m == 6) { moveLeftBackward(); } if (m == 9) { rotateLeft(); } if (m == 10) { rotateRight(); } if (m == 0) { stopMoving(); } //Serial.println(dataIn); // If button "SAVE" is pressed if (m == 12) { if (index == 0) { LeftBackWheel.setCurrentPosition(0); LeftFrontWheel.setCurrentPosition(0); RightBackWheel.setCurrentPosition(0); RightFrontWheel.setCurrentPosition(0); } lbw[index] = LeftBackWheel.currentPosition(); // save position into the array lfw[index] = LeftFrontWheel.currentPosition(); rbw[index] = RightBackWheel.currentPosition(); rfw[index] = RightFrontWheel.currentPosition(); index++; // Increase the array index m = 0; } if (m == 14) { runSteps(); if (dataIn != 14) { stopMoving(); memset(lbw, 0, sizeof(lbw)); // Clear the array data to 0 memset(lfw, 0, sizeof(lfw)); memset(rbw, 0, sizeof(rbw)); memset(rfw, 0, sizeof(rfw)); index = 0; // Index to 0 } } LeftFrontWheel.runSpeed(); LeftBackWheel.runSpeed(); RightFrontWheel.runSpeed(); RightBackWheel.runSpeed(); // Monitor the battery voltage int sensorValue = analogRead(A0); float voltage = sensorValue * (5.0 / 1023.00) * 3; // Convert the reading values from 5v to suitable 12V i //Serial.println(voltage); // If voltage is below 11V turn on the LED if (voltage < 11) { digitalWrite(led, HIGH); } else { digitalWrite(led, LOW); } } void runSteps() { for (int i = index - 1; i >= 0; i--) { // Run through all steps(index) LeftFrontWheel.moveTo(lfw[i]); LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.moveTo(lbw[i]); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.moveTo(rfw[i]); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.moveTo(rbw[i]); RightBackWheel.setSpeed(wheelSpeed); while (LeftBackWheel.currentPosition() != lbw[i] & LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) { LeftFrontWheel.runSpeedToPosition(); LeftBackWheel.runSpeedToPosition(); RightFrontWheel.runSpeedToPosition(); RightBackWheel.runSpeedToPosition(); if (Bluetooth.available() > 0) { // Check for incomding data dataIn = Bluetooth.read(); if ( dataIn == 15) { // If button "PAUSE" is pressed while (dataIn != 14) { // Wait until "RUN" is pressed again if (Bluetooth.available() > 0) { dataIn = Bluetooth.read(); if ( dataIn == 13) { stopMoving(); break; } } } } if (dataIn >= 16) { wheelSpeed = dataIn * 10; dataIn = 14; } if ( dataIn == 13) { break; } } } } // Go back through steps for (int i = 1; i <= index - 1; i++) { // Run through all steps(index) LeftFrontWheel.moveTo(lfw[i]); LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.moveTo(lbw[i]); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.moveTo(rfw[i]); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.moveTo(rbw[i]); RightBackWheel.setSpeed(wheelSpeed); while (LeftBackWheel.currentPosition() != lbw[i]& LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) { LeftFrontWheel.runSpeedToPosition(); LeftBackWheel.runSpeedToPosition(); RightFrontWheel.runSpeedToPosition(); RightBackWheel.runSpeedToPosition(); //Serial.print(" current: "); //Serial.println(LeftBackWheel.currentPosition()); if (Bluetooth.available() > 0) { // Check for incomding data dataIn = Bluetooth.read(); if ( dataIn == 15) { // If button "PAUSE" is pressed while (dataIn != 14) { // Wait until "RUN" is pressed again if (Bluetooth.available() > 0) { dataIn = Bluetooth.read(); if ( dataIn == 13) { stopMoving(); break; } } } } if (dataIn >= 16) { wheelSpeed = dataIn * 10; dataIn = 14; } if ( dataIn == 13) { //Serial.println("DEKI"); break; } } } } } void moveForward() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void moveBackward() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void moveSidewaysRight() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void moveSidewaysLeft() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void rotateLeft() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(wheelSpeed); } void rotateRight() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(-wheelSpeed); } void moveRightForward() { LeftFrontWheel.setSpeed(wheelSpeed); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(wheelSpeed); } void moveRightBackward() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(-wheelSpeed); RightFrontWheel.setSpeed(-wheelSpeed); RightBackWheel.setSpeed(0); } void moveLeftForward() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(wheelSpeed); RightFrontWheel.setSpeed(wheelSpeed); RightBackWheel.setSpeed(0); } void moveLeftBackward() { LeftFrontWheel.setSpeed(-wheelSpeed); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(-wheelSpeed); } void stopMoving() { LeftFrontWheel.setSpeed(0); LeftBackWheel.setSpeed(0); RightFrontWheel.setSpeed(0); RightBackWheel.setSpeed(0); } |
Описание: этот код для управления роботом с помощью приложения Android очень похож на предыдущий и работает по такому же принципу. Здесь вместо радиомодуля нам нужно подключить модуль Bluetooth и инициализировать его связь в разделе настройки. Итак, опять же, сначала мы считываем входящие данные со смартфона или Android-приложения и по ним указываем роботу, в каком направлении двигаться.
Если мы посмотрим на приложение для Android, то увидим, что оно просто отправляет числа от 0 до 15 через Bluetooth при нажатии кнопок.
Приложение создано с использованием онлайн-приложения MIT App Inventor, и более подробную информацию как им пользоваться вы можете найти в отдельной статье на нашем сайте .
По следующей ссылке вы можете скачать это приложение, а также редактируемый файл проекта: файлы приложений для робота Arduino Mecanum Wheels.
Для программирования автоматического движения робота с помощью этого приложения, когда мы нажимаем кнопку «СОХРАНИТЬ» (Save), мы просто сохраняем текущие положения шаговых двигателей в массивы. Затем, когда мы нажимаем кнопку «RUN», мы вызываем пользовательскую функцию runSteps(), которая выполняет или прогоняет все сохраненные шаги, используя некоторые циклы for и while.