CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem with PWM to do all I want using HEX values in EEPROM

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Arkaedus



Joined: 29 Apr 2015
Posts: 2

View user's profile Send private message

Problem with PWM to do all I want using HEX values in EEPROM
PostPosted: Sat Jun 27, 2015 5:38 am     Reply with quote

Hello

First of all, sorry for my English, I am not an English speaker.

I don't know how to do that because i don't know how to work with hex numbers to do the PWMs.

I have four variables in hex on the EEPROM in my PIC18F8722 (I need 3 PWM, can I do it with that PIC??) For each day of the week I have four variables they on a programmer to turn on some lights for an aquarium fish LED lights.

I have those variables, that are written on the PIC EEPROM memory for everyday of the week with the help of the DS1302 dow:

config_hour_init[dow], config_minute_init[dow]
config_hour_end[dow], config:minute_end[dow]

The variables are in HEX and I use a ds1302 to see if the hour and minutes are the same or not that ds1302 to turn on or off the lights and I show the values on a LCD40x4.

Now i want to do two PWM changing the value of those according to the time.

For example I put in the init configuration 12:03 and in the end 13:05

I want that the PWMs changes his value on that time like this:




The two first are for day cycle, warm white LEDs and White LEDS and the time each pwm value change with the variables values.

The another is for night i want that the PWM raises or fall in 1 hour when day cycle is off.

I have the lights turning on or off at the init or end but i need PWM to do that light more brightness or down his brightness.

Sorry i know that is very complicated but i need to know how to do it, because i want to do my LED Light for my aquarium.

If someone can tell me how to do at least one PWM i want to try to do.


Thank to all, and thanks to read and help me Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19545

View user's profile Send private message

PostPosted: Sat Jun 27, 2015 6:00 am     Reply with quote

First, unless you are storing the values into the EEPROM, as text, they _won't_ be 'hex'.

Understand that hex is just a way of representing a number, and the chip actually just stores the number in binary:
Code:


    int8 val;

    val=123;
    val=0x7B;
    val=0b01111011;


All, put exactly the same number into 'val'. It doesn't hold 'hex', or decimal, just the number (which it stores in binary).

Then, 'yes of course' you can do code to behave as you describe. You'll need a timer interrupt, and to ramp the values actually fed to the PWM, from one value to another, based on time.

Yes, your chiup can do three distinct PWM's (actually five). Use the three ECCP outputs, so the code is the same for all three channels (your PIC has two normal PWM's, and three ECCP PWM's - it is simpler to use the three similar channels, than to use one or two of one type, and then the others of the other type.

This is called programming!. What you need to do, is approach the tasks one by one. First verify you can store and retrieve the numbers required. Then prove you can control the three PWM's and adjust the values as required. Then work out the maths of the ramping, and starting on one channel, and ramping much faster than really required verify you can do the smooth changes required. Then put it together....
Arkaedus



Joined: 29 Apr 2015
Posts: 2

View user's profile Send private message

PostPosted: Mon Jun 29, 2015 12:04 am     Reply with quote

I don't explain it correctly.

I go to post my code.

This is DS1302 driver:

Code:
//////////////////////////////////////////////////////////////////////////
////                               DS1302.C                           ////
////                     Driver for Real Time Clock                   ////
////                                                                  ////
////  rtc_init()                                   Call after power up////
////                                                                  ////
////  rtc_set_datetime(day,mth,year,dow,hour,min)  Set the date/time  ////
////                                                                  ////
////  rtc_get_date(day,mth,year,dow)               Get the date       ////
////                                                                  ////
////  rtc_get_time(hr,min,sec)                     Get the time       ////
////                                                                  ////
////  rtc_write_nvr(address,data)                  Write to NVR       ////
////                                                                  ////
////  data = rtc_read_nvr(address)                 Read from NVR      ////
////                                                                  ////
////  get_bcd(data)                              Convert data to BCD  ////
////                                                                  ////
////  rm_bcd(data)                               Convert data to int  ////
////                                                                  ////
//////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services          ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler.  This source code may only be distributed to other     ////
//// licensed users of the CCS C compiler.  No other use, reproduction////
//// or distribution is permitted without written permission.         ////
//// Derivative programs created using this software in object code   ////
//// form are not restricted in any way.                              ////
//////////////////////////////////////////////////////////////////////////

