Создание надежного Arduino RC-приемника для моделей и проектов
В этом уроке мы научимся создавать Arduino-базированный RC-приемник. После того как я построил свой DIY Arduino RC-передатчик в одном из предыдущих видео, я получил много просьб сделать для него отдельный приемник, так что вот он. Вы можете посмотреть следующее видео или прочитать письменный урок ниже. Теперь эти два устройства могут легко общаться, и мы можем использовать их для беспроводного управления многими вещами. Я объясню, как все работает, через несколько примеров. В первом примере мы используем этот Arduino RC-приемник для управления простой машинкой с двумя двигателями постоянного тока. Во втором примере я покажу, как управлять бесколлекторными двигателями и сервоприводами, которые являются распространенными компонентами во многих коммерческих RC-самолетах, лодках, машинках и так далее. Если мы знаем, как их управлять, мы можем легко модифицировать и управлять многими RC-моделями с помощью нашего самодельного Arduino-передатчика. В третьем примере я покажу, как я модифицировал и использовал эту Arduino-базированную RC-систему для управления коммерческой RC-машинкой. Для начала давайте посмотрим на схему этой системы. Радиообмен основан на трансиверах NRF24L01. Передатчик постоянно отправляет данные от своих контроллеров: джойстиков, кнопок, потенциометров и тумблеров, а мы принимаем эти данные с помощью приемника. Более подробно о том, как работает этот Arduino-передатчик, можно узнать в моем другом подробном уроке. Также стоит отметить, что этот RC-приемник не обязательно работает только с этим конкретным передатчиком. Он может работать с любой другой похожей установкой, состоящей из платы Arduino и модуля NRF24L01. Тем не менее, «мозгом» этого RC-приемника является плата Arduino Pro Mini. Для питания мы можем использовать либо вывод VCC, к которому можно подключить 5В, либо вывод RAW, к которому можно подключить от 6 до 12В. Обратите внимание, что существует две версии Arduino Pro Mini: одна, которую я использую здесь, работает на 5В, а другая — на 3.3В. С другой стороны, модуль NRF24L01 работает на 3.3В, поэтому нам нужен стабилизатор напряжения. На этот раз я использую стабилизатор AMS1117, который выдает 3.3В от входного напряжения от 5В до 12В. Компоненты, необходимые для этого Arduino RC-приемника, можно найти по ссылкам ниже: Для связи с Arduino модуль NRF24L01 использует протокол SPI плюс два дополнительных цифровых вывода. Это оставляет нам 9 цифровых выводов, которые можно использовать в качестве выходных каналов, два из которых — это выводы RX и TX. Стоит отметить, что эти выводы должны быть отключены от чего-либо во время загрузки скетча в Arduino, поэтому я сделал возможным их подключение или отключение через отдельные пиновые заголовки. Кстати, мы также можем использовать аналоговые входы как цифровые выходы, так что хотя эта плата Arduino довольно мала, у нас есть много доступных выходов или каналов. Тем не менее, чтобы сохранить эту схему компактной, я сделал собственную печатную плату с помощью бесплатного онлайн-инструмента для проектирования схем EasyEDA. Здесь я разместил 8 каналов прямо рядом с шинами питания 5В и земли, поэтому мы можем напрямую подключать сервоприводы и ESC к ним. Канал номер 9 расположен в отдельном месте, рядом с выводом VCC Arduino, поэтому мы можем использовать, например, ESC для питания Arduino через его функцию BEC (Battery Eliminator Circuit), которая выдает 5В. Конечно, мы могли бы использовать для этого и любые другие каналы, так как вывод VCC также подключен к шине 5В. Что касается каналов номер 7 и 8, мы видим, что они прерываются этими пиновыми заголовками. Если мы хотим их использовать, нам просто нужно соединить два контакта вместе. Заголовок для программирования расположен в правом верхнем углу, а конденсатор 100 мкФ служит и для стабилизатора напряжения, и для модуля NRF24L01. В левом нижнем углу печатной платы я разместил аналоговые выводы. Здесь можно отметить еще одну вещь: некоторые платы Arduino Pro Mini могут иметь другую распиновку, поэтому я включил еще одну версию печатной платы, чтобы вы могли выбрать ту, которая соответствует вашей плате Arduino Pro Mini. Вот ссылка на файлы проекта этой печатной платы. После завершения проектирования я сгенерировал файлы Gerber, необходимые для производства печатной платы. Файлы Gerber: Затем я заказал печатную плату у JLCPCB, которые также являются спонсорами этого видео. Здесь мы можем просто перетащить файл Gerber, и после загрузки мы можем просмотреть нашу печатную плату в просмотрщике Gerber. Если все в порядке, мы можем продолжить и выбрать свойства, которые мы хотим для нашей печатной платы. И это все, теперь мы можем просто заказать нашу печатную плату по разумной цене. Обратите внимание, что если это ваш первый заказ у JLCPCB, вы можете получить до 5 печатных плат всего за $2. Через несколько дней печатные платы пришли. Качество печатных плат отлично, и все в точности соответствует проекту. Теперь мы можем перейти к сборке печатной платы. Сначала нам нужно припаять пиновые заголовки платы Arduino. Удобный способ сделать это — использовать макетную плату, чтобы вставить в нее пиновые заголовки, и тогда плата будет крепко держаться на месте во время пайки. Как я говорил ранее, в зависимости от вашей платы выводы могут немного отличаться, поэтому имейте это в виду при пайке. Также есть некоторые выводы GND, которые нам нужно оставить свободными, так как под ними на печатной плате проходят дорожки. После того как я припаял плату Arduino, я откусил лишнюю длину выводов. Затем я установил все остальные пиновые заголовки на место. Нам нужны как male, так и female заголовки, или это на ваше усмотрение, какие заголовки выбрать. Однако хорошей идеей является использование male заголовков для цифровых каналов, так как разъемы сервоприводов и ESC являются female, поэтому мы можем легко их подключить. Стабилизатор напряжения — это компонент для поверхностного монтажа, поэтому я использовал синий клей Blue-Tack, чтобы держать его на месте во время пайки. В конце, после того как мы припаяли два конденсатора, мы можем установить модуль NRF24L01 на соответствующие пиновые заголовки. В зависимости от приложения или необходимой дальности, мы можем использовать либо обычный модуль с напечатной антенной, либо тот, к которому можно подключить большую антенну и достичь беспроводной связи до 700 метров в открытом пространстве. Вот и все, наш Arduino RC-приемник готов, и мы можем использовать его для чего угодно. Для программирования приемника или подключения Arduino Pro Mini к компьютеру мы можем использовать USB-UART интерфейс, который можно подключить к заголовку программирования. В меню Инструменты Arduino IDE нам нужно выбрать плату Arduino Pro или Pro Mini, выбрать правильную версию процессора, выбрать порт и выбрать метод программирования «USBasp». И теперь мы можем загружать код в Arduino. Хорошо, теперь мы можем перейти к первому примеру. Это простая машинка, состоящая из двух двигателей постоянного тока 12В, и в некоторых из моих предыдущих видео я уже показывал, как она работает и как ее построить. См. также: Драйвер двигателя L298N — интерфейс с Arduino, как это работает, коды, схемы На этот раз мы будем использовать наш новый Arduino RC-приемник для управления ею. Для управления двигателями постоянного тока мы используем драйвер L298N, а для питания — 3 литий-ионных аккумулятора, которые обеспечивают около 12В. Компоненты, необходимые для этого примера, можно найти по ссылкам ниже: Подключения действительно просты: 12В от батарей идут на вывод 12В нашем приемнике, а шесть управляющих выводов драйвера идут на 6 каналов. Мы должны отметить, что для того, чтобы иметь возможность управлять скоростью двигателей, нам нужно подать PWM-сигнал на выводы Enable A и Enable B драйвера. В нашем приемнике каналы номер 2, 3, 6 и 9 могут выдавать PWM-сигналы, поэтому я подключил выводы Enable драйвера к каналам номер 2 и 6 в данном случае. Давайте посмотрим на код Arduino сейчас. Описание: Сначала нам нужно подключить библиотеки SPI и RF24, определить некоторые выводы, объект radio и структуру данных, в которой мы будем хранить входящие данные от передатчика. В разделе setup нам нужно определить выходы выводов и начать радиообмен. Более подробно о том, как это работает и что делает каждая из этих строк, можно узнать в моем подробном уроке по NRF24L01. В разделе loop мы постоянно проверяем, получаем ли мы данные, и если да, то считываем эти входящие данные. Если быстро взглянуть на код передатчика, мы увидим, какие данные он отправляет приемнику. Он считывает данные со всех своих контроллеров: джойстиков, потенциометров и кнопок, и отправляет эти данные как единый пакет приемнику. Итак, как только мы считаем эти данные, мы можем делать с ними что угодно. В этом случае мы будем использовать значение оси Y джойстика 1 для управления газами, а значение оси X — для управления рулем. Я помещаю эти данные в отдельные переменные throttle и steering. Значения, которые мы получаем от джойстиков, تتراوح от 0 до 255. Поэтому, если мы двигаем джойстик вниз, мы устанавливаем управляющие выводы драйвера соответствующим образом, чтобы машинка ехала назад, и используем значение throttle для управления скоростью движения. Тот же принцип применяется для движения вперед, влево и вправо. Опять же, у меня уже есть подробный урок о том, как работает эта машинка, так что вы можете посмотреть его для лучшего понимания. Внизу кода мы можем отметить пользовательскую функцию resetData(), которая сбрасывает все значения к их исходным значениям по умолчанию, поэтому в случае потери радиосвязи машинка остановится. Хорошо, теперь мы можем перейти ко второму примеру — управлению сервоприводами и бесколлекторными двигателями с помощью этого Arduino RC-приемника. Для управления бесколлекторными двигателями нам нужен ESC (электронный регулятор оборотов). Arduino общается с ESC всего через один вывод. Для управления ESC Arduino отправляет определенный PWM-сигнал ESC, и с его помощью ESC управляет скоростью двигателя. ESC через то же подключение обеспечивает 5В через свою функцию BEC (Battery Eliminator Circuit), поэтому мы также можем питать наш приемник от него. См. также: Урок по управлению бесколлекторным двигателем Arduino | ESC | BLDC Что касается сервоприводов, у них тот же тип подключений, что и у ESC, и мы можем просто подключить их к любому из доступных каналов. Компоненты, необходимые для этого примера, можно найти по ссылкам ниже: Входные сигналы для управления как сервоприводами, так и бесколлекторными двигателями с помощью ESC практически одинаковы. Они используют специфический PWM-сигнал 50 Гц, который можно легко сгенерировать с помощью библиотеки Servo Arduino. Примечание: При использовании сервоприводов MG996R с этой установкой они могут вызвать проблему в схеме и сжечь Arduino Pro Mini. Они могут потреблять больший ток, что может вызвать скачки напряжения на шине 5В. Arduino Pro Mini должен выдерживать до 5.5В на выводе 5В, но когда происходят эти скачки, это может сжечь Arduino. У меня была эта проблема при тестировании схемы, и кто-то в комментариях также сообщил об этом же. Решением может быть установка более крупных развязывающих конденсаторов на сервоприводах, но я не совсем уверен и не тестировал это. Так что, пожалуйста, будьте осведомлены об этой проблеме. С другой стороны, в примере я использовал два других сервопривода MG996R, которые не сожгли Arduino, я думаю, потому что они не вызывали таких высоких скачков. Также я использовал этот пример с 4 более маленькими сервоприводами S90, и у них не было никаких проблем. См. также: Как работает сервопривод и как управлять сервоприводами с помощью Arduino Итак, после получения данных от передатчика мы конвертируем значения от 0 до 255 в значения от 0 до 180 для управления сервоприводами с помощью функции write(). Похожим образом мы конвертируем данные для управления ESC в значения от 1000 до 2000. В этом примере мы управляем этим ESC от средней точки джойстика номер 1 до верхнего положения, поэтому мы конвертируем значения от середины, 127 до 255, в значения от 1000 до 2000. Используя функцию writeMicroseconds() библиотеки Servo, мы отправляем PWM-сигнал управления ESC, и так мы можем управлять скоростью бесколлекторного двигателя от минимума до максимума. См. также: Arduino RC самолет | 100% DIY Так мы можем управлять RC-самолетами, машинками, лодками и так далее, так как они обычно используют этот тип двигателей, сервоприводов и бесколлекторных двигателей. RC-машинка поставлялась со своим контроллером, который может управлять передними колесами для поворота влево и вправо, а также двигать машинку вперед и назад. Однако, так как это дешевая RC-машинка, управление дискретное, то есть либо включено, либо выключено, до максимального положения влево и вправо и максимальной скорости. Несмотря на это, я разобрал машинку, чтобы посмотреть, что внутри и как я могу реализовать Arduino RC-приемник для ее управления. После того как я открыл электронные компоненты, я заметил, что два двигателя — это на самом деле простые двигатели постоянного тока, работающие от 5В. Даже передний двигатель, который управляет ограниченными движениями для рулевого управления, является простым двигателем постоянного тока с непрерывным вращением. Так что, видимо, мы уже знаем, как управлять двигателями постоянного тока, поэтому замена этой платы на наш DIY Arduino-приемник будет довольно простой. В дополнение к нашему приемнику нам просто нужен драйвер двигателя, способный управлять двумя двигателями одновременно. Для этой цели есть множество вариантов, даже тот, который мы использовали в первом примере — драйвер L298N. Однако тот слишком большой для этого приложения, поэтому я выбрал драйвер двигателя MX1508. Это простой драйвер для двух двигателей постоянного тока, который имеет H-мост и PWM-управление. У него 4 управляющих входных вывода, 4 вывода для двигателей и 2 вывода для питания. Я отпаял подключения двигателей от платы RC-машинки и припаял их к драйверу. С обратной стороны я припаял выводы питания, и все, что осталось, — это подключить этот драйвер к приемнику. Питание для этой RC-машинки идет от батареи Ni-Cd 4.8В, расположенной на дне машинки. Итак, используя перемычки, я подключил эти выводы к выводу VCC Arduino, а также подключил 4 управляющих входных вывода драйвера к 4 цифровым каналам. Как я сказал, этот драйвер поддерживает PWM-управление, поэтому для двигателя B, или заднего двигателя, я использовал PWM-каналы номер 2 и 3. Компоненты, необходимые для этого примера, можно найти по ссылкам ниже: Код для этой RC-машинки очень похож на первый пример. Мы используем данные, поступающие от джойстиков, для управления газом и рулем RC-машинки. Для движения назад мы используем функцию analogWrite() для отправки PWM-сигнала драйверу на вывод Input3, удерживая вывод input4 в LOW. Для движения вперед мы делаем наоборот. Если джойстик остается в середине, мы даем команду драйверу затормозить или остановить двигатели. Тот же принцип используется для рулевого двигателя, хотя здесь нам не нужно использовать функцию analogWrite(), так как нам не нужно управлять скоростью этого двигателя. После загрузки этого скетча в Arduino мне пришлось собрать RC-машинку обратно. Я поместил маленький драйвер внутрь корпуса и закрепил остальные детали с винтами. Я переподключил приемник к драйверу и поместил его под внешний корпус машинки, в котором было достаточно места для размещения приемника. Так мы не только модифицировали эту RC-машинку для управления с помощью нашего DIY RC-передатчика, но и улучшили ее, добавив PWM-управление, так что теперь мы также можем управлять скоростью машинки. В случае, если RC-модель, которую вы хотите модифицировать, имеет сервоприводы и бесколлекторные двигатели вместо двигателей постоянного тока, вы можете следовать методу, объясненному во втором примере. Надеюсь, вам понравился этот урок, и вы узнали что-то новое. Не стесняйтесь задавать любые вопросы в разделе комментариев ниже и не забывайте проверять мою коллекцию проектов на Arduino.
Схема подключения Arduino RC-приемника


