плавный пуск + регулятор скорости коллекторного двигателя
Re: плавный пуск + регулятор скорости коллекторного двигател
Болгарка плавно набирает обороты при запуске, когда регулятор установлен на минимум, после этого можно добавить обороты до нужной величины.
Когда все функционирует идеально- становится скучно жить.
- Реклама
Re: плавный пуск + регулятор скорости коллекторного двигател
Там же еще МК будет? Или полностью схему нарисовать?BlackKilkennyCat писал(а):Это схема детектора перехода через ноль с бп, симистор к ней как-то рано.
С чего вы будете брать питание для этого транзистора?BlackKilkennyCat писал(а):Управляющий ток, если его действительно не хватает, обеспечивают транзистором. Зачем сразу лепить оптрон?
U2010B выдает 125 мА, это более чем достаточно для открытия любого симистора.
Понадобится высоковольтный транзистор и ...., напомните мне чем симистор отличается от тиристора?
MOC3023 - это готовое решение, с минимумом обвеса.
Мое мнение остается неизменным - существует специализированная микросхема фазового управления с обратной связью по току и защитой от перегрузки U2010B. Остальное "велосипед".
Но если все таки "велосипед", то сначала я бы собрал источник питания, нагрузил бы его нагрузкой 100 - 150 мА, светодиод поставил бы для визуального контроля, и раз так 50 включить-выключить, если не увидим "зарождение электрона", то все ОК.
Тут же прибором контролируем наличие 5 Вольт, осциллографом проверяем схему детектора, возможно так же применение стабилизатора AMS1117. (?)
PS на схеме не дорисовал один резистор килоом так на 300 параллельно С1.
- musor
- Друг Кота
- Сообщения: 39197
- Зарегистрирован: Сб сен 13, 2014 16:27:32
- Откуда: СпиртоГонск созвездия Омега
Re: плавный пуск + регулятор скорости коллекторного двигател
таких микрух хватает
U2010B. лиш 1из них и не самая распространеная
у нас например в рознице не наблюдаю сейчас
U2010B. лиш 1из них и не самая распространеная
у нас например в рознице не наблюдаю сейчас
ZМудрость(Опыт и выдержка) приходит с годами.
Все Ваши беды и проблемы, от недостатка знаний.
Умный и у дурака научится, а дураку и ..
Алберт Ейнштейн не поможет и ВВП не спасет.и МЧС опаздает
Все Ваши беды и проблемы, от недостатка знаний.
Умный и у дурака научится, а дураку и ..
Алберт Ейнштейн не поможет и ВВП не спасет.и МЧС опаздает
-
BlackKilkennyCat
- Собутыльник Кота
- Сообщения: 2905
- Зарегистрирован: Ср ноя 29, 2017 06:58:50
Re: плавный пуск + регулятор скорости коллекторного двигател
[uquote="Dimon456",url="/forum/viewtopic.php?p=3899656#p3899656"]Там же еще МК будет? Или полностью схему нарисовать?[/uquote]
Вообще-то да. Какой смысл от очередного варианта бестрансформаторного питания и чем оно отличается от ранее описанных?
Вообще-то да. Какой смысл от очередного варианта бестрансформаторного питания и чем оно отличается от ранее описанных?
а она эти 125 мА где берет?С чего вы будете брать питание для этого транзистора?
U2010B выдает 125 мА, это более чем достаточно для открытия любого симистора.
нетПонадобится высоковольтный транзистор
поясните, что имеете в виду, без намеков.и ...., напомните мне чем симистор отличается от тиристора?
дорого и много места. Кроме того, надо быть последовательным - какой смысл готовое решение в одном лишь месте? Давайте и всё остальное в виде готового решения, они есть.MOC3023 - это готовое решение, с минимумом обвеса.
Велосипеды изобретают до сих пор. Ваш вариант блока питания с детектором нуля - тот же велосипед, как и 99% радиолюбительских поделок в сегодняшнее время, к чему об этом разговаривать? Кроме того, существует куча различных требований к режимам работы электроприводов, и не всегда какая-то уникально-заточенная микросхема может их обеспечить. И как заметил musor, микросхема редкая, а вариант покупать на али - да лучше выкинуть электропривод и пойти пить чай...существует специализированная микросхема фазового управления с обратной связью по току и защитой от перегрузки U2010B. Остальное "велосипед".
Re: плавный пуск + регулятор скорости коллекторного двигател
U2010BBlackKilkennyCat писал(а):Давайте и всё остальное в виде готового решения, они есть.
- Реклама
-
BlackKilkennyCat
- Собутыльник Кота
- Сообщения: 2905
- Зарегистрирован: Ср ноя 29, 2017 06:58:50
Re: плавный пуск + регулятор скорости коллекторного двигател
ну, вот так лучше 
- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: плавный пуск + регулятор скорости коллекторного двигател
во че нашел!
фьюзы: Low = 0x2A , High = 0xFB
Добавлено after 5 hours 53 minutes 43 seconds:
Re: плавный пуск + регулятор скорости коллекторного двигателя
допишите плавный пуск, кому не трудно
Спойлер
#define F_CPU (9600000uL /#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) >>
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) >>
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: плавный пуск + регулятор скорости коллекторного двигател
Спойлер
#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: плавный пуск + регулятор скорости коллекторного двигател
тэг 'Code' есть для исходников - покрасивше будет
переменная вроде эта с ацп считывается
переменная вроде эта с ацп считывается
Код: Выделить всё
pwm_set[0] = ADCH; - Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: плавный пуск + регулятор скорости коллекторного двигател
Код: Выделить всё
//===плавный старт===
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;
}
//=================== НИ ФИГА НЕ ПОЛУЧАЕТСЯ
начинается с 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: плавный пуск + регулятор скорости коллекторного двигател
вообще плавный пуск есть, но коротенький, удлинить наверное можно

