lunes, 31 de octubre de 2011

Guía sobre condicionales parte 2

  En esta ocasión hablaremos de otros dos condicionales que son muy utilizados y en especial permiten realizar cosas bastante útiles durante un programa.

Condicional WHILE
  El condicional WHILE viene a ser una especie de supervisor de campo, si todo fluye bien entonces sigue dirigiendo las ordenes, si algo esta fuera de lo común entonces las interrumpe. Si lo llevamos a la lógica de programación, el WHILE lo que hace es realizar las ordenes asociadas a el mientras la condición o condiciones se cumplan, en el momento en que esas condiciones dejen de ser ciertas entonces interrumpe la ejecución de estas ordenes sin importar en que segmento se encuentren.

 La principal diferencia con el IF es que al contrario de este, el WHILE chequea en tiempo real que las condiciones sean ciertas, solo sigue ejecutando mientras sean ciertas, el IF solo realiza esta comprobación cuando se llega al segmento de código que lo solicita y ejecuta todos los comandos asociados a este sin importar si la o las condiciones siguen siendo ciertas. Muy útil si queremos supervisar múltiples controladores (switches) y realizar acciones en base a su estado actual por ejemplo.


Sintaxis en PIC BASIC

While condiciones
        ordenes
Wend

Sintaxis en C

Do{
       ordenes
}
while(condiciones);


 
  La lógica para las condiciones es la misma que para el IF, puede ser una o mas condiciones (mediante el uso de los OR y AND).

Ejemplos


Supongamos que queremos controlar un set de switches y mostrar en ellos un conteo de acuerdo a lo que se encuentre en ellos.
  Si los switches marcan 00 en binario parpadear el último numero contado, si marcan 01 realizar un conteo ascendente del 1 al 15 y si marcan 11 realizar un conteo descendente del 1 al 15. Se debe interrumpir el conteo y realizar la acción requerida si cambia el estado de los switches, es decir que si se encontraba en 01 y se colocan los switches en 00 deberá parpadear el ultimo conteo que se realizo, si estaba en 00 y luego se pone en 11 deberá empezar a realizar un conteo descendente. 

Esta tabla define que debería de suceder:

Switches
Acción
00
Parpadear ultimo digito contado
01
Conteo ascendente 1 - 15
11
Conteo descendente 15 - 1


Código 

Device 16F877A
Xtal 20
All_Digital true
Output PORTC
Input PORTB
Dim x As Byte
x = 0
Dim y As Byte
y = 15
Dim last As Byte
last = 0

inicio:
If x > 15 Then
    x = 0
    End If

If y < 0 Then
    y = 15
    End If

While PORTB = 000011 'chequea el estado del puerto
    PORTC = y
    DelayMS 1000
    last = y
    y = y - 1
Wend

While PORTB = 000001 'chequea el estado del puerto
    PORTC = x
    DelayMS 1000
    last = x
    Inc x 'incrementa en 1 la variable x
Wend

While PORTB = 000000 'chequea el estado del puerto
    PORTC = last
    DelayMS 250
    Low PORTC
    DelayMS 250
    PORTC = last
Wend
GoTo inicio
End    


 En C basta con seguir la sintaxis que les escribí previamente y colocar las ordenes dentro de las llaves. 

como por ejemplo:

Do{
    x = x+1;
    y = y +1;
}
While(y<100);

  En el caso anterior va a seguir incrementando "x" una y otra vez mientras "y" sea menor que 1, en el preciso momento en que y deje de ser menor que uno interrumpe la ejecución. 

Condicional FOR

    Este condicional es muy útil para realizar contadores, el condicional FOR lo que hace es realizar un numero X de veces la sucesión de ordenes que se tienen. Ese numero de veces dependerá de una variable de control que realiza el conteo y que puede ser modificada incluso dentro de las ordenes (esta variable debe existir para poder utilizar el FOR y debe ser de tipo entero). Utilizado para leer arreglos en sucesión en C, o sencillamente para realizar un conteo o un chequeo de algo un numero de veces dado. 


Sintaxis en PIC BASIC
For variable = inicio To variable = final Step numero_de pasos
     Ordenes