Проектирование печатной платы




Сборка печатной платы






Пример 1 – Arduino RC-машинка


/* Arduino RC Receiver - Car Example by Dejan, www.HowToMechatronics.com Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */ #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #define enA 9 // Arduino pin D9 - CH6 on PCB board - PWM output #define in1 8 // D8 - CH5 #define in2 7 // D7 - CH4 #define in3 6 // D6 - CH3 #define in4 4 // D4 - CH1 #define enB 5 // D5 - CH2 - PWM output RF24 radio(3, 2); // nRF24L01 (CE, CSN) const byte address[6] = "00001"; unsigned long lastReceiveTime = 0; unsigned long currentTime = 0; // Max size of this struct is 32 bytes 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 int steering, throttle; int motorSpeedA = 0; int motorSpeedB = 0; void setup() { pinMode(enA, OUTPUT); pinMode(enB, OUTPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(in3, OUTPUT); pinMode(in4, OUTPUT); //Serial.begin(9600); 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 resetData(); } 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 } // Parse the data from the Joystic 1 to the throttle and steering variables throttle = data.j1PotY; steering = data.j1PotX; // Throttle used for forward and backward control // Joystick values: 0 to 255; down = 0; middle = 127; up = 255 if (throttle < 110) { // Set Motor A backward digitalWrite(in1, HIGH); digitalWrite(in2, LOW); // Set Motor B backward digitalWrite(in3, HIGH); digitalWrite(in4, LOW); // Convert the declining throttle readings for going backward from 110 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed motorSpeedA = map(throttle, 110, 0, 0, 255); motorSpeedB = map(throttle, 110, 0, 0, 255); } else if (throttle > 140) { // Set Motor A forward digitalWrite(in1, LOW); digitalWrite(in2, HIGH); // Set Motor B forward digitalWrite(in3, LOW); digitalWrite(in4, HIGH); // Convert the increasing throttle readings for going forward from 140 to 255 into 0 to 255 value for the PWM signal for increasing the motor speed motorSpeedA = map(throttle, 140, 255, 0, 255); motorSpeedB = map(throttle, 140, 255, 0, 255); } // If joystick stays in middle the motors are not moving else { motorSpeedA = 0; motorSpeedB = 0; } // Steering used for left and right control if (steering < 110) { // Convert the declining steering readings from 140 to 255 into increasing 0 to 255 value int xMapped = map(steering, 110, 0, 0, 255); // Move to left - decrease left motor speed, increase right motor speed motorSpeedA = motorSpeedA - xMapped; motorSpeedB = motorSpeedB + xMapped; // Confine the range from 0 to 255 if (motorSpeedA < 0) { motorSpeedA = 0; } if (motorSpeedB > 255) { motorSpeedB = 255; } } if (steering > 140) { // Convert the increasing steering readings from 110 to 0 into 0 to 255 value int xMapped = map(steering, 140, 255, 0, 255); // Move right - decrease right motor speed, increase left motor speed motorSpeedA = motorSpeedA + xMapped; motorSpeedB = motorSpeedB - xMapped; // Confine the range from 0 to 255 if (motorSpeedA > 255) { motorSpeedA = 255; } if (motorSpeedB < 0) { motorSpeedB = 0; } } // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70) if (motorSpeedA < 70) { motorSpeedA = 0; } if (motorSpeedB < 70) { motorSpeedB = 0; } analogWrite(enA, motorSpeedA); // Send PWM signal to motor A analogWrite(enB, motorSpeedB); // Send PWM signal to motor B } 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; }Code language: Arduino (arduino)Пример 2 – Управление сервоприводами и бесколлекторными двигателями с помощью Arduino RC-приемника


