![]() |
[TUTORIAL] Arduino Consola y puerto serie
![]() Tutorial Arduino Consola y puerto serie. Interfaz creado con diversos lenguajes como C#, C++ CLR y VB .net bajo Visual Studio Community que puedes controlar el puerto serie a Arduino encendiendo y apagando un Led, manejar el LCD y recibes mensajes hacia el ordenador o PC. ![]() En este apartado mostramos el código fuente en C#, en el PDF se encuentra C#, C++ CLR y VB .net. Código C#: Código:
using System; Código:
using System; ![]() Código de Arduino: Código:
// ----- Electrónica PIC ----- ![]() Ver vídeo. https://www.youtube.com/watch?v=erQygRNAPWc Ver visor. Ver PDF. Un cordial saludo. |
^\||/^\||/^\||/
|
1 Archivos Adjunto(s)
Que tal REHome, sólo unos comentarios con respecto al código del Arduino. Ya que como es mi primer post todavía no puedo poner imágenes, por lo cual lo anexo como PDF.
El objetivo es que los lectores tomen conciencia de lo que pueden ocasionar nuestras decisiones de diseño, como la que muestras dentro de la función loop. Código:
while (Serial.available() > 0) Aunque sólo sea para enseñar, en mi opinión siempre hay que mostrar las consecuencias, porque si no lo hacemos, corremos el riesgo de diseminar malas prácticas de diseño entre los que nos leen, ya que por lo general somos lo suficientemente perezosos para superar el famoso copiar/pegar al que nos hemos ido acostumbrando. Saludos cordiales. |
Cita:
Y luego algún moderador añadirá la w que falta. |
Gracias por el tip, incluso agregué al final dos vídeos. Saludos
--------------------------------------------------------------------- Hay que tener en cuenta que estas trabajando con el puerto serie a 115200bps Código:
Serial.begin(115200); Luz_ON equivale a 5.22ms y Luz_OFF a 6.09ms Código:
while (Serial.available() > 0) Luego llegamos a ese delay de 10ms. A pesar de poder recibir un caracter cada 87us tenemos que esperar un total de 60 a 70 ms para recibir toda la cadena que compone un comando. Esto también puede ocasionar perdida de datos y además podemos ocasionar un OverRun en el Hardware U(S)ART. Reproduje tu código para mostrar a lo que me refiero ![]() Envío 1024 bytes más "\\r\\n" de los cauales se pierden 954 bytes En cambio, si lo hacemos con Código:
![]() Otro aspecto, envuelve el uso de la función loop. Si metes todo en esa función y si tienes retardos considerables, aun con el código que muestro arriba vas a tener algunos problemas de perdida de datos. Podríamos pensar en usar la función serialEvent, pero no todo es lo que parece. Esta función se llama después de llamar la función loop, así que cualquier retardo dentro de la función loop va a impactar el momento exacto en el que podemos procesar los datos entrantes. Arduino, internamente maneja una interrupción en la recepción que manda cada caracter recibido a un buffer de 63 bytes, la solución sería definir nosotros esa interrupción, pero si no nos queremos salir de las funciones que arduino nos provee, entonces debemos aprender a trabajar con lo que nos ofrece. Por lo pronto si en estos momentos le agregara un retardo de 500ms para hacer parpadear un led, enfrentaríamos los mismos problemas de posible perdidas de datos. Código:
const uint8_t Led=13; ![]() En esta última imagen se percibe que hay perdida de datos ya que los últimos debería de recibir los 1026 bytes, pero las perdidas pueden ser variables, además de que el U(S)ART deja de responder si el tamaño de la cadena que le llega es mayor a los 63 bytes del buffer de recepción. De este estado sale cuando introducimos una cadena que sea menor a 63 bytes, pero nos enfrentamos a la penosa perdida de datos. Aunque todo no esta perdido, ya que podemos hacer uso de la función micros de la siguiente forma para poder tener nuestro retardo de 500ms (aproximadamente) Código:
![]() No soluciona todo ya que ahora nos enfrentamos al overflow de la variable que almacena los micro segundos que han pasado desde que el Arduino fue encendido, pero el código de arriba no bloquea el funcionamiento de otras secciones del sistema. A partir de esto ya se pude vislumbrar una mejor forma de desarrollar un sistema embebido que sea más confiable ya que tomamos conciencia de lo que puede ocasionar nuestras decisiones de diseño. Anexo dos vídeos donde se puede percibir de forma clara el problema que se ocasiona. Para las pruebas estoy enviando 40000 bytes al inicio con 0 ms entre byte y después 1 ms entre byte. En el primer vídeo vemos como el parpadeo del led se detiene mientras espera a que termine de enviar los datos y además se puede apreciar perdida de datos. En este segundo vídeo, la perdida de datos es debida a que no existe más RAM, pero no bloquea el parpadeo del led, así que ya tenemos la ventaja que el sistema no se va a bloquear mientras espera que todos los datos sean recibidos. Cabe aclarar que siempre hay mejores formas, pero con esto ya podemos ir un paso adelante. |
1 Archivos Adjunto(s)
@tsk
Buenas: No te había leído. Tendré que hacer otra vez el tutorial, ya que tengo intención de hacer lo mismo pero con entradas analógicas ya para Delphi 10.4. Lo que no me deja ahora mismo cargar el proyecto. Me da este error. Desde que pulse File--->Open Proyect para cargar un archivo me sale este error y no se el motivo. https://www.clubdelphi.com/foros/att...1&d=1615844858 Desinstalé Delphi 10.2 y luego instalé el Delphi 10.4. ¿Tiene algo que ver? Sobre el tutorial de arriba con el código de ARduino. Que es este. Código:
#include ¿Cómo harías el código sustituyendo a este? Lo comento para hacerlo de nuevo. A parte que voy hacer el de entradas y salidas analógicas. Quiero hacer coas con Delphi y Arduino. ;) Un cordial saludos y muy buena explicación. |
Es exactamente lo que que puse, lo que cambiaría es que eliminas la parte que hace parpadear el LED y dentro de la condición que se pregunta por stringComplet ahí procesas los comandos.
Aunque yo lo que haría es hacer un separación de los componentes del sistema para que te sea más fácil desarrollar. Por lo general siempre sigo una estrategia similar a la siguiente, aunque cada aplicación es su propio mundo, por lo que a veces no es posible generalizar. Defino una estructura donde coloco la información de cada comando, incluso lo que debe de ejecutar. Código PHP:
Después se crear un arreglo donde se colocan los comandos de la siguiente forma. Código PHP:
Código PHP:
Por ejemplo cmdSearch busca en el arreglo el índice del comando, si es que existe, en caso de existir regresa el índice, de lo contrario un -1. Con esa información cmdProcess se encargar de ejecutar el comando y decidir si el formato es de un query, un set o una ejecución Así es mucho más sencillo añadir comandos y que lleves un buen control. En tu ejemplo, tienes un Luz_ON, Luz_OFF, pero si quieres añadir más, o incluso preguntar el estado, le vas a tener que agregar más y más IFs, en cambio si lo planteas de esta forma, con un sólo comando podrías manejar todas las opciones {"+LUZ",4,getState,setState,NULL}, Entonces puedes definir un formato de comando, por ejemplo AT+LUZ <- Te regresa el estado de todas las luces que tengas definidas AT+LUZ?1 <- Te regresa el estado de la Luz 1 AT+LUZ==1,0 <- Pone la Luz 1 en estado bajo AT+LUZ==2,1 <- Pone la Luz 2 en estado alto De la misma forma, podrías aplicar el mismo concepto a la lectura de los sensores, y en lugar de actuar directamente sobre el sistema, este le enviaría un comando, por ejemplo: Código PHP:
Código PHP:
Código PHP:
Por ejemplo, ahorita sólo tienes un sólo LED y el comando AT+LUZ==1,1 te arrojaría un error, pero si decides agregarle una segunda luz, podrías ejecutar el comando AT+LUZ==1,1 modificando una sola parte del sistema sin importar que venga de un comando que se introduzca por el puerto serie o que provenga como respuesta a un estímulo de una entrada, de lo contrario vas a tener que modificar el código en, por lo menos dos partes: 1.- La sección que interpreta los comandos que entran por el puerto serie. 2.- En el código de cada uno de los sensores cuyo efecto se debe de notar en el estado de la salida en particular. |
La franja horaria es GMT +2. Ahora son las 15:24:21. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi