Go Down

Topic: Código funciona solo al presionar botón Reset de la placa Arduino UNO (Read 352 times) previous topic - next topic

FranVasquez

Hola, buen día a todos.
Estoy diseñando un proyecto para establecer comunicación entre dos Arduino UNO a través de radiofrecuencia, utilizando el módulo NRF24L01 (Transceptor, con Antena SMA, LNA y PA). Sin embargo el "Emisor" solo envía los datos al "Receptor" al estar activo un sensor (ultrasónico) y presionar el botón Reset de la placa Arduino UNO. ¿Será problema del código o es momento de cambiar las antenas? ¿Qué estoy haciendo mal?

Código Emisor
Code: [Select]

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

int trigPin1 = 19;
int echoPin1 = 2;

int trigPin2 = 3;
int echoPin2 = 4;

int trigPin3 = 5;
int echoPin3 = 6;

int trigPin4 = 7;
int echoPin4 = 8;

int msg[1];                             // Array a transmitir
RF24 radio(9,10);                        // Creamos un objeto radio del tipo RF2$
const uint64_t pipe = 0xE8E8F0F0E1LL;    // Usamos este canal

void setup(void) {
  Serial.begin (9600);
  
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
  
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);

  pinMode(trigPin3, OUTPUT);
  pinMode(echoPin3, INPUT);

  pinMode(trigPin4, OUTPUT);
  pinMode(echoPin4, INPUT);

  radio.begin();
  radio.openWritingPipe(pipe);          // Abrir para escribir
}


void secondsensor(){ // This function is for second sensor.
    int duration2, distance2;
    digitalWrite (trigPin2, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigPin2, LOW);
    duration2 = pulseIn (echoPin2, HIGH);
    distance2 = (duration2/2) / 29.1;
  
      Serial.print("2nd Sensor: ");
      Serial.print(distance2);  
      Serial.print("cm    ");
  
  if (distance2 < 20) {  // Change the number for long or short distances.
      msg[0] = 1;
      radio.write(msg, 1);
    }
  else {
      msg[0] = 2;
      radio.write(msg, 1);
    }    
}

void fourthsensor(){ // This function is for fourth sensor.
    int duration4, distance4;
    digitalWrite (trigPin4, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigPin4, LOW);
    duration4 = pulseIn (echoPin4, HIGH);
    distance4 = (duration4/2) / 29.1;
  
      Serial.print("4th Sensor: ");
      Serial.print(distance4);  
      Serial.print("cm    ");
  
  if (distance4 < 20) {  // Change the number for long or short distances.
      msg[0] = 3;
      radio.write(msg, 1);
    }
  else {
      msg[0] = 4;
      radio.write(msg, 1);
    }    
}


void loop(void) {
{
Serial.println("\n");
  int duration1, distance1;
  digitalWrite (trigPin1, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigPin1, LOW);
  duration1 = pulseIn (echoPin1, HIGH);
  distance1 = (duration1/2) / 29.1;

      Serial.print("1st Sensor: ");
      Serial.print(distance1);  
      Serial.print("cm    ");

  if (distance1 < 30) {  // Change the number for long or short distances.
    secondsensor();
    delay(100);
  }    
}
{
Serial.println("\n");
  int duration3, distance3;
  digitalWrite (trigPin3, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigPin3, LOW);
  duration3 = pulseIn (echoPin3, HIGH);
  distance3 = (duration3/2) / 29.1;

      Serial.print("3rd Sensor: ");
      Serial.print(distance3);  
      Serial.print("cm    ");

  if (distance3 < 30) {  // Change the number for long or short distances.
    fourthsensor();
    delay(100);
  }    
}
}



Código Receptor
Code: [Select]

#include <nRF24L01.h>
#include <RF24.h>
//#include <RF24_config.h>
#include <SPI.h>
#include <Wire.h>     // libreria de comunicacion por I2C
#include <LCD.h>      // libreria para funciones de LCD
#include <LiquidCrystal_I2C.h>    // libreria para LCD por I2C

LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7); // DIR, E, RW, RS, D4, D5, D6, D7

int ledPin1 = 3;
int ledPin2 = 4;

int msg[1];

RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void) {
  Serial.begin (9600);
    
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);

  lcd.setBacklightPin(3,POSITIVE);  // puerto P3 de PCF8574 como positivo
  lcd.setBacklight(HIGH);   // habilita iluminacion posterior de LCD
  lcd.begin(16, 2);     // 16 columnas por 2 lineas para LCD 1602A
  lcd.clear();      // limpia pantalla

  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();
}

