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.

Programando microcontrolador ARM: 6 - Estructura física GPIO y conectar LED para el blink (stm32f103c8)

Esta vez vamos a ver que posibilidades nos dan los pines GPIO y vamos a ver como conectar el LED de los tutoriales anteriores.

Empezando por el principio, vamos a estudiar como están construidos internamente los pines GPIO, centrándonos en el output.
Una salida nos proporciona tres diferentes modos:
  • Push-pull
  • Open-drain
  • Desconectado