Подключение китайского парктроника на 8 датчиков к arduino.

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

Приветствую всех, нужно сигнал DATA с блока парктроника расшифровать в ардуино ... если подцепиться осцилографом то получаем следующую картину: длинный импульс (2мс), видимо как синхросигнал, потом 49 импульсов (имеются импульсы 0.1 мс и 0.2мс - широкий и узкий) ... широкий - логическая единица, узкий - ноль ... между концом и началом повторения сигнала идет пробел в 25 мс. Не могу считать и выдать эти данные в порт ... а все потому что не могу разобраться и понять код, что и зачем здесь в параметрах и как это связано))) ...  

#include <TimerOne.h> 

#define LEDPIN 13        // Вывод светодиода 
#define BTNPIN 2  

#define BUFFER_LENGTH 100 

volatile uint16_t startImpuls; 
volatile uint16_t lengthImpuls; 
volatile uint16_t timerCount=0; 

byte buffPos = 0; 
byte Buffer[BUFFER_LENGTH]; 

byte packet[4]; 
byte posInPacket=0; 

byte startBYTE = 15; 

void setup() 
{  /* 
    LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения; 
    CHANGE – прерывание вызывается при изменении значения на входе; 
    RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH) 
    FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW) 
  */ 
  startImpuls=0; 
  lengthImpuls=0; 
   
  pinMode(BTNPIN, INPUT);   
   
  for(int i=0; i< BUFFER_LENGTH; i++) 
    Buffer[i]=0; 
     
  Serial.begin(115200); 
   
  Timer1.initialize(20); 
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt 

  attachInterrupt(0, fireUp, RISING); 
} 
void callback() {  timerCount++; } 

void loop() 
{ 
  if (lengthImpuls > 0) 
  { 
    uint16_t temp=0; 
    uint16_t li = lengthImpuls; 
    lengthImpuls=0; 
     
    //--------------------------// 
    // получена приамбула "1 1 1 1" 
    if (li >50 && li <60) 
    { 
       posInPacket =0; 
    } 
    // Расчитываю позицию массиве 
    temp = posInPacket / 8; 
    uint16_t bitPos = posInPacket; 
    // Разворачиваю позицию для метода bitSet(x,n) 
    bitPos = 7 - bitPos; 
    if (bitPos >= 8) 
    { 
      bitPos =  posInPacket - (8*temp); 
    } 
    
    // Получен "0" 
    if (li >4 && li <6) 
    { 
      posInPacket ++; 
    } 

     // Получен "1" 
    else if (li >10 && li <15) 
    { 
      bitSet(packet[temp],bitPos); 
      posInPacket ++; 
    } 
    //digitalWrite(13,LOW); 
    // Отправить пакет "большему брату" 
    if (posInPacket > 15) 
    { 
      detachInterrupt(0); 
    //  Serial.println("------"); 

      for(int i=0; i<4; i++) 
      { 
        Serial.print(packet[i], BIN); 
        Serial.print(" "); 
        packet[i]=0; 
      } 
      Serial.println(""); 
      posInPacket = 0; 
      attachInterrupt(0, fireUp, RISING); 
    } 
     
    //--------------------------// 
  } 
 } 

// Функция обработки прерывания на подъем 
void fireUp() 
{ 

  detachInterrupt(0); 
  startImpuls = timerCount; 
  attachInterrupt(0, fireDown, FALLING); 
} 

// Функция обработки прерывания на подъем 
void fireDown() 
{ 
  detachInterrupt(0); 
  lengthImpuls = timerCount - startImpuls; 
  startImpuls=0; 
  timerCount=0; 
  attachInterrupt(0, fireUp, RISING); 
}  

///////////////////////////////////////////////////////////////////////////////////////////////
 

для всего этого пользовался данными темы: http://arduino.ru/forum/apparatnye-voprosy/rebyata-pomogite-podklyuchit-datchiki-parkovki-ot-parktronika-k-arduino?page=3

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

С осцила, так выглядит сигнал на  DATA, парктроника

//////////////////////////////////////////////////////////////////////

Так выглядит серия сигналов

///////////////////////////////////////////////////////

Начало посылки ... 

///////////////////////////////////////////////

Конец посылки ... 

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

Если расшифровать данные как я описал выше получаем следующее: 
синхро сигнал, далее:

