Wpis z mikrobloga

@Niszczyciel666: Co prawda na PIC nic nie robiłem, ale z AVR mam doświadczenie. Najlepszą metodą na radzenie sobie ze zmiennymi typu float jest...


W obliczeniach zastępuj volty milivoltami, sekundy milisekundami itd.
np.

float voltage = 1.5 //V
zamień na

uint16_t voltage=1500 //mV
Jak wypisujesz to przez UART/na wyświetlacz, to rób tak:

printf("voltage= %u.%uV\n", voltage/1000, voltage%1000)
i dostaniesz

voltage=1.500V
@QBA__: no tak, tylko problemem jest tutaj regulator, bo to o współczynniki jego równania różnicowego się rozchodzi. Generalnie mam takie równanie regulatora y(k) = 0.007155e(k) - 0.0032e(k-1) - 0.003955e(k-2) + 2y(k-1) - y(k-2). Z tego co pamiętam w układach dyskretnych te współczynniki muszą być takie małe żeby układ zachował stabilność (koło jednostkowe). Tak na prawdę to cały regulator to PR więc problemem tutaj jest utrzymanie stabilności. Docelowo i tak odcinam część
@Niszczyciel666: Sorry nie mam teraz czasu analizować.
Masz tu ATMELowska notę aplikacyjną:
http://www.atmel.com/Images/Atmel-2558-Discrete-PID-Controller-on-tinyAVR-and-megaAVR_ApplicationNote_AVR221.pdf

i chyba kod regulatora z tego przykładu:
https://homepages.uni-regensburg.de/~erc24492/PID-Regler/AVR221/IAR/doxygen/pid_8c.html

Jeśli nie to szukaj tu:
http://start.atmel.com/#examples

Postaraj się przerobić pod siebie.

Albo taka moja pierwsza myśl:

y(k) = 0.007155e(k) - 0.0032e(k-1) - 0.003955e(k-2) + 2y(k-1) - y(k-2)
Rozpisz to tak:

y(k) = (7155*e(k) ) /10^6 - (32*e(k-1)) / 10^4 - (3955*e(k-2) )/ 10^6 + 2y(k-1) - y(k-2)
W sensie -
@QBA__: Na ten pomysł wpadłem już, po zmianie czas obsługi skrócił się trzykrotnie, ale to dalej dużo za dużo, na obługę ADC, PWM, obliczenia i zabezpieczenia mam 50us, a samo obliczanie regulatora teraz zajmuje 100us
@Niszczyciel666:

na short int

Oj, to żeby było szybciej, to albo szybsze taktowanie mikrokontrolera - inny kwarc, jak się da, albo ostatecznie wstawka assemblerowa, choć kompilatory dobrze optymalizują kod i cudów bym się nie spodziewał.

Sprawdź jeszcze czy w kompilatorze którego używasz masz poziomy optymalizacji. Nie znam się na PICach i nie wiem jakiego kompilatora tam sie używa.
W gcc masz poziomy od O0 do O3 albo Os z naciskiem na
@QBA__: Pracuję przy maksymalnej częstotliwości 32MHz. Możliwe że problemem jest optymalizacja kodu, bo pracuje na wersji darmowej LITE która ma ten optymalizator dosyć słaby. Jest jeszcze wersja PRO która podobno ma lepszy optymalizator, ale już nie za darmo. No nic trzeba będzie spróbować zdobyć wersję PRO ( ͡° ͜ʖ ͡°).
@wytrzzeszcz: Program jest do sterowania falownikiem jednofazowym
switch(quater)
{
case 1:
Uref = 200 + sinus[phi];
break;
case 2:
Uref = 200 + sinus[99-phi];
break;
case 3:
Uref = 200 - sinus[phi];
break;
case 4:
Uref = 200 - sinus[99 - phi];
break;
default:
break;
}
e = Uref - Ur;
y = (((e<<5)+(e<<4)+(e<<3)+(e<<1)+e) - ((eprev<<4)+(eprev<<3)+(eprev<<1)) - ((eprev2<<5)+eprev2))>>13 + (yprev << 1) - yprev2;
if (y>=400)
y = 400;
else if
@Niszczyciel666:
Jeszcze tak przy okazji.

if (phi >= 99)
{
if(quater == 4)
quater = 0;
phi = 0;
quater++;
}
else;

Może się mylę, ale jak quater dojdzie do 4, to po przejściu tego if'a jego wartość będzie 1 a nie 0. A chyba chcesz żeby szło po kolei.

Ja bym dał takie coś:

(quater == 4)?(quater = 0):(quater++);


EDIT:
A nie. To tak miało być. Ewentualnie możesz zastąpić tak: