Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Радиоуправляемый приемник Arduino своими руками для радиоуправляемых моделей и проектов Arduino

<основной класс="главный сайт" id="главный">

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

Вы можете посмотреть следующее видео или прочитать письменное руководство ниже.

Теперь эти два устройства могут легко обмениваться данными, и мы можем использовать их для беспроводного управления многими вещами. Я объясню, как все работает, на нескольких примерах. В первом примере мы будем использовать этот радиоуправляемый приемник Arduino для управления простым автомобилем, состоящим из двух двигателей постоянного тока. Во втором примере я покажу вам, как управлять бесщеточными двигателями и сервоприводами, которые являются обычными компонентами многих коммерческих радиоуправляемых самолетов, лодок, автомобилей и так далее. Если мы знаем, как управлять ими, мы можем легко модифицировать и управлять многими моделями RC с помощью нашего собственного передатчика Arduino, изготовленного по индивидуальному заказу.

В качестве третьего примера я покажу вам, как я модифицировал и использовал эту радиоуправляемую систему на базе Arduino для управления коммерческим радиоуправляемым автомобилем.

Схема приемника Arduino RC

Для начала рассмотрим принципиальную схему этой системы. Радиосвязь основана на приемопередающих модулях NRF24L01.

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

Мы также можем отметить, что этот радиоуправляемый приемник не обязательно работает только с этим конкретным передатчиком, который я построил. Он может работать с любой другой аналогичной установкой, состоящей из платы Arduino и модуля NRF24L01.

Тем не менее, мозгом этого радиоуправляемого приемника является плата Arduino Pro Mini. Для питания мы можем использовать либо контакт VCC, к которому мы можем подключить 5 В, либо контакт RAW, к которому мы можем подключить от 6 до 12 В. Обратите внимание, что существует две версии Arduino Pro Mini, например, та, которую я использую здесь, работает от 5 В, а другая работает от 3,3 В. С другой стороны, модуль NRF24L01 работает при напряжении 3,3 В, поэтому нам нужен регулятор напряжения. На этот раз я использую стабилизатор напряжения AMS1117, который выдает 3,3 В с входов, которые могут варьироваться от 5 В до 12 В.

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

Для связи с Arduino модуль NRF24L01 использует протокол SPI, а также два дополнительных цифровых контакта. Это означает, что у нас осталось 9 цифровых контактов, которые можно использовать в качестве выходных каналов, два из которых являются контактами RX и TX. Стоит отметить, что эти контакты должны быть отсоединены от чего-либо, пока мы загружаем скетч на плату Arduino, поэтому я сделал возможным подключение или отключение через отдельные разъемы для контактов. На самом деле, мы также можем использовать аналоговые входы в качестве цифровых выходов, так что, хотя эта плата Arduino довольно маленькая, у нас есть много доступных выходов или каналов.

Дизайн печатной платы

Тем не менее, чтобы сделать эту схему компактной, я сделал собственную печатную плату, используя бесплатное онлайн-программное обеспечение для проектирования схем EasyEDA. Здесь я разместил 8 каналов рядом с шиной 5V и заземлением, чтобы мы могли напрямую подключать к ним сервоприводы и ECS. Канал номер 9 расположен в отдельной позиции, рядом с контактом VCC Arduino, поэтому мы можем использовать, например, ESC для питания Arduino с его функцией Battery Eliminator Circuit, которая обеспечивает 5 В. Конечно, мы могли бы использовать любые другие каналы для этой цели, так как вывод VCC также подключен к этой шине 5V.

Что касается каналов № 7 и 8, то здесь мы можем видеть, как они прерываются этими штырьковыми разъемами. Если мы хотим их использовать, нам просто нужно соединить два контакта вместе. Заголовок программирования расположен в правом верхнем углу, а конденсатор 100 мкФ служит как для регулятора напряжения, так и для модуля NRF24L01. В левом нижнем углу печатной платы я разместил аналоговые контакты.

Здесь мы можем отметить еще одну вещь, а именно то, что некоторые платы Arduino Pro Mini могут иметь другое расположение контактов, поэтому я включил еще одну версию печатной платы, чтобы вы могли выбрать ту, которая соответствует вашей плате Arduino Pro Mini.

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

Gerber-файлы:

Затем я заказал печатную плату у JLCPCB, которая также является спонсором этого видео.

Здесь мы можем просто перетащить файл Gerber, и после загрузки мы можем просмотреть нашу плату в средстве просмотра Gerber. Если все в порядке, мы можем продолжить и выбрать свойства, которые мы хотим для нашей платы. И все, теперь мы можем просто заказать нашу плату по разумной цене. Обратите внимание:если это ваш первый заказ в JLCPCB, вы можете получить до 5 печатных плат всего за 2 доллара США.

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

Через несколько дней печатные платы прибыли. Качество печатных плат отличное и все точно так же, как и в дизайне.

Теперь можно двигаться дальше и собирать печатную плату. Во-первых, нам нужно припаять штыревые разъемы платы Arduino. Удобный способ сделать это — использовать макетную плату, чтобы вставить в нее контактные разъемы, чтобы плата оставалась на месте во время пайки. Как я уже говорил ранее, в зависимости от вашей платы контакты могут немного отличаться, так что имейте это в виду при их пайке.

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

