Domótica utilizando RTOS con PIC

Hola Hace un tiempo que estoy realizando una Domotica con un PIC18F46k22 pero hay un problema, cuando entro al menu y otra persona quiere hacer algo no se ejecuta porque no hace varias cosas a la vez porque el programa atiende un menu. Leyendo vi eso del RTOS que no lo conocia, comence hacer todo de nuevo pero no me funciona estoy en el comienzo del programa.
Quiero que me muestre la hora y mientras hace un escaneo de las teclas , pero no realiza ninguna de las dos cosas. Si anulo el #TASK del escaneo de teclas funciona el display pero viceversa no, y el el comienzo si no puedo con estas dos funciones no me quiero imaginar cuando tenga que desarrollar mas, me podrian ayudar con lo de RTOS para tratar de enterderlo bien lo que me llama la atencion que como lo puse me daria como que tendria que funcionar pero bueno no es asi. Estoy programando con CCS recien esta en comienzo esto, seguro con el tiempo van a surgir mas dudas. :confused::cry:
 

Adjuntos

  • maincontrolador_01.zip
    100.6 KB · Visitas: 14
  • proteus_MainControlador_01.zip
    116 KB · Visitas: 10
Y como harías para que te funcione? Como verás es solo un display funcionando y un for-next solo para escanear un puerto que aún no tiene algo de uso solo para hacer andar un contador de otro integrado aún falta la parte compleja. Como hiciste para que te funcione?

 
aaah pues es bien facil imagina que no usas delay en ningun caso

primero que nada debes elegir 1 timer puede ser timer0 o timer1 depende tu gusto.
despues elegir un tiempo de desborde asi bien papita digamos 10us

ahora para hacer funcionar una tarea digamos escrbir en display es mas o menos asi


timer0
{
interrupcion
segundos++

aqui hacemos un incremento para que cada segundo que pase imcremente mi variable llamada segundos
}

void main()
{
while(1)
{
if(segundos >=1)
{
escribimos pantalla
}


aqui escaneamos teclado

}



}
 
Está bien pero no entiendo eso con el RTOS? El RTOS utiliza timer0, vos ahí no estás utilizando eso. El RTOS lo que hace es llamar a una función un tiempo luego ejecuta la otra y así pero no es tan fácil como parece por eso subí los archivos así me muestran. En tu ejemplo no utilizas RTOS

 
Honestamente no se de ese RTOS, pero . . . si por una parte la isntrucción task define el tiempo máximo para la ejecución, y dentro de esta tienes delays que sobrepasan ese tiempo máximo, yo creo que por ahí comenzarás a tener problemas, el como los maneje no tengo idea.
 
En el programa reemplace un For-next que tenía para escanear las teclas con un do-While y funciono.
Pero en realidad si tenés un delay que sobrepasa igual no cede el manejo a otra función o espera a que se termine?

 
Hola dcsalg, lo que pasa es que en el esquema que tienes (simulación que subiste) cuando haces la lectura del teclado seleccionas al 74154 y luego te pones a leer pines del puerto B y estos pines están sin conexión haciendo que tu rutina de lectura de teclado se quede en un bucle infinito y debido a es el rtos nunca toma el control para ejecutar otras tareas.

Si en una tarea rtos introduces un delay_ms(xx); que supere el tiempo máximo de ejecución de la tarea, entonces termina el delay_ms(xx);, termina la tarea y recién sede el control para que otras tareas se ejecuten, una opción para que eso no suceda es utilizar rtos_yield();.
 
Lo del puerto b no importa por ahora si que me funcione el contador 74154 me mostraste con mi programa si te funciona el rtos_yield porque me da error

 
Yo ni tengo Proteus para comentar respecto al circuito, pero si dicen que están sin conexión y el simulador los toma como 0 entonces cuando haces
while(!input(segundo_bit_entrada)) delay_us(50);
Yo creo que sí importa, y mucho por que pasaría a while(1) delay_us(50);

Te doy dos consejos, simulaciones aparte, siempre incluye una imagen del diagrama y el otro es que uses signos de puntuación.
 
Nuyel tiene absoluta razón en la observación que hace.
solo si se conecta el puerto B a un nivel alto el programa corre "normalmente" bueno entre comillas por que en un momento dado el bus I2C falla.

Este un ejemplito sobre rtos y yield
PHP:
/*****************************************************************************/
#include <16F876A.h>
/*****************************************************************************/
#FUSES NOWDT
#FUSES PUT                      //Power Up Timer
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOPROTECT                //Code not protected from reading
/*****************************************************************************/
#use delay(crystal=20000000)
/*****************************************************************************/
#use rtos(timer=1, minor_cycle=100ms)

#task(rate=500ms)
void condador_display();

