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] Numbers with decimals without float

Status
Not open for further replies.
Try this code.


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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "float2ascii.h"
 
// Lcd module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_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;
 
#define method1
//#define method2
                                        
char strDisplay[30];
char unit[] = " G ";
 
double zMax = -3.0;
double xMax = -3.0;
double gVal = 0.0;
 
char i = 0;
 
double ReadAxis(char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
 
      while(i < 2) {
            analogvalue += ADC_Read(channel);
            Delay_us(10);
            ++i;
      }
 
      //return ((analogValue / 2.0) * 9.091 / 1023.0) - 3.0;
      return (analogValue / 225.06) - 3.01;
}
 
char interruptFlag = 0;
 
void interrupt() {
 
    #ifdef method1
        if(INTF_bit) {  //If button pressed
            interruptFlag = 1;          
        }
    #endif
 
    #ifdef method2
        if((INTF_bit) && (!INTEDG_bit)) {   //If button pressed
            INTEDG_bit = 1;         
        }
        else if((INTF_bit) && (INTEDG_bit)) {   //If button released
            interruptFlag = 1;
            INTEDG_bit = 0;         
        }
    #endif
 
    INTF_bit = 0;
}
 
double ReadAxis (char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
    
      while(i < 2) {
      analogvalue += ADC_Read(channel);
      Delay_us(10);
          ++i;
      }
 
      //return ((analogValue / 2.0) * 9.091 / 1023.0) - 3.0;
      return (analogValue / 225.1) - 3.0;
}
 
void main() {
 
      OSCCON = 0b01111010;     
      OSCSTAT = 0b00011001;
      OSCTUNE = 0b00011111;
      
      ADCON1 = 0b10000011;     
      
      DACCON0 = 0;          
      
      SRCON0 = 0;           
      
      CM1CON0 = 0;          
      CM2CON0 = 0;          
      
      TRISA  = 0b00000110;     
      TRISB  = 0b00000001;     
      ANSELA = 0b00000110;     
      ANSELB = 0b00000000;     
      
      Lcd_Init();
      Lcd_Cmd(_LCD_CURSOR_OFF);              
      Lcd_Cmd(_LCD_CLEAR);     
 
      OPTION_REG = 0b10000000;
      INTCON = 0b11010000;
 
      while(1) {                                  
      
 
        if(interruptFlag) {
 
        zMax = 0.0;
            xMax = 0.0;
            oldZanalogvalue = 0.0;
            oldXanalogvalue = 0.0;
 
        interruptFlag = 0;
            }
 
            if(i == 1) {                          
                
                gVal = ReadAxis(1);   
                Float2Ascii(gVal, strDisplay, 2);   
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay); 
 
                if(gVal > xMax) {             
                      xMax = gVal;
                      Float2Ascii(xMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);           
                }
                
                gVal = 0;                                
                                
            }
            
                        
            if(i == 2) {
            
                gVal = ReadAxis(2);   
                Float2Ascii(gVal, strDisplay, 2);
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay);
 
                if(gVal > zMax) {
                      zMax = gVal;
                      Float2Ascii(zMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);
                }
                
                gVal = i = 0;
            }
            
            i++;
 
            Delay_ms(100);
      }
}

 

Thank you Milan for your help. I've learned a lot. I have few questions.
- How could I clear display anytime I want? It will allow me to call Lcd_Cmd only in one place. Even though I make own procedure for display clear I can only call it inside one procedure/funtion.
- I need two pushbuttons. According to datasheet all RB ports are interrupt ports. How should this be done properly? I've tested the following way but it seems to work only intermittenly...
Code:
void interrupt(void){
     if (IOCBF.IOCBF7)	// RB7 interrupt
      {
		// Do stuff
      }
       IOCBF.IOCBF7 = 0;        // Clear interrupt flag

      if (IOCBF.IOCBF6)	// RB6 interrupt
      {
		// Do stuff
      }
       IOCBF.IOCBF6 = 0;        // Clear interrupt flag
       INTF_bit = 0;
 }
- In your example you only set one parameter inside interrupt handling and did all the necessary actions in other procedure. Does this mean you shouldn't do much things inside interrupt?
 

