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.
¡Caramba, amigo ADCL! Te agradezco la rapidez
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 ...
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.
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.
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.
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? =(
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).
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 ...
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.
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.
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
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
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.
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.