/* DIY RC Receiver - Servos and Brushless motors control by Dejan, www.HowToMechatronics.com Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */ #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <Servo.h> RF24 radio(3, 2); // nRF24L01 (CE, CSN) const byte address[6] = "00001"; unsigned long lastReceiveTime = 0; unsigned long currentTime = 0; Servo esc; // create servo object to control the ESC Servo servo1; Servo servo2; int escValue, servo1Value, servo2Value; // 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() { Serial.begin(9600); 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 resetData(); esc.attach(10); // Arduino digital pin D10 - CH9 on PCB board servo1.attach(4); // D4 - CH1 servo2.attach(5); // D5 - CH2 } 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 } // Controlling servos servo1Value = map(data.j2PotX, 0, 255, 0, 180); // Map the receiving value form 0 to 255 to 0 to 180(degrees), values used for controlling servos servo2Value = map(data.j2PotY, 0, 255, 0, 180); servo1.write(servo1Value); servo2.write(servo2Value); // Controlling brushless motor with ESC escValue = map(data.j1PotY, 127, 255, 1000, 2000); // Map the receiving value form 127 to 255 to 1000 to 2000, values used for controlling ESCs esc.writeMicroseconds(escValue); // Send the PWM control singal to the ESC } 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; }Code language: Arduino (arduino)Пример 3 – Управление моделью RC-машинки