Try this code. LCD connections are changed. RB0 and RB7 are for buttons. When button on RB7 is pressed then RB7 goes low.


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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#include "float2ascii.h"
 
// Lcd module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB1_bit;
sbit LCD_D5 at RB2_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB4_bit;
 
sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB1_bit;
sbit LCD_D5_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
 
#define method1
//#define method2
                                        
char strDisplay[30];
char unit[] = " G ";
 
double zMax = -3.0;
double xMax = -3.0;
double gVal = 0.0;
 
char i = 0;
 
char clrLcdFlag = 0;
 
double ReadAxis(char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
 
      while(i < 2) {
            analogvalue += ADC_Read(channel);
            Delay_us(10);
            ++i;
      }
 
      //return ((analogValue / 2.0) * 9.091 / 1023.0) - 3.0;
      return (analogValue / 225.06) - 3.01;
}
 
char interruptFlag = 0;
 
void interrupt() {
 
    #ifdef method1
        if(INTF_bit) {  //If button pressed
            interruptFlag = 1; 
            INTF_bit = 0;         
        }
    #endif
 
    #ifdef method2
        if((INTF_bit) && (!INTEDG_bit)) {   //If button pressed
            INTEDG_bit = 1;
            INTF_bit = 0;         
        }
        else if((INTF_bit) && (INTEDG_bit)) {   //If button released
            interruptFlag = 1;
            INTEDG_bit = 0; 
            INTF_bit = 0;        
        }
    #endif
 
    if((IOCF_bit) && (!RB7_bit)) {
        clrLcdFlag = 1;
        IOCF_bit = 0;
    }
}
 
double ReadAxis (char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
    
      while(i < 2) {
      analogvalue += ADC_Read(channel);
      Delay_us(10);
          ++i;
      }
 
      //return ((analogValue / 2.0) * 9.091 / 1023.0) - 3.0;
      return (analogValue / 225.1) - 3.0;
}
 
void main() {
 
      OSCCON = 0b01111010;     
      OSCSTAT = 0b00011001;
      OSCTUNE = 0b00011111;
      
      ADCON1 = 0b10000011;     
      
      DACCON0 = 0;          
      
      SRCON0 = 0;           
      
      CM1CON0 = 0;          
      CM2CON0 = 0;          
      
      TRISA  = 0b00000110;     
      TRISB  = 0b10000001;     
      ANSELA = 0b00000110;     
      ANSELB = 0b00000000;     
      
      Lcd_Init();
      Lcd_Cmd(_LCD_CURSOR_OFF);              
      Lcd_Cmd(_LCD_CLEAR);     
 
      OPTION_REG = 0b10000000;
      INTCON = 0b11011000;
 
      while(1) {                                  
      
    if(clrLcdFlag) {
        LCD_Cmd(_LCD_CLEAR);
        clrLcdFlag = 0;
    }
 
        if(interruptFlag) {
 
        zMax = 0.0;
            xMax = 0.0;
            oldZanalogvalue = 0.0;
            oldXanalogvalue = 0.0;
 
        interruptFlag = 0;
            }
 
            if(i == 1) {                          
                
                gVal = ReadAxis(1);   
                Float2Ascii(gVal, strDisplay, 2);   
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay); 
 
                if(gVal > xMax) {             
                      xMax = gVal;
                      Float2Ascii(xMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);           
                }
                
                gVal = 0;                                
                                
            }
            
                        
            if(i == 2) {
            
                gVal = ReadAxis(2);   
                Float2Ascii(gVal, strDisplay, 2);
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay);
 
                if(gVal > zMax) {
                      zMax = gVal;
                      Float2Ascii(zMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);
                }
                
                gVal = i = 0;
            }
            
            i++;
 
            Delay_ms(100);
      }
}



- - - Updated - - -

This is another version.


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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include "float2ascii.h"
 
// Lcd module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB1_bit;
sbit LCD_D5 at RB2_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB4_bit;
 
sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB1_bit;
sbit LCD_D5_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
 
#define method1
//#define method2
                                        
char strDisplay[30];
char unit[] = " G ";
 
double zMax = -3.0;
double xMax = -3.0;
double gVal = 0.0;
 
