Programando microcontrolador ARM: 7 - Nuevo entorno de desarrollo Open System Workbench for STM32 (Eclipse) (stm32f103c8)


Para facilitar el acceso al desarrollo y programación de microcontroladores STM32 vamos a cambiar a un entorno de desarrollo multiplataforma, de esta manera cualquier usuario, tanto Windows, Mac y Linux, podrá acceder a la información publicada en este blog.

El entorno que vamos a utilizar es System Workbench for STM32, este IDE está basado en Eclipse y contiene todo lo necesario para poder programar nuestros microcontroladores. Además de nuestro BluePill basado en STM32F103 vamos a poder programas toda la gama de microcontroladores STM32, aunque hay que tener en cuenta debemos configurar los proyectos específicamente para cada microcontrolador.

DESCARGA E INSTALACIÓN

Para poder descargar el entorno de desarrollo necesitamos registrarnos en la web de OpenSTM32, http://www.openstm32.org/HomePage.

Una vez registrados tendremos pleno acceso a la web y por tanto a las descargas. Seleccionaremos en el menú de la izquierda System Workbench for STM32.

Entonces nos aparecerá todo lo necesario para descargar el entorno. Además disponemos de una guía detallada para instalar correctamente el IDE para cada plataforma.

CREAR Y CONFIGURAR PROYECTO

Para configurar nuestro proyecto debemos empezar por crear un nuevo proyecto. Para crear un nuevo proyecto debemos ir a  File ->  New -> C Project. De esta manera nos aparecerá la primera ventana de configuración del proyecto.

En esta ventana (1) vamos a seleccionar un proyecto de tipo Executable y Ac6 STM32 MCY Project y con el toolchain Ac6 STM32 MCU GCC.

A continuación nos aparecerá la ventana (2) que nos permite seleccionar configuraciones, indicaremos que usaremos ambas configuraciones, Debug y Release.




La siguiente ventana nos va a solicitar indicar el microcontrolador que vamos a querer usar, en nuestro caso vamos a seleccionar  STM32F103C8Tx.

Primero debemos seleccionar la pestaña de Mcu, esta pestaña nos permite buscar directamente por modelos de microcontroladores STM32. Boards nos permite encontrar las diferentes placas que existen en el mercado con STM32.

Podemos usar varios filtros como escribir directamente el nombre del microcontrolador o filtrar por serie. De ambas maneras podemos lograr encontrar en microcontrolador que estamos usando.

A continuación es muy importante darle al botón de Next y no a finalizar. Si finalizamos en este paso no podremos terminar de configurar adecuadamente.


El siguiente paso nos permite configurar las bibliotecas necesarias para poder programar el microcontrolador.

Debemos seleccionar la opción de Standard Peripherial Library  (StdPeriph). Esta biblioteca es el fichero de tipo header stm32f10x.h, el cual contiene numerosos métodos definiciones de variables útiles a la hora de programar. 

Por último en caso de que no tengamos descargada la biblioteca nos aparecerá el botón de Download target firmaware en verde, una vez descargado el propio proyecto encintará los ficheros necesarios. 
Por lo general esta acción solo se realiza una vez por cada tipo de microcontrolador concretos que fuéramos a programar. Una vez realizado este paso, no necesitaríamos conexión a Internet para poder crear un proyecto nuevo.

Ahora el proyecto aparecerá en el Project Explorer, generalmente situado a la izquierda. Dentro del proyecto podemos encontrar la carpeta src y dentro el fichero main.c.

Configuración de Run y Debug

Para poder cargar nuestro código debemos realizar unas últimas configuraciones, en este caso tratan la manera en al que el código se carga en el microcontrolador.

Primero vamos a crear los ficheros necesarios para poder configurar estas opciones. Para crearlos simplemente pulsamos en el icono de Run o Debug.



Ahora si podemos acceder a la configuración de para cargar le código. Para acceder a estas configuraciones  debemos desplegar el menú de Debug o Run, cualquiera de ellos no van a llevar al mismo dialogo.


Podemos crear diferentes configuraciones para un proyecto y podremos ver todas las configuraciones de los proyectos. Podemos darle el nombre que queramos a cada configuración. Esto no es útil en caso de cargar el proyecto para diferentes microcontroladores que dispongan de configuraciones diferentes o vayamos a usar diferentes métodos de carga.


