Aunque hay bastante gente que ha conectado su arduino al simulador, hasta ahora lo mas flexible que encontre era el link2fs_inout de Jim. y no es precisame muy flexible o portable, pues parece programado en visual basic y para flight simulator.
No me gustaba, yo queria algo que hablase con sioc, para asi poder utilizarlo indistintamente con x-plane o con FsX
Asi que aplique un poco de filosofia unix, el KISS (keep it simple, stupid).
Mi idea es en el futuro que arduino, con una shield ethernet se comunicase directamente con un servidor IOCP, bien el programa sioc, bien el pluging para xplane, etc,etc...
La cuestion esta en como hacia para que mi actual arduino que se conecta por USB, hablase tambien con sioc.
Estaba claro que la solucion pasaba por un programa que hiciese de traductor entre la conexion TCP que espera IOCP, y la conexion serie que da arduino, que es lo mismo que hace la tarjeta LCD de opencockpits.
Empece programando el Arduino, por dos motivos, ya tengo una protocolo de comunicaciones, el SIOC, es sencillo de entender, y si el dia de mañana adquiero la shield ethernet tengo menos que modificar.
Luego tenia que programar la pasarela, como estoy en windows (por el sioc), y no tengo ni idea, la solucion paso por hacer una warreria en python.
Y voila!!! Funciona, puedo enviar y recibir datos entre arduino y SIOC, es bonito y es flexible.
Por hacer:
Hay algunas cosillas que aun no he terminado:
- El programa no responde a la orden Arn.Vive
Tengo una latencia importante en las comunicaciones, sirve para un piloto automatico, un panel de alarmas, pero no para una plataforma movil, o instrumentos de aguja.He reducido la latencia, aunque no lo he probado con indicadores de aguja u otros indicadores "sensibles"- Hay que configurar y compilar algunas cosas a pelo, y hay que isntalar python.
El programa pasarela.
Hay que instalar python, y luego la libreria pyserial, modificar las primeras lineas del programa para que se ajusten a tu configuracion:
#!/usr/bin/python # This is client.py file
# Distributed under GPL V3 License
# (C) Alvaro Alea Fdz 2012
import socket,serial,select # Import socket module
# la configuracion lo primero
host = "127.0.0.1" # socket.gethostname() Get local machine name
port = 8092 # Reserve a port for your service.
serialport=2 # com3
# Conectamos al servidor.
ne = socket.socket() # Create a socket object
print ("Conectando a servidor\n")
ne.connect((host, port))
ne.setblocking(0)
print ("Conectado a s. IOCP\n")
# Abrimos el puerto serie N 9 9600 por defecto
se = serial.Serial(serialport)
se.timeout=0
print ("Abierto puerto serie")
# El loop
#ne.send(bytes("Arn.Inicio:999:\r\n",'UTF-8'))
while 1:
d=0
while d==0:
b= se.read(1)
if b :
ne.send(b)
print (">")
else:
d=1
d=0
while d==0:
ready = select.select([ne],[],[],0.1)
if ready[0]:
a = ne.recv(1)
se.write(a)
print ("<")
else:
d=1
# salida normal del programa.
ne.close() # Close the socket when done
se.close()
El programa de arduino
Es solo el esqueleto de la aplicacion, el resto depende de lo que querais hacer, pronto pondre algun ejemplo completo:
// Distributed under GPL V3 License
// (C) Alvaro Alea Fdz 2012
// Algunas definiciones usadas por claridad.
#define XPDR_CODE 999
int dat,valor;
// llama a esta rutina al principio para iniciar el puerto serie y
// para indicar a sioc que variables monitorizar EDITALO
void setupserial(void){
Serial.begin(9600);
Serial.print("Arn.Inicio:");
Serial.print(XPDR_CODE);
Serial.println(":");
}
// funcion interna, ¿el nº en ascii es una numero?
int isnum(int n){
if ((n>47) && (n<58)) return 1;
else return 0;
}
// llama a esta funcion cuando quieras cambiar algo en sioc UTILIZALA
void enviapares(int dat, int valor){
Serial.print("Arn.Resp:");
Serial.print(dat);
Serial.print("=");
Serial.print(valor);
Serial.println(":");
}
// En esta funcion se reciben todos los cambios de sioc EDITALA
void procesapares(int dat, int valor){
int t1;
if (dat==XPDR_CODE){
}
}
// el meollo de la cuestion, NO TOCAR, FUNCIONA
void serialstuff(void) {
int c=0,pr;
pr=0;
if (Serial.available()==0) return;
c=Serial.read();
do {
switch (p){
case 0:
if (c=='A'){
p=1;
}
pr=1;
break;
case 1:
if (c=='r') {
p=2; pr=1;
} else { p=0;
}
break;
case 2:
if (c=='n') {
p=3; pr=1;
} else { p=0;
}
break;
case 3:
if (c=='.') {
p=4; pr=1;
} else { p=0;
}
break;
case 4:
switch (c) {
case 'R':
p=5; pr=1;
break;
default:
p=0;
break;
}
break;
case 5:
if (c=='e') {
p=6; pr=1;
} else {p=0;
}
break;
case 6:
if (c=='s') {
p=7; pr=1;
} else { p=0;
}
break;
case 7:
if (c=='p') {
p=8; pr=1;
} else { p=0;
}
break;
case 8:
if (c==':'){
p=9; pr=1; dat=0;
} else { p=0; }
break;
case 9:
switch (c){
case 13:
p=20; pr=1;
break;
case '=':
if (dat==0) {
p=0;
} else {
p=10; pr=1;
}
break;
default:
if (isnum(c)) {
dat = 10*dat + (c-48);
pr=1;
} else { p=0; }
break;
}
break;
case 10:
if (isnum(c)){
valor = (c-48); p=11; pr=1;
} else { p=0; }
break;
case 11:
switch (c) {
case ':':
procesapares(dat,valor);
p=8;
break;
default:
if (isnum(c)){
valor = 10*valor + (c-48); pr=1;
} else { p=0; }
break;
}
break;
case 20:
if (c==10) pr=1;
p=0;
break;
default:
p=0; pr=1;
break;
}
} while (pr==0);
}
// Al comenzar el programa inicializa el puerto serie.
void setup(){
setupserial();
}
// El bucle principal.
void loop(){
// Es necesario llamar a esta funciona cada poco para recibir datos.
serialstuff();
}
2012/01/27 - Corregido BUG: Cambiando un writeln por write en la funcion enviapares
Felicidades por tu trabajo,estoy muy interesado en charlar contigo , y hacerte una oferta de las buenas ...jejeje, Pertenzco al grupo de trabajo XPANDT , como mi socio Ignacio, y nos gustaria captarte y traerte al lado oscuro, al mundo del lowcost para electronica de comunicacion, en la construcion de nuestras cabinas.
ResponderEliminarEscribeme, te presentare al grupo, y te contare nuestras intenciones, te van a encantar:
Todo free
Todo documentado
Todo esquematizado
Todo lo relacionado con Arduino y simulador , organizado.
Todo publicado
Estamos empezando, creando documentacion y estructurando la web www.xpandt.com ahora en obras, pero por e back estamos trabajando mucho.
Escribeme por favor a 737dragon@gmail.com , mi nombre es Oscar, y espero impaciente tu correo
El Codigo para el arduino no compila, porque falta definir la variable "p" que se usa en el switch de la funcion serialstuff.
ResponderEliminarEl codigo compila cuando le añado dentro de la funcion un "int P=0;". Parece funcionar todo, porque la ventana de python envia y recibe, y en el monitor IOCP aparece como conectado.
Pero no se como monitorizar, por ejemplo, el "brake", de hecho tengo un led que monitoriza cuando hay trafico en el puerto serie, y no se enciende nada mas que cuando conecta.
¿Es posible que la declaracion de la variable "p" no este bien posicionada o que este mal definida?
Puedes por favor documentar un poco el uso de esta aplicacion?
Gracias por tu trabajo.
Como el codigo publicado es un recorte de uno mas grande, es posible que me haya pasado y me falte algunas cosas.
ResponderEliminarPero tal como esta no funcionara o no hara nada.
En las lineas de comentarios he indicado lo que hace cada funcion y en mayusculas lo que hay que hacer con ella.
Hablas del monitor IOCP, asi que imagino que usas SIOC, bien tienes que hacer que en sioc una variable sigua al freno.
Luego tienes que modificar la funcion setupserial para que se suscriba a esa variable, en el ejemplo yo me subscribo a la 999, y como seguramente en sioc tu no tienes asignado nada a esa variable, por eso no te hace nada.
Luego tienes que añadir codigo a la funcion procesapares para que cuando el simulador cambie algo, y se lo envie a sioc, y sioc al arduino.
Tambien tendrias que añadir codigo (en loop) que usase la funcion enviapares, cuando quieras enviar datos al simulador.
Espero que esto te aclare algo las cosas.
Lo cierto es que he pasado este fin de semana, haciendo un codigo nuevo basandome en el tuyo. He utilizado tu pasarela en python, que funciona estupendamente.
ResponderEliminarHe cambiado la funcion de recepcion serie, acortandola un poco. Ya que en tu version, compruebas caracter a caracter, que lo que llega se corresponda a "Arp.Resp:".
La funcion que he escrito espera que despues de ":" siempre llega el ID, y despues de "=" siempre llega el valor, para finalizar el envio con ":" otra vez. Es un poco mas rapido.
Tambien he añadido un LCD de 4x20 para la visualizacion de los datos.
Ahora mismo lo tengo funcionando en XP10 con UIPCX v0.4 con algun que otro bug en el procesado de ASCII a INT. (Tengo que poner a 0 unas variables y aun no he encontrado el momento perfecto)
Si quieres compartire mi codigo contigo para avanzar juntos.
El echo de ver caracter a caracter, es por que en el futuro tambien respondera a otras secuencias ademas de Arp.Resp, a fin de gestionar las reconexiones. (Arp.Vivo y demas...)
EliminarEstaria encantado de ver tu codigo, siempres se puede aprender algo nuevo, ademas como el mio tiene licencia GPL tienes la obligacion moral de hacerlo ;-)
Estimado,
ResponderEliminarmuy interesante y he seguido al pie de la letra, he buscado información adicional, pero creo que son los únicos sobre este proyecto.
Pero quiero conocer los avances (si es posible).
Saludos y felicidades.
Actualmente no tengo mas avances en este codigo, funciona adecuadamente bien, y lo estoy utilizando para varias partes del simulador, a medida que las vaya realizando lo ire documentando en el blog, pero no aportan mas cosas a lo ya dicho, espero en el futuro poder conectar una tarjeta Ethernet al arduino para prescindir del script en python, pero eso tardara aun bastante.
ResponderEliminarHola ... ^ ^
ResponderEliminarEn Corea a través de Google Translate para escribir ... ^ ^;
Arduino y cuál es la conexión entre SIOC se veía muy bien.
I se usa FS2004 (iFly 737).
He corrido el ejemplo.
En Aruino en relación python.
Los datos se transfieren hacia y vamos a ver que había una serpiente pitón.
Pero a medida que la escritura SIOC SIOC para pasar datos de reunirse, de tener más.
SIOC guión, ¿cómo lo hago?
Se agradecería respuestas .... ^ ^
logosjun@hanmail.net
Hola,
ResponderEliminarEn el artículo comentas que con un shield Ethernet no haría falta el programa puente para enviar/recibir datos entre SIOC y Arduino.
Pero... Cómo se haría?
Saludos!