Ср сен 30, 2020 07:53:13
Ср сен 30, 2020 09:37:23
Там же еще МК будет? Или полностью схему нарисовать?BlackKilkennyCat писал(а):Это схема детектора перехода через ноль с бп, симистор к ней как-то рано.
С чего вы будете брать питание для этого транзистора?BlackKilkennyCat писал(а):Управляющий ток, если его действительно не хватает, обеспечивают транзистором. Зачем сразу лепить оптрон?
Ср сен 30, 2020 10:54:24
Ср сен 30, 2020 12:40:29
С чего вы будете брать питание для этого транзистора?
U2010B выдает 125 мА, это более чем достаточно для открытия любого симистора.
нетПонадобится высоковольтный транзистор
поясните, что имеете в виду, без намеков.и ...., напомните мне чем симистор отличается от тиристора?
дорого и много места. Кроме того, надо быть последовательным - какой смысл готовое решение в одном лишь месте? Давайте и всё остальное в виде готового решения, они есть.MOC3023 - это готовое решение, с минимумом обвеса.
Велосипеды изобретают до сих пор. Ваш вариант блока питания с детектором нуля - тот же велосипед, как и 99% радиолюбительских поделок в сегодняшнее время, к чему об этом разговаривать? Кроме того, существует куча различных требований к режимам работы электроприводов, и не всегда какая-то уникально-заточенная микросхема может их обеспечить. И как заметил musor, микросхема редкая, а вариант покупать на али - да лучше выкинуть электропривод и пойти пить чай...существует специализированная микросхема фазового управления с обратной связью по току и защитой от перегрузки U2010B. Остальное "велосипед".
Ср сен 30, 2020 12:53:38
U2010BBlackKilkennyCat писал(а):Давайте и всё остальное в виде готового решения, они есть.
Ср сен 30, 2020 13:08:27
Чт окт 01, 2020 21:50:07
Пт окт 02, 2020 15:42:31
Пт окт 02, 2020 16:08:02
pwm_set[0] = ADCH;
Пт окт 02, 2020 23:39:11
//===плавный старт===
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;
}
//===================
Сб окт 03, 2020 11:17:02
/*
* 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_ */
Сб окт 03, 2020 12:03:01
вообще плавный пуск есть, но коротенький, удлинить наверное можно
Сб окт 03, 2020 12:46:19
/*
* 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
Сб окт 03, 2020 13:33:43
Сб окт 03, 2020 14:00:36
#define LIMIT_INC 1
Сб окт 03, 2020 14:51:42
#define LIMIT_INC
Сб окт 03, 2020 15:40:33
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;
Пн окт 05, 2020 11:52:33
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;
Пн окт 05, 2020 12:07:25
if (a › b)
z = a;
else
z = b;
z = (a › b) ? a: b; /* z = max(a, b) */
Пн окт 05, 2020 13:10:17
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;