void lcdest1l(){ //Ver "Libre" en lcd
  lcd.setCursor(0, 0);
  lcd.print("EST1 L");
}

void lcdest1o(){ //Ver "Ocupado" en lcd
  lcd.setCursor(0, 0);
  lcd.print("EST1 O");
}

void lcdest2l(){ //Ver "Libre" en lcd
  lcd.setCursor(0, 1);
  lcd.print("EST2 L");
}

void lcdest2o(){ //Ver "Ocupado" en lcd
  lcd.setCursor(0, 1);
  lcd.print("EST2 O");
}

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

  if (msg[0] == 1)
    {
    lcdest1o();
    }

  if (msg[0] == 2)
    {
    lcdest1l();
    }

  if (msg[0] == 3)
    {
    lcdest2o();
    }

  if (msg[0] == 4)
    {
    lcdest2l();
    }
    
  if (msg[0] == 1 || msg[0] == 3)
    {
    digitalWrite (ledPin1, HIGH);
    delay (100);
    digitalWrite (ledPin2, LOW);
    }
  else
  {
    digitalWrite (ledPin2, HIGH);
    delay (100);
    digitalWrite (ledPin1, LOW);
  }  
}
  }
    }


Desde ya, les agradezco su ayuda.

Daniel_Arg

Quote
¿Será problema del código o es momento de cambiar las antenas?
Si hay un momento donde la comunicación si se establece, entonces no es un problema de distancia.

¿Has intentado con algún ejemplo de la librería?


surbyte

Si trabajar con radios ya tiene sus detalles, se supone que tienes alguna experiencia programando.
Ver cosas como esta

Code: [Select]
Serial.println("\n");

me llaman la atención
O llaves al comienzo del loop que encierran código, son totalmente inservibles.

Bueno en tu código veo que tienes 4 sensores ultrasónicos.
El 1ro y el 2do estan dentro del loop y si las distancias medidas son menores a 30 cm llaman al 3ro y 4to sensor y recién envias datos.

Code: [Select]
    if (distance2 < 20) {  // Change the number for long or short distances.
        msg[0] = 1;
        radio.write(msg, 1);
    }
    else {
        msg[0] = 2;
        radio.write(msg, 1);
    } 


Esto envia datos y solo se da si Sensor1 cumple esta condición

