Arduino es un invento, de eso no cabe duda, y al estar tan extendido es ademas una plataforma muy barata y flexible de programar microcontroladores.
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.
Aqui esta la informacion util:
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 arduinoEs 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