плавный пуск + регулятор скорости коллекторного двигателя

Обсуждаем контроллеры компании Atmel.
Serrad
Прорезались зубы
Сообщения: 239
Зарегистрирован: Чт янв 16, 2014 00:06:54

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Serrad »

Болгарка плавно набирает обороты при запуске, когда регулятор установлен на минимум, после этого можно добавить обороты до нужной величины.
Когда все функционирует идеально- становится скучно жить.
Реклама
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Dimon456 »

BlackKilkennyCat писал(а):Это схема детектора перехода через ноль с бп, симистор к ней как-то рано.
Там же еще МК будет? Или полностью схему нарисовать?
BlackKilkennyCat писал(а):Управляющий ток, если его действительно не хватает, обеспечивают транзистором. Зачем сразу лепить оптрон?
С чего вы будете брать питание для этого транзистора?
U2010B выдает 125 мА, это более чем достаточно для открытия любого симистора.
Понадобится высоковольтный транзистор и ...., напомните мне чем симистор отличается от тиристора?

MOC3023 - это готовое решение, с минимумом обвеса.

Мое мнение остается неизменным - существует специализированная микросхема фазового управления с обратной связью по току и защитой от перегрузки U2010B. Остальное "велосипед".

Но если все таки "велосипед", то сначала я бы собрал источник питания, нагрузил бы его нагрузкой 100 - 150 мА, светодиод поставил бы для визуального контроля, и раз так 50 включить-выключить, если не увидим "зарождение электрона", то все ОК.
Тут же прибором контролируем наличие 5 Вольт, осциллографом проверяем схему детектора, возможно так же применение стабилизатора AMS1117. (?)
PS на схеме не дорисовал один резистор килоом так на 300 параллельно С1.
Реклама
Аватара пользователя
musor
Друг Кота
Сообщения: 39197
Зарегистрирован: Сб сен 13, 2014 16:27:32
Откуда: СпиртоГонск созвездия Омега

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение musor »

таких микрух хватает
U2010B. лиш 1из них и не самая распространеная
у нас например в рознице не наблюдаю сейчас
ZМудрость(Опыт и выдержка) приходит с годами.
Все Ваши беды и проблемы, от недостатка знаний.
Умный и у дурака научится, а дураку и ..
Алберт Ейнштейн не поможет и ВВП не спасет.и МЧС опаздает
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение BlackKilkennyCat »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3899656#p3899656"]Там же еще МК будет? Или полностью схему нарисовать?[/uquote]
Вообще-то да. Какой смысл от очередного варианта бестрансформаторного питания и чем оно отличается от ранее описанных?
С чего вы будете брать питание для этого транзистора?
U2010B выдает 125 мА, это более чем достаточно для открытия любого симистора.
а она эти 125 мА где берет?
Понадобится высоковольтный транзистор
нет
и ...., напомните мне чем симистор отличается от тиристора?
поясните, что имеете в виду, без намеков.
MOC3023 - это готовое решение, с минимумом обвеса.
дорого и много места. Кроме того, надо быть последовательным - какой смысл готовое решение в одном лишь месте? Давайте и всё остальное в виде готового решения, они есть.
существует специализированная микросхема фазового управления с обратной связью по току и защитой от перегрузки U2010B. Остальное "велосипед".
Велосипеды изобретают до сих пор. Ваш вариант блока питания с детектором нуля - тот же велосипед, как и 99% радиолюбительских поделок в сегодняшнее время, к чему об этом разговаривать? Кроме того, существует куча различных требований к режимам работы электроприводов, и не всегда какая-то уникально-заточенная микросхема может их обеспечить. И как заметил musor, микросхема редкая, а вариант покупать на али - да лучше выкинуть электропривод и пойти пить чай...
Реклама
Эиком - электронные компоненты и радиодетали
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Dimon456 »

BlackKilkennyCat писал(а):Давайте и всё остальное в виде готового решения, они есть.
U2010B
Реклама
BlackKilkennyCat
Собутыльник Кота
Сообщения: 2905
Зарегистрирован: Ср ноя 29, 2017 06:58:50

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение BlackKilkennyCat »

ну, вот так лучше :)
Реклама
Аватара пользователя
Serzh2000
Опытный кот
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Serzh2000 »

Изображение

во че нашел! :)))

фьюзы: Low = 0x2A , High = 0xFB

Добавлено after 5 hours 53 minutes 43 seconds:
Re: плавный пуск + регулятор скорости коллекторного двигателя
допишите плавный пуск, кому не трудно :? у меня не получается :dont_know:
Спойлер#define F_CPU (9600000uL / 8)

#include "stdint.h"
#include "avr/io.h"
#include "avr/interrupt.h"
#include "util/delay.h"


#define PWM_AC_PULSE 4
#define PWM_MIN 5
#define PWM_MAX_DIF 10

