10ms delay in hardware

Thread Starter

Drools

Joined Jan 6, 2009
18
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?
 

hgmjr

Joined Jan 28, 2005
9,027
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?
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
 

Thread Starter

Drools

Joined Jan 6, 2009
18
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.

Rich (BB code):
int main(void)
{
 LanesInit();
 while(1){
  if bit_is_set(PINC,PC0) {  
      PORTD |= (1<<PORTD4);
   _delay_ms(5);
      PORTD &= ~(1<<PORTD4);
        } else if bit_is_set(PINC,PC1) {             
   PORTD |= (1<<PORTD5);
   _delay_ms(5);
      PORTD &= ~(1<<PORTD5);
        } else if bit_is_set(PINC,PC2) {      
   PORTD |= (1<<PORTD6);
   _delay_ms(5);
      PORTD &= ~(1<<PORTD6);             
        } else if bit_is_set(PINC,PC3) {              
   PORTD |= (1<<PORTD7);
   _delay_ms(5);
      PORTD &= ~(1<<PORTD7);             
        }
 };
 return 0;
}
 

hgmjr

Joined Jan 28, 2005
9,027
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
 

jpanhalt

Joined Jan 18, 2008
11,087
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.



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
 

Thread Starter

Drools

Joined Jan 6, 2009
18
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.

Rich (BB code):
int main(void)
{
 LanesInit();
 while(1){
   if bit_is_set(PINC,PC0) {PORTD |= (1<<PORTD4);  _delay_ms(5); PORTD &= ~(1<<PORTD4);} 
 if bit_is_set(PINC,PC1) {PORTD |= (1<<PORTD5);  _delay_ms(5); PORTD &= ~(1<<PORTD5);} 
 if bit_is_set(PINC,PC2) {PORTD |= (1<<PORTD6);  _delay_ms(5); PORTD &= ~(1<<PORTD6);} 
 if bit_is_set(PINC,PC3) {PORTD |= (1<<PORTD7); _delay_ms(5); PORTD &= ~(1<<PORTD7);}
 };
 return 0;
}
 

hgmjr

Joined Jan 28, 2005
9,027
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
 

hgmjr

Joined Jan 28, 2005
9,027
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
 

Thread Starter

Drools

Joined Jan 6, 2009
18
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.
 
Top