повыкидывал "лишнее":
main.c
main.h
повыкидывал "лишнее":
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
*
* 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: плавный пуск + регулятор скорости коллекторного двигател
наверно...вообще плавный пуск есть, но коротенький, удлинить наверное можно
- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: плавный пуск + регулятор скорости коллекторного двигател
легким движением руки удлиняем в три раза (больше тоже легко - увеличиваем магическую цифру '3' ):
в main.h поменял
правда и ацп медленнее вычитывается...
Спойлер
Код: Выделить всё
/*
* 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
}Код: Выделить всё
#define STARTUP_DELAY 5- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: плавный пуск + регулятор скорости коллекторного двигател
интересный ход с тыла
, но это не то...
надо завести "вредную-переменную" и крутить ее ставя в нее цифры больше-меньше
а она бы увеличивала время разгона двигателя или уменьшала

надо завести "вредную-переменную" и крутить ее ставя в нее цифры больше-меньше
а она бы увеличивала время разгона двигателя или уменьшала
- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: плавный пуск + регулятор скорости коллекторного двигател
так там еще можно крутить типа
Код: Выделить всё
#define LIMIT_INC 1- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: плавный пуск + регулятор скорости коллекторного двигател
Я ТАК ПОНЯЛ - ЭТО ШАГИ ПЕРЕМЕННОГО РЕЗИСТОРА ИЛИ НЕТ?#define LIMIT_INC
- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: плавный пуск + регулятор скорости коллекторного двигател
не, он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: плавный пуск + регулятор скорости коллекторного двигател
Спойлер
#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
}
Код: Выделить всё
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: плавный пуск + регулятор скорости коллекторного двигател
основоположников почитать - понятнее будет
2.11 Условные выражения
Инструкции
пересылают в z большее из двух значений a и b. Условное выражение, написанное с помощью тернарного (т. е. имеющего три операнда) оператора "?: ", представляет собой другой способ записи этой и подобных ей конструкций. В выражении
выр1 ? выр2 : выр3
первым вычисляется выражение выр1. Если его значение не нуль (истина), то вычисляется выражение выр2, и значение этого выражения становится значением всего условного выражения. В противном случае вычисляется выражение выр3 и его значение становится значением условного выражения. Следует отметить, что из выражений выр2 и выр3 вычисляется только одно из них. Таким образом, чтобы установить в z большее из a и b, можно написать
https://www.rulit.me/books/yazyk-progra ... section_34
2.11 Условные выражения
Инструкции
Код: Выделить всё
if (a › b)
z = a;
else
z = b;выр1 ? выр2 : выр3
первым вычисляется выражение выр1. Если его значение не нуль (истина), то вычисляется выражение выр2, и значение этого выражения становится значением всего условного выражения. В противном случае вычисляется выражение выр3 и его значение становится значением условного выражения. Следует отметить, что из выражений выр2 и выр3 вычисляется только одно из них. Таким образом, чтобы установить в z большее из a и b, можно написать
Код: Выделить всё
z = (a › b) ? a: b; /* z = max(a, b) */- Serzh2000
- Опытный кот
- Сообщения: 867
- Зарегистрирован: Пт фев 27, 2015 12:00:53
- Откуда: Рязанская область
Re: плавный пуск + регулятор скорости коллекторного двигател
? : что это значит я понимаю...
я про другое спрашивал, что мы здесь считаем в этом именно коде
я про другое спрашивал, что мы здесь считаем в этом именно коде
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;