#define LIMIT_INC 10

#define STARTUP_DELAY 50

#define KBD_ADC_THRESHOLD 5
#define KBD_CNT_ONOFF 5
#define KBD_CNT_ONOFF_THRESHOLD 50
#define KBD_CNT_LONG 200


inline void pwm2_on() { PORTB |= (1<<PB1); }
inline void pwm2_off(){ PORTB &= ~(1<<PB1); }




volatile uint8_t sync_flag; // PWM top sync flag

volatile uint8_t pwm_top=0xFF; // PWMs maximum
register uint8_t pwm_set[2] asm("r2"); // PWMS set
register uint8_t pwm_cur[2] asm("r4"); // PWMS current
register uint8_t pwm_ac asm("r6"); // AC sync flag

uint8_t limit_en[2] = {1,1},limit[2];

uint8_t startup_cnt = STARTUP_DELAY;

uint8_t kbd_en[2], kbd_cnt[2], kbd_prev[2],kbd_cur[2], kbd_inc[2];



int main(){
// setup

// GPIO
PORTB |= (1<<PB3)|(1<<PB2);
DDRB &= ~((1<<PB2)|(1<<PB3));
PORTB &= ~(1<<PB1);
DDRB |= (1<<PB1);

// PCINT
GIMSK |= (1<<PCIE);
PCMSK = (1<<PCINT2);

// timer 0
TCCR0A = 0;
TCCR0B = (1<<CS01)|(1<<CS00);
TIMSK0 = (1<<TOIE0)|(1<<OCIE0B)|(1<<OCIE0A);

// ADC
ADMUX = (1<<ADLAR)|(1<<MUX1);
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
ADCSRB = 0;
DIDR0 = 0;




pwm_set[0] = pwm_set[1] = 0xFF;


sei();

// main loop
while(1){
// ZC sync
if (sync_flag){
sync_flag = 0;

// decrement startup timer
if (startup_cnt) startup_cnt--;

// update limiters
else for (uint8_t i=0; i<2; i++){
if (limit_en == 1){ // limit increment
if (limit < (0xFF - LIMIT_INC)) limit += LIMIT_INC;
else {
limit = 0xFF;
limit_en = 0;
}
} else if (limit_en == 2){ // limit decrement
if (limit > LIMIT_INC) limit -= LIMIT_INC;
else {
limit = 0;
limit_en = 0;
}
}
}

// calculate PWMs
uint8_t pwm = (!pwm_set[0]) ? 0 : (pwm_set[0] < limit[0]) ? pwm_set[0] : limit[0];
pwm = pwm_top - (((uint16_t)pwm * pwm_top) >> 8);
pwm_cur[0] = (startup_cnt || (pwm_set[0] < PWM_MIN)||((pwm_top - pwm) < PWM_MAX_DIF)) ? 0 : pwm;

pwm = (!pwm_set[1]) ? 0 : (pwm_set[1] < limit[1]) ? pwm_set[1] : limit[1];
pwm = pwm_top - (((uint16_t)pwm * pwm_top) >> 8);
pwm_cur[1] = (startup_cnt || (pwm_set[1] < PWM_MIN)||((pwm_top - pwm) < PWM_MAX_DIF)) ? 0 : pwm;

// read ADC
if (ADMUX & (1<<MUX0)){ ADMUX &= ~(1<<MUX0); if (!kbd_en[1]) pwm_set[1] = ADCH;
} else { ADMUX |= (1<<MUX0); if (!kbd_en[0]) pwm_set[0] = ADCH; }
ADCSRA |= (1<<ADSC);



}
}

// exit
return 0;
}



ISR(TIM0_COMPB_vect){
if (pwm_cur[1]){
pwm2_on();
sei();
if (pwm_ac){
_delay_us(PWM_AC_PULSE);
pwm2_off();
}
}
}

ISR(TIM0_OVF_vect){
pwm2_off(); // PWMs off
pwm_top = 0xFF; // update PWM top
OCR0A = pwm_cur[0]; OCR0B = pwm_cur[1]; // reload PWMs
sync_flag = 1; pwm_ac = 0; // set Sync flag / reset AC flag
TIFR0 |= (1<<OCF0A)|(1<<OCF0B); // reset capture interrupts
}

// external interrupt on zero-cross
ISR(PCINT0_vect){
pwm2_off(); // PWMs off
pwm_top = TCNT0; // get PWM top
// uint8_t cnt = TCNT0; // get PWM top
TCNT0 = 0; // reset TCNT0
OCR0A = pwm_cur[0]; OCR0B = pwm_cur[1]; // reload PWMs
sync_flag = pwm_ac = 1; // set Sync/AC flag
// pwm_top = ((uint16_t)cnt + pwm_top) >> 1; // filter PWM top
TIFR0 |= (1<<OCF0A)|(1<<OCF0B)|(1<<TOV0); // reset capture interrupts
}
Вложения
t13-dim.zip
(151.48 КБ) 300 скачиваний
Аватара пользователя
Serzh2000
Опытный кот
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Serzh2000 »