0111100001111000011110000000001001111101011111010 1 датчик
0000001010000010000000100000001011111101011111010 4 датчика
0000000000000010000000000000000001111101011111010 4 датчика  и препятствие 

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

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020
#include <TimerOne.h>

#define BTNPIN 2 // Вход сигнала
#define TEST 13  // Тест

#define BUFFER_LENGTH 100 // длинна буфера

volatile uint16_t startImpuls;
volatile uint16_t lengthImpuls;
volatile uint16_t timerCount=0;

byte buffPos = 0;            // позиция буфера
byte Buffer[BUFFER_LENGTH]; // длиннпа буфера
byte packet[50];            // хз, разиер пакета
byte posInPacket=0;         // позиция входящего пакета
byte startBYTE = 15;        // стартовый байт

int dat;

void setup()
{  

/* LOW — вызов прерывания всякий раз, 
    когда на порту низкий уровень напряжения;
    CHANGE – прерывание вызывается при изменении 
    значения на входе;
    RISING – вызов прерывания при изменении уровня 
    напряжения с низкого (LOW) на высокое(HIGH)
    FALLING – вызов прерывания при изменении уровня 
    напряжения с высокого (HIGH) на низкое (LOW)*/
  
  startImpuls=0;
  lengthImpuls=0; 
  
  pinMode (TEST, OUTPUT);

  for(int i=0; i< BUFFER_LENGTH; i++) 
    Buffer[i]=0; 
  
  Serial.begin(115200);

  Timer1.initialize(20);                // Интервал срабатывания таймера 1мс
  Timer1.attachInterrupt(callback);

  attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW
                                       // Замеряем только низкий уровень сигнала
}
void callback() {  timerCount++; }

void loop()
{
   if (lengthImpuls > 0) 
  {
     uint16_t temp=0;
     uint16_t li = lengthImpuls; 
     lengthImpuls=0;
  
     if (li > 1.5  && li < 2.5)   // При сигнале длинной 2мс начало пакета
     digitalWrite(13, LOW);
     
     if (li > 0.07  && li < 0.13)   // При сигнале длинной 0.1мс соответствует - 0
     digitalWrite(13, LOW);
     
     if (li > 0.17  && li < 0.23)   // При сигнале длинной 0.2мс соответствует - 1
     digitalWrite(13, HIGH);
     
     Serial.println (li, DEC);    // Отправляем в порт для тестового просмотра
    }
 } 

// Функция обработки прерывания на подъем
void fireUp()
{

  detachInterrupt(0);
  startImpuls = timerCount;
  attachInterrupt(0, fireDown, FALLING);
}

// Функция обработки прерывания на падение
void fireDown()
{
  detachInterrupt(0);
  lengthImpuls = timerCount - startImpuls;
  startImpuls=0;
  timerCount=0;
  attachInterrupt(0, fireUp, RISING);
}
Используя этот код получаю данные с DATA в непрерывном столбце, точно повторяют осцил, только значение 5 - короткий импульс (ноль),
 значение 10 - длинный импульс (единица) ... есть еще сигнал начала передачи (широкий импульс в самом начале) - 97-98 ... 
как бы эти данные разбить на массивы по 50  или 49 (без импульса синхронизации) чисел ... 
и числа 5 и 10 превратить в логические 0 и единицы, чтобы получить логический код ... чтобы приступить к расшифровке.
Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

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

Делал когда то человеку. Да, 49 бит на входе. Тоже  длительности измерял, но уже не помню что к чему.)

MaksVV
Offline
Зарегистрирован: 06.08.2015
#include <TimerOne.h>

#define BTNPIN 2 // Вход сигнала
#define TEST 13  // Тест

#define BUFFER_LENGTH 100 // длинна буфера

volatile uint16_t startImpuls;
volatile uint16_t lengthImpuls;
volatile uint16_t timerCount=0;

byte buffPos = 0;            // позиция буфера
byte Buffer[BUFFER_LENGTH]; // длиннпа буфера
byte packet[50];            // хз, разиер пакета
byte posInPacket=0;         // позиция входящего пакета
byte startBYTE = 15;        // стартовый байт

int dat;