Затем я поместил все остальные контактные разъемы на место. Нам нужны как мужские, так и женские контактные разъемы, или на самом деле вам решать, какие контактные разъемы вы решите использовать. Тем не менее, рекомендуется использовать вилки для цифровых каналов, так как соединения серводвигателей и ESC являются гнездами, поэтому мы можем легко их подключить.

Регулятор напряжения является компонентом для поверхностного монтажа, поэтому я использовал клей Blue-Tack, чтобы удерживать его на месте во время пайки. Наконец, после того как мы припаяем два конденсатора на место, мы сможем подключить модуль NRF24L01 к соответствующим контактным разъемам.

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

Для программирования приемника или подключения Arduino Pro Mini к компьютеру мы можем использовать USB-последовательный интерфейс UART, который можно подключить к разъему для программирования.

В меню инструментов Arduino IDE нам нужно выбрать плату Arduino Pro или Pro Mini, выбрать нужную версию процессора, выбрать порт и выбрать метод программирования «USBasp».

Итак, теперь мы можем загружать коды в Arduino.

Пример 1 — Радиоуправляемая машинка Arduino

Хорошо, теперь мы можем двигаться дальше и взглянуть на первый пример.

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

См. также:Драйвер двигателя L298N – Интерфейс Arduino, как это работает, коды, схемы

На этот раз мы будем использовать наш новый радиоуправляемый приемник Arduino для управления им. Для управления двигателями постоянного тока мы используем драйвер двигателя L298N, а для питания мы используем 3 литий-ионных аккумулятора, которые обеспечивают около 12 В.

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

Итак, соединения действительно просты, 12 В, поступающие от аккумуляторов, идут на контакт 12 В нашего приемника, а шесть управляющих контактов драйвера идут на 6 каналов. Здесь нужно отметить, что для того, чтобы иметь возможность управлять скоростью двигателей, нам необходимо подать сигнал PWM на контакты Enable A и Enable B драйвера. В нашем приемнике каналы 2, 3, 6 и 9 могут выводить ШИМ-сигналы, поэтому в данном случае я подключил контакты Enable драйвера к каналам 2 и 6.

Давайте теперь посмотрим на код Arduino.

