Проблема при подключении двух arduino с NRF24L01

Я новичок в программировании Arduino, так что эта программа также немного длинна, извините за неудобства. Я сделал программу для бесконтактного управления серводвигателем и светодиодом(7 номеров), используя ARDUINO UNO, Funduino Joy stick shield V1.A и NRF24L01.Сначала я подготовил программу (используя массив) только для управления светодиодами, и она стала успешной, поскольку светодиоды работают в соответствии с программой.Затем я добавил серводвигатель также в схему и внес некоторые изменения в существующую светодиодную программу. К сожалению, результат получается неустойчивым.входной сигнал joy stick прерывает светодиодный сигнал, и через некоторое время серводвигатель реагирует на светодиодный вход .Код передачи и код приемника приведены ниже.

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

ПЕРЕДАТЧИК

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

>



#define xAxis A0   
RF24 radio(9,10);
const uint64_t pipe = 0xF0F0F0F0D2L;

int msg[1];
int buttonPin1 = 2;
int buttonPin2 = 3;
int buttonPin3 = 4;
int buttonPin4 = 5;
int buttonPin5 = 6;
int buttonPin6 = 7;
int buttonPin7 = 8;
int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;
int buttonState6 = 0;
int buttonState7 = 0;


void setup(void)
{
  radio.begin();
  radio.openWritingPipe(pipe);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);
  pinMode(buttonPin6, INPUT_PULLUP);
  pinMode(buttonPin7, INPUT_PULLUP);
}

void loop(void)
{
  int potValue = analogRead(A0);                              //  INPUT FOR SERVO MOTOR
  int angleValue = map(potValue, 0, 1023, 0, 180); // INPUT FOR SERVO MOTOR
  radio.write(&angleValue, sizeof(angleValue));         // INPUT FOR SERVO MOTOR

  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  buttonState4 = digitalRead(buttonPin4);
  buttonState5 = digitalRead(buttonPin5);
  buttonState6 = digitalRead(buttonPin6);
  buttonState7 = digitalRead(buttonPin7);


 if (buttonState1 == LOW){
    msg[0] = 111;
    radio.write(msg, 1);               // INPUT FOR LED1
   }
 if (buttonState2 == LOW){ 
    msg[0] = 222;
    radio.write(msg, 1);               // INPUT FOR LED2
   }
 if (buttonState3 == LOW){
    msg[0] = 212;
    radio.write(msg, 1);               // INPUT FOR LED3
   }  
 if (buttonState4 == LOW){
    msg[0] = 216;
    radio.write(msg, 1);                 // INPUT FOR LED4
   }
 if (buttonState5 == LOW){
    msg[0] = 218;
    radio.write(msg, 1);                // INPUT FOR LED5
   }
 if (buttonState6 == LOW){
    msg[0] = 220;
    radio.write(msg, 1);                 // INPUT FOR LED6
   }
    if (buttonState7 == LOW){
    msg[0] = 224;
    radio.write(msg, 1);
   }                                              // INPUT FOR LED7

  }

РЕСИВЕР

 #include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>  
#include <Servo.h>  // SERVO LIBRARY INCLUDED

Servo myServo; 
RF24 radio(9,10);
const uint64_t pipe = 0xF0F0F0F0D2L;

int led1 = 2;
int led2 = A2;
int led3 = 4;
int led4 = 5;
int led5 = 6;
int led6 = 7;
int led7 = 8;
int msg[1];
int angleValue ;