char i = 0;
 
char clrLcdFlag = 0;
 
double ReadAxis(char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
 
      while(i < 2) {
            analogvalue += ADC_Read(channel);
            Delay_us(10);
            ++i;
      }
 
      //return ((analogValue / 2.0) * 9.091 / 1023.0) - 3.0;
      return (analogValue / 225.06) - 3.01;
}
 
char interruptFlag = 0;
 
void interrupt() {
 
    #ifdef method1
        if(INTF_bit) {  //If button pressed
            interruptFlag = 1; 
            INTF_bit = 0;         
        }
    #endif
 
    #ifdef method2
        if((INTF_bit) && (!INTEDG_bit)) {   //If button pressed
            INTEDG_bit = 1;
            INTF_bit = 0;         
        }
        else if((INTF_bit) && (INTEDG_bit)) {   //If button released
            interruptFlag = 1;
            INTEDG_bit = 0; 
            INTF_bit = 0;        
        }
    #endif
 
    if((IOCF_bit) && (!RB7_bit)) {
        clrLcdFlag = 1;
        IOCF_bit = 0;
    }
 
    if(IOCBF7_bit) {
        clrLcdFlag = 1;
        IOCBF7_bit = 0;
    }
}
 
double ReadAxis (char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
    
      while(i < 2) {
      analogvalue += ADC_Read(channel);
      Delay_us(10);
          ++i;
      }
 
      //return ((analogValue / 2.0) * 9.091 / 1023.0) - 3.0;
      return (analogValue / 225.1) - 3.0;
}
 
void main() {
 
      OSCCON = 0b01111010;     
      OSCSTAT = 0b00011001;
      OSCTUNE = 0b00011111;
      
      ADCON1 = 0b10000011;     
      
      DACCON0 = 0;          
      
      SRCON0 = 0;           
      
      CM1CON0 = 0;          
      CM2CON0 = 0;          
      
      TRISA  = 0b00000110;     
      TRISB  = 0b10000001;     
      ANSELA = 0b00000110;     
      ANSELB = 0b00000000;
      IOCBP = 0x00;
      IOCBN = 0x80;      
      IOCBF = 0x00;
 
      Lcd_Init();
      Lcd_Cmd(_LCD_CURSOR_OFF);              
      Lcd_Cmd(_LCD_CLEAR);     
 
      OPTION_REG = 0b10000000;
      INTCON = 0b11011000;
 
      while(1) {                                  
      
    if(clrLcdFlag) {
        LCD_Cmd(_LCD_CLEAR);
        clrLcdFlag = 0;
    }
 
        if(interruptFlag) {
 
        zMax = 0.0;
            xMax = 0.0;
            oldZanalogvalue = 0.0;
            oldXanalogvalue = 0.0;
 
        interruptFlag = 0;
            }
 
            if(i == 1) {                          
                
                gVal = ReadAxis(1);   
                Float2Ascii(gVal, strDisplay, 2);   
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay); 
 
                if(gVal > xMax) {             
                      xMax = gVal;
                      Float2Ascii(xMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);           
                }
                
                gVal = 0;                                
                                
            }
            
                        
            if(i == 2) {
            
                gVal = ReadAxis(2);   
                Float2Ascii(gVal, strDisplay, 2);
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay);
 
                if(gVal > zMax) {
                      zMax = gVal;
                      Float2Ascii(zMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);
                }
                
                gVal = i = 0;
            }
            
            i++;
 
            Delay_ms(100);
      }
}

 
Does this mean you shouldn't do much things inside interrupt?

There is no functional reason why code inside an ISR has to be kept to a minimum but there are good reasons why it is good practise to do so. In most processors, while an interrupt is being serviced (you are in the ISR) any further interrupts are inhibited. This is to prevent the ISR being called from within itself if a subsequent interrupt is triggered. Normally, the running ISR finishes and if there is another pending interrupt it is re-entered to service it so although it may be called several times only one ISR instance runs at a time. If you do things inside an ISR that can slow it down (delays are the worst thing you can put in an ISR) there is a danger that a second pending interrupt request is overwritten by a third or even greater request. There is a danger that your code is not able to see these later requests and fails to operate as it should.