#ifndef RTC_SCLK

#define RTC_SCLK PIN_E1
#define RTC_IO   PIN_E0
#define RTC_RST  PIN_E2

#endif

void write_ds1302_byte(BYTE cmd) {
   BYTE i;

   for(i=0;i<=7;++i) {
      output_bit(RTC_IO, shift_right(&cmd,1,0) );
      output_high(RTC_SCLK);
      output_low(RTC_SCLK);
   }
}

void write_ds1302(BYTE cmd, BYTE data) {

   output_high(RTC_RST);
   write_ds1302_byte(cmd);
   write_ds1302_byte(data);
   output_low(RTC_RST);
}

BYTE read_ds1302(BYTE cmd) {
   BYTE i,data;

   output_high(RTC_RST);
   write_ds1302_byte(cmd);
   
   input(RTC_IO);
   delay_us(1);
         
   for(i=0;i<=7;++i) {
      shift_right(&data,1,input(RTC_IO));
      output_high(RTC_SCLK);
      delay_us(2);
      output_low(RTC_SCLK);
      delay_us(2);
   }
   output_low(RTC_RST);

   return(data);
}

void rtc_init() {
   BYTE x;
   output_low(RTC_RST);
   delay_us(2);
   output_low(RTC_SCLK);
   write_ds1302(0x8e,0);
   write_ds1302(0x90,0xa4);
   x=read_ds1302(0x81);
   if((x & 0x80)!=0)
     write_ds1302(0x80,0);
}



void rtc_set_datetime(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min) {

   write_ds1302(0x86,day);
   write_ds1302(0x88,mth);
   write_ds1302(0x8c,year);
   write_ds1302(0x8a,dow);
   write_ds1302(0x84,hr);
   write_ds1302(0x82,min);
   write_ds1302(0x80,(0));
}

void rtc_get_date(BYTE& day, BYTE& mth, BYTE& year, BYTE& dow) {
   day = read_ds1302(0x87);
   mth = read_ds1302(0x89);
   year = read_ds1302(0x8d);
   dow = read_ds1302(0x8b);
}

void rtc_get_time(BYTE& hr, BYTE& min, BYTE& sec) {
   hr = read_ds1302(0x85);
   min = read_ds1302(0x83);
   sec = read_ds1302(0x81);
}

void rtc_write_nvr(BYTE address, BYTE data) {
   write_ds1302(address|0xc0,data);
}

BYTE rtc_read_nvr(BYTE address) {
    return(read_ds1302(address|0xc1));
}



I print the value of the time get in DS1307 in LCD using that function:
Code:
//-----------------------------------------------------------------------------
void lcd_print_2num_bcd_lcd1(int num_bcd)
{
   lcd_putc1((num_bcd >> 4)    + 0x30);      //DECENAS
   lcd_putc1((num_bcd &  0x0F) + 0x30);      //UNIDADES
}
//-----------------------------------------------------------------------------


