Błąd pomiaru prądu przekładnikiem prądowym?
-
Autor tematu - Lider FORUM (min. 2000)
- Posty w temacie: 35
- Posty: 6356
- Rejestracja: 29 kwie 2009, 10:11
- Lokalizacja: Kraków / Jaworzno / Kopanka
Re: Błąd pomiaru prądu przekładnikiem prądowym?
Nie znam się, sam tego nie zrobię. A czy z ACS758 nie będzie podobnych problemów?
„Największym wrogiem wolności jest najedzony niewolnik.”
-
- Lider FORUM (min. 2000)
- Posty w temacie: 29
- Posty: 3780
- Rejestracja: 21 kwie 2011, 10:58
- Lokalizacja: ::
Re: Błąd pomiaru prądu przekładnikiem prądowym?
Będą. Do poprawnego pomiaru potrzeba odpowiedniego programu. Dość prosty no ale trzeba go mieć.
Jak byś programował w C to bym Ci podrzucił prawie gotowca.
Jak byś programował w C to bym Ci podrzucił prawie gotowca.
-
Autor tematu - Lider FORUM (min. 2000)
- Posty w temacie: 35
- Posty: 6356
- Rejestracja: 29 kwie 2009, 10:11
- Lokalizacja: Kraków / Jaworzno / Kopanka
Re: Błąd pomiaru prądu przekładnikiem prądowym?
Pokaż w C, może coś podejrzę 

