Осциллограф програмный, через звуковуху? На меньшей частоте 1-2 кГц тоже самое?
Ослик DSO-2150 USB
dimax пишет:
3dmax -код в шапке слишком примитивен, на длительность фронтов влияет прерывание таймера0. Если нужен сигнал стабильной формы - к вашим услугам три аппаратных таймера.
Дня доброго всем. Такой вопрос, залил этот скетч в уно через ардуино иде 1,06. На более новых(1,6-1,8) вообще этот код компилироваться отказывается. Короче запустил, подключил, на экране только надпись ардуино пушпулл. Подключил осцил - на фото всё видно, ничего не регулируется переменниками((( Кто-нибудь может ещё раз проверить данный скетч на правильность или у меня одного ардуина какая-то не правильная))
renoshnik пишет:
Вот полный скетч...
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
void (*mas[4]) (void)={poluper1, dead_time1, poluper2, dead_time2}; // массив указателей функций
volatile int val_fr = 533; // длительность полупериода f=18000000/val_fr/2(Гц),
volatile int dead_time = 91; // пауза между периодами, не должна быть меньше 92 и больше val_fr-92
byte uk=0;
int f_val, d_val;
float rpm, dtm;
// ********************************************************************
// ********************************************************************
void setup() {
DDRD = B11111000; // нужные пины на выход
PORTD = B00000100; // на втором пине устанавливаем "единицу"
TCCR1A=0; TIMSK1=0; // сбрасываем на всякий эти регистры
// TCCR1A=0; TIMSK=0;
TCCR1B=0; // мало ли что arduino IDE туда записало
TCNT1=0; // сбрасываем счетный регистр таймера 1
OCR1A=0; // задаем частоту, в Гц, по формуле f=F_CPU/OCR1A/2 где F_CPU тактовая частота
TIMSK1|=(1<<OCIE1A); // разрешаем генерацию прерывания таймера 1, по совпадению с регистром OCR1A
// TIMSK|=(1<<OCIE1A);
// Скетч будет работать на дуинах с atmega168/328.
// При использовании atmega8 меняем все TIMSK1 на TIMSK (убираем еденицу).
TCCR1B|=((1<<CS10)|(1<<WGM12)); // запускаем таймер 1 без предделителя в режиме СТС
lcd.begin(16, 2);
lcd.print("arduino PushPull");
}
// ********************************************************************
// ********************************************************************
void loop(){
if ((PIND&(1<<2)) == 0) l_c_d(); // если на пин 2 лог 0
}
// ********************************************************************
// ********************************************************************
ISR(TIMER1_COMPA_vect) {
(*mas[uk])(); // вызываем функцию по указателю
}
// ********************************************************************
// ********************************************************************
// ********************************************************************
void poluper1(void) {
PORTD&=~(1<<5); // на пин 5 лог 0
PORTD|=(1<<4); // на пин 4 лог 1, формируем первый полупериод
if(dead_time<92) {OCR1A=val_fr; uk=2;} // если пауза меньше 92 тогда она формироваться не будет
else {OCR1A=val_fr-dead_time; uk=1;} // иначе уменьшаем полупериод на длительность паузы чтоб сохранить частоту
}
void dead_time1(void) {
PORTD&=~(1<<4); // на пинах 4 и 5 лог 0, формируем dead_time паузу
OCR1A=dead_time; uk=2;
}
void poluper2(void) {
PORTD&=~(1<<4); // на пин 4 лог 0
PORTD|=(1<<5); // на пин 5 лог 1, формируем второй полупериод
if(dead_time<92) {OCR1A=val_fr; uk=0;}
else {OCR1A=val_fr-dead_time; uk=3;}
}
void dead_time2(void) {
PORTD&=~(1<<5); // на пинах 4 и 5 лог 0, формируем dead_time паузу
OCR1A=dead_time; uk=0;
}
// ********************************************************************
// ********************************************************************
void l_c_d() {
// работаем с частотой от 15009(533) Гц до 30075(266) Гц (f=F_CPU/OCR1A/2)
// работаем с частотой от 20000(400) Гц до 30075(266) Гц (f=F_CPU/OCR1A/2)
f_val = analogRead(A3);
val_fr = map(f_val, 0, 1023, 533, 266);
rpm = 16000000.0/val_fr/2.0; // частота в Герцах
// работаем со скважностью
// пауза между периодами, не должна быть меньше 92 и больше val_fr-91
d_val = analogRead(A2);
int max_dt = val_fr-92;
dead_time = map(d_val, 0, 1023, 91, max_dt);
dtm = dead_time/(val_fr/100.0); // скважность в процентах
if (dead_time < 92) dtm=0;
lcd.setCursor(0, 0);
lcd.print("freq Hz");
lcd.setCursor(5, 0);
lcd.print(rpm);
lcd.setCursor(0, 1);
lcd.print("dead time %");
lcd.setCursor(10, 1);
lcd.print(dtm, 1);
//delay(400);
}
Люди добрые подскажите пожалуйста а как реализовать двухтактный генератр у которого 2 выхода работают в противофазе, с регулировкой частоты от 40Гц и выше...
Люди добрые подскажите пожалуйста а как реализовать двухтактный генератр у которого 2 выхода работают в противофазе, с регулировкой частоты от 40Гц и выше...
Evgen, спасибо всё понял, а то, что-то запутался....
ещё.
я немного изменил строки с массивом функций, всё работает но хочется узнать на сколько это правильно.
void (*mas[4]) (void)={poluper1, dead_time1, poluper2, dead_time2}; // массив указателей функций
int uk=0;
вчера взял осцилограф (не Бог весть что, но лучше чем прога в компе)... Вот что получается.
volatile int val_fr = 900;
volatile int dead_time = 500;
volatile int val_fr = 900;
volatile int dead_time = 250;
теперь нормально видно, что "мёртвая зона" отрабатывается правильно, с двух сторон от полупериода.
Только при изменении дедтайма изменяется частота...
Думаю, что частоту (полупериод) и скважность (дедтайм) нужно расчитывать от одного числа. Тоесть "полупериод" плюс "дедтайм" должно быть равно при изменении одного из слагаемых.
Люди добрые подскажите пожалуйста а как реализовать двухтактный генератр у которого 2 выхода работают в противофазе, с регулировкой частоты от 40Гц и выше...
нее, не совсем то, мне нужно 2 выхода работающих в противофазе, с небольшой задержной относительно друг друга, дабы Н-мост не спалить, в идеале deadTime регулировать как и частоту, наверника это уже гдето реализовано, велосипед изобретать не есть хорошо
4KLIN4, дидтайм аппаратно умеют платы: дижиспарк, микро, про-микро, леонардо. Примеров и ардуино-френдли библиотек для лёгкой реализации вашей задумки нет(или мне не встречалось).
Люди добрые подскажите пожалуйста а как реализовать двухтактный генератр у которого 2 выхода работают в противофазе, с регулировкой частоты от 40Гц и выше...
нее, не совсем то, мне нужно 2 выхода работающих в противофазе, с небольшой задержной относительно друг друга, дабы Н-мост не спалить, в идеале deadTime регулировать как и частоту, наверника это уже гдето реализовано, велосипед изобретать не есть хорошо
На осцилограммах видно, что тут дедтайм регулируется...
Evgen, спасибо всё понял, а то, что-то запутался....
ещё.
я немного изменил строки с массивом функций, всё работает но хочется узнать на сколько это правильно.
void (*mas[4]) (void)={poluper1, dead_time1, poluper2, dead_time2}; // массив указателей функций
int uk=0;
вчера взял осцилограф (не Бог весть что, но лучше чем прога в компе)... Вот что получается.
volatile int val_fr = 900;
volatile int dead_time = 500;
volatile int val_fr = 900;
volatile int dead_time = 250;
теперь нормально видно, что "мёртвая зона" отрабатывается правильно, с двух сторон от полупериода.
Только при изменении дедтайма изменяется частота...
Думаю, что частоту (полупериод) и скважность (дедтайм) нужно расчитывать от одного числа. Тоесть "полупериод" плюс "дедтайм" должно быть равно при изменении одного из слагаемых.
В хороших руках техника хорошо сохраняется )))
Эпоха перестройки, годы так 1980-1986 )))
Я на таком отлаживал схему генератора трёх уровневого стробирующего импульса (для декодеров PAL)
для TDA4510
Здравствуйте, знаю что это не спортивно, но не мог бы кто-то из знатоков дать пример кода для управлением пуш-пулл на фиксированной частоте с дедтаймом. Нашел вот такой костыль, но он создает дедтайм только "с одной стороны".
void setup ()
{
TCCR1A = (TCCR1A & 0x0F) | 0xB0 ; // set pin 10 inverted
int val = 100 ;
int dead = 2 ;
analogWrite (9, val) ;
analogWrite (10, val+dead) ;
}
void loop ()
{}
Регулировать нужно только скважность, никаких дополнительных наворотов кроме дедтайма не нужно. Спасибо.
Здравствуйте, знаю что это не спортивно, но не мог бы кто-то из знатоков дать пример кода для управлением пуш-пулл на фиксированной частоте с дедтаймом. Нашел вот такой костыль, но он создает дедтайм только "с одной стороны".
void setup ()
{
TCCR1A = (TCCR1A & 0x0F) | 0xB0 ; // set pin 10 inverted
int val = 100 ;
int dead = 2 ;
analogWrite (9, val) ;
analogWrite (10, val+dead) ;
}
void loop ()
{}
Регулировать нужно только скважность, никаких дополнительных наворотов кроме дедтайма не нужно. Спасибо.
Проблема моя в том что программист я никакой( это если коротко.
А если расширенно, то в коде из этой темы много лишних, ненужных мне функций, а т.к. почти вся программа сводится к управлению регистрами, вычленить оттуда нужную мне часть - сложно.
А пример, ссылку на который я скинул выше - гораздо более прост для понимания. Вот изготовленный мной огрызок данного кода, рабочий, проверенный на осциллографе:
//~9 TL, PH1, TMR1, PWM data value
//~10 TH, PH1, TMR1, PWM data value
const int dead_time = 10;//10 = 0.625 us
const int half_dead_time = dead_time / 2;//
int PWM = 0;
void setup()
{
pinMode(9, INPUT); //PWM is set to input before PWM initialized to prevent start up short circuit
pinMode(10, INPUT); //PWM is set to input before PWM initialized to prevent start up short circuit
}
void update_pwm(void)
{
//Limit the pwm_phx so it take the dead time into account so it not will swap over when reach end limit of workable PWM range
if (PWM > (255 - half_dead_time))
{
PWM = (255 - half_dead_time);
}
if (PWM < half_dead_time)
{
PWM = half_dead_time;
}
//All The PWM will run from 0xFF to 0x00 and up again to TOP 0xFF
//The OCRnx will automatic update when TCNTn is on TOP 0xFF by hardware
//Therefor it is sutible to change both OCRnx pair on a place where TCNT not update to ensure that the hardware automatic update NOT occur exact when only one of the two OCRnx have changed by this code
while (TCNT1 > 0x7F)
{
}
//Now it's safe to update OCR1x pair (connect to same transistor pair)
OCR1A = (255 - PWM + half_dead_time); //~9 TL PH1 TMR1
OCR1B = (PWM - half_dead_time); //~10 TH PH1 TMR1
}
void loop()
{
TCCR1A = 0xE1;//PWM, Phase Correct 8-bit TOP at 0xFF
TCCR1B = 0x01;//clkI/O/1 (No prescaling) 31.25kHz PWM frequency
update_pwm();
pinMode(9, OUTPUT); //PWM output
pinMode(10, OUTPUT); //PWM output
while (1)
{
PWM ++;
if(PWM>128)PWM=0;
update_pwm();
delay(100);//delay timer scale is screwd up by the new PWM TMR settings
}
}
Делает вроде бы ровно то что мне нужно. Посмотрите пожалуйста нет ли в нем подводных камней, вроде возможности отказа стандартных ардуиновских функций и библиотек. И можно ли в нем изменить частоту на 62кГц? Что-то подсказывает что нужно заменить строчки 39,40, но вот на что?) Спасибо
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
void (*mas[4]) (void)={poluper1, dead_time1, poluper2, dead_time2}; // массив указателей функций
volatile int val_fr = 533; // длительность полупериода f=18000000/val_fr/2(Гц),
volatile int dead_time = 91; // пауза между периодами, не должна быть меньше 92 и больше val_fr-92
byte uk=0;
int f_val, d_val;
float rpm, dtm;
// ********************************************************************
// ********************************************************************
void setup() {
DDRD = B11111000; // нужные пины на выход
PORTD = B00000100; // на втором пине устанавливаем "единицу"
TCCR1A=0; TIMSK1=0; // сбрасываем на всякий эти регистры
// TCCR1A=0; TIMSK=0;
TCCR1B=0; // мало ли что arduino IDE туда записало
TCNT1=0; // сбрасываем счетный регистр таймера 1
OCR1A=0; // задаем частоту, в Гц, по формуле f=F_CPU/OCR1A/2 где F_CPU тактовая частота
TIMSK1|=(1<<OCIE1A); // разрешаем генерацию прерывания таймера 1, по совпадению с регистром OCR1A
// TIMSK|=(1<<OCIE1A);
// Скетч будет работать на дуинах с atmega168/328.
// При использовании atmega8 меняем все TIMSK1 на TIMSK (убираем еденицу).
TCCR1B|=((1<<CS10)|(1<<WGM12)); // запускаем таймер 1 без предделителя в режиме СТС
lcd.begin(16, 2);
lcd.print("arduino PushPull");
}
// ********************************************************************
// ********************************************************************
void loop(){
if ((PIND&(1<<2)) == 0) l_c_d(); // если на пин 2 лог 0
}
// ********************************************************************
// ********************************************************************
ISR(TIMER1_COMPA_vect) {
(*mas[uk])(); // вызываем функцию по указателю
}
// ********************************************************************
// ********************************************************************
// ********************************************************************
void poluper1(void) {
PORTD&=~(1<<5); // на пин 5 лог 0
PORTD|=(1<<4); // на пин 4 лог 1, формируем первый полупериод
if(dead_time<92) {OCR1A=val_fr; uk=2;} // если пауза меньше 92 тогда она формироваться не будет
else {OCR1A=val_fr-dead_time; uk=1;} // иначе уменьшаем полупериод на длительность паузы чтоб сохранить частоту
}
void dead_time1(void) {
PORTD&=~(1<<4); // на пинах 4 и 5 лог 0, формируем dead_time паузу
OCR1A=dead_time; uk=2;
}
void poluper2(void) {
PORTD&=~(1<<4); // на пин 4 лог 0
PORTD|=(1<<5); // на пин 5 лог 1, формируем второй полупериод
if(dead_time<92) {OCR1A=val_fr; uk=0;}
else {OCR1A=val_fr-dead_time; uk=3;}
}
void dead_time2(void) {
PORTD&=~(1<<5); // на пинах 4 и 5 лог 0, формируем dead_time паузу
OCR1A=dead_time; uk=0;
}
// ********************************************************************
// ********************************************************************
void l_c_d() {
// работаем с частотой от 15009(533) Гц до 30075(266) Гц (f=F_CPU/OCR1A/2)
// работаем с частотой от 20000(400) Гц до 30075(266) Гц (f=F_CPU/OCR1A/2)
f_val = analogRead(A3);
val_fr = map(f_val, 0, 1023, 533, 266);
rpm = 16000000.0/val_fr/2.0; // частота в Герцах
// работаем со скважностью
// пауза между периодами, не должна быть меньше 92 и больше val_fr-91
d_val = analogRead(A2);
int max_dt = val_fr-92;
dead_time = map(d_val, 0, 1023, 91, max_dt);
dtm = dead_time/(val_fr/100.0); // скважность в процентах
if (dead_time < 92) dtm=0;
lcd.setCursor(0, 0);
lcd.print("freq Hz");
lcd.setCursor(5, 0);
lcd.print(rpm);
lcd.setCursor(0, 1);
lcd.print("dead time %");
lcd.setCursor(10, 1);
lcd.print(dtm, 1);
//delay(400);
}
Гуру, подскажите почему этот код не компилируется в IDE 1.8.9 ?
Гуру, подскажите почему этот код не компилируется в IDE 1.8.9 ?
потому что любая функция должна быть описана до первого обращения к ней. А у вас ваши функции полу_пер и прочие описаны в строчках 42-62, а первое обращение к ним - в строчке 3
Поместите сами функции или их обьявление до третьей строчки - ошибки исчезнут
Гуру, подскажите почему этот код не компилируется в IDE 1.8.9 ?
потому что любая функция должна быть описана до первого обращения к ней. А у вас ваши функции полу_пер и прочие описаны в строчках 42-62, а первое обращение к ним - в строчке 3
Поместите сами функции или их обьявление до третьей строчки - ошибки исчезнут
Спасибо за подсказку. Но самое интересное что в IDE 1.5.7 компилируется.
Вот переделал
// 27-11-2019 переделал методом переноса текста , компилируется в IDE 1.8.9
// в железе надо проверить
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
volatile int val_fr = 533; // длительность полупериода f=18000000/val_fr/2(Гц),
volatile int dead_time = 91; // пауза между периодами, не должна быть меньше 92 и больше val_fr-92
byte uk=0;
int f_val, d_val;
float rpm, dtm;
// ********************************************************************
// ********************************************************************
void poluper1(void) {
PORTD&=~(1<<5); // на пин 5 лог 0
PORTD|=(1<<4); // на пин 4 лог 1, формируем первый полупериод
if(dead_time<92) {OCR1A=val_fr; uk=2;} // если пауза меньше 92 тогда она формироваться не будет
else {OCR1A=val_fr-dead_time; uk=1;} // иначе уменьшаем полупериод на длительность паузы чтоб сохранить частоту
}
void dead_time1(void) {
PORTD&=~(1<<4); // на пинах 4 и 5 лог 0, формируем dead_time паузу
OCR1A=dead_time; uk=2;
}
void poluper2(void) {
PORTD&=~(1<<4); // на пин 4 лог 0
PORTD|=(1<<5); // на пин 5 лог 1, формируем второй полупериод
if(dead_time<92) {OCR1A=val_fr; uk=0;}
else {OCR1A=val_fr-dead_time; uk=3;}
}
void dead_time2(void) {
PORTD&=~(1<<5); // на пинах 4 и 5 лог 0, формируем dead_time паузу
OCR1A=dead_time; uk=0;
}
// ********************************************************************
void (*mas[4]) (void)={poluper1, dead_time1, poluper2, dead_time2}; // массив указателей функций
// ********************************************************************
// ********************************************************************
void setup() {
DDRD = B11111000; // нужные пины на выход
PORTD = B00000100; // на втором пине устанавливаем "единицу"
TCCR1A=0; TIMSK1=0; // сбрасываем на всякий эти регистры
// TCCR1A=0; TIMSK=0;
TCCR1B=0; // мало ли что arduino IDE туда записало
TCNT1=0; // сбрасываем счетный регистр таймера 1
OCR1A=0; // задаем частоту, в Гц, по формуле f=F_CPU/OCR1A/2 где F_CPU тактовая частота
TIMSK1|=(1<<OCIE1A); // разрешаем генерацию прерывания таймера 1, по совпадению с регистром OCR1A
// TIMSK|=(1<<OCIE1A);
// Скетч будет работать на дуинах с atmega168/328.
// При использовании atmega8 меняем все TIMSK1 на TIMSK (убираем еденицу).
TCCR1B|=((1<<CS10)|(1<<WGM12)); // запускаем таймер 1 без предделителя в режиме СТС
lcd.begin(16, 2);
lcd.print("arduino PushPull");
}
// ********************************************************************
// ********************************************************************
void loop(){
if ((PIND&(1<<2)) == 0) l_c_d(); // если на пин 2 лог 0
}
// ********************************************************************
// ********************************************************************
ISR(TIMER1_COMPA_vect) {
(*mas[uk])(); // вызываем функцию по указателю
}
// ********************************************************************
// ********************************************************************
// ********************************************************************
void l_c_d() {
// работаем с частотой от 15009(533) Гц до 30075(266) Гц (f=F_CPU/OCR1A/2)
// работаем с частотой от 20000(400) Гц до 30075(266) Гц (f=F_CPU/OCR1A/2)
f_val = analogRead(A3);
val_fr = map(f_val, 0, 1023, 533, 266);
rpm = 16000000.0/val_fr/2.0; // частота в Герцах
// работаем со скважностью
// пауза между периодами, не должна быть меньше 92 и больше val_fr-91
d_val = analogRead(A2);
int max_dt = val_fr-92;
dead_time = map(d_val, 0, 1023, 91, max_dt);
dtm = dead_time/(val_fr/100.0); // скважность в процентах
if (dead_time < 92) dtm=0;
lcd.setCursor(0, 0);
lcd.print("freq Hz");
lcd.setCursor(5, 0);
lcd.print(rpm);
lcd.setCursor(0, 1);
lcd.print("dead time %");
lcd.setCursor(10, 1);
lcd.print(dtm, 1);
//delay(400);
}
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,10,11,12,13);
volatile int val_fr = 533; // длительность полупериода f=18000000/val_fr/2(Гц),
volatile int dead_time = 91; // пауза между периодами, не должна быть меньше 92 и больше val_fr-92
byte uk=0;
int f_val, d_val;
float rpm, dtm;
// ********************************************************************
// ********************************************************************
void poluper1(void) {
PORTD&=~(1<<5); // на пин 5 лог 0
PORTD|=(1<<4); // на пин 4 лог 1, формируем первый полупериод
if(dead_time<92) {OCR1A=val_fr; uk=2;} // если пауза меньше 92 тогда она формироваться не будет
else {OCR1A=val_fr-dead_time; uk=1;} // иначе уменьшаем полупериод на длительность паузы чтоб сохранить частоту
}
void dead_time1(void) {
PORTD&=~(1<<4); // на пинах 4 и 5 лог 0, формируем dead_time паузу
OCR1A=dead_time; uk=2;
}
void poluper2(void) {
PORTD&=~(1<<4); // на пин 4 лог 0
PORTD|=(1<<5); // на пин 5 лог 1, формируем второй полупериод
if(dead_time<92) {OCR1A=val_fr; uk=0;}
else {OCR1A=val_fr-dead_time; uk=3;}
}
void dead_time2(void) {
PORTD&=~(1<<5); // на пинах 4 и 5 лог 0, формируем dead_time паузу
OCR1A=dead_time; uk=0;
}
// ********************************************************************
void (*mas[4]) (void)={poluper1, dead_time1, poluper2, dead_time2}; // массив указателей функций
// ********************************************************************
// ********************************************************************
void setup() {
DDRD = B11111000; // нужные пины на выход
PORTD = B00000100; // на втором пине устанавливаем "единицу"
TCCR1A=0; TIMSK1=0; // сбрасываем на всякий эти регистры
// TCCR1A=0; TIMSK=0;
TCCR1B=0; // мало ли что arduino IDE туда записало
TCNT1=0; // сбрасываем счетный регистр таймера 1
OCR1A=0; // задаем частоту, в Гц, по формуле f=F_CPU/OCR1A/2 где F_CPU тактовая частота
TIMSK1|=(1<<OCIE1A); // разрешаем генерацию прерывания таймера 1, по совпадению с регистром OCR1A
// TIMSK|=(1<<OCIE1A);
// Скетч будет работать на дуинах с atmega168/328.
// При использовании atmega8 меняем все TIMSK1 на TIMSK (убираем еденицу).
TCCR1B|=((1<<CS10)|(1<<WGM12)); // запускаем таймер 1 без предделителя в режиме СТС
lcd.begin(16, 2);
lcd.print("arduino PushPull");
}
// ********************************************************************
// ********************************************************************
void loop(){
if ((PIND&(1<<2)) == 0) l_c_d(); // если на пин 2 лог 0
}
// ********************************************************************
// ********************************************************************
ISR(TIMER1_COMPA_vect) {
(*mas[uk])(); // вызываем функцию по указателю
}
// ********************************************************************
// ********************************************************************
// ********************************************************************
void l_c_d() {
// работаем с частотой от 15009(533) Гц до 30075(266) Гц (f=F_CPU/OCR1A/2)
// работаем с частотой от 20000(400) Гц до 30075(266) Гц (f=F_CPU/OCR1A/2)
f_val = analogRead(A3);
val_fr = map(f_val, 0, 1023, 533, 266);
rpm = 16000000.0/val_fr/2.0; // частота в Герцах
// работаем со скважностью
// пауза между периодами, не должна быть меньше 92 и больше val_fr-91
d_val = analogRead(A2);
int max_dt = val_fr-92;
dead_time = map(d_val, 0, 1023, 91, max_dt);
dtm = dead_time/(val_fr/100.0); // скважность в процентах
if (dead_time < 92) dtm=0;
lcd.setCursor(0, 0);
lcd.print("freq Hz");
lcd.setCursor(5, 0);
lcd.print(rpm);
lcd.setCursor(0, 1);
lcd.print("dead time %");
lcd.setCursor(10, 1);
lcd.print(dtm, 1);
//delay(400);
}
Люди ДОБРЫЕ ! ПОМОЖИТЕ! Как этот скеч сделать под регулировку тремя кнопками?
Пытаюсь слямзить с этого скеча управление , да вот мозги дымятся !!!
// генератор сигналов с регулировкой частоты и скважности по двум каналам.
// частота от 0 до 100 кГц, ШИМ от 0 до 255
//
//подключение библиотек *********************************************************************
#include <PWM.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd (2, 12, 4, 5, 6, 7); // назначение пин LCD (rs, enable, d4, d5, d6, d7)
//********************************************************************************************
//определение пинов **************************************************************************
#define OK_PIN 8 // кнопка ОК (можно любой пин)
#define OUT_1_PIN 9 // пин для генератора сигналов (не менять)
#define OUT_2_PIN 10 // пин для генератора сигналов (не менять)
#define LEFT_PIN A0 // кнопка ЛЕВО (можно любой пин)
#define RIGHT_PIN A1 // кнопка ПРАВО (можно любой пин)
//*********************************************************************************************
//объявление переменных ***********************************************************************
int PWM_1 = 200; // стартовое значение ШИМ_1 от 0 до 255
int PWM_2 = 50; // стартовое значение ШИМ_2 от 0 до 255
int32_t frequency = 10000; // стартовое значение частоты в Гц
byte hag = 0; // стартовое значение выбора режима
int mnog = 1; // стартовое значение коэф. частоты
int flag = 0; // стартовое флага
//*********************************************************************************************
// ********************************************************************************************
void setup()
{
InitTimersSafe(); // инициализация таймеров
//инициализация lcd *************************************************************************
lcd.begin(16, 2);
lcd.clear(); lcd. noCursor();
//*******************************************************************************************
// назначение портов ************************************************************************
pinMode(OUT_1_PIN, OUTPUT);
pinMode(OUT_2_PIN, OUTPUT);
pinMode(LEFT_PIN, INPUT);
pinMode(RIGHT_PIN, INPUT);
pinMode(OK_PIN, INPUT);
// ******************************************************************************************
bool success_1 = SetPinFrequencySafe(OUT_1_PIN, frequency); // первоначальная установка частоты на первом выходе
delay(50);
bool success_2 = SetPinFrequencySafe(OUT_2_PIN, frequency); // первоначальная установка частоты на втором выходе
delay(50);
pwmWrite(OUT_1_PIN, PWM_1); // первоначальная установка ШИМ на первом выходе
pwmWrite(OUT_2_PIN, PWM_2); // первоначальная установка ШИМ на втором выходе
// вывод на экран *****************************************************************************
lcd.setCursor(0, 0); lcd.print(frequency); lcd.print("Hz * "); lcd.setCursor(15, 0); lcd.print(mnog);
lcd.setCursor(0, 1);
lcd.print("1PWM"); lcd.setCursor(4, 1); lcd.print(PWM_1);
lcd.setCursor(9, 1);
lcd.print("2PWM"); lcd.setCursor(13, 1); lcd.print(PWM_2);
}
// ********************************************************************************************
// основной цикл программы **********************************************************************
void loop()
{
if ((digitalRead(LEFT_PIN) == HIGH) || (digitalRead(RIGHT_PIN) == HIGH) // если нажата любая кнопка
|| (digitalRead(OK_PIN) == HIGH))
{
key(); // то вызов подпрограммы опроса кнопок
}
bool success_1 = SetPinFrequencySafe(OUT_1_PIN, frequency); // установка частоты на первом выходе
delay(10);
bool success_2 = SetPinFrequencySafe(OUT_2_PIN, frequency); // установка частоты на втором выходе
delay(10);
pwmWrite(OUT_1_PIN, PWM_1); // установка ШИМ на первом выходе
pwmWrite(OUT_2_PIN, PWM_2); // установка ШИМ на втором выходе
}
//*************************************************************************************************
// подпрограмма опроса кнопок и установки частоты и скважности ************************************
void key()
{
if (digitalRead(OK_PIN) == HIGH) // если нажата кнопка ОК - перебор коэф. для частоты и ШИМ
{
switch (hag)
{
case 0: // выбор множителя частоты (1)
lcd.setCursor(12, 0);
lcd.print(" 1");
mnog = 1;
flag = 0;
break;
case 1: // выбор множителя частоты (10)
lcd.setCursor(12, 0);
lcd.print(" 10");
mnog = 10;
flag = 0;
break;
case 2: // выбор множителя частоты (100)
lcd.setCursor(12, 0);
lcd.print(" 100");
mnog = 100;
flag = 0;
break;
case 3: // выбор множителя частоты (1000)
lcd.setCursor(12, 0);
lcd.print(" 1K");
mnog = 1000;
flag = 0;
break;
case 4: // выбор множителя частоты (5000)
lcd.setCursor(12, 0);
lcd.print(" 5K");
mnog = 5000;
flag = 0;
break;
case 5: // выбор 1 канала для регулировки ШИМ
lcd.setCursor(12, 0);
lcd.print("1PWM");
flag = 1;
break;
case 6: // выбор 2 канала для регулировки ШИМ
lcd.setCursor(12, 0);
lcd.print("2PWM");
flag = 2;
break;
case 7: // перебор параметров по кругу
flag = 0;
break;
}
hag = hag + 1; delay(100); // приращение счетчика
if (hag == 8) hag = 0;
}
if (flag == 0) // флаг выборов режима настройки ШИМ или частоты (по умолчанию флаг =0 - настройка частоты)
{
if (digitalRead(LEFT_PIN) == HIGH) // если нажата кнопка ЛЕВО
{
frequency = frequency - mnog; // то уменьшение частоты на выбранный коэф.
if (frequency < 0) // если частота меньше 0
{
frequency = 0; // то частота =0
}
delay(100); // защита от дребезга
}
if (digitalRead(RIGHT_PIN) == HIGH) // если нажата кнопка ПРАВО
{
frequency = frequency + mnog; // то увеличение частоты
if (frequency >= 99999) // если частота больше 99 999
{
frequency = 99999; // то частота = 99 999
}
delay(100); // защита от дребезга
}
lcd.setCursor(0, 0); // вывод на экран частоты
lcd.print(frequency); lcd.print("Hz * "); // вывод на экран
}
if (flag == 1) // флаг выборов режима настройки ШИМ 1
{
if (digitalRead(LEFT_PIN) == HIGH) // если нажата кнопка ЛЕВО
{
PWM_1 = PWM_1 - 5; // то уменьшение ШИМ на 5
if (PWM_1 < 10) // если ШИМ меньше 10
{
PWM_1 = 10; // то ШИМ = 10
}
delay(100); // защита от дребезга
}
if (digitalRead(RIGHT_PIN) == HIGH) // если нажата кнопка ПРАВО то приращение ШИМ на 5
{
PWM_1 = PWM_1 + 5;
if (PWM_1 > 255) // если ШИМ больше 255
{
PWM_1 = 255; // то ШИМ = 255
}
delay(100); //Serial.print("PWM1= "); Serial.println(PWM_1); // защита от дребезга
}
}
if (flag == 2) // флаг выбора режима настройки ШИМ 2
{
if (digitalRead(LEFT_PIN) == HIGH) // аналогично ШИМ первого канала
{
PWM_2 = PWM_2 - 5;
if (PWM_2 < 10)
{
PWM_2 = 10;
}
delay(100);
}
if (digitalRead(RIGHT_PIN) == HIGH)
{
PWM_2 = PWM_2 + 5;
if (PWM_2 > 255)
{
PWM_2 = 255;
}
delay(100);
}
}
// вывод на экран ШИМ 1,2 ***************************************************************************
lcd.setCursor(4, 1);
if (PWM_1 < 100)
{
lcd.print("0"); lcd.print(PWM_1);
}
else
{
lcd.print(PWM_1);
}
lcd.setCursor(13, 1);
if (PWM_2 < 100)
{
lcd.print("0"); lcd.print(PWM_2);
}
else
{
lcd.print(PWM_2);
}
//***************************************************************************************************
}
Осциллограф програмный, через звуковуху? На меньшей частоте 1-2 кГц тоже самое?
Ослик DSO-2150 USB
3dmax -код в шапке слишком примитивен, на длительность фронтов влияет прерывание таймера0. Если нужен сигнал стабильной формы - к вашим услугам три аппаратных таймера.
то есть таким способом проблемму не решить ? :(
Дня доброго всем. Такой вопрос, залил этот скетч в уно через ардуино иде 1,06. На более новых(1,6-1,8) вообще этот код компилироваться отказывается. Короче запустил, подключил, на экране только надпись ардуино пушпулл. Подключил осцил - на фото всё видно, ничего не регулируется переменниками((( Кто-нибудь может ещё раз проверить данный скетч на правильность или у меня одного ардуина какая-то не правильная))
Вот полный скетч...
>> ничего не регулируется переменниками
Возможно нужно притянуть пин. Строка 33.
Спасибо, заработало!
dimax, предлогаешь использовать таймер1 или таймер2 вместо таймер0?
Люди добрые подскажите пожалуйста а как реализовать двухтактный генератр у которого 2 выхода работают в противофазе, с регулировкой частоты от 40Гц и выше...
Буду ОЧЕНЬ благодарен за ответ.
Люди добрые подскажите пожалуйста а как реализовать двухтактный генератр у которого 2 выхода работают в противофазе, с регулировкой частоты от 40Гц и выше...
Буду ОЧЕНЬ благодарен за ответ.
А выше написанное чем не подходит ?
https://www.drive2.ru/b/572409/
Evgen, спасибо всё понял, а то, что-то запутался....
ещё.
я немного изменил строки с массивом функций, всё работает но хочется узнать на сколько это правильно.
вчера взял осцилограф (не Бог весть что, но лучше чем прога в компе)... Вот что получается.
volatile int val_fr = 900;
volatile int dead_time = 500;
volatile int val_fr = 900;
volatile int dead_time = 250;
теперь нормально видно, что "мёртвая зона" отрабатывается правильно, с двух сторон от полупериода.
Только при изменении дедтайма изменяется частота...
Думаю, что частоту (полупериод) и скважность (дедтайм) нужно расчитывать от одного числа. Тоесть "полупериод" плюс "дедтайм" должно быть равно при изменении одного из слагаемых.
В общем есть чем заниматься на выходных...
Ещё раз ОГРОМНОЕ СПАСИБО !!! за помощь...
ОГО - Это жеж ОМЛ-2М или ОМЛ-3М, я прав?
Люди добрые подскажите пожалуйста а как реализовать двухтактный генератр у которого 2 выхода работают в противофазе, с регулировкой частоты от 40Гц и выше...
Буду ОЧЕНЬ благодарен за ответ.
А выше написанное чем не подходит ?
https://www.drive2.ru/b/572409/
нее, не совсем то, мне нужно 2 выхода работающих в противофазе, с небольшой задержной относительно друг друга, дабы Н-мост не спалить, в идеале deadTime регулировать как и частоту, наверника это уже гдето реализовано, велосипед изобретать не есть хорошо
4KLIN4, дидтайм аппаратно умеют платы: дижиспарк, микро, про-микро, леонардо. Примеров и ардуино-френдли библиотек для лёгкой реализации вашей задумки нет(или мне не встречалось).
Люди добрые подскажите пожалуйста а как реализовать двухтактный генератр у которого 2 выхода работают в противофазе, с регулировкой частоты от 40Гц и выше...
Буду ОЧЕНЬ благодарен за ответ.
А выше написанное чем не подходит ?
https://www.drive2.ru/b/572409/
нее, не совсем то, мне нужно 2 выхода работающих в противофазе, с небольшой задержной относительно друг друга, дабы Н-мост не спалить, в идеале deadTime регулировать как и частоту, наверника это уже гдето реализовано, велосипед изобретать не есть хорошо
На осцилограммах видно, что тут дедтайм регулируется...
Evgen, спасибо всё понял, а то, что-то запутался....
ещё.
я немного изменил строки с массивом функций, всё работает но хочется узнать на сколько это правильно.
вчера взял осцилограф (не Бог весть что, но лучше чем прога в компе)... Вот что получается.
volatile int val_fr = 900;
volatile int dead_time = 500;
volatile int val_fr = 900;
volatile int dead_time = 250;
теперь нормально видно, что "мёртвая зона" отрабатывается правильно, с двух сторон от полупериода.
Только при изменении дедтайма изменяется частота...
Думаю, что частоту (полупериод) и скважность (дедтайм) нужно расчитывать от одного числа. Тоесть "полупериод" плюс "дедтайм" должно быть равно при изменении одного из слагаемых.
В общем есть чем заниматься на выходных...
Ещё раз ОГРОМНОЕ СПАСИБО !!! за помощь...
ОГО - Это жеж ОМЛ-2М или ОМЛ-3М, я прав?
Помоему да ... :-))
В хороших руках техника хорошо сохраняется )))
Эпоха перестройки, годы так 1980-1986 )))
Я на таком отлаживал схему генератора трёх уровневого стробирующего импульса (для декодеров PAL)
для TDA4510
Здравствуйте, знаю что это не спортивно, но не мог бы кто-то из знатоков дать пример кода для управлением пуш-пулл на фиксированной частоте с дедтаймом. Нашел вот такой костыль, но он создает дедтайм только "с одной стороны".
Регулировать нужно только скважность, никаких дополнительных наворотов кроме дедтайма не нужно. Спасибо.
Здравствуйте, знаю что это не спортивно, но не мог бы кто-то из знатоков дать пример кода для управлением пуш-пулл на фиксированной частоте с дедтаймом. Нашел вот такой костыль, но он создает дедтайм только "с одной стороны".
Регулировать нужно только скважность, никаких дополнительных наворотов кроме дедтайма не нужно. Спасибо.
бесполезно
Tolik4, лучше взять МК с аппаратной поддержкой дид-тайма, Tiny85 например.
Есть диджиспарк, его можно заставить генерировать ШИМ с дедтаймом средствани Ардуино ИДЕ?
Tolik4, возможно что "средства" Arduino IDE будут как раз мешать, нужно проверять. Есть примерчик под "голую" тини85.
https://gist.github.com/ollewelin/4afcf202a6ff267aa70e5b289724abc2 вот нашел пример для трех фаз, можно ли из него повыбрасывать лишнее и дальше писать свой недокод как для обычного ардуино?
https://gist.github.com/ollewelin/4afcf202a6ff267aa70e5b289724abc2 вот нашел пример для трех фаз, можно ли из него повыбрасывать лишнее и дальше писать свой недокод как для обычного ардуино?
Tolik4, я не пойму в чем проблема у вас проблема ? Выше есть рабочий скетч с регулировкой дедтайма !
Вот работа этого скетча...
https://www.youtube.com/watch?v=gz3YcAGV678
https://www.youtube.com/watch?v=rQ368CWKoCU
https://www.youtube.com/watch?v=3VD1KAxJrA0
Проблема моя в том что программист я никакой( это если коротко.
А если расширенно, то в коде из этой темы много лишних, ненужных мне функций, а т.к. почти вся программа сводится к управлению регистрами, вычленить оттуда нужную мне часть - сложно.
А пример, ссылку на который я скинул выше - гораздо более прост для понимания. Вот изготовленный мной огрызок данного кода, рабочий, проверенный на осциллографе:
Делает вроде бы ровно то что мне нужно. Посмотрите пожалуйста нет ли в нем подводных камней, вроде возможности отказа стандартных ардуиновских функций и библиотек. И можно ли в нем изменить частоту на 62кГц? Что-то подсказывает что нужно заменить строчки 39,40, но вот на что?) Спасибо
Вот изготовленный мной огрызок данного кода, рабочий, проверенный на осциллографе:
Можно картинку, что показывает осцилограф ?
https://ibb.co/me1Qpn
Пробовал вставить гиф в сообщение - не хочет(
https://ibb.co/me1Qpn
Пробовал вставить гиф в сообщение - не хочет(
думаете такой сигнал подойдет для пуш-пула ?
смотрите тут в теме есть осцилограммы...
Я, как вы уже догадались, не специалист) Вдохновлялся этим:
https://www.youtube.com/watch?v=bYGeAu6_c6w
Доброго дня, а каким образом можно обратную связь по напряжению осуществить?
Вот полный скетч...
Ругается на строку 3
Arduino: 1.8.9 (Windows 7), Плата:"Arduino/Genuino Uno"
push_pull:3:24: error: 'poluper1' was not declared in this scope
push_pull:3:34: error: 'dead_time1' was not declared in this scope
push_pull:3:46: error: 'poluper2' was not declared in this scope
push_pull:3:56: error: 'dead_time2' was not declared in this scope
exit status 1
'poluper1' was not declared in this scope
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
Not declared - не заданна переменная (не задекларирована - если дословно)
Гуру, подскажите почему этот код не компилируется в IDE 1.8.9 ?
потому что любая функция должна быть описана до первого обращения к ней. А у вас ваши функции полу_пер и прочие описаны в строчках 42-62, а первое обращение к ним - в строчке 3
Поместите сами функции или их обьявление до третьей строчки - ошибки исчезнут
Гуру, подскажите почему этот код не компилируется в IDE 1.8.9 ?
потому что любая функция должна быть описана до первого обращения к ней. А у вас ваши функции полу_пер и прочие описаны в строчках 42-62, а первое обращение к ним - в строчке 3
Поместите сами функции или их обьявление до третьей строчки - ошибки исчезнут
Спасибо за подсказку. Но самое интересное что в IDE 1.5.7 компилируется.
Вот переделал
самое интересное что в IDE 1.5.7 компилируется.
ничего "интересного" в этом нет, это печально. Просто IDE 1.5.7 делает за вас эту работу, расслабляя новичков.
Правильно - как требует IDE 1.8.9 - то есть описывать функции до их использования
Для разрешения регулировки частоты и дедтайма я так понял пин 2 на общий провод замыкать?
И какие номиналы потенциометров использовать для регулировки частоты и дедтайма?
как обычно, стандартные 10 кОм
Что поменять в скетче чтобы пределы регулирования по частоте от 1Гц до 500Гц было?
Люди ДОБРЫЕ ! ПОМОЖИТЕ! Как этот скеч сделать под регулировку тремя кнопками?
Пытаюсь слямзить с этого скеча управление , да вот мозги дымятся !!!