Код машинки
C++:
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(9, 10);
// ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ (видны всей программе)
uint16_t rx_mask = 0;
uint32_t last_signal_time = 0;
bool light_state = false; // Хранит состояние света
bool x_was_pressed = false; // Хранит предыдущее состояние кнопки X
int gear = 5; // По умолчанию максимальная скорость
int gear_speeds[] = { 0, 110, 145, 180, 215, 255 }; // Значения ШИМ для передач 0..5
bool c_was_pressed = false;
void setup() {
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
radio.begin();
radio.setChannel(102); // Уходим на чистую частоту 2502 МГц
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
// Настройки подтверждения (делаем ДО startListening)
radio.setAutoAck(true);
radio.setRetries(5, 15);
radio.enableDynamicPayloads(); // Помогает при помехах
radio.openReadingPipe(1, 0x0123456789LL);
radio.startListening(); // Включаем приём в самом конце
}
void loop() {
// 1. ПРОВЕРКА ПАКЕТОВ (Максимально быстро)
if (radio.available()) {
radio.read(&rx_mask, sizeof(rx_mask));
last_signal_time = millis();
}
// 2. ПОТЕРЯ СИГНАЛА
if (millis() - last_signal_time > 500) {
rx_mask = 0;
if (!light_state) { // Если свет был выключен, включаем как аварийку
light_state = true;
digitalWrite(7, HIGH);
}
}
// 3. ИСПОЛНЕНИЕ КОМАНД
bool c_now_pressed = (rx_mask & (1 << 5)); // Кнопка C (бит 5)
if (c_now_pressed && !c_was_pressed) {
gear++;
if (gear > 5) gear = 0; // Сбрасываем на 0 передачу (стоп) после 5-й
}
c_was_pressed = c_now_pressed;
// Текущая скорость из массива в зависимости от передачи
int current_speed = gear_speeds[gear];
// ИСПОЛНЕНИЕ КОМАНД С ШИМ (Пины 5 и 6)
// Движение НАЗАД (Пин 6)
if (rx_mask & (1 << 6)) { // Нажата А
digitalWrite(5, LOW);
analogWrite(6, current_speed);
}
// Движение ВПЕРЁД (Пин 5)
else if (rx_mask & (1 << 4)) { // Нажата B
digitalWrite(6, LOW);
analogWrite(5, current_speed);
}
// Если ничего не нажато — стоп
else {
analogWrite(5, 0);
analogWrite(6, 0);
}
// прямые команды
digitalWrite(3, (rx_mask & (1 << 2)) ? HIGH : LOW); // LEFT
digitalWrite(2, (rx_mask & (1 << 3)) ? HIGH : LOW); // RIGHT
// 4. ЛОГИКА СВЕТА
bool x_now_pressed = (rx_mask & (1 << 8));
if (x_now_pressed && !x_was_pressed) {
light_state = !light_state;
digitalWrite(7, light_state ? HIGH : LOW);
}
x_was_pressed = x_now_pressed;
// 5. ОТЛАДКА (Выводим только при реальных изменениях, чтобы не забивать шину)
static uint16_t prev_rx_mask = 0;
}