Ардуино и RoboRoverM1: делаем полноприводную машинку

Ардуино и RoboRoverM1: делаем полноприводную машинку Самолеты

Arduino – машинка на nrf24l01

Здарова всем, хочу поделиться своим проектом – машинка под управлением nrf24l01. Машинка получилась очень резвая и быстрая.

Управляется за счёт двух джойстиков от приставки. Ездит на 2 колёсах и одной шаровой опоре.

Делалась она из того, что было, а именно, из какого-то светорассеивающего оргстекла, пульт из распределительной коробки. Корпус это две пластинки из светорассеивающего оргстекла, которые скреплены между собой шестью спейсерами длиной 2 см. Размеры машинки: прямоугольник 10×15 см, у которого спереди по бокам срезано два треугольника 2.5×5 cм, высота 2 см. Размер распределительной коробки: 4 см высота, диаметр 10 см.

фото
P_20220731_172610[1].jpgP_20220731_172521[1].jpgP_20220731_172558[1].jpg

Перейдём к внутренностям:

КОМПОНЕНТЫ ПУЛЬТА

  • arduino nano
  • nrf24l01 без антенны c адаптером
  • Аккумулятор 610мАч 7.4А (две банки)
  • Джойстики X2
  • Выключатель

Фото внутренностей

P_20220731_181023[1].jpg
КОМПОНЕНТЫ МАШИНКИ

  • arduino nano
  • nrf24l01 с антенной и адаптером
  • Аккумулятор 610мАч 7.4В (две банки)
  • Драйвер моторов двухканальный Pololu на TB6612FNG v2 <1А
  • Мотор-редуктор Gekko MR12-050 turbo X2
  • Колесо Pololu 32×7 X2
  • Выключатель

Фото внутренностей

P_20220731_181942[1].jpg
СХЕМА МАШИНКИ
машинка схема.PNG

СХЕМА ПУЛЬТА
Схема пульт_xx.png

Принцип работы кода. Скорости вычисляются так: у нас есть 4 значения от 0 до 1023, измеряющихся в реальном времени (я решил использовать только два и разбил их на две части каждую, в итоге получили 4). Теперь преобразовываем их так, чтобы при сгибании 1-го джойстика из центра до максимума вперёд получали значения от 0 да 255, и при сгибании из центра назад было бы тоже самое. Со 2-м джойстиком, тоже из центра влево от 0 до 255 и в право от 0 да 255. В первой версии кода мы просто складывали эти скорости, то есть третье с четвёртым прибавляем к первым двум, и скорость движения вперёд просто пишем через if, чтобы можно было стоять . Это лишало нас способности поворачивать при движении вперёд на максимальной скорости. В version 2 (отдельное спасибо Nashatirkoза помощь в написании кода) c джойстика, отвечающего за поворот ось Y, мы снимаем коэффициент скорости колеса от 0 да 100, что более разумно. И вот так высчитываем скорость одного колеса: spr = x1p * y2r / 100. Скачать скетчи можно по ссылке.
КОД ПУЛЬТА

/*   Данный скетч модернизация скетча AlexGyver

*    исходник тут https://github.com/AlexGyver/nRF24L01

*/



#include <SPI.h>          // библиотека для работы с шиной SPI

#include "nRF24L01.h"     // библиотека радиомодуля

#include "RF24.h"         // ещё библиотека радиомодуля



RF24 radio(9, 10);





byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

byte transmit_data[4];





void setup() {

  Serial.begin(9600); //открываем порт для связи с ПК



  radio.begin(); //активировать модуль

  radio.setAutoAck(0);         //режим подтверждения приёма, 1 вкл 0 выкл

  radio.setRetries(0, 0);    //время между попыткой достучаться, число попыток

  radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал

  radio.setPayloadSize(32);     //размер пакета, в байтах



  radio.openWritingPipe(address[0]);   //мы - труба 0, открываем канал для передачи данных

  radio.setChannel(0x60);  //выбираем канал (в котором нет шумов!)



  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX

  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS

  //должна быть одинакова на приёмнике и передатчике!

  //при самой низкой скорости имеем самую высокую чувствительность и дальность!



  radio.powerUp(); //начать работу

  radio.stopListening();  //не слушаем радиоэфир, мы передатчик

}
void loop() {

  transmit_data[0] = map(analogRead(A0), 0, 1023, 0, 255); //считываем и обрезаем показания с джостика 1 оси X

  transmit_data[1] = map(analogRead(A1), 0, 1023, 0, 255); //считываем и обрезаем показания с джостика 1 оси Y

  transmit_data[2] = map(analogRead(A2), 0, 1023, 0, 255); //считываем и обрезаем показания с джостика 2 оси X

  transmit_data[3] = map(analogRead(A3), 0, 1023, 0, 255); //считываем и обрезаем показания с джостика 2 оси Y

  radio.write(&transmit_data, sizeof(transmit_data)); //отправляем получившийся массив
}

КОД МАШИНКИ Version 2

/*   Данный скетч модернизация скетча AlexGyver
*    исходник тут https://github.com/AlexGyver/nRF24L01
*/

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

RF24 radio(9,10); // "создать" модуль на пинах 9 и 10 Для Уно
//RF24 radio(9,53); // для Меги