Спойлер#define F_CPU (9600000uL / 8 )

#include "stdint.h"
#include "avr/io.h"
#include "avr/interrupt.h"
#include "util/delay.h"


#define PWM_AC_PULSE 4
#define PWM_MIN 5
#define PWM_MAX_DIF 10

#define LIMIT_INC 10 //ПРЕДЕЛ

#define STARTUP_DELAY 50 //ЗАДЕРЖКА ЗАПУСКА

#define KBD_ADC_THRESHOLD 5 //ПОРОГ АЦП



inline void pwm2_on() { PORTB |= (1<<PB1); }
inline void pwm2_off(){ PORTB &= ~(1<<PB1); }




volatile uint8_t sync_flag; //Флаг верхней синхронизации ШИМ
volatile uint8_t pwm_top=0xFF; // Максимальное ШИМ
register uint8_t pwm_set[2] asm("r2"); // ШИМ-комплект
register uint8_t pwm_cur asm("r4"); // Ток ШИМ
register uint8_t pwm_ac asm("r6"); // Флаг синхронизации переменного тока

unsigned int start_first = 0; // флаг первого запуска

uint8_t limit_en[2] = {1,1},limit[2];

uint8_t startup_cnt = STARTUP_DELAY;

uint8_t kbd_en[2]; //kbd_inc[2];



int main(){
// setup

// GPIO
PORTB |= (1<<PB3)|(1<<PB2);
DDRB &= ~((1<<PB2)|(1<<PB3));
PORTB &= ~(1<<PB1);
DDRB |= (1<<PB1);

// PCINT
GIMSK |= (1<<PCIE);
PCMSK = (1<<PCINT2);

// timer 0
TCCR0A = 0;
TCCR0B = (1<<CS01)|(1<<CS00);
TIMSK0 = (1<<TOIE0)|(1<<OCIE0B)|(1<<OCIE0A);

// ADC
ADMUX = (1<<ADLAR)|(1<<MUX1);
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
ADCSRB = 0;
DIDR0 = 0;

sei();

// main loop
while(1){




// ZC sync
if (sync_flag){
sync_flag = 0;

//===плавный старт======================
if (start_first==0){
for (pwm_cur = 0; pwm_cur < 0xFF; pwm_cur++){

for (int k = 0; k<10000; k++){ // ПОТОМ УБРАТЬ !!!

if (!kbd_en[1]) pwm_set[1] = ADCH;

if (!kbd_en[0]) pwm_set[0] = ADCH;
}
}
start_first = 1;
}
//========


// таймер запуска уменьшение
if (startup_cnt) startup_cnt--;

// ограничители обновления
else for (uint8_t i=0; i<2; i++){
if (limit_en == 1){ // предельное увеличение
if (limit < (0xFF - LIMIT_INC)) limit += LIMIT_INC;
else {
limit = 0xFF;
limit_en = 0;
}
} else if (limit_en == 2){ //предельное уменьшение
if (limit > LIMIT_INC) limit -= LIMIT_INC;
else {
limit = 0;
limit_en = 0;
}
}
}

// расчет ШИМ
uint8_t pwm = (!pwm_set[0]) ? 0 : (pwm_set[0] < limit[0]) ? pwm_set[0] : limit[0];
pwm = pwm_top - (((uint16_t)pwm * pwm_top) >> 8 ) ;


pwm = (!pwm_set[1]) ? 0 : (pwm_set[1] < limit[1]) ? pwm_set[1] : limit[1];
pwm = pwm_top - (((uint16_t)pwm * pwm_top) >> 8 ) ;
pwm_cur = (startup_cnt || (pwm_set[1] < PWM_MIN)||((pwm_top - pwm) < PWM_MAX_DIF)) ? 0 : pwm;

// read ADC
if (ADMUX & (1<<MUX0)){ ADMUX &= ~(1<<MUX0); if (!kbd_en[1]) pwm_set[1] = ADCH;
} else { ADMUX |= (1<<MUX0); if (!kbd_en[0]) pwm_set[0] = ADCH; }
ADCSRA |= (1<<ADSC);
}
}

// exit
return 0;
}



ISR(TIM0_COMPB_vect){ //внешнее прирывание
if (pwm_cur){
pwm2_on();
sei();
if (pwm_ac){
_delay_us(PWM_AC_PULSE); //ШИМ-ИМПУЛЬС ПЕРЕМЕННОГО ТОКА
pwm2_off();
}
}
}

ISR(TIM0_OVF_vect){
pwm2_off(); // PWMs off
pwm_top = 0xFF; // обновление PWM сверху
OCR0B = pwm_cur; // перезарядка ШИМ
sync_flag = 1; pwm_ac = 0; // установить флаг синхронизации / сбросить флаг переменного тока
TIFR0 |= (1<<OCF0A)|(1<<OCF0B); // сброс прерываний захвата
}

// внешнее прерывание на нулевом пересечении
ISR(PCINT0_vect){
pwm2_off(); // PWMs off
pwm_top = TCNT0; // получить ШИМ сверху
// uint8_t cnt = TCNT0; //получить ШИМ сверху
TCNT0 = 0; // сброс TCNT0
OCR0B = pwm_cur; // перезарядка ШИМ
sync_flag = pwm_ac = 1; // установить флаг синхронизации/переменного тока
// pwm_top = ((uint16_t)cnt + pwm_top) >> 1; // фильтр ШИМ сверху
TIFR0 |= (1<<OCF0A)|(1<<OCF0B)|(1<<TOV0); // сброс прерываний захвата
}






ткните в код, пожалуйста, где эта "переменная" напряжения на центральном контакте переменного резистора.
чтобы при подачи питания скорость двигателя плавно возросла до этой "переменной"

for (pwm_cur = 0; pwm_cur < "переменная"на центральном контакте переменного резистора; pwm_cur++)
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение oleg110592 »

тэг 'Code' есть для исходников - покрасивше будет
переменная вроде эта с ацп считывается

Код: Выделить всё

 pwm_set[0] = ADCH; 
Аватара пользователя
Serzh2000
Опытный кот
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Serzh2000 »

Код: Выделить всё

				//===плавный старт===
					
		             if (start_first==0){
						 //int STOP =ADCH;
							for (pwm_cur = 0xC8; pwm_cur > ADCH; pwm_cur--){

								    for (int k = 0; k<10000; k++){  // ПОТОМ УБРАТЬ !!!
								 
									if (!kbd_en[1]) pwm_set[1] =ADCH;
									
								    if (!kbd_en[0]) pwm_set[0] =ADCH;	
															}
								}
                              start_first = 1;
							}
	         //===================	

НИ ФИГА НЕ ПОЛУЧАЕТСЯ :dont_know:

начинается с 0xC8 правильно, и не останавливаясь на середине примерно 0х7F увеличивает обороты до 0хFF и только потом становиться в нужное положение :?




порект взят с https://www.radiokot.ru/forum/viewtopic.php?p=2353553 автор ncp1400
Вложения
13_dimmer.zip
(75.06 КБ) 263 скачивания
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение oleg110592 »

вообще плавный пуск есть, но коротенький, удлинить наверное можно
Изображение
повыкидывал "лишнее":
main.c
Спойлер

Код: Выделить всё

/*
 * main.c
 *
 *  Created on: May 11, 2015
 *      Author: qwer
 */

#include "main.h"

volatile uint8_t sync_flag; // PWM top sync flag

volatile uint8_t pwm_top = 0xFF;	   // PWMs maximum
register uint8_t pwm_set[2] asm("r2"); // PWMS set
register uint8_t pwm_cur[2] asm("r4"); // PWMS current
register uint8_t pwm_ac asm("r6");	   // AC sync flag

uint8_t limit_en[2] = {1, 1}, limit[2];

uint8_t startup_cnt = STARTUP_DELAY;

uint8_t kbd_en[2], kbd_cnt[2], kbd_prev[2], kbd_cur[2], kbd_inc[2];

uint8_t pwm_sete[2] EEMEM;
register uint8_t eep_update_cnt asm("r7");

#define pwm2_on() PORTB |= (1 << PB1)
#define pwm2_off() PORTB &= ~(1 << PB1)

