Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Is there a relation between LED current and speed?

Status
Not open for further replies.
Hi Roman,

The parts don't seem to have anything other than resistors on board. My wife has taken some macro pictures of them and you can see clearly what there is. I don't understand why they "leak" in my circuit but I guess thats not what they had in mind when they made them. Think most people just use them for lighting things like under cars and stuff. The setup in the photo is just the test rig I built to check why they were leaking, don't worry, the segments have not started to mutate. ;)

As to the offer of help with the code, I'm sure I will be taking you up on that mate. As I have said on older threads I am sure that every time I learn anything it pushes something else out, and usually more than I learnt! :eek:

Thanks again mate, and in the unlikely event of you needing my help, don't hesitate to ask.

Cheers, Al

PS photo's and video of clock coming soon, just doing the surround and fascia, watch this space.
 
Cool thanks for the photos. Looks like the LEDs they used must just have a low Vr leakage voltage. Like you said that wouldn't matter if they are used for cheap general lighting applications.
 
Hi to all,

Roman, How difficult would it be to incorporate a DS 1307 RTC IC into the software?

It would be useful to me to have battery backup that the 1307 provides. What I don't understand is the way the clock would be set with the 1307. Also I can't figure out how your code gets the timing? I have read and re-read the code but I am not getting it at all.

Any help appreciated.

Thanks, Al
 
Hi Al, the timing in my code is done in the interrupt, with a Bresenham accumulator. It is quite simple, every interrupt a fixed value is added to the bres variable, then when it gets larger than 0.5 seconds the clock makes a "halfsecond" event.

The Dallas RTCs are annoyingly difficult to use, they require an I2C back and forth protocol and would add a lot of extra work to a very simple project code.

You also have no pins left on your PIC 16F628, the code already has to switch 2 pins between driving the LEDs to testing the 2 buttons.

May I suggest just using battery backup for the PIC? 3 or 4 AA batteries would provide enough power to keep the PIC running and can be added to your existing project. You need to separate the PIC power 5v from the other ICs, say by using diodes so the PIC normally runs from the 5v PSU but if that goes down the PIC is kept running from the battery (but the rest of the clock ICs and display is not powered).
 
Last edited:
Hi Roman,

Hey mate I hadn't thought of the extra pins needed for the 1307, doh!

Sounds like the best option is to use batteries like you said. Wonder if I can incorporate some rechargeables into it and let it charge them as it goes. 4 x Nicads would be just about right for charging at 5v with a limiting resistor and should be able to be trickled forever I think?

Well I'm just building the final bits of the case now so I'll get back to it.

Thanks, Al
 
-----
 
Last edited:
...
Sounds like the best option is to use batteries like you said. Wonder if I can incorporate some rechargeables into it and let it charge them as it goes. 4 x Nicads would be just about right for charging at 5v with a limiting resistor and should be able to be trickled forever I think?
...

4 AA NiCd cells will run about 4.8v, so you could power the PIC from that, say through a resistor to limit max charge current when power is reconnected. Max current will be when the cells are low, maybe 4v so it would be 1v drop. Allowing 500mA for max charge current would give a resistor of 2.2 ohms. Then the battery pack and series resistor is just attached across your 5v rail.

The other thing needed would be a diode before your 5v regulator, in series with its Vin pin, to stop any battery current from flowing back out the other side of the regulator when power goes down.

It's a crude system and of course won't give optimal charging etc, but since this is a clock that will be powered 99% of the time the NiCds will always have a reasonable charge in them floating at 5.0v, and since they only power the PIC and some inputs to the ULN driver chips (maybe 40mA total?) the AA NiCds will be probably >1000 mAh stored so will run the PIC for approx 25 hours, and maybe more.

It's crude, but one resistor and one diode and it's done, and should work ok.
 
Unless you're doing some high current discharge you'd be better off with NiMH batteries over Nicads. You'll get much better energy density.
 
Hi Mate,

Wouldn't NiMH batteries be worse to keep charged? I mean I have read that they don't like constant charging?

Al
 
Yes and no. Many NiMH batteries have high self-discharge rates. The "eneloop" brand by Sanyo does not. I have had them last 6 months with almost no change in charge. Battery University has a lot of information on self-discharge rates.

John
 
Hi to all,

Roman, can you please help me understand something in your code?

I have been studying it for quite a while now and still can't get my head round something. One of the lines in your code reads" if(hours10 >= 2 && hours > 4) // if > 24:00"