byte address[][6] = {"1Node","2Node","3Node","4Node","5Node","6Node"};  //возможные номера труб
byte recieved_data[4];
void setup(){
  Serial.begin(9600); //открываем порт для связи с ПК

  pinMode(4, OUTPUT);

  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(5, OUTPUT);

  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(6, OUTPUT);


  radio.begin(); //активировать модуль
  radio.setAutoAck(0);         //режим подтверждения приёма, 1 вкл 0 выкл
  radio.setRetries(0,15);     //(время между попыткой достучаться, число попыток)
  radio.enableAckPayload();    //разрешить отсылку данных в ответ на входящий сигнал
  radio.setPayloadSize(32);     //размер пакета, в байтах

  radio.openReadingPipe(1,address[0]);      //хотим слушать трубу 0
  radio.setChannel(0x60);  //выбираем канал (в котором нет шумов!)

  radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
  radio.setDataRate (RF24_1MBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
  //должна быть одинакова на приёмнике и передатчике!
  //при самой низкой скорости имеем самую высокую чувствительность и дальность!!

  radio.powerUp(); //начать работу
  radio.startListening();  //начинаем слушать эфир, мы приёмный модуль
}

void loop() {
    byte pipeNo;               
    while( radio.available(&pipeNo)){    // слушаем эфир со всех труб
      radio.read( &recieved_data, sizeof(recieved_data) ); //читаем присланный массив
      digitalWrite(4, HIGH);

      int x1p = constrain(map(recieved_data[1], 128, 255, 0, 255), 0, 255); //обрезаем и переворачиваем значения
      int x1b = constrain(map(recieved_data[1], 128, 0, 0, 255), 0, 255); //обрезаем и переворачиваем значения
      int y2r = constrain(map(recieved_data[2], 122, 255, 100, 1), 0, 100); //обрезаем и переворачиваем значения
      int y2l = constrain(map(recieved_data[2], 122, 0, 100, 1), 0, 100); //обрезаем и переворачиваем значения

      int stl = constrain(map(recieved_data[2], 123, 255, 0, 255), 0, 255); //обрезаем и переворачиваем значения
      int str = constrain(map(recieved_data[2], 122, 0, 0, 255), 0, 255); //обрезаем и переворачиваем значения

      //Serial.print(x1p); Serial.print(" | "); Serial.print(x1b); Serial.print(" | "); Serial.print(y2r); Serial.print(" | "); Serial.print(y2l); Serial.println();
      int spr = constrain(x1p * y2r / 100, 0, 255); //скорость правого колеса
      int spl = constrain(x1p * y2l / 100, 0, 255); //скорость левого колеса
      int bspr = constrain(x1b * y2r / 100, 0, 255); //скорость правого колеса назад
      int bspl = constrain(x1b * y2l / 100, 0, 255); //скорость левого колеса назад
      Serial.print(stl); Serial.print(" | "); Serial.print(str); Serial.println();
      //Serial.print(recieved_data[2]); Serial.println();
      if (recieved_data[1]>138)
    { digitalWrite(A1, LOW);
      digitalWrite(A0, HIGH);
      analogWrite(5, spr);

      digitalWrite(7, LOW);
      digitalWrite(8, HIGH);
      analogWrite(6, spl);
    } else if (recieved_data[1]<118)
    { digitalWrite(A1, !LOW);
      digitalWrite(A0, !HIGH);
      analogWrite(5, bspr);

      digitalWrite(7, !LOW);
      digitalWrite(8, !HIGH);
      analogWrite(6, bspl);
    }else if (118<recieved_data[1]<138)
    { digitalWrite(A1, LOW);
      digitalWrite(A0, HIGH);
      analogWrite(5, str);

      digitalWrite(7, LOW);
      digitalWrite(8, HIGH);
      analogWrite(6, stl);
      }
  }
}

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

Кстати скоро выйдет версия с камерой как у Алекса.

Всем спасибо за внимание!

Rc авто c gps на платформе arduino nano

Ардуино и RoboRoverM1: делаем полноприводную машинку

Моя идея: узнать максимальную скорость в радиоуправляемой машинке и запоминание при выключение питания, добавить включение фар при наборе скорости, включение поворотников при поворотах, включение стопсигналов при торможение, включение габаритных огней при стоянке, мигалок при нажатие кнопки на машинке(кнопка сброса максимальной скорости).

Машинка, которая используется в комплектации:

Задача сделать на имеющей машинке:

  1. Установить все световые огни и кнопку
  2. Установить аппаратуру ардуино
  3. Закачать программу в ардуино
  4. Настройка программы

Установка световых огней. Я взял готовые светодиоды с проводами из набора «RC Car Flashing Light System».

Ардуино и RoboRoverM1: делаем полноприводную машинку
Установка передних фар (они же являются габаритами) и поворотников

Ардуино и RoboRoverM1: делаем полноприводную машинку
Установка аппаратуры ардуино Nano и GPS, все закрепил двухсторонем скотчем и винтами

Ардуино и RoboRoverM1: делаем полноприводную машинку
Установка LCD на заднем стекле, закрепил винтами

Что понадобится для сборки:
Arduino Nano, цена от 200 р.
GPS приемник, цена от 900 р.
Светодиоды, цена от 100 р. / Светодиоды белые, 3 шт. (передние фары и задний ход), красные 2 шт. (тормоз), оранжевые 2 шт. (поворотники)
Провода, цена от 100 р.
LCD и I2C, цена от 200 р.
Кнопка и резистор, цена от 100 р. / Кнопка (сброс скорости и включение мигалок) и резистор 10 кОм

Цена проекта получилось 1600 рублей.

1. Arduino Nano

Ардуино и RoboRoverM1: делаем полноприводную машинку

2. LCD 1602 и I2C

Ардуино и RoboRoverM1: делаем полноприводную машинку
LCD

Ардуино и RoboRoverM1: делаем полноприводную машинку
Задняя сторона LCD и припаял к нему модуль I2C

3. GPS-GY-NEO-6MV2 (GPS приемник)

Ардуино и RoboRoverM1: делаем полноприводную машинку
GPS-приемник

Устанавливаем программу для ардуино в комп и закачиваем скетч в ардуино.

Если не хватает библиотеки, то нужно их скачать и установить на компе: LiquidCrystal_I2C.h, EEPROM.h, Wire.h, SoftwareSerial.h, TinyGPS.h.

Сам скетч:

СКЕТЧ

#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); //I2C: SDA pin A4 / SCL pin A5 /VCC pin 3,3V /GND pin GND
#include <SoftwareSerial.h>
#include <TinyGPS.h>
TinyGPS gps;
SoftwareSerial ss(4, 3); // GPS: RX pin D4, TX pin D3, VCC pin 5V ,GND pin GND
static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
float flat, flon; //
unsigned long fix_age, time, date, speed, course; //
int value;
int value2;
int pin = 7; //поворотник D7
int pins = 8; //движение D8
int pin1 = 11;//Светодиод оранжевый: влево D11
int pin2 = 12;// Светодиод оранжевый: вправо D12
int pin3 = 10;// Светодиоды красные: тормоз D10
int pin4 = 9;// Светодиоды белые : вперед D9
int pin6 = 6;// Светодиод белый : задний ход D6
unsigned long duration1;//центр 1372 ,влево 1834 ,вправо973
unsigned long duration2;//тормоз 1834 ,вперед 973
int pin7 = 2;// Светодиод мигалка красная: pin D2
int pin8 = 13;// Светодиод мигалка синяя pin D13
const int buttonPin = 5; // Кнопка (сброса) номер входа, подключенный к кнопке pin D5
int buttonState = 0; // переменная для хранения состояния кнопки
void setup()
{
pinMode(pin, INPUT);
pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
pinMode(pins, INPUT);
pinMode(pin3, OUTPUT);
pinMode(pin4, OUTPUT);
pinMode(pin6, OUTPUT);
pinMode(pin7, OUTPUT);
pinMode(pin8, OUTPUT);
pinMode(buttonPin, INPUT); // инициализируем пин, подключенный к кнопке, как вход
Serial.begin(115200); //для отладки
ss.begin(9600); //gps
Serial.println("RRRR777");
lcd.init(); // инициализация ЖК
lcd.clear();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("RRRR777 2022");
lcd.setCursor(0, 1);
lcd.print(" GPS RCavto");
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем с
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем с
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500);
digitalWrite(pin7, LOW); //
digitalWrite(pin8, LOW); //
delay(500); // ждем
lcd.clear();
delay(500);
}
void loop()
{
duration1 = pulseIn(pin, HIGH);
duration2 = pulseIn(pins, HIGH);
if ((duration1 > 1500) && (duration1 < 2000))
{digitalWrite(pin1, HIGH); // зажигаем светодиод LEFT
delay(250); // ждем секунду
digitalWrite(pin1, LOW); // выключаем светодиод
}
if ((duration1 < 1300) && (duration1 > 800))
{digitalWrite(pin2, HIGH); // зажигаем светодиод RIGHT
delay(250); // ждем секунду
digitalWrite(pin2, LOW); // выключаем светодиод
}
if ((duration2 > 1480) && (duration2 < 2000))//ФАРЫ
{ analogWrite(pin4, 20); //габариты задние
analogWrite(pin3, 255); // зажигаем светодиод фары
delay(500); // ждем
}
if ((duration2 < 1480) && (duration2 > 800)) //ТОРМОЗ
{analogWrite(pin4, 255); // светодиод тормоз
analogWrite(pin3, 20); // зажигаем светодиод фары габариты *
digitalWrite(pin6, LOW); // выключаем светодиод
delay(50);
}
if ((duration2 < 1400) && (duration2 > 800))//Задний ход
{//digitalWrite(pin4, LOW); // зажигаем светодиод
digitalWrite(pin6, HIGH); // зажигаем светодиод
delay(500); // ждем секунду
}
float flat, flon;
unsigned long age, date, time, chars = 0;
unsigned short sentences = 0, failed = 0;
float h = gps.f_speed_kmph(); // speed in km/hr
int h1 = (h-(int)h)*100;
Serial.println(h);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Mersedes GT3"); // название машины
lcd.setCursor(0, 1);
lcd.print("S=");
lcd.print(h);
lcd.setCursor(8, 1);
lcd.print("MS=");
value = EEPROM.read(0); //чтение из памяти
value2 = EEPROM.read(1);
lcd.print(value);
lcd.print(".");
lcd.print(value2);
buttonState = digitalRead(buttonPin);// считываем значения с входа кнопки
if (buttonState == HIGH)// LOW) ///
{
EEPROM.write (0,0);
EEPROM.write (1,0);
lcd.setCursor(8, 1);
lcd.print("MS=RESET");
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем с
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500);
lcd.setCursor(0, 1);
lcd.print("Rusticktigr777@mail.ru");
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем с
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500);
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500); // ждем с
digitalWrite(pin8, HIGH); //
digitalWrite(pin7, LOW); //
delay(500); // ждем
digitalWrite(pin7, HIGH); //
digitalWrite(pin8, LOW); //
delay(500);
digitalWrite(pin7, LOW); //
digitalWrite(pin8, LOW); //
}
if (h > value)//RECORD
{
EEPROM.write (0,h);
EEPROM.write (1,h1);
}
smartdelay(500);
}
static void smartdelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void print_float(float val, float invalid, int len, int prec)
{
if (val == invalid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec (val < 0.0 ? 2 : 1); // . and -
flen = vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; i)
Serial.print(' ');
}
smartdelay(0);
}
static void print_int(unsigned long val, unsigned long invalid, int len)
{
char sz[32];
if (val == invalid)
strcpy(sz, "*******");
else
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i<len; i)
sz[i] = ' ';
if (len > 0)
sz[len-1] = ' ';
Serial.print(sz);
smartdelay(0);
}
static void print_date(TinyGPS &gps)
{
int year;
byte month, day, hour, minute, second, hundredths;
unsigned long age;
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
if (age == TinyGPS::GPS_INVALID_AGE)
Serial.print("********** ******** ");
else
{
char sz[32];
sprintf(sz, "d/d/d d:d:d ",
month, day, year, hour, minute, second);
Serial.print(sz);
}
print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
smartdelay(0);
}