Next


  Recuerden que deben inicializar una variable para el conteo, inicio representa desde donde, final hasta donde y pasos representa de cuanto en cuanto se debe contar. 

 Programa simple para realizar un conteo con LEDs del 1 al 15. 

Device = 16F877A
Xtal 20
All_Digital true
Output PORTC
Dim x As Byte 'variable que utilizare para el conteo
inicio:
For x = 0 To x = 15 Step 1 'x desde 0 hasta el 15 de uno en uno, 0, 1, 2, 3... etc
    PORTC = x 'le digo que tome el valor de x
    DelayMS 500
Next
GoTo inicio
End


  Noten que no le digo que incremente de 1 en 1 la variable x, esto es porque el For lo realiza de forma automática, si quisiera por ejemplo que el conteo fuera de 3 en 3 bastaría con colocar un 3 en lugar de 1 al lado del Step. Si se quisiera un conteo descentende entonces bastaria con colocarle un menos (-) al lado del numero del Step y logicamente iniciarlizar la variable en la parte mas alta y finalizarla en la parte mas baja.

For x = 15 To x = 0 Step -1 <- Realiza un conteo descendente de 1 en 1 desde el 15 hasta el 0. 

La primera vez x vale 0 y se muestra un 0 en binario en el puerto C, se le suma 1 y entonces se muestra un uno binario en el puerto C, asi seguira hasta el 15 donde terminara el conteo y terminara el ciclo. 

Sintaxis en C
For(var=inicio;var=final;var++){               
         Ordenes
}

 Mismas consideraciones, se debe inicializar la variable primero y si se desea un conteo descendente basta con colocar dos signos menos al lado de la variable (--), suponiendo que la variable fuera Z por ejemplo, un conteo ascendente hasta el 100 desde el 20 seria:

For(Z=20;Z=100;Z++){
   Ordenes
}

Un conteo descendente seria:

For(Z=100;Z=20;Z--){
   Ordenes
}

 Espero que esto les sirva para aclarar dudas. 

viernes, 28 de octubre de 2011

Guía sobre los condicionales en C y PIC BASIC Primera Parte

  Tanto en C como en PIC BASIC (así como en cualquier lenguaje de programación que sea digno de utilizar) existen los denominados condicionales, un condicional es una sentencia de órdenes que se cumple si y solo si la o las condiciones son validas para el momento en que se llama.
Comenzaremos por el más “simple” de todos el IF

  IF en ingles significa SI, lo que hace este condicional es verificar la(s) condición(es) y realizar acciones en base a estas. El IF por norma general se acompaña de un ELSE que significa SINO o un (o unos) ELSE IF que significan SINO SI. La principal limitación del IF es que este solo verifica el cumplimiento de la condición(es) una vez y luego procede a realizar las ordenes, por lo tanto no es tan práctico para realizar chequeos continuos sobre condiciones que se prestan a cambiar en el transcurso del programa, como ciclos o contadores por ejemplo.

Sintaxis en PIC BASIC
If Condicion o condicionesThen  
  Ordenes
ElseIfCondicionesThen
   Ordenes
Else
  Ordenes
End If   

Los Elseif y Else con completamente situacionales, es decir no son necesario salvo que deseen agregar más acciones acorde al cumplimiento o no de las condiciones.  Recordar que se pueden utilizar más de una condición para ello se hace uso de los OR y los AND, el primero la condición se cumple cuando alguno de los estados es cierto, sin importar los demás, en el segundo la condición se cumple solo cuando todos los estados condicionales son ciertos.
Ejemplos
                Supongamos que tenemos una variable X y otra Variable Y, queremos incrementar en función de los valores de X, si X vale 4 entonces que Y valga 20, si X vale otra cosa entonces que Y valga 50.
                Ahora supongamos que tenemos el mismo caso anterior pero queremos que Y valga 50 si X < 4 y 100 si X > 4.


Código 1
If X = 4 then
                Y = 20
Else
                Y = 50
End If
Observen lo que sucede, SI X = 4 entonces Y valdra 20, Caso contrario (ELSE) Y valdra 50, justo como queríamos.
Código 2
If X = 4 then
                Y = 20
ElseIf X < 4 then
                Y = 50
ElseIf X > 4 then
                Y = 100
End if   
 En este caso sucede lo siguiente, verifica Si X = 4, si lo es Y entonces valdrá 20, sino pasa a la siguiente verificación, ¿es X menor que 4? Si es así, Y valdrá 50 y luego pasa a la siguiente verificación ¿es X mayor que 4? Si es así Y valdrá 100.

Supongamos que ahora además de esas variables tenemos una tercera que llamaremos Z, si X y  Z valen 4 entonces queremos que Y valga 500.

Código 3
If X = 4 AND Z = 4 then
                Y = 500
End If
Noten que todos los IF deben terminar con su correspondiente End If, pueden incluso utilizar otros If dentro de uno superior (anidarlos) pero por cada secuencia If que generen deben cerrarla con su End If.

Sintaxis en C
If(condiciones){
Ordenes
Else;
Ordenes
}
Más abajo hay otra entrada donde se explica con un ejemplo este sistema en C, solo deben descargar el .rar que contiene el código fuente, en general funciona igual que en PIC BASIC, solo que noten que las condiciones van encerradas en paréntesis, el Else lleva punto y coma y las ordenes del If empiezan y terminan con llaves. 

jueves, 27 de octubre de 2011

Introducción a los motores Paso a Paso Unipolares. (Stepper Motor en ingles)

 En este caso hablare sobre una herramienta muy utilizada con los PICs, los motores paso a paso unipolares. Estos motores tienen como particularidad que no se mueven totalmente cuando son alimentados, por el contrario ellos dan "pasos".

 Un motor paso a paso consta de 4 bobinas, estas bobinas deben energizarse en un orden definido para que funcione el motor, la sucesión de encendido y apagado de estas bobinas permite realizar "pasos" o "semi-pasos". Normalmente cada paso de una bobina de esta realiza un giro cuyo valor se encuentra entre 7º - 10º, un semi-paso entonces vendría siendo la mitad de esto.
En la imagen se pueden observar las bobinas, el engranaje gira a medida que se encienden en sucesión

 ¿Como se activan estas bobinas? sencillo, en el empaquetado de este motor que trabaja con corriente continua, encontraran por lo general 6 cables de diferentes colores. Esto se puede dividir en 2 segmentos de 3 cables cada uno, 2 para las bobinas y uno para el punto común a VCC o Tierra (GND) según sea como se activen.

 Por norma general al trabajar con un PIC conviene tener un motor paso a paso cuyo punto en común sea VCC, de esta forma cada bobina se activaría con un cero lógico en la salida del PIC, la razón radica en que si queremos mover cargas muy grandes con el motor necesitaríamos uno con mayor torque lo que usualmente implica mayor consumo de corriente, corriente que un PIC normalmente no puede entregar. En cambio al activarse con un 0 nos garantizamos que el PIC sirva solo como controlador del dispositivo y la alimentación se la dejamos a la fuente.

 Debemos probar del motor la sucesión de bobinas con su punto en común para saber en que orden debemos energizarlas. Para ello basta con conectar los cables comunes a VCC (usualmente son el Rojo y el Negro) e ir probando los otros cables conectándolos a Tierra, así sabremos en que orden se activan para realizar el movimiento. Realizamos una tabla con esta sucesión para poder utilizarla como referencia. Análogamente si el punto en común es Tierra, realizamos lo mismo pero conectando entonces los otros cables a VCC.

 Puntos a tomar en cuenta:

  • Usualmente 1 paso completo incluye energizar 2 bobinas a la vez y un medio paso seria energizar una sola, como norma un paso posee mucho mas torque que un medio paso.
  • Cuidado con la alimentación hay que estar claros de cuanto consumen estos motores cuando se compran hay de varios tipos, 5 V, 12 V, por ejemplo.
  • Considerar que si el punto en común es VCC en nuestro código se debe colocar un "0" para activarlo, si es Tierra se debe colocar un "1" todo haciendo referencia a niveles lógicos de tensión. 
  • Si cada paso es de 10º entonces hay que realizar los cálculos necesarios para saber cuantos hay que dar para una vuelta completa (360º) serian entonces 36, lo mismo es para cualquier otro angulo que deseemos. 
  • Los retrasos entre paso y paso deben ser tomados en cuenta y no deben ser muy pequeños, de lo contrario el motor puede no funcionar adecuadamente, si la frecuencia excede los 600 Hz tiende a suceder esto. Corregir esto con pausas entre paso y paso de X cantidad de ms. 