void setup()
{  

/* LOW — вызов прерывания всякий раз, 
    когда на порту низкий уровень напряжения;
    CHANGE – прерывание вызывается при изменении 
    значения на входе;
    RISING – вызов прерывания при изменении уровня 
    напряжения с низкого (LOW) на высокое(HIGH)
    FALLING – вызов прерывания при изменении уровня 
    напряжения с высокого (HIGH) на низкое (LOW)*/
  
  startImpuls=0;
  lengthImpuls=0; 
  
  pinMode (TEST, OUTPUT);

  for(int i=0; i< BUFFER_LENGTH; i++) 
    Buffer[i]=0; 
  
  Serial.begin(115200);

  Timer1.initialize(20);                // Интервал срабатывания таймера 1мс
  Timer1.attachInterrupt(callback);

  attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW
                                       // Замеряем только низкий уровень сигнала
}
void callback() {  timerCount++; }

void loop()
{
   if (lengthImpuls > 0) 
  {
     uint16_t temp=0;
     uint16_t li = lengthImpuls; 
     lengthImpuls=0;
  
     if (li > 95  && li < 100)   // При сигнале длинной 2мс начало пакета
     Serial.println();
     
     if (li > 3  && li < 6)   // При сигнале длинной 0.1мс соответствует - 0
     {Serial.print("0"); Serial.print(" ");}
     
     if (li > 8  && li < 12)   // При сигнале длинной 0.2мс соответствует - 1
     {Serial.print("1"); Serial.print(" ");}
     
    // Serial.println (li, DEC);    // Отправляем в порт для тестового просмотра
    }
 } 

// Функция обработки прерывания на подъем
void fireUp()
{

  detachInterrupt(0);
  startImpuls = timerCount;
  attachInterrupt(0, fireDown, FALLING);
}

// Функция обработки прерывания на падение
void fireDown()
{
  detachInterrupt(0);
  lengthImpuls = timerCount - startImpuls;
  startImpuls=0;
  timerCount=0;
  attachInterrupt(0, fireUp, RISING);
}

 

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

MaksVV пишет:

#include <TimerOne.h>

#define BTNPIN 2 // Вход сигнала
#define TEST 13  // Тест

#define BUFFER_LENGTH 100 // длинна буфера

volatile uint16_t startImpuls;
volatile uint16_t lengthImpuls;
volatile uint16_t timerCount=0;

byte buffPos = 0;            // позиция буфера
byte Buffer[BUFFER_LENGTH]; // длиннпа буфера
byte packet[50];            // хз, разиер пакета
byte posInPacket=0;         // позиция входящего пакета
byte startBYTE = 15;        // стартовый байт

int dat;

void setup()
{  

/* LOW — вызов прерывания всякий раз, 
    когда на порту низкий уровень напряжения;
    CHANGE – прерывание вызывается при изменении 
    значения на входе;
    RISING – вызов прерывания при изменении уровня 
    напряжения с низкого (LOW) на высокое(HIGH)
    FALLING – вызов прерывания при изменении уровня 
    напряжения с высокого (HIGH) на низкое (LOW)*/
  
  startImpuls=0;
  lengthImpuls=0; 
  
  pinMode (TEST, OUTPUT);

  for(int i=0; i< BUFFER_LENGTH; i++) 
    Buffer[i]=0; 
  
  Serial.begin(115200);

  Timer1.initialize(20);                // Интервал срабатывания таймера 1мс
  Timer1.attachInterrupt(callback);

  attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW
                                       // Замеряем только низкий уровень сигнала
}
void callback() {  timerCount++; }

void loop()
{
   if (lengthImpuls > 0) 
  {
     uint16_t temp=0;
     uint16_t li = lengthImpuls; 
     lengthImpuls=0;
  
     if (li > 95  && li < 100)   // При сигнале длинной 2мс начало пакета
     Serial.println();
     
     if (li > 3  && li < 6)   // При сигнале длинной 0.1мс соответствует - 0
     {Serial.print("0"); Serial.print(" ");}
     
     if (li > 8  && li < 12)   // При сигнале длинной 0.2мс соответствует - 1
     {Serial.print("1"); Serial.print(" ");}
     
    // Serial.println (li, DEC);    // Отправляем в порт для тестового просмотра
    }
 } 

// Функция обработки прерывания на подъем
void fireUp()
{

  detachInterrupt(0);
  startImpuls = timerCount;
  attachInterrupt(0, fireDown, FALLING);
}