Why does the clock display in 12 hour format when the code seems to me to mean reset to zero after 24.00?

I seem to be understanding most of the "C" stuff except the interrupts, which I still don't get even in basic, but I can't get at all how the clock shows 12 hour format when that line of code tells it 24 hour.

Code:
/******************************************************************************
  seg7_clock_no0.c   4digit clock using PIC 16F628A and 7seg displays
  28th Jan 2012 - open source - www.RomanBlack.com
  Compiler - MikroC, tested in hardware on EasyPIC4
  
  NOTE! This is a variation of the clock that does not show the leading
  zero digit, ie it shows 1:00 and not 01:00.

  Written for BigAl, to suit his multiplexed clock hardware (see schematic)
  Operation; Interrupt generates a 0.5 second event, and also does the
  4 digit multiplexing. The 0.5 second event is used for clock setting buttons,
  and also counts 120 halfseconds to generate 1 minute (to operate the clock).

  PIC 16F628A, 4MHz xtal
  Pins;
   PORTA 0,1,2,3  - 4 digit drivers, LO = digit ON
   PORTB 0-6      - 7 segment drivers, HI = segment ON
   PORTB 0,1      - also used for 2 clockset buttons, HI = pressed
                    (see schematic for buttons and required button resistors)
   PORTB7         - used as a "heartbeat" LED, flashes every second
   
  PIC config; MCLRE_OFF, BODEN_OFF, BORES_OFF, LVP_OFF, WDT_OFF, PWRTE_OFF
******************************************************************************/
// global variables
unsigned char buttons;    // used in interrupt for multiplxing etc
unsigned char digit;
unsigned char segments;
unsigned char multiplex;
unsigned char halfsecond;

unsigned char mins;       // used for clock time data
unsigned char mins10;
unsigned char hours;
unsigned char hours10;

unsigned long bres;       // used to generate accurate halfsecond period