int main()
{
	// setup

	// GPIO
	PORTB |= (1 << PB3) | (1 << PB4) | (1 << PB2);
	DDRB &= ~((1 << PB2) | (1 << PB3) | (1 << PB4));
	PORTB &= ~((1 << PB0) | (1 << PB1));
	DDRB |= (1 << PB0) | (1 << PB1);

	// PCINT
	GIMSK |= (1 << PCIE);
	PCMSK = (1 << PCINT2);

	// timer 0
	TCCR0A = 0;
	TCCR0B = (1 << CS01) | (1 << CS00);
	TIMSK0 = (1 << TOIE0) | (1 << OCIE0B) | (1 << OCIE0A);

	// ADC
	ADMUX = (1 << ADLAR) | (1 << MUX1);
	ADMUX |= (1 << MUX0);
	ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
	ADCSRB = 0;
	DIDR0 = 0;

	// check buttons/Pots
	for (uint8_t i = 0; i < 2; i++)
	{
		while (ADCSRA & (1 << ADSC))
			;
		kbd_en[i] = (ADCH < KBD_ADC_THRESHOLD) || (ADCH > (0xFF - KBD_ADC_THRESHOLD));
		if (kbd_en[i])
			limit_en[i] = 0;
		//ADMUX ^= (1 << MUX0);
		ADCSRA |= (1 << ADSC);
	}

	// restore current power from EEPROM
	//	pwm_set[0] = eeprom_read_byte(&pwm_sete[0]);
	//	pwm_set[1] = eeprom_read_byte(&pwm_sete[1]);
	//	pwm_set[0] = pwm_set[1] = 0xFF;
	EEARL = 0;
	EECR |= (1 << EERE);
	pwm_set[0] = EEDR;
	EEARL = 1;
	EECR |= (1 << EERE);
	pwm_set[1] = EEDR;

	sei();

	// main loop
	while (1)
	{
		// ZC sync
		if (sync_flag)
		{
			sync_flag = 0;

			// decrement startup timer
			if (startup_cnt)
			{
				startup_cnt--;
			}

			// update limiters
			else
			{
				for (uint8_t i = 0; i < 2; i++)
				{
					if (limit_en[i] == 1)
					{ // limit increment
						if (limit[i] < (0xFF - LIMIT_INC))
							limit[i] += LIMIT_INC;
						else
						{
							limit[i] = 0xFF;
							limit_en[i] = 0;
						}
					}
					else if (limit_en[i] == 2)
					{ // limit decrement
						if (limit[i] > LIMIT_INC)
							limit[i] -= LIMIT_INC;
						else
						{
							limit[i] = 0;
							limit_en[i] = 0;
						}
					}
				}
			}
			// calculate PWMs

			uint8_t pwm = (!pwm_set[1]) ? 0 : (pwm_set[1] < limit[1]) ? pwm_set[1] : limit[1];
			pwm = pwm_top - (((uint16_t)pwm * pwm_top) >> 8);
			pwm_cur[1] = (startup_cnt || (pwm_set[1] < PWM_MIN) || ((pwm_top - pwm) < PWM_MAX_DIF)) ? 0 : pwm;

			// read ADC
			if (ADMUX & (1 << MUX0))
			{
				if (!kbd_en[1])
					pwm_set[1] = ADCH;
			}
			ADCSRA |= (1 << ADSC);
		}
	}

	// exit
	return 0;
}

ISR(TIM0_COMPA_vect)
{
}

ISR(TIM0_COMPB_vect)
{
	if (pwm_cur[1])
	{
		pwm2_on();
		sei();
		if (pwm_ac)
		{
			_delay_us(PWM_AC_PULSE);
			pwm2_off();
		}
	}
}

ISR(TIM0_OVF_vect)
{
	pwm2_off();			// PWMs off
	pwm_top = 0xFF;		// update PWM top
	OCR0B = pwm_cur[1]; // reload PWMs
	sync_flag = 1;
	pwm_ac = 0;							  // set Sync flag / reset AC flag
	TIFR0 |= (1 << OCF0A) | (1 << OCF0B); // reset capture interrupts
}

// external interrupt on zero-cross
ISR(PCINT0_vect)
{
	pwm2_off();											// PWMs off
	pwm_top = TCNT0;									// get PWM top
														//	uint8_t cnt = TCNT0;                      // get PWM top
	TCNT0 = 0;											// reset TCNT0
	OCR0B = pwm_cur[1];									// reload PWMs
	sync_flag = pwm_ac = 1;								// set Sync/AC flag
														//	pwm_top = ((uint16_t)cnt + pwm_top) >> 1; // filter PWM top
	TIFR0 |= (1 << OCF0A) | (1 << OCF0B) | (1 << TOV0); // reset capture interrupts
}
main.h
Спойлер

Код: Выделить всё

/*
 * main.h
 *
 *  Created on: May 11, 2015
 *      Author: qwer
 */

#ifndef MAIN_H_
#define MAIN_H_

#define F_CPU (9600000uL / 8)

#include "stdint.h"
#include "avr/io.h"
#include "avr/interrupt.h"
#include "util/delay.h"
#include "avr/eeprom.h"

#define PWM_AC_PULSE            4
#define PWM_MIN                 5
#define PWM_MAX_DIF             10

#define LIMIT_INC               10

#define STARTUP_DELAY           50

#define KBD_ADC_THRESHOLD       5
#define KBD_CNT_ONOFF           5
#define KBD_CNT_ONOFF_THRESHOLD 50
#define KBD_CNT_LONG            200

#endif /* MAIN_H_ */
Аватара пользователя
Serzh2000
Опытный кот
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Serzh2000 »

вообще плавный пуск есть, но коротенький, удлинить наверное можно
наверно... :dont_know: я только второй день ломаю голову... еще вся жизнь впереди :wink:
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение oleg110592 »

легким движением руки удлиняем в три раза (больше тоже легко - увеличиваем магическую цифру '3' ):
Изображение
Спойлер

