Считывание данных с парктроника

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

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

с помощью вот этого скетча нахожу длинну импульса, и вывожу на экран значения либо 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

Вопрос в следующем, как можно организовать чтение сигналов для представления их в двоичном представлении в массиве, для дальнейшей обработки? Я понимаю, что обращение к элементам массива и сравнение их для вывода на дисплей это еще тот костыль, было бы удобнее получать значения в бинарном коде, а потом сравнивать и выводить на дисплей. Не прошу писать код полностью, а натолкнуть на правильную мысль

 

rkit
Offline
Зарегистрирован: 23.11.2016

Это тупо шим-сигнал

длинный импульс - 1

короткий - 0.

Или наоборот.

b707
Offline
Зарегистрирован: 26.05.2017

kovalenkosteam пишет:

Я понимаю, что обращение к элементам массива и сравнение их для вывода на дисплей это еще тот костыль, было бы удобнее получать значения в бинарном коде, а потом сравнивать и выводить на дисплей.

фигня какая-то написана...

"обращение к элементам массива и сравнение их для вывода на дисплей"  и "удобнее получать значения в бинарном коде, а потом сравнивать и выводить на дисплей" - а в чем разница? то что "в бинарном виде" ? - а в массиве они как, не бинарные?

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

rkit пишет:

Это тупо шим-сигнал

длинный импульс - 1

короткий - 0.

Или наоборот.

Т.е надо в любом случае сравнивать длинну импульса? К примеру если он меньше 100 мкс, то это 0, если больше то 1?

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

возможно мы не поняли друг друга. Имеется массив с длительностью импульсов(как лог.1 так и лог.0). я хочу понять каким способом можно создать массив только с сигналом лог.1 определенной длинны. 

примерно чтобы на выходе было вот так

b707
Offline
Зарегистрирован: 26.05.2017

kovalenkosteam пишет:

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

примерно чтобы на выходе было вот так

всеравно непонятно. Где тут на графике массив только из лог 1? А между сигналами в промежутках - что? Разве не лог 0?

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

Создать массив необходимо. Если длинна импульса лог. 1>100мкс(к примеру) то в массив идёт 1, если меньше, то записываем в массив 0

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

а чем не устраивает 0b10000001100010110 ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

kovalenkosteam пишет:
Создать массив необходимо.

Не понимаю не только как Вы его будете создавать (например, какого размера он у Вас будет), но и, главное, зачем. Нет ни одной задачи, которую этот массив помог бы решить.

Но, если так хотите ... создавайте. Делается это так. Заводите массив и переменную - штдекс. Изначально индекс равен нулю.

1. Ждёте пока уровень не сменится на высокий.
2. Засекаете время
3. Ждёте пока уровень не сменится на низкий
4. Смотрите сколько времени прошло и пишете в массив по индексу 0 или 1
5. Увеличиваете индекс на 1
6. снова с п. 1

Вот собственно всё. Когда массив переполнится, Вы легко узнаете об этом по неадекватному поведению Ардуины.

Пример п.п. 1-4 Вы можете найти в библиотеке для ультразвукового датчика дистанции. Там именно так делается.

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

Тогда как Вы предложите реализовать это без массива? Посылка состоит из:

Первый широкий импульс всегда одинаковый, далее

первые 4 бита неизменны.

5-й бит если 0 — информации на датчике нет, 1 — есть препятствие.

6-й бит всегда 0

7, 8-й биты номер датчика

9-16 биты расстояние в сантиме трах

Я так думаю, что все эти значения необходимо записывать в массив, а дальше брать 9-16 биты, переводить их в расстояние и выводить на экран

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

Вот я не знаю как это сделать без костылей

rkit
Offline
Зарегистрирован: 23.11.2016

kovalenkosteam пишет:

Вот я не знаю как это сделать без костылей

а с костылями религия не позволяет

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

Ну я пишу код как позволяют мои знания. Но мне кажется что вот такой код 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х датчиков?

nik182
Offline
Зарегистрирован: 04.05.2015

А это точно ШИМ? Как по мне это что то 16 битное в последовательном исполнении.Очень похоже на DНТ22.

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

Как мо мне это 1wire

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

kovalenkosteam пишет:

9-16 биты расстояние в сантиме трах

Ровно 8 бит. 1 байт. Собрать биты в байт и все. Скорее всего и переводить в сантиметры не понадобится

b707
Offline
Зарегистрирован: 26.05.2017

