Добрый день. Понадобилось сделать свой пульт управления и приемник для лодки. Есть готовый проект на двух NRF24L01 (How To Make 6-Channel Radio Control. Range 2000m+ – RC Models, DIY Hobby Elektronics, Arduino projects, RC Airplanes) , все работает, я проверил, но мне нужно чтобы модуль NRF24L01 который используется в качестве приемника и стоит на борту лодки, мог бы отправлять значение напряжения бортового аккумулятора на пульт. На пульте допустим стоит OLED экран и выводит это напряжение. Это нужно чтобы не потерять лодку из-за разряда АКБ. Сам я в программировании мало что понимаю, но я целый день просидел с ChatGPT и он мне выдал код, который по его мнению должен работать, но он не работает и даже джойстик перестал работать. Не подскажите в чем проблема?
Код для приемника на лодке:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
int ch_width_1 = 0;
int ch_width_2 = 0;
int ch_width_3 = 0;
int ch_width_4 = 0;
int ch_width_5 = 0;
int ch_width_6 = 0;
Servo ch1;
Servo ch2;
Servo ch3;
Servo ch4;
Servo ch5;
Servo ch6;
struct Signal {
byte throttle;
byte pitch;
byte roll;
byte yaw;
byte aux1;
byte aux2;
int voltage; // Добавлено: поле для напряжения
};
Signal data;
const uint64_t pipeIn = 0xABCDABCD71LL;
const uint64_t pipeOut = 0xE8E8F0F0E1LL;
RF24 radio(9, 10);
void ResetData() {
data.throttle = 0;
data.pitch = 127;
data.yaw = 127;
data.aux1 = 0;
data.aux2 = 0;
data.voltage = 0; // Добавлено: сброс значения напряжения
}
void setup() {
ch1.attach(2);
ch2.attach(3);
ch3.attach(4);
ch4.attach(5);
ch5.attach(6);
ch6.attach(7);
ResetData();
radio.begin();
radio.openReadingPipe(1,pipeIn);
radio.openWritingPipe(pipeOut);
radio.setChannel(100);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
radio.startListening(); // Начинаем с режима прослушивания
}
unsigned long lastRecvTime = 0;
void recvData() {
while ( radio.available() ) {
radio.read(&data, sizeof(Signal));
lastRecvTime = millis();
}
}
void loop() {
recvData();
unsigned long now = millis();
if ( now - lastRecvTime > 1000 ) {
ResetData();
}
data.voltage = analogRead(A0); // Добавлено: чтение напряжения с порта A0
ch_width_1 = map(data.roll, 0, 255, 1000, 2000);
ch_width_2 = map(data.pitch, 0, 255, 1000, 2000);
ch_width_3 = map(data.throttle, 0, 255, 1000, 2000);
ch_width_4 = map(data.yaw, 0, 255, 1000, 2000);
ch_width_5 = map(data.aux1, 0, 1, 1000, 2000);
ch_width_6 = map(data.aux2, 0, 1, 1000, 2000);
ch1.writeMicroseconds(ch_width_1);
ch2.writeMicroseconds(ch_width_2);
ch3.writeMicroseconds(ch_width_3);
ch4.writeMicroseconds(ch_width_4);
ch5.writeMicroseconds(ch_width_5);
ch6.writeMicroseconds(ch_width_6);
radio.stopListening(); // Останавливаем прослушивание
radio.write(&data, sizeof(Signal)); // Отправляем данные напряжения
radio.startListening(); // Снова начинаем прослушивание
}
А это код для пульта с экраном OLED
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
const uint64_t pipeIn = 0xE8E8F0F0E1LL; // NOTE: The address in the Transmitter and Receiver code must be the same "0xE8E8F0F0E1LL"
const uint64_t pipeOut = 0xABCDABCD71LL; // NOTE: The address in the Transmitter and Receiver code must be the same "0xABCDABCD71LL"
RF24 radio(9, 10); // select CE,CSN pin
struct Signal {
byte throttle;
byte pitch;
byte roll;
byte yaw;
byte aux1;
byte aux2;
};
struct Voltage {
int voltage;
};
Signal data;
Voltage voltageData;
void ResetData()
{
data.throttle = 0;
data.pitch = 127;
data.roll = 127;
data.yaw = 127;
data.aux1 = 0;
data.aux2 = 0;
voltageData.voltage = 0; // Добавлено: сброс значения напряжения
}
void setup() {
radio.begin();
radio.openReadingPipe(1,pipeIn);
radio.openWritingPipe(pipeOut);
radio.setChannel(100);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS); // The lowest data rate value for more stable communication
radio.setPALevel(RF24_PA_MAX); // Output power is set for maximum range
radio.startListening(); // Start the radio comunication for Transmitter
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Voltage:");
display.display();
}
int Border_Map(int val, int lower, int middle, int upper, bool reverse)
{
val = constrain(val, lower, upper);
if ( val < middle )
val = map(val, lower, middle, 0, 128);
else
val = map(val, middle, upper, 128, 255);
return ( reverse ? 255 - val : val );
}
void loop() {
data.roll = Border_Map( analogRead(A3), 0, 512, 1023, true ); // CH1 Note: "true" or "false" for signal direction
data.pitch = Border_Map( analogRead(A0), 0, 512, 1023, true ); // CH2
data.throttle = Border_Map( analogRead(A2),0, 340, 570, true ); // CH3 Note: For Single side ESC |
// data.throttle = Border_Map( analogRead(A2),0, 512, 1023, true ); // CH3 Note: For Bidirectional ESC |
data.yaw = Border_Map( analogRead(A1), 0, 512, 1023, false ); // CH4
data.aux1 = digitalRead(0); // CH5
data.aux2 = digitalRead(3); // CH6
radio.stopListening(); // Останавливаем прослушивание
radio.write(&data, sizeof(Signal)); // Отправляем данные
radio.startListening(); // Снова начинаем прослушивание
if (radio.available()) {
radio.read(&voltageData, sizeof(Voltage)); // Принимаем данные
display.clearDisplay();
display.setCursor(0,0);
display.println("Voltage:");
display.println(voltageData.voltage); // Вывод значения напряжения на OLED экран
display.display();
}
}
Это код приемника из готового проекта который работает, но без вольтметра
//Receiver
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
int ch_width_1 = 0;
int ch_width_2 = 0;
int ch_width_3 = 0;
int ch_width_4 = 0;
int ch_width_5 = 0;
int ch_width_6 = 0;
Servo ch1;
Servo ch2;
Servo ch3;
Servo ch4;
Servo ch5;
Servo ch6;
struct Signal {
byte throttle;
byte pitch;
byte roll;
byte yaw;
byte aux1;
byte aux2;
};
Signal data;
const uint64_t pipeIn = 0xABCDABCD71LL;
RF24 radio(9, 10);
void ResetData()
{
data.throttle = 0; // Define the inicial value of each data input.
data.pitch = 127;
data.yaw = 127;
data.aux1 = 0;
data.aux2 = 0;
}
void setup()
{
// Set the pins for each PWM signal
ch1.attach(2);
ch2.attach(3);
ch3.attach(4);
ch4.attach(5);
ch5.attach(6);
ch6.attach(7);
ResetData(); // Configure the NRF24 module
radio.begin();
radio.openReadingPipe(1,pipeIn);
radio.setChannel(100);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS); // The lowest data rate value for more stable communication
radio.setPALevel(RF24_PA_MAX); // Output power is set for maximum
radio.startListening(); // Start the radio comunication for receiver
}
unsigned long lastRecvTime = 0;
void recvData()
{
while ( radio.available() ) {
radio.read(&data, sizeof(Signal));
lastRecvTime = millis(); // Receive the data
}
}
void loop()
{
recvData();
unsigned long now = millis();
if ( now - lastRecvTime > 1000 ) {
ResetData(); // Signal lost.. Reset data
}
ch_width_1 = map(data.roll, 0, 255, 1000, 2000);
ch_width_2 = map(data.pitch, 0, 255, 1000, 2000);
ch_width_3 = map(data.throttle, 0, 255, 1000, 2000);
ch_width_4 = map(data.yaw, 0, 255, 1000, 2000);
ch_width_5 = map(data.aux1, 0, 1, 1000, 2000);
ch_width_6 = map(data.aux2, 0, 1, 1000, 2000);
ch1.writeMicroseconds(ch_width_1); // Write the PWM signal
ch2.writeMicroseconds(ch_width_2);
ch3.writeMicroseconds(ch_width_3);
ch4.writeMicroseconds(ch_width_4);
ch5.writeMicroseconds(ch_width_5);
ch6.writeMicroseconds(ch_width_6);
}
А это код передатчика - пульта из готового проекта , который работает, но нет вольтметра
//Transmitter
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
const uint64_t pipeOut = 0xABCDABCD71LL; // NOTE: The address in the Transmitter and Receiver code must be the same "0xABCDABCD71LL"
RF24 radio(9, 10); // select CE,CSN pin
struct Signal {
byte throttle;
byte pitch;
byte roll;
byte yaw;
byte aux1;
byte aux2;
};
Signal data;
void ResetData()
{
data.throttle = 0;
data.pitch = 127;
data.roll = 127;
data.yaw = 127;
data.aux1 = 0;
data.aux2 = 0;
}
void setup()
{
// Configure the NRF24 module
radio.begin();
radio.openWritingPipe(pipeOut);
radio.setChannel(100);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS); // The lowest data rate value for more stable communication
radio.setPALevel(RF24_PA_MAX); // Output power is set for maximum range
radio.stopListening(); // Start the radio comunication for Transmitter
ResetData();
}
// Joystick center and its borders
int Border_Map(int val, int lower, int middle, int upper, bool reverse)
{
val = constrain(val, lower, upper);
if ( val < middle )
val = map(val, lower, middle, 0, 128);
else
val = map(val, middle, upper, 128, 255);
return ( reverse ? 255 - val : val );
}
void loop()
{
data.roll = Border_Map( analogRead(A3), 0, 512, 1023, true ); // CH1 Note: "true" or "false" for signal direction
data.pitch = Border_Map( analogRead(A0), 0, 512, 1023, true ); // CH2
data.throttle = Border_Map( analogRead(A2),0, 340, 570, true ); // CH3 Note: For Single side ESC |
// data.throttle = Border_Map( analogRead(A2),0, 512, 1023, true ); // CH3 Note: For Bidirectional ESC |
data.yaw = Border_Map( analogRead(A1), 0, 512, 1023, false ); // CH4
data.aux1 = digitalRead(0); // CH5
data.aux2 = digitalRead(3); // CH6
radio.write(&data, sizeof(Signal));
}