3 votos

Software de Arduino UnoConflicto de serie y de serie

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 utilizando la biblioteca 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 RF, simplemente lo escribo en el Serial (para poder verlo en mi PC en el monitor serial). Hacer esto parece entrar en conflicto entre SoftwareSerial y Serial, ya que la función available() se incrementa rápidamente y por lo tanto tengo un montón de 0's impresos (dado que ningún dato fue realmente transmitido, pero available() devolvió 63 - el máximo del buffer 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 quito la línea pinMode(rxPin, INPUT) entonces nunca se recibe nada (y rf.available() es siempre 0).

3voto

Jeremy Ruten Puntos 59989

Probé con un voltímetro sobre GND y DI10 y al medir mostró 0V.

Eso no suena bien. Cuando una UART no está transmitiendo ningún dato, permanece en el estado "1" de reposo. Esperaba que los cables conectados al Arduino tuvieran los llamados niveles RS232TTL de +5V en el estado "1" y cerca de GND en el estado "0". (d) Cuando la UART es transmitiendo muchos datos, un multímetro suele mostrar algún tipo de tensión media entre el estado "1" y el estado "0", rebotando entre 2 V y 4 V. ¿Quizás una línea de alimentación o de datos se desconectó o se conectó mal?

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

Eso es muy inesperado. La mayoría de la documentación de Arduino dice cosas como "Los pines de Arduino (Atmega) son por defecto entradas, por lo que no es necesario declararlos explícitamente como entradas con pinMode()". (a)

Algunos tutoriales de SoftwareSerial sugieren declarar explícitamente que los pines TX sean de salida. (b) ¿Quizás lo que está escuchando a "txPin" está captando ruido, haciendo que haga algo inesperado?

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

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

¿Cómo puedes saber eso? Empiezo a sospechar que el código de tu Arduino es algún programa otros que lo que has publicado.

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

Puede que el SoftwareSerial funcione bien con datos UART normales, pero no puede manejar los fallos de alta frecuencia comunes en los receptores de radio de bajo coste. En ese caso, tal vez funcionaría mejor

  • (a) Conecta la UART hardware de Arduino (D0 Rx y D1 Tx) a la radio, y el SoftwareSerial a tu monitor serial de depuración. O
  • (b) utilizar un hardware más sofisticado que haga la recuperación del reloj, etc. como el HopeRF RFM12B utilizado en el JeeNode y el Moteino, o
  • (c) utilizar programas más sofisticados, como el protocolo que Roman Black inventó y describe en "Módulos de radiofrecuencia de forma sencilla" o el sistema de manipulación de frecuencias desarrollado por Tom Boyd en "Detección del tren de impulsos con un Arduino" .

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);
  }
}

1voto

Olly Puntos 319

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

Sin embargo, para probar esto es fácil: comenta el Serial.println y pon el LED oboard en la Uno cuando available() devuelva 63 y apágalo cuando != 63.

Si todavía notas que el buffer de entrada se llena, la lectura del módulo RF es el problema.

Por cierto, ¿qué tipo de módulo de radiofrecuencia utiliza?

0voto

muffel Puntos 1186

En primer lugar, es posible que tenga que utilizar Serial.print() en lugar de Serial.println() . Además, hay que tener en cuenta que el SoftwareSerial.h se modificó el año pasado y requiere un formato diferente cuando se utiliza Serial.print() . Es posible que tenga que cambiar su línea de salida a

 Serial.print( (Dec) incomingByte );

Tuve que hacer esto para uno de mis proyectos.

0voto

Leng Puntos 1

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

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

Ahora veo que funciona. Como estoy depurando por serie, utilizando el módulo GSM, y la placa es Arduino Leonardo.

0voto

Gary Puntos 282
#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 entrada salida para los pines Rx y Tx dentro de la configuración de la función...

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X