Подключение проводов к ардуино:

Смотрите про коптеры:  РадиоКот :: 10 командное радиоуправление на MRF49XA

Провода

I2C: SDA pin A4 / SCL pin A5 /VCC pin 3,3V /GND pin GND (установить максимальная яркость и подсветку)

GPS: RX pin D4, TX pin D3, VCC pin 5V ,GND pin GND

Кнопка сброса (нормально разомкнутая кнопка): один контакт VCC pin 5V, другой контакт на pin D5, резистор на pin D5 и pin GND

Светодиоды: Фары передние (габариты) белые « » на pin D9

Светодиоды: Фары задние (габариты) красные « » на pin D10

Светодиод: Задний ход белый « » на pin D6

Светодиоды: Фары передние (габариты) белые « » на pin D9

Светодиод: Поворот влево оранжевый « » на pin D11

Светодиод: Поворот вправо оранжевый « » на pin D12

Светодиод: Мигалка красный « » на pin D2

Светодиод: Мигалка синий « » на pin D13

Для всех Светодиодов «-» на pin GND

Подключаем провод для поворотников на pin D7 от входа сервомашинки поворотов (три провода обычно это белый к нему подпаеваемся и выводим провод на pin D7, красный — питание плюс, черный — питание минус, подключается к приемнику).

