Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Flow meter code not working

Status
Not open for further replies.

baileychic

Advanced Member level 3
Advanced Member level 3
Joined
Aug 2, 2017
Messages
728
Helped
56
Reputation
112
Reaction score
57
Trophy points
28
Visit site
Activity points
7,033
My flow meter code is not working properly. I have to multiply the count of the TMR1 register by 2 to get correct value. Why is it ?

This is my code. PIC18F26K22 is running at XT 4 MHz.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "float2ascii.h"
 
// LCD module connections
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;
 
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
 
// strings
const code char txt1[] = "   Flow Meter   ";
const code char txt2[] = "dL/ds: ";
char txt[32];
 
typedef struct {
    unsigned long pulses_per_sec;
    unsigned char one_sec_delay_counter;
    unsigned char one_second_delay_count;
    double liters_per_sec;
    double scaling_factor;
} FLOW_METER_TYPE;
 
FLOW_METER_TYPE my_flow_meter;
 
//Timer0
//Prescaler 1:8; TMR0 Preload = 3036; Actual Interrupt Time : 500 ms
void InitTimer0() {
    T0CON = 0x82;
    TMR0H = 0x0B;
    TMR0L = 0xDC;
    GIE_bit = 1;
    TMR0IE_bit = 1;
}
 
void Interrupt(){
    if((TMR0IE_bit) && (TMR0IF_bit)) {
       TMR0IF_bit = 0;
       TMR0H = 0x0B;
       TMR0L = 0xDC;
       //Enter your code here
       if(++my_flow_meter.one_sec_delay_counter >= my_flow_meter.one_second_delay_count) {
            TMR1ON_bit = 0;
            my_flow_meter.one_sec_delay_counter = 0;
            TMR0IE_bit = 0;
       }
    }
 
    if((TMR1IE_bit) && (TMR1IF_bit)) {
        TMR1IF_bit = 0;
    }
}
 
 
char *CopyConst2Ram(char * dest, const code char *src) {
    char *d;
 
    d = dest;
 
    for(;*dest++ = *src++;);
 
    return d;
}
 
void main(void) {
 
    CM1CON0 = 0x00;
    CM2CON0 = 0x00;
 
    ANSELA = 0x00;
    ANSELB = 0x00;
    ANSELC = 0x00;
 
    TRISA = 0x00;
    TRISB = 0x00;
    TRISC = 0x01;
 
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
 
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
 
    Delay_ms(200);
 
    Lcd_Init();
    Lcd_Cmd(_LCD_CURSOR_OFF);
    Lcd_Cmd(_LCD_CLEAR);
 
    //Lcd_Out(1,1,CopyConst2Ram(txt, txt1));
    Lcd_Out(2,1,CopyConst2Ram(txt, txt2));
 
    T1CON = 0b10000100;
    T1GCON = 0x00;
 
    my_flow_meter.scaling_factor = 1.70068e-4;
    
    PWM1_Init(588);
    PWM1_Set_Duty(127);
    PWM1_Start();
 
    while (1) {
 
           TMR1H = 0;
           TMR1L = 0;
           InitTimer0();
           TMR1ON_bit = 1;
           while(TMR1ON_bit);
           my_flow_meter.pulses_per_sec = (unsigned long)(((unsigned int)(TMR1H << 8) + TMR1L) * 2);
           my_flow_meter.liters_per_sec = (double)my_flow_meter.pulses_per_sec * my_flow_meter.scaling_factor;
           Float2Ascii(my_flow_meter.liters_per_sec, txt, 5);
           strcat(txt,"   ");
           Lcd_Out(2,8,txt);
           Float2Ascii((double)my_flow_meter.pulses_per_sec, txt, 2);
           strcat(txt,"   ");
           Lcd_Out(1,1,txt);
    }
}



This is the screenshot of simulation.
 

Attachments

  • flow meter 03.png
    flow meter 03.png
    56 KB · Views: 219
Last edited:

Hi,

multiply with what value?
A random calibration value?

Klaus
 

Unless you have posted the question just to show this project, in other words you are just asking "why a physical quantity liters_per_sec is not exactly the same value of the current timer pulses_ per_ sec ?"
 

Here is the datasheet of the flow sensor.

Calculation is like this.

Max flow is 6Ltr/min = 6Ltr/60sec and so for 1 sec max flow is 0.1Ltr.

For 1 Ltr max pulses is 5880.

So, for 0.1 Ltr max pulses is 588.

max 0.1 Ltr flows in 1 sec and so to convert 588 to 0.1 the magic number is

588 * x = 0.1

x = 0.1 / 588 = 1.70068e-4

PIC18F26K22 is used. Why there is a need to multiply the value (count value) in TMR1 register with 2 to get correct reading ?

I have attached the flow meter mikroC PRO PIC project.

Edit:

Found the bug and fixed it and it is working fine now.

Had to initialize this variable.

Code:
my_flow_meter.one_second_delay_count = 2;

Thank you all for helping.
 

Attachments

  • flow sensor.pdf
    167.1 KB · Views: 163
  • PIC18F26K22 - Flow Meter.rar
    27.4 KB · Views: 147
Last edited:

@KlausST