#task(rate=300ms)
void rotar_leds();

#task(rate=100ms)
void parpadeo_led();
/*****************************************************************************/
void parpadeo_led()
{
   unsigned int8 n;
   output_high(pin_a0);
   rtos_yield();
   output_low(pin_a0);
   for(n=0;n<8;n++,rtos_yield());
}
/*****************************************************************************/
void rotar_leds()
{
   char tabla[]={1,2,4,8,16,32,64,128};
   unsigned int8 index;
   while(true)
   {
      for(index=0;index<8;index++)
      {
         output_c(tabla[index]);
         rtos_yield();
      }
   }
}
/*****************************************************************************/
void condador_display()
{
   unsigned int8 contador;
   while(true)
   {
      for(contador=0;contador<10;contador++)
      {
         output_b(contador);
         rtos_yield();
      }
   }
}
/*****************************************************************************/
void main()
{   
   while(TRUE)
   {
      rtos_run();
   }
}
/*****************************************************************************/
Sin título.jpg
 

Adjuntos

  • ejemplo_yield.rar
    90.1 KB · Visitas: 6
bueno, programar también es un arte y depende del artista, normalmente es mas llevadero trabajar con rtos pero si te llevas mejor con las interrupciones entonces esa es la mejor opción.
 
Voy a modificar todo porque me me meti en algo que no es práctico para instalar si lo termino , si va ser un sistema domotico tendria que ser facil y mediante dos cables de datos me parece y no tirar 64 cables de una central para controlar las llaver de las luces por ejemplo.

Mi intención es una central y varios modulos pero comence mal ya, porque los modulos quiero utilizar un PIC16F88 pero ya asi con el programa en vacio, que s que hago por lo general que es quie hago por lo general antes de programar para ver si coloque bien los fuses y demas y cargarlo a Proteus y me Aparecio este mensaje:
[PIC 16 MEMORY] PC=0x00CE OSCTUNE register is not modelled y otro que dice
[PIC 16 ADC] PC=0x00F0 ADC conversion clock period (2.5e-07 ........


siendo que ni configure aun los ADC es mas nose si los voy a utilizar pero me desconcerto lo de OSCTUNE register.....

a que se debe eso ? por supuesto que ni siquiera funciona el programa. Siendo que en CCS no me dio error al compilar lo basico.

Código:
#include <16F88.h>
#device ADC=10

#FUSES NOWDT
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
//#FUSES WRT                      //Program Memory Write Protected
//#FUSES PROTECT                  //Code protected from reads
//#FUSES MCLR
#FUSES INTRC_IO

//

//---------------------------------------------------------LIBRERIA  sModule v1.h  
#use delay(internal=8MHz)
//#use FIXED_IO( A_outputs=PIN_A1 )
#define EN1   PIN_A6
#define RXEN1   PIN_A7
#define RX1   PIN_B2    //PIN_B0
#define SDA1   PIN_B1
#define TX1   PIN_B5
#define SCL1   PIN_B4


//port1
#define RS485_USE_EXT_INT FALSE  //TRUE
#define RS485_RX_PIN RX1
#define RS485_TX_PIN TX1
#define RS485_ENABLE_PIN RXEN1
#define RS485_RX_ENABLE EN1
#define RS485_RX_BUFFER_SIZE 5
#define RS485_ID 10
#include <rs485.c>//NOTE: only one RS485 port is supported by the driver

#use i2c(Master,Fast,I2C1) //sda=SDA1,scl=SCL1)

//----------------------------------------------------- FIN sModule v1.h ----------------------



#include <sModule v1.h>

#ZERO_RAM

//#include <mcp23017_dcs.c>


void main()
{
 //  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_BIT);      //128 us overflow
  // int a;
  // setup_oscillator(OSC_8MHZ | OSC_INTRC); 
  //// SETUP_ADC_PORTS(NO_ANALOGS);
  // setup_adc(ADC_OFF);
   
  // mcp_init();

  // while(TRUE)
 //  {
  //    a=1;

      //TODO: User Code
  // }

}

eso es lo que escribi y ya aparee ese error en proteus. EL encabezado fuses y demas esta en una libreria sModule v1.h lo otro seria el programa principal , repito yo antes de comenzar a escribir el programa ya con esto crequeo para que me salten los errores, sino seria tedioso escribir todo y ver que me sale esto y perdi tiempo programando
 
Última edición:
Alguien Sabe que sucede en mi ejemplo anterior? adjunto archivos, el programa esta en la carpeta Firmware sModule v1 y hay una carpeta con proteus que es donde esta el circuito porque sucede ese error por favor!. :cry:
 

Adjuntos

  • SMART HOME 001.zip
    277.4 KB · Visitas: 9
Atrás
Arriba