Прямоугольник низкой частоты и финкция tone()

VladimrYA
Offline
Зарегистрирован: 10.08.2016

Приветствую!

Нужна помощь...

Требуется генерация прямоугольного сигнала (меандр) низкой частоты (в диапазоне 5-10 герц).

Функция tone() работает только до 25-30  Гц, ниже не генерирует.

Подскажите код который сможет генерировать меандр низкой частоты.

Спасибо.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Пример Blink из поставки IDE генерирует меандр с частотой 0,5 герц. Переделать на нужную Вам частоту сами сумеете?

VladimrYA
Offline
Зарегистрирован: 10.08.2016

ЕвгенийП пишет:

Пример Blink из поставки IDE генерирует меандр с частотой 0,5 герц. Переделать на нужную Вам частоту сами сумеете?

Конечно сумею...

но используемый в Blink оператор delay() останавливает выполнение программы, меня это не устраивает.

Необходимо решение с программироанием таймеров.

 

negavoid
Offline
Зарегистрирован: 09.07.2016

https://arduino-info.wikispaces.com/Timers-Arduino

#define ledPin 13

void setup()
{
  pinMode(ledPin, OUTPUT);

  // using timer1
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;

  TCNT1 = 34286;            // preload timer 65536-16MHz/256/2Hz
  TCCR1B |= (1 << CS12);    // 256 prescaler 
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts();             // enable all interrupts
}

ISR(TIMER1_OVF_vect)        
{
  TCNT1 = 34286;            // preload timer
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
}

void loop()
{
  // your program goes here...
}

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

VladimrYA пишет:

но используемый в Blink оператор delay() останавливает выполнение программы, меня это не устраивает.

http://arduino.ru/tutorials/BlinkWithoutDelay

http://robocraft.ru/blog/arduino/385.html

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

VladimrYA пишет:

но используемый в Blink оператор delay() останавливает выполнение программы, меня это не устраивает.

Кто Вам мешает написать блинк без delay? Пример прямо на главной странице этого сайта.

VladimrYA пишет:

Необходимо решение с программироанием таймеров.

Ну, надо было так сразу и говорить, а то попросили код - Вам дали. 

Если уж Вы решили, что Вам нужно связываться с таймерами, так определитесь дальше - Вас интересует таймер в нормальном режиме (работать по переполнению) или таймер в режиме СТС - там можно вообще один раз его сконфигурить и больше ни строчки Вашего кода не исполняется. Вот здесь есть пример на частоты от 0,12Гц и калькулятор частоты. 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

negavoid, проще в СТС, там не нужен обработчик прерывания.

VladimrYA
Offline
Зарегистрирован: 10.08.2016

ЕвгенийП пишет:

VladimrYA пишет:

но используемый в Blink оператор delay() останавливает выполнение программы, меня это не устраивает.

Кто Вам мешает написать блинк без delay? Пример прямо на главной странице этого сайта.

VladimrYA пишет:

Необходимо решение с программироанием таймеров.

Ну, надо было так сразу и говорить, а то попросили код - Вам дали. 

Если уж Вы решили, что Вам нужно связываться с таймерами, так определитесь дальше - Вас интересует таймер в нормальном режиме (работать по переполнению) или таймер в режиме СТС - там можно вообще один раз его сконфигурить и больше ни строчки Вашего кода не исполняется. Вот здесь есть пример на частоты от 0,12Гц и калькулятор частоты. 

 

Спасибо, это то, что требуется.

Но, нужен не калькулятор.

Нужен код или библиотека, где можно задать частоту в качестве параметра. Типа LongTime(pin,10)

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так там же есть примеры кода с разными частотами, ну и сделайте по образу и подобию, как Вам надо. Если же Вам нужно, чтобы кто-то для Вас сделал, так обратитесь в профильный раздел, там сделают.

VladimrYA
Offline
Зарегистрирован: 10.08.2016

ЕвгенийП пишет:

Так там же есть примеры кода с разными частотами, ну и сделайте по образу и подобию, как Вам надо. Если же Вам нужно, чтобы кто-то для Вас сделал, так обратитесь в профильный раздел, там сделают.

Спасибо. Ваш ответ мне понятен. Вы не знаете такой библиотеки.

Будем искать.

Если кто-то поделится библиотекой, в которой есть функция генерирования меандра заданой частоты без использования delay(), посредством программирования таймеров, напишите, пожалуйста, в этом топике.

Подобная искомой, функция tone(pin, frequency, duration) работает до частоты 31 Гц (https://www.arduino.cc/en/Reference/Tone) на частотах ниже - не работает.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

VladimrYA, гуглить не пробовали?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

VladimrYA пишет:

Вы не знаете такой библиотеки.

Абсолютно точно! Не знаю. И, собственно, не нуждаюсь в таких знаниях. Да и Вы не особо нуждаетесь. На том примере, что я Вам дал, нужная Вам функциональность пишется на 3-5 минут - это значительно быстрее. чем искать и ставить библиотеку. Сделайте сами и не парьтесь! 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Не нравится delay() пользуйтесь antidelay()

void antidelay(uint32_t timing){
timing += millis();
while(millis()<=timing);
}
void setup() {
 pinMode(13, OUTPUT);
}
void loop() {
 digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  antidelay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  antidelay(1000);  
}

Работает до 1кГц. Скорее меньше.

VladimrYA
Offline
Зарегистрирован: 10.08.2016

qwone пишет:

Не нравится delay() пользуйтесь antidelay()

void antidelay(uint32_t timing){
timing += millis();
while(millis()<=timing);
}
void setup() {
 pinMode(13, OUTPUT);
}
void loop() {
 digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  antidelay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  antidelay(1000);  
}

Работает до 1кГц. Скорее меньше.

Спасибо! Улыбнуло ))

