Здарова всем, хочу поделиться своим проектом - машинка под управлением nrf24l01. Машинка получилась очень резвая и быстрая.
Управляется за счёт двух джойстиков от приставки. Ездит на 2 колёсах и одной шаровой опоре.
Делалась она из того, что было, а именно, из какого-то светорассеивающего оргстекла, пульт из распределительной коробки. Корпус это две пластинки из светорассеивающего оргстекла, которые скреплены между собой шестью спейсерами длиной 2 см. Размеры машинки: прямоугольник 10x15 см, у которого спереди по бокам срезано два треугольника 2.5x5 cм, высота 2 см. Размер распределительной коробки: 4 см высота, диаметр 10 см.
фото
Перейдём к внутренностям:
КОМПОНЕНТЫ ПУЛЬТА
КОМПОНЕНТЫ МАШИНКИ
СХЕМА МАШИНКИ
СХЕМА ПУЛЬТА
Принцип работы кода. Скорости вычисляются так: у нас есть 4 значения от 0 до 1023, измеряющихся в реальном времени (я решил использовать только два и разбил их на две части каждую, в итоге получили 4). Теперь преобразовываем их так, чтобы при сгибании 1-го джойстика из центра до максимума вперёд получали значения от 0 да 255, и при сгибании из центра назад было бы тоже самое. Со 2-м джойстиком, тоже из центра влево от 0 до 255 и в право от 0 да 255. В первой версии кода мы просто складывали эти скорости, то есть третье с четвёртым прибавляем к первым двум, и скорость движения вперёд просто пишем через if, чтобы можно было стоять . Это лишало нас способности поворачивать при движении вперёд на максимальной скорости. В version 2 (отдельное спасибо Nashatirko за помощь в написании кода) c джойстика, отвечающего за поворот ось Y, мы снимаем коэффициент скорости колеса от 0 да 100, что более разумно. И вот так высчитываем скорость одного колеса: spr = x1p * y2r / 100. Скачать скетчи можно по ссылке.
КОД ПУЛЬТА
КОД МАШИНКИ Version 2
Я думаю, нужно усовершенствовать код. И машинке хорошо бы придумать применение, чтоб она не только была как игрушка для детей. К примеру, сверху держатель для бутылки приделать, чтобы возить напитки, не вставая с дивана, но это слишком просто. Предлагайте свои идеи по поводу кода и апгрейда. Кстати скоро выйдет версия с камерой как у Алекса.
Управляется за счёт двух джойстиков от приставки. Ездит на 2 колёсах и одной шаровой опоре.
Делалась она из того, что было, а именно, из какого-то светорассеивающего оргстекла, пульт из распределительной коробки. Корпус это две пластинки из светорассеивающего оргстекла, которые скреплены между собой шестью спейсерами длиной 2 см. Размеры машинки: прямоугольник 10x15 см, у которого спереди по бокам срезано два треугольника 2.5x5 cм, высота 2 см. Размер распределительной коробки: 4 см высота, диаметр 10 см.
фото
Перейдём к внутренностям:
КОМПОНЕНТЫ ПУЛЬТА
- arduino nano
- nrf24l01 без антенны c адаптером
- Аккумулятор 610мАч 7.4А (две банки)
- Джойстики X2
- Выключатель
КОМПОНЕНТЫ МАШИНКИ
- arduino nano
- nrf24l01 с антенной и адаптером
- Аккумулятор 610мАч 7.4В (две банки)
- Драйвер моторов двухканальный Pololu на TB6612FNG v2 <1А
- Мотор-редуктор Gekko MR12-050 turbo X2
- Колесо Pololu 32x7 X2
- Выключатель
СХЕМА МАШИНКИ
СХЕМА ПУЛЬТА
Принцип работы кода. Скорости вычисляются так: у нас есть 4 значения от 0 до 1023, измеряющихся в реальном времени (я решил использовать только два и разбил их на две части каждую, в итоге получили 4). Теперь преобразовываем их так, чтобы при сгибании 1-го джойстика из центра до максимума вперёд получали значения от 0 да 255, и при сгибании из центра назад было бы тоже самое. Со 2-м джойстиком, тоже из центра влево от 0 до 255 и в право от 0 да 255. В первой версии кода мы просто складывали эти скорости, то есть третье с четвёртым прибавляем к первым двум, и скорость движения вперёд просто пишем через if, чтобы можно было стоять . Это лишало нас способности поворачивать при движении вперёд на максимальной скорости. В version 2 (отдельное спасибо Nashatirko за помощь в написании кода) c джойстика, отвечающего за поворот ось Y, мы снимаем коэффициент скорости колеса от 0 да 100, что более разумно. И вот так высчитываем скорость одного колеса: spr = x1p * y2r / 100. Скачать скетчи можно по ссылке.
КОД ПУЛЬТА
C++:
/* Данный скетч модернизация скетча 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)); //отправляем получившийся массив
}
C++:
/* Данный скетч модернизация скетча 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);
}
}
}
Всем спасибо за внимание!
Изменено: