Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?
21/04/2012 #1841

Avatar de reyvilla

Bueno aqui dejo un codigo base para un tiempo de 999.96 milisegundos, practicamente 1 segundo, con un error de 4us, creo puede mejorarse , en fin no es muy complicado pero si es necesario conocer mas a fondo los ciclos de maquina para mayor precisión, aparte de tener en cuenta el oscilador a utilizar y que rango del divisor prescaller usar, en mi caso, no necesito tanta precisión pero quise llevarlo un poco mas allá, y logre hasta 999.96ms, para llegar aquí primero coloque al máximo el prescaller osea 256, osea cada 256 ciclos el cuenta 1, como cada ciclo de maquina es de 4 pulsos de reloj, en la formula que encontré del TMR0, es por eso la multiplicación por 4 luego de la división de 1/F, lo que da 1us por cada ciclo de maquina para los microcontroladores pic, eso utilizando un oscilador de 4MHZ, si es de 20MHZ da 0.2us, para poder lograr mas o menos 1 segundo con un margen de error mínimo con 20MHZ, lo que hice fue escoger un valor redondo en mi caso 12800us, utilizando un programa que encontré y anexo,
esos 12800us me dan con un valor de 6 cargado en el registro TMR0, lo que quiere decir que a partir de alli es que empieza a contar,
o lo que es lo mismo le resto a 256 - 6, entonces ahora no desborda al contar de 00 a 256, si no de 06 a 256,
si sacamos cuenta, para ciclos
con duración de 0.2us x 250 = 50us x 256 = 12800us = 12.8ms,
ahora eso no es ni la mitad de un segundo, para llegar a 1 segundo, multiplique cuantas veces fue necesario para llegar lo mas cerca a 1 segundo,
en mi caso elegí 78 que da 12.8ms x 78 = 998.4ms,
elegí ese porque era el mas redondo de los que calcule, ahora tengo una diferencia de 1,6ms, para compensarlo coloque 20us de pausa por cada interrupción
como son 78 entonces 20us x 78 = 1560us = 1.56ms
Y en total tenemos 998.4ms + 1.56 = 999.96ms por cada 78 interrupciones.
Ahora esto es relativo, si sabemos que cada ciclo es de 0.2us, si después de la interrupción, hacemos un procedimiento ya sea de suma o condicional, eso consume ciclos de maquina lo cual debe restarse del tiempo calculado,
digamos que un IF THEN, consume 2 ciclos de maquina,
entonces tendríamos que multiplicar 0.2us x 2 x 78 y nos daría cuanto es el tiempo que tendríamos de diferencia para 1 segundo con esa instrucción y así para cada instrucción que se vaya a realizar en la subrutina de interrupción.

Bueno hasta aquí la pequeña explicación dejo el programa, el código y la simulación para que la prueben, el código esta comentado en ingles para los registros de interrupción y option lo coloque así por que se entiende mejor que al traducirlo.

El programa lo que hace es togglear un led cada segundo bueno cada 999.96ms aproximadamente...Cualquier cosa que me este equivocando me avisan...

PD: El pulsador no tiene ninguna función de momento era para las practicas, en el proteus tienen una opción que esta en la barra de herramientas debug que se llama "Excute For Specified Time", sirve para ejecutar la simulación en un tiempo especificado es milisegundos, para menor tiempo pueden poner 0.500 y es medio segundo.
21/04/2012 #1842

Avatar de reyvilla

Por aca dejo un pequeño código muy interesante, puede controlar hasta 5 interruptores para el control de un led, funciona como los llamados 3 way, que usan dos interruptores para el apagado y encendido de un bombillo, ahora este tiene 5 y cualquiera de los 5 puede cambiar el estado del led, si esta prendido lo apaga y si esta apagado lo enciende, esta echo con un pic12F675 y el código realmente no es código, es mas configuración que código cuando lo vean se daran cuenta que únicamente tiene la instrucción GOTO inicio, y es solo ese loop lo que hace, lo interesante es que se trata de interrupciones por cambio de estado, al cambiar el estado de cualquiera de las entradas cambia el estado del led.