Вы или меня прикалываете, либо не поняли вопроса...
Генерация импульсов должна быть фоновой, как у функции tone().

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну шаг в 0.1 мксек вы позже сказали. А функция tone() делается аппаратным, а не программным путем. Я так в процессор не лезу.  И наконец, мне всегда нравится постановка задачи задающими вопросы на форуме. Часть напишут, часть подумают. Вот и вытягивай условия задачи. 

VladimrYA
Offline
Зарегистрирован: 10.08.2016

qwone пишет:

Ну шаг в 0.1 мксек вы позже сказали. А функция tone() делается аппаратным, а не программным путем. Я так в процессор не лезу.  И наконец, мне всегда нравится постановка задачи задающими вопросы на форуме. Часть напишут, часть подумают. Вот и вытягивай условия задачи. 

Простите, где я писал, а вы прочитали про шаг в 0.1 мксек?

Я ищу функцию подобную tone() работующую на частоте НИЖЕ 31 Гц.
Пожалуста, прочитайте топик.

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вам нужно что бы процессор генерировал частоту и при этом работала программа?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

VladimrYA, а вы нажимали на ссылку в #10 ?  первая же строчка в поиске ведёт к нужной ВАМ библиотеке.

VladimrYA
Offline
Зарегистрирован: 10.08.2016

dimax, спасибо.

Извините, ваш пост игнорировал, поскольку конечно же искал и "гуглил". PWM считал другой задачей, как поднять несущую частоту ШИМ...

Постараюсь разобраться, хотя сразу говорят о нижней частоте 31 герц на 8 битных таймерах, как минимально возможных. Видимо ограничения функции tone() имеет эту природу.

negavoid
Offline
Зарегистрирован: 09.07.2016

dimax ЕвгенийП

я искренне поражаюсь вашему терпению, ну, контингент форума обязывает :)

ЕвгенийП читал ваши статьи ещё до приобретения первой ардуины и задолго до регистрации на форуме, большое спасибо, парочку вещей разложили в моей голове в нужные места по полочкам. Да, через СТС и правда удобнее.

VladimrYA
Offline
Зарегистрирован: 10.08.2016

Спасибо всем, кто давал добрые советы )))

Задача:
сделать меандр, низкой частоты (5-10 Гц) используя таймеры и не пользуясь функцией delay() и тем более antidelay(), по понятным соображениям.

Искалась библиотека или функция (код), которые могут это делать. Штатная функция tone() использует 8 битный таймер и имеет ограничение частоты генерации снизу в 31 Гц.

Было предложено разное ((( , в том числе калькулятор расчёта делителей для таймеров, алгоритм выбора таймеров с наименьшей погрешностью генерируемой частоты, библиотека PWM (ШИМ) - видимо всё это работает, не проверялось.

Решение:
скачиваем библиотеку TimerOne.h (16 битный таймер у Arduino Uno) и устанавливаем в системе.
В примере ISRBlink$ генерация меандра 10 Гц: "Timer1.initialize(100000)" в милисекундах. Проверено = работает.

 
 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ура!

Но самому написать было бы полезнее, как ни крути :-)

VladimrYA
Offline
Зарегистрирован: 10.08.2016

ЕвгенийП пишет:

Ура!

Но самому написать было бы полезнее, как ни крути :-)

ЕвгенийП, я всем уже сказал спасибо в топике #20.
Вам персональное спасибо за топики #1, #5, #8, #11.
Особенно за первый ))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вот вариант. Но лучше эту программу загружать на плату и смотреть. Потом подгружать по частям код вашей программы.

// ========== базовый класс   "согласовки" ==================
class qw_basic {            
  public:  
    qw_basic(uint32_t span);
    virtual uint8_t go();
protected:    
    uint32_t span;         // интервал гашения или включения
    uint32_t future;     // время сменить состояние гашения или включения    
};
qw_basic::qw_basic(uint32_t span){
    this->span = span ;
    future = span +  millis();
}
uint8_t qw_basic::go() {           // конструктор qw_basic
    if (millis() < future) return 1;
    future  = span + millis();
    return 0;
}
qw_basic Time_16Gz(500/16); // создание объекта представителя работает с частотой16 Гц
// если надо под другую частоту, то замените 16 
// ====================== Мигалка ==================================
const int Blink_Pin=13;//  вывод устройствa
uint8_t Blink_stat;// состояние светодиода
uint8_t Blink_ini(){
  pinMode(Blink_Pin, OUTPUT);
  Blink_stat = 0;
  digitalWrite(13, Blink_stat);
}
void Blink(){
  Blink_stat = !Blink_stat;
  digitalWrite(13, Blink_stat);
}


// ======================= главная часть программы ========================
void setup() {
  Blink_ini();

}

void loop() {
  if ( ! Time_16Gz.go()) {
  Blink(); // здесь ваш меандр
  }
  //здесь ваш код программы , но старайтесь что бы цилк loop() закачивался чаще 16 Гц.
}

 

NA
Offline
Зарегистрирован: 06.02.2018

Да... терпение потрясающее. Шляпу снимаю с нескрываемым уважением.

Сам бы дальше 3-4 поста это "вы что тут все офигели быстро давайте мне сюда готовое а не фуфло что вы тут обычно кидаете я уже третий раз жду" вряд ли бы стерпел)

Уж простите за некропост))