Arduino Uno SoftwareSerial and Serial conflict

3

Tengo una configuración muy simple con un Arduino Uno R3 conectado a mi Windows 7 x64 con Arduino 1.0.1.

Tengo un receptor de RF conectado al Arduino en el puerto DI10 usando la biblioteca de SoftwareSerial. Estoy utilizando un módulo AM-RRQ3-433. Ver rfsolutions.co.uk/acatalog/AM_Super-heterodyne_Receiver.html

Cuando recibo un byte del receptor de RF, simplemente lo escribo en el Serial (para poder verlo en mi PC en el monitor de serie). Al hacerlo, parece que existe un conflicto entre SoftwareSerial y Serial, ya que la función available () aumenta rápidamente y, por lo tanto, tengo una gran cantidad de 0 impresos (dado que en realidad no se transmitieron datos, pero available () devolvió 63, el máximo del búfer de recepción).

El código de Arduino es el siguiente:

#include <SoftwareSerial.h>
#define rxPin 10
#define txPin 11

SoftwareSerial rf(rxPin, txPin);
int incomingByte = 0;

void setup() {
  pinMode(rxPin, INPUT);  
  Serial.begin(57600);
  rf.begin(2400);
}

void loop() {
  if (rf.available() > 0) {
    incomingByte = rf.read();
    Serial.println(incomingByte, DEC);
  }
}

Como nota al margen, si elimino la línea pinMode (rxPin, INPUT), entonces nunca se recibe nada (y rf.available () siempre es 0).

    
pregunta kfuglsang

5 respuestas

3
  

Probé un voltímetro sobre GND y DI10 y mientras lo medía mostraba   0V.

Eso no suena bien. Cuando un UART no está transmitiendo ningún dato, permanece en el estado inactivo "1". Esperaba que los cables conectados al Arduino fueran niveles llamados RS232TTL de + 5V en el estado "1" y cerca de GND en el estado "0". (d) Cuando el UART está transmitiendo gran cantidad de datos, un multímetro generalmente muestra algún tipo de voltaje promedio entre el estado "1" y el estado "0", rebotando alrededor de 2 V a 4 V. ¿Quizás una línea de alimentación o de datos se desconectó o se conectó incorrectamente?

  

Como nota al margen, si quito la línea pinMode (rxPin, INPUT) entonces   nunca se recibe nada (y rf.available () siempre es 0).

Eso es muy inesperado. La mayoría de la documentación de Arduino dice cosas como "Los pines Arduino (Atmega) están predeterminados en las entradas, por lo que no necesitan ser declarados explícitamente como entradas con pinMode ()". (a)

Algunos tutoriales para SoftwareSerial sugieren declarar explícitamente la salida de los pines TX. (b) Tal vez lo que sea que esté escuchando "txPin" esté captando ruido, ¿haciendo que haga algo inesperado?

La mayoría de los tutoriales de Arduino parecen usar 9600 bps para el hardware Serial uart. (c)

  

rf.available () siempre es > 0 (y también se convierte en 63)

¿Cómo podrías saber eso? Estoy empezando a sospechar que el código en su Arduino es un programa otro que el que usted publicó.

¿Qué sucede cuando prueba exactamente el mismo programa, pero con una fuente en serie conocida? Por ejemplo, en lugar de conectar Arduino D10 (su SoftwareSerial rxPin) a la radio, en lugar de eso, conecte D10 a Arduino D0 (los datos que escribe en el monitor de serie de su PC) y escriba algunas palabras. ¿Qué pasa entonces?

Tal vez el SoftwareSerial funciona bien con los datos normales de UART, pero no puede manejar los fallos de alta frecuencia comunes en los receptores de radio de bajo costo. En ese caso, tal vez sería mejor para

  • (a) conecte el hardware de Arduino UART (D0 Rx y D1 Tx) a la radio, y el SoftwareSerial a su monitor serie de depuración. O
  • (b) utiliza un hardware más sofisticado que recupera el reloj, etc., como el HopeRF RFM12B que se usa en el JeeNode y el Moteino, o
  • (c) utiliza un software más sofisticado, como el protocolo que Roman Black inventó y describe en "Los módulos RF son fáciles" o el sistema de codificación de cambio de frecuencia desarrollado por Tom Boyd en "Detección de tren de pulsos con un Arduino" . li>

Algunos códigos de prueba:

#include <SoftwareSerial.h>
#define rxPin 10
#define txPin 11
SoftwareSerial rf(rxPin, txPin);

void setup() {
  pinMode(rxPin, INPUT);  
  pinMode(txPin, OUTPUT);  
  Serial.begin(9600);
  rf.begin(2400);
  Serial.println("Hello, I was compiled " __DATE__ );
}

void loop() {
  if( rf.available() ){
    int incomingByte = rf.read();
    Serial.print(incomingByte, DEC);
    Serial.print(" ");
    Serial.println( rf.available(), DEC);
  }
}
    
respondido por el davidcary
1

No creo que usar SoftwareSerial y Serial al mismo tiempo sea un problema. Estoy usando SoftwareSerial para comunicarme con mi módulo GSM y uso Serial.print (ln) al mismo tiempo para la depuración.

Sin embargo, para probar esto es fácil: comente la Serial.println y configure el LED de oboard en el Uno cuando esté disponible () devuelve 63 y se apaga cuando! = 63.

Si aún observa que el búfer de entrada se llena, el problema es leer el módulo RF.

Por cierto, ¿qué tipo de módulo de RF está utilizando?

    
respondido por el Anthon
0

Primero, es posible que necesites usar Serial.print() en lugar de Serial.println() . Además, una cosa a tener en cuenta es que la biblioteca SoftwareSerial.h se modificó el año pasado y requiere un formato diferente cuando se utiliza Serial.print() . Es posible que deba cambiar la línea de salida a

 Serial.print( (Dec) incomingByte );

Tuve que hacer esto para uno de mis proyectos.

    
respondido por el ridecontrol53
0

En primer lugar, el Arduino Leonardo no funciona con Serial (1) y SoftwareSerial. Porque lo he probado al implementar GSM_Library para EFComm Module V1.0 (portado a la nueva versión IDE). Entonces, intente reemplazar la referencia de objeto "mySerial" en GSM_Library.cpp por Serial1. Luego, conecte RX a pin1 y TX a pin0, para usar el chip serie incorporado.

También elimine todas las inclusiones de softwareserial o newsoftserial si aún no lo ha portado.

Ahora puedo ver que funciona. Como estoy depurando por serial, usando el módulo GSM, y la placa es Arduino Leonardo.

    
respondido por el abel romero
0
#include <SoftwareSerial.h>
#define rxPin 10
#define txPin 11
SoftwareSerial rf(rxPin, txPin);

void setup() {
  Serial.begin(9600);
  rf.begin(2400);
  Serial.println("Hello, I was compiled " __DATE__ );
}

void loop() {
  if( rf.available() ){
    int incomingByte = rf.read();
    Serial.print(incomingByte, DEC);
    Serial.print(" ");
    Serial.println( rf.available(), DEC);
  }
}

No es necesario declarar como salida de entrada para los pines Rx y Tx dentro de la configuración de la función ...

    
respondido por el user79893

Lea otras preguntas en las etiquetas