„Największym wrogiem wolności jest najedzony niewolnik.”
-
- Lider FORUM (min. 2000)
- Posty w temacie: 29
- Posty: 3780
- Rejestracja: 21 kwie 2011, 10:58
- Lokalizacja: ::
Re: Błąd pomiaru prądu przekładnikiem prądowym?
Nie mogę znaleźć dla AVR. To masz trochę uproszczony dla STMa (to tylko na początek, żebyś zobaczył, potem trzeba będzie to trochę popoprawiać):
Kod: Zaznacz cały
int main(void)
{
u_offset = 512;
i_offset = 512;
i_magnitude = 1022;
u_magnitude = 3435;
if (New_meassurments != 0)
{
New_meassurments = 0;
Float = u_rms_irq;
Float = sqrtf(Float * 0.001) * (float)(u_magnitude); //Bez mnożenia przez U_magnitude: 1854.862448 - 100V
u_rms = roundf(Float);
u_rms = u_rms >> 16; //1000 - 100V
u_dc = (int64_t)((int64_t)(u_dc_irq) * (int64_t)(u_magnitude) * (int64_t)(67108)) >> 42; //Bez mnożenia 1854862.448 - 100V
//u_dc = u_dc; //1000 - 100V
u_max = (int64_t)((int64_t)(u_max_irq) * (int64_t)(u_magnitude)) >> 16; //Bez mnożenia 1854.862448 - 100V
//u_max = u_max; //1000 - 100V
Float = i_rms_irq;
Float = sqrtf(Float * 0.001) * (float)(i_magnitude); //Bez mnożenia przez i_magnitude: 12057.48916 - 1A
i_rms = roundf(Float);
i_rms = i_rms >> 16; //1000 - 1A
p_irq = p_irq;// >> 16; //Bez przesówania o 16 bitów 22364983.86 - 100W. Z przesówaniem 341.26257110595703125 - 100W
p_irq = (p_irq * 1099571) >> 32;
p = (p_irq* (int64_t)(u_magnitude) * (int64_t)(i_magnitude)) >> 40; //10 - 1W
if (p > 0)
p_energy += p; //10 - 1J
}
}
void TIM1_UP_IRQHandler(void) //Co 100us
{
static uint16_t Licznik_100ms = 10; //Czas wykonywania 11/19us
TIM1->SR = 0x0000;
get_adc12(6 , 5 , (int16_t*)&ADC1_buffer[0], (int16_t*)&ADC2_buffer[0]); //I1, U1
i = (ADC1_buffer[0] - i_offset); //Wyjdzie z zakresu -511...511
u = (ADC2_buffer[0] - u_offset); //Wyjdzie z zakresu -511...511
u_rms_buffer = u_rms_buffer + (u * u); //Wyjdzie z zakresu -67108864...67108864 (27 bitów)
u_dc_buffer = u_dc_buffer + u; //Wyjdzie z zakresu -512...512 (10 bitów)
if (abs(u) > u_max_buffer)
u_max_buffer = abs(u);
i_rms_buffer = i_rms_buffer + (i * i); //Wyjdzie z zakresu -77577846784...77577846784 (37 bitów)
p_buffer = p_buffer + (i * u); //Wyjdzie z zakresu -2281701376...2281701376 (31 bitów)
Licznik_100ms++;
if (Licznik_100ms >= 1000) //Co 100ms
{
Licznik_100ms = 0;
u_rms_irq = u_rms_buffer; //Max 67108864000
u_dc_irq = u_dc_buffer; //Max 8192000
u_max_irq = u_max_buffer; //Max 8192
i_rms_irq = i_rms_buffer; //Max 77577846784000
p_irq = p_buffer; //Max 2281701376000
New_meassurments = 1;
u_rms_buffer = 0;
u_dc_buffer = 0;
u_max_buffer = 0;
i_rms_buffer = 0;
p_buffer = 0;
}
-
Autor tematu - Lider FORUM (min. 2000)
- Posty w temacie: 35
- Posty: 6356
- Rejestracja: 29 kwie 2009, 10:11
- Lokalizacja: Kraków / Jaworzno / Kopanka
Re: Błąd pomiaru prądu przekładnikiem prądowym?
Tu masz dużo lepszy przetwornik, to może mieć znaczenie?
Dodane 1 godzina 22 minuty 47 sekundy:
A jakby tak wyprostować to napięcie i wygładzić przed pomiarem? Jedna dioda i kondensator?
Dodane 1 godzina 22 minuty 47 sekundy:
A jakby tak wyprostować to napięcie i wygładzić przed pomiarem? Jedna dioda i kondensator?
„Największym wrogiem wolności jest najedzony niewolnik.”
-
- Lider FORUM (min. 2000)
- Posty w temacie: 29
- Posty: 3780
- Rejestracja: 21 kwie 2011, 10:58
- Lokalizacja: ::
Re: Błąd pomiaru prądu przekładnikiem prądowym?
Na AVR też mierzyło całkiem dokładnie ale program jest bardzo stary i nie pamiętam gdzie (a kto wie czy nie był jeszcze w BASCOMie).oprawcafotografii pisze: ↑28 lip 2024, 18:54Tu masz dużo lepszy przetwornik, to może mieć znaczenie?
Ten program tak naprawdę jest bardzo prosty, tylko na potrzeby procesora bez FPU (a tym bardziej 8-bitowego) musi mieć wiele dodatkowych udziwnień.
To pomiar będzie bardzo niedokładny. Lepszy już będzie ten program z pierwszego postu, bo on przynajmniej ma "prostownik" idealny (bez spadku napięcia).oprawcafotografii pisze: ↑28 lip 2024, 18:54A jakby tak wyprostować to napięcie i wygładzić przed pomiarem? Jedna dioda i kondensator?
Decyzja należy do Ciebie.
-
- Lider FORUM (min. 2000)
- Posty w temacie: 29
- Posty: 3780
- Rejestracja: 21 kwie 2011, 10:58
- Lokalizacja: ::
Re: Błąd pomiaru prądu przekładnikiem prądowym?
A, miałem wenę:
To ciągle niesprawdzony kod, ale już o wiele bliższy docelowego.
Kod: Zaznacz cały
int16_t I1; //zmierzone wartości chwilowe
int16_t I2;
int16_t I3;
int16_t U1;
int16_t U2;
int16_t U3;
int16_t UI_offset; //zmierzony offset (napiecie 2.5V z dzielnika napiecia)
int32_t I1_buffer; //akumulatory wartosci
int32_t I2_buffer;
int32_t I3_buffer;
int32_t U1_buffer;
int32_t U2_buffer;
int32_t U3_buffer;
int32_t P1_buffer;
int32_t P2_buffer;
int32_t P3_buffer;
int32_t I1_buffer_irq_main; //zapamietywacze do przekazania wartosci do maina
int32_t I2_buffer_irq_main;
int32_t I3_buffer_irq_main;
int32_t U1_buffer_irq_main;
int32_t U2_buffer_irq_main;
int32_t U3_buffer_irq_main;
int32_t P1_buffer_irq_main;
int32_t P2_buffer_irq_main;
int32_t P3_buffer_irq_main;
float I_scaler; //skalery koncowych wynikow
float U_scaler;
float I1_RMS; //wartosci koncowe
float I2_RMS;
float I3_RMS;
float U1_RMS;
float U2_RMS;
float U3_RMS;
float P1_; //moce czynne
float P2_;
float P3_;
float S1_; //moce pozorne
float S2_;
float S3_;
float E1_; //liczniki energii czynnej
float E2_;
float E3_;
int main(void)
{
I_scaler = 1.232; //to trzeba dopiero ustawic
U_scaler = 2.22;
if (New_meassurments != 0)
{
New_meassurments = 0;
U1_RMS = U1_buffer_irq_main;
U1_RMS = sqrtf(U1_RMS * 0.001) * U_scaler; //100 - 100V
U2_RMS = U2_buffer_irq_main;
U2_RMS = sqrtf(U2_RMS * 0.001) * U_scaler; //100 - 100V
U3_RMS = U3_buffer_irq_main;
U3_RMS = sqrtf(U3_RMS * 0.001) * U_scaler; //100 - 100V
I1_RMS = I1_buffer_irq_main;
I1_RMS = sqrtf(I1_RMS * 0.001) * I_scaler; //1 - 1A
I2_RMS = I2_buffer_irq_main;
I2_RMS = sqrtf(I2_RMS * 0.001) * I_scaler; //1 - 1A
I3_RMS = I3_buffer_irq_main;
I3_RMS = sqrtf(I3_RMS * 0.001) * I_scaler; //1 - 1A
P1_ = P1_buffer_irq_main * 0.001 * I_scaler * U_scaler; //1 - 1W
P2_ = P2_buffer_irq_main * 0.001 * I_scaler * U_scaler;
P3_ = P3_buffer_irq_main * 0.001 * I_scaler * U_scaler;
S1_ = I1_RMS * U1_RMS; //1 - 1VA
S2_ = I2_RMS * U2_RMS;
S3_ = I3_RMS * U3_RMS;
if (P1_ > 0)
E1_ += P1_; //1 - 1J
if (P2_ > 0)
E2_ += P2_; //1 - 1J
if (P3_ > 0)
E3_ += P3_; //1 - 1J
LCD(line_1, row_1, U1_RMS); //tu sobie wyswietlisz albo wyslesz wartosci po UARCie
}
}
void TIM1_UP_IRQHandler(void) //Co 125us
{
static uint8_t Co_mierzyc = 0;
static uint8_t Licznik_100ms = 0;
TIM1->SR = 0x0000; //to zamienic na odpowiednik z AVRa
Co_mierzyc++;
Co_mierzyc &= 0x07;
switch (Co_mierzyc)
{
case 0: //Pomiar UI_offset
UI_offset = getadc(0); //Wyjdzie z zakresu -511...511
break;
case 1: //Pomiar I1
I_1 = getadc(1) - UI_offset; //Wyjdzie z zakresu -511...511
I1_buffer = I1_buffer + (I_1 * I_1); //Wyjdzie z zakresu -26112100...26112100 (25 bitów)
break;
case 2: //Pomiar I2
I_2 = getadc(2) - UI_offset; //Wyjdzie z zakresu -511...511
I2_buffer = I2_buffer + (I_2 * I_2); //Wyjdzie z zakresu -26112100...26112100 (25 bitów)
break;
case 3: //Pomiar I3
I_3 = getadc(3) - UI_offset; //Wyjdzie z zakresu -511...511
I3_buffer = I3_buffer + (I_3 * I_3); //Wyjdzie z zakresu -26112100...26112100 (25 bitów)
break;
case 4: //Pomiar U1
U_1 = getadc(4) - UI_offset; //Wyjdzie z zakresu -511...511
U1_buffer = U1_buffer + (U_1 * U_1); //Wyjdzie z zakresu -26112100...26112100 (25 bitów)
P1_buffer = P1_buffer + (I_1 * U_1); //Wyjdzie z zakresu -26112100...26112100 (25 bitów)
break;
case 5: //Pomiar U2
U_2 = getadc(5) - UI_offset; //Wyjdzie z zakresu -511...511
U2_buffer = U2_buffer + (U_2 * U_2); //Wyjdzie z zakresu -26112100...26112100 (25 bitów)
P2_buffer = P2_buffer + (I_2 * U_2); //Wyjdzie z zakresu -26112100...26112100 (25 bitów)
break;
case 6: //Pomiar U3
U_3 = getadc(6) - UI_offset; //Wyjdzie z zakresu -511...511
U3_buffer = U3_buffer + (U_3 * U_3); //Wyjdzie z zakresu -26112100...26112100 (25 bitów)
P3_buffer = P3_buffer + (I_3 * U_3); //Wyjdzie z zakresu -26112100...26112100 (25 bitów)
break;
case 7: //Pomiar U1
Licznik_100ms++;
if (Licznik_100ms >= 100) //Co 100ms
{
Licznik_100ms = 0;
I1_buffer_irq_main = I1_buffer;
I2_buffer_irq_main = I2_buffer;
I3_buffer_irq_main = I3_buffer;
U1_buffer_irq_main = U1_buffer;
U2_buffer_irq_main = U2_buffer;
U3_buffer_irq_main = U3_buffer;
P1_buffer_irq_main = P1_buffer;
P2_buffer_irq_main = P2_buffer;
P3_buffer_irq_main = P3_buffer;
New_meassurments = 1;
I1_buffer = 0;
I2_buffer = 0;
I3_buffer = 0;
U1_buffer = 0;
U2_buffer = 0;
U3_buffer = 0;
P1_buffer = 0;
P2_buffer = 0;
P3_buffer = 0;
}
break;
}
}
-
Autor tematu - Lider FORUM (min. 2000)
- Posty w temacie: 35
- Posty: 6356
- Rejestracja: 29 kwie 2009, 10:11
- Lokalizacja: Kraków / Jaworzno / Kopanka
Re: Błąd pomiaru prądu przekładnikiem prądowym?
Póki co szukam sposobu na szybszy analogRead();
Normalnie Arduino czyta pin analogowy niecałe 10.000x/s ale da się to zmienić - w poniższym przykładzie wychodzi około 30000x/s.
Normalnie Arduino czyta pin analogowy niecałe 10.000x/s ale da się to zmienić - w poniższym przykładzie wychodzi około 30000x/s.
Kod: Zaznacz cały
#define FASTADC 1
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
int licznik = 0;
float msSTOPER_1 = 0; float msSTOPER_2 = 0;
void setup()
{
Serial.begin(115200); //Start serial communication
Serial.println("START");
#if FASTADC
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
#endif
}
void loop()
{
licznik = 0;
msSTOPER_1 = micros();
while (micros() < msSTOPER_1 + 1000000)
{
analogRead(1);
licznik++;
}
msSTOPER_2 = micros();
Serial.print("Licznik: "); Serial.print(licznik); Serial.print(" Czas: "); Serial.println(msSTOPER_2-msSTOPER_1);
delay(1000);
}
„Największym wrogiem wolności jest najedzony niewolnik.”
-
- Lider FORUM (min. 2000)
- Posty w temacie: 29
- Posty: 3780
- Rejestracja: 21 kwie 2011, 10:58
- Lokalizacja: ::
Re: Błąd pomiaru prądu przekładnikiem prądowym?
Najlepiej to napisać samemu. Wtedy można zrobić osobne funkcje na wyzwalanie pomiaru i na odczyt.
Czyli takie adc_start i adc_read. Procesor by wtedy nie tracił czasu na czekanie na wynik.
Czyli takie adc_start i adc_read. Procesor by wtedy nie tracił czasu na czekanie na wynik.
-
Autor tematu - Lider FORUM (min. 2000)
- Posty w temacie: 35
- Posty: 6356
- Rejestracja: 29 kwie 2009, 10:11
- Lokalizacja: Kraków / Jaworzno / Kopanka
Re: Błąd pomiaru prądu przekładnikiem prądowym?
Niestety moje umiejętności są zbyt ograniczone żeby samemu ognień wymyślać...
„Największym wrogiem wolności jest najedzony niewolnik.”