Electronic – How to control interrupt using timer in microcontroller

8051cmicrocontroller

Hi I am using 8051 microcontroller. I do have a digital Water Meter which gives binary 0 1 0 1 type data.
I attached it with 8051 INT1 so that i can get interrupt. Now when ever water flow through meter it will start sending interrupt (pulses of 0101) to 8051 INT1.
Now i want to count total pulses and send it.

For that i am using this program in Kiel in C language : [2nd Updated]

#include<reg51.h> // include at89x51 . h
#include<stdio.h>// include stdio . h
#include<stdlib.h>// include stdlib . h

unsigned long  value,x;
unsigned long check;
unsigned long time_overflow_count=0;
void initialize_GSM_modem(void);
void initialize_serialcommunication(void);
unsigned char Command_CMGF[]="AT+CMGF=1\r"; 
// AT+CMGF for selecting Text Mode
unsigned char CtrlZ=0x1A;                   
// CTRL+Z for sedning SMS after the message has been entered
unsigned char Command_CMGS[]="AT+CMGS=\"+9xxxxxxxxx\"\r"; 
// recepient mobile number
unsigned char Command_AT[]="AT\r";
unsigned char msg02[]="Hello!";

unsigned char buf[10]={0};


void send(void)interrupt 1
{
time_overflow_count=time_overflow_count+1;
if (time_overflow_count==5){
if(value==x){

sprintf((char*)buf, "R %lu", value);

time_overflow_count=0;

initialize_GSM_modem();
value=0;
}
}
TR0=1;
}

void input_counting(void) interrupt 2
{
TR0=0;
TL0=0x00;
TH0=0x00;

value=value+1;
TR0=1;

}


void main (void) {

TMOD = 0x21;
TH1 = 0xFD;
TL0=0x55;
TH0=0x55;
SCON = 0x50;
TR1=1;
EX1=1;///Enable external intrrupt 1
EA=1;
IE1=1;
IT1=1;
PX1=1;
ET0=1;

TI=1;
while(1)
{
x=value;
}
}

void delay(void){
unsigned int i;
for(i=0;i<50;i++);
}


 void delay2(void){
unsigned long i;
for(i=0;i<15000;i++);
}

 void initialize_GSM_modem(void)
 {
 delay2();
puts(Command_CMGS);
delay2();
puts((char *)buf);
delay2();

while(!TI); TI = 0;SBUF = 0x1A;
 }

*Updated :*So using this I'm trying to get a timer interrupt which checks when there is no pulses for some time interval then it assumes that meter flow is complete and send the message.

But there an error : I don't know why but our program keeps on sending continues messages for a number of times even if I don't start water meter. If I start water meter it sends the total value at stop and if I don't, it keeps sending 0 at regular interval

What I want is that it waits for water flow (or interrupt to start) and then checks for last value and send it only one time.

Next time I start the meter, it should wait and send the value again, but it should not keep on sending 0s at regular intervals.

UPDATE : I have updated the code and its working fine but its not working as i wish

Please Suggest

Thanks

Best Answer

It sounds like your underlying architectural flaw is that you have the receiving of pulses coupled to sending out the flow rate or accumulated water information. Also, make sure that this water meter either produces clean digital pulses already, or that you debounce the signal in case it is just from a mechanical switch.

In the most general case where you have to debounce the water pulses, don't interrupt on the pulses at all. Interrupt regularly from a timer. This needs to be a minimum of 10s of times faster than the pulses at the maximum flow rate. The interrupt routine will require a minimum number of consecutive high or low states before considering the debounced signal to have changed to the new state. Once that happens, it increments a counter. Microcontrollers are much faster than water meters, especially mechanical ones, so interrupting fast enough should be no problem. Usually a 1 ms interrupt is good enough for this, and then you can use it for other system timing.

Now you can periodically send the counter value or any accumulated delta on ansynchronously. To avoid contention over the counter with the interrupt routine, the counter the interrupt routine increments can be a single byte. The foreground code keeps it own copy of the last known value of that byte. It periodically reads the interrupt routine counter, compares it to the last known value, processes any new ticks the difference represents, then updates the last known value. As long as the foreground routine does this often enough so that the single byte counter can't wrap between samples, no data will be lost.

The foreground code can then decide when to send information. This can be based on a timer tick and/or when there is new information to send.

Related Topic