Code: [Select]
if (distance1 < 30) {

Asi que con esto respondo tu consulta.


A tu código no le pasa nada, funciona bien, porque eso es lo que esta programado.
En todo caso dinos que quieres que haga

Ahora no se que tiene que ver el boton reset con el envio de datos.

Si la distancia < 30 en el S1 o S2 enviara datos y si no, NO!.

Esto envia datos

Code: [Select]
radio.write(msg, 1);

Asi que, si lo pones en el loop y agregas algo como

Code: [Select]
msg[0] = 1;
radio.write(msg, 1);


enviará datos correspondiente al sensor 1 por ejemplo.


FranVasquez

Si trabajar con radios ya tiene sus detalles, se supone que tienes alguna experiencia programando.
He hecho un par de proyectos con Arduino y este sería el segundo que hago con radiofrecuencia.

A tu código no le pasa nada, funciona bien, porque eso es lo que esta programado.
En todo caso dinos que quieres que haga

Ahora no se que tiene que ver el boton reset con el envio de datos.
Me alegra saber que el código esté bien, ya que quiero que al colocar un objeto (en el rango de distancia establecido) si dos sensores "se activan" (son dos parejas de sensores) me debe mostrar un mensaje en un display, de igual forma si estos están "desactivados" me debe mostrar otro mensaje.

El problema lo tengo al realizar la prueba con los 4 sensores; si coloco un objeto frente a 2 sensores (S1 y S2) a una distancia < 30 cm  el Arduino no envía ningún dato al receptor, a menos que mantenga el objeto frente a los  dos sensores y presione el botón de Reset de la placa Arduino UNO. Así es con la otra pareja de sensores (S3 y S4), debo mantener el objeto y resetear la placa para que me envíe los datos.

Al detectar el objeto, automáticamente el Arduino emisor debe enviar los mensajes, pero no es así, siempre debo presionar el botón Reset para que los envíe.



FranVasquez

Si hay un momento donde la comunicación si se establece, entonces no es un problema de distancia.

¿Has intentado con algún ejemplo de la librería?

He probado las antenas con un proyecto que encontré en Internet:
https://www.elec-cafe.com/nrf24l01-basic-control-led-arduino/

Es básicamente encender un LED a distancia presionando un pulsador. En este proyecto el problema que tuve es que a una distancia de aproximadamente 10 m, al presionar el pulsador el LED encendía, pero al soltarlo se mantenía encendido, sin que yo estuviera presionando, cosa que no debía ser así, ya que se debía apagar.

Daniel_Arg

Quote
al presionar el pulsador el LED encendía, pero al soltarlo se mantenía encendido, sin que yo estuviera presionando, cosa que no debía ser así, ya que se debía apaga
En ese ejemplo se envía al receptor un valor de 111 que al recibirlo debe imprimir en el monitor serial el valor. ¿Has probado ver que recibe cuando sueltas el pulsador? porque si no recibe un valor diferente no apaga el led.

En el código del transmisor no veo que mande otro valor cuando el botón está LOW

Code: [Select]
void loop(void){
if (digitalRead(SW1) == HIGH){
msg[0] = 111;
radio.write(msg, 1);}}


Prueba en el loop del código transmisor con

Code: [Select]
void loop(void){
if (digitalRead(SW1) == HIGH){
msg[0] = 111;
radio.write(msg, 1);}
else {
msg[0] = 100;
radio.write(msg, 1);}
delay(500);
}


Saludos


FranVasquez

En ese ejemplo se envía al receptor un valor de 111 que al recibirlo debe imprimir en el monitor serial el valor. ¿Has probado ver que recibe cuando sueltas el pulsador? porque si no recibe un valor diferente no apaga el led.
...
Saludos
Hola hola, me había perdido un tiempo del foro. Les comento, probé nuevamente el código de encender un LED a distancia con un pulsador y ya no mostraba la falla. Ahora he probado con un código diferente para enviar y recibir los datos de los sensores ultrasónicos, sin embargo aunque si se establece la comunicación con radiofrecuencia, los datos no se envían en tiempo real, es decir, solamente se envían una vez al iniciar la placa o al cargar el código a la placa. Después de esto parece que quedan estáticos en la LCD, ya que no cambian. Este es mi nuevo código:

Código Emisor

Code: [Select]

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

//Declaremos los pines CE y el CSN
#define CE_PIN 9
#define CSN_PIN 10
 
//Variable con la dirección del canal por donde se va a transmitir
byte direccion[5] ={'c','a','n','a','l'};

//creamos el objeto radio (NRF24L01)
RF24 radio(CE_PIN, CSN_PIN);

//vector con los datos a enviar
double datos[4];

int trigPin1 = 19;
int echoPin1 = 2;

int trigPin2 = 3;
int echoPin2 = 4;

int trigPin3 = 5;
int echoPin3 = 6;

int trigPin4 = 7;
int echoPin4 = 8;

void setup()
{
  //inicializamos el NRF24L01
  radio.begin();
  //inicializamos el puerto serie
  Serial.begin(9600);
 
//Abrimos un canal de escritura
 radio.openWritingPipe(direccion);

  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
 
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);

  pinMode(trigPin3, OUTPUT);
  pinMode(echoPin3, INPUT);

  pinMode(trigPin4, OUTPUT);
  pinMode(echoPin4, INPUT);
}

 void secondsensor(){ // This function is for second sensor.
    int duration2, distance2;
    digitalWrite (trigPin2, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigPin2, LOW);
    duration2 = pulseIn (echoPin2, HIGH);
    distance2 = (duration2/2) / 29.1;
 
      Serial.print("2nd Sensor: ");
      Serial.print(distance2); 
      Serial.print("cm    ");
   
  if (distance2 < 20) {  // Change the number for long or short distances.
      datos[0] = 1;
      //radio.write(msg, 1);
    }
  else {
      datos[1] = 2;
      //radio.write(msg, 1);
    }   
}