I already fixed it. It was mentioned in my previous post. Here is the final project.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "float2ascii.h"
 
// LCD module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RD0_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D7 at RD3_bit;
 
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISD0_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISD3_bit;
// End LCD module connections
 
// strings
const code char txt1[] = "     Flow Meter";
const code char txt2[] = "dL/ds  : ";
const code char txt3[] = "dL/dm  : ";
const code char txt4[] = "Pulse/s: ";
char txt[32];
 
typedef struct {
    double pulses_per_sec;
    unsigned char one_sec_delay_counter;
    unsigned char one_second_delay_count;
    double liters_per_sec;
    double liters_per_min;
    double scaling_factor;
    double previous_pulses_per_sec;
} FLOW_METER_TYPE;
 
FLOW_METER_TYPE my_flow_meter;
 
//Timer0
//Prescaler 1:256; TMR0 Preload = 61; Actual Interrupt Time : 49.92 ms
void InitTimer0() {
    OPTION_REG = 0x87;
    TMR0 = 61;
    INTCON = 0xA0;
}
 
void Interrupt() {
    if((TMR0IE_bit) && (TMR0IF_bit)) {
       TMR0IF_bit = 0;
       TMR0 = 61;
       //Enter your code here
       if(++my_flow_meter.one_sec_delay_counter >= my_flow_meter.one_second_delay_count) {
            TMR1ON_bit = 0;
            my_flow_meter.one_sec_delay_counter = 0;
            TMR0IE_bit = 0;
       }
    }
    
    if((TMR1IE_bit) && (TMR1IF_bit)) {
        TMR1IF_bit = 0;
    }
}
 
 
char *CopyConst2Ram(char * dest, const code char *src) {
    char *d;
 
    d = dest;
 
    for(;*dest++ = *src++;);
 
    return d;
}
 
void main(void) {
 
    CMCON = 0x07;
 
    ADCON0 = 0x40;
    ADCON1 = 0x8F;
 
    TRISA = 0x00;
    TRISB = 0x00;
    TRISC = 0x01;
    TRISD = 0x00;
    TRISE = 0x00;
 
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    PORTE = 0x00;
    
    Delay_ms(200);
 
    Lcd_Init();
    Lcd_Cmd(_LCD_CURSOR_OFF);
    Lcd_Cmd(_LCD_CLEAR);
 
    Lcd_Out(1,1,CopyConst2Ram(txt, txt1));
    Lcd_Out(2,1,CopyConst2Ram(txt, txt2));
    Lcd_Out(3,1,CopyConst2Ram(txt, txt3));
    Lcd_Out(4,1,CopyConst2Ram(txt, txt4));
    
    Float2Ascii(my_flow_meter.liters_per_sec, txt, 3);
    strcat(txt," Lt/s ");
    Lcd_Out(2,10,txt);
    Float2Ascii(my_flow_meter.liters_per_min, txt, 3);
    strcat(txt," Lt/m ");
    Lcd_Out(3,10,txt);
    Float2Ascii((double)my_flow_meter.pulses_per_sec, txt, 1);
    strcat(txt,"  ");
    Lcd_Out(4,10,txt);
    
    T1CON = 0x06;
    
    my_flow_meter.previous_pulses_per_sec = 0xFFFFFFFF;
    my_flow_meter.one_second_delay_count = 20;
    my_flow_meter.scaling_factor = 1.700680e-4;
    
    InitTimer0();
    
    while (1) {
           TMR1H = 0;
           TMR1L = 0;
           TMR0 = 61;
           TMR0IE_bit = 1;
           TMR1ON_bit = 1;
           while(TMR1ON_bit);
           my_flow_meter.pulses_per_sec = (double)((double)((unsigned int)(TMR1H << 8) + TMR1L) * 1.0);
           
           if(my_flow_meter.previous_pulses_per_sec != my_flow_meter.pulses_per_sec) {
               my_flow_meter.liters_per_sec = (double)my_flow_meter.pulses_per_sec * my_flow_meter.scaling_factor;
               my_flow_meter.liters_per_min = my_flow_meter.liters_per_sec * 60.0;
               Float2Ascii(my_flow_meter.liters_per_sec, txt, 3);
               strcat(txt," Lt/s ");
               Lcd_Out(2,10,txt);
               Float2Ascii(my_flow_meter.liters_per_min, txt, 3);
               strcat(txt," Lt/m ");
               Lcd_Out(3,10,txt);
               Float2Ascii((double)my_flow_meter.pulses_per_sec, txt, 1);
               strcat(txt,"  ");
               Lcd_Out(4,10,txt);
               
               my_flow_meter.previous_pulses_per_sec = my_flow_meter.pulses_per_sec;
           }
    }
}

 

Attachments

  • Flow Meter.rar
    21.7 KB · Views: 137
  • flow meter 06.png
    flow meter 06.png
    44.6 KB · Views: 229

Here is my Flow Meter updated project with my Proteus Flow Sensor VSM model. This VSM model is made by me. I am not posting any copy righted material here.
 

Attachments

  • Flow Meter + Flow Sensor Proteus VSM Model.rar
    207 KB · Views: 153
  • Flow Meter.png
    Flow Meter.png
    51.4 KB · Views: 224

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top