Ejemplo de control de medio paso en Basic:

giro_motor:

PORTC.0 = 1
PORTC.1 = 0
PORTC.2 = 1
PORTC.3 = 1
DelayMS 150
PORTC.0 = 1
PORTC.1 = 1
PORTC.2 = 0
PORTC.3 = 1
DelayMS 150
PORTC.0 = 1
PORTC.1 = 1
PORTC.2 = 1
PORTC.3 = 0
DelayMS 150
PORTC.0 = 0
PORTC.1 = 1
PORTC.2 = 1
PORTC.3 = 1
DelayMS 150 <- los retrasos de los que les hable antes. 

return

 Noten como coloco en 0 un puerto tras otro en orden para activar el motor dejando los otros en 1 para que no circule corriente por ellos. Es un ejemplo básico, en la practica se puede modificar mucho o simplificar (con corrimientos de Bit por ejemplo) 

Rudimentaria la info pero creo que sirve como introducción. 

 

Consejos para diseño de software

 En esta ocasión les voy a dar algunos consejos sobre el diseño de algoritmos basado en mi experiencia como programador "newbie". La principal razón de que no se logre entender como resolver un problema en programación radica en el hecho de que aun no tienen la "mentalidad de programador" por así decirlo. Espero que con estos tips/consejos puedan mejorar.

 Primeramente, deben pensar en forma esquematizada. Este esquema esta predefinido en un orden que yo denomino O.P.H.A (Objetivo(s), Procesos, Herramientas, Acción). Es una definición propia que decidí tomar cuando comencé a aprender programación por mi cuenta. A pesar de lo enrevesado que pueda parecer es muy sencillo.

Objetivo(s): definido como el cometido de nuestro programa, es la razón de porque lo creamos. Comienza con una idea y termina con un sistema totalmente funcional. Cabe acotar que también pueden existir objetivos propios internos del programa mas allá del resultado que queremos de este, por ejemplo podemos tener un objetivo central y objetivos secundarios para llegar al primero.
Procesos: los pasos inherentes y básicos (en orden jerárquico) a seguir para llegar a la solución del problema. En otras palabras, tu, como ser humano ¿qué realizarias para lograr llegar al objetivo?
Herramientas: selección de palabras claves, código, lenguaje a utilizar.
Acción: montaje y prueba del software (corrida en frió se incluye aquí).

  Cabe acotar que todos estos procesos son retroalimentados, por cada etapa usualmente se darán cuenta que pueden mejorar la anterior, por ejemplo en el desarrollo de mis procesos entonces puede que encuentre una idea para mejorar mi objetivo, ampliarlo, durante la selección de herramientas puedo encontrar formas mas eficaces de realizar los procesos. Pensar como programador no es ser un sabio del lenguaje y conocer cada lenguaje existente en el mundo, no, es saber llevar un orden de ideas, todo lo demás es carpintería.

  Ejemplo practico de este método