If you keep ISR code as short as possible it helps to minimize the chance of missing interrupts. The best thing to do is simply set a flag in a variable to say the interrupt was triggered then clean up and exit the ISR. You can then check and reset the flag in your main code while still letting the interrupt system have the fast response time it needs.

Brian.
 
I don't remember to have ever used an interrupt input for a button, except for wakeup from power saving modes.
 
Test this code.


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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include "float2ascii.h"
 
// Lcd module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB1_bit;
sbit LCD_D5 at RB2_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB4_bit;
 
sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB1_bit;
sbit LCD_D5_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
 
#define method1
//#define method2
                                        
char strDisplay[30];
char unit[] = " G ";
 
double zMax = -3.0;
double xMax = -3.0;
double gVal = 0.0;
 
char i = 0;
 
char myFlags = 0;
 
#define INTERRUPT_FLAG myFlags.F0
 
 
double ReadAxis(char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
 
      while(i < 2) {
            analogvalue += ADC_Read(channel);
            Delay_us(10);
            ++i;
      }
 
      //return ((analogValue / 2.0) * 9.091 / 1023.0) - 3.0;
      return (analogValue / 225.06) - 3.01;
}
 
char interruptFlag = 0;
 
void interrupt() {
 
    INTERRUPT_FLAG = 1;
}
 
double ReadAxis (char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
    
      while(i < 2) {
      analogvalue += ADC_Read(channel);
      Delay_us(10);
          ++i;
      }
 
      //return ((analogValue / 2.0) * 9.091 / 1023.0) - 3.0;
      return (analogValue / 225.1) - 3.0;
}
 
void Clear_Vars() {
 
    zMax = 0.0;
        xMax = 0.0;
        oldZanalogvalue = 0.0;
        oldXanalogvalue = 0.0;
}
 
void main() {
 
      OSCCON = 0b01111010;     
      OSCSTAT = 0b00011001;
      OSCTUNE = 0b00011111;
      
      ADCON1 = 0b10000011;     
      
      DACCON0 = 0;          
      
      SRCON0 = 0;           
      
      CM1CON0 = 0;          
      CM2CON0 = 0;          
      
      TRISA  = 0b00000110;     
      TRISB  = 0b10000001;     
      ANSELA = 0b00000110;     
      ANSELB = 0b00000000;
      IOCBP = 0x00;
      IOCBN = 0x80;      
      IOCBF = 0x00;
 
      Lcd_Init();
      Lcd_Cmd(_LCD_CURSOR_OFF);              
      Lcd_Cmd(_LCD_CLEAR);     
 
      OPTION_REG = 0b10000000;
      INTCON = 0b11011000;
 
      while(1) {                                  
      
 
        if(INTERRUPT_FLAG) {
 
            #ifdef method1
                    if(INTF_bit) {  //If button pressed
                            Clear_Vars();
                            INTF_bit = 0;         
                }
                #endif
 
                #ifdef method2
                    if((INTF_bit) && (!INTEDG_bit)) {   //If button pressed
                            INTEDG_bit = 1;
                            INTF_bit = 0;         
                }
                else if((INTF_bit) && (INTEDG_bit)) {   //If button released
                    Clear_Vars();
                            INTEDG_bit = 0; 
                            INTF_bit = 0;        
                }
                #endif
 
                if((IOCF_bit) && (!RB7_bit)) {
                LCD_Cmd(_LCD_CLEAR);
                    IOCF_bit = 0;
                }
 
                if(IOCBF7_bit) {
                    LCD_Cmd(_LCD_CLEAR);
                    IOCBF7_bit = 0;
                }
 
            INTERRUPT_FLAG = 0;
        }
 
 
            if(i == 1) {                          
                
                gVal = ReadAxis(1);   
                Float2Ascii(gVal, strDisplay, 2);   
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay); 
 
                if(gVal > xMax) {             
                      xMax = gVal;
                      Float2Ascii(xMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);           
                }
                
                gVal = 0;                                
                                
            }
            
                        
            if(i == 2) {
            
                gVal = ReadAxis(2);   
                Float2Ascii(gVal, strDisplay, 2);
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay);
 
                if(gVal > zMax) {
                      zMax = gVal;
                      Float2Ascii(zMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);
                }
                
                gVal = i = 0;
            }
            
            i++;
 
            Delay_ms(100);
      }
}

 
That INTF_bit doesn't work. It freezes the MCU completely. RB7 does work.