// Функция обработки прерывания на падение
void fireDown()
{
  detachInterrupt(0);
  lengthImpuls = timerCount - startImpuls;
  startImpuls=0;
  timerCount=0;
  attachInterrupt(0, fireUp, RISING);
}

ооо спасибо)) сегодня занят по работе, как время появится попробую))

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

Green пишет:

Делал когда то человеку. Да, 49 бит на входе. Тоже  длительности измерял, но уже не помню что к чему.)

блин, печально)) и кода и пр. не сохранилось?)) 

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

согласно последнему коду, получилось рассмотреть код лучше ... в итоге пришел к выводу что точное расстояние этот парктроник не показывает, только расстояние  к примеру - от 5 до 30 одно и тоже значение ... от 30 до 60 другое... от 60 и до 130 третье ... нуи  само собой есть препятствие или нет совсем ... походу придется выкидывать МК и цеплять вместо МК ардуино, и уже писать совсем другой код)) ... буду думать как поступить ... 

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

Punk_Андрей пишет:

... походу придется выкидывать МК и цеплять вместо МК ардуино

переведи...

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

Ну МК это что? Это так... А вот АРДУИНО... Это сила)!

MaksVV
Offline
Зарегистрирован: 06.08.2015

вангую, ТС хотел зацепиться к сигналу штатного контроллера системы парктроника, но его это не устроило . И он решил, сам управлять ультразвуковыми датчиками от ардуино, без этого штатного контроллера. 

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

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

MaksVV пишет:

вангую, ТС хотел зацепиться к сигналу штатного контроллера системы парктроника, но его это не устроило . И он решил, сам управлять ультразвуковыми датчиками от ардуино, без этого штатного контроллера. 

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

так и есть))) либо выкинуть контроллер в блоке парктроника и там расшифровывать (подключить дуню) ... либо вообще выкинуть блок парктроника и купить платки от JSN-SR04T  ... по 170 за платку нашел ... нужно 8 ... 
_____________
этот парктроник показывает по 4 деления на каждый датчик ... вот они и есть)) - без препятствия и 4 уровня с препятствием ... на дисплее 8 сегментов ... 4 лево 4 право ... причем он даже не показывает спереди препятствие или сзади ... в коде ... код одинаковый что для переда что для зада ... просто питание приходит в блок разное

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

Punk_Андрей пишет:

блин, печально)) и кода и пр. не сохранилось?)) 

Почему нет? "У нас все ходы записаны.")
Глянул. Ардуино транслирует сигналы с 2х парктроников (8 датчиков) в UART на 9600.

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

Green пишет:

Почему нет? "У нас все ходы записаны.")
Глянул. Ардуино транслирует сигналы с 2х парктроников (8 датчиков) в UART на 9600.

а у меня походу UART не пашет, даже тестовые не работают))) ... Друг программист помог, по коду выше сделать))

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020
#include <TimerOne.h>

#define BTNPIN 2 // Вход сигнала
#define TEST 13  // Тест

//#define BUFFER_LENGTH 100 // длинна буфера

volatile uint16_t startImpuls;
volatile uint16_t lengthImpuls;
volatile uint16_t timerCount=0;

byte buffPos = 0;            // позиция буфера
//byte Buffer[BUFFER_LENGTH]; // длиннпа буфера
byte packet[8];            // хз, разиер пакета
byte posInPacket=0;         // позиция входящего пакета
byte startBYTE = 15;        // стартовый байт

//int dat;

void setup()
{  

/* LOW — вызов прерывания всякий раз, 
    когда на порту низкий уровень напряжения;
    CHANGE – прерывание вызывается при изменении 
    значения на входе;
    RISING – вызов прерывания при изменении уровня 
    напряжения с низкого (LOW) на высокое(HIGH)
    FALLING – вызов прерывания при изменении уровня 
    напряжения с высокого (HIGH) на низкое (LOW)*/
  
  startImpuls=0;
  lengthImpuls=0; 
  
  pinMode (TEST, OUTPUT);

  //for(int i=0; i< BUFFER_LENGTH; i++) 
   // Buffer[i]=0; 
  
  Serial.begin(115200);

  Timer1.initialize(20);                // Интервал срабатывания таймера 1мс
  Timer1.attachInterrupt(callback);

  attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW
                                       // Замеряем только низкий уровень сигнала
}
void callback() {  timerCount++; }