Подключаем провод для движения на pin D8 от входа сервомашинки двигателя (три провода: обычно это белый, к нему подпаеваемся и выводим провод на pin D8, красный — питание плюс, черный — питание минус, подключается к приемнику).

Питание для Ардуино берется прямо из аккумулятора « » на pin VIN (в моем 7,2в). Общий провод GND для Ардуино прямо из аккумулятора «-».

Настройка: если не правильно срабатывает при поворотах или движении, то через программу на компьютере изменяем значения на свои: в строчках if ((durationХ > ХХХХ) && (durationХ < ХХХХ)) если не обрабатывается данные и горит зеленый светодиод на плате GPS, TX/RX возможно нужно поменять местами RX pin D4, TX pin D3,)

P.S. Идея оказалось несложной, зная программирование, можно еще добавить в эту машинку температуру в двигателе и оповещение о ней, добавить моточасы, тахометр и видеокамеру на «Mercedes-Benz GT3».

Всем удачи!

Машинка на радиоуправлении своими руками.

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

NRF24L01 (можно заказать по ссылке)

, плату Ардуино 

например Arduino UNO (купить по ссылке)

 (или любую другую Ардуино или подобную плату). Также понадобятся драйверы для управления двигателями, можно использовать например L293D если двигатели потребляют ток до 600мА, сами двигатели, батарейки и некоторые дополнительные элементы. В рулевой системе машинки можно установить такой же линейный актуатор с шаговым двигателем которые используются в дисководах. Механика рулевой системы должна быть такой чтобы не было необходимости в большой силе двигателя для того чтобы осуществить поворот. Если поворот осуществляется достаточно легко то можно сделать полношаговое управление двигателем с использованием одной фазы на каждом шаге, если при всех стараниях не получилось сделать достаточно легко поворачивающиеся передние колёса то для решения проблемы поворота можно сделать полношаговое управление с использованием двух фаз на каждом шаге и немного увеличить напряжение питания при этом увеличиться момент и потребление тока в следствии чего батарейки будут быстрее разряжаться но зато рулевая система будет более надёжной. Для движения вперёд и назад можно использовать любой подходящий и достаточно мощный коллекторный электродвигатель постоянного тока в котором реверс осуществляется сменой полярности подаваемого на него напряжения. У большинства таких двигателей обороты слишком большие и момент слишком мал для того чтобы можно было использовать прямую передачу на колёса без редуктора (например надев колесо на вал двигателя). Редуктор можно использовать готовый или изготовить самостоятельно. Если редуктор изготавливается самостоятельно но необходимо уделить достаточно внимания его изготовлению и по возможности избежать фрикционных и ремённых передач а делать только с шестерёнками, если этого не получилось то ремённые или фрикционные передачи необходимо делать очень качественно. При изготовлении механических частей машинки для скрепления частей можно использовать цианоакрилатный клей (например

Смотрите про коптеры:  РОБОТ на базе: android, arduino, bluetooth. Начало / Хабр

клей (можно заказать по ссылке)

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

Рисунок 1 – Приёмник

Радиомодуль NRF24L01 взаимодействует с платой Arduino через интерфейс SPI. Питание 3.3В на радиомодуль идёт с платы Arduino (в плате есть стабилизатор напряжения). На саму плату Ардуино подаётся 9В от 6ти пальчиковых батареек соединённых последовательно. Это питание следует подавать через специальный разъём (понятно из рисунка 1). На плате есть стабилизатор на 5В. Между выводом GND и  3.3В радиомодуляNRF24L01 стоит конденсатор для сглаживания пульсаций напряжения которые могут появляться например при работе двигателей. Драйверы запитываются непосредственно от батареек, один из драйверов целиком используется для управления шаговым двигателем, другой для управления коллекторным, светодиодными фонарями и пьезодинамиком. Пьезодинамик можно поставить на тот же полумост драйвера что и фонари т.к. он издаёт звуки только от переменного напряжения. Скетч в Ардуино загружается при отключенном питании. Давайте рассмотрим скетч:

#include “SPI.h”
#include “nRF24L01.h”
#include “RF24.h”

RF24 radio(9,10);

const uint64_t pipe = 0xF0F0F0F0E1LL;

char data = ‘z’;
char data_turning = ‘s’;
//20 binary 00010100
//24 binary 00011000
//40 binary 00101000
//36 binary 00100100
unsigned char arr[4]={20,24,40,36};
unsigned char counter = 0;
unsigned char out_condit = 0;
unsigned char out_going = 0;
void stepper_rotate()
{
if (data_turning == ‘l’)
{
counter ;
if(counter3)counter=0;
out_condit = arr[counter];
}
else if (data_turning == ‘r’)
{
if(counter==0)
{
out_condit = arr[0];
counter=3;
}
else
{
out_condit = arr[counter];
counter–;
}
}
else if(data_turning == ‘s’)
{
out_condit = 0;
}
}
void bebep()
{
for(int i=0;i5000;i )  
{
digitalWrite(8, HIGH);
delayMicroseconds(100);
digitalWrite(8, LOW);
delayMicroseconds(100);
}
}
void setup(void)
{
radio.begin();
radio.setRetries(15,15);
radio.openReadingPipe(1,pipe);
radio.startListening();
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
}

void loop(void)
{
if ( radio.available() )
{
radio.read( &data, sizeof(char) );
switch(data)
{
//мотор
case ‘a’:
out_going = 128;
break;
case ‘b’:
out_going = 64;
break;
case ‘c’:
out_going = 0;
break;
//фары
case ‘d’:
digitalWrite(8, HIGH);
break;
case ‘e’:
digitalWrite(8, LOW);
break;
//гудок
case ‘f’:
bebep();
break;
//руль
case ‘r’:
data_turning = ‘r’;
break;
case ‘l’:
data_turning = ‘l’;
break;
case ‘s’:
data_turning = ‘s’;
break;
}
}
//руль
stepper_rotate();
PORTD &= 195;//binary 11000011
PORTD |= out_condit;
//мотор
PORTD &= 63;//binary 00111111
PORTD |= out_going;
delay(12);
}

Это скетч для приёмника, в первых трёх строчках этого скетча подключаются заголовочные файлы для простой реализации связи по SPI и использования радиомодуля NRF24L01 . Следующая строка – это создание экземпляра класса “RF24”, первым параметром в конструктор этого класса передаётся номер пина Ардуино который следует соединить с CE радиомодуля а вторым параметром – номер пина который следует соединить с CSN радиомодуля. Следующая строка – это адрес канала, он должен быть одинаковым у приёмника и передатчика. Далее идёт инициализация переменных. В переменную “data” записывается принятый по радио символ. В переменную “data_turning” записывается символ который определяет будет ли вращаться ротор шагового двигателя рулевой системы и если да то в какую сторону. Далее идёт массив состояний порта для управления шаговым двигателем. Переменная “counter” вспомогательная для функции управления шаговым двигателем. Дальше идёт функция управления шаговым двигателем “stepper_rotate()” после неё идёт функция создания гудка “bebep()”. В функции “setap” происходит инициализация радиомодуля и выводов Ардуино. В функции “loop” принимается символ и в соответствии с принятым символом совершаются определённые действия.
Передатчик можно изготовить на любом Ардуино. Рассмотрим схему передатчика:

Рисунок 2 – Передатчик

У каждого Arduino есть выводы SPI но обычно на плате они не подписаны, выяснить где эти выводы находятся можно из документации на конкретное Arduino. На рисунке 2 показан джойстик, джойстик обычно можно представить в виде набора кнопок. Если соответствующая кнопка нажата то на соответствующем выводе Arduino появиться низкое напряжение (логический ноль), если кнопка не нажата то на выводе будет высокое напряжение (логическая единица) т.к. этот вывод соединён с  5В через резистор с сопротивлением 10кОм (можно использовать резистор с другим близким к 10кОм сопротивлением) эти  5В берутся с вывода Ардуино. Ардуино можно питать одной батарейкой “Крона” на 9В, это питание также подаётся на Arduino через специальный разъём. Скетч также загружается при отключенном питании. Скетч для передатчика:

#include <SPI.h>
#include “nRF24L01.h”
#include “RF24.h”

RF24 radio(9,10);

const uint64_t pipe = 0xF0F0F0F0E1LL;
char data=’a’;

boolean but_forward_before;
boolean but_forward;
boolean but_back_before;
boolean but_back;
boolean but_left_before;
boolean but_left;
boolean but_right_before;
boolean but_right;
boolean but_fire_before;
boolean but_fire;

void sendData()
{
radio.openWritingPipe(pipe);
radio.startListening();
radio.write( &data, sizeof(char) );
delay(20);
}

void setup(void)
{
//Serial.begin(57600);
radio.begin();
radio.setRetries(15,15);
radio.openWritingPipe(pipe);
radio.startListening();
//установки для кнопок
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode(3, INPUT);
digitalWrite(3, HIGH);
pinMode(4, INPUT);
digitalWrite(4, HIGH);
pinMode(5, INPUT);
digitalWrite(5, HIGH);
pinMode(6, INPUT);
digitalWrite(6, HIGH);
}

void loop(void)
{
but_forward = digitalRead(2);
but_back = digitalRead(3);
but_left = digitalRead(4);
but_right = digitalRead(5);
but_fire = digitalRead(6);
if(but_forward_before && !but_forward)
{
data = ‘a’;
sendData();
}
else if(but_back_before && !but_back)
{
data = ‘b’;
sendData();
}
else if((!but_forward_before && but_forward) || (!but_back_before && but_back))
{
data = ‘c’;
sendData();
}
if(but_left_before && !but_left)
{
data = ‘l’;
sendData();
}
else if(but_right_before && !but_right)
{
data = ‘r’;
sendData();
}
else if((!but_left_before && but_left) || (!but_right_before && but_right))
{
data = ‘s’;
sendData();
}
if(but_fire_before && !but_fire)
{
data = ‘f’;
sendData();
}
but_forward_before = but_forward;
but_back_before = but_back;
but_left_before = but_left;
but_right_before = but_right;
but_fire_before = but_fire;
delay(80);
}

Первые 6 строчек аналогичны тем что в скетче для приёмника, далее идут переменные которые используются для хранения текущих и предыдущих состояний кнопок джойстика. Функция “sendData()” отсылает символ который записан в переменной “data”. В функции “setup” происходит инициализация радиомодуля и настройка необходимых выводов. В функции “loop” происходит отправка символа для движения вперёд если кнопка “вперёд” переходит из не нажатого состояния в нажатое, если тоже самое происходит в кнопкой “назад” то отсылается символ для движения машинки назад, если кнопка “вперёд” переходит из нажатого состояния в ненажатое или кнопка “назад” переходит из нажатого состояния в не нажатое то отправляется символ для остановки машинки, аналогично и для рулевой системы, есть ещё символ для гудка и он отправляется если кнопка “гудок” переходит из не нажатого состояния в нажатое. В общем скетчи достаточно простые, скачать их можно по ссылке: https://yadi.sk/d/K0HfKwcojCuaX.
Корпус лучше сделать из картона т.к. он не мешает прохождению радиосигнала, к тому же его можно красиво раскрасить:

Процесс сборки (неполный и ускоренный для экономии времени) машинки с некоторыми комментариями а также демонстрацию работы можно увидеть на видео:

КАРТА БЛОГА (содержание)

Простая bluetooth машинка на arduino

Широкое распространение и дешевизна платформы Arduino и различных робоплатформ позволило любителям создавать радиоуправляемые машинки на любой вкус. А широкое распространение смартфонов позволило использовать их в качестве контроллеров этих машинок. Главной проблемой для многих любителей Arduino является отсутствие опыта в программировании под Android. Сегодня я расскажу, как легко решить эту проблему, используя среду визуальной разработки android-приложений App Inventor 2.

Постройку любой машинки надо начинать с «железа», поэтому вкратце опишу, что использовал для своей машинки:
arduino nano
bluetooth module HC-05
Z-Mini Motor Sensor Shield L293D
2WD Motor Chassis
Конфигурация «железа» не играет большой роли в этом проекте, поэтому шасси, шилд и саму ардуино можно заменить на любые аналоги.

Теперь перейдем к созданию приложения для Android. App Inventor — среда визуальной разработки android-приложений, работает из браузера. Заходим на сайт, разрешаем доступ к своему аккаунту в Google, нажимаем кнопку «create» и создаем новый проект. В новом проекте методом «Drag and Drop» создаем 4 кнопки для выбора направления движения и одну для подключения к нашему bluetooth модулю. Примерно так:

image

Далее нажимаем на кнопку «Blocks» в правом верхнем углу и все тем же методом перетаскивания элементов создаем логику работы нашего android-приложения примерно вот так:

image

Теперь остается скомпилировать приложение, нажав на кнопку «Build».

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

скетч
Смотрите про коптеры:  RC лодка на Arduino из палок и ... | Пикабу

int val;

int IN1 = 4;

int IN2 = 7;

int EN1 = 6;

int EN2 = 5;

void setup()
{
Serial.begin(9600);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(EN1, OUTPUT);
pinMode(EN2, OUTPUT);

}
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);
}