Código:
@ DEVICE PIC12F675
@ DEVICE INTRC_OSC_NOCLKOUT
@ DEVICE WDT_OFF       
@ DEVICE PWRT_OFF
@ DEVICE MCLR_OFF
@ DEVICE BOD_OFF
@ DEVICE PROTECT_OFF
@ DEVICE CPD_OFF 

DEFINE OSCCAL_1K 1
DEFINE OSC 4  

INTCON = %10001000 'INTERRUPCIONES ACTIVADAS
OPTION_REG = %00000000
WPU = %00110110 'TODOS LOS PINES CON PULL-UP MENOS GPIO.0 y GPIO.3
IOC = %00111110 'TODOS LOS PINES COMO INTERRUPCION MENOS GPIO.0 
ANSEL = %00000000 'ADC DESABILITADO 
CMCON = %00000111 'COMPARADOR DESABILITADO 
         
SYMBOL LED = GPIO.0

TRISIO =%00111110 'TODOS COMO ENTRADA MENOS GPIO.0    
GPIO  = %00000000 
    

ON INTERRUPT GOTO SWCHIT 
INTCON = %10001000 

INICIO:

GOTO INICIO

Disable
SWCHIT:
TOGGLE LED 
PAUSE 400
INTCON = %10001000 
Resume
Enabl
Cuando abran el archivo del código pbp, verán que esta full comentado para que vean cual es el truco del código, les dejo la simulación y el codigo...
22/04/2012 #1843


quiciera que me ayudaran con algo:

pretendo programar un micro para controlar la velocidad de motores con un radio control. la cosa es que quiciera hacer un programa de modo que cuando suba el ancho de pulso del receptor, el ancho de pulso que quiero generar en el micro me baje osea, que la funcion sea inversa.
23/04/2012 #1844


Hola amigos, quisiera por favor alguien me ayudara intruyendome un poco sobre el siguiente tema que pongo a su consideracion:
Sucede que estoy por presentar mi proyecto de grado el cual consiste en automatizar mi departamento usando PICs; bueno basicamente lo que hace el PIC es recibir un SMS enviado desde cualquier movil y accionar diferentes cosas en base a reles, en otras palabras el PIC recibe un mensaje y este le manda una señal a un o varios reles y estos proceden abrise o cerrarse; el problema que se me ha presentado esque no puedo independizar los reles, osea si quiero activar el rele dos, primero debo activar el rele uno, porque en el codigo fuente esta primero la linea que contiene al rele uno, entonces quiero saber si hay la posiblidad de saltarme esas lineas de codigo para que no siga el orden logico o bien sea poner condicionantes para que si a determinada accion se active cualquier rele ya sea el uno el dos, el tres, etc.

Adjunto mi codigo fuente que este hecho en Basic, en microcode studio.

Cualquier ayuda m sería de gran utilidad.

Gracias
Archivos Adjuntos
Tipo de Archivo: txt Programa.txt (1,2 KB (Kilobytes), 44 visitas)
23/04/2012 #1845

Avatar de reyvilla

guigo dijo: Ver Mensaje
quiciera que me ayudaran con algo:

pretendo programar un micro para controlar la velocidad de motores con un radio control. la cosa es que quiciera hacer un programa de modo que cuando suba el ancho de pulso del receptor, el ancho de pulso que quiero generar en el micro me baje osea, que la funcion sea inversa.
Hola y que has hecho hasta el momento si tienes algo adelantado colócalo para poder ayudarte.

---------- Actualizado después de 47 minutos ----------

Pull1988 dijo: Ver Mensaje
Hola amigos, quisiera por favor alguien me ayudara intruyendome un poco sobre el siguiente tema que pongo a su consideracion:
Sucede que estoy por presentar mi proyecto de grado el cual consiste en automatizar mi departamento usando PICs; bueno basicamente lo que hace el PIC es recibir un SMS enviado desde cualquier movil y accionar diferentes cosas en base a reles, en otras palabras el PIC recibe un mensaje y este le manda una señal a un o varios reles y estos proceden abrise o cerrarse; el problema que se me ha presentado esque no puedo independizar los reles, osea si quiero activar el rele dos, primero debo activar el rele uno, porque en el codigo fuente esta primero la linea que contiene al rele uno, entonces quiero saber si hay la posiblidad de saltarme esas lineas de codigo para que no siga el orden logico o bien sea poner condicionantes para que si a determinada accion se active cualquier rele ya sea el uno el dos, el tres, etc.

Adjunto mi codigo fuente que este hecho en Basic, en microcode studio.

Cualquier ayuda m sería de gran utilidad.

Gracias
Hola vi tu código y según entiendo, el espera a que llegue 1 de 3 mensajes y según el que llegue primero es la acción a tomar, así que si primero llega "Activar R2", debería activar R2, bueno esa es mi primera teoría, ahora el "WAIT", es para indicarle que debe esperar hasta que llegue una secuencia exacta de caracteres y de ser así entonces se quedaría en la primera linea de serin2, hasta que llegue "Activar R1", ahora como no utilizas un gosub si no goto, las demás nunca van a llegar a funcionar ya que retorna directo a inicio y quedaría siempre en la primera linea.
Ahora para lograr lo que tu quieres una opcion es darle un timeout a la sentencia serin2, de tal manera que si no llega esa en un tiempo determinado la primera cadena de caracteres, siga a la siguiente con una subrutina.

Quedaría algo asi:

Código:
include "modedefs.bas"
define OSC 4
CMCON=7
REL1 VAR PORTA.0
REL2 VAR PORTA.1                   
RX VAR PORTB.0
TX VAR PORTB.1

INICIO:
GOTO RECIBIENDO1

RECIBIENDO1:
SERIN2 TX,16468,100,RECIBIENDO2,[WAIT("Activar R1")]  'espera 100ms y si no llega nada se va a RECIBIENDO2
HIGH REL1
pause 5000
goto ENVIAR
RECIBIENDO2:
SERIN2 TX,16468,100,RECIBIENDO3,[WAIT("Activar R2")] 'espera 100ms y si no llega nada se va a RECIBIENDO3
high rel2
PAUSE 5000
GOto ENVIAR1
RECIBIENDO3:
SERIN2 TX,16468,100,INICIO,[WAIT("Desactivar R1")] 'espera 100ms y si no llega nada se va a INICIO
high rel2
PAUSE 5000
GOto ENVIAR1

GOTO INICIO
end 


ENVIAR:
    PAUSE 10000
    serout2 Rx,16468,["AT+CMGF=1",13]
        PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R1 activado",26]
        pause 50
    goto inicio

ENVIAR1:
    PAUSE 10000
    serout2 Rx,16468,["AT+CMGF=1",13]
       PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R2 activado",26]
        pause 50
    goto inicio

DESCATIVAR:
    PAUSE 10000
    SEROUT2 RX,16468,["AT+CMGF=1",13]
        PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R1 desactivado",26]
        pause 50
    goto inicio
Nota: No lo he probado, por lo que no se si funciona, si tienes un esquema en proteus para probar seria mejor y puede haber muchas otras maneras es solo una idea que se me ocurre ahora.
23/04/2012 #1846


Hola amigo, primero antes de todo quiero darte mil gracias por el tiempo que has empleado en mi problema, en segundo lugar te doy las gracias por la ayuda que me has brindado en la programacion, se me han aclarado bastantes cosas partiendo de tu gran ayuda, tiene mucha logica lo que tu haces y procedere a probarlo ya en la practica y te comentaré como me fue.
Reitero mis agradecimientos para contigo
23/04/2012 #1847


lubeck dijo: Ver Mensaje
nop....

pero mira este manual ahi estan todos los comandos seriales...

http://cmucam.org/wiki/Documentation

en el apartado de applications el que dice CMUcam2 MAnual
Disculpa una pregunta tu cres que con la cmucam 3 pueda tomar una foto y guardarla en una EEprom para verla via ethernet por un Pic conectado a Ethernet
23/04/2012 #1848


Disculpa una pregunta tu cres que con la cmucam 3 pueda tomar una foto y guardarla en una EEprom para verla via ethernet por un Pic conectado a Ethernet
En teoria yo diria que si...

si tienes una memoria lo suficientemente grande para que quepa la foto o si la envias por partes... y claro, si tienes un modulo usart-ethernet...
23/04/2012 #1849


Amigo Reyvilla, acabo de probar el programa en el protoboard, ya esta solucionado en parte el problema, digo en parte porque ahora el problemita q se me esta presentando es que tengo q darle unos 3 a 6 enviar para que se active o desactive algun rele, puesto que como esta ese tiempo de 100 ms y salta a la siguinte subrutina se pone hacer eso en cada serin2 y ahi es donde hay ese retraso, le puse una velocidad de 50 ms y nada y ahora con 10 ms y nada, talves me puedes sugerir algo mas?
23/04/2012 #1850

Avatar de reyvilla

Ok fíjate hay dos maneras, una la que ya te indique, otra que te trato por aqui: Envio de SMS con PBP
que es guardar el mensaje y luego hacer una comparación o condición según el mensaje, el tema que te coloque tiene tiempo sin movimiento, en fin es lo mismo que tu quieres lograr hacer. Tu código tiene como condición de recepción 3 alternativas,se utiliza como flag o bandera, si no se recibe esa bandera no recibe el dato siguiente, el dato verdadero seria el que le sigue. Para Manejar el dato, debido a que los datos son de 8 bits cada uno necesitarías hacer una arreglo de variable para tu mensaje, si el mensaje es "Activar R1", serian 10 datos de 8bits incluyendo el espacio en blanco que también forma parte del mensaje, para un total de 80bits, la variable mas grande es de 16bits que es la word, así que la única manera es utilizando un arreglo de una variable tipo byte, como indica el amigo lubeck en el tema que te coloque, de todas formas voy a ir chequeando a ver si consigo algo aparte y te estoy avisando
23/04/2012 #1851


Ok amigo reyvilla voy a seguir intentandolo si logro algo te aviso, muchas gracias
24/04/2012 #1852


reyvilla dijo: Ver Mensaje
Hola y que has hecho hasta el momento si tienes algo adelantado colócalo para poder ayudarte.

---------- Actualizado después de 47 minutos ----------



Hola vi tu código y según entiendo, el espera a que llegue 1 de 3 mensajes y según el que llegue primero es la acción a tomar, así que si primero llega "Activar R2", debería activar R2, bueno esa es mi primera teoría, ahora el "WAIT", es para indicarle que debe esperar hasta que llegue una secuencia exacta de caracteres y de ser así entonces se quedaría en la primera linea de serin2, hasta que llegue "Activar R1", ahora como no utilizas un gosub si no goto, las demás nunca van a llegar a funcionar ya que retorna directo a inicio y quedaría siempre en la primera linea.
Ahora para lograr lo que tu quieres una opcion es darle un timeout a la sentencia serin2, de tal manera que si no llega esa en un tiempo determinado la primera cadena de caracteres, siga a la siguiente con una subrutina.

Quedaría algo asi:

Código:
include "modedefs.bas"
define OSC 4
CMCON=7
REL1 VAR PORTA.0
REL2 VAR PORTA.1                   
RX VAR PORTB.0
TX VAR PORTB.1

INICIO:
GOTO RECIBIENDO1

RECIBIENDO1:
SERIN2 TX,16468,100,RECIBIENDO2,[WAIT("Activar R1")]  'espera 100ms y si no llega nada se va a RECIBIENDO2
HIGH REL1
pause 5000
goto ENVIAR
RECIBIENDO2:
SERIN2 TX,16468,100,RECIBIENDO3,[WAIT("Activar R2")] 'espera 100ms y si no llega nada se va a RECIBIENDO3
high rel2
PAUSE 5000
GOto ENVIAR1
RECIBIENDO3:
SERIN2 TX,16468,100,INICIO,[WAIT("Desactivar R1")] 'espera 100ms y si no llega nada se va a INICIO
high rel2
PAUSE 5000
GOto ENVIAR1

GOTO INICIO
end 


ENVIAR:
    PAUSE 10000
    serout2 Rx,16468,["AT+CMGF=1",13]
        PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R1 activado",26]
        pause 50
    goto inicio

ENVIAR1:
    PAUSE 10000
    serout2 Rx,16468,["AT+CMGF=1",13]
       PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R2 activado",26]
        pause 50
    goto inicio