void loop()
{
     int i=0;
     uint16_t dist=0;
     uint16_t li=0;
     bool firstbit=true;
     uint8_t data[8];
     uint8_t sensorindex=0;
  while(true)
  {   
   if (lengthImpuls > 0) 
  {
    // uint16_t temp=0;
     li = lengthImpuls; 
     lengthImpuls=0;

     
     if (li > 90)   // При сигнале длинной 2мс начало пакета
     {
      i=0;
      Serial.print("\n");

      for(int b=0;b<4;b++)
      {
         Serial.print(data[b]);
         Serial.print(" ");
         data[b]=0;
      }
      Serial.print("                 ");
      firstbit=true;
      sensorindex=0;
     } 
     else 
      if (!firstbit)
      {
        if(i>7)
        {
          i=0;
          sensorindex++;
        } 
        
        if (li > 7)   // При сигнале длинной 0.1мс соответствует - 0
          bitSet(data[sensorindex],7-i);
        i++;
       
      
      }
      else
        firstbit=false;
      
   }   
     

    }
    
 } 

// Функция обработки прерывания на подъем
void fireUp()
{

  detachInterrupt(0);
  startImpuls = timerCount;
  attachInterrupt(0, fireDown, FALLING);
}

// Функция обработки прерывания на падение
void fireDown()
{
  detachInterrupt(0);
  lengthImpuls = timerCount - startImpuls;
  startImpuls=0;
  timerCount=0;
  attachInterrupt(0, fireUp, RISING);
}

в общем по этому коду получаем значения)) 0 - препятствие впритык, (потом зона не чувствительности до 25 см, всегда - 0), потом 3 - 30см, 4-40, 5-50 и так далее до 14 ... это условно опять же))
_________
MaksVV,  оказался прав делений куда больше) чем 5-30, 30-60 и так далее)) как раз каждые 10 см примерно ... 

sadman41
Offline
Зарегистрирован: 19.10.2016

Макс, ты же вот с машинами возишься. Если два экземпляра едут друг другу навстречу парктрониками - у приборов башню не сносит? Они же должны издавать сигналы, которые будут пересекаться во времени и пространстве.

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

Я этим паркам не особенно то доверяю. С ними расслабляешься и меньше глядишь в зеркала. А видят они далеко не всё. Хотя на моей машине их просто нет, зато есть фаркоп)) Жена тут сдавала назад, слышит хрусь. Берёзку сломала диаметром см 7, прям шаром фаркопа  упёрлась , вот это радар. 

PS есть камера заднего вида, но она почему-то не всегда работает. Сапожник без сапог, как обычно...

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

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

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020
#include <TimerOne.h>            //библиотека счетчика
#include <Adafruit_GFX.h>        //библиотека графического дисплея
#include <Adafruit_SSD1306.h>    //библиотека OLED дисплея

Использую в коде только 3 библиотеки

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // ширина в пикселях
#define SCREEN_HEIGHT 32 // высота в пикселях
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(OLED_RESET);


void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Инициализирует дисплей. Адрес 0x3C для 128x32
  example_draw_text();    //выводим текст
}


void loop() {
}

void example_draw_text(void) {

     display.clearDisplay(); //очищаем дисплей
     display.setTextSize(3); //размер букв        
     display.setTextColor(WHITE); //цвет букв
     display.setCursor(0,0); //координаты текста          
     display.println("04:28"); //текст
     display.display(); //выводим на дисплей все, что было задано
}

простой скетч, по выводу на дисплей текста)

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020
#include <SPI.h>
#include <TimerOne.h>            //библиотека счетчика
#include <Wire.h>
#include <Adafruit_GFX.h>        //библиотека графического дисплея
#include <Adafruit_SSD1306.h>    //библиотека OLED дисплея

#define OLED_RESET 7                    //пин сброса дисплея
Adafruit_SSD1306 display(OLED_RESET);   //

#define BTNPIN 2 // Вход DATA c парктроника
#define TEST 13  // Тестовый светодиод

volatile uint16_t startImpuls;
volatile uint16_t lengthImpuls;
volatile uint16_t timerCount=0;

