ШИМ контроллер на ардуино.
- Войдите на сайт для отправки комментариев
Сб, 28/01/2017 - 10:00
Всем привет!
Я не особо сильный ардуинщик,могу только лампочками управлять или типа того. Но потребовалось сделать шим для IGBT модуля на три фазы. Суть такая из постоянного тока получаем переменный три фазы,и изменяя частоту регулируем скорость. В модуле есть 6 транзисторов,которые должны открываться в заданой последовательности. Эта последовательность,жуткая тайна,узнать которую мне не удалось. Зато нашел готовый скетч в интернете,но он не загружается,потому что там переменные не задекларированы.Пишет : exit status 1
'io_init' was not declared in this scope
Помогите исправить,если есть возможность:
#define UN (400.0) //napiecie znamionowe silnika
#define FN (50.0) //czestotliwosc znamionowa silnika
#define P (UN/FN) //wsp. okreslajacy proporcje napiecia do czestotliwoci znamionowej
#define T_PWM (0.000255) //okres sygnalu PWM - ustawiony przez preskaler w licznikach
#define T_MAX (4.0) //okreslenie maksymalnego okresu napiecia wyjsciowego
#define T_MIN (0.02) //minimalny okres napiecia wyjsciowego
#define K_MAX floor(T_MAX/T_PWM) //liczba wartosci okresu dla T_MAX
#define K_MIN ceil(T_MIN/T_PWM) //liczba wartosci okresu dla T_MIN
volatile static unsigned int dlugosc_tab_sin; //zmienna zawierajaca liczbe wartosci w pelnym
//okresie napiecia wyjsciowego
static unsigned int i = 0; //zmienna pomocniacza
volatile static unsigned int licznik_glowny = 0;//zmienna wystepujaca w przerwaniu czyklicznie
//^ co okres T_PWM zwiekszajaca swoja wartosc o 1
static unsigned int next_value_sin = 0; //zmienna ktora wartosc sin nalezy obliczyc
static double t_param=100; //parametr okreslajacy okres napiecia wyjsciowego
static float t = T_PWM; //T_PWM
static float omega_t; //pulsacja napiecia wyjsciowego pomnozona przez T_PWM
static float t_out; //okres wyjsciowy napiecia
static float U_o_param; //parametr okreslajacy wielkosc napiecie wyjsciowego
//^ obliczony na podstawie t_out i U_in
static unsigned int ocr0a, ocr0b, ocr1a;//zmienne pomocnicze do przechowywania obl. wypelnien
static unsigned int ocr1b, ocr2a, ocr2b;//^
static double sin_in; //zmienna zawierajaca parametr funkcji sin
static double blad = 1; //zmienna uzyta do zatrzymania generowania napiecia przy przeciazeniu
static unsigned int analog=0; //zmienna zawierajaca zmierzona wartosc
static double U_in = 0; //zmienna przechowujนca pomiar napiecia ukladu posredniczacego
static double U_rms_max; //maksymalna aktualnie mozliwa do generacji wartosc skuteczna napiecia
static bool a=0; //zmienna logiczna do realizacji dwoch naprzemiennych pomiarow
int main()
{
io_init(); //inicjalizacja wejsc i wyjsc
timers_init(); //inicjalizacja licznikow PWM
adc_init(); //inicjalizacja przetwornika ADC
while(1) //nieskonczona petla z programem glownym
{
if(i==185) //warunek okreslajacy wejscie do funkcji zmiany
{ //parametrow napiecia wysjciowego, wywolanie co okolo 100ms
zmien_predkosc(); //funkcja zmiany parametrow napiecia wyjsciowego
i=0;
}
next_value_sin = licznik_glowny%dlugosc_tab_sin; //kolejna wartoœๆ sinusa do obliczenia
sin_in=omega_t*next_value_sin;
//Расчет регистров значений, определяющих wyjscioweg сигнала заполнения/
ocr0a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6
ocr0b = ocr0a - 1;
ocr1a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 9
ocr1b = ocr1a - 1;
ocr2a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11
ocr2b = ocr2a - 1;
//обновить значения в регистрах/
cli(); //запретить obsloge прервать в случае
//при обновлении прерывания
OCR0A = ocr0a; //pin 6
OCR0B = ocr0b; //pin 5
OCR1AL = ocr1a; //pin 9
OCR1BL = ocr1b; //pin 10
OCR2A = ocr2a; //pin 11
OCR2B = ocr2b; //pin 3
sei(); //zezwolenie na obsloge przerwan
i++;
}
}
void adc_init()
{
ADCSRA |= _BV(ADEN);//uruchomienie przetwornika
ADCSRA |= _BV(ADPS2);//ustawienie preskalera
ADCSRA |= _BV(ADPS1);//^
ADCSRA |= _BV(ADPS0);//^
ADMUX |= _BV(REFS0);// napiecie odniesienia ustawione jako napiecie zasilania
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru
}
void timers_init()
{
cli(); // obsloga przerwan zabroniona
//timer0 init
TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00);
TCCR0B |= _BV(CS01); //preskaler 8
TIMSK0 |= _BV(TOIE0); //flaga od wartosci 0 wlaczona
//timer1 init
TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);
TCCR1B |= _BV(CS11); //preskaler 8
//timer2 init
TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1) | _BV(WGM20);
TCCR2B |= _BV(CS21); //preskaler 8
//Сброс значения licznik3w
TCNT0 = 0;
TCNT1L = 0;
TCNT2 = 0;
/* он считает g3re до 255, а затем на d3 ณ: / \ / \ / \
значение 255 прерывается, на котором выполняется августа
измерения напряжений и токов
*/
sei(); //zezwolenie na obsloge przerwan
}
void io_init()
{
pinMode(6, OUTPUT); //OC0A
pinMode(5, OUTPUT); //OC0B
pinMode(9, OUTPUT); //OC1A
pinMode(10, OUTPUT);//OC1B
pinMode(11, OUTPUT);//OC2A
pinMode(3, OUTPUT); //OC2B
pinMode(2, INPUT);
pinMode(4, INPUT);
pinMode(12, OUTPUT);
}
ISR(TIMER0_OVF_vect) //прерывание значений 0 licznika0
{
analog = ADC;
if(a)
{
U_in = 0.0709*analog;
ADMUX |= _BV(MUX0); //wybranie wejscia ADC1 do pomiaru pradu
}
else
{
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru napiecia
if(analog>579)
{
blad = 0; //jezeli przeciazenie wylaczenie generacji napiecia
digitalWrite(12, HIGH); //zapalenie diody
}
}
ADCSRA |= _BV(ADSC);//start odczytywania pomiaru
a=a^1; //bramka XOR neguje wartosc logiczna a
licznik_glowny++;
if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0;
}
void zmien_predkosc()
{
t_param = map(analogRead(3),0,1023,0,100);
U_rms_max = U_in*0.62; //wartosc 0.62 wyzanczona eksperymentalnie
bool up; //zmienna logiczna, informuje o nacisnietym przycisku zwieksz czestotliwosc
bool down; //zmienna logiczna, informuje o nacisnietym przycisku zmiejsz czestotliwosc
up = digitalRead(4); //odczyt: czy nacisniety przycisk zwieksz czestotliwosc
down = digitalRead(2); //odczyt: czy nacisniety przycisk zmiejsz czestotliwosc
if(up==1) t_param--; //jezeli nacisniety przycisk zwieksz czestotliwosc to zmiejsz okres
if(down==1) t_param++; //jezeli nacisniety przycisk zmniejsz czestotliwosc to zwieksz okres
if(t_param<0) t_param=0; //zabezpieczenie przekroczenia wartosci skrajnych
if(t_param>100) t_param=100;//^
dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/500+K_MIN);//ilosc wartosci wypelnien w jednym okresie
t_out = T_PWM*dlugosc_tab_sin; //obliczenie okresu napiecia wyjsciowego
omega_t = t*2*PI/t_out; //obliczenie pulsacji napiecia wyjsciowego
U_o_param = (P/t_out)/U_rms_max; //obliczenie parametru okreslajacego wielkosc napiecia wyjsciowego
if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //napi๊cie na wyjsciu przy niskiej czestotliwosci 10V
if(U_o_param>1) U_o_param=1;
//zabezpieczenie przekroczenia wartosci skrajnych
blad = 1; //jezeli przeciazenie wylaczenie generacji napiecia
digitalWrite(12, LOW); //zapalenie diody
}
Может быть название и страшное у этого скетча,но по сути он управляет миганием 6 диодов , частота изменяется резистором. Уже второй месяц ковыряю эту тему,лучше этого скетча не нашел ничего. Но у меня почему то не работает.
Вот я одного не пойму. Почему вы не переведете комментарии на русский и вставите в программу.
ПС: зачем извращаться нарисуйте прогрограмму с помощью millis().
/*to_144.ino ключ + полуволны->2 (plus_pin) 0 закрыто /1 открыто ключ - полуволны->3 (minus_pin) 0 закрыто /1 открыто */ const uint32_t period = 100; // период 0,1 сек - частота 10 гц const byte plus_pin = 2; bool plus_ON ; // флаг открытия ключа+ const uint32_t T1 = 12; // время открытия ключа+ bool plus_OFF ; // флаг закрытия ключа+ const uint32_t T2 = 27; // время закрытия ключа+ const byte minus_pin = 3; bool minus_ON ; // флаг открытия ключа- const uint32_t T3 = 62; // время открытия ключа- bool minus_OFF ; // флаг закрытия ключа- const uint32_t T4 = 77; // время закрытия ключа- void setup() { pinMode(plus_pin, OUTPUT); digitalWrite(plus_pin, 0); plus_ON = 0; plus_OFF = 0; pinMode(minus_pin, OUTPUT); digitalWrite(minus_pin, 0); minus_ON = 0; minus_OFF = 0; } void loop() { static uint32_t past = 0 ; if (millis() - past >= period) { // если прошeл период past = millis() ; plus_ON = 1; minus_ON = 1; } if (plus_ON && millis() - past >= T1) { // если подошло время включить ключ + plus_ON = 0; plus_OFF = 1; digitalWrite(plus_pin, 1); } if (plus_OFF && millis() - past >= T2) {// если подошло время выключить ключ + plus_OFF = 0; digitalWrite(plus_pin, 0); } if (minus_ON && millis() - past >= T3) {// если подошло время включить ключ - minus_ON = 0; minus_OFF = 1; digitalWrite(minus_pin, 1); } if (minus_OFF && millis() - past >= T4) {// если подошло время выключить ключ - minus_OFF = 0; digitalWrite(minus_pin, 0); } }дак а где я задержки возьму? и какую обмотку когда какую полярность подавать?
я бы может и сваял что то подобное,даже на микросхемах.только данных мало исходных. а если этот скетч оживлю,то подключу к модулю транзисторному и всё пошло. У поляка этотого работает и еще у одного чувака работает,но он тоже не русский и тайну не раскрывает.
дак а где я задержки возьму? и какую обмотку когда какую полярность подавать?
Если бы вы сказали , где бы вам мозги взять, то бы не так удивился. Вы что не знаете, что такое переменный ток, что такое синус.
я бы может и сваял что то подобное,даже на микросхемах.только данных мало исходных. а если этот скетч оживлю,то подключу к модулю транзисторному и всё пошло. У поляка этотого работает и еще у одного чувака работает,но он тоже не русский и тайну не раскрывает.
Ну мозги есть не только у полякоговорящих.http://electrono.ru/elektricheskie-mashiny/vrashhayushheesya-magnitnoe-pole
http://electrono.ru/3-invertory-napryazheniya-i-toka-energ_electr
Я конечно новичок на этом форуме. Но я не просил лекцию по электротехнике. А просил подсказать как скетч исправить,а если мозгов не хватает это понять,то наверное не надо спамить. Мне не надо мериться умами,мне надо решить проблему.
Ну ладно, "походите по рынку". Я вам дал все для понимания, но если пациент хочет в морг, то врач тут бессилен.
Ну ладно, "походите по рынку". Я вам дал все для понимания, но если пациент хочет в морг, то врач тут бессилен.
Да, я понял уже что ты "спец". Можешь дальше не пыжиться.
Если мне надо будет ходить по рынку,то ты будешь последний к кому я подойду. И вообще если ходить по рынку на нафиг надо ардуино и этот форум? Я просто закажу у нормального чувака плату и он мне её сделает,под мои хотелки.
Пишет : exit status 1
Проверил У меня он компилируется. Arduino 1.6.10. Попробуйте сменить IDE
Этот скеч будет работать на меге. Ну или с некоторыми натяжками на леонарде или мини. Uno & nano не будут работать. А вообще для данной задачи лучше подходит stm32. У него первый таймер имеет режим генерации трёхфазного управления мотором и входной делитель позволяет плавно менять частоту. На AVR плавного изменения частоты не получится.
Пишет : exit status 1
Проверил У меня он компилируется. Arduino 1.6.10. Попробуйте сменить IDE
Большое спасибо за ответ! А как мне сменить IDE ? В интернете есть видео где он работает даже на Ардуино Микро.
А как мне сменить IDE ?
Зайти на официальный сайт проекта Arduino и скачать оттуда.
Спасибо всем кто откликнулся!
Не было времени ответить раньше.
Смена IDE помогла,всё загрузилось и работает. Осталось подключить к IGBT модулю,но это уже другая задача.