// Задаём движение назад
if ( val == ‘S’)
{
digitalWrite(EN1, HIGH);
digitalWrite(EN2, HIGH);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}

// Задаём движение вправо
if ( val == ‘D’)
{
digitalWrite(EN1, HIGH);
digitalWrite(EN2, HIGH);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
}

// Задаём движение влево
if ( val == ‘A’)
{
digitalWrite(EN1, HIGH);
digitalWrite(EN2, HIGH);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
}

// Стоп режим
// При отпускании клавиш в программе в порт шлется «T»
if ( val == ‘T’) // При нажатии клавиши «T»
{
// Выводы ENABLE притянуты к минусу, моторы не работают
digitalWrite(EN1, LOW);
digitalWrite(EN2, LOW);
}
}
}

Итак, вот такая у меня получилась машинка:

Ардуино и RoboRoverM1: делаем полноприводную машинку

Те, кому нравится дизайн в приложениях, могут немного поменять. Подробно описывать как это делать не буду, там не сложно самому разобраться. Скажу лишь, что для этого в основном нужно использовать .png файлы, вместо .jpeg, которые не поддерживают прозрачный фон. Например, сделать такой дизайн за полчаса или час сможет любой неподготовленный человек:

image

P.S. Для тех, кто не сталкивался с разработкой приложений в App Inventor 2, я сделал более подробный гайд по разработке этого приложения (для просмотра нужно перейти на ютуб).