// functions
void get_segments(unsigned char);
void update_clock(void);


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void  interrupt(void)
{
  //-------------------------------------------------------
  // This is the TMR0 overflow int.
  // 16MHz TMR0 is 1:2 prescale so we get here every 512 PIC instructions
  // with 4MHz xtal (1uS per instruction) that is every 512uS (1953 Hz).
  // Multplexing is done at 1 digit per interrupt, so is approx 488 Hz
  // per digit.
  //-------------------------------------------------------
  // first do timing sensitive stuff, like dead time to stop
  // display ghosting, and during dead time read the 2 buttons.
  
  PORTA = 0b00001111;     // all 4 digit drivers OFF
  PORTB = 0b00000000;     // all 7 segments OFF
  asm nop;
  asm nop;
  TRISB = 0b00000011;     // change 2 button pins to inputs again
  asm nop;
  asm nop;
  asm nop;
  asm nop;
  buttons = PORTB;        // read the 2 buttons
  TRISB = 0b00000000;     // change the 2 button pins back to outputs

  if(halfsecond.F0) segments.F7 = 1;  // (optional) heartbeat LED on PORTB7

  PORTB = segments;       // select the segments for the next digit
  PORTA = digit;          // and light the digit up!

  //-------------------------------------------------------
  // multiplexing sequencing; 1 2 3 4
  // and get digits and segments loaded (ready for next interrupt)
  multiplex++;
  if(multiplex > 4) multiplex = 1;

  if(multiplex == 1)
  {
    // note, this first digit now suppresses leading zero!
    if(hours10 >= 10) get_segments(1);  // display the 1 for 10, 11, 12
    else              segments = 0;     // <10 make all segments OFF
    digit = 0b00001110;     // Al's hardware (has reversed digit order; 4321, and active LOW)
  }
  if(multiplex == 2)
  {
    get_segments(hours);
    digit = 0b00001101;     // Al
  }
  if(multiplex == 3)
  {
    get_segments(mins10);
    digit = 0b00001011;     // Al
  }
  if(multiplex == 4)
  {
    get_segments(mins);
    digit = 0b00000111;     // Al
  }

  //-------------------------------------------------------
  // do timekeeping, calc halfseconds
  // this is a simple zero-error Bresenham system, a halfsecond
  // is 500000 uS (500000 PIC instructions)

  bres += 512;        // add another interrupt; +512uS
  if(bres >= 500000)  // if reached a halfsecond
  {
    bres -= 500000;
    halfsecond++;     // add another halfsecond (which is handled in main()
  }
  else
  {
    buttons = 0;      // kill button read if not a halfsecond
  }

  //-------------------------------------------------------
  // reset the TMR0 int flag and exit
  INTCON.T0IF = 0;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


//=============================================================================
//  GET_SEGMENTS
//=============================================================================
void get_segments(unsigned char numb)
{
  //-------------------------------------------------------
  // this loads the 7 segments to match a decimal digit
  // PORTB0 = segA to PORTB6 = segG, standard 7-seg A-G format.
  // 1 = segment ON
  //-------------------------------------------------------
  if(numb == 0) segments = 0b00111111;
  if(numb == 1) segments = 0b00000110;
  if(numb == 2) segments = 0b01011011;
  if(numb == 3) segments = 0b01001111;
  if(numb == 4) segments = 0b01100110;
  if(numb == 5) segments = 0b01101101;
  if(numb == 6) segments = 0b01111101;
  if(numb == 7) segments = 0b00000111;
  if(numb == 8) segments = 0b01111111;
  if(numb == 9) segments = 0b01101111;
}
//-----------------------------------------------------------------------------


//=============================================================================
//  UPDATE_CLOCK
//=============================================================================
void update_clock(void)
{
  //-------------------------------------------------------
  // this checks if the clock has changed, if so it
  // handles all digit overflows.
  //-------------------------------------------------------
  if(mins >= 10)
  {
    mins = 0;
    mins10++;
  }
  if(mins10 >= 6)
  {
    mins10 = 0;
    hours++;
  }
  if(hours >= 10)
  {
    hours = 0;
    hours10++;
  }
  if(hours10 >= 2 && hours > 4)  // if > 24:00
  {
    hours10 = 0;      // set to 00:00
    hours = 0;
  }
}
//-----------------------------------------------------------------------------


//=============================================================================
//  MAIN
//=============================================================================
void main(void)
{
  //-------------------------------------------------------
  // setup PIC 16F628A ports and timer
  PORTA  = 0b00001111;    // 4 digit drivers all OFF (1 = OFF)
  TRISA  = 0b11110000;          // PORTA0-3, are 4 outputs for digit drivers
  PORTB  = 0b00000000;    // PORTB all 7 segments off (0 = OFF)
  TRISB  = 0b00000000;           // PORTB all 8 pins are outputs

  OPTION_REG = 0b10000000;  // TMR0 at 2:1 prescaler, PORTB pullups OFF

  //-------------------------------------------------------
  // setup variables before start (before first interrupt)
  bres = 0;
  digit = 0b00001111;   // digits OFF
  segments = 0;         // segments OFF
  halfsecond = 0;

  mins = 0;             // set clock start time to 12:00
  mins10 = 0;
  hours = 2;
  hours10 = 1;

  INTCON = 0b10100000;  // GIE on, T0IE on (turns TMR0 interrupt ON)

  //-------------------------------------------------------
  // main loop
  while(1)
  {
    //---------------------------------------------
    // test for buttons pressed, they are checked in the interrupt
    // every halfsecond
    if(buttons.F0)       // if MINS button pressed
    {
      buttons = 0;
      mins++;           // add a minute
      halfsecond = 0;   // reset seconds
      update_clock();
    }
    if(buttons.F1)       // if HOURS button pressed
    {
      buttons = 0;
      hours++;           // add an hour
      halfsecond = 0;   // reset seconds
      update_clock();
    }

    //---------------------------------------------
    // test for a minute reached, and update clock
    if(halfsecond >= 120)     // 120 halfseconds = 1 minute
    {
      mins++;           // add a minute
      halfsecond = 0;   // reset seconds
      update_clock();
    }
  }
}
//-----------------------------------------------------------------------------


Thanks, Al
 
Hi Al, I juts checked on my other computer and checked both my last compiled files; seg7_clock.c and seg7_clock_no0.c and both have this code;
Code:
  if(hours10 >= 1 && hours > 2)  // if > 12:00
  {
    hours10 = 0;      // set to 01:00
    hours = 1;
  }

Which is correct and tested for the 12:00 version of the clock. I'm not sure where you got that 24:00 code from? Maybe it was from one of the earlier versions I posted?

Is there something about the interrupt to wanted me to explain? Basically its a timer interrupt, to its just a chunk of code that always executes every 512uS without fail. It does two tasks;
1. sequencing the 4digit display multiplexing (and adding the dead zone between digits)
2. generating a "clock" event every halfsecond which is used to update the real time clock

Just ask if you need specifics on what any of the code is doing. :)
 
Status
Not open for further replies.

Latest threads

Back
Top