DESCATIVAR:
    PAUSE 10000
    SEROUT2 RX,16468,["AT+CMGF=1",13]
        PAUSE 50
    serout2 Rx,16468,["AT+CMGS=",34,"092661649",34,13]
        PAUSE 50
    SEROUT2 Rx,16468,["R1 desactivado",26]
        pause 50
    goto inicio
Nota: No lo he probado, por lo que no se si funciona, si tienes un esquema en proteus para probar seria mejor y puede haber muchas otras maneras es solo una idea que se me ocurre ahora.
mira, creo que la idea es que el mensaje que llegue se direccione a pin estableciendo un valor y tenes que utilizar los condicionales " if - then para que el pic te hubique el pin al cual queres darle salida. asumiendo que ya conoces los comandos AT y la comunicacion serial con pic. cuando el comando llegue al pic debe haber un valor entonces lo que tenes que hacer es si ese valor existe entonces 1 en pin. podes guardar ese valor en una variable y cuando le oredenes al pic que si esa variable es igual al valor contenido en el comando entonces el te direcciona de una.

guigo dijo: Ver Mensaje
quiciera que me ayudaran con algo:

pretendo programar un micro para controlar la velocidad de motores con un radio control. la cosa es que quiciera hacer un programa de modo que cuando suba el ancho de pulso del receptor, el ancho de pulso que quiero generar en el micro me baje osea, que la funcion sea inversa.


solucionado el problema, era el calculo que le habia planteado al pic muchas gracias por la respuesta.
24/04/2012 #1853


Hola amigo, gracias por tu respuesta, sabes justamente eso pensé en un princio porner un IF THEN, es mas ya lo he puesto, pero sin resultados, lo mas seguro esque lo estoy ubicando mal por eso no consigo nada, talves me podrias ayudar partiendo de ese codigo que el amigo reyvilla lo puso a ubicar los IF y la variable?.
Si conozco los comandos AT y la comunicacion serial.

muchas gracias de antemano
24/04/2012 #1854


amigo pull1988...

que telefono estas usando????(me refiero a marca y modelo) curiosidad mia....

y porque no subes la simulacion en proteus??? no tienes?
24/04/2012 #1855

Avatar de reyvilla

Hola lubeck una pregunta, tu conoces los comandos DEBUG Y DEBUGIN del PBP?

Y los as usados?
24/04/2012 #1856


reyvilla dijo: Ver Mensaje
Hola lubeck una pregunta, tu conoces los comandos DEBUG Y DEBUGIN del PBP?

Y los as usados?
nop.. no los he usado y para serte honesto no sabia que existian o mas bien no les habia prestado atencion... pero me suena que se usan en conjunto con algun debugger...

deja leer la ayuda del microcode...
24/04/2012 #1857

Avatar de reyvilla

Fijate de yo pense igual y resulta que son para comunicación serial, mira por aca: http://melabs.com/resources/pbpmanual/
24/04/2012 #1858


parece que si es para algun debugger...
como estos...


por que mira lo que dice...
DEBUG is one of several built-in asynchronous serial functions. It is the smallest of the software generated serial routines. It can be used to send debugging information (variables, program position markers, etc.) to a terminal program like Hyperterm. It can also be used anytime serial output is desired on a fixed pin at a fixed baud rate.
24/04/2012 #1859

Avatar de reyvilla

Si eso vi también que puede ser usado como depurador de código, en el manual que yo tengo en español solo tiene el DEBUG y dice lo siguiente:

DEBUG es una de varias funciones seriales asincronicas pre-construidas .Es la más pequeña de las rutinas
seriales generadas por software .Puede ser usada para enviar información de depuración (variables
,posición de marcadores , etc).a un programa terminal como HyperTerm .También se puede usar cuando
se desee salida serial sobre un pin determinado y con un baud rate determinado .
24/04/2012 #1860


pues le doy un 90% que solo sirve para eso y la verdad a mi no me agradan mucho los debuggers... soy mas de probar y programar, probar y programar... y pues con eso de las simulaciones en proteus que son bastante buenas no me llama la atención buscarle por ese lado de los debuggers...

si me topo con algun dato adicional te echo un grito...
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.