void setup()
{  

/* LOW — вызов прерывания всякий раз, 
    когда на порту низкий уровень напряжения;
    CHANGE – прерывание вызывается при изменении 
    значения на входе;
    RISING – вызов прерывания при изменении уровня 
    напряжения с низкого (LOW) на высокое(HIGH)
    FALLING – вызов прерывания при изменении уровня 
    напряжения с высокого (HIGH) на низкое (LOW)*/

 
  startImpuls=0;
  lengthImpuls=0; 
  
  pinMode (TEST, OUTPUT);
  Serial.begin(115200);
  Timer1.initialize(20);                // Интервал срабатывания таймера 1мс
  Timer1.attachInterrupt(callback);
  attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW
   
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // инициализация дисплея по интерфейсу I2C, адрес 0x3C)
  display.clearDisplay(); // очистка дисплея
  display.setTextSize(2); //размер букв        
  display.setTextColor(WHITE); //цвет букв
  display.setCursor(0,0); //координаты текста
  //example_draw_text();   
  
}

void callback() {timerCount++;}

void loop()
   {
    
    //display.println(12);
    //display.display();
    //interrupts();
    TIME();
    //noInterrupts();
    OLED();     
  } 

///////////////////// Функция обработки прерывания на подъем
void fireUp()
  {
  detachInterrupt(0);
  startImpuls = timerCount;
  attachInterrupt(0, fireDown, FALLING);
  }

///////////////////// Функция обработки прерывания на падение
void fireDown()
  {
  detachInterrupt(0);
  lengthImpuls = timerCount - startImpuls;
  startImpuls=0;
  timerCount=0;
  attachInterrupt(0, fireUp, RISING);
  }

////////////////////// Функция обработки полученных данных
void TIME()
   {
   int i=0;
   uint16_t dist=0;
   uint16_t li=0;
   bool firstbit=true;
   uint8_t data[8];
   uint8_t sensorindex=0;
   
   while(true)
        {
        if (lengthImpuls > 0) 
             {
             li = lengthImpuls; 
             lengthImpuls=0;
             if (li > 90)   // Сигнал начала пакета
                   {
                   i=0;
                   Serial.print("\n");
                   for(int b=0;b<4;b++)
                           {
                           Serial.print(data[b]);
                           Serial.print(" ");
                           data[b]=0;
                           }
                   Serial.print("                 ");
                   firstbit=true;
                   sensorindex=0;
                   } 
             else 
             if (!firstbit)
                   {
                   if(i>7)
                           {
                           i=0;
                           sensorindex++;
                           } 
                   if (li > 7)   // При сигнале длинной 0.1мс соответствует - 0
                   bitSet(data[sensorindex],7-i);
                   i++;
                   }
             else
             firstbit=false;  
             }   
        }
   }

/////////////////////// Вывод на дисплей
void OLED(void)
  {
  display.println(data[1]); //текст
  display.display();
  }

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

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

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

поэтому просто примите как данность - этот код на экран ничего выводить не будет, даже если вы исправите ошибку с data[]

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

b707 пишет:

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

поэтому просто примите как данность - этот код на экран ничего выводить не будет, даже если вы исправите ошибку с data[]

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

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

b707 пишет:

 походу вы полный ноль в программировании...

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

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

я не знаю, о каком "таймере" вы говорите, но дело не в нем...

Зачем Вы вставили цикл while(true) в ЛУП (строка 89) ? - из этого цикла у вас в программе нет выхода, один раз попав в него, программа зависнет там и уже никогда не попадет в процедуру OLED(). Поэтому у вас и нет вывода на экран.

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

b707 пишет:

я не знаю, о каком "таймере" вы говорите, но дело не в нем...

Зачем Вы вставили цикл while(true) в ЛУП (строка 89) ? - из этого цикла у вас в программе нет выхода, один раз попав в него, программа зависнет там и уже никогда не попадет в процедуру OLED(). Поэтому у вас и нет вывода на экран.

ого, не знал)) думаю почему после этого цикла ничего не прилетает)) ... это друг написал часть кода, я не знал что делает while:) спасибо, пошел курить на эту тему))

Punk_Андрей
Offline
Зарегистрирован: 12.10.2020

b707 пишет:

Зачем Вы вставили цикл while(true) в ЛУП (строка 89) ? - из этого цикла у вас в программе нет выхода, один раз попав в него, программа зависнет там и уже никогда не попадет в процедуру OLED(). Поэтому у вас и нет вывода на экран.

