Состояние цифрового вывода Arduino не передается через NRF24L01, тогда как состояние аналогового вывода передается, почему?

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

Transmitter Code:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include <Wire.h>

//Определяем цифровые входы
#define tGL1 7
#define tGL2 6
#define b1 5
#define b2 4
#define b3 3
#define b4 2


const int MPU = 0x68; // I2C-адрес MPU6050
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY;
float angleX, angleY;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY;
float elapsedTime, currentTime, previousTime;
int c = 0;

RF24 radio(9,10);
const byte address[6]="00001";

struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j2PotX;
  byte j2PotY;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
  byte tSwitch1;
  byte tSwitch2;
  byte pot1;
  byte pot2;
};

Data_Package data;


void setup() {
  // поместите сюда код установки для однократного запуска:
  Serial.begin(9600);
  initialize_MPU6050();

  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);

  pinMode(tGL1, INPUT_PULLUP);
  pinMode(tGL2, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);
  pinMode(b4, INPUT_PULLUP);

   data.j1PotX = 127; // Значения от 0 до 255. Когда джойстик находится в положении покоя, значение находится посередине, или 127. Фактически мы отображаем значение горшка от 0 до 1023 до 0 до 255, потому что это одно БАЙТОВОЕ значение
   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;

}

void loop() {
  // поместите сюда ваш основной код для многократного запуска:
  data.j1PotX = map(analogRead(A2), 0, 1023, 0, 255); // Преобразование аналогового считываемого значения от 0 до 1023 в значение BYTE от 0 до 255
  data.j1PotY = map(analogRead(A1), 0, 1023, 0, 255);
  data.j2PotX = map(analogRead(A3), 0, 1023, 0, 255);
  data.j2PotY = map(analogRead(A0), 0, 1023, 0, 255);
  data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
  data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);

  data.tSwitch2 = digitalRead(tGL2);

  data.button1 = digitalRead(b1);
  data.button2 = digitalRead(b2);
  data.button3 = digitalRead(b3);
  data.button4 = digitalRead(b4);

  if (digitalRead(tGL1) == 0) {
    read_IMU();    // Используйте MPU6050 вместо джойстика 1 для управления движением влево, вправо, вперед и назад
  }

  radio.write(&data, sizeof(Data_Package));
}

Это код получателя

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10);   // nRF24L01 (СЕ, ДНС)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
// Максимальный размер этой структуры 32 байта - предел буфера NRF24L01
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j2PotX;
  byte j2PotY;
  byte pot1;
  byte pot2;
  byte tSwitch1;
  byte tSwitch2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
};
Data_Package data; //Создаем переменную с указанной выше структурой
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(); // Установите модуль в качестве получателя
  resetData();
}
void loop() {
  // Проверяем, есть ли данные для приема
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package)); // Читаем все данные и сохраняем их в структуру 'data'
    lastReceiveTime = millis(); // В этот момент мы получили данные
  }
  // Проверяем, продолжаем ли мы получать данные, или у нас есть связь между двумя модулями
  currentTime = millis();
  if ( currentTime - lastReceiveTime > 1000 ) { // Если текущее время больше 1 секунды с момента получения последних данных, это означает, что мы потеряли соединение
    resetData(); // Если соединение потеряно, сбрасываем данные. Это предотвращает нежелательное поведение, например, если у дрона есть газ, и мы теряем связь, он может продолжать летать, пока мы не сбросим значения.
  }
  // Печатаем данные в Serial Monitor
  Serial.print("j1PotX: ");
  Serial.print(data.j1PotX);
  Serial.print("; j1PotY: ");
  Serial.print(data.j1PotY);
  Serial.print("; button1: ");
  Serial.print(data.button1);
  Serial.print("; j2PotX: ");
  Serial.println(data.j2PotX); 
}

Когда я печатаю статус кнопок и джойстика в моем передатчике (джойстике), я получаю правильный статус моей кнопки, когда я нажимаю, но статус моей кнопки остается неизменным в последовательном мониторе моего приемника, несмотря на наличие изменить другие значения (я имею в виду, что аналоговое значение передается правильно)

Это скриншот обоих мониторов с последовательным интерфейсом. COM7 является моим передатчиком, но COM6 является приемником, но изменение состояния кнопки 1 означает, что COM7 не производится в COM6

, 👍0

Обсуждение

Подсказка: общий заголовочный файл со структурой сообщения поможет избежать этой проблемы. Расположение структур не то же самое :), @Mikael Patel


1 ответ


Лучший ответ:

2

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

Transmitter               Receiver
=====================     =====================
struct Data_Package {     struct Data_Package {
      byte j1PotX;    ->      byte j1PotX;
      byte j1PotY;    ->      byte j1PotY;
      byte j2PotX;    ->      byte j2PotX;
      byte j2PotY;    ->      byte j2PotY;
      byte button1;   ->      byte pot1;
      byte button2;   ->      byte pot2;
      byte button3;   ->      byte tSwitch1;
      byte button4;   ->      byte tSwitch2;
      byte tSwitch1;  ->      byte button1;
      byte tSwitch2;  ->      byte button2;
      byte pot1;      ->      byte button3;
      byte pot2;      ->      byte button4;
};                        };

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

Лучший способ избежать этой проблемы — создать один заголовочный файл (сделайте его библиотекой, чтобы было проще делиться), содержащий структуру пакета. Затем, если вы когда-нибудь внесете какие-либо изменения в пакет, все скетчи, которые его используют, увидят это изменение при следующей компиляции.

,

Означает ли это, что мне нужно создать файл с расширением .h, а затем импортировать его с помощью #include?, @Abel C Dixon

Да. Если вы создадите этот файл как Documents\Arduino\libraries\PacketFormat\PacketFormat.h, вы можете просто #include <PacketFormat.h> в любой скетч, чтобы получить структуру., @Majenko