SLA Charger/Backup System

Discussion in 'Embedded Systems and Microcontrollers' started by R!f@@, Jan 10, 2016.

  1. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    I would like to continue from this thread onwards.
    Link to other thread to avoid confusion
    One, Two and Three

    I am attaching the Schema for reference.

    Aim: The PIC monitors the PSU, Charger Voltage, Charging current and Float charging mode. Senses AC failure and PSU + charger fault conditions.
    Displays everything in a 16x2 LCD in 4 bit mode. Audible alarm is also there just to annoy me if I forgot to check since this charger is mounted a bit high. :D

    Continued from this thread.

    @JohnInTX
    The Buzzer is at RC6. RC2 is Enable pin of LCD.
    I will swap them if you want me to.

    The Problem I had was that the LCD is getting jumbled as I add more messages.
    I figured it was due to all blocking codes of the buzzer and LCD like you said.

    As of now the beeper is working. From the scope images you can see.

    The Project is about the SLA charger I built.
    I can do the ADC reading and displaying stuff. I have done that before. Crude but works. It gets messed up with too many messages. I cannot figure out why and nobody here had an answer before.

    Since you are here I knew you will have an answer and so I thought why not start it.
    The aim of the code is to monitor the charger.
    Measure voltages from 5 different ADC inputs. Display them and act on it accordingly. Nothing more. It drives the Charging circuit, ON, OFF and alarm stuff with 16x2 4 bit LCD display.

    All I need for now it to display Messages in LCD using interrupt. It must be possible but I cannot get my head around that part.
    Can we use TMR0 for LCD messages and leave TMR2 for buzzer as it is ?

    PS. Originally the target was '876 but that did not have an int osc. So switched to '886. It was PIN compatible
     
    Last edited: Jan 10, 2016
  2. Picbuster

    Member

    Dec 2, 2013
    376
    50
    I don't know how your program is constructed.
    But read all your inputs using interrupts.
    In main you go once a time round to read, average and display content.
    next step as you said is send data, under interrupt, to display.
    But here is some care needed some compilers do not like an interrupt into an interrupt.
    like
    if ( int serial){
    reading=serial_byte;
    output_serial(serial_byte; // this goes wrong without any code attention
    }
     
  3. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    @Picbuster
    Wouldn't it be better to update the LCD in 100ms intervals via interrupt. Read ADC, do the conversion and update LCD Data register in Main.

    @JohnInTX
    As you said before that I do not need reload TMR2 I tried as below.
    Commented out TMR += TMR2reload and the buzzer is at 10KHz. I can see from the scope.
    I need to reload TMR2 to TMR2reload value to get the buzzer at 3.3KHz.

    Am I missing something here ?
     
  4. Picbuster

    Member

    Dec 2, 2013
    376
    50
    Conversion in interrupt and display in main is the best way. But again I do not have your code.
    Displays don't need, in a normal case, updates faster than 0,5 sec. I use 1 sec.
     
  5. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    We'll see. I do not have a complete working code, just the buzzer part is working
     
  6. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    @R!f@@
    Ahhh.. I see. Not Easy7. Thanks for the skiz, I'll take a look at it.
    I don't see any reason that this can't be done with what you have drawn. As Picbuster says, display in main. The ADC conversion can be done via interrupt but I usually just start a conversion in an ADC task and leave. Next time the task runs, the ADC is likely done. Read it and start conversion again. This makes for lots of readings. I average them for a smooth converted value.
    A display update interval of 100ms is probably more than you need. 500ms-1 sec is probably plenty. The values don't change that fast in a charger.
    I'll take a look at your code..

    EDIT: Have you laid out PC boards for this or is it in proto stage? If still a proto, we can make things better with some pin relocations. If already on a PCB, we can go from there.
    EDIT: Do you want the backlight to be dimmable (PWM?) or just switchable on/off?
    EDIT: Are you going to use a debugger that uses the ICSP lines or just reserve them for programming? (I'd use the debugger if you have it available).I'm working up a better pinout for you if you can move pins... It takes advantage of both hardware PWMs and will make the rest of your code much easier..
     
    Last edited: Jan 10, 2016
  7. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    What's Easy7 ?
    Are you referring to the EasyPIC7 I have ?

    Fair enough. I will go with the advice. You guys know better about these stuff

    PCB is already made and the components are in, as you can see from the pictures. Even though a proto, making PCB's is not easy for me yet.
    It will be easy for me if you can go with what I have already made.

    Just ON/OFF not dimmable. No need for that

    PCB is made to use ICSP only. Nothing else is connected.

    What do you have in mind. It won't harm to lay out what you think. Might be better for the next version. A better one may be.
     
    Last edited: Jan 10, 2016
  8. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    OK, I'll chew on that for awhile..
    You will use MikroC's LCD routines I assume and they won't be compatible with the software PWM we have since you can't mix shadowed (our PWM) and non-shadowed (MikroC libraries) constructs on the same port. No worries. Just have to think on it a bit...
     
  9. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    I do not need to use MikroC's routines if I can do what I want without it :)
    It's not compatible. I checked. The Buzzer does not work if I put a message routine in the main.

    Me think this is new to you too...!
     
  10. JohnInTX

    Moderator

    Jun 26, 2012
    2,348
    1,029
    Its not news but I didn't know the context until now. Thinking...
     
  11. Picbuster

    Member

    Dec 2, 2013
    376
    50
    your lcd driver for the 16 x2 in 4 bit mode. ( rename to lcd.c)
    I am to lazy to map the data and control lines to your hw but file will explain it self.
     
    • lcd.txt
      File size:
      2.3 KB
      Views:
      4
  12. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    What pictures, please? Are they buried in one of the three other threads?

    I get confused trying to figure out which particular problem you're actually working on at any given moment (lol).
     
  13. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    @Picbuster
    Thanks ... I will check it.

    @MMcLaren
    Where have you been ?
    Sorry the pictures were buried in the other threads. Different questions on one project. That is why I decided to put them in one.
    I believe I posted a question especially to you MMClaren in the Led strip project. I believe John wanted your opinion on a issue I ran into.
    Not tht is a priority.
    Need to get this project done as soon as possible.

    I like to learn to fix this issue. It will solve a previous problem I had with an earlier project (which is on hold) too
     
  14. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    So how does this actually work.
    I see it uses delays. If it does, that is what I wanna avoid
     
  15. Picbuster

    Member

    Dec 2, 2013
    376
    50
    Delays the display needs some time to handle the data see spec sheet.
    Some displays are faster please use delays as indicated by supplier.
    The program is simple and easy to understand but here is how to use it.
    I use it with 4 X 20 and 2 x 20 displays and 1 x 16 and 2 x 16
    The delay can't be the problem if you handle this in main

    do an include lcd.h with content
    #define LCD_RS your pin
    #define LCD_RW your pin
    #define LCD_EN your pin
    #define LCD_DATA your pin
    end lcd.h

    lcd_init(); // at start-up

    lcd_clear(); // when needed

    lcd_goto(DR1); // goto line/ position
    lcd_puts("this is written @ DR1"); // print the line

    two lines display uses DR1 and DR2 ( note: they are not sequential)
    DR1= 64+10 start at position 10 at second line.
    the positions for a 4 line display are
    #define DR1 0
    #define DR2 64
    #define DR3 20
    #define DR4 84
     
  16. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    LCD_DATA ???
    Is it for I2C ?

    My Code

    Code (C):
    1. // ****** LCD Configuration ************
    2. sbit LCD_RS at RC0_bit;
    3. sbit LCD_EN at RC1_bit;
    4. sbit LCD_D4 at RC2_bit;
    5. sbit LCD_D5 at RC3_bit;
    6. sbit LCD_D6 at RC4_bit;
    7. sbit LCD_D7 at RC5_bit;
    8. sbit LCD_RS_Direction at TRISC0_bit;
    9. sbit LCD_EN_Direction at TRISC1_bit;
    10. sbit LCD_D4_Direction at TRISC2_bit;
    11. sbit LCD_D5_Direction at TRISC3_bit;
    12. sbit LCD_D6_Direction at TRISC4_bit;
    13. sbit LCD_D7_Direction at TRISC5_bit;
    14. // End of LCD Connections.
     
  17. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    I recall you guys were wondering which rotary encoder I had used but I had already stated it was a Bourns PEC11 series (lol)...
    Well, I agree with JohnInTx and Picbuster that it's time to ditch the MikroC LCD library routines. The LCD functions Picbuster posted are similar to the ones I use. Ask him to post a simple usage example... oops! I see he already has...
     
    Last edited: Jan 10, 2016
  18. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    The encoder issue,we could discuss later on that thread if you up for it.

    For this project any example will help. Please post if you don't mind
    Is Picbuster routine for serial I2C
     
  19. R!f@@

    Thread Starter AAC Fanatic!

    Apr 2, 2009
    8,754
    760
    @MMcLaren I bumped that thread so you can check it out
     
  20. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    Ok, here's an example... It's actually a project from Raj Bhatt that was written in MikroC Pro that I converted to BoostC for someone. It includes actual LCD and ADC functions instead of the MikroC library functions... I know you've had difficulties with BoostC's handling of bits so I'm not sure this will be much help. BoostC also allows "function overloading" which explains why a couple functions have the same name. I don't know if MikroC or XC8 support "function overloading". Anyway, good luck on your project...

    Code (Text):
    1.  
    2.   /******************************************************************
    3.    *                                                                *
    4.    *  Project: Raj Voltmeter                                        *
    5.    *   Source: Raj_Voltmeter.c                                      *
    6.    *   Author: Mike McLaren, K8LH                                   *
    7.    *     Date: 03-Aug-12                                            *
    8.    *  Revised: 03-Aug-12                                            *
    9.    *                                                                *
    10.    *  16F688 + HD44780 2x16 LCD 0-20V Voltmeter Experiment based    *
    11.    *  on a project from Rajendra Bhatt's blog (embedded-lab.com).   *
    12.    *                                                                *
    13.    *                                                                *
    14.    *      IDE: MPLAB 8.84 (tabs = 4)                                *
    15.    *     Lang: Sourceboost BoostC v7.05, Lite/Free version          *
    16.    *                                                                *
    17.    ******************************************************************/
    18.  
    19.    #include <system.h>
    20.  
    21.    #pragma DATA _CONFIG, _WDT_OFF & _INTOSCIO
    22.  
    23.    #pragma CLOCK_FREQ 8000000   // 8-MHz INTOSC
    24.  
    25.   /******************************************************************
    26.    *  function prototypes                                           *
    27.    ******************************************************************/
    28.   /******************************************************************
    29.    *  variables                                                     *
    30.    ******************************************************************/
    31.  
    32.    int input;                   // adc voltage reading
    33.  
    34.   /******************************************************************
    35.    *  constants                                                     *
    36.    ******************************************************************/
    37.  
    38.    #define line1 0x80           // lcd ddram address for line 1
    39.    #define line2 0xC0           // lcd ddram address for line 2
    40.  
    41.    #define lcd_d4 portc.0       // RC0
    42.    #define lcd_d5 portc.1       // RC1
    43.    #define lcd_d6 portc.2       // RC2
    44.    #define lcd_d7 portc.3       // RC3
    45.    #define lcd_rs portc.4       // RC4
    46.    #define lcd_e portc.5        // RC5
    47.  
    48.   /******************************************************************
    49.    *  low level drivers & functions                                 *
    50.    ******************************************************************/
    51.  
    52.    void PutNyb(char work)       // write nibble
    53.    { lcd_d4 = work.4;           //
    54.      lcd_d5 = work.5;           //
    55.      lcd_d6 = work.6;           //
    56.      lcd_d7 = work.7;           //
    57.      lcd_e = 1; lcd_e = 0;      // strobe 'E' pin
    58.      delay_us(160);             //
    59.    }                            //
    60.  
    61.    void PutLCD(char work)       // write byte (two nibbles)
    62.    { PutNyb(work);              // write hi nibble
    63.      asm swapf  _work,F         // swap nibbles
    64.      PutNyb(work);              // write lo nibble
    65.    }                            //
    66.  
    67.    void PutCMD(char pdata)      // lcd command (RS=0)
    68.    { lcd_rs = 0; PutLCD(pdata); //
    69.    }                            //
    70.  
    71.    void PutDAT(char pdata)      // lcd data (RS=1)
    72.    { lcd_rs = 1; PutLCD(pdata); //
    73.    }                            //
    74.  
    75.    void PutDAT(char *pdata)     // lcd data (RS=1) strings
    76.    { while(*pdata)              //
    77.        PutDAT(*pdata++);        //
    78.    }                            //
    79.  
    80.   /*                                                                *
    81.    *  HD44780 "initialize by instruction" procedure for 4-bit mode  *
    82.    *                                                                */
    83.    void lcdinit()               //
    84.    { delay_ms(100);             //
    85.      lcd_rs = 0;                // RS=0 (command)
    86.      PutNyb(0x30); delay_ms(4); // step 1 (required 4-ms delay)
    87.      PutNyb(0x30);              // step 2 (built-in 160-us delay)
    88.      PutNyb(0x30);              // step 3 (built-in 160-us delay)
    89.      PutNyb(0x20);              // step 4 (built-in 160-us delay)
    90.   /*                                                                *
    91.    *  now in 4-bit interface mode and can write full 8-bit bytes    *
    92.    *                                                                */
    93.      PutCMD(0x28);              // 4-bit, 2-lines, 5x7 font
    94.      PutCMD(0x0C);              // display on, currsor & blink off
    95.      PutCMD(0x06);              // cursor inc, shift off
    96.      PutCMD(0x01);              // clear display
    97.      delay_ms(2);               // required delay
    98.    }                            //
    99.  
    100.    int getadc(char channel)     // channel, 0..7
    101.    { int result;                //
    102.      adcon0.CHS0 = channel.0;   // select channel
    103.      adcon0.CHS1 = channel.1;   //   "
    104.      adcon0.CHS2 = channel.2;   //   "
    105.      adcon0.ADON = 1;           // turn ADC on
    106.      delay_us(20);              // acquisition delay
    107.      adcon0.GO_DONE = 1;        // start conversion
    108.      while(adcon0.GO_DONE);     // wait for conversion complete
    109.      adcon0.ADON = 0;           // turn ADC off
    110.      result = adresh << 8;      // collect ADC reading
    111.      result |= adresl;          //
    112.      return result;             // 0..1023
    113.    }
    114.  
    115.   /******************************************************************
    116.    *  main setup                                                    *
    117.    ******************************************************************/
    118.  
    119.    void main()                  //
    120.    {
    121.      ansel = 0b00000100;        // RA2/AN2 analog, others digital
    122.      adcon0 = 0b10000000;       // right justified adc result
    123.      adcon1 = 0b01010000;       // Fosc/16 conversion clock
    124.      cmcon0 = 0x07;             // disable comparators
    125.      osccon = 0b01110000;       // INTOSC = 8-MHz
    126.      while(osccon.HTS == 0);    // wait until osc stable
    127.      trisa = 0b00001100;        // RA2(AN2) & RA3(MCLR) inputs
    128.      trisc = 0b00000000;        // portc all outputs
    129.      lcdinit();                 // init LCD in 4-bit interface mode
    130.      PutDAT("DVM Project");     //
    131.  
    132.   /******************************************************************
    133.    *  main loop                                                     *
    134.    ******************************************************************/
    135.  
    136.      while(1)                   //
    137.      { input = getadc(2);       // get adc reading, 0..1023
    138.        input *= 2;              // scale to volts * 100
    139.        input += 5;              // rounding (to 1/10th volt)
    140.        PutCMD(line2+5);         // line 2 tab 6
    141.        PutDAT((input/1000) | '0');    // 'tens' digit
    142.        PutDAT((input/100)%10 | '0');  // 'ones' digit
    143.        PutDAT('.');                   // '.'
    144.        PutDAT((input/10)%10 | '0');   // 'tenths' digit
    145.        delay_ms(500);           // 500 msec update intervals
    146.      }                          // loop forever
    147.    }                            // end main()
    148.  
     
    Last edited: Jan 10, 2016
Loading...