Написание своей функции pulseIn()
- Войдите на сайт для отправки комментариев
Считываю данные с ультразвукового дальномера HC-SR04 с помощью pulseIn(), но при большом значении расстояния сигнал получается довольно длинный (каждые 58 микросекунд означают 1 см, а датчиков я использую 5 шт и накапливаются значительные задержки), и я решил написать свою версию этой функции, чтобы она считывала длину импульса не более 58 миллисекунд. Получилось следующее:
long mPulseIn(int pin, int state) { unsigned long pulse=0; for(long i=0; i<=1000000; i+=5) if(digitalRead(pin)==state) {break;} else delayMicroseconds(5); for(long i=0; i<=58000; i+=5) if(digitalRead(pin)!=state) {pulse=i; break;} else delayMicroseconds(5); return pulse; }
Но работает это некорректно. Чаще всего функция выводит значение примерно в два раза меньше, чем штатный pulseIn(), а при малых расстояниях вообще что-то не относящееся к делу.
В чем я ошибся, возможно ли вообще написание этой функции таким образом и можно ли реализовать то, что мне нужно, другим способом? Заранее спасибо.
Ваша ошибка в том что вы не внимательно читаете описание функций прежде чем изобретать велосипед. pulseIn()
Возможно я не прав, но там написано, что таймаут задается для ожидания сигнала, а не для ограничения длительности считывания самого сигнала, разве не так?
Без таймера измерять задержки сложно. Я отказался от этой затеи.
Ну и сам puleIn Довольно хитро реализован. Рекомендую посмотреть его исходники
long mPulseIn(int pin, int state)
Я делал повтор работы с дальномером и pulseIn следующим образом. Структурно, код такой:
1. Ждем, пока на ECHO пине дальномера не появится LOW (значит ничем он сейчас не занят и можно юзать)
2. TRIG рин в LOW, 2 мкс задержки, TRIG рин в HIGH, 10 мкс задержки, TRIG рин в LOW (это повор необходимого для работы дальномера)
3. Ждем пока на ECHO пине не появится HIGH (450 микросек примерно)
4. Запускаем таймер для отсчета микросекунд
У себя настраивал так:
5. Ждем LOW на ECHO пине + отслеживаем таймаут
6. Остановливаем таймер и смотрим длину импульса. Или считаем, что измерение не прошло, если длина больше или равна таймауту
Вам, собственно, надо сделать неблокирующие циклы, которые есть в PulseIn
Возможно я не прав, но там написано, что таймаут задается для ожидания сигнала, а не для ограничения длительности считывания самого сигнала, разве не так?
sds, спасибо, если совсем не будет получаться, буду разбираться более подробно. maksim, тоже спасибо, не знал, об ограничении самого импульса нигде, вроде, не писали (или я невнимательный).
Кстати, в самой функции вы можете изменить время ожидания импульса и время длительности импульса.
в файле arduino-1.Х\hardware\arduino\cores\arduino\Arduino.h замените строки:
на
и
на
и в файле arduino-1.Х\hardware\arduino\cores\arduino\wiring_pulse.c замените его содержимое на это:
Тогда при указании 4-го параметра, время ожидания и ограничения будут разными и функция при превышении ограничения будет возвращать ораничение, а не 0:
Большое спасибо, так действительно удобнее