unsigned int max = 0;
unsigned int old_max = 0;
unsigned int min = 0;
unsigned int old_min = 0;
double volt = 0.0;
double current = 0.0;
char txt[23];
void main() {
OSCCON = 0b01101011;
OSCTUNE = 0x00;
CM1CON0 = 0x00;
TRISA = 0xFC;
PORTA = 0x00;
LATA = 0x00;
ANSELA = 0x10;
ADCON1 = 0b11010000;
UART1_Init(9600);
Delay_ms(200);
while(1) {
max = 0;
old_max = 0;
while(1) {
max = (double)ADC_Read(3);
if(old_max < max)old_max = max;
else break;
}
min = 0;
old_min = 1024;
while(1) {
min = (double)ADC_Read(3);
if(old_min > min)old_min = min;
else break;
}
volt = (double)(old_max - old_min) * 5.0 / 1023.0;
volt = (volt / 2.0) * 0.707;
current = volt * 1000.0 / 185.0;
FloatToStr(current, txt);
Ltrim(txt);
strcat(txt," Amps\r\n");
UART1_Write_Text(txt);
Delay_ms(300);
}
}
what is the best way to measure the AC current using ACS712-05T sensor module?
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 sbit Chip_Select at LATC0_bit; sbit Chip_Select_Direction at TRISC0_bit; unsigned int adcVal = 0; unsigned int rawCurrentValue[8] = {0}; unsigned int rawCurrentValueMax[8] = {0}; unsigned int rawCurrentValueMin[8] = {1024}; char i = 0; char j = 0; char txt[47]; unsigned char flagReg = 0; sbit maxFlag at flagReg.B0; sbit minFlag at flagReg.B1; void Select_ADG731_Channel(unsigned char data_) { Chip_Select = 1; Delay_us(1); Chip_Select = 0; SPI1_Write(data_); } void interrupt() { if((ADIE_bit) && (ADIF_bit)) { ADIF_bit = 0; adcVal = (unsigned int)((unsigned int)(ADRESH << 8) + ADRESL); if(rawCurrentValueMax[i] <= adcVal)rawCurrentValueMax[i] = adcVal; else maxFlag = 1; if(rawCurrentValueMin[i] >= adcVal)rawCurrentValueMin[i] = adcVal; else minFlag = 1; if(!((maxFlag) && (minFlag))) { GO_DONE_bit = 1; } } LATD7_bit = ~LATD7_bit; } void main() { CM1CON0 = 0x00; CM2CON0 = 0x00; SLRCON = 0x00; ADCON1 = 0x00; ADCON2 = 0b10110101; ANSELA = 0x01; ANSELB = 0x00; ANSELC = 0x00; ANSELD = 0x00; ANSELE = 0x00; TRISA = 0x01; 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; SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH); Delay_ms(100); ADC_Init_Advanced(_ADC_INTERNAL_REF); ADIE_bit = 1; UART1_Write_Text("Taking readings...\r\n\r\n"); INTCON |= 0xC0; Select_ADG731_Channel(0); GO_DONE_bit = 1; while(1) { IntToStr(adcVal,txt); UART1_Write_Text(txt); if((maxFlag) && (minFlag)) { for(j = 0; j < 8; j++) { rawCurrentValue[j] = rawCurrentValueMax[j] - rawCurrentValueMin[j]; sprintf(txt, "Channel [%d] = %5.2f Amps\r\n", j, (double)rawCurrentValue[j]); UART1_Write_Text(txt); } UART1_Write_Text("\r\n"); memset(rawCurrentValueMax, 0, sizeof(rawCurrentValueMax)); memset(rawCurrentValueMin, 1024, sizeof(rawCurrentValueMin)); maxFlag = 0; minFlag = 0; GO_DONE_bit = 1; } } }
sbit Chip_Select at LATC0_bit;
sbit Chip_Select_Direction at TRISC0_bit;
unsigned int adcVal = 0;
unsigned int rawCurrentValue[8] = {0};
unsigned int rawCurrentValueMax[8] = {0};
unsigned int rawCurrentValueMin[8] = {1024};
char i = 0;
char j = 0;
char txt[47];
unsigned char flagReg = 0;
sbit maxFlag at flagReg.B0;
sbit minFlag at flagReg.B1;
void Select_ADG731_Channel(unsigned char data_) {
Chip_Select = 1;
Delay_us(1);
Chip_Select = 0;
SPI1_Write(data_);
}
void interrupt() {
if((ADIE_bit) && (ADIF_bit)) {
ADIF_bit = 0;
adcVal = (unsigned int)((unsigned int)(ADRESH << 8) + ADRESL);
if(rawCurrentValueMax[i] <= adcVal)rawCurrentValueMax[i] = adcVal;
else maxFlag = 1;
if(rawCurrentValueMin[i] >= adcVal)rawCurrentValueMin[i] = adcVal;
else minFlag = 1;
if(!((maxFlag) && (minFlag))) {
GO_DONE_bit = 1;
}
}
LATD7_bit = ~LATD7_bit;
}
void main() {
CM1CON0 = 0x00;
CM2CON0 = 0x00;
SLRCON = 0x00;
ADCON1 = 0x00;
ADCON2 = 0b10110101;
ANSELA = 0x01;
ANSELB = 0x00;
ANSELC = 0x00;
ANSELD = 0x00;
ANSELE = 0x00;
TRISA = 0x01;
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;
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
Delay_ms(100);
ADC_Init_Advanced(_ADC_INTERNAL_REF);
ADIE_bit = 1;
UART1_Write_Text("Taking readings...\r\n\r\n");
INTCON |= 0xC0;
Select_ADG731_Channel(0);
GO_DONE_bit = 1;
while(1) {
sprintf(txt, "adcVal = %d\r\n\r\n", adcVal);
UART1_Write_Text(txt);
if((maxFlag) && (minFlag)) {
for(j = 0; j < 8; j++) {
rawCurrentValue[j] = rawCurrentValueMax[j] - rawCurrentValueMin[j];
sprintf(txt, "Channel [%d] = %5.2f Amps\r\n", j, (double)rawCurrentValue[j]);
UART1_Write_Text(txt);
}
UART1_Write_Text("\r\n");
memset(rawCurrentValueMax, 0, sizeof(rawCurrentValueMax));
memset(rawCurrentValueMin, 1024, sizeof(rawCurrentValueMin));
maxFlag = 0;
minFlag = 0;
GO_DONE_bit = 1;
}
}
}
Should I take say 10 samples in 10ms = 20 samples in 20ms
A rather curious requirement.If current for that channel is beyond the thresholds then SSR of that channel will be tripped in 3ms.
I discarded application 4 as the compensation of diode Vf doesn't give correct and accurate readings.
Instead, I just measured AC current continuously.
Here is my code which works fine.
Code:unsigned int max = 0; unsigned int old_max = 0; unsigned int min = 0; unsigned int old_min = 0; double volt = 0.0; double current = 0.0; char txt[23]; void main() { OSCCON = 0b01101011; OSCTUNE = 0x00; CM1CON0 = 0x00; TRISA = 0xFC; PORTA = 0x00; LATA = 0x00; ANSELA = 0x10; ADCON1 = 0b11010000; UART1_Init(9600); Delay_ms(200); while(1) { max = 0; old_max = 0; while(1) { max = (double)ADC_Read(3); if(old_max < max)old_max = max; else break; } min = 0; old_min = 1024; while(1) { min = (double)ADC_Read(3); if(old_min > min)old_min = min; else break; } volt = (double)(old_max - old_min) * 5.0 / 1023.0; volt = (volt / 2.0) * 0.707; current = volt * 1000.0 / 185.0; FloatToStr(current, txt); Ltrim(txt); strcat(txt," Amps\r\n"); UART1_Write_Text(txt); Delay_ms(300); } }
unsigned int max = 0;
unsigned int old_max = 0;
unsigned int min = 0;
unsigned int old_min = 0;
max = (double)ADC_Read(3); ?
min = (double)ADC_Read(3); ?
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 sbit Chip_Select at LATC0_bit; sbit Chip_Select_Direction at TRISC0_bit; unsigned int max[8] = {0}; unsigned int old_max[8] = {0}; unsigned int min[8] = {0}; unsigned int old_min[8] = {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)); memset(old_max, 0, sizeof(old_max)); memset(old_min, 0, sizeof(old_min)); } void main() { 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(); while(1) { i = 0; while(i < 8) { Select_ADG731_Channel(i); Delay_us(50); max[i] = 0; old_max[i] = 0; while(1) { max[i] = ADC_Read(0); Delay_us(10); if(old_max[i] < max[i])old_max[i] = max[i]; else break; } min[i] = 0; old_min[i] = 1024; while(1) { min[i] = ADC_Read(0); Delay_us(10); if(old_min[i] > min[i])old_min[i] = min[i]; else break; } i++; } for(i = 0; i < 8; i++) { volt = (double)(old_max[i] - old_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(); } }
I don´t understand why "non interrupt" solution.I tried to implement a non-interrupt based code
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?