Всем известны "Передаём сигнал проверки времени (СПВ). Начало шестого сигнала соответствует...". Ну и шесть пиков. Надо чтобы начало 6-го пика сбросило в ноль счетчики секунд и минут. А его длительность - выставила текущий час (опционально). Но для этого надо сначала убедиться что это именно СПВ, и именно шестой пик. Логично делать это по частоте тона и длительностям пиков и пауз. Выделить сигнал пиков (1000Гц) - не трудно преобразованием Герцеля. Соответственно время начала и конца пика и паузы. Надо сначала пять раз убедиться, что имеем правильные времена, и только после этого начало шестого сигнала принимать за истину. Нет тут ничего сверхумного, только логика. Но на эту логику у меня не хватает фантазии. Может у кого из участников есть готовое решение. С уважением. Вот здесь две рабочие лошадки алгоритма - получение времён начала и конца ПИКА, (то бишь наоборот - конца и начала паузы))))). Все остальное должно делаться на этих временах. Длительность ПИка - 100мС, паузы - 900мС. Длительность 6-го ПИКА зависит от часа - Тмс = 100мс + 20мс * Nчаса. Спойлер boolean Flag1 = false; boolean Flag2 = false; //================================== void loop() { if (Goertz == true) { // Разрешаем искать сигнал проверки времени (СПВ) *********** Mag = TONE.Mag(Samples, numSampl); // Получаем значение сигнала 1000 Гц //--------------------------------------------------- if ((Mag > MinMag && Mag < MaxMag) && (Flag1 == false)) { Start1 = millis(); Flag1 = true; prints("1"); putx('\r'); Silents = (Start1 - Stop1); } //--------------------------------------------------- if ((Mag < MinMag) && (Flag1 == true)) { Stop1 = millis(); Flag1 = false; prints("0"); putx('\r'); Tones = (Stop1 - Start1); } //--------------------------------------------------- if ((Tones > 95) && (Tones < 105) && (Silents > 865) && (Silents < 875)) { // Проверяем длительность Пика и Паузы с точностью 10% prints_P(PSTR(" Tone OK ")); putx('\r'); Tones = 0; Silents = 0; } } } //================================== ПС. Есть рабочий ассемблерный код для PIC-процессора. Но в нем существенный изъян. Он проверяет интервал между началами пиков. Но не проверяет длительность пика и паузы (скважность). То есть любые 1-герцные посылки тона 1КГц для него - СПВ.
честно говоря. не понял, в чём вопрос. Подсчёт пиков проще всего делать на машине состояний. Что-то пошло не по условию - сброс машины в начальное состояние.
не майся дурью, 21 век на дворе. Синхронизируйся по атомным часам, это существенно проще в наше время.
Дык тут первое - суметь ! Моё хобби - впихивать толстое в узкое. Тема ветки - в том же русле. ПС. На одной из хай-тек выставок распиаренный робот супер-позорно облажался. Не смог элементарно вымыть полы, потому что пропал сигнал GPS (!!!). А моя бабушка всю жизнь это делала весьма успешно без GPS-ов, а порой и без электричества !?! ППС. В предложенном выше коде проверяются длительности Пиков и Пауз. Можно конечно проверять длительность ПИКА и Интервал между началами Пиков. Но пока - что есть.
За неимением лучшего, нарисовал сам. Отладочные сообщения конечно можно удалить. Спойлер Goertz == true; //================================== void loop() { if (Goertz == true) { // Разрешаем искать сигнал проверки времени (СПВ) ***************** // Получаем магнитуду для заданной частоты (Freq) Mag = TONE.Mag(Samples, numSampl); //--------------------------------------------------- if ((Mag < MinMag) && (Flag == true)) { // Детектируем конец ПИКА (сигнала) Stop = millis(); // Получили момент конца ПИКа Flag = false; // Отключаем детекцию конца ПИКа prints("0"); putx('\r'); Tones = (Stop1 - Start1); // Вычисляем длительность ПИКа //------------------ if (Picks == 6) { // Если это был 6-й пик - itoa(Tones, ValStr, 10); // Конвертируем число в строку для вывода в ValStr[6] = 0; // терминал в 10-ричной системе. prints_P(PSTR(" Hour is - ")); // Вычисляем номер часа. prints(ValStr); putx('\r'); Picks = 0; // Обнуляем счетчик пиков // Goertz = false; // Можно выходить из процедуры ------ ??????????????????????????????????????????????? // выход из функции } //------------------ // if ((Tones > 380) && (Tones < 420) && (Silents > 3460) && (Silents < 3500)) { if ((Tones > 380) && (Tones < 420) && (Period > 3950) && (Period < 4050)) { Picks++; itoa(Picks, ValStr, 10); // Конвертируем число в строку для вывода в ValStr[6] = 0; // терминал в 10-ричной системе. prints_P(PSTR(" Tone ")); prints(ValStr); putx('\r'); } else { Picks = 0; } //------------------ } //--------------------------------------------------- if ((Mag > MinMag && Mag < MaxMag) && (Flag == false)) { // Детектируем начало ПИКа (сигнала) if (Picks == 6) { // Если здесь начало шестого сигнала - prints_P(PSTR(" ZERO OK ")); // - переход на процедуру обнуления putx('\r'); // счетчиков секунд и минут } // StartPrev = Start; Start = millis(); // Получили момент начала ПИКа Flag = true; // Отключили детекцию начала ПИКа prints("1"); putx('\r'); // Silents = (Start - Stop); // Вычислили длительность паузы Period = (Start - StartPrev); } //--------------------------------------------------- } } //================================== Возникает вопрос : 1. Как и можно ли выйти из функции не оставляя следов ? То бишь полностью освободив память, стек до следующего вызова. Что надо синтаксически правильно дописать в точке выхода (где вопросительные знаки) ? В Протеусе работает. Критика приветствуется. С уважением. ПС. Насчет значений времен (миллисекунд) в коде - Почему-то Диджиспарка в реале работает вчетверо быстрее чем задано в коде. Это не глюк Протеуса, это в реале так. Например Сериал в коде 9600, в реале 38400. Поэтому все цифры времен - умножены в 4 раза. Причину искать мне пока не было интереса.
Мне полностью не надо. Надо правильно ЗА ФУНКЦИЕЙ вычистить. Иначе после каждого вызова функции (6-го пика Маяка) - будет уменьшаться свободная дин. память (как оно там называется - утечка памяти ?) , или стек переполнится.
Ну ладно. Будем надеяться что компилятор позаботится о порядке на вверенной территории. Конечно размещать в главном цикле процедуру, которая нужна от силы 10 секунд в час - глупо. Лучше она смотрится в роли подпрограммы (функции). Спойлер //================================== void loop() { if (Goertz == true) { // Разрешаем искать сигнал проверки времени (СПВ) TimeCorrection(); } } //================================== //================================== void TimeCorrection() { // Функция обнуления минут и секунд и // установки номера часа. while (Goertz) { ********** // Получаем магнитуду для заданной частоты (Freq). Mag = TONE.Mag(Samples, numSampl); //--------------------------------------------------- if ((Mag < MinMag) && (Flag == true)) { // Детектируем конец ПИКА (сигнала) Stop1 = millis(); // Получили момент конца ПИКа Flag = false; // Отключаем детекцию конца ПИКа prints("0"); putx('\r'); Tones = (Stop1 - Start1); // Вычисляем длительность ПИКа //------------------ if (Picks == 6) { // Если это был 6-й пик - itoa(Tones, ValStr, 10); // Конвертируем число в строку для вывода в ValStr[6] = 0; // терминал в 10-ричной системе. prints_P(PSTR(" Hour is - ")); // Вычисляем номер часа. prints(ValStr); putx('\r'); Picks = 0; // Обнуляем счетчик пиков Goertz = false; // Блокируем цикл процедуры return; // Выход } //------------------ // if ((Tones > 380) && (Tones < 420) && (Silents > 3460) && (Silents < 3500)) { if ((Tones > 380) && (Tones < 420) && (Period > 3800) && (Period < 3900)) { Picks++; itoa(Picks, ValStr, 10); // Конвертируем число в строку для вывода в ValStr[6] = 0; // терминал в 10-ричной системе. prints_P(PSTR(" Tone ")); prints(ValStr); putx('\r'); } else { Picks = 0; } //------------------ } //--------------------------------------------------- if ((Mag > MinMag && Mag < MaxMag) && (Flag == false)) { // Детектируем начало ПИКа (сигнала) if (Picks == 6) { // Если здесь начало шестого сигнала - prints_P(PSTR(" ZERO OK ")); // - переход на процедуру обнуления putx('\r'); // счетчиков секунд и минут } // Start2 = Start1; Start1 = millis(); // Получили момент начала ПИКа Flag = true; // Отключили детекцию начала ПИКа prints("1"); putx('\r'); // Silents = (Start1 - Stop1); // Вычислили длительность паузы Period = (Start1 - Start2); // Вычислили длительность периода } } } //--------------------------------------------------- Не мешало бы задействовать управление усилением канала. Коль уж задаром .
на си нет процедур в ардуино проектах никаких стандартов нет. А в действительно больших проектах архитектура проекта очень важна. сишный компилятор никак не следит за действиями программиста и сборщика мусора у него тоже нет. Поэтому читаем книжку и вникаем в простейшие азы.