Lecturas NMEA bastante raras

Hola amigos.
Este es mi primer post por estos territorios, aunque os leo a menudo. Mi nivel en estas materias es de rudimentos, pero desde que me he jubilado tengo el tiempo a favor para ir aprendiendo y disfrutando.
Estoy intentando leer los mensajes NMEA que envía el equipo de viento de mi velero (es un Clipper wind system de NASA). El sketch es absolutamente simple: el cable de datos que sale del equipo de viento conectado al pin digital 0, el cable GROUND al GND del Arduino uno. Las lecturas, byte a byte, mediante Serial.read las mando al monitor con Serial.println.
El resultado debería ser el mensaje NMEA MWV, es decir, algo similar a "$IIMWV,xxx.x,R,x.x,N*hh", aunque no sé si el fabricante incluye el checksum "*hh" . Los códigos ASCII correspondientes serían:"36 73 73 77 87 86 44 etc ..." (puede que los dos 73 , que significan instrumento integrado, II, sean otros distintos).
Bueno, pues en la práctica lo que obtengo es " 0 91 213 149 69 77 157 153 149 141 167 91 167 159 163 159 167 99 167 125 171 153 155 229 235 0 ", que no se parece demasiado :~ Y, por supuesto, con los caracteres 'reales' da grima verlo: "[Õ?EM??§[§?£?§c§}«??åë ".
El 'churro' aparece con intervalos de un segundo, con el mismo número de bytes y el mismo valor, salvo que cambie la posición de la veleta o giren las cazoletas del sensor de viento, en cuyo caso sí cambian los valores en las zonas marcadas con x en el mensaje teórico. No parece interferencia aleatoria.
He 'jugado' con todos los sketches de los ejemplos, con el pullup, con el software serial. La placa Arduino funciona perfectamente. No creo que sea problema del equipo de viento, porque he probado con otro distinto (la corredera) y ocurre lo mismo; y es poco probable que ambos estén estropeados.
Y como estoy a punto de probar finalmente con el martillo, recurro al foro por si podéis echar una mano.

Muy agradecido

José Luis Hernández

LectorNMEAserial.ino (148 Bytes)

¿Cuantos metros de cable hay de por medio?

¿Puedes pegar el código del sketch?

¿Estás totalmente seguro de los parametros de conexión del puerto serie (baudios, paridad, bits de parada, ...)?

¿Puedes leer esos datos desde un puerto serie conectado a un PC?

Bueno, son sólo algunas preguntas para empezar ...

¡Caramba, amigo ADCL! Te agradezco la rapidez :slight_smile:
Aún no he instalado el equipo de viento en el barco, para poder hacer estas pruebas. El Arduino está a centímetros, la longitud de los jumpers de conexión.
Verguenza me da decirlo, pero he adjuntado como attach el 'ino' porque no sabía pegar ... :grin:

byte unDato;

void setup() {
Serial.begin(4800);
}

void loop() {
if (Serial.available() > 0) {
Serial.println(Serial.read());
}
}

En cuanto a los parámetros, razonablemente seguro; aunque tengo claro que algo estoy haciendo mal ...

Y referente a lo de leer los datos por un puerto serie del PC, no lo he hecho ('Caps tono de voz bajito' porque no sé como puedo hacerlo 'Caps off' :blush: )

De momento he dejado el martillo en la estanteria.
Gracias!!!

José Luis

Hola,
lo primero que te puedo comentar es que la funcion read() devuelve un número (int) mientras que tu lo que quieres es imprimir un caracter ASCII (char).
Lo mejor es empezar por poner la siguiente linea en vez de la que tienes.

Serial.println((char)Serial.read());

(No lo he probado, pero espero que funcione)

¿No deberíamos usar puertos Serial distintos para la comunicación NMEA y la consola?

Si, eso es otra.
Si es un Arduino Uno estás compartiendo la linea de recepción entre el ordenador y tu dispositivo, y se podrían interferir si los dos escriben a la vez (lo puedes comprobar simplemente escribiendo cosas en la consula de recepción y viendo que recibes el eco).

Si estás usando un Arduino Mega o un Leonardo, estas versiones tienen al menos otro puerto serie disponible.

Aquí comenta un poco que puertos tiene cada placa: Serial - Arduino Reference

Si no, siempre puedes usar una implementación SW para usar cualesquiera otros pines:

De todas formas, esos caracteres parece que vienen del cacharro, no del PC.
No estoy muy seguro que se hace con los caracteres que se reciben con error, si se descartan o te los devuelven.
Si se descartaran, el comportamiento normal cuando los parámetros de la conexión no están bien es que se deescarte todo lo recibido (errorneamente), pero si no se hace, lo que pasaría es que recibirías basura (como te está pasando).

El Serial.begin() acepta más opciones para definir la paridad y bits de stop:

Por defecto son 8 bits sin paridad y con 1 bit de parada.

¿Tiene tu PC puerto de entrada serie?