https://www.youtube.com/watch?v=y2jAJ05s2EQ

P.P.S. Сборник из более 100 обучающих материалов по ардуино для начинающих и профи тут.
Онлайн курс по ардуино на гиктаймс здесь.
UPD 1.02.2022: выложил приложение на play market.
Аналогичные проекты с другими шилдами здесь.

Собираем arduino машинку на motor shield l293d и ик пульте

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

управления?
Просто по всем отзывам и разработкам
это самая простая и дешевая
машинка.

При
выборе комплектующих выбор пал на
Arduino UNO
и
Motor Shield L293D.

Почему
именно
Motor
Shield
? Это
связанно с тем что я к тому моменту паять
пробовал в жизни 2 раза. И решил что
использование
шилд паять
не нужно
будет.

Что
мне понадобилось:

1.
Arduino UNO 190
руб.

2.
Motor Shield L293D
100
руб.

3.
Два
мотор редуктора и два колеса. 240 руб.

4.IR приемник пульт ДУ 50 руб.

5.
Источник питания. Я покупал
power bank
за
300 руб. или
тут

Можно
купить
бокс под батарейки 50 руб.

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

7.
ПВХ панель. Обрезок картонки,
фанерки и пр.

8.
мебельное колесико в магазине стоит
около 50 руб.

