Tenía algunos sensores "Sharp GP2D12" medidores de distancia por casa y se me ha ocurrido hacer una aplicación en VB.NET para mostraros como trabaja este sensor. Para ello se me ha ocurrido usar Arduino como tarjeta de conversión para transmitir los datos del Sensor "GP2D12" al PC.
Aquí os dejo un primer pantallazo de como ha quedado la aplicación gráfica realizada con VB.NET para trabajar con este sensor tan interesante para muchas aplicaciones. En mi caso por ejemplo empecé a usarlo en los combates de robots de sumo, para detectar a los robots contrarios en el tatami, entre otras.
Bien, manos a la obra ...
He usado Arduino como placa encargada de convertir la señal analógica que este sensor nos da en función de la distancia y enviarla vía serie-usb hacia el PC. Una aplicación programada en Visual Basic .NET es la encarga de mostrar la medida que realiza el sensor a modo de simulación de proximidad del objeto que el GP2D12 detecta.
En primer lugar aquí os dejo el datasheet del sensor GP2D12, para que lo echéis un vistazo y veáis como trabaja este modelo en concreto.
Existen otros modelos que también son idénticos en encapsulado y que su modo de funcionamiento es diferente a este. Por ejemplo los hay que miden la distancia pero la salida es simplemente un nivel lógico de 0 ó 5V, es decir son con salida digital, otro lo que da es la medida vía serie y hay que leerla para poder interpretarla, otros miden distancias mayores o menores, pero el principio de funcionamiento es el mismo.
El pin out de este sensor es el que os muestro en la siguiente imagen. Si bien es verdad yo no pude encontrar el conector idóneo para este conector, por lo que en mi caso tuve que improvisar una solución soldando unos cablecillo a los pines de la placa que sujeta el propio conector. Si lo encontráis mucho mejor, pues así evitareis tener que arriesgaros haciéndole alguna ñapa con los pines del conector.
GP2D12 Arduino
Vo = Pin A0
GND = Gnd
Vcc = +5V
El funcionamiento de este modelo es el siguiente. Cuando el sensor detecta la presencia de un objeto
este nos entrega una señal de salida analógica. Esta señal se encuentra comprendida entre los 0,4V y 2,7V con una rango de distancia al objeto que detecta, el cual no es lineal, y va desde los 80 cm hasta los 10 cm. A continuación os dejo la gráfica de comportamiento sacada del datasheet del fabricante:
Pulsa en este enlace para descargaros la hoja de cálculo de Excel para generar la curva de regresión que acabo de mostrar:
A continuación os muestro el montaje del Sensor GP2D12 sobre una pequeña placa board y conexionada con la placa de Arduino.
//CONTROL GP2D12
// ENTRADA ANALOGICA / ANALOG INPUT
// In this case, for do any actions with ANALOG INPUT the received command must be:
// Example: A03_IN__XXX
// Where inDatoVB[0] = A --> ANALOG PIN
// inDatoVB[1] = Number of the pin (tens)
// inDatoVB[2] = Number of the pin (units)
// inDatoVB[3] = Always Character '_'
// inDatoVB[4] = Character 'I' -->
// inDatoVB[5] = Character 'N' --> Type of PIN INPUT
// inDatoVB[6] = Always Character '_'
// inDatoVB[7] = Always Character '_'
// inDatoVB[8] = Always Character 'X'
// inDatoVB[9] = Always Character 'X'
// inDatoVB[10]= Always Character 'X'
Para programar la tarjeta de Arduino hay que hacer lo siguiente:
o bien hacer un copy/paste del código que muestro a continuación y salvarlo en un fichero.
//'*****************************************************************************************
//' LICENSE INFORMATION
//'*****************************************************************************************
//' Example Application for Control a GP2D12 Distance Sensor with Arduino and VB.NET 1.0.1.0
//' It shows a program that show the distance from the sensor to an object. The measurements
//' are sent to a GUI developed in Visual Basic .NET through serial/usb port
// It's implemented an own small protocol to do the communication very easy.
//'
//'
//' Copyright © 2015
//' Rubén García Coronado
//' Email: rubengaco13@gmail.com
//' Created: Feb 2015
//'
//' This program is free software: you can redistribute it and/or modify
//' it under the terms of the GNU General Public License as published by
//' the Free Software Foundation, either version 3 of the License, or
//' (at your option) any later version.
//'
//' This program is distributed in the hope that it will be useful,
//' but WITHOUT ANY WARRANTY; without even the implied warranty of
//' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//' GNU General Public License for more details.
//'
//' You should have received a copy of the GNU General Public License
//' along with this program. If not, see <http://www.gnu.org/licenses/>.
//'*****************************************************************************************
int len; //Variable to know the size of the received command
char inDatoVB[10]; //Variable to store the received command
int sensorPin = A0; // Select the input pin for the GP2D12
int GP2D12_Value = 0; // Variable to store the value coming from the sensor
float GP2D12_Voltage = 0.0; // Variable to stora the value of the Voltage
int GP2D12_Distance = 0; // Variable to store the value of the Distance
void setup() {
Serial.begin(115000);
Serial.print("Ready the communication Port, RUBEN"); //Send a message to the port
}
void loop() {
if (Serial.available() > 0)
{
//Data received are read in the variable inDatoVB array
//These values are the streaming that would be sent from application GUI VB .NET
//They are read one by one to check what is the action to do.
len = Serial.readBytes(inDatoVB,11);
Serial.print(inDatoVB[0]);
Serial.print(inDatoVB[1]);
Serial.print(inDatoVB[2]);
Serial.print(inDatoVB[3]);
Serial.print(inDatoVB[4]);
Serial.print(inDatoVB[5]);
Serial.print(inDatoVB[6]);
Serial.print(inDatoVB[7]);
Serial.print(inDatoVB[8]);
Serial.print(inDatoVB[9]);
Serial.print(inDatoVB[10]);
// CONTROL GP2D12
// ENTRADA ANALOGICA / ANALOG INPUT
// In this case, for do any actions with ANALOG INPUT the received command must be:
// Example: A03_IN__XXX
// Where inDatoVB[0] = A --> ANALOG PIN
// inDatoVB[1] = Number of the pin (tens)
// inDatoVB[2] = Number of the pin (units)
// inDatoVB[3] = Always Character '_'
// inDatoVB[4] = Character 'I' -->
// inDatoVB[5] = Character 'N' --> Type of PIN INPUT
// inDatoVB[6] = Always Character '_'
// inDatoVB[7] = Always Character '_'
// inDatoVB[8] = Always Character 'X'
// inDatoVB[9] = Always Character 'X'
// inDatoVB[10] = Always Character 'X'
if (inDatoVB[0] =='A' && inDatoVB[1]=='X' && inDatoVB[2] =='X' && inDatoVB[3]=='_' && inDatoVB[4] =='I' && inDatoVB[5]=='N' && inDatoVB[6]=='_' && inDatoVB[7] =='_')
{
// Read the value from the sensor:
GP2D12_Value = analogRead(sensorPin);
GP2D12_Voltage = (GP2D12_Value * 5.0)/1023;
Serial.println(GP2D12_Voltage);
delay(100);
}
}
}
2. Conectar la placa de Arduino a un puerto USB del PC y lanzar el IDE de Arduino. Automáticamente el software detectará el puerto de conexión usado. Si tuvieseis algún problema con la detección del puerto USB con el PC, os recomiendo que echéis un vistazo a este enlace.
3. Abrir el fichero que anteriormente os habéis descargado.
5. Pulsar sobre el botón de reset de la placa de Arduino y el software ya estará listo, enviando las lecturas que este haciendo del sensor GP2D12 hacia el PC.
Os dejo un vídeo para que veáis el funcionamiento de la aplicación VB.NET midiendo la distancia del objeto en movimiento con el GP2D12. Para hacer que la medida no oscile mucho, he programado una media aritmética con cada N medidas que se hacen. Donde N la he definido como una variable publica global que permite configurar nuestra media a nuestro gusto, para así observar el efecto de cuanto oscila la medida mostrada en el display.
También os muestro unas imágenes con algunos de los valores medidos con el sensor GP2D12 mostrados en la aplicación gráfica de Visual Basic.
En estos pantallazos se muestran las medidas obtenidas de distancia moviendo un objeto. Se puede apreciar como el voltaje analógico que marca el GP2D12 va decrementando a medida que el objeto se aleja del sensor.
Como podéis observar en esta última, se indica de color rojo que el objeto detectado supera la distancia máxima para la cual el sensor ha sido calibrado.
Además para que sea mucho más fácil la calibración de la distancia medida, la fórmula de ajuste que anteriormente os había mostrado, ha sido programada en la aplicación gráfica con VB.NET. A continuación os muestro la parte del código que se encarga de hacer el cálculo y el movimiento del objeto en función del valor analógico recibido de la placa de Arduino.
Private Sub Timer_A_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer_A.Tick
Application.DoEvents()
If Estado_Botones_Analogicos_IN(Val(Pin_A0)) = True Then
If A0_Valor = "" Or A0_Valor = "0.0" Or A0_Valor = "0." Or A0_Valor = "0" Or A0_Valor = "0.00" Then
Else
'Probando otra aproximación
GP2D12_Distance = 29.88 * Math.Pow(Val(A0_Valor), -1.25)
GP2D12_Distance = Math.Round(29.88 * Math.Pow(Val(A0_Valor), -1.25))
'GP2D12_Distance = 28.81 * Math.Pow(Val(A0_Valor), -1.15)
'GP2D12_Distance = Math.Round(28.81 * Math.Pow(Val(A0_Valor), -1.15))
GP2D12_Media_Indice = GP2D12_Media_Indice + 1
If GP2D12_Media_Indice = GP2D12_Media_N Then
Label_A0.Text = A0_Valor & "V"
'Calculo de la Media de las medidas
For i = 0 To GP2D12_Media_N - 1
GP2D12_Media = Val(GP2D12_Array_Media(i)) + Val(GP2D12_Media)
Next
GP2D12_Media = Math.Round(GP2D12_Media / GP2D12_Media_N)
GP2D12_Media_Indice = 0
If Len(GP2D12_Media) = 1 Then
Control_Display_7Segments_U.Ruben_Input_Display = Mid(GP2D12_Media, 1, 1)
Control_Display_7Segments_D.Ruben_Input_Display = "0"
ElseIf Len(GP2D12_Media) = 2 Then
Control_Display_7Segments_D.Ruben_Input_Display = Mid(GP2D12_Media, 1, 1)
Control_Display_7Segments_U.Ruben_Input_Display = Mid(GP2D12_Media, 2, 1)
ElseIf Len(GP2D12_Media) > 3 Then
Control_Display_7Segments_D.Ruben_Input_Display = ""
Control_Display_7Segments_U.Ruben_Input_Display = ""
End If
If GP2D12_Media > 80 Then
Control_Display_7Segments_U.Ruben_Color_Display = "Red"
Control_Display_7Segments_D.Ruben_Color_Display = "Red"
Panel1.BackColor = Color.Red
Panel_Object.BackColor = Color.Red
Label_A0.ForeColor = Color.Red
Else
Control_Display_7Segments_U.Ruben_Color_Display = "Green"
Control_Display_7Segments_D.Ruben_Color_Display = "Green"
Panel1.BackColor = Color.Black
Panel_Object.BackColor = Color.Lime
Label_A0.ForeColor = Color.White
End If
Object_Position.X = Object_X0 + (GP2D12_Media * (Object_X1 - Object_X0)) / GP2D12_Max
Object_Position.Y = Object_Y1
Panel_Object.Location = Object_Position
If GP2D12_Media >= GP2D12_Max Or GP2D12_Media < 0 Then
ProgressBar_A0.Value = "255"
Else
ProgressBar_A0.Value = (GP2D12_Media) * (255 / GP2D12_Max)
End If
End If
GP2D12_Array_Media(GP2D12_Media_Indice) = GP2D12_Distance
GP2D12_Media = "0"
End If
End If
Comando_P1A = CA
Comando_P2A = Cvalor_2X 'Label_Pin_A0.Text
Comando_P3A = Cin
Comando_P4A = Cvalor_3X
Comando_to_Arduino = Comando_P1A & Comando_P2A & Separador & Comando_P3A & Separador & Comando_P4A
txtSend.Text = Comando_to_Arduino
cmdSend_Click(sender, e)
If Button_A0_On_Off.Text = "GP2D12 state: Off" Then
Timer_A.Enabled = False
End If
End Sub
El código que se encuentra en color rojo es la parte que calcula la distancia del objeto detectado en función del valor analógico que nos envía Arduino tras la conversión y donde se calcula la media de un número N de distancias medidas.
Las lineas de código que programan el comportamiento del Sensor GP2D12 son:
GP2D12_Distance = 29.88 * Math.Pow(Val(A0_Valor), -1.25)
GP2D12_Distance = Math.Round(29.88 * Math.Pow(Val(A0_Valor), -1.25))
Además de esta fórmula, probé otras ajustando otros valores de distancia y voltaje y así poder comprobar como cambiaba el comportamiento del GP2D12. Podéis hacer esta pruebas y así ver el resultado.
Para descargaros todo el código fuente de la aplicación de Control del GP2D12, el código de Arduino y la hoja de calculo Excel, pulsar sobre el siguiente enlace:
Código fuente para el "control del GP2D12"
Espero que os guste y espero también vuestros comentarios.
Un saludo.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Por favor, si te ha gustado el blog, te ha ayudado o has visto algún proyecto interesante del que te has podido descargar alguna documentación por favor deja algún comentario. Gracias.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
No hay comentarios:
Publicar un comentario
Deja tu comentario