Код: Выделить всё

/*
 * main.c
 *
 *  Created on: May 11, 2015
 *      Author: qwer
 */

#include "main.h"

volatile uint8_t sync_flag; // PWM top sync flag
uint8_t sync_cnt;

volatile uint8_t pwm_top = 0xFF;	   // PWMs maximum
register uint8_t pwm_set[2] asm("r2"); // PWMS set
register uint8_t pwm_cur[2] asm("r4"); // PWMS current
register uint8_t pwm_ac asm("r6");	   // AC sync flag

uint8_t limit_en[2] = {1, 1}, limit[2];

uint8_t startup_cnt = STARTUP_DELAY;

uint8_t kbd_en[2], kbd_cnt[2], kbd_prev[2], kbd_cur[2], kbd_inc[2];

uint8_t pwm_sete[2] EEMEM;
register uint8_t eep_update_cnt asm("r7");

#define pwm2_on() PORTB |= (1 << PB1)
#define pwm2_off() PORTB &= ~(1 << PB1)

int main()
{
	// setup

	// GPIO
	PORTB |= (1 << PB3) | (1 << PB4) | (1 << PB2);
	DDRB &= ~((1 << PB2) | (1 << PB3) | (1 << PB4));
	PORTB &= ~((1 << PB0) | (1 << PB1));
	DDRB |= (1 << PB0) | (1 << PB1);

	// PCINT
	GIMSK |= (1 << PCIE);
	PCMSK = (1 << PCINT2);

	// timer 0
	TCCR0A = 0;
	TCCR0B = (1 << CS01) | (1 << CS00);
	TIMSK0 = (1 << TOIE0) | (1 << OCIE0B) | (1 << OCIE0A);

	// ADC
	ADMUX = (1 << ADLAR) | (1 << MUX1);
	ADMUX |= (1 << MUX0);
	ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
	ADCSRB = 0;
	DIDR0 = 0;

	// check buttons/Pots
	for (uint8_t i = 0; i < 2; i++)
	{
		while (ADCSRA & (1 << ADSC))
			;
		kbd_en[i] = (ADCH < KBD_ADC_THRESHOLD) || (ADCH > (0xFF - KBD_ADC_THRESHOLD));
		if (kbd_en[i])
			limit_en[i] = 0;
		//ADMUX ^= (1 << MUX0);
		ADCSRA |= (1 << ADSC);
	}

	// restore current power from EEPROM
	//	pwm_set[0] = eeprom_read_byte(&pwm_sete[0]);
	//	pwm_set[1] = eeprom_read_byte(&pwm_sete[1]);
	//	pwm_set[0] = pwm_set[1] = 0xFF;
	EEARL = 0;
	EECR |= (1 << EERE);
	pwm_set[0] = EEDR;
	EEARL = 1;
	EECR |= (1 << EERE);
	pwm_set[1] = EEDR;
	sync_cnt = 0;

	sei();

	// main loop
	while (1)
	{
		// ZC sync
		if (sync_flag)
		{

			sync_flag = 0;
			if (++sync_cnt == 3)
			{
				sync_cnt = 0;
				// decrement startup timer
				if (startup_cnt)
				{
					startup_cnt--;
				}

				// update limiters
				else
				{
					for (uint8_t i = 0; i < 2; i++)
					{
						if (limit_en[i] == 1)
						{ // limit increment
							if (limit[i] < (0xFF - LIMIT_INC))
								limit[i] += LIMIT_INC;
							else
							{
								limit[i] = 0xFF;
								limit_en[i] = 0;
							}
						}
						else if (limit_en[i] == 2)
						{ // limit decrement
							if (limit[i] > LIMIT_INC)
								limit[i] -= LIMIT_INC;
							else
							{
								limit[i] = 0;
								limit_en[i] = 0;
							}
						}
					}
				}
			}
			// calculate PWMs

			uint8_t pwm = (!pwm_set[1]) ? 0 : (pwm_set[1] < limit[1]) ? pwm_set[1] : limit[1];
			pwm = pwm_top - (((uint16_t)pwm * pwm_top) >> 8);
			pwm_cur[1] = (startup_cnt || (pwm_set[1] < PWM_MIN) || ((pwm_top - pwm) < PWM_MAX_DIF)) ? 0 : pwm;

			// read ADC
			if (ADMUX & (1 << MUX0))
			{
				if (!kbd_en[1])
					pwm_set[1] = ADCH;
			}
			ADCSRA |= (1 << ADSC);
		}
	}

	// exit
	return 0;
}

ISR(TIM0_COMPA_vect)
{
}

ISR(TIM0_COMPB_vect)
{
	if (pwm_cur[1])
	{
		pwm2_on();
		sei();
		if (pwm_ac)
		{
			_delay_us(PWM_AC_PULSE);
			pwm2_off();
		}
	}
}