A continuación debemos acceder a la pestaña debugger. En ella debemos realizar varios cambios, primero debemos desplegar la opciones del generador, para ello presionamos en Show generator options. Al abrir esta opción debemos modificar el Reset Mode y seleccionar Software system Reset.
A continuación debemos marcar la opción de Shareable ST-Link. Como se puede ver al accionar esta opción automáticamente podemos ver si tenemos la placa o el microcontrolador conectado y comprobar si las conexiones son correctas.



Una vez que tengamos nuestra placa conectada podemos usar el botón de refres y automáticamente aparecerá nuestra placa.
Además tenemos la posibilidad de cambiarle el nombre para poder identificarla con otras y también podemos hacer parpadear el LED del programador ST-Link, de esta manera es mas fácil identificarlos microcontroladores

Ahora nos desplazamos a la pestaña Startup, en ella simplemente debemos desmarcar las opciones de Reset and Delay y Halt.


En este punto ya podemos subir y probar nuestro código. Para ello primero debemos tener conectado nuestro Blue Pill STM32F103 a través del ST-LinkV2 que disponemos. Aconsejo iniciar el programa siempre en modo debug, de esta manera podemos controlar mejor lo que pasa al cargar el código y podremos visualizar errores o advertencias en caso de que los hubiera.

Al accionar el debug entramos en la vista debug, si todo está correcto no recibiremos ningún error y el código estará ya cargado. Es posible que tengamos que accionar el play que se encuentra arriba a la izquierda en verde para que el código corra en modo debug. Debemos tener en cuenta que el código se carga desde un principio en el microcontrolador.

Podemos probar un primer código muy sencillo:
_________________________________________________________________
#include "stm32f10x.h"
void delay(long cycles);
void GPIOC_Init(void);
void led_blink(void);

int main(void)
{
GPIOC_Init();

while(1){

led_blink();
delay(500);
}
}

/***************************************************
 * Initialize GPIOC and pin13 as PP y max speed V1
 ***************************************************/
void GPIOC_Init(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; //iniciamos el reloj para los pines del puerto C
GPIOC->CRH |= GPIO_CRH_MODE13; // en el pin 13 ponemos CNF 00 (General purpose push-pull)
   // y tambien Output mode, max speed 50MHz
}

/*******************************************
 * Blink led_blink macro
 *******************************************/
void led_blink(void){

//clear pin set to 0
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
//reset 0010 0000 0000 0000 |set 0000 0000 0000 0000
delay(2000000);

       //set pin to 1
GPIO_SetBits(GPIOC, GPIO_Pin_13);
//reset 0000 0000 0000 0000 |set 0010 0000 0000 0000
delay(2000000);

}

/*******************************************
 * Delay
 *******************************************/
void delay (long cycles){
while (cycles > 0)
cycles--;
}
_________________________________________________________________

Cuando el código está en marcha tenemos varias vistas interesantes en el modo debug, aconsejo añadir algún breakpoints en el código y así podemos observar el valor de variables y registros de memoria en tiempo real.



Para cualquier duda escribir un comentario, si hay dudas iré modificando el tutorial para fortalecerlo con la información requerida.




Programing Challenge 2 - Ordenar puntos en espacio tridimensional, Clase (Python)


En esta entrega de Programming Challenge vamos a evolucionar el código que habíamos creado para ordenar puntos en espacio tridimensional.
Para ello vamos a introducirnos a las clases y objetos en Python. De igual manera que otros lenguajes de programción podemos crear clases, que a groso modo son contenedores de información y además podemos crear funciones de la clases que nos permiten manejar esa información.

Para poder usar estos contenedores de información instanciamos, creamos, objetos. Estos objetos tienen las características específicas de la clase a la que pertenezcan.


Para este Challenge he creado una clase punto que simplemente es capaz de almacenar las tres coordenadas de un punto. Este método tiene un def que podríamos compararlo con el constructor de cualquier lenguaje orientado a objetos, el método def __init__(), se ejecutará al instanciar un objeto.
____________________________________________
class Point

    def __init__(self, xc=0, yc=0, zc=0):
        self.xc = xc
        self.yc = yc
        self.zc = zc

    def setXc(xc):
        self.xc = xc
    
    def setYc(yc):
        self.yc = yc
        
    def setZc(zc):
        self.zc = zc
        
    def getXc(self):
        return self.xc
    
    def getYc(self):
        return self.yc
        
    def getZc(self):
        return self.zc
________________________________

Además hemos añadidos los métodos get y set para poder interactuar con estas variables. El código anterior está situado en un fichero a parte de python llamado Poitn.py. De esta manera desde cualquier otro script de python. Para poder acceder a esta clase debeos importar la biblioteca.

from Point import Point

Podemos situar múltiples clases en un fichero, de esta manera podríamos tener un fichero con un conjunto de clases relacionadas, por ejemplo un fichero Geometrics e importar múltiples clases de el.

from Geometrics import Point
from Geometrics import Line
from Geometrics import Cube
from Geometrics import Cone
...

Lo mas complejo de las clases que se diferencia de otro lenguajes es el uso del self esta palabra la utilizamos para referirnos al propio objeto instanciado de la clase. Si no usáramos esta referencia de no podríamos referirnos al propio objeto de la clase.

El resto del código es muy similar a la anterior entrega del programming challenge. Podemos ver que en el momento de crear los puntos random creamos objetos de la clase Point. El resto se basa en utilizar los métodos get de la clase para calcular la distancia al origen.

Todos los ficheros .py usados en los challenges los podéis encontrar en mi GitHub (https://github.com/KarlVaello/python-programming-challenges)
___________________________________________________________
from random import randint
import math
from Point import Point

# def that sort an array of points (bubble algorithm)
def bubbleSort(alist):
    n = len(alist)
    for i in range(len(alist)-1):
        swp = False
        for j in range(len(alist)-1):
            if (alist[j][2] > alist[j+1][2]):
                tempPoint =  alist[j]
                alist[j] = alist[j+1]
                alist[j+1] = tempPoint
                swp = True

        if (swp == False):
            break

nPoint = 9 # numer of points
points = [] # points array

pointRange = 90 #aleatory range

# loop to create new random points
for x in range (nPoint):
    newPointObjet = Point(randint(-pointRange,pointRange),randint(-pointRange,pointRange),randint(-pointRange,pointRange))
    newPoint = [x+1, newPointObjet]
    points.append(newPoint)

# loop to print element on creation order
print("Element on creation order [x,y,z]")
for i in range(nPoint):
    print("(" + str(points[i][0]) + ",[" + str(points[i][1].getXc())+ ", " + str(points[i][1].getYc())+ ", " + str(points[i][1].getZc()) + "])")
    
print()
# loop to calculate distance to [0, 0, 0] of each point
for e in range (nPoint):
    d = math.sqrt(((points[e][1].getXc()-0)**2)+((points[e][1].getYc()-0)**2)+((points[e][1].getYc()-0)**2))
    points[e].append(d)
   
# loop to print element on creation order and distance to [0, 0, 0]
print("Element on creation order ( n [x,y,z] / DistanceTo0,0,0]")
for i in range(nPoint):
    print("(" + str(points[i][0]) + ",[" + str(points[i][1].getXc())+ ", " + str(points[i][1].getYc())+ ", " + str(points[i][1].getZc()) + "], " + str(points[i][2]) +  ")")
    
# bubble sort algorithm 
bubbleSort(points)

print()
# print elements in order
print("Elements ordered by distance")
for i in range(nPoint):
    print("(" + str(points[i][0]) + ",[" + str(points[i][1].getXc())+ ", " + str(points[i][1].getYc())+ ", " + str(points[i][1].getZc()) + "], " + str(points[i][2]) +  ")")
   
___________________________________________________________



   
   
  





Programing Challenge 1 - Ordenar puntos en espacio tridimensional (Python)

Este es un ejercicio básico de introducción al Programing Challenge. El objetivo de estos ejemplos o ejercicios no es explicar la base de la programación si no, aplicar los conocimientos ya conocidos y aplicarlos con el lenguaje de programación Python.

En este caso uso estos ejercicios para aprender Python pero pueden ser realizados con cualquier lenguaje de programación. Aunque si que se explicaran ciertos temas que pueden ser de interés como algoritmos y formas de plantear los problemas.
Y por último aclarar que en el mundo de la programación existen diferentes vías de llegar a un mismo resultado. 

Ordenar puntos en espacio tridimensional

En este caso se desea ordenar una cantidad de puntos dispersos en el espacio. Estos puntos se crean de manera aleatoria. El criterio que seguimos para ordenarlos es a razón de la distancia a la que se encuentre del origen de coordenadas. Para ordenar estos puntos usaremos el algoritmo de la burbuja (Bubble sort)

Resumen de objetivos:

* Crear puntos aleatorios es un espacio tridimensional.
* Calcular la distancia de los puntos al origen de coordenadas [0, 0, 0].
* Ordenar puntos a razón de distancia utilizando el algoritmo de la burbuja.

Puntos Aleatorios

Para crear puntos aleatorios haremos uso de la función randint(int low, int high), esta función devuelve valores enteros en un rango de low (incluido) a high (excluido). Para poder utilizar esta función debemos importar la biblioteca random:

from random import randint

A esta función le pasaremos un parámetro pointRange anteriormente definido este parámetro define el rango de valores que la función random creará.

for x in range (nPoint):
    newPoint=[x+1,randint(-pointRange,pointRange),randint(-pointRange,pointRange),randint( pointRange,pointRange)]  
    points.append(newPoint)

Calcular distancia al origen

El cálculo se hace a través de la formula de la distancia entre puntos, aplicando su forma de 3 coordenadas. Asignando uno de los puntos el (0, 0, 0) y otro el punto aleatorio creado anteriormente.

Como podemos observar en la fórmula necesitamos realizar operaciones matemáticas sencillas. Sin embargo la raíz cuadrada no se contempla como operación matemática básica y para poder operar con ella debemos importar la biblioteca math.

import math

Esta biblioteca nos permitirá utilizar la función sqrt() para realizar la raíz cuadrada.

for e in range (nPoint):
    d = math.sqrt(((points[e][1]-0)**2)+((points[e][2]-0)**2)+((points[e][3]-0)**2))

    points[e].append(d)

Nota: ** nos permite indicar el exponencial, 'x**2' equivale a 'x^2'.

Está distancia la añadiremos a nuestro array en su correspondiente slot y de esta manera estaremos almacenado el orden de creación, las tres coordenadas del punto y su distancia al origen de coordenadas.

Ordenar puntos

Por último, nos queda ordenar los puntos, de menor a mayor. Para ello vamos a utilizar el algoritmo de la burbuja (bubble sort), aunque podríamos utilizar el algoritmo de ordenación que quisiéramos. Para ello vamos a crear un función o mejor dicho definición (mas acorde a la terminología que utiliza Python).

El algoritmo de la burbuja es uno de los algoritmos más sencillo de entender y de los mas básicos, bubble sort se basa en recorrer un array o lista comparando valores de dos en dos, en caso de que no estén ordenados, que es cuando p(x) > p(x+1), los intercambiara y volverá a recorrer desde el principio el array o la lista, de esta manera se da un momento que un uno de los ciclos de esta iteración no se produzca ningún intercambio, en ese momento sabremos que nuestro valores están ordenados.


def bubbleSort(alist):
    n = len(alist)
    for i in range(len(alist)-1):
        swp = False
        for j in range(len(alist)-1):
            if (alist[j][4] > alist[j+1][4]):
                tempPoint =  alist[j]
                alist[j] = alist[j+1]
                alist[j+1] = tempPoint
                swp = True

        if (swp == False):
            break


En el siguiente Programing Challenge nos metemos en materia de clases y objetos y realizaremos este mismo ejercicio pero mejorando el código y reordenandolo.

Todos los ficheros .py usados en los challenges los podéis encontrar en mi GitHub (https://github.com/KarlVaello/python-programming-challenges)

Este es el código completo de este Programing Challenge.
_________________________________________________________________________

from random import randint
import math

# def that sort an array of points (bubble algorithm)
def bubbleSort(alist):
    n = len(alist)
    for i in range(len(alist)-1):
        swp = False
        for j in range(len(alist)-1):
            if (alist[j][4] > alist[j+1][4]):
                tempPoint =  alist[j]
                alist[j] = alist[j+1]
                alist[j+1] = tempPoint
                swp = True

        if (swp == False):
            break

nPoint = 9 # numer of points
points = [] # points array

pointRange = 90 #aleatory range

# loop to create new random points
for x in range (nPoint):
   newPoint=[x+1,randint(-pointRange,pointRange),randint(-pointRange,pointRange),randint(-pointRange,pointRange)]  
    points.append(newPoint)

# loop to print element on creation order
print("Element on creation order [x,y,z]")
for i in range(nPoint):
    print(points[i])
    
print()
# loop to calculate distance to [0, 0, 0] of each point
print("Element on creation order [x,y,z, DistanceTo0,0,0]")
for e in range (nPoint):
    d = math.sqrt(((points[e][1]-0)**2)+((points[e][2]-0)**2)+((points[e][3]-0)**2))
    points[e].append(d)
    
# loop to print element on creation order and distance to [0, 0, 0]
for i in range(nPoint):
    print(points[i])
    
# bubble sort algorithm
bubbleSort(points)

print()
# print elements in order
print("Elements ordered by distance")
for i in range(nPoint):
    print(points[i])

_________________________________________________________________________

Protección de circuitos - Polaridad inversa

Los circuitos electrónicos necesitan electricidad para funcionar. Esta electricidad proviene generalmente de fuentes externas las cuales tienen una polaridad concreta, lo que significa que la salida de la fuente tendrá un conector con un polo negativo y otro positivo.

La mayoría de los componentes electrónicos no tienen ningún tipo de protección frente a conexiones diferentes para las que están diseñados, por lo que muchos de estos se dañan. Sin embargo, existen circuitos muy sencillos que permiten proteger los dispositivos de conectarlos erróneamente.

A continuación veremos 3 tipos de circuitos que previenen de alimentar un circuito con polaridad inversa y, por tanto, evitan que los dispositivos se dañen.
  • Diodo en serie
  • Relé
  • MOSFET

Protección con diodo en serie

En el primer tipo de circuito utilizamos un diodo que solo permite circular la corriente en un único sentido. Es el más simple y el más barato, sin embargo debemos tener en cuenta ciertas limitaciones.

Dependiendo del modelo el diodo nos presenta, en polaridad directa, una caída de tensión entre 0.7 V y 1 V, por lo tanto con circuitos de baja tensión puede suponer grandes pérdidas o incluso que nuestros dispositivos no funcionen. Esta tensión se denomina Vth.

La otra desventaja es que un diodo es capaz de soportar cierta tensión negativa durante muy poco tiempo, posteriormente este se rompe de manera permanente y habría que sustituirlo por uno nuevo.
Diodo polarizado correctamente (izquierda), y polarizado en inversa (derecha)

Como podemos ver en la simulación, cuando el diodo está polarizado correctamente, a la salida del diodo obtenemos la tensión de la fuente de tensión continua menos 0.7 V.
Por lo tanto: Vout = Vcc - Vth.

Por otro lado, cuando colocamos la fuente al revés se observa como el diodo queda polarizado de manera inversa y, por lo tanto, no deja pasar la corriente. Sin embargo, esto no mantiene la fuente desconectada del circuito y puede causar efectos no deseados sobre el mismo.


Protección con relé
La protección con relé es muy útil cuando queremos tener totalmente separado nuestra protección del circuito que queremos proteger, ya que de ninguna manera la tensión de alimentación en polaridad errónea circulará por el circuito.

Pese a esta ventaja no es la protección más utilizada debido al coste de los relés y el gran tamaño que los mismos ocupan.

Circuito de protección con relé
Lo ideal es conectarlo de tal manera que si se polariza correctamente el relé no tenga que cambiar de posición cada vez que se conecte la alimentación.

Como se observa en la imagen, en caso de conectarse con la polaridad invertida el relé cambia de posición y se enciende un LED indicando que la polaridad es errónea.


MOSFET

Actualmente es el modo de protección más utilizado. Estos dispositivos son pequeños y económicos y, además, pueden soportar grandes tensiones en polaridad inversa.

Para esta aplicación seguiremos el principio y las ecuaciones que vimos sobre MOSFETS.
MOSFET activado (izquierda), MOSFET desactivado (derecha)

Como podemos ver en la ilustración, cuando la fuente se polariza correctamente el MOSFET queda activado y por tanto cierra el circuito en la parte de tierra. No obstante, en el segundo circuito con la fuente invertida se observa como el MOSFET está desactivado y, además, se enciende el LED indicando que la conexión no es correcta.

En este caso, al igual que en el circuito con diodo, el circuito que queremos proteger no queda completamente desconectado cuando se polariza incorrectamente.




Electrónica de potencia - Rectificador media onda monofásico

Primero vamos a definir qué significa el término rectificador en el mundo de la electrónica de potencia. Un rectificador consiste en convertir la corriente alterna en corriente continua, debido a ello en muchos sitio podemos encontrar que se refieren a ellos como conversor CA-CC (AC-DC en inglés) y ese es el objetivo de todos los modelos de rectificador, sin embargo unos lo hacen de mejor o peor manera o como debemos decir en electrónica de potencia, con mayor eficacia.



En el mundo de la electrónica de potencia uno de los circuitos más simples es el rectificador media onda monofásico. Este circuito nos permite entender cómo afecta un dispositivo electrónico a una corriente de tipo alterna y será la base para entender otro tipo de circuitos de rectificación.


Este circuito cuenta con una carga pura resistiva, esto quiere decir que donde nos interesa obtener la rectificación estará basado únicamente por una resistencia. Esta resistencia va a determinar la corriente que circula por nuestro circuito.


Por otro lado encontramos un diodo, el diodo rectificador, colocado en polarización directa y va a ser el encargado de eliminar la parte negativa de la señal alterna. Como sabemos, un diodo solo conduce cuando la tensión  es superior a la tensión de unión, dependiendo del diodo estos valores pueden ir de 0V a 1V.

El resultado gráfico de este circuito es el siguiente.


Como ya habíamos dicho la señal queda recortada en la parte negativa, podemos ver la señal original (rojo) y la señal recortada o de salida (verde).

En estos circuitos podemos realizar varios cálculos. Uno de los mas habituales es calcular la tensión y la corriente en continua que cae en la resistencia de carga

[1]

Donde debemos tener en cuenta que Vmax no es el valor rms de la señal si no el valor pico. Por lo tanto si por ejemplo tenemos 220V de rms vamos a tener una tensión pico de

[2]

Por lo tanto por ejemplo si tenemos una tensión de 220 Vrms podemos calcular la tensión en la resistencia de carga de tal manera que 


Por otro lado podemos calcular la corriente en forma de continua (DC), simplemente utilizamos la ley de ohm.

Por ejemplo si tenemos una resistencia de 10 ohmios podemos calcular directamente la corriente

[3]
Y de la misma manera podemos calcular la resistencia para que pase una cierta corriente, por ejemplo 1.5 amperio.


Otro dato importante es la potencia absorbida por la resistencia (P). Esto se calcula a través de 

[4]
Y podemos calcular Vrms a través de las siguiente ecuaciones

[5]

Es muy importante no confundir el Vrms de la fuente de alterna (Vin) con el Vrms resultante de la rectificación. Por lo tanto, en el mismo ejemplo de antes con una fuente de 220 Vrms y sabiendo que tenemos un Vmax de 311 V podemos calcular Vrms


Y por tanto podríamos calcular la corriente rms con la ley de ohm

[6]

Y de esta manera ya podemos calcular la potencia con la ecuación [4] ,que depende directamente de valor de la resistencia. Por ejemplo si tenemos una resistencia de 10 Kohm











Electrónica de Potencia - MOSFET. Conexiones y uso con Arduino.

Primero vamos a definir qué es un MOSFET. Un MOSFET es un dispositivo electrónico de tres pines semiconductor que se usa generalmente como conmutador de corriente y amplificador de señales.

Este dispositivo tiene una puerta llamada GATE, encargada de controlar el estado del MOSFET. Es un dispositivo controlado por tensión, por lo tanto, aplicando una cierta tensión en GATE, cambiaremos el estado del MOSFET.

Tiene otros dos pines denominados Drain (D) y Source (S).

Existen dos tipos de MOSFET, PNP (Canal P) y NPN (Canal N). 

Proyecto Rotae - Velocímetro y distancia recorrida mostrado en un TFT, sensor Hall y Arduino (Parte 1)

  En proyecto nos marcamos como objetivo crear un velocímetro con diferentes funciones. Queremos que sea capaz de medir la velocidad, registrar un espacio.

  En esta primera parte nos vamos a centrar sobretodo en el funcionamiento del sensor del efecto hall y en mostrarlo por la pantalla.

  En la segunda parte añadiremos varias funciones como, un cronometro y para e iniciar la cuenta de distancia, GPS, etc.


INTRODUCCIÓN



 La idea es muy sencilla, el sensor de efecto hall detecta el giro completo de una de las ruedas, contando el tiempo de vuelta y lo que recorre la rueda tenemos la velocidad.

  Esta velocidad es mostrada al usuario en la pantalla TFT, además en esta pantalla vamos a mostrar la distancia recorrida.