Paso 6: El Software de Windows...
El Software de Windows fue escrito usando Microsoft Visual Studio 2015 actualización 1. Es una aplicación basada en diálogo MFC de C++ nativa creada mediante el Asistente de cuadro de diálogo MFC. La interfaz de usuario - el cuadro de diálogo fue creado usando el editor de recursos. El cuerpo del código generado por el asistente. Señalaré sólo las partes que demuestran comunicación con el Arduino. El resto del código está disponible en github aquí:
https://github.com/alsliahona/CO2LaserWaterFlowMonitor/
Encontrar el Arduino puerto serie "COM"
Ahora que nos hemos movido en gran parte más allá de los días de los módems, no es común que muchos puertos COM en Windows PC en funcionamiento. Es posible que pueden tener dispositivos de USB como su Arduino que utilizar un COM puerto como una interfaz serial. Podemos enumerar todos los puertos COM disponibles en el PC fácilmente usando un bucle for que invoca QueryDosDevice. Una vez que tenemos una lista de puertos COM podemos presentar la lista que les permite al usuario seleccionar la que es su monitor de flujo de agua. Si hay sólo un elemento en la lista automáticamente podemos abrirlo. Para comenzar entonces, añadimos un envase para la clase de CCO2WaterFlowDlg. Esto está en la línea 50 de CO2WaterFlowDlg.h, como un std::map de dos cadenas. La primera cadena (la clave) es el puerto COM que vamos a mostrar y abrir. La otra cadena es el nombre del dispositivo DOS, que guardan sobre todo para el diagnóstico.
El método declarado en la línea 54 se utiliza para rellenar el contenedor. Se implementa en CO2WaterFlowDlg.cpp, líneas 70-78:
BuildCOMPortMap() se llama cuando la aplicación se inicia y se construye una instancia de CCO2WaterFlowDlg, como se puede ver en línea 94 por encima. En este punto, los dispositivos COM presentes en el sistema será en nuestro envase.
Cuando el cuadro de diálogo primero inicializa comprobará en OnInitDialog() para ver si hay puertos COM disponibles. Si no, se mostrará un mensaje al usuario pidiéndole al plug-in el monitor de la tasa de flujo. Este mensaje se repetirá hasta que el usuario hace clic en cancelar, o hasta un dispositivo de COM está presente. Ver el lazo en líneas 146-155 a continuación:
La lista de dispositivos disponibles se mostrarán en la lista desplegable (ComboBox). Esto se hace cuando se llama a RefreshCOMList() en la línea 161 por encima. El código para esto es bastante estándar código MFC para rellenar un ComboBox. Se muestra a continuación:
Líneas 296 a 301 entradas claro en el cuadro combinado, mientras que líneas 304 a 309 agregar cada elemento del contenedor al cuadro combinado. Otro contenedor, m_COMSelectionMap se mantiene el puerto COM que asocia el identificador de entrada de cuadro combinado. Cuando el usuario hace clic en abrir, esto se utiliza para extraer el nombre del puerto COM para abrir.
En la línea 310, se selecciona el último elemento añadido al cuadro combinado.
Si sólo un elemento se encuentra en la lista (línea 312), ese elemento se abre automáticamente mediante la simulación de un usuario, haga clic en el botón Open (línea 316).
Abrir el puerto COM
Cuando el usuario hace clic en el botón abrir, o cuando se invoca a OnBnClickedButtonOpen() de RefreshCOMList() el elemento seleccionado del cuadro combinado se utiliza para obtener el nombre del puerto COM (líneas 221 y 222 abajo):
En línea 223 en el intento se hace para abrir el puerto serie. Si el usuario no se solicitará y se permitirá seleccionar un nuevo elemento. Si sin embargo con éxito abrir el puerto COM, líneas 230-232 deshabilitará los botones Open y escanear puertos y permitirán el botón establecer umbral. Una vez que se ha abierto el puerto COM, un temporizador para encender cada 1/8 de segundo. El controlador de temporizador utiliza m_SerialPort para leer la última actualización (si está disponible) del Monitor de flujo de agua y actualiza el estado de muestra en el cuadro de diálogo.
El ScanPorts el botón no hace nada más que volver a invocar BuildCOMPortMap() y RefreshCOMList().
La clase ArduinoSerial
La clase ArduinoSerial encarga de todo lo asociado a apertura, cierre, lectura y escritura para el Arduino a través del puerto serial. Está diseñado específicamente para el Monitor de flujo de agua, pero puede ser fácilmente adaptado para las necesidades de alternativas. Se define en ArdSerial.h como sigue:
Tenga en cuenta que la clase es la inicialización porque no queremos abrir el puerto COM hasta que sepamos lo que seleccionar. Cuando se llama a Close() se cerrará el puerto COM como m_hSerial se pasa a CloseHandle(), m_bConnected se establecerá nuevamente en falso. Porque esto es una clase RAII, será automáticamente limpiar (por ejemplo, cerca de la manija) cuando su destructor se invoca, esto se hace llamando a Close().
Anteriormente hemos visto donde se invoca el método Open() en OnBnClickedButtonOpen() de CCO2WaterFlowDlg.cpp [línea 223 de CO2WaterFlowDlg.cpp]. Te darás cuenta que m_SerialPort es una instancia de ArduinoSerial declarada en la línea 52 de CO2WaterFlowDlg.h:
CreateFile y ajuste de parámetros de COM
Abrir el aparato, una vez que sabemos el puerto COM es simplemente una cuestión de llamar a CreateFile seguido por llamadas a GetCOMState y SetCOMState que la velocidad y otros parámetros de la serie. Líneas 26 a 50 siguientes muestran la llamada CreateFile y el indicador de usuario en caso de error:
Con el puerto abierto obtenemos el estado COM y ajustar para que utilice una tasa de 9600 baudios (no dude en cambiar a esta si le gusta, pero coincide con el cambio en su sketch de Arduino!) Todo el restante configuración del puerto COM se muestra a continuación. Aunque parece un montón de código, no hay mucho que explicar:
Observe la llamada al PurgeComm on line 87 y el sueño en la línea 89. Cada vez que conectas al puerto serie de Arduino restablece el dispositivo.
Lectura y la escritura desde el Arduino
Porque útil hemos mantenido la comunicación desde el Arduino y muy simple, la ArduinoSerial Lee y escribir los métodos se limitan a leer un completo, null terminada línea de texto y escribe un único byte. Usted puede haber notado la declaración de nuestro buffer leer en línea 45 de ArdSerial.h, así como la función de miembro privado que readavailable() declarada en la línea 47. ReadAvailable se utiliza para añadir nuevos datos del puerto serial a nuestro buffer. Este aspecto:
(Tenga en cuenta el comentario a la línea 124 es un remanente del ejemplo de Arduino Serial aquí:
http://playground.arduino.cc/Interfacing/CPPWindows). En la línea 122 un búfer temporal asignado el tamaño de que los partidos los bytes legibles registrados por la llamada a ClearCommError en línea 114. En línea 126 se leen los bytes en el búfer temporal (vArray). Y en líneas de 131 a 134 esos bytes se adjuntan al m_vBuffer.
ReadAvailable() se invoca cada vez que se llama ReadNullZString() y se ReadNullZString a la primera cadena terminada en null en el búfer de la salida strRead:
Escritura para el Arduino es muy sencilla, y esto es en gran parte porque sólo tenemos que enviar un solo byte, utilizado para actualizar el valor de umbral:
Atar a la interfaz de usuario
El temporizador que se ha mencionado anteriormente, que dispara cada 1/8 de segundo llama m_Serial.ReadNullZString(). Cuando una cadena está disponible entonces analizar la cadena y actualizar la interfaz de usuario. Esto se muestra en la parte de abajo. (Ver el código de github para ver el resto del código)
Una cosa importante a observar... El "flujo" aparecido se basa en las especificaciones para el sensor de velocidad de flujo. Si utiliza un sensor de velocidad de flujo diferentes, ajustar los cálculos a partir de la línea 275 de acuerdo a las especificaciones del sensor.
Ajuste del umbral de
Lo último para cubrir es cómo enviamos el nuevo umbral para el Arduino. Probablemente ya has adivinado basado en el código anterior, que llamamos simplemente m_SerialPort.WriteByte() con el nuevo umbral. Sería correcto. El código es muy simple como se puede ver a continuación:
En línea 329, el valor de umbral es leer desde la interfaz de usuario, convierte a un BYTE en la línea 330 y enviado a Arduino en línea 331. Recordará desde el sketch de Arduino que esto interrumpe el bucle principal, ajuste el umbral de alarma y luego reinicie el bucle principal.