Silnik na prąd stały kiedy jest napędzany staje się prądnicą. Jest tak więc nawet kiedy kreci się siłą swojej bezwładności. Można to wykorzystać.
Sterując silnikiem poprzez PWM włączamy i wyłączamy przepływ prądu. W momencie kiedy silnik nie jest zasilany można zmierzyć napięcie które wytwarza od sam. Jest ono proporcjonalne do jego prędkości.
Im wyższa prędkość tym niższe jest napięcie odczytywane na ADC mikrokontrolera. Dlaczego tak się dzieje można poczytać wszędzie. Ja skupię się na tym jak to praktycznie napisać i wykorzystać.
Najpierw napisałem program w którym za pomocą przycisków bądź enkodera można regulować wartość sygnału PWM. Dzięki temu można poznać wartości które docierają do ADC przy różnych prędkościach. Interesują nas właśnie wartości bez obciążenia. Do nich będzie dążył mikrokontroler kiedy silnik zostanie obciążony.
$regfile = "m32adef.dat" $crystal = 8000000 $hwstack = 128 $swstack = 64 $framesize = 64 Config Timer1 = Pwm , Pwm = 9 , Compare_a_pwm = Clear_up , Compare_b_pwm = Disconnect , Prescale = 1 Enable Compare1a : On Compare1a Get_bemf Nosave Dim Current_off As Byte , Pwm_val As Word Config Adc = Single , Prescaler = Auto , Reference = Avcc Dim Bemf As Word ' 9BIT PWM to zakres od 0 do 512 ' ustawmy cos do testu by nie zaciemniac Pwm_val = 150 Pwm1a = Pwm_val Enable Interrupts Do If Current_off = 1 Then Current_off = 0 'zmierz napiecie Bemf = Getadc(2) 'mozemy poznac napiecie jakie tu panuje kiedy silnik kreci sie 'z pozadaną przez nas predkoscia End If Loop End 'kiedy nastepuje Compare Match i odlaczenie zrodla Get_bemf: $asm PUSH R24 !in R24, sreg PUSH R24 $end Asm 'ustaw flage Current_off = 1 ' Tuned with NoSave Tool $asm POP R24 !out sreg, r24 POP R24 $end Asm Return
Jeśli zależy nam by silnik kręcił się z jakąś konkretną prędkością możemy badać jego prędkość stroboskopowym miernikiem prędkości. Poprzez zmianę PWM ustawiamy prędkość silnika której potem ma pilnować mikrokontroler i odczytujemy wartość która dociera do ADC z powrotem z silnika.
Stroboskopowy miernik obrotów - pod tym linkiem można znaleźć projekt i kod źródłowy który można wrzucić na zestaw uruchomieniowy jeśli chcemy wyskalować tylko jeden silnik
Teraz wystarczy odwrócić logikę. Sterownik ustawia PWM zależnie od tego jaki sygnał zwrotny otrzymał z silnika. Kiedy wartość jest zbyt wysoka oznacza, że silnik zwolnił i należy podnieść wartość PWM. Analogicznie kiedy wartość BEMF spada oznacza że silnik kreci się już za szybko i należy wartość PWM zmniejszyć.
W ten sposób niezależnie od obciążenia mamy ciągle tę samą prędkość silnika.
$regfile = "m32adef.dat" $crystal = 8000000 ' taktowanie procesora $hwstack = 128 ' default 32 $swstack = 64 ' default 8 $framesize = 64 ' default 16 Config Timer1 = Pwm , Pwm = 9 , Compare_a_pwm = Clear_up , Compare_b_pwm = Disconnect , Prescale = 1 Enable Compare1a : On Compare1a Get_bemf Nosave Dim Current_off As Byte , Pwm_val As Word , Wanted_bemf As Word Config Adc = Single , Prescaler = Auto , Reference = Avcc Dim Bemf As Word Wanted_bemf = 400 'tej wartości mikrokontroler będzie pilnował Enable Interrupts Do If Current_off = 1 Then Current_off = 0 'zmierz napiecie Bemf = Getadc(2) If Bemf > Wanted_bemf Then If Pwm_val < 1022 Then Incr Pwm_val Elseif Bemf < Wanted_bemf Then If Pwm_val > 0 Then Decr Pwm_val End If Pwm1a = Pwm_val End If Loop End 'kiedy nastepuje Compare Match i odlaczenie zrodla Get_bemf: $asm PUSH R24 !in R24, sreg PUSH R24 $end Asm 'ustaw flage Current_off = 1 ' Tuned with NoSave Tool $asm POP R24 !out sreg, r24 POP R24 $end Asm Return
Programy na filmie pozwalają wybrać kilka prędkości, ale na stronie chciałem przedstawić sprawę jak najprościej.
Widać, że wartość PWM zwiększa się kiedy silnikowi zada się obciążenie. Układ reguluje się sam.