Software Arduino UnoSerial y Conflicto serial

Tengo una configuración muy sencilla 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 SoftwareSerial. Estoy usando un módulo AM-RRQ3-433. Consulte 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 serial). Hacerlo parece generar un conflicto entre SoftwareSerial y Serial, ya que la función disponible() aumenta rápidamente y, por lo tanto, tengo muchos 0 impresos (dado que en realidad no se transmitieron datos, pero disponible() 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), nunca se recibe nada (y rf. available() siempre es 0).

Esto suena como un problema de software puro. ¿Cuál es su pregunta de ingeniería eléctrica?
@Butzke Ese es un sitio no funcional que solo está comprometido en un 60 por ciento y es poco probable que despegue. En mi opinión, ese no es un comentario útil.
Arduino 1.01 tiene más de un año en este momento. ¿Por qué estás usando una versión tan antigua?
¿Puedes asegurarte de que no estás usando el bus SPI también? El pin digital 10 no se puede usar como entrada si lo está. No está permitido debido al modo de selección SPI Slave del propio atmega cuando SPI está activo.
En su configuración () no definió txPin como salida. Usted debe hacer esto
Esto debe preguntarse en un foro Arduino Forum.arduino.cc/…

Respuestas (5)

Probé un voltímetro sobre GND y DI10 y mientras 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 los llamados niveles RS232TTL de +5V en el estado "1" y cerca de GND en el estado "0". (d) Cuando el UART está transmitiendo una 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. Tal vez se desconectó una línea de alimentación o de datos. o cableado mal?

Como nota al margen, si elimino la línea pinMode (rxPin, INPUT), 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 "Arduino (Atmega) pines predeterminados a las entradas, por lo que no es necesario declararlos explícitamente como entradas con pinMode()". (a)

Algunos tutoriales para SoftwareSerial sugieren declarar explícitamente los pines TX como salida. (b) ¿Quizás 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.disponible() es siempre > 0 (y también se convierte en 63)

¿Cómo puedes saber eso? Estoy empezando a sospechar que el código en tu Arduino es algún programa diferente al que publicaste.

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

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

  • (a) conecte el hardware UART de Arduino (D0 Rx y D1 Tx) a la radio y el SoftwareSerial a su monitor serial de depuración. O
  • (b) usar hardware más sofisticado que hace la recuperación del reloj, etc. como el HopeRF RFM12B que se usa en el JeeNode y el Moteino, o
  • (c) usar software más sofisticado, como el protocolo que Roman Black inventó y describe en "Módulos de RF simplificados" o el sistema de cambio de frecuencia desarrollado por Tom Boyd en "Detección de tren de pulsos con un Arduino" .

Algún código 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);
  }
}

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, probar esto es fácil: comente Serial.println y configure el LED externo en el Uno cuando esté disponible() devuelve 63 y se apaga cuando != 63.

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

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

Bien, así que hice eso ahora. Si compruebo rf.disponible() == 63, entonces el LED nunca se enciende. Sin embargo, si simplemente verifico rf. available() > 0, entonces el LED se enciende después de un breve período de tiempo (como se esperaba). Además, intenté buscar > 1 y el LED aún no está encendido. Esto sugiere que en realidad estoy leyendo datos del módulo de RF, pero que entra en conflicto con el Serial incorporado. Estoy usando un módulo AM-RRQ3-433. Consulte rfsolutions.co.uk/acatalog/AM_Super-heterodyne_Receiver.html
Parece que estaba equivocado. El módulo RF en realidad estaba conectado a DI8 (a partir de un experimento con AltSoftSerial anoche). Cuando lo conecté a DI10, el LED se enciende constantemente, lo que sugiere que rf. available() siempre es > 0 (y también se convierte en 63) incluso cuando no estoy instanciando o usando el Serial incorporado. Probé un voltímetro sobre GND y DI10 y mientras medía mostraba 0V.
Además, traté de invertir la señal usando el tercer argumento del constructor SoftwareSerial. Esto no cambia nada (excepto que si imprimo el byte es 255 en lugar de 0).
Empecé a pensar más en pinMode (rxPin, INPUT). De las muestras que he visto, esto no es necesario. Si lo elimino, rf. available() nunca se convierte en > 0. Además, intenté cambiar el módulo RF por otro (que probé en un FEZ Panda). El mismo problema.

Primero, es posible que deba usar Serial.print()en lugar de Serial.println(). Además, una cosa a tener en cuenta es que la SoftwareSerial.hbiblioteca se cambió el año pasado y requiere un formato diferente cuando usa Serial.print(). En realidad, es posible que necesite cambiar su línea de salida a

 Serial.print( (Dec) incomingByte );

Tuve que hacer esto para uno de mis proyectos.

En primer lugar, el Arduino Leonardo no funciona con Serial(1) y SoftwareSerial. Porque lo probé al implementar GSM_Library para EFComm Module V1.0 (portado a la nueva versión IDE). Entonces, intente reemplazar la referencia del objeto "mySerial" en GSM_Library.cpp por Serial1. Luego conecte RX al pin1 y TX al pin0, para usar el chip serial 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.

#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 funciones...