10ms delay in hardware

Discussion in 'General Electronics Chat' started by Drools, Sep 1, 2009.

  1. Drools

    Thread Starter Member

    Jan 6, 2009
    18
    0
    I'm working on programming an Atmega48 uC, I can do the delay on the uC but when the chip is actually in the delay it can not do anything else which is a problem. I'm monitoring 16 switches which can be pushed simultaneously or individually when a switch is pressed I produce a high output which lasts ~10ms. Problem is when 2 or more switches are pressed close together some switches are missed due to the uC working on the delay from an earlier switch. I thought about threading the code but I do not think the Atmega supports threads.
    So what I thought about doing is producing a tiny pulse to a hardware circuit that would do the delay for me. Does that sound reasonable?
     
  2. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Post your code so that we can see how you have implemented your delay. It sounds like you are not using the full power of the interrupt system.

    hgmjr
     
  3. Drools

    Thread Starter Member

    Jan 6, 2009
    18
    0
    I'm just polling the PIN status in a loop. I have used a pin change interupt in other projects but I figured that would be overkill. I could try it here, but wouldn't the same problem exist. 4 switches shown.

    Code ( (Unknown Language)):
    1.  
    2. int main(void)
    3. {
    4.  LanesInit();
    5.  while(1){
    6.   if bit_is_set(PINC,PC0) {  
    7.       PORTD |= (1<<PORTD4);
    8.    _delay_ms(5);
    9.       PORTD &= ~(1<<PORTD4);
    10.         } else if bit_is_set(PINC,PC1) {            
    11.    PORTD |= (1<<PORTD5);
    12.    _delay_ms(5);
    13.       PORTD &= ~(1<<PORTD5);
    14.         } else if bit_is_set(PINC,PC2) {      
    15.    PORTD |= (1<<PORTD6);
    16.    _delay_ms(5);
    17.       PORTD &= ~(1<<PORTD6);            
    18.         } else if bit_is_set(PINC,PC3) {              
    19.    PORTD |= (1<<PORTD7);
    20.    _delay_ms(5);
    21.       PORTD &= ~(1<<PORTD7);            
    22.         }
    23.  };
    24.  return 0;
    25. }
    26.  
    27.  
     
  4. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    If I understand your problem correctly, you are wanting to put the time that you are spending in the _delay_ms() function calls to more efficent use.

    Is that what you are wanting to do?

    hgmjr
     
  5. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,692
    903
    If the switch stays high long enough to charge the gate of a small, logic-level mosfet, you can control the time the mosfet stays on independently for each switch using a high value resistor on the gate. In this schematic, I have added additional capacitance (C1) so R1 doesn't have to be quite so big.

    [​IMG]

    This is just a simple hardware solution, as you requested. If you want more complexity, you can use a one-shot, say made from a 555, on each switch.

    John
     
  6. Drools

    Thread Starter Member

    Jan 6, 2009
    18
    0
    From what I can tell from using the code, while the _delay_ms(x); is going on the switches are not going to be read. As well I'm not sure the "if else" cascading reading of the switches is the proper way to go about coding this.
    I will test this code but still while the delay is in effect I will not be reading the other switches.

    Code ( (Unknown Language)):
    1.  
    2. int main(void)
    3. {
    4.  LanesInit();
    5.  while(1){
    6.    if bit_is_set(PINC,PC0) {PORTD |= (1<<PORTD4);  _delay_ms(5); PORTD &= ~(1<<PORTD4);}
    7.  if bit_is_set(PINC,PC1) {PORTD |= (1<<PORTD5);  _delay_ms(5); PORTD &= ~(1<<PORTD5);}
    8.  if bit_is_set(PINC,PC2) {PORTD |= (1<<PORTD6);  _delay_ms(5); PORTD &= ~(1<<PORTD6);}
    9.  if bit_is_set(PINC,PC3) {PORTD |= (1<<PORTD7); _delay_ms(5); PORTD &= ~(1<<PORTD7);}
    10.  };
    11.  return 0;
    12. }
    13.  
     
  7. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Can you provide a bit more detail about the programs purpose?

    Just a wild guess but with a function call labeled LaneInit(), it sounds like you may be using the processor to judge the winner in a Pinewood Derby contest with 4 lanes to monitor.

    hgmjr
     
  8. Drools

    Thread Starter Member

    Jan 6, 2009
    18
    0
    Actually that is not what I'm doing here but you are close.
     
  9. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    I think I would create a function called ServiceSwitches(). In this function I would read all four switches at one time. You would then be snap-shotting the switch states all at once. You could prioritize the resulting value by using a bit mask to check each switch state in turn. By reading them all at the same time, you should get a fairer judging of which one closed first. If there was more than one then you could rule it as a tie.

    You would call the new function in your while(1) loop once each time around. In the meantime you could perform other functions in the while(1) loop.

    hgmjr
     
  10. Drools

    Thread Starter Member

    Jan 6, 2009
    18
    0
    lets call it a pinewood derby with check points. At each check point I need to send a signal to my main uC so it can calculate times.
     
  11. Drools

    Thread Starter Member

    Jan 6, 2009
    18
    0
  12. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
Loading...