9.
винтики болтик можно купить руб за 40 в
строительном магазине.

И
того машинку на
Motor Shield L293D
и
ИК
пульте
можно собрать за 670 руб.

Когда
пришли все комплектующие я понял, что
паять
все
таки
нужно
будет.
И на первом этапе мне показалось что
Motor
Shield
не
предназначен
для сборки машинок на
ИК
пульте
управления.

Прочитал
я статьи про
Motor
Shield
и
понял, что стандартную библиотеку
использовать
в данном случае
не получиться. Разобрав
электрическую схему я понял как
можно подключить
I
R приемник и двигателя. Написал небольшой
скетч. Сделал основу из панели ПВХ.
Процесс сборки смотрите в видео. Я
повторил первую
версию машинки в
точности как была сделана.

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

Автосервисв Курске, ремонт автомобилей делают
быстро и качественно.

В
новый
год у меня сломался power
bank.
Я заказал запчасти чтобы его отремонтировать.

Dc-Dc преобразователь

и плата контроля заряда шли больше 2
месяцев. И поэтому машинка у меня стояла,
пылилась.

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

После
того как отпускаем кнопку машинка
останавливается.
Стало намного удобнее.

По просьбе
подписчиков выкладываю скетч. Снять
отдельно видео пока не получается. Если
возникнут вопросы пишите в группу в
контакте:
Arduino Portal-PK.

Нужно поставить
библиотеку для работы со сдвиговым
регистром

#include <Shift595.h> // https://sites.google.com/site/shift595arduino/downloads

Укажите ваши
коты с пульта ДУ

#define POWER_KEY 0x61D66897 // коды пульта ДУ
#define KEY1 0x61D6D02F  // вперед 
#define KEY2 0x61D6A857 // назад
#define KEY3 0x61D618E7  // влево
#define KEY4 0x61D630CF  // вправо

Подключения
IR приемника производиться к пинам серво привода 1 или 2

#define SER1 10
#define SER2 9

IRrecv irrecv(SER1);