void setup(void)
{
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1, pipe);
  radio.startListening();
  myServo.attach(3);                  // СЕРВОПРИВОД, ПОДКЛЮЧЕННЫЙ К КОНТАКТУ 3
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
}
void loop(void)
{
   // Код приема для светодиода от 1 до светодиода 7

  if(radio.available()){
    bool done = false;
    while (!done) {
    done = radio.read(msg, 1);
    Serial.println(msg[0]);

    if (msg[0] == 111) {
      digitalWrite(led1, HIGH);
      digitalWrite(led7, LOW);
      }
    if(msg[0] == 222){
        digitalWrite(led1, LOW);
        digitalWrite(led2, HIGH);
        digitalWrite(led7, LOW);
        }
     else if (msg[0] == 111){
          digitalWrite(led2, LOW);
        }
     else if(msg[0] == 212){

          digitalWrite(led3, HIGH);
        }
    else if(msg[0] == 216){
          digitalWrite(led4, HIGH);
        }
    else if(msg[0] == 218){
          digitalWrite(led5, HIGH);
        }
    else if(msg[0] == 220){
          digitalWrite(led6, HIGH);
        }
    else if(msg[0] == 224){
          digitalWrite(led7, HIGH);
          digitalWrite(led1, LOW);
          digitalWrite(led2, LOW);
        delay(10);
        }
      }
   }

//Получение кода для серводвигателя

    if(radio.available()){           
      bool done = false;             
      while (!done) {
      done = radio.read(&angleValue,sizeof (angleValue) );
      myServo.write(angleValue);}
      delay(10);
     }
                  //Код приема светодиодов
      else {   
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      digitalWrite(led5, LOW);
      digitalWrite(led6, LOW);

      }
 }

Я попытался сделать программу, используя "struct" для состояния 6 кнопок и одного входного сигнала угла для управления с помощью 6 светодиодов и одного сервопривода, и она работает нормально(программа упомянута ниже). Но проблема в том, что когда я добавляю еще два входных сигнала, время выхода становится неустойчивым, и выход не получается в соответствии с программой.Пожалуйста, помогите изменить программу. передатчик

#include <SPI.h>
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#define CE_PIN   9
#define CSN_PIN 10
const uint64_t pipe = 0xE8E8F0F0E1LL;
RF24 radio(CE_PIN, CSN_PIN);
int upbut = 2;
int rightbut = 3;
int downbut = 4;
int leftbut = 5;
int nuetral = 6;
int starte = 7;
int stope = 8;
struct data {
    uint8_t leds;
    uint8_t angle;
};
struct data packet;
void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);
  pinMode(upbut,INPUT_PULLUP);
  digitalWrite(upbut,LOW);
  pinMode(rightbut,INPUT_PULLUP);
  digitalWrite(rightbut,LOW);
   pinMode(downbut,INPUT_PULLUP);
  digitalWrite(downbut,LOW);
  pinMode(leftbut,INPUT_PULLUP);
  digitalWrite(leftbut,LOW);
  pinMode(nuetral,INPUT_PULLUP);
  digitalWrite(nuetral,LOW);
  pinMode(starte,INPUT_PULLUP);
  digitalWrite(starte,LOW);
  pinMode(stope,INPUT_PULLUP);
  digitalWrite(stope,LOW);
  //end pinMode and digitalWrite
}//--(end setup )---
void loop(){
int potValue = analogRead(A0);
packet.angle = map(potValue, 0, 1023, 0, 180);

packet.leds = 0;
packet.leds = digitalRead(upbut) ? 0x00 : 0x01;
packet.leds |= digitalRead(rightbut) ? 0x00 : 0x02;
packet.leds |= digitalRead(downbut) ? 0x00 : 0x04;
packet.leds |= digitalRead(leftbut) ? 0x00 : 0x08;
packet.leds |= digitalRead(nuetral) ? 0x00 : 0x10;
packet.leds |= digitalRead(starte) ? 0x00 : 0x20;
/*packet.leds |= digitalRead(starte) ? 0x00 : 0x30;*/

radio.write((uint8_t *)&packet, sizeof(struct data));
}

приемник

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

#include <Servo.h>
#define CE_PIN 6
#define CSN_PIN 7
const uint64_t pipe = 0xE8E8F0F0E1LL;
RF24 radio(CE_PIN, CSN_PIN); 
const int servo1 = 9;
int servoVal;
Servo myservo1;
struct data {
    uint8_t leds;
    uint8_t angle;
};
struct data packet;
int led1 = 2; // digital out put
int led2 = 3; // digital out put
int led3 = 4; // digital out put
int led4 = 5; // digital out put
int led5 = 8; // digital out put
int led6 = A0; // digital out put
int led7 = A1; // digital out put
void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);
  myservo1.attach(servo1); // attaches the servo1 /analog output

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);
  Serial.println("Nrf24L01 Receiver Starting");
  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();;
}                             //--(end setup )---

