Hoy veremos como obtener valores enviados por el Arduino dentro del Excel, y volcándolos a celdas para después poder trabajar con ellos.
Hay multitud de aplicaciones para esto, desde graficar las mismas como en el ejemplo que dejo yo (que puede ser por ejemplo, una medición de temperatura y humedad de un ambiente, o tensión deformación de alguna pieza), hasta realizar correcciones a través de estos y luego enviar los valores corregidos nuevamente al Arduino para que realice algo.
Video de Igor R usando un potenciómetro lineal para graficar su valor con respecto a la variable tiempo (millis).
Paso por Paso:
Lo primero que hacemos es pensar como va a funcionar nuestro sistema. En este caso, se encuentra de la siguiente forma:
Tendremos 5 botones: Abrir Puerto COM, Obtener dato individual, Obtener datos de manera automática, Cerrar Puerto COM y por ultimo Borrar Datos que explicaré mas adelante.
Que hace cada uno?
Abrir Puerto COM: Presionando este botón abriremos el Puerto COM. Tendremos que elegir el puerto donde se encuentre el arduino. Si no sabés que puerto es, podés conectar el Arduino, abrir el IDE (el software), ir a Tools-Serial Port y el que este seleccionado será el puerto utilizado.
Private Sub CommandButton1_Click()
If NETComm1.PortOpen = True Then NETComm1.PortOpen = False 'Si el puerto esta abierto, lo cierra.
'Esto nos asegura de abrir el puerto con los parámetros que están a continuación
NETComm1.CommPort = Sheet1.Range("C3").Value 'Toma el valor de la celda "C3". Ahi escribiremos el número del puerto.
NETComm1.Settings = "9600, N, 8, 1" '9600 es la velocidad en baudios, N es la paridad,
'8 es la cantidad de bits, y 1 es el numero de bits de parada.
NETComm1.Handshaking = comNone '<a href="http://msdn.microsoft.com/en-us/library/aa259410%28VS.60%29.aspx">http://msdn.microsoft.com/en-us/library/aa259410%28VS.60%29.aspx</a>
NETComm1.InputMode = comInputModeText '<a href="http://msdn.microsoft.com/en-us/library/aa259414%28VS.60%29.aspx">http://msdn.microsoft.com/en-us/library/aa259414%28VS.60%29.aspx
</a> NETComm1.RThreshold = 1 '<a href="http://msdn.microsoft.com/en-us/library/aa259423%28VS.60%29.aspx">http://msdn.microsoft.com/en-us/library/aa259423%28VS.60%29.aspx</a>
NETComm1.InputLen = 1 '<a href="http://msdn.microsoft.com/en-us/library/aa259413%28VS.60%29.aspx">http://msdn.microsoft.com/en-us/library/aa259413%28VS.60%29.aspx</a>
NETComm1.InBufferSize = 1024 '<a href="http://msdn.microsoft.com/en-us/library/aa259412%28VS.60%29.aspx">http://msdn.microsoft.com/en-us/library/aa259412%28VS.60%29.aspx
</a>
If NETComm1.PortOpen = False Then
NETComm1.PortOpen = True
End If
Obtener dato individual: Enviaremos la letra "D" por el puerto serie al Arduino.
Private Sub CommandButton2_Click()
NETComm1.Output = "D"
End Sub
Obtener datos de manera automática: Envia una "D" cada un tiempo determinado. Se vale de una API de Windows que te devuelve el tiempo en ms desde que se inicio el sistema.
Donde se declaran las variables debe ponerse Private Declare Function timeGetTime Lib "winmm.dll" () As Long
El código será:
tiempo_inicial = timeGetTime()
While NETComm1.PortOpen = True
tiempo_actual = timeGetTime()
If ((tiempo_actual - tiempo_inicial) >= Sheet1.Cells(5, 3).Value) Then 'Valor de la celda de la columna 5, fila 3.
tiempo_inicial = timeGetTime()
NETComm1.Output = "D"
End If
kk = DoEvents()
Wend
Cerrar Puerto COM: Cierra el puerto.
Private Sub CommandButton4_Click()
NETComm1.PortOpen = False
End Sub
Ahora vamos a la parte del código dentro del Arduino:
//Medición de un potenciometro con Excel y Arduino
//Nico - 07/2009 - www.ingenegros.com.ar
int inByte;
int Primer_Pote;
int Segundo_Pote;
void setup() {
Serial.begin(9600); //Abrimos el puerto serie a una velocidad de 9600 baudios
}
void loop() {
if (Serial.available() >0) { //Nos fijamos si hay hay información entrando por el puerto serie
inByte=Serial.read(); //Si en efecto estamos recibiendo datos, entonces los escribimos en la variable inByte
if (inByte==68) { //Vemos si lo que recibimos fue una "D"
//(o caracter 68, en el código ASCII - <a href="http://www.arduino.cc/en/Reference/ASCIIchart">http://www.arduino.cc/en/Reference/ASCIIchart</a>)
Primer_Pote=(analogRead(0))*(5000.0/1023); //Leemos el primer potenciometro
//que esta conectado al pin 0.
delay(10); //Esperamos 10 segundos para darle tiempo al conversor analógico digital a que se recupere
Segundo_Pote=(analogRead(1))*(5000.0/1023); //Tomamos la medición del otro pote, conectado al pin 1.
Serial.print(millis()); //Imprimimos la variable millis que nos devuelve el tiempo en
//ms desde que se esta ejecutando el programa.
Serial.print(char(44)); //Enviamos el caracter 44 en ASCII, que es una ","
delay(20);
Serial.print(Primer_Pote,DEC); //Enviamos el valor del primer pote de forma decimal
Serial.print(char(45)); //Mandamos el caracter 45 que es "-"
delay(20);
Serial.println(Segundo_Pote,DEC); //El println nos dice que luego de imprimirse la variable
//se hará un enter (salto de linea) o lo que es lo mismo el caracter 10
}
}
}
NOTA: Si tienen algún error al tratar de compilarlo, eliminen todos los comentarios que hice y vuelvan a intentarlo
Volvemos a la parte de VBA en el Excel y mostramos como hace el evento OnComm() para obtener los datos:
Private Sub Netcomm1_OnComm()
If NETComm1.CommEvent = NETComm_EV_RECEIVE Then
datos = NETComm1.InputData
nadoti = Asc(datos) 'Devuelve el valor en ASCII de lo que recibimos a traves del InputData
If ((nadoti > 13) And (nadoti 44)) Then 'Lee toda la cadena
buffer = buffer + datos
End If
If (nadoti = 44) Then 'Si se encuentra con una "," se detiene y guarda la variable hasta ese momento.
tiempo = buffer
buffer = ""
Sheet1.Cells(12, 5).Value = tiempo 'Me escribe el valor en la celda
If i >= 2 Then
Sheet2.Cells(i, 2).Value = tiempo 'Esto me dice que continuará
'escribiendo los sucesivos valores en las celdas
i = i + 1
End If
End If
If (nadoti = 45) Then 'Igual que en el caso anterior pero con la "-"
largo = Len(buffer)
pote = Left(buffer, largo - 1)
buffer = ""
Sheet1.Cells(12, 9).Value = pote
If j >= 2 Then
Sheet2.Cells(j, 3).Value = pote
j = j + 1
End If
End If
If (nadoti = 10) Then 'El 10 será el ultimo caracter que recibamos
dato = buffer
buffer = ""
Sheet1.Cells(12, 12).Value = dato
If k >= 2 Then
Sheet2.Cells(k, 4).Value = dato
k = k + 1
End If
End If
End If
End Sub
Que hace el botón Borrar Datos?
Nos limpiará todas las celdas hasta ese momento, de la siguiente manera:
Private Sub CommandButton5_Click()
For var_i = 2 To i
Sheet2.Cells(var_i, 2).Value = ""
Next var_i
For var_j = 2 To j
Sheet2.Cells(var_j, 3).Value = ""
Next var_j
For var_k = 2 To k
Sheet2.Cells(var_k, 4).Value = ""
Next var_k
Sheet1.Cells(12, 5).Value = tiempo
Sheet1.Cells(12, 9).Value = pote
Sheet1.Cells(12, 12).Value = dato
End Sub
Como hago el grafico?
Elijo dentro del Excel que las variables a graficar sean Tiempo, datos Pote 1 y datos Pote 2. Recuerden que el valor máximo de celdas para un gráfico dentro del Excel es de 32000 (aunque el maximo para calculos sea de 65536, asi que tengan cuidado cuando eligen la tasa de refresco y van a realizar un ensayo que se extienda mucho en el tiempo.
Videos y link de descarga:
Aca me pueden ver a mi jugando un poco con el programa
Espero que les sirva de ayuda, cualquier duda que tengan dejen un comentario ;)
Saludos, Nico!
Comentarios
¡Sólo los usuarios registrados pueden escribir comentarios!
Bravinsky
|2009-07-24 18:51:32
hola ingenegros, tengo una duda existencial. como se hace para que funcione el excel con el arduino? conecto el equipo directamentre a la PC?
hace falta tener el excel 2007 como el que usan ustedes?
gracias!
josé aguirre
- gráfico
|2009-09-28 10:46:07
Hola Nico: muy bueno el aporte. Lo bajé y funciona ok en el Excel. Por cierto, la gráfica que obtengo es la de abajo. La que figura en el video, la del círculo rojo que se cierra, cómo se logra?. Muchas gracias
Nico
|2009-11-30 16:10:16
Fijate en este link abajo de todo http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=12 30677761 Ahi Igor R postea un link para bajarse su programa en excel, ese el del circulo.