Девяти канальный генератор прямоугольных импульсов
- Войдите на сайт для отправки комментариев
Всем привет, я новичек на форуме и в программировании тоже.
Прошу помощи.
В общем нужен скетч для 9ти канального генератора импульсов прямоугольной формы, с регулировкой частоты и скважности (можно как и правкой скетча, так и потенциометрами или кнопками). Частота до 500Гц.
Самое главное в работе генератора, это чтобы 8 каналов зависили от одного. Тоесть за некоторое время до окончания импульса на этом канале на остальных импульса не было. Оставшиеся 8 каналов работают по типу бегущих огней.
Прилагаю рисунок, сильно не пинать, я не пикассо.
Скетч я написал, но только для работы каналов в разнобой, не могу прописать зависимость всех каналов от одного.
int genPin = 13; // номер пина генератора int genState = LOW; // состояние генератора // последний момент времени, когда состояние генератора изменялось unsigned long previousMillisGen = 0; long genOnTime = 100; // длительность импульса (в миллисекундах) long genOffTime = 100; // длительность паузы (в миллисекундах) class Flasher { // Переменные - члены класса // Инициализируются при запуске int ledPin; // номер пина со светодиодом long OnTime; // время включения в миллисекундах long OffTime; // время, когда светодиод выключен // Текущее состояние int ledState; // состояние ВКЛ/ВЫКЛ unsigned long previousMillis; // последний момент смены состояния // Конструктор создает экземпляр Flasher и инициализирует // переменные-члены класса и состояние public: Flasher(int pin, long on, long off) { ledPin = pin; pinMode(ledPin, OUTPUT); OnTime = on; OffTime = off; ledState = LOW; previousMillis = 0; } void Update() { // выясняем не настал ли момент сменить состояние светодиода unsigned long currentMillis = millis(); // текущее время в миллисекундах if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime)) { ledState = LOW; // выключаем previousMillis = currentMillis; // запоминаем момент времени digitalWrite(ledPin, ledState); // реализуем новое состояние } else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime)) { ledState = HIGH; // включаем previousMillis = currentMillis ; // запоминаем момент времени digitalWrite(ledPin, ledState); // реализуем новое состояние } } }; Flasher led1(9, 100, 100); Flasher led2(10, 300, 200); Flasher led3(11, 400, 300); Flasher led4(12, 600, 500); void setup() { // устанавливаем цифровой пин генератора как ВЫХОД pinMode(genPin, OUTPUT); } void loop() { // выясняем не настал ли момент сменить состояние генератора unsigned long currentMillisGen = millis(); // текущее время в миллисекундах // если светодиод включен и светится больше чем надо if((genState == HIGH) && (currentMillisGen - previousMillisGen >= genOnTime)) { genState = LOW; // выключаем previousMillisGen = currentMillisGen; // запоминаем момент времени digitalWrite(genPin, genState); // реализуем новое состояние } else if ((genState == LOW) && (currentMillisGen - previousMillisGen >= genOffTime)) { genState = HIGH; // включаем previousMillisGen = currentMillisGen ; // запоминаем момент времени digitalWrite(genPin, genState); // реализуем новое состояние } led1.Update(); led2.Update(); led3.Update(); led4.Update(); }
Не обращайте внимания на названия переменных, они взяты из разных скетчей. Там где написано Gen это тот канал от котоорого нужна зависимость. LED это 8 зависимых каналов.
Всем заранее благодарен!!!
Не понял, по какому принципу формируются импульсы на зависимых каналах, но это такое. На рисунке зависимостей не углядел, скетч смотреть лень (тем более, что он работает не так, как хочется). Я так понял, что основная проблема сейчас - это запрет импульсов в "зеленой зоне"? Если да, то можно сделать так. Генерируем импульсы на главном канале ведь мы сами, т.е. всегда знаем их длительность - допустим 10 ms. "Некоторое время до окончания импульса", ну и "некоторое время после окончания импульса" нам, я так понимаю, тоже задано и известно, допустим по 0.5 ms, т.е. "зеленая зона" будет иметь длительность 1 ms.
Заведем какую-то глобальную переменную, по значению которой будем определять, можно ли выдавать на выходах зависимых каналов импульсы (пускай при ее значении "1" - можно, "0" - запрет, при ее инициализации ставим ее в "1"). В момент начала импульса на главном канале, запускаем отсчет времени и по истечении 9.5 ms (длина импульса на главном канале минус "некоторое время до окончания импульса") выставляем значение этой переменной в "0", а по истечении еще 1 ms ("зеленая зона" закончилась) возвращаем ее в "1".
А уже при генерации импульсов на зависимых каналах будем проверять эту глобальную переменную. Если в какой-то момент на выходе зависимого канала должен быть высокий уровень, то проверяем также и эту переменную. Если там "добро", то выдаем высокий уровень, иначе - попали на "зеленую зону" и выставляем низкий. Т.е. тут чистое логическое "И".
Да Вы полностью правы, но поскольку я ноль в программировании, то написать это я сам не могу.
Частота 1го канала и 8ми остальных регулируюся отдельно, 8 зависимых каналов имеют одну частоту
Папалекси, это не тот случай, когда можно помочь советом. Тут светит серьёзная работа по разработке алгоритма и программированию.
Да он просто криво нарисовал, миллиметровки или листка в клеточку не нашлось, алгоритм простой, нечётные импульсы тактируются передним фронтом, чётные задним с задержкой T, число импульсов для счёта - 4 )))
Разрисовать получится красиво, а не эта абракадабра
да скважность естественно не 50
ua6em, ну так посоветуйте ТС что-то, коли алгоритм простой ) Мне вот видится большая рутина..
1 канал работает на своей отдельной частоте и скважности.
Частота и скважность 1го не зависит от частоты и скважности со 2го по9й
каналы со 2го по 9й работают на другой частоте и другой скважности.
и там и там частота и скважность регулируется отдельно.
каналы со 2го по 9й - это бегущие огни, каждый следующий включается после предыдущего.
Самое главное чтобы небыло сигнала на каналах со 2го по 9й в конце импульса первого канала.
В скетче который я выложил все генерируется, только в зеленой зоне сигнал на каналах 2-9 есть, а надо чтобы небыло.
Да Вы полностью правы, но поскольку я ноль в программировании, то написать это я сам не могу.
Ну скетч то Вы уже написали, значит не полный ноль. Начните с того, что нарисуйте тот же рисунок, но точный (можно на миллиметровке, можно в графическом редакторе на компе), чтобы было видно, что и в какой момент должно происходить. Но пока без "зеленых зон". Разберитесь как оно должно работать. Создайте алгоритм - представьте, что это вам самому надо включать и выключать рубильники в определенной последовательности - напишите для себя эту последовательность, чтобы Вы сами понимали. А по алгоритму уже пишите скетч. И уже потом, когда будет работать как надо, но без "зеленых зон", добавите эти "зеленые зоны". Алгоритм их работы я уже расписал.
Хорошо попробую. Потом отпишусь что из этого вышло.
я этот скетч просто собрал из двух уже готовых, сделанных не мной
По сути здесь два независимых генератора. Выход второго блокируется на неизвестное время. Второй имеет 8 выходов, которые крутятся по кругу с каждым импульсом. Что бы хоть что то посоветовать надо знать следующее. От какой частоты и с каким шагом регулировать первый генератор до частоты 500Гц. Тоже для второго генератора. Ширина зелёной зоны и зависит ли она от частоты. Пределы регулирования скважности первого и второго генератора. Если шаг изменения частоты равен зелёной зоне, и минимальная частота на менее 2 герц, то всё просто. Если что то то более затратное по ресурсам то надо думать, как впихнуть невпихуемое.
ua6em, ну так посоветуйте ТС что-то, коли алгоритм простой ) Мне вот видится большая рутина..
я заблуждался, синхронизации никакой нет, следовательно, вижу только как решить програмно-аппаратно, немного логики рассыпухи и одновибратор типа АГ запускаемый по заднему фронту, можно на 555 но я с ними не работал, увы, программно это тоже можно, но это реалтайм, на этом проце точно не ко мне
Я немного неправильно описал, не по заднему фронту, а за некоторое время до заднего фронта и некоторое после заднего фронта. На аппаратном уровне несколько сложно это реализовать.
Как на рисунке начало и конец "зеленой зоны"
Я немного неправильно описал, не по заднему фронту, а за некоторое время до заднего фронта и некоторое после заднего фронта. На аппаратном уровне несколько сложно это реализовать.
Как на рисунке начало и конец "зеленой зоны"
тогда понадобится два одновибратора или программно реализовать это "несколько впереди заднего фронта" и начинать надо с канала 1 (по вашему обозначению)
Вроде получилось, только не могу сбросить зависимые каналы во время зеленой зоны.
Код не претендует конечно на оптимизированность, но главное что истина гдето рядом.
они остаются в том же состоянии что и до зеленой зоны, но во время зеленой зоны импульсы на зависимых каналах не генерируются.
Помогите кто чем может.
зависымые каналы включаются с 84 строки, туда нужно подставить код, который будет переводить выходы в LOW.
не могу никак это сделать.
1) проблема в том, что не любую частоту можно синтезировать. Чем выше частота -тем больше шаг в "сетке" возможных частот. Впрочем до 5000 Герц особых проблем нет. Шаг в 1 Герц реален.
2,3) Скорее ни на какой, если нужно именно от 5 каналов. Реально на плате с МК stm32 , причём подойдёт не любая, а та, где много таймеров. Типа такой, тут 8 таймеров, соответссно 8 каналов возможно сделать:
О,как...
по п.1 - там частота в "подчиненных" каналах может быть значительно выше 5к... и значительно ниже 2 - это возможно? Про "плавающий" шаг при регулировке я читал в Ваших постах - это мне не критично. Меня интересует - какую максимальную/минимальную частоту я могу получить?
по 2-3 - а как же это обсуждение в этой ветке девятиканального генератора?
Spbster, о максимальных частотах и шаге почитайте тут, пост 23, параграф Генерация прямоугольного сигнала. Минимальная частота тоже имеет ограничение, но сходу не вспомню. Единицы миллигерц наверное. У топикстартера другая задача -частота там до 500 Герц, это можно программными методами решить. В вашем случае только аппаратными.
Частоту отличную от основной можно получить только на отдельном таймере. Если частота одна и таже но скважность разная то на stm может быть 4 канала на таймер. Частота зависит от скважности, при меандре до десятков МГц. В низ практически сколько угодно.
Понял, большое спасибо за ответы.