Supongamos que queremos realizar un programa que promedie una serie de números. Aquí ya tenemos definido nuestro objetivo (en este caso solo uno).

 Partiendo de esto, nuestros procesos serian los siguientes:

  1. Definir la cantidad de números a promediar, si es definido por el usuario esto conlleva un sub-proceso que es -> Solicitar al usuario la cantidad de números a promediar. 
  2. Ingresar datos, es decir, solicitar al usuario el ingreso de los números que desea promediar. 
  3. Punto de quiebre, aqui podríamos realizar dos posibles acciones a) Sumamos en tiempo real los números a medida que se introducen o b) almacenamos los números para procesarlos luego.
  4. Opcional, sumar los números almacenados. 
  5. Promediar, esto es tomar la suma total y dividirla entre la cantidad de números introducidos.
  6. Mostrar resultado al usuario. 
 En esta primera parte es un acercamiento bastante simple a lo que se podría hacer para llegar a nuestro objetivo, como pueden ver se presta a modificaciones tan simples como definir de serie una cantidad determinada de números a promediar como a cambiar esta cantidad en función de los deseos del usuario, también podriamos decidir entre almacenar numero a numero cada uno o no, para futuras referencias. Queda a discreción del programador adaptar estos procesos a sus gustos, formas de pensar y necesidad propias del programa. 


 Durante esta etapa lo común es representar los procesos en orden de ideas ya sea en listas como la anterior como diagramas de flujo o pseudo código. Nuevamente esto depende ya de los deseos de quien esta programando.

 Ahora pasamos a las herramientas, dependerán de en que lenguaje estamos trabajando, en nuestro caso me enfocare en C, sin embargo esta etapa se admite para cualquier otro lenguaje, lo que cambiaría seria la sintaxis (forma de escribir los comandos). La lógica nos ayudara mucho en esto conociendo que la base para cualquier programa radica única y exclusivamente en dos fundamentos:


  • Variables: o lugares en memoria donde se almacenan datos que pueden cambiar en tiempo real a medida que el código se ejecuta y en función de estímulos externos (como el usuario, un sensor, etc).
  • Condicionales: la programación no seria lo que es sin la aparición de esto, un condicional es algo (una acción o serie de acciones) que depende de que se cumpla o no un suceso. En programación estos son los tan famosos If, While, Do, Repeat, For, etc, que aparecen en cualquier lenguaje que sea minimamente útil. 
 En la selección de herramientas entonces primeramente definimos el numero de variables a utilizar y luego adaptamos nuestros procesos en función de la sintaxis del lenguaje a utilizar. Sea un condiciona, imprimir en pantalla, etc. Desglosar los procesos en comandos es algo que puede llevar mucho tiempo y dependerá de dos cosas imaginación y conocimiento de que es lo que hace cada comando. Por eso como consejo diría que se deben ir buscando leer los comandos en C (en este caso, substituir C por el lenguaje a utilizar como BASIC por ejemplo). En internet hay mucha documentación al respecto muy útil. 

Código en C: 

//Programa que promedia N cantidad de numeros
#include
main(){
int N,ciclo; //Definir las variables donde guardare los datos que necesito
float numeros,resultado=0;
printf("introduzca la cantidad de numeros a promediar: ");scanf("%d",&N); //solicitar y almacenar el numero de digitos
for(ciclo=1;ciclo<=N;ciclo++){ // aqui comienza el proceso de sumado
     printf("\n introduzca cifra numero: %d  ",ciclo);scanf("%f",&numeros);
     resultado=resultado+numeros;
                    }
resultado = resultado/N; //promediacion 
printf("\n su promedio es: %.2f ",resultado); //mostrar el resultado al usuario.
getch();
}
    
 
 El segmento de Acción se reducir a correr el programa y corregirlo en busca de errores y/o optimización-mejora. Para esto basta con correrlo en frió.

Corrida en frió: teniendo ya la secuencia de lo que se hará, sencillamente realicen paso a paso esta secuencia dando valores arbitrarios y posiciones a sus variables (con lápiz y papel), si al llegar al final del programa consiguen el resultado esperado, entonces el código esta bien, si por el contrario no es así, hay un error y les aseguro que lo detectaran rápidamente al hacer esto. Como consejo principal al correr en frió deben es fijarse en todo momento en que sucede con los datos que manejan, si algún dato hace algo extraño verifiquen esa sección de código.

En fin, recapitulando los consejos en si son:

  • Realicen un esquema de lo que harán, empezando por los objetivos.
  • Aprendan que hace cada comando del lenguaje que van a utilizar.
  • Lápiz y papel, no se vayan de una a la pc, primero diseñen todo en una hoja y luego si cuando estén seguros de que eso es lo que quieren, entonces vayan a la PC, esto les servirá de referencia y evitaran perderse. Con diseño me refiero a realizar diagramas de flujo o listas de procesos, no escribir el código. 
  • Después de tener todo escrito, corranlo en frió (nuevamente, lápiz y papel). Si el código es MUY grande, corran en frió cada sección de este antes de proceder a la siguiente. 
 Por ahora esto es todo, espero les sirva. 

nota: por alguna razón el que va al lado del #include, se borra cuando lo edito aquí en blogger, si van a correr este programa recordar agregarlo al código.