ISR(TIM0_OVF_vect)
{
	pwm2_off();			// PWMs off
	pwm_top = 0xFF;		// update PWM top
	OCR0B = pwm_cur[1]; // reload PWMs
	sync_flag = 1;
	pwm_ac = 0;							  // set Sync flag / reset AC flag
	TIFR0 |= (1 << OCF0A) | (1 << OCF0B); // reset capture interrupts
}

// external interrupt on zero-cross
ISR(PCINT0_vect)
{
	pwm2_off();											// PWMs off
	pwm_top = TCNT0;									// get PWM top
														//	uint8_t cnt = TCNT0;                      // get PWM top
	TCNT0 = 0;											// reset TCNT0
	OCR0B = pwm_cur[1];									// reload PWMs
	sync_flag = pwm_ac = 1;								// set Sync/AC flag
														//	pwm_top = ((uint16_t)cnt + pwm_top) >> 1; // filter PWM top
	TIFR0 |= (1 << OCF0A) | (1 << OCF0B) | (1 << TOV0); // reset capture interrupts
}
в main.h поменял

Код: Выделить всё

#define STARTUP_DELAY           5
правда и ацп медленнее вычитывается...
Аватара пользователя
Serzh2000
Опытный кот
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Serzh2000 »

интересный ход с тыла :beer: , но это не то...
надо завести "вредную-переменную" и крутить ее ставя в нее цифры больше-меньше
а она бы увеличивала время разгона двигателя или уменьшала :idea: :roll:
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение oleg110592 »

так там еще можно крутить типа

Код: Выделить всё

#define LIMIT_INC               1
Аватара пользователя
Serzh2000
Опытный кот
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Serzh2000 »

#define LIMIT_INC
Я ТАК ПОНЯЛ - ЭТО ШАГИ ПЕРЕМЕННОГО РЕЗИСТОРА ИЛИ НЕТ?
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение oleg110592 »

не, онj участвует в значении переменной pwm, от которой зависит pwm_cur[1], которое записывают в OCR0B = pwm_cur[1]; // reload PWMs

Код: Выделить всё

uint8_t pwm = (!pwm_set[1]) ? 0 : (pwm_set[1] < limit[1]) ? pwm_set[1] : limit[1];
типа на сколько добавить/убавить значение (самому не до конца понятный механизм)

Код: Выделить всё

// limit increment
	if (limit[i] < (0xFF - LIMIT_INC))
	limit[i] += LIMIT_INC;
 // limit decrement
	if (limit[i] > LIMIT_INC)
	limit[i] -= LIMIT_INC;
Аватара пользователя
Serzh2000
Опытный кот
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Serzh2000 »

Спойлер#define F_CPU (9600000uL / 8 )

#include "stdint.h"
#include "avr/io.h"
#include "avr/interrupt.h"
#include "util/delay.h"


#define PWM_AC_PULSE 4
#define PWM_MIN 5
#define PWM_MAX_DIF 10

#define LIMIT_INC 10

#define STARTUP_DELAY 50

#define KBD_ADC_THRESHOLD 5
#define KBD_CNT_ONOFF 5
#define KBD_CNT_ONOFF_THRESHOLD 50
#define KBD_CNT_LONG 200


inline void pwm2_on() { PORTB |= (1<<PB1); }
inline void pwm2_off(){ PORTB &= ~(1<<PB1); }

unsigned int start_first = 0;
unsigned int STOP;


volatile uint8_t sync_flag; // PWM top sync flag

volatile uint8_t pwm_top=0xFF; // PWMs maximum
register uint8_t pwm_set asm("r2"); // PWMS set
register uint8_t pwm_cur asm("r4"); // PWMS current
register uint8_t pwm_ac asm("r6"); // AC sync flag

uint8_t limit_en = 1, limit;

uint8_t startup_cnt = STARTUP_DELAY;




