KlausST
Advanced Member level 7
- Joined
- Apr 17, 2014
- Messages
- 26,362
- Helped
- 4,926
- Reputation
- 9,875
- Reaction score
- 5,803
- Trophy points
- 1,393
- Activity points
- 177,531
When using ADC interrupt, why not immediately process the incoming data? You have plenty of time doing this inbetween two samples.This way the reading + processing should not exceed 20ms + 10ms (64 MHz Oscillator) and I will be able to trip the faulty load line within 30ms of fault.
compare stored_ADC value with trip_max
* if bigger: trip SSR
* compare stored_ADC value with trip_min
* if lower: trip SSR
* setup ADC that conversion can be triggered by timer
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 #define Method 0 sbit Chip_Select at LATC0_bit; sbit Chip_Select_Direction at TRISC0_bit; unsigned int adcVal = 0; unsigned int max[8] = {0}; unsigned int min[8] = {0}; unsigned char maxFlag = 0; unsigned char minFlag = 0; double volt = 0.0; double current = 0.0; unsigned int i = 0; char txt[67]; void Select_ADG731_Channel(unsigned char data_) { Chip_Select = 0; SPI1_Write(data_); Chip_Select = 1; } void Clear_Arrays() { memset(max, 0, sizeof(max)); memset(min, 0, sizeof(min)); maxFlag = 0; minFlag = 0; } void main() { OSCCON = 0x73; OSCCON2 - 0x03; OSCTUNE = 0x00; CM1CON0 = 0x00; CM2CON0 = 0x00; SLRCON = 0x00; ADCON0 = 0x00; ADCON1 = 0x00; ADCON2 = 0b10110101; ANSELA = 0x01; ANSELB = 0x00; ANSELC = 0x00; ANSELD = 0x00; ANSELE = 0x00; TRISA = 0xC1; TRISB = 0x00; TRISC = 0xC0; TRISD = 0x00; TRISE = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x00; LATA = 0x00; LATB = 0x00; LATC = 0x00; LATD = 0x00; LATE = 0x00; UART1_Init(9600); Chip_Select = 1; Chip_Select_Direction = 0; SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW); Delay_ms(100); UART1_Write_Text("Taking readings...\r\n\r\n"); Clear_Arrays(); LATD5_bit = 1; while(1) { #if Method i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); max[i] = 0; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(20); if(max[i] < adcVal)max[i] = adcVal; else break; } min[i] = 1024; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(20); if(min[i] > adcVal)min[i] = adcVal; else break; } i++; } #else memset(max, 0, sizeof(max)); while(maxFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); adcVal = 0; adcVal = ADC_Read(0); Delay_us(20); if(max[i] < adcVal)max[i] = adcVal; else maxFlag |= (1 << i); i++; } } memset(min, 0, sizeof(min)); while(minFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); adcVal = 0; adcVal = ADC_Read(0); Delay_us(20); if(min[i] > adcVal)min[i] = adcVal; else minFlag |= (1 << i); i++; } } #endif LATD6_bit = 1; for(i = 0; i < 8; i++) { volt = (double)(max[i] - min[i]) * 5.0 / 1023.0; volt = (volt / 2.0) * 0.707; current = volt * 1000.0 / 185.0; sprintf(txt, "Channel [%u] = %5.2f Amps\r\n", i, current); UART1_Write_Text(txt); } UART1_Write_Text("\r\n"); Clear_Arrays(); LATD7_bit = 1; asm reset } }
without processing the raw data
* timer triggers ADC_conversionWhat should be the timer ISR interrupt period?
When I want to process 50Hz as well as 60Hz I use a running average over 100ms. (5 full waves of 50Hz / 6 fullwaves of 60Hz)I am taking into consideration 45Hz to 70Hz for mains frequency as I am trying to implement for both 110C 60Hz and 220V 50Hz systems.
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 #define Method 1 sbit Chip_Select at LATC0_bit; sbit Chip_Select_Direction at TRISC0_bit; unsigned int adcVal = 0; unsigned int max[8] = {0}; unsigned int min[8] = {0}; unsigned char maxFlag = 0; unsigned char minFlag = 0; double volt = 0.0; double current = 0.0; unsigned int i = 0; char txt[87]; void Select_ADG731_Channel(unsigned char data_) { Chip_Select = 0; SPI1_Write(data_); Chip_Select = 1; } void Clear_Arrays() { memset(max, 0, sizeof(max)); memset(min, 0, sizeof(min)); maxFlag = 0; minFlag = 0; } void main() { OSCCON = 0x73; OSCCON2 - 0x03; OSCTUNE = 0x40; CM1CON0 = 0x00; CM2CON0 = 0x00; SLRCON = 0x00; ADCON0 = 0x00; ADCON1 = 0x00; ADCON2 = 0b10110101; ANSELA = 0x01; ANSELB = 0x00; ANSELC = 0x00; ANSELD = 0x00; ANSELE = 0x00; TRISA = 0xC1; TRISB = 0x00; TRISC = 0xC0; TRISD = 0x00; TRISE = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x00; LATA = 0x00; LATB = 0x00; LATC = 0x00; LATD = 0x00; LATE = 0x00; UART1_Init(9600); Chip_Select = 1; Chip_Select_Direction = 0; SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW); Delay_ms(100); UART1_Write_Text("Taking readings...\r\n\r\n"); Clear_Arrays(); LATD5_bit = 1; while(1) { #if Method i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); max[i] = 0; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(20); if(max[i] <= adcVal)max[i] = adcVal; else break; } min[i] = 1024; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(20); if(min[i] >= adcVal)min[i] = adcVal; else break; } i++; } #else memset(max, 0, sizeof(max)); while(maxFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); adcVal = 0; adcVal = ADC_Read(0); Delay_us(20); if(adcVal >= max[i])max[i] = adcVal; else maxFlag |= (1 << i); i++; } } memset(min, 1024, sizeof(min)); while(minFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); adcVal = 0; adcVal = ADC_Read(0); Delay_us(20); if(adcVal <= min[i])min[i] = adcVal; else minFlag |= (1 << i); i++; } } #endif LATD6_bit = 1; //if((maxFlag == 0xFF) && (minFlag == 0xFF)) { for(i = 0; i < 8; i++) { volt = (double)(max[i] - min[i]) * 5.0 / 1023.0; sprintf(txt, "max[%u] = %u, min[%u] = %u, max[%u] - min[%u] = %u\r\n", i, max[i], i, min[i], i, i, max[i] - min[i]); UART1_Write_Text(txt); volt = (volt / 2.0) * 0.707; current = volt * 1000.0 / 185.0; sprintf(txt, "Channel [%u] = %5.2f Amps\r\n", i, current); UART1_Write_Text(txt); } UART1_Write_Text("\r\n"); Clear_Arrays(); LATD7_bit = 1; //} //asm reset } }
#define Method 1
#define Method 0
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 #define Method 0 sbit Chip_Select at LATC0_bit; sbit Chip_Select_Direction at TRISC0_bit; unsigned int adcVal = 0; unsigned int max[8] = {0}; unsigned int min[8] = {0}; unsigned char maxFlag = 0; unsigned char minFlag = 0; double volt = 0.0; double current = 0.0; unsigned int i = 0; char txt[87]; void Select_ADG731_Channel(unsigned char data_) { Chip_Select = 0; SPI1_Write(data_); Chip_Select = 1; } void Clear_Arrays() { //memset(max, 0, sizeof(max)); //memset(min, 1024, sizeof(min)); maxFlag = 0; minFlag = 0; } void main() { OSCCON = 0x73; OSCCON2 - 0x03; OSCTUNE = 0x40; CM1CON0 = 0x00; CM2CON0 = 0x00; SLRCON = 0x00; ADCON0 = 0x00; ADCON1 = 0x00; ADCON2 = 0b10110101; ANSELA = 0x01; ANSELB = 0x00; ANSELC = 0x00; ANSELD = 0x00; ANSELE = 0x00; TRISA = 0xC1; TRISB = 0x00; TRISC = 0xC0; TRISD = 0x00; TRISE = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x00; LATA = 0x00; LATB = 0x00; LATC = 0x00; LATD = 0x00; LATE = 0x00; UART1_Init(9600); Chip_Select = 1; Chip_Select_Direction = 0; SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW); Delay_ms(100); UART1_Write_Text("Taking readings...\r\n\r\n"); Clear_Arrays(); LATD5_bit = 1; while(1) { #if Method i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); max[i] = 0; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(20); if(max[i] <= adcVal)max[i] = adcVal; else break; } min[i] = 1024; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(20); if(min[i] >= adcVal)min[i] = adcVal; else break; } i++; } #else memset(max, 0, sizeof(max)); while(maxFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); adcVal = 0; adcVal = ADC_Read(0); Delay_us(20); if(adcVal >= max[i])max[i] = adcVal; else maxFlag |= (1 << i); i++; } } //memset(min, 1024, sizeof(min)); for(i = 0; i < 8; i++) { min[i] = 1024; } while(minFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); adcVal = 0; adcVal = ADC_Read(0); Delay_us(20); if(adcVal <= min[i])min[i] = adcVal; else minFlag |= (1 << i); i++; } } #endif LATD6_bit = 1; //if((maxFlag == 0xFF) && (minFlag == 0xFF)) { for(i = 0; i < 8; i++) { volt = (double)(max[i] - min[i]) * 5.0 / 1023.0; sprintf(txt, "max[%u] = %u, min[%u] = %u, max[%u] - min[%u] = %u\r\n", i, max[i], i, min[i], i, i, max[i] - min[i]); UART1_Write_Text(txt); volt = (volt / 2.0) * 0.707; current = volt * 1000.0 / 185.0; sprintf(txt, "Channel [%u] = %5.2f Amps\r\n", i, current); UART1_Write_Text(txt); } UART1_Write_Text("\r\n"); Clear_Arrays(); LATD7_bit = 1; //} //asm reset } }
memset(min, 1024, sizeof(min));
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 #define Method 1 sbit Chip_Select at LATC0_bit; sbit Chip_Select_Direction at TRISC0_bit; unsigned int adcVal = 0; unsigned int max[8] = {0}; unsigned int min[8] = {0}; unsigned char maxFlag = 0; unsigned char minFlag = 0; double volt = 0.0; double current = 0.0; unsigned int i = 0; char txt[87]; void Select_ADG731_Channel(unsigned char data_) { Chip_Select = 0; SPI1_Write(data_); Chip_Select = 1; } void Clear_Flags() { maxFlag = 0; minFlag = 0; } void main() { OSCCON = 0x73; OSCCON2 - 0x03; OSCTUNE = 0x40; CM1CON0 = 0x00; CM2CON0 = 0x00; SLRCON = 0x00; ADCON0 = 0x00; ADCON1 = 0x00; ADCON2 = 0b10110101; ANSELA = 0x01; ANSELB = 0x00; ANSELC = 0x00; ANSELD = 0x00; ANSELE = 0x00; TRISA = 0xC1; TRISB = 0x00; TRISC = 0xC0; TRISD = 0x00; TRISE = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x00; LATA = 0x00; LATB = 0x00; LATC = 0x00; LATD = 0x00; LATE = 0x00; UART1_Init(9600); Chip_Select = 1; Chip_Select_Direction = 0; SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW); Delay_ms(100); UART1_Write_Text("Taking readings...\r\n\r\n"); LATD5_bit = 1; while(1) { Clear_Flags(); #if Method i = 0; Delay_ms(10); //Don't modify this delay, it is required to get correct value for max[0] while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); max[i] = 0; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(10); if(max[i] <= adcVal)max[i] = adcVal; else break; } min[i] = 1024; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(10); if(min[i] >= adcVal)min[i] = adcVal; else break; } i++; } #else memset(max, 0, sizeof(max)); while(maxFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); adcVal = 0; adcVal = ADC_Read(0); Delay_us(10); if(adcVal >= max[i])max[i] = adcVal; else maxFlag |= (1 << i); i++; } } //memset(min, 1024, sizeof(min)); for(i = 0; i < 8; i++) { //New patch up code as above memset() code was not working, compiler bug!? min[i] = 1024; } while(minFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(1); adcVal = 0; adcVal = ADC_Read(0); Delay_us(10); if(adcVal <= min[i])min[i] = adcVal; else minFlag |= (1 << i); i++; } } #endif LATD6_bit = 1; //if((maxFlag == 0xFF) && (minFlag == 0xFF)) { for(i = 0; i < 8; i++) { volt = (double)(max[i] - min[i]) * 5.0 / 1023.0; sprintf(txt, "max[%u] = %u, min[%u] = %u, max[%u] - min[%u] = %u\r\n", i, max[i], i, min[i], i, i, max[i] - min[i]); UART1_Write_Text(txt); volt = (volt / 2.0) * 0.707; current = volt * 1000.0 / 185.0; sprintf(txt, "Channel [%u] = %5.2f Amps\r\n", i, current); UART1_Write_Text(txt); } UART1_Write_Text("\r\n"); LATD7_bit = 1; //} //asm reset } }
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 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 #define Method 0 #define BreakPoints 0 #define Isr1 1 #ifndef Isr1 #define Isr2 1 #endif sbit Chip_Select at LATC0_bit; sbit Chip_Select_Direction at TRISC0_bit; unsigned int adcVal = 0; unsigned int max[8] = {0}; unsigned int min[8] = {1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024}; unsigned char maxFlag = 0; unsigned char minFlag = 0; double volt = 0.0; double current = 0.0; unsigned int i = 0; unsigned int j = 0; char txt[87]; #define _MAX_CHANNELS 12 #define _MAX_SAMPLES 20 unsigned int _minRawAdcValue[_MAX_CHANNELS][_MAX_SAMPLES] = {0, 0}; unsigned int _maxRawAdcValue[_MAX_CHANNELS][_MAX_SAMPLES] = {0, 0}; unsigned int _rawCurrents[_MAX_CHANNELS][_MAX_SAMPLES] = {0, 0}; unsigned int _rawCurrentsSquared[_MAX_CHANNELS][_MAX_SAMPLES] = {0, 0}; unsigned int _rawCurrentsAverage[_MAX_CHANNELS][_MAX_SAMPLES] = {0, 0}; unsigned int _rawCurrentsRms[_MAX_CHANNELS][_MAX_SAMPLES] = {0, 0}; unsigned int _minFlag = 0; unsigned int _maxFlag = 0; unsigned int _min[_MAX_CHANNELS][_MAX_SAMPLES] = {0, 0}; unsigned int _max[_MAX_CHANNELS][_MAX_SAMPLES] = {0, 0}; unsigned char flagReg = 0; sbit skipFirstReadingFlag at flagReg.B0; //Timer4 //Prescaler 1:4; Postscaler 1:8; TMR4 Preload = 250; Actual Interrupt Time : 500.5 us void InitTimer4() { T4CON = 0x3D; TMR4IE_bit = 1; PR4 = 250; } void Select_ADG731_Channel(unsigned char data_) { Chip_Select = 0; SPI1_Write(data_); Chip_Select = 1; } void interrupt() { #if Isr1 if((ADIE_bit) && (ADIF_bit)) { ADIF_bit = 0; adcVal = 0; if(skipFirstReadingFlag == 1) { skipFirstReadingFlag = 0; i = 0; Select_ADG731_Channel(i); asm nop GO_DONE_bit = 1; } else { adcVal = (unsigned int)((unsigned int)(ADRESH << 8) + ADRESL); if(maxFlag != 0xFF) { if(adcVal >= max[i])max[i] = adcVal; else maxFlag |= (1 << i); } if((maxFlag == 0xFF) && (minFlag != 0xFF)) { if(adcVal <= min[i])min[i] = adcVal; else minFlag |= (1 << i); } if(++i >= 8)i = 0; Select_ADG731_Channel(i); asm nop if(!((maxFlag == 0xFF) && (minFlag == 0xFF)))GO_DONE_bit = 1; } } #endif if((TMR4IE_bit) && (TMR4IF_bit)) { TMR4IF_bit = 0; } if((ADIE_bit) && (ADIF_bit)) { ADIF_bit = 0; adcVal = 0; } #if Isr2 #endif } void Clear_Flags() { maxFlag = 0; minFlag = 0; } void main() { OSCCON = 0x73; OSCCON2 - 0x03; OSCTUNE = 0x40; CM1CON0 = 0x00; CM2CON0 = 0x00; SLRCON = 0x00; ADCON0 = 0x00; ADCON1 = 0x00; //ADCON2 = 0b10110101; ADCON2 = 0b10111110; ANSELA = 0x01; ANSELB = 0x00; ANSELC = 0x00; ANSELD = 0x00; ANSELE = 0x00; TRISA = 0xC1; TRISB = 0x00; TRISC = 0xC0; TRISD = 0x00; TRISE = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x00; LATA = 0x00; LATB = 0x00; LATC = 0x00; LATD = 0x00; LATE = 0x00; UART1_Init(9600); Chip_Select = 1; Chip_Select_Direction = 0; SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW); UART1_Write_Text("Taking readings...\r\n\r\n"); ADC_Init_Advanced(_ADC_INTERNAL_REF); ADIE_bit = 1; INTCON |= 0xC0; #if Isr2 InitTimer4(); #endif skipFirstReadingFlag = 1; Delay_ms(100); GO_DONE_bit = 1; #if BreakPoints LATD5_bit = 1; #endif while(1) { #if Isr1 if((maxFlag == 0xFF) && (minFlag == 0xFF)) { //UART1_Write_Text("Isr1 Method...\r\n\r\n"); //this line makes readings funky that is alternte burst readings differ for(i = 0; i < 8; i++) { sprintf(txt, "max[%u] = %u, min[%u] = %u, max[%u] - min[%u] = %u\r\n", i, max[i], i, min[i], i, i, max[i] - min[i]); UART1_Write_Text(txt); volt = (double)(max[i] - min[i]) * 5.0 / 1023.0; volt = (volt / 2.0) * 0.707; current = volt * 1000.0 / 185.0; sprintf(txt, "Channel [%u] = %5.2f Amps\r\n", i, current); UART1_Write_Text(txt); } memset(max, 0, sizeof(max)); for(i = 0; i < 8; i++) { min[i] = 1024; } maxFlag = 0; minFlag = 0; UART1_Write_Text("\r\n"); #if BreakPoints LATD7_bit = 1; #endif GO_DONE_bit = 1; } #elif Isr2 #else Clear_Flags(); #if Method i = 0; Delay_ms(10); //Don't modify this delay, it is required to get correct value for max[0] while(i < 8) { Select_ADG731_Channel(i); //Delay_us(1); asm nop max[i] = 0; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(10); if(max[i] <= adcVal)max[i] = adcVal; else break; } min[i] = 1024; adcVal = 0; while(1) { adcVal = ADC_Read(0); Delay_us(10); if(min[i] >= adcVal)min[i] = adcVal; else break; } i++; } #else memset(max, 0, sizeof(max)); while(maxFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); //Delay_us(1); asm nop adcVal = 0; adcVal = ADC_Read(0); Delay_us(10); if(adcVal >= max[i])max[i] = adcVal; else maxFlag |= (1 << i); i++; } } //memset(min, 1024, sizeof(min)); for(i = 0; i < 8; i++) { //New patch up code as above memset() code was not working, compiler bug!? min[i] = 1024; } while(minFlag != 0xFF) { i = 0; while(i < 8) { Select_ADG731_Channel(i); //Delay_us(1); asm nop adcVal = 0; adcVal = ADC_Read(0); Delay_us(10); if(adcVal <= min[i])min[i] = adcVal; else minFlag |= (1 << i); i++; } } #endif #if BreakPoints LATD6_bit = 1; #endif //if((maxFlag == 0xFF) && (minFlag == 0xFF)) { for(i = 0; i < 8; i++) { volt = (double)(max[i] - min[i]) * 5.0 / 1023.0; sprintf(txt, "max[%u] = %u, min[%u] = %u, max[%u] - min[%u] = %u\r\n", i, max[i], i, min[i], i, i, max[i] - min[i]); UART1_Write_Text(txt); volt = (volt / 2.0) * 0.707; current = volt * 1000.0 / 185.0; sprintf(txt, "Channel [%u] = %5.2f Amps\r\n", i, current); UART1_Write_Text(txt); } UART1_Write_Text("\r\n"); #if BreakPoints LATD7_bit = 1; #endif //} //asm reset #endif } }
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 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 #define _BREAKPOINTS_PROTEUS 1 #define _RESET 0 #define _DEBUG1 0 #define _PRINT_MEAN_VALUES 0 #define _MAX_CHANNELS 8 #define _MAX_SAMPLES 20 sbit Chip_Select at LATC0_bit; sbit Chip_Select_Direction at TRISC0_bit; sbit INT0_FREQ at LATD0_bit; sbit TMR4_FREQ at LATD1_bit; sbit ZC_RESET_FREQ at LATD2_bit; sbit ADC_ISR_FREQ at LATD3_bit; sbit i_RESET_FREQ at LATD4_bit; sbit j_RESET_FREQ at LATD5_bit; sbit BP1 at LATD7_bit; unsigned int i = 0; unsigned int j = 0; unsigned int k = 0; unsigned int t = 0; char txt[23]; unsigned int adcValue = 0; long sample = 0; unsigned long squareValue = 0; unsigned long meanValues[_MAX_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0}; unsigned long meanValuesSaved[_MAX_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0}; double Irms[_MAX_CHANNELS] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; unsigned char flagReg = 0; sbit processDataFlag at flagReg.B0; //Timer4 //Prescaler 1:1; Postscaler 1:8; TMR4 Preload = 249; Actual Interrupt Time : 125 us void InitTimer4() { T4CON = 0x38; TMR4IE_bit = 1; PR4 = 249; } void Select_ADG731_Channel(unsigned char data_) { Chip_Select = 0; SPI1_Write(data_); Chip_Select = 1; } void Start_ADC_Conversion() { GO_DONE_bit = 1; } void interrupt() { if((TMR4IE_bit) && (TMR4IF_bit)) { TMR4IF_bit = 0; TMR4_FREQ = ~TMR4_FREQ; Start_ADC_Conversion(); } if((INT0IE_bit) && (INT0IF_bit)) { INT0IF_bit = 0; INTEDG0_bit = ~INTEDG0_bit; INT0_FREQ = ~INT0_FREQ; ZC_RESET_FREQ = ~ZC_RESET_FREQ; if(!TMR4ON_bit) { i = 0; j = 0; Select_ADG731_Channel(i); TMR4ON_bit = 1; } Start_ADC_Conversion(); } if((ADIE_bit) && (ADIF_bit)) { ADIF_bit = 0; ADC_ISR_FREQ = ~ADC_ISR_FREQ; #if DEBUG1 #else adcValue = 0; sample = 0; squareValue = 0; #endif adcValue = ((unsigned int)(ADRESH << 8) + ADRESL); sample = (signed long)adcValue - 512; squareValue = (unsigned int)(sample * sample); //casting is wrong but gives correct values //squareValue = (unsigned long)(sample * sample); //casting is correct but gives rotated once correct values meanValues[i] += (squareValue / 20); if(++i >= 8) { i_RESET_FREQ = ~i_RESET_FREQ; i = 0; if(++j >= 20) { j_RESET_FREQ = ~j_RESET_FREQ; j = 0; if(!processDataFlag) { for(t = 0; t < 8; t++)meanValuesSaved[t] = meanValues[t]; } processDataFlag = 1; memset(meanValues, 0, sizeof(meanValues)); } } Select_ADG731_Channel(i); } } void main() { OSCCON = 0x70; OSCCON2 = 0x03; OSCTUNE = 0x40; CM1CON0 = 0x00; CM2CON0 = 0x00; SLRCON = 0x00; ADCON0 = 0x00; ADCON1 = 0x00; ADCON2 = 0b10111110; ANSELA = 0x01; ANSELB = 0x00; ANSELC = 0x00; ANSELD = 0x00; ANSELE = 0x00; TRISA = 0xC1; TRISB = 0x01; TRISC = 0xC0; TRISD = 0x00; TRISE = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x00; LATA = 0x00; LATB = 0x00; LATC = 0x00; LATD = 0x00; LATE = 0x00; UART1_Init(9600); Chip_Select = 1; Chip_Select_Direction = 0; SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW); UART1_Write_Text("Taking readings...\r\n\r\n"); ADC_Init_Advanced(_ADC_INTERNAL_REF); ADIE_bit = 1; INTEDG0_bit = 0; INT0IF_bit = 0; INT0IE_bit = 1; InitTimer4(); INT0_FREQ = 1; INTCON |= 0xC0; #if _BREAKPOINTS_PROTEUS BP1 = 1; BP1 = 0; #endif while(1) { #if _DEBUG1 sprintf(txt, "adcValue = %u\r\n", adcValue); UART1_Write_Text(txt); sprintf(txt, "sample = %d\r\n", sample); UART1_Write_Text(txt); #endif if(processDataFlag) { for(k = 0; k < 8; k++) { Irms[k] = sqrt((double)(meanValuesSaved[k])) * 0.026393581; meanValuesSaved[k] = 0; } processDataFlag = 0; #if _BREAKPOINTS_PROTEUS BP1 = 1; BP1 = 0; #endif for(k = 0; k < 8; k++) { #if _PRINT_MEAN_VALUES sprintf(txt, "meanValues[%u] = %lu\r\n", k, meanValuesSaved[k]); UART1_Write_Text(txt); #endif sprintf(txt, "Irms[%u] = %5.2fA\r\n", k, Irms[k]); UART1_Write_Text(txt); } UART1_Write_Text("\r\n\r\n"); #if _BREAKPOINTS_PROTEUS BP1 = 1; BP1 = 0; #endif #if _RESET asm reset #endif } } }
meanValues[i] += (squareValue / 20);
Irms[k] = sqrt((double)(meanValuesSaved[k])) * 0.026393581;
Just replace "0.026393581" with "0.026393581 / sqrt(20)", which is "0.0059017841"
Klaus
Irms[k] = sqrt((double)(meanValuesSaved[k] / 20)) * 0.026393581;
if(!TMR4ON_bit) {
i = 0;
j = 0;
Select_ADG731_Channel(i);
TMR4ON_bit = 1;
}
if(!processDataFlag) {
for(t = 0; t < 8; t++)meanValuesSaved[t] = meanValues[t] / 20;
}
#define _BREAKPOINTS_PROTEUS 1
#define _RESET 0
#define _DEBUG1 0
#define _PRINT_MEAN_VALUES 1
#define _MAX_CHANNELS 8
#define _MAX_SAMPLES 20
sbit Chip_Select at LATC0_bit;
sbit Chip_Select_Direction at TRISC0_bit;
sbit INT0_FREQ at LATD0_bit;
sbit TMR4_FREQ at LATD1_bit;
sbit ZC_RESET_FREQ at LATD2_bit;
sbit ADC_ISR_FREQ at LATD3_bit;
sbit i_RESET_FREQ at LATD4_bit;
sbit j_RESET_FREQ at LATD5_bit;
sbit BP1 at LATD7_bit;
unsigned int i = 0;
unsigned int j = 0;
unsigned int k = 0;
unsigned int t = 0;
char txt[23];
unsigned int adcValue = 0;
long sample = 0;
unsigned long squareValue = 0;
unsigned long meanValues[_MAX_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned long meanValuesSaved[_MAX_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0};
double Irms[_MAX_CHANNELS] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
unsigned char flagReg = 0;
sbit processDataFlag at flagReg.B0;
//Timer4
//Prescaler 1:1; Postscaler 1:8; TMR4 Preload = 249; Actual Interrupt Time : 125 us
void InitTimer4() {
T4CON = 0x38;
TMR4IE_bit = 1;
PR4 = 249;
}
void Select_ADG731_Channel(unsigned char data_) {
Chip_Select = 0;
SPI1_Write(data_);
Chip_Select = 1;
}
void interrupt() {
if((TMR4IE_bit) && (TMR4IF_bit)) {
TMR4IF_bit = 0;
TMR4_FREQ = ~TMR4_FREQ;
GO_DONE_bit = 1;
}
if((INT0IE_bit) && (INT0IF_bit)) {
INT0IF_bit = 0;
INTEDG0_bit = ~INTEDG0_bit;
INT0_FREQ = ~INT0_FREQ;
ZC_RESET_FREQ = ~ZC_RESET_FREQ;
if(!TMR4ON_bit) {
i = 0;
j = 0;
Select_ADG731_Channel(i);
TMR4ON_bit = 1;
}
GO_DONE_bit = 1;
}
if((ADIE_bit) && (ADIF_bit)) {
ADIF_bit = 0;
ADC_ISR_FREQ = ~ADC_ISR_FREQ;
#if DEBUG1
#else
adcValue = 0;
sample = 0;
squareValue = 0;
#endif
adcValue = ((unsigned int)(ADRESH << 8) + ADRESL);
sample = (signed long)adcValue - 512;
squareValue = sample * sample;
meanValues[i] += squareValue;
if(++i >= 8) {
i_RESET_FREQ = ~i_RESET_FREQ;
i = 0;
if(++j >= 20) {
j_RESET_FREQ = ~j_RESET_FREQ;
j = 0;
if(!processDataFlag) {
for(t = 0; t < 8; t++)meanValuesSaved[t] = meanValues[t] / 20;
}
processDataFlag = 1;
memset(meanValues, 0, sizeof(meanValues));
}
}
Select_ADG731_Channel(i);
}
}
void main() {
OSCCON = 0x70;
OSCCON2 = 0x03;
OSCTUNE = 0x40;
CM1CON0 = 0x00;
CM2CON0 = 0x00;
SLRCON = 0x00;
ADCON0 = 0x00;
ADCON1 = 0x00;
ADCON2 = 0b10111110;
ANSELA = 0x01;
ANSELB = 0x00;
ANSELC = 0x00;
ANSELD = 0x00;
ANSELE = 0x00;
TRISA = 0xC1;
TRISB = 0x01;
TRISC = 0xC0;
TRISD = 0x00;
TRISE = 0x00;
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;
LATA = 0x00;
LATB = 0x00;
LATC = 0x00;
LATD = 0x00;
LATE = 0x00;
UART1_Init(9600);
Chip_Select = 1;
Chip_Select_Direction = 0;
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW);
UART1_Write_Text("Taking readings...\r\n\r\n");
ADC_Init_Advanced(_ADC_INTERNAL_REF);
ADIE_bit = 1;
INTEDG0_bit = 0;
INT0IF_bit = 0;
INT0IE_bit = 1;
InitTimer4();
INT0_FREQ = 1;
INTCON |= 0xC0;
#if _BREAKPOINTS_PROTEUS
BP1 = 1;
BP1 = 0;
#endif
while(1) {
#if _DEBUG1
sprintf(txt, "adcValue = %u\r\n", adcValue);
UART1_Write_Text(txt);
sprintf(txt, "sample = %d\r\n", sample);
UART1_Write_Text(txt);
#endif
if(processDataFlag) {
for(k = 0; k < 8; k++) {
Irms[k] = sqrt((double)(meanValuesSaved[k])) * 0.026393581;
#if _PRINT_MEAN_VALUES
#else
meanValuesSaved[k] = 0;
#endif
}
processDataFlag = 0;
#if _BREAKPOINTS_PROTEUS
BP1 = 1;
BP1 = 0;
#endif
for(k = 0; k < 8; k++) {
#if _PRINT_MEAN_VALUES
sprintf(txt, "meanValuesSaved[%u] = %lu\r\n", k, meanValuesSaved[k]);
UART1_Write_Text(txt);
#endif
sprintf(txt, "Irms[%u] = %5.2fA\r\n", k, Irms[k]);
UART1_Write_Text(txt);
}
UART1_Write_Text("\r\n\r\n");
#if _BREAKPOINTS_PROTEUS
BP1 = 1;
BP1 = 0;
#endif
#if _RESET
asm reset
#endif
}
}
}
You mean
???Code:: Irms[k] = sqrt((double)(meanValuesSaved[k] / 20)) * 0.026393581;
:
Irms[k] = sqrt((double)(meanValuesSaved[k])) [COLOR="#008000"]* 0.0059017841[/COLOR];
Hi,
No. This is what I mean:
Code:: Irms[k] = sqrt((double)(meanValuesSaved[k])) [COLOR="#008000"]* 0.0059017841[/COLOR];
Klaus
#define _BREAKPOINTS_PROTEUS 1
#define _RESET 0
#define _DEBUG1 0
#define _PRINT_MEAN_VALUES 1
#define _METHOD1 0
#define _METHOD2 1
#define _MAX_CHANNELS 8
#define _MAX_SAMPLES 20
sbit Chip_Select at LATC0_bit;
sbit Chip_Select_Direction at TRISC0_bit;
sbit INT0_FREQ at LATD0_bit;
sbit TMR4_FREQ at LATD1_bit;
sbit ZC_RESET_FREQ at LATD2_bit;
sbit ADC_ISR_FREQ at LATD3_bit;
sbit i_RESET_FREQ at LATD4_bit;
sbit j_RESET_FREQ at LATD5_bit;
sbit BP1 at LATD7_bit;
unsigned int i = 0;
unsigned int j = 0;
unsigned int k = 0;
unsigned int t = 0;
char txt[23];
unsigned int adcValue = 0;
long sample = 0;
unsigned long squareValue = 0;
unsigned long meanValues[_MAX_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned long meanValuesSaved[_MAX_CHANNELS] = {0, 0, 0, 0, 0, 0, 0, 0};
double Irms[_MAX_CHANNELS] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
unsigned char flagReg = 0;
sbit processDataFlag at flagReg.B0;
//Timer4
//Prescaler 1:1; Postscaler 1:8; TMR4 Preload = 249; Actual Interrupt Time : 125 us
void InitTimer4() {
T4CON = 0x38;
TMR4IE_bit = 1;
PR4 = 249;
}
void Select_ADG731_Channel(unsigned char data_) {
Chip_Select = 0;
SPI1_Write(data_);
Chip_Select = 1;
}
void interrupt() {
if((TMR4IE_bit) && (TMR4IF_bit)) {
TMR4IF_bit = 0;
TMR4_FREQ = ~TMR4_FREQ;
GO_DONE_bit = 1;
}
if((INT0IE_bit) && (INT0IF_bit)) {
INT0IF_bit = 0;
INTEDG0_bit = ~INTEDG0_bit;
INT0_FREQ = ~INT0_FREQ;
ZC_RESET_FREQ = ~ZC_RESET_FREQ;
if(!TMR4ON_bit) {
i = 0;
j = 0;
Select_ADG731_Channel(i);
TMR4ON_bit = 1;
}
GO_DONE_bit = 1;
}
if((ADIE_bit) && (ADIF_bit)) {
ADIF_bit = 0;
ADC_ISR_FREQ = ~ADC_ISR_FREQ;
#if DEBUG1
#else
adcValue = 0;
sample = 0;
squareValue = 0;
#endif
adcValue = ((unsigned int)(ADRESH << 8) + ADRESL);
sample = (signed long)adcValue - 512;
squareValue = sample * sample;
meanValues[i] += squareValue;
if(++i >= 8) {
i_RESET_FREQ = ~i_RESET_FREQ;
i = 0;
if(++j >= 20) {
j_RESET_FREQ = ~j_RESET_FREQ;
j = 0;
if(!processDataFlag) {
#if _METHOD1
for(t = 0; t < 8; t++)meanValuesSaved[t] = meanValues[t] / 20;
#endif
#if _METHOD2
for(t = 0; t < 8; t++)meanValuesSaved[t] = meanValues[t];
#endif
processDataFlag = 1;
}
memset(meanValues, 0, sizeof(meanValues));
}
}
Select_ADG731_Channel(i);
}
}
void main() {
OSCCON = 0x70;
OSCCON2 = 0x03;
OSCTUNE = 0x40;
CM1CON0 = 0x00;
CM2CON0 = 0x00;
SLRCON = 0x00;
ADCON0 = 0x00;
ADCON1 = 0x00;
ADCON2 = 0b10111110;
ANSELA = 0x01;
ANSELB = 0x00;
ANSELC = 0x00;
ANSELD = 0x00;
ANSELE = 0x00;
TRISA = 0xC1;
TRISB = 0x01;
TRISC = 0xC0;
TRISD = 0x00;
TRISE = 0x00;
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;
LATA = 0x00;
LATB = 0x00;
LATC = 0x00;
LATD = 0x00;
LATE = 0x00;
UART1_Init(9600);
Chip_Select = 1;
Chip_Select_Direction = 0;
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_HIGH_2_LOW);
UART1_Write_Text("Taking readings...\r\n\r\n");
ADC_Init_Advanced(_ADC_INTERNAL_REF);
ADIE_bit = 1;
INTEDG0_bit = 0;
INT0IF_bit = 0;
INT0IE_bit = 1;
InitTimer4();
INT0_FREQ = 1;
INTCON |= 0xC0;
#if _BREAKPOINTS_PROTEUS
BP1 = 1;
BP1 = 0;
#endif
while(1) {
#if _DEBUG1
sprintf(txt, "adcValue = %u\r\n", adcValue);
UART1_Write_Text(txt);
sprintf(txt, "sample = %d\r\n", sample);
UART1_Write_Text(txt);
#endif
if(processDataFlag) {
for(k = 0; k < 8; k++) {
#if _METHOD1
Irms[k] = sqrt((double)(meanValuesSaved[k])) * 0.026393581;
#endif
#if _METHOD2
Irms[k] = sqrt((double)(meanValuesSaved[k])) * 0.0059017841;
#endif
#if _PRINT_MEAN_VALUES
#else
meanValuesSaved[k] = 0;
#endif
}
processDataFlag = 0;
#if _PRINT_MEAN_VALUES
#else
memset(meanValuesSaved, 0, sizeof(meanValuesSaved));
#endif
#if _BREAKPOINTS_PROTEUS
BP1 = 1;
BP1 = 0;
#endif
for(k = 0; k < 8; k++) {
#if _PRINT_MEAN_VALUES
sprintf(txt, "meanValuesSaved[%u] = %lu\r\n", k, meanValuesSaved[k]);
UART1_Write_Text(txt);
#endif
sprintf(txt, "Irms[%u] = %5.2fA\r\n", k, Irms[k]);
UART1_Write_Text(txt);
}
UART1_Write_Text("\r\n\r\n");
#if _BREAKPOINTS_PROTEUS
BP1 = 1;
BP1 = 0;
#endif
#if _RESET
asm reset
#endif
}
}
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?