void loop(){

if (radio.available()) {
    radio.read((uint8_t *)&packet, sizeof(struct data));
    myservo1.write(packet.angle);
   if (packet.leds ==0x01){
    digitalWrite(led1, packet.leds & 0x01);
    digitalWrite(led2, packet.leds & 0x00);
    digitalWrite(led6, packet.leds & 0x00);
    }
   else if (packet.leds ==0x02){
    digitalWrite(led2, packet.leds & 0x02);
    digitalWrite(led1, packet.leds & 0x00);
    digitalWrite(led6, packet.leds & 0x00);
    }
    else if (packet.leds ==0x20){
    digitalWrite(led6, packet.leds & 0x20);
    digitalWrite(led1, packet.leds & 0x00);
    digitalWrite(led2, packet.leds & 0x00);
    }
    digitalWrite(led3, packet.leds & 0x04);
    digitalWrite(led4, packet.leds & 0x08);
    digitalWrite(led5, packet.leds & 0x10);

   /*digitalWrite(led7, packet.leds & 0x30);*/
}
}

, 👍0

Обсуждение

Вы посылаете два байта, каждый из которых несет различную информацию (значения светодиода и сервопривода), но у вас нет никакого способа отличить их друг от друга. Подумайте о том, что происходит, когда один байт теряется при передаче. Все будет идти не в ногу. Возможно, вам следует отправлять только полные сообщения с разделителем, который отмечает конец пакета. Внутри этого пакета вы можете использовать позиции байтов. Также, возможно, вам нужно какое-то обнаружение/исправление ошибок., @chrisl

В системах nRF нет необходимости в разделителях - они посылают дискретные пакеты., @Majenko


1 ответ


1

Весь ваш метод совершенно неверен.

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

Вам нужно либо:

  • Отправьте значение байта(ов) вместе с байтом(ов) или
  • Отправляйте всю информацию каждый раз в заранее определенные промежутки времени.

Из двух вариантов я бы предпочел последний, используя структуру:

struct data {
    uint8_t leds;
    uint8_t angle;
};

А потом:

struct data packet;

int potValue = analogRead(A0);
packet.angle = map(potValue, 0, 1023, 0, 180);

packet.leds = 0;
packet.led |= digitalRead(buttonPin1) ? 0x00 : 0x01;
packet.led |= digitalRead(buttonPin2) ? 0x00 : 0x02;
packet.led |= digitalRead(buttonPin3) ? 0x00 : 0x04;
packet.led |= digitalRead(buttonPin4) ? 0x00 : 0x08;
packet.led |= digitalRead(buttonPin5) ? 0x00 : 0x10;
packet.led |= digitalRead(buttonPin6) ? 0x00 : 0x20;

radio.write((uint8_t *)&packet, sizeof(struct data));

Тогда при чтении вы делаете прямо противоположное:

struct data packet;

if (radio.available()) {
    radio.read((uint8_t *)&packet, sizeof(struct data));
    myServo.write(packet.angle);
    digitalWrite(led1, packet.leds & 0x01);
    digitalWrite(led2, packet.leds & 0x02);
    digitalWrite(led3, packet.leds & 0x04);
    digitalWrite(led4, packet.leds & 0x08);
    digitalWrite(led5, packet.leds & 0x10);
    digitalWrite(led6, packet.leds & 0x20);
}

Структура объединяет несколько переменных в один блок данных, предоставляя вам легкий доступ по имени к различным частям. Один из них, переменная leds, затем используется в качестве растрового изображения того, включен ли каждый светодиод (1) или выключен (0). Таким образом, вы можете отправить текущее состояние до 8 светодиодов всего за один байт. Если вы хотите расширить его, чтобы отправлять различные комбинации светодиодов, просто измените, какие биты байта установлены.

Если вы хотите "переключить" светодиоды, то необходимо будет сохранить запись у отправителя состояний и отправить ее вместо необработанных данных кнопки.

,

До 6 светодиодов и один угловой вход работают нормально.Но я добавил один светодиод и угол ввода больше, чтобы время вывода стало неустойчивым.#include, @SREEKe