Primero y principal: gracias por ayudar.
Comentarios:
Modificada la línea para que imprima el carácter en lugar del código ASCII. Aparecen los dichosos caracteres que pegaba en el mensaje inicial.
Tema puertos. Toda la razón en el riesgo de colisión al usar la uart para entrada desde el aparato de marras y para salida hacia el monitor serie del entorno Arduino. Pero al no teclear nada en la consola no parece que se interfieran. De todos modos, y por si acaso, en las pruebas usando SoftwareSerial con distintos pines para el input obtengo los mismos resultados. Curioso. ¿Serán gremlins? =(

En parte por eso te comentaba lo de usar un puerto serie conectado al PC, para descartar cualquier problema de configuración del arduino.

¿Tiene tu PC puerto serie?
¿Cual es la configuración serie del dispositivo? (baudios, bits, etc)
¿Cuada cuanto manda un mensaje el dispositivo?

Por cierto, acabo de caer ...
La salida del dispositivo muy probablemente sea RS232 compatible con voltages de salida normalmente en el rango +/-9V, algo que no es compatible con el Arduino.
Necesitarías un MAX232 o parecido para adaptar los niveles (si solo tienes que adaptar la entrada RX, hay formas más sencillas que usar un chip).
Eso lo podrás comprobar rápidamente con un polímetro, viendola tensión de la linea TX del dispositivo (la que conectas al arduino, pero estando desconectada).

Por lo que veo aquí, el NMEA deja bastante abierto el interfaz de salida del dispositivo: podrías ser TTL, RS232 o RS2422 ...

¿Qué salida tiene el Clipper wind system de NASA?

En el PC solo tengo puertos USB.
El Clipper manda sus mensajes puntualmente cada segundo. Según el fabricante la salida es NMEA 183 standar, a 4.800,8,N,1,N. Niveles 0-5 V. Es decir, cumple el EIA-422, con la diferencia de que usa un solo hilo para la señal en lugar de un par diferencial, cosa que es muy frecuente en equipos de segundas firmas.
Lo que estoy intentando es leer la sentencia MWV para, a partir de ella crear una VWR, que es la que 'entiende' el piloto automático. He encontrado en la red algún sketch que hace eso exactamente, pero que no me funciona porque no recibe los caracteres ASCII correctos. Existe la opción de comprar un bonito multiplexador y cruzar los dedos, pero el presupuesto no está para alegrías ... :slight_smile:

¿Y cual es la tensión de reposo de al linea de TX que sale del sensor (entiendo que debería ser 5V)?

¿Que tensión hay en el pin 0 cuando el arduino está encendido pero el sensor no está conectado?

El pin 0 con el arduino encendido y sin sensor está a 5.00 V
La salida del instrumento no consigo leerla, porque está oscilando constantemente, ya que en cuanto se alimenta empieza a mandar sus sentencias.

Pudiera ser que la polaridad de la señal fuese la inversa.

Me explico. En RS-232 el esado de la linea en reposo corresponde a -15V; su rango de salida es de -15V a +15V.
Cuando usamos la señal RS232 a nivel TTL o CMOS, los niveles se "invierten", correspondiendo a 5V para tensiones de entrada RS232 negativas y 0V para tensiones de entrada positivas.

En el RS422 de un sólo hilo la señal cambia entre 0 y 5V. Pero, ¿cual es al tensión de reposo?
No tiene por qué ser equivalente la señal RS422 de un sólo hilo que la señal RS232 TTL. De hecho, lo lógico me parece que sería lo contrario: 0V en RS422 para el mismo estado que cuando el RSS tiene que esta en tensiones negativas y +5V para cuando el RS232 debería estar en positiva. O sea, al contrario de lo que espera la UART del Arduino (creo).

De todas formas, por probar a invertir la señal con un simple negador no pierdes nada.
Si no tienes negador, lo puedes "montar" con el mismo arduino.

Pues me pongo ahora mismo. A bote pronto tiene muy buena pinta el consejo. ¡La deuda aumenta! :slight_smile:

Intentaré encontrar el negador por esos mundos de tutoriales. Si me veo perdido te amenazo con seguir exprimiendote XD

De cara sólo a probar, puedes conectar el TX del sensor al pin, digamos 5, leerlo en el bucle principal y poner el valor negado en el, digamos, 4 en modo salida, conectando el pin 4 al RX (0).

Para 4800 baudios, el bucle principales suficientemente rápido ... aunque sólo para probar.
Si no funciona, aún así, me buscaría un negador como dios manda.

Tengo que hacer una pausa, para que no me acusen en casa de nocturnidad.
Mañana más. Muchas gracias.

De regreso, tras un poco de trasteo y con un millón de gracias para el tipo estupendo, por competencia e interes, que me ha resuelto la cuestión.
Estoy en deuda contigo ADLC.
Como apuntabas, la cosa iba de negar la señal.

byte unDato = 0;

void setup() {
pinMode(7, INPUT); // pin de entrada del cable de datos del Clipper
pinMode(8, OUTPUT); // salida de datos negados, conectada al pin 0

Serial.begin(4800);
}

void loop() {
if (digitalRead(7) == LOW) {
digitalWrite(8, HIGH);
}
else
{
digitalWrite(8, LOW);
}

while(Serial.available()) {
unDato = Serial.read();
Serial.write(unDato);
}
}

Con esto tengo resuelto el asunto de la conversión de sentencias NMEA: $WIMWV,358,R,0.0,N,A*33

La segunda parte será mandarle al piloto automático señales que entienda, pero descubierto el meollo, confío en que sabremos :slight_smile:
Ha sido una magnífica idea recurrir a este foro, en el que, de ahora en adelante me teneis para lo que os pueda servir.

Muchas gracias

Gracias a ti; hoy he aprendido un montón de cosas nuevas respecto a los RS422, NMEA, etc. Interesante todo.

Por otra parte, consiguete un negador. Lo de cambiar los propios pins del arduino está bien, pero te puede dar problemas conforme sigas desarrollando el sketch.