I configure the turn on and turn off the lights with that code:
Code:
 //PANTALLA DE CONFIGURACION
         case 1:   
         
     
            switch (config_cursor_actual)
            {
               //CURSOR EN DIA DE LA SEMANA           
               case 0:
                  if (puls_up_fs && comprobar_datos_config())
                  {
                     if (++config_dia_actual == 8) config_dia_actual = 1;
                  }
                  if (puls_down_fs && comprobar_datos_config())
                  {
                     if (--config_dia_actual == 0) config_dia_actual = 7;                     
                  }
               //-------------------------                 
                  break;                 
                 
               //CURSOR EN DECENAS HORA INICIO                 
               case 1:
                  if (puls_up_fs)
                  {
                     inc_2bcd(&config_hora_inicio[config_dia_actual],
                              LIMIT_HORAS_INC, 1);
                  }
                  if (puls_down_fs)
                  {
                     dec_2bcd(&config_hora_inicio[config_dia_actual],
                              LIMIT_HORAS_DEC, 1);
                  }
               //-------------------------
                  break;
                 
               //CURSOR EN UNIDADES HORA INICIO               
               case 2:   
                  if (puls_up_fs)
                  {
                     inc_2bcd(&config_hora_inicio[config_dia_actual],
                              LIMIT_HORAS_INC, 0);
                  }
                  if (puls_down_fs)
                  {
                     dec_2bcd(&config_hora_inicio[config_dia_actual],
                              LIMIT_HORAS_DEC, 0);
                  }               
               //-------------------------
                  break;
                 
               //CURSOR EN DECENAS MINUTOS INICIO                 
               case 3:
                  if (puls_up_fs){
                     if (inc_2bcd(&config_minuto_inicio[config_dia_actual],
                                  LIMIT_MINS_INC, 1))
                     {
                        inc_2bcd(&config_hora_inicio[config_dia_actual],
                                 LIMIT_HORAS_INC, 0);
                     }
                  }
                  if (puls_down_fs){
                     if (dec_2bcd(&config_minuto_inicio[config_dia_actual],
                                  LIMIT_MINS_DEC, 1))
                     {
                        dec_2bcd(&config_hora_inicio[config_dia_actual],
                                 LIMIT_HORAS_DEC, 0);
                     }
                  }
               //-------------------------
                  break;
                 
               //CURSOR EN UNIDADES MINUTOS INICIO                 
               case 4:
                  if (puls_up_fs){
                     if (inc_2bcd(&config_minuto_inicio[config_dia_actual],
                                  LIMIT_MINS_INC, 0))
                     {
                        inc_2bcd(&config_hora_inicio[config_dia_actual],
                                 LIMIT_HORAS_INC, 0);
                     }
                  }
                  if (puls_down_fs){
                     if (dec_2bcd(&config_minuto_inicio[config_dia_actual],
                                  LIMIT_MINS_DEC, 0))
                     {
                        dec_2bcd(&config_hora_inicio[config_dia_actual],
                                 LIMIT_HORAS_DEC, 0);
                     }
                  }         
               //-------------------------
                  break;
               
             
             
             //CURSOR EN DECENAS HORA FIN                 
               case 5:
                  if (puls_up_fs)
                  {
                     inc_2bcd(&config_hora_fin[config_dia_actual],
                              LIMIT_HORAS_INC, 1);
                  }
                  if (puls_down_fs)
                  {
                     dec_2bcd(&config_hora_fin[config_dia_actual],
                              LIMIT_HORAS_DEC, 1);
                  }
               //-------------------------
                  break;
                 
               //CURSOR EN UNIDADES HORA FIN               
               case 6:   
                  if (puls_up_fs)
                  {
                     inc_2bcd(&config_hora_fin[config_dia_actual],
                              LIMIT_HORAS_INC, 0);
                  }
                  if (puls_down_fs)
                  {
                     dec_2bcd(&config_hora_fin[config_dia_actual],
                              LIMIT_HORAS_DEC, 0);
                  }               
               //-------------------------
                  break;
                 
               //CURSOR EN DECENAS MINUTOS FIN                 
               case 7:
                  if (puls_up_fs){
                     if (inc_2bcd(&config_minuto_fin[config_dia_actual],
                                  LIMIT_MINS_INC, 1))
                     {
                        inc_2bcd(&config_hora_fin[config_dia_actual],
                                 LIMIT_HORAS_INC, 0);
                     }
                  }
                  if (puls_down_fs){
                     if (dec_2bcd(&config_minuto_fin[config_dia_actual],
                                  LIMIT_MINS_DEC, 1))
                     {
                        dec_2bcd(&config_hora_fin[config_dia_actual],
                                 LIMIT_HORAS_DEC, 0);
                     }
                  }
               //-------------------------
                  break;
                 
               //CURSOR EN UNIDADES MINUTOS FIN                 
               case 8:
                  if (puls_up_fs){
                     if (inc_2bcd(&config_minuto_fin[config_dia_actual],
                                  LIMIT_MINS_INC, 0))
                     {
                        inc_2bcd(&config_hora_fin[config_dia_actual],
                                 LIMIT_HORAS_INC, 0);
                     }
                  }
                  if (puls_down_fs){
                     if (dec_2bcd(&config_minuto_fin[config_dia_actual],
                                  LIMIT_MINS_DEC, 0))
                     {
                        dec_2bcd(&config_hora_fin[config_dia_actual],
                                 LIMIT_HORAS_DEC, 0);
                     }
                  }         
               //-------------------------
                  break;


Where I define that at the first lines:

#define LIMIT_HORAS_INC 0x24
#define LIMIT_MINS_INC 0x60

#define LIMIT_HORAS_DEC 0x23
#define LIMIT_MINS_DEC 0x59


It is printed on a LCD screen with that code:
Code:
//PANTALLA DE CONFIGURACION           
         case 1:

            //ENCABEZADO
            lcd_gotoxy (1,1);
            printf (lcd_putc1 "< PANTALLA PARA PROGRAMAR EL ENCENDIDO >");
           
            //DIA
            lcd_gotoxy(1,2);
            printf(lcd_putc1,"Encender el ");
            lcd_gotoxy(13,2);
            lcd_print_nom_dia_sem(config_dia_actual);
            lcd_gotoxy(16,2);
            printf(lcd_putc1," de ");
           
            //INICIO
            lcd_gotoxy(20,2);
            lcd_print_2num_bcd_lcd1(config_hora_inicio[config_dia_actual]);
            lcd_gotoxy(22,2);
            printf(lcd_putc1,":");
            lcd_gotoxy(23,2);
            lcd_print_2num_bcd_lcd1(config_minuto_inicio[config_dia_actual]);
            lcd_gotoxy(25,2);
            printf(lcd_putc1," a ");
           
            //FIN
            lcd_gotoxy(28,2);
            lcd_print_2num_bcd_lcd1(config_hora_fin[config_dia_actual]);
            lcd_gotoxy(30,2);
            printf(lcd_putc1,":");
            lcd_gotoxy(31,2);
            lcd_print_2num_bcd_lcd1(config_minuto_fin[config_dia_actual]);
            lcd_gotoxy(33,2);
            printf(lcd_putc1,"   ");

            break;


I change the values using a cursor and the code to increase and decrease values is this:

Code:
//-----------------------------------------------------------------------------
short inc_2bcd(int* num_bcd, int bcd_limite = 0x9A, short digito = 0)
//Significado de los parametros:
//    num_bcd:    numero de 2 cifras en BCD que queremos incrementar
//    bcd_limite: valor una vez incrementado el numero BCD que se considera que
//                ha habido un desbordamiento, volviendo al valor 0. Los unicos
//                valores no BCD aceptables son desde 0x9A hasta 0xA0 que
//                equivalen a 100 BCD.
//    digito:     especifica si se ha de incrementar la cifra de las unidades(0)
//                o la de las decenas (1)
//
//Devuelve 1 si desborda por el limite
{
   switch (digito)
   {
      //Incrementar unidades
      case 0:
         *num_bcd +=1;              //Unidades + 1
         if ((*num_bcd & 0x0F) > 9) //Unidades > 9?
         {
            *num_bcd &= 0xF0;          //Unidades = 0
            *num_bcd += 0x10;          //Decenas + 1
         }
         if (*num_bcd >= bcd_limite)//Desbordamiento?
         {
            *num_bcd = 0x00;           //Numero BCD = 00
            return 1;                  //Devolver desbordamiento
         }
         break;
      //Incrementar decenas         
      case 1:
         *num_bcd += 0x10;          //Decenas + 1
         if (*num_bcd >= bcd_limite)//Desbordamiento?
         {
            *num_bcd &= 0x0F;          //Decenas = 0
            return 1;                  //Devolver desbordamiento
         }         
         break;
   }
   return 0;
}
//-----------------------------------------------------------------------------

short dec_2bcd(int* num_bcd, int bcd_limite = 0x99, short digito = 0)
//Significado de los parametros:
//    num_bcd:    numero de 2 cifras en BCD que queremos decrementar
//    bcd_limite: valor que tomará el numero BCD si se ha llegado a numeros
//                negativos (desbordamiento).
//    digito:     especifica si se ha de decrementar la cifra de las unidades(0)
//                o la de las decenas (1)
//
//Devuelve 1 si desborda por debajo de 0
{
   switch (digito)
   {
      //Decrementar unidades
      case 0:
         *num_bcd -= 1;                //Unidades - 1
         
         if (*num_bcd == 0xFF)           //Desbordamiento?
         {
            *num_bcd = bcd_limite;        //Numero BCD = limite
            return 1;                     //Devolver desbordamiento
         }

         if ((*num_bcd & 0x0F) == 0x0F)//Desbordamiento de Unidades?           
         {                                //Automaticamente -> Decenas - 1
            *num_bcd &= 0xF9;//0b11111001;//Unidades = 9         
         }
         break;
         
      //Decrementar decenas         
      case 1:
         *num_bcd -= 0x10;             //Decenas - 1

         if ((*num_bcd & 0xF0) == 0xF0)//Desbordamiento?
         {
            *num_bcd = (*num_bcd & 0x0F) | (bcd_limite & 0xF0); //Decenas = Decenas de limite
            if (*num_bcd > bcd_limite){   //Al restaurar las decenas, el numBCD es > limite?
               *num_bcd -= 0x10;               //Decenas - 1
            }
            return 1;                     //Devolver desbordamiento
         }       
         break;
   }
   return 0;
}


And this is EEPROM code where i store the 4 values (2 for init (hour_init, min_init) and 2 for end(hour_end, min_end)):
Code:
//-----------------------------------------------------------------------------
short cargar_eeprom() //Devuelve 0 si todo correcto / 1 si ha ocurrido algun error
{
   short temp_return;
   int *array;
   int i;
   int checksum_calc, checksum_leido;
   
   checksum_calc = 0x4A;  //Valor de inicio de la suma de comprobación de errores.   
   
   for (i = 0; i < 4; i++){
      switch(i)
      {
         case 0: array = &config_hora_inicio[0];   break;
         case 1: array = &config_minuto_inicio[0]; break;
         case 2: array = &config_hora_fin[0];      break;
         case 3: array = &config_minuto_fin[0];    break;
      }
     
      for (temp = 0; temp < 7; temp++){
         array[temp] = read_eeprom((i*7) + temp);
         if (array[temp] > 0x59) temp_return = 1;
         
         checksum_calc += array[temp];
      }
     
   }
   
   //Comprobación de errores
   checksum_leido = read_eeprom(0x1C /* =4*7 */);
   
   if (checksum_calc != checksum_leido){
      //Reset Data
      for (temp = 0; temp < 7; temp++){
         config_hora_inicio[temp]   = config_minuto_inicio[temp]  = 0x00;
         config_hora_fin[temp]      = config_minuto_fin[temp]     = 0x00;
      }
      return 1;
   }else return 0;
}
//-----------------------------------------------------------------------------
void guardar_eeprom()
{
   int *array;
   int i;
   int checksum;
   
   checksum = 0x4A;  //Valor de inicio de la suma de comprobación de errores. 
   
   for (i = 0; i < 4; i++){
      switch(i)
      {
         case 0: array = &config_hora_inicio[0];   break;
         case 1: array = &config_minuto_inicio[0]; break;
         case 2: array = &config_hora_fin[0];      break;
         case 3: array = &config_minuto_fin[0];    break;
      }

      for (temp = 0; temp < 7; temp++){
         write_eeprom((i*7) + temp, array[temp]);
         
         checksum += array[temp];
      }     
   } 
   write_eeprom((0x1C /* =4*7 */), checksum);
}
//-----------------------------------------------------------------------------;



I never done a PWM code this is the first that you should know.
My idea was do PWM using decimal system doing the rest (but i don't know how to do PWM, if you can help me if you know another form to do it, I would be very grateful).

resthour = config_hora_fin - config_hora_inicio
and
restmin = config_minuto_fin - config_hora_inicio

because i want multiply hour by 3600 and minutes by 60 to get the seconds and use it to do the PWM code

seconds total = resthour*3600+restmin*60


Thaks to read that, and sorry, but I want to post the code to show how I am working.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group