Edit:
Indeed, I just added to main while loop checking of the state of buttons and do there necessary. Works like a treat and much simpler.. Thanks for you all.
 
Last edited:

When does it freeze ? If you press button on RB0, press and hold button on RB0, press and release button on RB0 ?
 

When does it freeze ? If you press button on RB0, press and hold button on RB0, press and release button on RB0 ?
Instantly when I press the button. This seems to be the freezer: if(INTF_bit)
 

Try this.


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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include "float2ascii.h"
 
// Lcd module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB1_bit;
sbit LCD_D5 at RB2_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB4_bit;
 
sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB1_bit;
sbit LCD_D5_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
 
#define method1
//#define method2
                                        
char strDisplay[30];
char unit[] = " G ";
 
double zMax = -3.0;
double xMax = -3.0;
double gVal = 0.0;
 
char i = 0;
 
char myFlags = 0;
 
#define INTERRUPT_FLAG myFlags.F0
 
 
double ReadAxis(char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
 
      while(i < 2) {
            analogvalue += ADC_Read(channel);
            Delay_us(10);
            ++i;
      }
 
      return (analogValue / 225.06) - 3.01;
}
 
void interrupt() {
 
    INTERRUPT_FLAG = 1;
}
 
double ReadAxis (char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
    
      while(i < 2) {
      analogvalue += ADC_Read(channel);
      Delay_us(10);
          ++i;
      }
 
      //return ((analogValue / 2.0) * 9.091 / 1023.0) - 3.0;
      return (analogValue / 225.1) - 3.0;
}
 
void Clear_Vars() {
 
    zMax = 0.0;
        xMax = 0.0;
        oldZanalogvalue = 0.0;
        oldXanalogvalue = 0.0;
}
 
void main() {
 
      OSCCON = 0b01111010;     
      OSCSTAT = 0b00011001;
      OSCTUNE = 0b00011111;
      
      ADCON1 = 0b10000011;     
      
      DACCON0 = 0;          
      
      SRCON0 = 0;           
      
      CM1CON0 = 0;          
      CM2CON0 = 0;          
      
      TRISA  = 0b00000110;     
      TRISB  = 0b10000001;     
      ANSELA = 0b00000110;     
      ANSELB = 0b00000000;
      IOCBP = 0x00;
      IOCBN = 0x80;      
      IOCBF = 0x00;
 
      Lcd_Init();
      Lcd_Cmd(_LCD_CURSOR_OFF);              
      Lcd_Cmd(_LCD_CLEAR);     
 
      OPTION_REG = 0b10000000;
      INTCON = 0b11011000;
 
      while(1) {                                  
      
 
        if(INTERRUPT_FLAG) {
 
            #ifdef method1
                    if(INTF_bit) {  //If button pressed
                            Clear_Vars();                                     
                }
                #endif
 
                #ifdef method2
                    if((INTF_bit) && (!INTEDG_bit)) {   //If button pressed
                            INTEDG_bit = 1;                                  
                }
                else if((INTF_bit) && (INTEDG_bit)) {   //If button released
                            Clear_Vars();
                            INTEDG_bit = 0;                                 
                }
                #endif
 
                if((IOCF_bit) && (!RB7_bit)) {
                LCD_Cmd(_LCD_CLEAR);
                    IOCF_bit = 0;
                }
 
                if(IOCBF7_bit) {
                    LCD_Cmd(_LCD_CLEAR);
                    IOCBF7_bit = 0;
                }
 
        INTF_bit = 0;
            INTERRUPT_FLAG = 0;
        }
 
 
            if(i == 1) {                          
                
                gVal = ReadAxis(1);   
                Float2Ascii(gVal, strDisplay, 2);   
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay); 
 
                if(gVal > xMax) {             
                      xMax = gVal;
                      Float2Ascii(xMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);           
                }
                
                gVal = 0;                                
                                
            }
            
                        
            if(i == 2) {
            
                gVal = ReadAxis(2);   
                Float2Ascii(gVal, strDisplay, 2);
                
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay);
 
                if(gVal > zMax) {
                      zMax = gVal;
                      Float2Ascii(zMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);
                }
                
                gVal = i = 0;
            }
            
            i++;
 
            Delay_ms(100);
      }
}

 
Hai everyone....
I am using like this

void float_disp(int value)
{
d1=value/100;
d2=value%100;
d3=d2/10;
d4=d2%10;
lcd_data(d1);
lcd_data(0x2e);
lcd_data(d3);
lcd_data(d4);
}
 
Last edited:
I think this can be the final code which doesn't need any more changes.


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
148
149
150
151
152
153
154
155
156
#include "float2ascii.h"
 
// Lcd module connections
sbit LCD_RS at RB5_bit;
sbit LCD_EN at RB6_bit;
sbit LCD_D4 at RB1_bit;
sbit LCD_D5 at RB2_bit;
sbit LCD_D6 at RB3_bit;
sbit LCD_D7 at RB4_bit;
 
sbit LCD_RS_Direction at TRISB5_bit;
sbit LCD_EN_Direction at TRISB6_bit;
sbit LCD_D4_Direction at TRISB1_bit;
sbit LCD_D5_Direction at TRISB2_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
 
#define method1
//#define method2
 
char strDisplay[30];
char unit[] = " G ";
double zMax = -3.0;
double xMax = -3.0;
double gVal = 0.0;
char i = 0;
char myFlags = 0;
 
#define INTERRUPT_FLAG myFlags.F0
 
void interrupt() {
    INTERRUPT_FLAG = 1;
}
 
double ReadAxis(char channel) {    // Read Axis values from DE-ACCM3D
 
      char i = 0;
      double analogvalue = 0.0;
 
      while(i < 2) {
            analogvalue += ADC_Read(channel);
            Delay_us(10);
            ++i;
      }
 
      return (analogValue / 225.06) - 3.01;
}
 
void Clear_Vars() {
      zMax = 0.0;
      xMax = 0.0;
}
 
void main() {
 
      OSCCON = 0b01111010;
      OSCSTAT = 0b00011001;
      OSCTUNE = 0b00011111;
 
      ADCON1 = 0b10000011;
 
      DACCON0 = 0;
 
      SRCON0 = 0;
 
      CM1CON0 = 0;
      CM2CON0 = 0;
 
      TRISA  = 0b00000110;
      TRISB  = 0b10000001;
      ANSELA = 0b00000110;
      ANSELB = 0b00000000;
      IOCBP = 0x00;
      IOCBN = 0x80;
      IOCBF = 0x00;
 
      Lcd_Init();
      Lcd_Cmd(_LCD_CURSOR_OFF);
      Lcd_Cmd(_LCD_CLEAR);
 
      OPTION_REG = 0b10000000;
      INTCON = 0b11011000;
 
      while(1) {
 
 
            if(INTERRUPT_FLAG) {
 
                    #ifdef method1
                        if(INTF_bit) {  //If button pressed
                              Clear_Vars();
                    }
                    #endif
 
                    #ifdef method2
                        if((INTF_bit) && (!INTEDG_bit)) {   //If button pressed
                                INTEDG_bit = 1;
                    }
                    else if((INTF_bit) && (INTEDG_bit)) {   //If button released
                            Clear_Vars();
                                INTEDG_bit = 0;
                    }
                    #endif
 
                    if(IOCBF7_bit) {
                        LCD_Cmd(_LCD_CLEAR);
                    }
 
                    INTF_bit = 0;
                    IOCBF7_bit = 0;
                    
                    INTERRUPT_FLAG = 0;
            }
 
 
            if(i == 1) {
 
                gVal = ReadAxis(1);
                Float2Ascii(gVal, strDisplay, 2);
 
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay);
 
                if(gVal > xMax) {
                      xMax = gVal;
                      Float2Ascii(xMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);
                }
 
                gVal = 0;
 
            }
 
 
            if(i == 2) {
 
                gVal = ReadAxis(2);
                Float2Ascii(gVal, strDisplay, 2);
 
            strcat(strDisplay, "G");
            Lcd_Out(1,1,strDisplay);
 
                if(gVal > zMax) {
                      zMax = gVal;
                      Float2Ascii(zMax, strDisplay, 2);
                      Lcd_Out_cp(strDisplay);
                }
 
                gVal = i = 0;
            }
 
            i++;
 
            Delay_ms(100);
      }
}

 
Thanks Milan. I don't know why does it freeze immediately when it goes to line if(INTF_bit). Also those strcat things make extra G's on display. I dumped the idea of interrupt and handle those buttons in main. Nevermind this way it works but it's not the smoothest and simplest. I still got 63% free rom and 65% free ram on that PIC16F1847 chip which is plenty. I added following features to the toggle button: Maximum G values on both axis -> Minimum X values on both axis -> difference between max and min values. Reset button resets all stored values. Values from accelerometer are read very often and stored to variables but display is updated only like 0.1sec+nsec. I'm happy with the results. Here's the code if someone would like to build similar device. I was thinking to add third button to store the values but I don't see much use of it..