Полный код Arduino машинки на Motor Shield L293D и ИК пульте

#include <Shift595.h> // https://sites.google.com/site/shift595arduino/downloads
#include <IRremote.h> 
#define POWER_KEY 0x61D66897 // коды пульта ДУ
#define KEY1 0x61D6D02F  // вперед 
#define KEY2 0x61D6A857 // назад
#define KEY3 0x61D618E7  // влево
#define KEY4 0x61D630CF  // вправо
#define M1A 2 
#define M1B 3 
#define M2A 1
#define M2B 4
#define M4A 0
#define M4B 6
#define M3A 5
#define M3B 7
#define PWM_M1 11
#define PWM_M2 3
#define PWM_M3 6
#define PWM_M4 5
#define SER1 10
#define SER2 9
#define PWRON 7
IRrecv irrecv(SER1);
Shift595 Shifter(8, 12, 4, 1);
decode_results results;
 /* определяем два массива с перечислением пинов для каждого мотора */
unsigned char RightMotor[3] =  {M3A, M3B, PWM_M3};
unsigned char LeftMotor[3] = {M4A, M4B, PWM_M4}; 
long prestro1Millis = 0;        // до мигания ( в целом переменная времени)
int key;
int v= 10;
void setup()
{ 
  irrecv.enableIRIn();
  pinMode(PWRON, OUTPUT); 
  digitalWrite(PWRON, LOW); // включение 74HC595
  pinMode(PWM_M1, OUTPUT); // включение L293D
  pinMode(PWM_M2, OUTPUT); 
  pinMode(PWM_M3, OUTPUT); 
  pinMode(PWM_M4, OUTPUT); 
  digitalWrite(PWM_M1, HIGH);
  digitalWrite(PWM_M2, HIGH);
  digitalWrite(PWM_M3, HIGH);
  digitalWrite(PWM_M4, HIGH);
}
void loop(){
  unsigned long curstro1Millis = millis();  // устанавливаем время в сейчас
  if ((curstro1Millis - prestro1Millis) > 200) // проверяем интервал
  {
  if (irrecv.decode(&results)) {
        if (results.value == KEY1)
          key = 1;
         else if (results.value == KEY2)
          key = 2;
         else if (results.value == KEY3)
          key = 3;
           else if (results.value == KEY4)
          key = 4;
           else if (results.value == POWER_KEY)
           {
            key = 0;
            v= 10;
           }
          if (results.value == 0xFFFFFFFF)
          {
            key = key;
            v= v 10;
          }
        irrecv.resume();// Receive the next value
    }
    else
    {
      key = 0;
      v= 10;
     }
    prestro1Millis = curstro1Millis;
    } 
      if (key == 1){ 
        Motor (RightMotor, v);
        Motor (LeftMotor, v);
     }
     else if (key == 2){
        Motor (RightMotor, -v);
        Motor (LeftMotor, -v);     
     }
     else if (key == 3){
        Motor (RightMotor, -v);
        Motor (LeftMotor, v);
     }
     else if (key == 4){
        Motor (RightMotor, v);
        Motor (LeftMotor, -v);  
     } 
     else if (key == 0) {       
        Motor (RightMotor,0);
        Motor (LeftMotor,0);  
     }
}
   void Motor(unsigned char * motor, int v) {
    if (v>100) v=100;
    if (v<-100) v=-100;
    if (v>0) {
      Shifter.setRegisterPin(motor[0], LOW);
      Shifter.setRegisterPin(motor[1], HIGH);
      digitalWrite(motor[2], v*2.55);
      Serial.println(motor[0]);
    }
    else if (v<0) {
      Shifter.setRegisterPin(motor[0], HIGH);
      Shifter.setRegisterPin(motor[1], LOW);
      digitalWrite(motor[2], (-v)*2.55);
    }
    else {
      Shifter.setRegisterPin(motor[0], LOW);
      Shifter.setRegisterPin(motor[1], LOW);
      digitalWrite(motor[2], 0);
    } 
}

Схема электропитания робота автомобиля

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

Давайте разберем самый простой вариант схемы питания электромоторов. Перед началом сборки лучше заранее припаять провода к моторам.

Схема ардуино робота машинки 2
Схема питания и подключения двигателей в ардуино автомобиле

Все достаточно стандартно и вы найдете в интернете десятки подобных примеров. Но в этой схеме есть большой минус – в случае полного разряда аккумуляторы придут в негодность.

Машинка на Ардуино
Машинка на Ардуино

Для добавления контроллера разряда придется внести следующие изменения в схему:

Схема ардуино робота машинки 3
Схема питания с контролем разряда аккумулятора

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

Питание ардуино
Питание робота Ардуино

Для зарядки можно использовать модуль повышения напряжения с 5v до необходимого уровня зарядки, который зависит от количества серий используемых аккумуляторов. Он имеет гнездо типа микро USB и при частом использовании оно может сломаться, поэтому мы рекомендуем установить дополнительное гнездо для последующей подзарядки пяти вольтовым блоком питания. Для зарядки двух литий-ионных аккумуляторов необходимо настроить выходное напряжение на 8,4 Вольта.

Схема питания ардуино робота машинки
Схема питания с модулем зарядки для ардуино робота машинки
Оцените статью
Радиокоптер.ру
Добавить комментарий

Adblock
detector