в общем ушел от того кода, ибо не знаю как избавиться от While, ничего не нарушив в работе ... вернулся к изначальному, но сравнив эти два кода получил это: 

#include <TimerOne.h> 
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // ширина в пикселях
#define SCREEN_HEIGHT 32 // высота в пикселях
#define OLED_RESET     4 // сброс дисплея

#define LEDPIN 13        // Вывод светодиода 
#define BTNPIN 2  

#define BUFFER_LENGTH 100 

volatile uint16_t startImpuls; 
volatile uint16_t lengthImpuls; 
volatile uint16_t timerCount=0; 

byte buffPos = 0; 
byte Buffer[BUFFER_LENGTH]; 

byte packet[8]; 
byte posInPacket=0; 

byte startBYTE = 20; 

Adafruit_SSD1306 display(OLED_RESET);

void setup() 
{  /* 
    LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения; 
    CHANGE – прерывание вызывается при изменении значения на входе; 
    RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH) 
    FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW) 
  */ 

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Инициализирует дисплей. Адрес 0x3C для 128x32
  display.clearDisplay(); //очищаем дисплей
  display.setTextSize(3); //размер букв        
  display.setTextColor(WHITE); //цвет букв
  display.setCursor(0,0); //координаты текста
     
  startImpuls=0; 
  lengthImpuls=0; 
   
  pinMode(BTNPIN, INPUT);   
   
  for(int i=0; i< BUFFER_LENGTH; i++) 
    Buffer[i]=0; 
     
  Serial.begin(115200); 
   
  Timer1.initialize(20); 
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt 

  attachInterrupt(0, fireUp, RISING); 
} 
void callback() {  timerCount++; } 

void loop() 
{display.clearDisplay();
 scanner ();
// OLED();
} 

// Функция обработки прерывания на подъем 
void fireUp() 
{ 

  detachInterrupt(0); 
  startImpuls = timerCount; 
  attachInterrupt(0, fireDown, FALLING); 
} 

// Функция обработки прерывания на подъем 
void fireDown() 
{ 
  detachInterrupt(0); 
  lengthImpuls = timerCount - startImpuls; 
  startImpuls=0; 
  timerCount=0; 
  attachInterrupt(0, fireUp, RISING); 
}  

// Преобразования
void scanner()
{ 
    if (lengthImpuls > 0) 
    { 
    uint16_t temp=0; 
    uint16_t li = lengthImpuls;
    lengthImpuls=0; 
     
       if (li >90) {posInPacket = 2;}           // Начало пакета 
       temp = posInPacket / 8;                 // Расчитываю позицию массиве 
       uint16_t bitPos = posInPacket; 
       bitPos = 7 - bitPos;                    // Разворачиваю позицию для метода bitSet(x,n) 
       if (bitPos >= 8) {bitPos =  posInPacket - (8*temp);} 
       if (li <7) {posInPacket ++;}  // Получен "0" 
       else if (li >8) {bitSet(packet[temp],bitPos); posInPacket++;}  // Получен "1" 
       if (posInPacket > 49) {detachInterrupt(0);   // Отправить пакет "большему брату" 
       for(int i=0; i<8; i++) {Serial.print(packet[i], BIN); Serial.print(" "); /*display.print(packet[i], DEC); display.display();*/ packet[i]=0;} //выводим на дисплей все, что было задано
       Serial.println(""); 
       posInPacket = 47; 
       attachInterrupt(0, fireUp, RISING);} 
     } 
 } 
// Дисплей
/*void OLED()
{
  display.print(packet[2], DEC); 
  display.display();}*/

 

проблема сейчас в следующем ... после начала "контрольной суммы" идет лишний бит, потом идут 4 партии по 8 бит на датчик ( по байту на датчик) ... дак вот из за этого лишнего бита вначале ... три датчика (2 3 4) показывают правильно, а первый фигню гонит ... можете подсказать как исключить один, первый бит? т. е. начиная со второго считать 4 пакета по 8 бит ... данные получаю вот такие: 

101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11111000 11111000 11111100 11111110 11111111 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11111000 11111100 11111100 11111111 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11111000 11111000 11111100 11111110 11111111 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11111000 11111000 11111100 11111100 11111111 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 
101111 11110000 11110000 11110000 11110000 11110101 1 0 

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