/* Arduino RC Receiver - RC Model control by Dejan , www.HowToMechatronics.com Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */ #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #define in3 5 // D5 - CH2 - PWM output #define in4 6 // D6 - CH3 - PWM output #define in1 7 // D7 - CH4 #define in2 8 // D8 - CH5 RF24 radio(3, 2); // nRF24L01 (CE, CSN) const byte address[6] = "00001"; unsigned long lastReceiveTime = 0; unsigned long currentTime = 0; // Max size of this struct is 32 bytes 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 int steering, throttle; int motorSpeedA = 0; int motorSpeedB = 0; void setup() { pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(in3, OUTPUT); pinMode(in4, OUTPUT); Serial.begin(9600); 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 resetData(); } 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 } // Parse the data from the Joystic 1 to the steering and throttle variables steering = data.j2PotX; throttle = data.j1PotY; // Throttle used for forward and backward control if (throttle < 110) { // Convert the declining throttle readings for going backward from 110 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed motorSpeedB = map(throttle, 110, 0, 0, 255); // Set Motor B backward analogWrite(in3, motorSpeedB); digitalWrite(in4, LOW); } else if (throttle > 140) { // Convert the increasing throttle readings for going forward from 140 to 255 into 0 to 255 value for the PWM signal for increasing the motor speed motorSpeedB = map(throttle, 140, 255, 0, 255); // Set Motor B forward digitalWrite(in3, LOW); analogWrite(in4, motorSpeedB); } // If joystick stays in middle the motors are not moving else { digitalWrite(in3, HIGH); digitalWrite(in4, HIGH); } // steering used for left and right control if (steering < 110) { digitalWrite(in1, HIGH); digitalWrite(in2, LOW); } if (steering > 140) { digitalWrite(in1, LOW); digitalWrite(in2, HIGH); } // If joystick stays in middle the motors are not moving else { digitalWrite(in1, HIGH); digitalWrite(in2, HIGH); } } 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; }Code language: Arduino (arduino)
Производственный процесс
- Самодельная система термостатирования для домашнего пивоварения: мониторинг и регулирование на Arduino
- Точное измерение и логирование термопар для лабораторных и научных экспериментов
- ЧПУ-фрезер vs ЧПУ-лазерный резак: что лучше для ваших DIY-проектов
- Создание анимации и игр на LCD 16×2 с Arduino UNO
- Умный вольтметр на Arduino и смартфоне — простое DIY-проект
- Сборка вольтметра на Arduino с дисплеем Nokia 5110 — Пошаговое руководство
- Управление Arduino Uno из Python 3: команды через последовательный порт и демонстрация с LED
- Как CAD-модели ведут к успеху в металлообрабатывающих проектах
- Скоростные токарные станки Twister: передовая полировка и зачистка с на 50% большей мощностью и рекуперативным ко…
- Arduino MKR1000: полное руководство по распиновке, питанию и старту для IoT