/*
   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)

Описание: Итак, сначала нам нужно включить SPI и библиотеку RF24, определить некоторые выводы, радиообъект и структуру данных, в которой мы будем хранить входящие данные от передатчика. В разделе настройки нам нужно определить выходы контактов и начать радиосвязь. Для получения более подробной информации о том, как это работает и что делает каждая из этих строк, вы можете ознакомиться с моим подробным руководством по NRF24L01.

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

Итак, как только мы прочитаем эти данные, мы можем делать с ними все, что захотим. В этом случае мы будем использовать значение оси Y джойстика 1 для управления дроссельной заслонкой и значение оси X для управления рулевым управлением. Я помещаю эти данные в отдельные переменные газа и рулевого управления. Значения, которые мы получаем от джойстиков, находятся в диапазоне от 0 до 255. Итак, если мы переместим джойстик вниз, мы соответствующим образом установим штифты управления водителем, чтобы машина двигалась назад, и используем значение газа для управления скоростью движения. Тот же принцип применяется для движения вперед, влево и вправо. Опять же, у меня уже есть подробное руководство о том, как работает этот автомобиль, так что вы можете проверить его для лучшего понимания. В нижней части кода мы можем отметить пользовательскую функцию resetData(), которая сбрасывает все значения до их начальных значений по умолчанию, поэтому в случае потери радиосвязи автомобиль заметит движение.

Пример 2 – Управление сервоприводами и бесколлекторными двигателями приемника Arduino RC

Хорошо, теперь мы можем перейти ко второму примеру, управляя сервоприводами и бесколлекторными двигателями с помощью этого радиоуправляемого приемника Arduino.

Для управления бесщеточными двигателями нам нужен ESC или электронный регулятор скорости. Arduino связывается с ESC с помощью всего одного контакта. Для управления ESC Arduino посылает специальный сигнал PWM на ESC, и с его помощью ESC управляет скоростью двигателя. Регулятор скорости с тем же соединением обеспечивает 5 В благодаря функции выпрямителя батареи, так что мы также можем питать от него наш приемник.

См. также:Учебное пособие по управлению бесщеточным двигателем Arduino | ESC | BLDC

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

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

Входные сигналы для управления как сервоприводами, так и бесколлекторными двигателями с помощью ESC почти одинаковы. Они используют специальный ШИМ-сигнал частотой 50 Гц, который можно легко сгенерировать с помощью библиотеки Arduino Servo.

Примечание.  При использовании сервоприводов MG996R с такой настройкой они могут вызвать проблемы в цепи и сжечь Arduino Pro Mini. Это может привести к более высокому току, что может вызвать скачки напряжения на шине 5 В. Arduino Pro Mini должен выдерживать до 5,5 В на выводе 5 В, но когда возникают эти всплески, это может сжечь Arduino. У меня была эта проблема при тестировании схемы, и кто-то в разделе комментариев также сообщил о том же. Решением этой проблемы может быть установка больших развязывающих конденсаторов на сервоприводах, но я не совсем уверен и не проверял это. Поэтому помните об этой проблеме.

С другой стороны, в примере я использовал два других сервопривода MG996R, которые не сжигали Arduino, я думаю, потому, что они не вызывали таких высоких всплесков. Также я использовал этот пример с 4 меньшими сервоприводами S90, и у него не было никаких проблем.

См. также: Как работает серводвигатель & Как управлять сервоприводами с помощью Arduino

/*
  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)

Итак, после получения данных от передатчика мы конвертируем значения от 0 до 255 в значения от 0 до 180 для управления сервоприводами с помощью функции write(). Аналогичным образом мы преобразуем данные для управления ESC в значения от 1000 до 2000. В этом примере мы управляем этим ESC из средней точки джойстика № 1 в верхнее положение, поэтому мы конвертируем значения из середины , от 127 до 255 в значения от 1000 до 2000. С помощью функции writeMicroseconds() библиотеки сервоприводов мы отправляем сигнал ШИМ на ESC, чтобы мы могли контролировать скорость бесколлекторного двигателя от минимальной до максимальной.

См. также:Радиоуправляемый самолет на Arduino | 100% своими руками

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

Пример 3 – Управление моделью автомобиля на радиоуправлении

Радиоуправляемая машинка поставляется с собственным контроллером, который может управлять передними колесами для перемещения влево и вправо, а также для перемещения машины вперед и назад.

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

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

Итак, судя по всему, мы уже умеем управлять двигателями постоянного тока, поэтому заменить эту плату на наш самодельный приемник Arduino будет совсем несложно. В дополнение к нашему приемнику нам просто нужен драйвер двигателя, способный управлять двумя двигателями одновременно. Для этого существует множество вариантов, даже тот, который мы использовали в первом примере, драйвер L298N.

Однако он слишком велик для этого приложения, поэтому я выбрал драйвер двигателя MX1508. Это простой драйвер с двумя двигателями постоянного тока, оснащенный Н-мостом и ШИМ-управлением. Он имеет 4 входа управления, 4 контакта для двигателей и 2 контакта для питания.

Я отпаял разъемы двигателей от платы радиоуправляемого автомобиля и припаял их к драйверу. С обратной стороны я припаял контакты питания и теперь осталось соединить этот драйвер с ресивером. Питание этой радиоуправляемой машинки осуществляется от никель-кадмиевой батареи 4,8 В, расположенной в нижней части машины.

Итак, с помощью соединительных проводов я соединил эти контакты с контактом VCC Arduino, а также соединил 4 управляющих входных контакта драйвера с 4 цифровыми каналами. Как я уже сказал, этот драйвер поддерживает ШИМ-управление, поэтому для мотора B, или заднего мотора, я использовал ШИМ-каналы номер 2 и 3.

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

Код для этой радиоуправляемой машинки очень похож на первый пример.

/*
   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)

Мы используем данные, поступающие от джойстиков, для управления дроссельной заслонкой и рулевым управлением радиоуправляемой машинки. Для перемещения назад мы используем функцию AnalogWrite() для отправки ШИМ-сигнала драйверу на контакте Input3, в то время как на контакте input4 мы удерживаем НИЗКИЙ уровень. Для продвижения вперед мы делаем это наоборот. Если джойстик остается посередине, мы даем команду водителю затормозить или остановить моторы. Тот же принцип используется для рулевого двигателя, хотя здесь нам не нужно использовать функцию AnalogWrite(), так как нам не нужно контролировать скорость этого двигателя.

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

Таким образом, мы не только модифицировали эту радиоуправляемую машинку, чтобы она управлялась нашим самодельным радиоуправляемым передатчиком, но также улучшили ее, добавив ШИМ-управление, так что теперь мы также можем контролировать скорость машины. Если модель RC, которую вы хотите изменить, имеет сервоприводы и бесщеточные двигатели вместо двигателей постоянного тока, вы можете следовать методу, описанному во втором примере.

Надеюсь, вам понравился этот урок и вы узнали что-то новое. Не стесняйтесь задавать любые вопросы в разделе комментариев ниже и не забудьте проверить мою коллекцию проектов Arduino.


Производственный процесс

  1. Сделай сам:мониторинг и регулирование температуры для домашнего пивоварения
  2. Измерение температуры для лабораторных и научных проектов
  3. Выбор между фрезерным станком с ЧПУ и лазерным резаком с ЧПУ для ваших ремесленных проектов.
  4. ЖК-анимация и игры
  5. Вольтметр своими руками с использованием Arduino и смартфона
  6. DIY вольтметр с Arduino и дисплеем Nokia 5110
  7. Связь Python3 и Arduino
  8. Важность моделей САПР для проектов по изготовлению металлоконструкций
  9. Усовершенствованные токарные станки для полировки и удаления заусенцев
  10. Распиновка Mkr1000:предпочтительный выбор для проектов IoT