Code:
#include "float2ascii.h"

// Lcd module connections
// Channel 1 = X Axis, Channel 2 = Z axis
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB6_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB6_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

sbit reset_button at RB0_bit;
sbit toggle_button at RB7_bit;

#define CALIBRATED_0G_Z        368.00   //this is the analog value for the zero G point for Z
#define CALIBRATED_0G_X        349.00   //this is the analog value for the zero G point for X
#define CALIBRATED_SENSITIVITY  59.77   //this number will convert 10bit analog value
                                        //into Gs
char AxisX[30];
char AxisZ[30];
char maxValX[30];
char maxValZ[30];
char minValX[30];
char minValZ[30];
char xDiffVal[30];
char ZDiffVal[30];
char interruptflag = 0;

double zMax = -3.0;
double xMax = -3.0;
double zMin = 3.0;
double xMin = 3.0;
double gValX = 0.0;
double gValZ = 0.0;
double xDiff = 0.0;
double zDiff = 0.0;
double oldXanalogvalue = 0.0;
double oldZanalogvalue = 0.0;
double tempreading = 0.0;

int temp = 0, i= 0;
char clrLcdFlag = 0;
char WhatInterrupt = 0;

void MyDelay(char time) {                // Delay routines

      switch(time) {
          case 1:
                delay_us(10);
                break;
          case 2:
                delay_ms(5);
                break;
      };
}

double ReadAxis (char channel) {    // Read Axis values from DE-ACCM3D X = 1, Z = 2

      double analogvalue = 0.0;

      analogvalue =  ADC_Read(channel);                        // Read from spesific channel
      MyDelay(1);
      analogvalue += ADC_Read(channel);                       //take an average of 2 readings to reduce noise
      analogvalue /= 2.0;
      if (channel == 1) temp = analogvalue-oldXanalogvalue;
      if (channel == 2) temp = analogvalue-oldZanalogvalue;
      
      if( temp>1 || temp<-1 ) //ignore small changes to make display more readable
      {                                                              //convert analog value into G digits
      if (channel == 1) {
         oldXanalogvalue = analogvalue;
         analogvalue -= CALIBRATED_0G_X;
      }
      if (channel == 2) {
         oldZanalogvalue = analogvalue;
         analogvalue -= CALIBRATED_0G_Z;
      }

      analogvalue *= 100.0;                                  // Multiply by 100 to get more resolution before dividing
      analogvalue /= CALIBRATED_SENSITIVITY;
      return analogvalue;
      } else return 5000;
}

