Сообщение передается несколько раз от одного arduino к другому с помощью nRF24L01
Я пытаюсь построить двунаправленный канал связи, используя nRF24L01 и два arduino. Сообщение вводится с помощью кнопки (but) в азбуке Морзе, декодируется и затем отправляется при нажатии другой кнопки (but_send). Хотя все вроде бы работает нормально, сообщение отправляется несколько раз, хотя я и добавил задержки. Я новичок в Arduino и понятия не имею, что еще я мог бы сделать. Я даже попытался удалить строку сразу после radio.write, но, похоже, это тоже не сработало. Если у кого-то есть идея, пожалуйста, помогите!
Вот эти два кода. Они довольно похожи, но я добавил их на всякий случай:
#include <LiquidCrystal.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
struct record
{
char mesaj[10];
boolean state = 1;
};
typedef struct record Record;
Record button_state, button_state1 ;
RF24 radio(9, 10); // CE, CSN(pini nrf01)
const byte addresses [][6] = {"00001", "00002"}; //Setting the two addresses. One for transmitting and one for receiving
String code = "";
int len = 0;
char ch;
int ok;
char new_char;
int i1 = 0;
int i2 = 1;
const int but_send = 8;
const int but = 5;
const int led = 4;
const int del = 3;
String a = "";
unsigned long pres_len = 0, rel_time, pres_time = 0, old_time_len = 0, old_pres = 0, space = 0;
int state = 0;
int unit_delay = 250;
int min_delay = 10;
int buttonState = 0;
char MakeString()
{
if (pres_len < (unit_delay * 3) && pres_len > 50)
{
return '.'; //if button press less than 0.6sec, it is a dot
}
else if (pres_len > (unit_delay * 3))
{
return '-'; //if button press more than 0.6sec, it is a dash
}
}
void Morse_decod()
{
static String morse[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "!"
};
int i = 0;
while (morse[i] != "!")
{
if (morse[i] == code)
{
Serial.print(char('A' + i));
a = a + char('A' + i);
Serial.print(" ");
}
if (morse[i] == "!")
{
Serial.println("");
Serial.println("This code is not exist!");
}
code = "";
}
void sendText()
{
// Aici trebuie sa fe codul pentru trimiterea efectiva a msj
if (ok == 1) {
Serial.println("Lavinia:" + a);
}
ok = 0;
delay(100);
}
void setup() {
Serial.begin(9600);
pinMode(but, INPUT_PULLUP);
pinMode(but_send, INPUT_PULLUP);
pinMode(del, INPUT_PULLUP);
pinMode(led, OUTPUT);
radio.begin(); //Starting the radio communication
radio.openWritingPipe(addresses[0]); //Setting the address at which we will send the data
radio.openReadingPipe(1, addresses[1]); //Setting the address at which we will receive the data
radio.setPALevel(RF24_PA_MIN); //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.
}
void loop() {
label:
while (digitalRead(but) == HIGH) {
delay(5);
radio.startListening();
if (radio.available()) //Looking for incoming data
{
radio.read(&button_state, sizeof(button_state));
if (button_state.state == 0)
{
ok = 1;
sendText();
String final = "";
for (int i = 0; i < strlen(button_state.mesaj); i++)
{
final += String(button_state.mesaj[i]);
}
ok = 1;
Serial.println("Iulia: " + final);
button_state.state = 1;
radio.stopListening();
}
else
{
//nu se intampla nimic daca eu nu am trimis mesaj
}
delay(5);
radio.stopListening(); //This sets the module as transmitter
button_state1.state = digitalRead(but_send);
int n = a.length();
char char_array[n + 1];
strcpy(char_array, a.c_str());
strcpy(button_state1.mesaj, char_array);
radio.write(&button_state1, sizeof(button_state1)); //Sending the data
}
if (digitalRead(del) == LOW && a[0] != '\0' ) {
Serial.println("Deleted string");
a = "\0";
Serial.println(a);
}
}
old_pres = rel_time;
pres_time = millis();
digitalWrite(led, HIGH);
while (digitalRead(but) == LOW) {}
rel_time = millis();
digitalWrite(led, LOW);
pres_len = rel_time - pres_time;
space = pres_time - old_pres;
if (pres_len > min_delay)
{
code += MakeString();
}
while ((millis() - rel_time) < (unit_delay * 3))
{
if (digitalRead(but) == LOW)
{
goto label;
}
}
Morse_decod();
delay(1000);
}
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN(pini nrf01)
#include <LiquidCrystal.h>
struct record
{
char mesaj[10];
boolean state = 1;
};
typedef struct record Record;
const byte addresses [][6] = {"00001", "00002"}; //Setting the two addresses. One for transmitting and one for receiving
String code = "";
int len = 0;
char ch;
int ok;
int ok2;
char new_char;
int i1 = 0;
int i2 = 1;
const int but_send = 8;
const int but = 5;
const int led = 4;
const int del = 3;
String a = "";
unsigned long pres_len = 0, rel_time, pres_time = 0, old_time_len = 0, old_pres = 0, space = 0;
int state = 0;
int unit_delay = 250;
int min_delay = 10;
Record button_state, button_state1 ;
char MakeString()
{
if (pres_len < (unit_delay * 3) && pres_len > 50)
{
return '.'; //if button press less than 0.6sec, it is a dot
}
else if (pres_len > (unit_delay * 3))
{
return '-'; //if button press more than 0.6sec, it is a dash
}
}
void Morse_decod()
{
static String morse[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "!"
};
int i = 0;
while (morse[i] != "!")
{
if (morse[i] == code)
{
Serial.print(char('A' + i));
a = a + char('A' + i);
Serial.print(" ");
}
if (morse[i] == "!")
{
Serial.println("");
Serial.println("This code is not exist!");
}
code = "";
}
void sendText()
{
// Aici trebuie sa fe codul pentru trimiterea efectiva a msj
if (ok == 1) {
Serial.println("Iulia:" + a);
}
ok = 0;
delay(100);
}
void setup() {
Serial.begin(9600);
pinMode(but, INPUT_PULLUP);
pinMode(but_send, INPUT_PULLUP);
pinMode(del, INPUT_PULLUP);
pinMode(led, OUTPUT);
radio.begin(); //Starting the radio communication
radio.openWritingPipe(addresses[1]); //Setting the address at which we will send the data
radio.openReadingPipe(1, addresses[0]); //Setting the address at which we will receive the data
radio.setPALevel(RF24_PA_MIN); //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.
}
void loop() {
label:
while (digitalRead(but) == HIGH) {
delay(5);
radio.stopListening(); //This sets the module as transmitter
button_state.state = digitalRead(but_send);
int n = a.length();
char char_array[n + 1];
strcpy(char_array, a.c_str());
strcpy(button_state.mesaj, char_array);
radio.write(&button_state, sizeof(button_state)); //Sending the data
delay(5);
radio.startListening(); //This sets the module as receiver
if (radio.available())
{
radio.read(&button_state1, sizeof(button_state1)); //Reading the data
String final = "";
if (button_state1.state == 0) {
ok = 1;
sendText();
for (int i = 0; i < strlen(button_state1.mesaj); i++)
{
final += String(button_state1.mesaj[i]);
}
Serial.println("Lavinia: " + final);
button_state1.state = 1;
}
}
if (digitalRead(del) == LOW && a[0] != '\0' ) {
Serial.println("Deleted string");
a = "\0";
Serial.println(a);
}
}
old_pres = rel_time;
pres_time = millis();
digitalWrite(led, HIGH);
while (digitalRead(but) == LOW) {}
rel_time = millis();
digitalWrite(led, LOW);
pres_len = rel_time - pres_time;
space = pres_time - old_pres;
if (pres_len > min_delay)
{
code += MakeString();
}
while ((millis() - rel_time) < (unit_delay * 3))
{
if (digitalRead(but) == LOW)
{
goto label;
}
}
Morse_decod();
delay(1000);
}
Я полагаю, что соответствующая часть будет следующей:
int n = a.length();
char char_array[n + 1];
strcpy(char_array, a.c_str());
strcpy(button_state.mesaj, char_array);
radio.write(&button_state, sizeof(button_state)); //Sending the data
delay(5);
где а-это сообщение, которое должно быть отправлено.
@MarryPoppins, 👍1
Обсуждение1 ответ
(Слишком мало символов в комментариях, поэтому пишем вместо ответа)
Это немного сложно понять, не имея настройки здесь, и я не думаю, что у меня есть какие-либо радиомодули в моей коробке.
Я думаю, что происходит вот что.
Похоже, что первый код ничего не отправит, пока не получит сообщение от второго кода, потому что radio.write находится внутри radio.available if-block. Но когда он получает сообщение, сообщение для отправки обратно должно присутствовать, поэтому вы начинаете с ввода сообщения на Arduino1.
Затем вы вводите сообщение на Arduino2. Вы нажимаете кнопку, она пропускает цикл while ниже метки. Когда вы отпустите кнопку, она войдет в цикл while и отправит сообщение. Для обеих версий сообщение будет отправлено, как только "но" будет выпущено. but_send копируется в отправленную запись, но отправка не зависит от состояния этой кнопки. Для этого вам нужен оператор if, который проверяет but_send. В результате вы можете отправить только". "или" -", потому что сообщение отправляется сразу же, прежде чем вы успеете ввести больше точек или тире.
В любом случае, сообщение от Arduino2 принимается Arduino1. Если поле состояния сообщения равно 1, то сообщение записывается в последовательный порт. Затем сообщение от Arduino1 отправляется на Arduino2. Поскольку мы не нажимаем никаких кнопок, сообщение от Arduino 2 отправляется снова, снова и снова. Поле state будет 0, потому что but_send не нажата, но сообщение все равно отправляется. Это запускает новую отправку на Arduino 1, потому что он получает что-то от Arduino 2 и попадает в радио.
Кажется, что сообщения будут отскакивать назад и вперед. Единственная причина, по которой вы не видите, что ваша последовательная консоль заполнена буквами, заключается в том, что состояние равно 0 для большинства сообщений, потому что вы выпускаете btn_send. Но пока вы удерживаете btn_send, он установит state=1 и напечатает сообщение на приемном конце.
Чтобы предотвратить это, вы не должны вызывать radio.write, пока не будет выпущен btn_send. Это движение от НИЗКОГО УРОВНЯ к ВЫСОКОМУ. Чтобы проверить это, есть переменная old_btn_send и сделать что-то вроде этого: Инициализировать old_btn_send в HIGH in setup()
if (old_btn_send == LOW && digitalRead(btn_send) == HIGH {
[do the sending thing]
}
old_btn_send = digitalRead(btn_send);
То есть вы нажимаете btn_send. Мы не войдем в блок if, но old_btn_send будет НИЗКИМ. Когда вы отпустите его, условие будет истинным, но только один раз, потому что old_btn_send будет ВЫСОКИМ после блока if.
Пожалуйста, обратите внимание, что то, что я пишу, происходит от чтения кода и не делает никакого тестирования, так что я могу быть совершенно неправ :)
- Как автоматически сбросить nrf24l01+ с кодом?
- nRF24L01 + потеря пакетов, вызванная считыванием Arduino и связью с датчиками
- nRF24L01 - пропускает конечные символы во время передачи
- Serial.parseInt() занимает больше времени, чем хотелось бы
- nRF24L01+ Невозможно установить адрес
- Не вызовут ли помехи одновременно работающие радиомодули nrf24L01 ?
- вопрос по трубке nRF24L01
- Основная связь Arduino ModBus RTU с проблемой измерителя мощности
Попробуйте создать новый, простой проект, который отправляет число от 1 arduino к другому. Если вы отправляете его из функции setup (), то он должен быть отправлен только один раз. Если это работает, попробуйте создать простую программу, которая отправляет "1", когда кнопка нажата, и "0", если кнопка отпущена. Когда это сработает, постройте свой проект морзе из этого. Проще отлаживать короткие, простые программы и заставлять работать по одному биту за раз., @jkp
@jkp Привет. Спасибо, что ответили на этот вопрос! Я уже пробовал это делать, так как начинал с простого проекта, который сработал. Но с тех пор как я добавил больше функций, мне кажется, что где-то что-то идет не так. Есть ли у вас какое-то общее представление о том, что может быть не так в коде, возможно, о задержках?, @MarryPoppins