int main(){
// setup

// GPIO
PORTB |= (1<<PB3)|(1<<PB2);
DDRB &= ~((1<<PB2)|(1<<PB3));
PORTB &= ~(1<<PB1);
DDRB |= (1<<PB1);

// PCINT
GIMSK |= (1<<PCIE);
PCMSK = (1<<PCINT2);

// timer 0
TCCR0A = 0;
TCCR0B = (1<<CS01)|(1<<CS00);
TIMSK0 = (1<<TOIE0)|(1<<OCIE0B)|(1<<OCIE0A);

// ADC
ADMUX = (1<<ADLAR)|(1<<MUX1)|(1<<MUX0);
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
ADCSRB = 0;
DIDR0 = 0;

sei();

// main loop
while(1){
//===плавный старт===

if (start_first==0){
// read ADC
while(ADCSRA & (1<<ADSC));
pwm_set = ADCH;
ADCSRA |= (1<<ADSC);
STOP =ADCH;
for (pwm_cur = 0xFF; pwm_cur > STOP; pwm_cur--){

for (int k = 0; k<10000; k++){ // ПОТОМ УБРАТЬ !!!

pwm_set =ADC;

}
}
start_first = 1;
}
//===================

// ZC sync
if (sync_flag){
sync_flag = 0;

// decrement startup timer
if (startup_cnt) startup_cnt--;


// update limiters
else

if (limit_en == 1){ // limit increment
if (limit < (0xFF - LIMIT_INC)) limit += LIMIT_INC;
else {
limit = 0xFF;
limit_en= 0;
}
}
else if (limit_en== 2){ // limit decrement
if (limit> LIMIT_INC) limit-= LIMIT_INC;
else {
limit= 0;
limit_en= 0;
}
}


uint8_t
pwm = (!pwm_set) ? 0 : (pwm_set < limit) ? pwm_set : limit;
pwm = pwm_top - (((uint16_t)pwm * pwm_top) >> 8 ) ;
pwm_cur = (startup_cnt || (pwm_set < PWM_MIN)||((pwm_top - pwm) < PWM_MAX_DIF)) ? 0 : pwm;

// read ADC
while(ADCSRA & (1<<ADSC));
pwm_set = ADCH;
ADCSRA |= (1<<ADSC);

}
}

// exit
return 0;
}


ISR(TIM0_COMPB_vect){
if (pwm_cur){
pwm2_on();
sei();
if (pwm_ac){
_delay_us(PWM_AC_PULSE);
pwm2_off();
}
}
}

ISR(TIM0_OVF_vect){
pwm2_off(); // PWMs off
pwm_top = 0xFF; // update PWM top
OCR0B = pwm_cur; // reload PWMs
sync_flag = 1; pwm_ac = 0; // set Sync flag / reset AC flag
TIFR0 |= (1<<OCF0A)|(1<<OCF0B); // reset capture interrupts
}

// external interrupt on zero-cross
ISR(PCINT0_vect){
pwm2_off(); // PWMs off
pwm_top = TCNT0; // get PWM top
// uint8_t cnt = TCNT0; // get PWM top
TCNT0 = 0; // reset TCNT0
OCR0B = pwm_cur; // reload PWMs
sync_flag = pwm_ac = 1; // set Sync/AC flag
// pwm_top = ((uint16_t)cnt + pwm_top) >> 1; // filter PWM top
TIFR0 |= (1<<OCF0A)|(1<<OCF0B)|(1<<TOV0); // reset capture interrupts
}
ни фига не получается плавный пуск :cry:

Код: Выделить всё

			uint8_t
			pwm = (!pwm_set) ? 0 : (pwm_set < limit) ? pwm_set : limit;
			pwm = pwm_top - (((uint16_t)pwm * pwm_top) >> 8);
			pwm_cur = (startup_cnt || (pwm_set < PWM_MIN)||((pwm_top - pwm) < PWM_MAX_DIF)) ? 0 : pwm;
а что тут написано? кто нибуть может прочитать и пояснить?
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение oleg110592 »

основоположников почитать - понятнее будет
2.11 Условные выражения

Инструкции

Код: Выделить всё

if (a › b)

 z = a;

else

 z = b;
пересылают в z большее из двух значений a и b. Условное выражение, написанное с помощью тернарного (т. е. имеющего три операнда) оператора "?: ", представляет собой другой способ записи этой и подобных ей конструкций. В выражении

выр1 ? выр2 : выр3

первым вычисляется выражение выр1. Если его значение не нуль (истина), то вычисляется выражение выр2, и значение этого выражения становится значением всего условного выражения. В противном случае вычисляется выражение выр3 и его значение становится значением условного выражения. Следует отметить, что из выражений выр2 и выр3 вычисляется только одно из них. Таким образом, чтобы установить в z большее из a и b, можно написать

Код: Выделить всё

z = (a › b) ? a: b; /* z = max(a, b) */
https://www.rulit.me/books/yazyk-progra ... section_34
Аватара пользователя
Serzh2000
Опытный кот
Сообщения: 867
Зарегистрирован: Пт фев 27, 2015 12:00:53
Откуда: Рязанская область

Re: плавный пуск + регулятор скорости коллекторного двигател

Сообщение Serzh2000 »

? : что это значит я понимаю...
я про другое спрашивал, что мы здесь считаем в этом именно коде
uint8_t
pwm = (!pwm_set) ? 0 : (pwm_set < limit) ? pwm_set : limit;
pwm = pwm_top - (((uint16_t)pwm * pwm_top) >> 8 );
pwm_cur = (startup_cnt || (pwm_set < PWM_MIN)||((pwm_top - pwm) < PWM_MAX_DIF)) ? 0 : pwm;
Ответить

Вернуться в «AVR»