void main() {

      OSCCON = 0b01111010;     // Set internal oscillator to 16mhz
      OSCSTAT = 0b00011001;

      ADCON1 = 0b11010011;        // Set VREF+ to fixed voltage, fosc/2, A/D right justified

      DACCON0.b7 = 0;          // DAC disabled

      SRCON0.b7 = 0;           // SR latch disabled

      CM1CON0.b7 = 0;          // Disable comparator 1
      CM2CON0.b7 = 0;          // Disable comparator 2

      TRISA  = 0b00000110;     //Set RA2 & RA1 as input, others are output
      TRISB  = 0b10000001;     // Set all RB as output except RB7 & RB0
      ANSELA = 0b00000110;     // Set RA1 & RA2 as analog
      ANSELB = 0b00000000;     // Set all B ports as digital

      Lcd_Init();              // Initialize Lcd
      Lcd_Cmd(_LCD_CLEAR);
      Lcd_Cmd(_LCD_CURSOR_OFF);

      
      while(1) {                                 // Endless loop
//------------------------------------------------------------------ Button handing
               if(!Reset_button) {
               while(!Reset_button);
                  zMax = GValZ;
                  xMax = GValX;
                  zMin = GValZ;
                  xMin = GValX;
                  oldZanalogvalue = 0.0;
                  oldXanalogvalue = 0.0;
                  clrLcdFlag = 1;
                }
                if (!Toggle_button) {
                while(!Toggle_button);
                  interruptflag++;
                  clrLcdFlag = 1;
                  if (interruptflag == 3) interruptflag = 0;
                }
                
                if(clrLcdFlag) {
                   LCD_Cmd(_LCD_CLEAR);
                   clrLcdFlag = 0;
                }
// --------------------------------------------------- X Axis reading
                tempreading = ReadAxis(1);
                if (tempreading != 5000)
                {
                gValX = tempreading;
                gValX = gValX/100;
                Float2Ascii(gValX, AxisX, 2);   // Put float value to char and 2 decimal

                if(gValX > xMax) {             // Update maximum X axial G-force
                      xMax = gValX;
                }
                else if (gValX < xMin) {
                      xMin = gValX;
                }
                }
//------------------------------------------------------------------ Z Axis reading
                tempreading = ReadAxis(2);
                if (tempreading != 5000)
                {
                gValZ = tempreading;
                gValZ = gValZ/100;
                Float2Ascii(gValZ, AxisZ, 2);
                
                if(gValZ > zMax) {
                      zMax = gValZ;
                }
                else if (gValZ < zMin) {
                      zMin = gValZ;
                }
                }
//----------------------------------------------------------- Displaying result
                if ( i == 20)                    // Update display on every 20th loop round
                {
                Lcd_Out(1,1,"X=");// Print X axis G-value to first line
                Lcd_out_cp(AxisX);
                Lcd_out_cp("G ");                 // Add G

                if (interruptflag == 0) {
                   Float2Ascii(xMax, maxValX, 2);
                   Lcd_Out(1,10, maxValX);                 // Print maximum registered X axis G force
                   Lcd_out_cp("max");
                   }
                else if (interruptflag == 1) {
                   Float2Ascii(xMin, minValX, 2);
                   Lcd_Out(1,10, minValX);                 // Print minimum registered X axis G force
                   Lcd_out_cp("mi");
                   }
                else if (interruptflag == 2) {
                    xDiff = xMax - xMin;
                    Float2Ascii(xDiff, xDiffVal, 2);
                    Lcd_Out(1,10,xDiffVal);
                    Lcd_Out_Cp("Df");
                   }
                
                Lcd_Out(2,1,"Z=");               // Print Zaxis G-value to second line
                Lcd_out_cp(AxisZ);
                Lcd_out_cp("G ");

                if (interruptflag == 0) {
                   Float2Ascii(zMax, maxValZ, 2);
                   Lcd_Out(2,10,maxValZ);                // Print maximum registered Z axis G force
                   Lcd_out_cp("max");
                   }
                else if (interruptflag == 1) {
                   Float2Ascii(zMin, minValz, 2);
                   Lcd_Out(2,10,minValZ);                // Print minimum registered Z axis G force
                   Lcd_out_cp("mi");
                   }
                else if (interruptflag == 2) {
                    zDiff = zMax - zMin;
                    Float2Ascii(zDiff, zDiffVal, 2);
                    Lcd_Out(2,10,zDiffVal);             // Print difference of max and min registered Z axis G force
                    Lcd_Out_Cp("Df");
                   }
                  i = 0;
                 }
                 
                 i++;
            MyDelay(2);
      }
}
 

If your chip has ADC then you can use a single adc pin for 4X4 or any number of keys keypad.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top