void fourthsensor(){ // This function is for fourth sensor.
    int duration4, distance4;
    digitalWrite (trigPin4, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigPin4, LOW);
    duration4 = pulseIn (echoPin4, HIGH);
    distance4 = (duration4/2) / 29.1;
 
      Serial.print("4th Sensor: ");
      Serial.print(distance4); 
      Serial.print("cm    ");
   
  if (distance4 < 20) {  // Change the number for long or short distances.
      datos[2] = 3;
      //radio.write(msg, 1);
    }
  else {
      datos[3] = 4;
      //radio.write(msg, 1);
    }   
}
void loop()
{
  {
Serial.println("\n");
  int duration1, distance1;
  digitalWrite (trigPin1, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigPin1, LOW);
  duration1 = pulseIn (echoPin1, HIGH);
  distance1 = (duration1/2) / 29.1;

      Serial.print("1st Sensor: ");
      Serial.print(distance1); 
      Serial.print("cm    ");

  if (distance1 < 30) {  // Change the number for long or short distances.
    secondsensor();
    delay(100);
  }     
}
{
Serial.println("\n");
  int duration3, distance3;
  digitalWrite (trigPin3, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigPin3, LOW);
  duration3 = pulseIn (echoPin3, HIGH);
  distance3 = (duration3/2) / 29.1;

      Serial.print("3rd Sensor: ");
      Serial.print(distance3); 
      Serial.print("cm    ");

  if (distance3 < 30) {  // Change the number for long or short distances.
    fourthsensor();
    delay(100);
  }     
}
{
   //enviamos los datos
 bool ok = radio.write(datos, sizeof(datos));
  //reportamos por el puerto serial los datos enviados
  if(ok)
  {
        if(datos[0] == 1)
    {
      datos[0]=1;
      radio.write(datos, sizeof(datos));
      Serial.print("S ON");
    }
        if(datos[1] == 2)
    {
      datos[1]= 2;
      radio.write(datos, sizeof(datos));
      Serial.print("S OFF");
    }
        if(datos[2] == 3)
    {
      datos[2]= 3;
      radio.write(datos, sizeof(datos));
      Serial.print("S ON");
    }
        if(datos[3] == 4)
    {
      datos[3]= 4;
      radio.write(datos, sizeof(datos));
      Serial.print("S OFF");
    }
  }
  else
  {
     Serial.println("Datos no enviados");
  }
  delay(1000);
}
 }



Código Receptor

Code: [Select]

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>     // libreria de comunicacion por I2C
#include <LCD.h>      // libreria para funciones de LCD
#include <LiquidCrystal_I2C.h>    // libreria para LCD por I2C
 
//Declaremos los pines CE y el CSN
#define CE_PIN 9
#define CSN_PIN 10
 
//Variable con la dirección del canal que se va a leer
byte direccion[5] ={'c','a','n','a','l'};

//creamos el objeto radio (NRF24L01)
RF24 radio(CE_PIN, CSN_PIN);

//vector para los datos recibidos
double datos[4];

LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7); // DIR, E, RW, RS, D4, D5, D6, D7

int ledPin1 = 3;
int ledPin2 = 4;

void setup()
{
 //inicializamos el NRF24L01
  radio.begin();
  //inicializamos el puerto serie
  Serial.begin(9600);
 
  //Abrimos el canal de Lectura
  radio.openReadingPipe(1, direccion);
 
    //empezamos a escuchar por el canal
  radio.startListening();

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);

  lcd.setBacklightPin(3,POSITIVE);  // puerto P3 de PCF8574 como positivo
  lcd.setBacklight(HIGH);   // habilita iluminacion posterior de LCD
  lcd.begin(16, 2);     // 16 columnas por 2 lineas para LCD 1602A
  lcd.clear();      // limpia pantalla
}

void lcdest1l(){ //Ver "Libre" en lcd
  lcd.setCursor(0, 0);
  lcd.print("EST1 L");
}

void lcdest1o(){ //Ver "Ocupado" en lcd
  lcd.setCursor(0, 0);
  lcd.print("EST1 O");
}

void lcdest2l(){ //Ver "Libre" en lcd
  lcd.setCursor(0, 1);
  lcd.print("EST2 L");
}

void lcdest2o(){ //Ver "Ocupado" en lcd
  lcd.setCursor(0, 1);
  lcd.print("EST2 O");
}

void loop() {
 uint8_t numero_canal;
 //if ( radio.available(&numero_canal) )
 if ( radio.available() )
 {   
     //Leemos los datos y los guardamos en la variable datos[]
     radio.read(datos,sizeof(datos));

    if (datos[0] == 1)
    {
    lcdest1o();
    Serial.print("E1 O");
    }

  if (datos[1] == 2)
    {
    lcdest1l();
    Serial.print("E1 L");
    }

  if (datos[2] == 3)
    {
    lcdest2o();
    Serial.print("E2 O");
    }

  if (datos[3] == 4)
    {
    lcdest2l();
    Serial.print("E2 L");
    }
   
  if (datos[1] == 2 || datos[3] == 4)
    {
    digitalWrite (ledPin1, HIGH);
    delay (100);
    digitalWrite (ledPin2, LOW);
    }
  else
  {
    digitalWrite (ledPin2, HIGH);
    delay (100);
    digitalWrite (ledPin1, LOW);
  }
     }
 else
 {
     Serial.println("No hay datos de radio disponibles");
 }
 delay(1000);
}


Hay alguna falla que puede que no esté viendo, les agradezco desde ya que me echen la mano.

Go Up