kovalenkosteam пишет:
Ну я пишу код как позволяют мои знания. Но мне кажется что вот такой код 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) для определения только одного значения расстояния выглядит как то странно.

не пишите бреда. Вам уже выше пояснили, как раскодировать ваш сигнал в битовую последовательность, никакие массивы и зубодробительные комбинации из десятка условий для этого не нужны.

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

Через bitWrite это организовать?

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Чем снят сигнал ? Где точные временные данные ?

nik182
Offline
Зарегистрирован: 04.05.2015

kovalenkosteam пишет:
Через bitWrite это организовать?

Посмотрите библиотеку DHT22, там организовано считывание похожего сигнала.

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

kovalenkosteam пишет:
Через bitWrite это организовать?

Можно и так

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

Картинка взята из интернета. Но у меня сигнал точно такой же. Время измерения в первом сообщении

Green
Offline
Зарегистрирован: 01.10.2015

Парктроники разные бывают. У одного были посылки 49 бит (старт и 6 байт), у других UART 9600...

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018
1020	
112	1132
228	
120	348
84	
260	344
84	
260	344
84	
256	340
228	
116	344
88	
256	344
88	
252	340
228	
116	344
228	
112	340
224	
120	344
224	
112	336
228	
116	344
228	
112	340
228	
116	344
228	
112	340
228	
120	348
84	

Ждём пока результат pulseIn(pin, HIGH) не будет больше 1000.

В цикле на нужное число бит проверяем результат pulseIn(pin, value) и если он меньше 100, то пишем в текущий бит "0", иначе "1".

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

kovalenkosteam пишет:

Тогда как Вы предложите реализовать это без массива?

Вы забыли написать что "это". Общая задача не описана.

kovalenkosteam пишет:

Я так думаю, что все эти значения необходимо записывать в массив

Ну, думаете, так делайте. Я Вам написал как сложить всё в массив. Надеялся сегодня увидетm Ваш код, написанный по моему алгоритму, но чёта нету :-(

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

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

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

Изменил скетч, теперь он вот такой


#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);
}

на выходе получаем вот такое

100010101111111100
100010001111111100
100010111111111100
100010011111111100
100010101111111100
100010001111111100
100010111111111100
100010011111111100
100010101111111100
100010001111111100
100010111111111100

правда не знаю почему в конце еще один ноль появляется, но с такими данными уже можно будет работать. В любом случае спасибо за советы

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

kovalenkosteam пишет:

правда не знаю почему в конце еще один ноль появляется

Видимо именно столько бит и передает ваш датчик.

Если прерывание настроить на CHANGE, то код прерывания можно сделать короче и быстрее:

attachInterrupt(digitalPinToInterrupt(BTNPIN), Up, CHANGE);
void Up()
{
  if (digitalRead(BTNPIN))
  {
    startImpuls = micros();
  }
  else
  {
    lengthImpuls = micros() -  startImpuls; // Высчитываем длинну сигнала
    startImpuls = 0;
  };
}

 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020
volatile unsigned int startImpuls = 0;
volatile unsigned int lengthImpuls= 0;
unsigned int li = 0;

Почему unsigned int? Разве там предполагаются отрицательные значения? Так то micros() возвращает unsigned long

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

v258 пишет:

Почему unsigned int? Разве там предполагаются отрицательные значения? 

Не чуствуешь здесь противоречия? 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Точно, блин. И ведь шевелилось что-то внутрях на эту тему. И это я еще праздновать толком не начал )))

Вопрос следует поставить по другому - коротковато таки unsigned int здесь будет )))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а я тока завтра в Питере - пить. 

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Не, мяско замариновал, сейчас в фольгу да в духовку. Картошки отварю, пиво в холодильнике - что еще нужно одинокому мужику для праздника )))

А завтра - дела

Green
Offline
Зарегистрирован: 01.10.2015

v258 пишет:

...что еще нужно одинокому мужику для праздника )))


Ну бабу же!)

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Green пишет:

v258 пишет:

...что еще нужно одинокому мужику для праздника )))


Ну бабу же!)

Шоб все испортить? ))) Не, у меня пива только на одного ))

Green
Offline
Зарегистрирован: 01.10.2015

Это да. На бабу нужно раскошеливаться.)) А лонгеры, шампусики сегодня не дёшевы.(

kovalenkosteam
Offline
Зарегистрирован: 28.04.2022

Благодарю, все работает. Спасибо за оптимизацию. Далее буду делать графическое представление, как на родном дисплее парктроника