Выполнение двух подпрограмм одновременно.

400kg
Offline
Зарегистрирован: 13.12.2013

Добрый день. Решил познать мир программирования МК и прикупил платку ардуинки. 

Итак, возникла идейка, сделать на ардуине генератор импульсов и частотомер. Допустим на одной ноге МК висит генератор, который генерирует прямоугольную последовательность импульсов. На другой ноге висит частотомер. По раздельности всё прекрасно работает, но есть одно важное условие, генератор и частотомер должны работь одновременно и не зависимо. 

Вопрос: возможно ли это реализовать на одной плате UNO?

Генератор осуществил следующим образом:

digitalWrite(10, HIGH);
delay(100);
digitalWrite(10, LOW);
delay(100);

Частотомер взял из примера:

#define MAPpin 2 // датчик давления
unsigned long micros_prev = 0, Hz = 0;
void setup() {
	pinMode(4, OUTPUT);
	Serial.begin(115200);
	digitalWrite(MAPpin, 1);
	attachInterrupt(0, MAP, FALLING);
}
void loop(){
	Serial.println(Hz - 40, DEC); // об/мин
	delay(500);
}
void MAP (){
	Hz = (1000000.0/(micros() - micros_prev));
	micros_prev = micros();
}

 

MaksMS
Offline
Зарегистрирован: 11.03.2013

Это тыщу раз обсуждалось как сделать паузу с помощью функции millis()   http://arduino.ru/tutorials/BlinkWithoutDelay

 

 

 

400kg
Offline
Зарегистрирован: 13.12.2013

спасибо, но это не то, что я спрашивал и уже разобрался и сделал с помощью функции tone(), частота удовлетворяет по всем параметрам.

axill
Offline
Зарегистрирован: 05.09.2011

Мк любую программу выполняет последовательно. Если срабатывает прерывание, то выполнение основной программы приостанавливается, обработка других прерываний откладывается

так что в чистом виде "одновременно" и "независимо" не получится

inspiritus
Offline
Зарегистрирован: 17.12.2012

Для генератора ипользуйте не программный генератор на задержках, а один из внутренних таймеров. Выставили на нем частоту , толкнули, и далее он сам, в тч и с разной скважностью.

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

400kg
Offline
Зарегистрирован: 13.12.2013

axill, это понятно, что выполнение программы происходит пошагово, и выполнение 2х программ не возможно на одном МК, меня интересовало, можно ли реализовать сиё дело, так что бы было минимальное время между выполнением кода (и без остановок выполнения кода, т.е. не использовать dleay()).

А чем функция tone() не подходит? Мне нужен генератор меандра с частотой 1350 Гц. На осцилографе отличный прямоугольный импульс.

Вот итоговый код, знатоки, что скажите?

//-----------------Определения-------------------------
#define     MAPpin				2 //вход частотомера
#define		speed				115200 //Скорость передачи данных для последовательного порта
#define		delayMS				500 //Время общей задержки
//------------------------------------------------------------------

//------------------------Переменные--------------------------------
unsigned long micros_prev = 0, Hz = 0;
int PWM = 10;
int Generator = 4;
//------------------------------------------------------------------

void setup() {
	
	//-----------Определяем направление портов--------------------------
	pinMode(Generator, OUTPUT);
	pinMode(PWM, OUTPUT);
	//------------------------------------------------------------------

	Serial.begin(speed); //включаем передачу данных в последовательный порт
	
	digitalWrite(MAPpin, 1);
	attachInterrupt(0, MAP, FALLING); //разрешаем прерывание по функции MAP, при любом изменении сигнала на порту, на пине 2
}

void loop(){
	Serial.println(Hz-86, DEC); // выводим в монитор порта результат измерения
	tone(Generator, 1350); //задаём на выходе 4, сигнал меандр с частотой 1350 Гц
	analogWrite(10, ((Hz-86)/6)-172); //Выводим на пин 10, уровень сигнала при частоте 1350 Гц, напряжение должно быть равно 1В
	delay(delayMS);
}

//Функция подсчёта импульсов. При изменении уровня сигнала, происходит прерывание
void MAP (){		//и расчёт длительности импульса
	Hz = (1000000.0/(micros() - micros_prev));
	micros_prev = micros();
}

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Чтотто каша какаятто

зачем некоторые константы определены в дефайнах, а некоторые определены переменными?

Что такое Hz-86 зачем минус 86 и почему нельзя вычесть один раз, при присвоении переменной Hz

Hz = (1000000.0/(micros() - micros_prev)) - 86;
 
На пин 10 в стр 29 выводится некий PWM , соответствующий условиям - параметрам, чтобы он стал уровнем необходима RC цепочка, на крайняк электролит ( но без сопротивления существует опасность пожечь выход) и наконец чем определяется такая зависимость ожидаемого уровня на 10 пине от частоты на 4 пине. Кстати модулируемая по амплитуде частота на 10 пине не получится. Там будет просто PWM, Если только не применены внешние схемные решения для амплитудной модуляции.

зачем каждые полсекунды передергивается генератор подачей команды tone 

Как я понял Вы генерите в черный ящик меандр, ящик его делит по каким то своим правилам, а Вы считаете частоту что получилось у яшшика на выходе.

может быть Вы опишете полную задачу и окажется, что есть другин пути ее решения ;)

400kg
Offline
Зарегистрирован: 13.12.2013

В общем, на работе в соседнем отделе собирается стенд для настройки и проверки кювет в основе которых лежит лазер. Для настройки сего лазера необходимо на него подать последовательность прямоугольных импульсов со с кважностью 2 и частотой 1350 Гц. Далее, необходимо на выходе лазера (после настройки), необходимо проконтролировать частоту, для этого необходимо измерить выходную частоту и преобразовать её в напряжение (для контроля обычным тестером). Для удобного контроля, было выбрано напряжение в 1В.

Hz-86, 86 это поправка, так как при измерении частоты и отслеживания её в последовательном порту, частота выше как раз на 86 Hz.
Задержка в пол секунды, для удобства отображения данных в мониторе порта, при работе в стенде, планировалось убрать.

inspiritus
Offline
Зарегистрирован: 17.12.2012

Понятно, пин 10 для измерения частоты косвенно ,.. А почему бы не вывести просто значение на дисплейчик?

Напряжение при равной шим на 10 пине может сильно разнИться в зависимости от параметров элементов выходной цепи пин 10.

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

если лазер модулируется некими импульсами может ли вообще измениться частота на выходе?

если считается на арде, при чем тут последовательный порт, там же только отображение уже посчитанного числа?

формально одно и то же , что в порт, что на дисплей, что по сетке....

Когда подается команда tone происходит переинциализация внутреннего таймера и , как следствие сбой фазы выдаваемой частоты. На осциллографе выглядит, как единоразовая большая длительность площадки импульса ___-----___-----_________-----___ ( лог1 или лог0) . Более частая команда - постоянные сбои , прощай скважность, и частота в общем тоже.

 

400kg
Offline
Зарегистрирован: 13.12.2013

последовательный порт временно используется для отображения результата измерений частоты (аля дисплей) в дальнейшем всё что связано с последовательном портом уберётся, ибо не нужно.
Выходные значения с лазера зависят не только от входной частоты, но и от опорных напряжений, которые настраиваюся с помощью подстроечных резисторов.

В 1 Вольт не уперлось совершенно, это был один из вариантов. Вообще я пытался уговорить выводить на дисплей непосредственно частоту снятого с датчика.