Считывание данных с парктроника
- Войдите на сайт для отправки комментариев
Всех приветствую. Хочу разобраться в декодировании сигнала с парктроника, но возникают некоторые сложности в этом. Будем рассматривать сигнал с одного датчика, он имеет следующий вид
с помощью вот этого скетча нахожу длинну импульса, и вывожу на экран значения либо 2.5 метра до препятствия, либо 0.3
#include <LCD_1602_RUS.h>
LCD_1602_RUS lcd(0x27, 16, 2);
const int pin =2;
const unsigned int number=36;
volatile unsigned long microseconds;
volatile byte idx=0;
const int led=13;
volatile unsigned int results[number];
void setup() {
// put your setup code here, to run once:
pinMode(pin,INPUT_PULLUP);
Serial.begin(115200);
lcd.init();
lcd.backlight();
lcd.clear();
attachInterrupt(digitalPinToInterrupt(pin), analyze, CHANGE);
results[0]=0;
}
void loop() {
// put your main code here, to run repeatedly:
if(idx>=number)
{
Serial.print("Duration in Microseconds are:");
for(byte i=0;i<number; i=i+1)
{
Serial.print(i);
Serial.print(":");
Serial.println(results[i]);
if (results[15]>150 && results[17]>150 && results[19]>150 && results[21]>150 && results[23]>150 && results[25]>150 && results[27]>150 && results[29]>150 && results[31]>150 && results[33]>150)
{
lcd.setCursor(3, 0);
lcd.print("2.5 метра");
}
if (results[15]>150 && results[17]>150 && results[19]<150 && results[21]<150 && results[23]<150 && results[25]>150 && results[27]>150 && results[29]>150 && results[31]>150 && results[33]<150)
{
lcd.setCursor(3, 0);
lcd.print("0.3 метра");
//digitalWrite(led,LOW);
}
}
idx=0;
}
//delay(1000);
}
void analyze()
{
if(idx<number)
{
if(idx>=0)
{
results[idx]=micros()-microseconds;
}
idx++;
}
microseconds= micros();
}
по этой этому скетчу получаю значения
1:1020 2:112 3:228 4:120 5:84 6:260 7:84 8:260 9:84 10:256 11:228 12:116 13:88 14:256 15:88 16:252 17:228 18:116 19:228 20:112 21:224 22:120 23:224 24:112 25:228 26:116 27:228 28:112 29:228 30:116 31:228 32:112 33:228 34:120 35:84
Вопрос в следующем, как можно организовать чтение сигналов для представления их в двоичном представлении в массиве, для дальнейшей обработки? Я понимаю, что обращение к элементам массива и сравнение их для вывода на дисплей это еще тот костыль, было бы удобнее получать значения в бинарном коде, а потом сравнивать и выводить на дисплей. Не прошу писать код полностью, а натолкнуть на правильную мысль
Это тупо шим-сигнал
длинный импульс - 1
короткий - 0.
Или наоборот.
Я понимаю, что обращение к элементам массива и сравнение их для вывода на дисплей это еще тот костыль, было бы удобнее получать значения в бинарном коде, а потом сравнивать и выводить на дисплей.
фигня какая-то написана...
"обращение к элементам массива и сравнение их для вывода на дисплей" и "удобнее получать значения в бинарном коде, а потом сравнивать и выводить на дисплей" - а в чем разница? то что "в бинарном виде" ? - а в массиве они как, не бинарные?
Это тупо шим-сигнал
длинный импульс - 1
короткий - 0.
Или наоборот.
возможно мы не поняли друг друга. Имеется массив с длительностью импульсов(как лог.1 так и лог.0). я хочу понять каким способом можно создать массив только с сигналом лог.1 определенной длинны.
примерно чтобы на выходе было вот так
хочу понять каким способом можно создать массив только с сигналом лог.1 определенной длинны.
примерно чтобы на выходе было вот так
всеравно непонятно. Где тут на графике массив только из лог 1? А между сигналами в промежутках - что? Разве не лог 0?
Создать массив необходимо. Если длинна импульса лог. 1>100мкс(к примеру) то в массив идёт 1, если меньше, то записываем в массив 0
а чем не устраивает 0b10000001100010110 ?
Не понимаю не только как Вы его будете создавать (например, какого размера он у Вас будет), но и, главное, зачем. Нет ни одной задачи, которую этот массив помог бы решить.
Но, если так хотите ... создавайте. Делается это так. Заводите массив и переменную - штдекс. Изначально индекс равен нулю.
1. Ждёте пока уровень не сменится на высокий.
2. Засекаете время
3. Ждёте пока уровень не сменится на низкий
4. Смотрите сколько времени прошло и пишете в массив по индексу 0 или 1
5. Увеличиваете индекс на 1
6. снова с п. 1
Вот собственно всё. Когда массив переполнится, Вы легко узнаете об этом по неадекватному поведению Ардуины.
Пример п.п. 1-4 Вы можете найти в библиотеке для ультразвукового датчика дистанции. Там именно так делается.
Тогда как Вы предложите реализовать это без массива? Посылка состоит из:
Первый широкий импульс всегда одинаковый, далее
первые 4 бита неизменны.
5-й бит если 0 — информации на датчике нет, 1 — есть препятствие.
6-й бит всегда 0
7, 8-й биты номер датчика
9-16 биты расстояние в сантиме трах
Я так думаю, что все эти значения необходимо записывать в массив, а дальше брать 9-16 биты, переводить их в расстояние и выводить на экран
Вот я не знаю как это сделать без костылей
Вот я не знаю как это сделать без костылей
а с костылями религия не позволяет
Ну я пишу код как позволяют мои знания. Но мне кажется что вот такой код if (results[15]>150 && results[17]>150 && results[19]>150 && results[21]>150 && results[23]>150 && results[25]>150 && results[27]>150 && results[29]>150 && results[31]>150 && results[33]>150) для определения только одного значения расстояния выглядит как то странно. А если надо все значения расстояния? Тем более с 4х датчиков?
А это точно ШИМ? Как по мне это что то 16 битное в последовательном исполнении.Очень похоже на DНТ22.
Как мо мне это 1wire
9-16 биты расстояние в сантиме трах
Ровно 8 бит. 1 байт. Собрать биты в байт и все. Скорее всего и переводить в сантиметры не понадобится
не пишите бреда. Вам уже выше пояснили, как раскодировать ваш сигнал в битовую последовательность, никакие массивы и зубодробительные комбинации из десятка условий для этого не нужны.
Через bitWrite это организовать?
Чем снят сигнал ? Где точные временные данные ?
Посмотрите библиотеку DHT22, там организовано считывание похожего сигнала.
Можно и так
Картинка взята из интернета. Но у меня сигнал точно такой же. Время измерения в первом сообщении
Парктроники разные бывают. У одного были посылки 49 бит (старт и 6 байт), у других UART 9600...
Ждём пока результат pulseIn(pin, HIGH) не будет больше 1000.
В цикле на нужное число бит проверяем результат pulseIn(pin, value) и если он меньше 100, то пишем в текущий бит "0", иначе "1".
Тогда как Вы предложите реализовать это без массива?
Вы забыли написать что "это". Общая задача не описана.
Я так думаю, что все эти значения необходимо записывать в массив
Ну, думаете, так делайте. Я Вам написал как сложить всё в массив. Надеялся сегодня увидетm Ваш код, написанный по моему алгоритму, но чёта нету :-(
Работу никто не отменял... ( Вы были правы, насчёт того что массив не нужен, а проще будет записывать побитово в переменную, а потом считывать с неё определённые байты. Вот сижу разбираюсь пока в этом вопросе
Изменил скетч, теперь он вот такой
#define BTNPIN 2 // Вход сигнала от линии DA парктроника volatile unsigned int startImpuls = 0; volatile unsigned int lengthImpuls= 0; unsigned int li = 0; unsigned long myByte; void setup() { pinMode(BTNPIN, INPUT_PULLUP); Serial.begin(115200); attachInterrupt(0, Up, RISING); // Запуск прерывания при наличии сигнала HIGH } void loop() { if (lengthImpuls > 0) { li = lengthImpuls; lengthImpuls=0; if (li > 900 && li < 1200) // При сигнале длинной 1024 мкс начало пакета { Serial.println(myByte,BIN); myByte=0; // Переменная сбрасывается в ноль при наличии первого неизменного импульса } if (li > 50 && li < 150) // При сигнале длинной менее 100 мкс соответствует лог.0 { myByte=myByte<<1; // Перемещаем бит влево при ниличии лог.0 } if (li > 190 && li < 240) // При сигнале длинной 200 мкс соответствует лог. 1 { bitSet(myByte,0); // Выставляем бит=1 при наличии лог.1 myByte=myByte<<1; // сдвигаем бит влево } } } // Функция обработки прерывания на подъем void Up() { detachInterrupt(0); startImpuls = micros(); attachInterrupt(0, Down, FALLING); } // Функция обработки прерывания на падение void Down() { detachInterrupt(0); lengthImpuls = micros() - startImpuls; // Высчитываем длинну сигнала startImpuls=0; attachInterrupt(0, Up, RISING); }на выходе получаем вот такое
правда не знаю почему в конце еще один ноль появляется, но с такими данными уже можно будет работать. В любом случае спасибо за советы
правда не знаю почему в конце еще один ноль появляется
Видимо именно столько бит и передает ваш датчик.
Если прерывание настроить на CHANGE, то код прерывания можно сделать короче и быстрее:
void Up() { if (digitalRead(BTNPIN)) { startImpuls = micros(); } else { lengthImpuls = micros() - startImpuls; // Высчитываем длинну сигнала startImpuls = 0; }; }Почему unsigned int? Разве там предполагаются отрицательные значения? Так то micros() возвращает unsigned long
Почему unsigned int? Разве там предполагаются отрицательные значения?
Не чуствуешь здесь противоречия?
Точно, блин. И ведь шевелилось что-то внутрях на эту тему. И это я еще праздновать толком не начал )))
Вопрос следует поставить по другому - коротковато таки unsigned int здесь будет )))
а я тока завтра в Питере - пить.
Не, мяско замариновал, сейчас в фольгу да в духовку. Картошки отварю, пиво в холодильнике - что еще нужно одинокому мужику для праздника )))
А завтра - дела
...что еще нужно одинокому мужику для праздника )))
Ну бабу же!)
...что еще нужно одинокому мужику для праздника )))
Ну бабу же!)
Шоб все испортить? ))) Не, у меня пива только на одного ))
Это да. На бабу нужно раскошеливаться.)) А лонгеры, шампусики сегодня не дёшевы.(
Благодарю, все работает. Спасибо за оптимизацию. Далее буду делать графическое представление, как на родном дисплее парктроника