Помогите посчитать длительность импульсов.

typeigor
Offline
Зарегистрирован: 04.08.2013

Ардуино...

Сигнал...

0 иль 1 зависит от длительности.

Пробовал методом PulseIn.По отдельности Hight или Low считает...Вместе никак...

Может подскажете метод по изящнее...

Нужно получить  A7 C0 03 01 BB 40...

Да и хорошоб возможность и отправить...

Заранее.Best Regards.

maksim
Offline
Зарегистрирован: 12.02.2012

В прерывании фиксируйте значение micros() и в зависимости от уровня сигнала определяйте 0 это или 1.

volatile byte data = 0;
volatile bool flag = 0;

void setup() 
{
  Serial.begin(115200);
  digitalWrite(2, 1);
  attachInterrupt(0, signal, CHANGE);
}

void loop() 
{
  if(flag)
  {
    Serial.println(data, HEX);
    data = 0;
    flag = 0;
  }

}

void signal()
{
  static uint32_t microsec_prev;
  uint32_t microsec_now = micros();
  uint32_t microsec = microsec_now - microsec_prev;
  microsec_prev = microsec_now;
  static char bit = 7;
  
  if(PIND & 1<<2)
  {
    if(microsec > 50 && microsec < 80) 
    {
      data |= 1<<bit;
      bit--;
    }
    else if(microsec > 110 && microsec < 140) bit--;
  }
  else
  {
    if(microsec > 50 && microsec < 80) bit--;
    else if(microsec > 110 && microsec < 140) 
    {
      data |= 1<<bit;
      bit--;
    }
  }
  
  if(bit == -1)
  {
    bit = 7;
    flag = 1;
  }
}

 

typeigor
Offline
Зарегистрирован: 04.08.2013

Спасибо.

Действительно хорошо...

Только чтото вот код другой пишет...

Апрайсин
Апрайсин аватар
Offline
Зарегистрирован: 05.08.2013

#define stop_timer1 TCCR1B=0
#define start_timer1 TCCR1B = (0<<CS12)|(1<<CS11)|(1<<CS10)  //частота/64  4mkc

ISR(TIMER1_OVF_vect) //прерывание по таймеру1
{   
 stop_timer1;    //остановка таймера
 we_stend = true ; //импульсов небыло больше 1 сек установлен флаг стоим
}

////////////скорость///
volatile boolean period_speed = false ;  // период загружен ??????
volatile unsigned int periodspeed ;  // период 
volatile boolean we_stend = true ;  //стоим
volatile int skor_array[5] = {0,0,0,0,0}; //усреднение
int skor;//значение усреднения




void setup()
{  
   pinMode(2, INPUT);  //Вход датчика скорости  
   attachInterrupt(0, speedd, RISING);  // настроить прерывание interrupt 0 на pin 2 фронт
   TIM_Init();//инициализация таймера 
 }


void loop()
{



   if(period_speed==true) //если период загружен
 {
      skor_array[0] = skor_array[1];
      skor_array[1] = skor_array[2];
      skor_array[2] = skor_array[3];
      skor_array[3] = skor_array[4];
      skor_array[4] = 225000/periodspeed; //150000/periodspeed; // скорость равна 3,6*1000000/период*4*6  (ещё умножил на 1.5)!!!!!!    
      skor = (skor_array[0] + skor_array[1] + skor_array[2] + skor_array[3] + skor_array[4]) / 5;

      period_speed = false ;
 }

  if(we_stend == true) skor = 0 ;


}


void TIM_Init(void)  
 {
   stop_timer1;
   TCCR1A=0 ;
   TCNT1 = 0; 
   TIMSK1 = (1<<TOIE1);   //разрешить прерывание по переполнению таймер1
 }  

 void  speedd()    //прерывание по датчику скорости
{   
  stop_timer1;
  if(we_stend == false) periodspeed=TCNT1 , period_speed = true; //если не стоим сохраняется период
  TCNT1=0;          //сброс счетчика таймера1
  start_timer1;     //запуск нового цикла
  we_stend = false; //едем
  
  imp=imp+1; //импульсы для одометра
}  

Это я использовал для спидометра на запорожец) Всё отлично работает. Есть второй таймер для тахометра.

maksim
Offline
Зарегистрирован: 12.02.2012

А причем тут спидометр или тахометр??? Вы не видите что тут организован протокол обмена данными, а не просто импульсы.

Апрайсин
Апрайсин аватар
Offline
Зарегистрирован: 05.08.2013

в том коде считаеться длительность импульсов (нету времени найти, где именно) помоемму TCNT1 - это и есть длительность в милисекундах

а если тебе нужны коды, то чем это не удел? http://arduino.ru/Reference/Serial/Read

только Serial.println(incomingByte, DEC); измени на Serial.println(incomingByte, HEX);

maksim
Offline
Зарегистрирован: 12.02.2012

Вы о чем вообще?

Апрайсин пишет:

TCNT1 - это и есть длительность в милисекундах

Нужно в микросекундах и по какому фронту считываются импульсы?

Апрайсин пишет:

а если тебе нужны коды, то чем это не удел? http://arduino.ru/Reference/Serial/Read

А причем тут UART ?

typeigor
Offline
Зарегистрирован: 04.08.2013

Считать по переходу.

Это протокол J1850.

maksim
Offline
Зарегистрирован: 12.02.2012

typeigor пишет:

Только чтото вот код другой пишет...

Нужно еще как то определять начало передачи и конец.

Предпологаю что как то так

то есть первый и последний импульсы должны быть 200 мкс.

volatile byte data = 0;
volatile bool flag = 0;

void setup() 
{
  Serial.begin(115200);
  digitalWrite(2, 1);
  attachInterrupt(0, signal, CHANGE);
}

void loop() 
{
  if(flag)
  {
    Serial.println(data, HEX);
    data = 0;
    flag = 0;
  }

}

void signal()
{
  static uint32_t microsec_prev;
  uint32_t microsec_now = micros();
  uint32_t microsec = microsec_now - microsec_prev;
  microsec_prev = microsec_now;
  static char bit = 7;
  static bool start;
  if(microsec > 180 && microsec < 220) start = !start;
  else if(start)
  {
    if(PIND & 1<<2)
    {
      if(microsec > 50 && microsec < 80) 
      {
        data |= 1<<bit;
        bit--;
      }
      else if(microsec > 110 && microsec < 140) bit--;
    }
    else
    {
      if(microsec > 50 && microsec < 80) bit--;
      else if(microsec > 110 && microsec < 140) 
      {
        data |= 1<<bit;
        bit--;
      }
    }
    if(bit == -1)
    {
      bit = 7;
      flag = 1;
    }
  }
}

 

typeigor
Offline
Зарегистрирован: 04.08.2013

Да..Зазор сразу поправил...

Код стал стабильным. но не тот...

Пропускает мож пока сериалит...

Начало после конца.

Пороги 34.96.163 и 239.

О...заинвертил и код правильный стал...

Позитив...

А обратно как его...Код этот выдать???

maksim
Offline
Зарегистрирован: 12.02.2012

Скорее всего нужно весь пакет сохранять в массив, и только потом выводить в монитор.

typeigor
Offline
Зарегистрирован: 04.08.2013

Массив хорошо...Только пакеты разной длинны.

maksim
Offline
Зарегистрирован: 12.02.2012

Ну так и сделать буфер например на 64 байта

volatile byte buff[64];
volatile byte num;
volatile bool flag = 0;

void setup() 
{
  Serial.begin(115200);
  digitalWrite(2, 1);
  attachInterrupt(0, signal, CHANGE);
}

void loop() 
{
  if(flag)
  {
    byte buff2[num];
    for(byte i = 0; i < num; i++) buff2[i] =  buff[i];
    flag = 0;
    num = 0;
    for(byte i = 0; i < num; i++) 
    {
      Serial.print(buff2[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }

}

void signal()
{
  static uint32_t microsec_prev;
  uint32_t microsec_now = micros();
  uint32_t microsec = microsec_now - microsec_prev;
  microsec_prev = microsec_now;
  static char bit = 7;
  static byte data;
  static bool start;
  
  if(microsec > 180 && microsec < 220) 
  {
    start = !start;
    if(!start) flag = 1;
  }
  else if(start)
  {
    if(PIND & 1<<2)
    {
      if(microsec > 50 && microsec < 80) 
      {
        data |= 1<<bit;
        bit--;
      }
      else if(microsec > 110 && microsec < 140) bit--;
    }
    else
    {
      if(microsec > 50 && microsec < 80) bit--;
      else if(microsec > 110 && microsec < 140) 
      {
        data |= 1<<bit;
        bit--;
      }
    }
    if(bit == -1)
    {
      bit = 7;
      buff[num] = data;
      num++;
      data = 0;
    }
  }
}

 

typeigor
Offline
Зарегистрирован: 04.08.2013

Всё класс...Понял...

Я вижу код...

 

 

maksim
Offline
Зарегистрирован: 12.02.2012

Да в предыдущем коде num занулялся и вывода не было.

volatile byte buff[64];
volatile byte num;
volatile bool flag = 0;

void setup() 
{
  Serial.begin(115200);
  digitalWrite(2, 1);
  attachInterrupt(0, signal, CHANGE);
}

void loop() 
{
  if(flag)
  {
    byte buff2[num];
    for(byte i = 0; i < num; i++) buff2[i] =  buff[i];
    byte n = num;
    num = 0;
    flag = 0;
    for(byte i = 0; i < n; i++) 
    {
      Serial.print(buff2[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }

}

void signal()
{
  static uint32_t microsec_prev;
  uint32_t microsec_now = micros();
  uint32_t microsec = microsec_now - microsec_prev;
  microsec_prev = microsec_now;
  static char bit = 7;
  static byte data;
  static bool start;
  
  if(microsec > 180 && microsec < 220) 
  {
    start = !start;
    if(!start) flag = 1;
  }
  else if(start)
  {
    if(PIND & 1<<2)
    {
      if(microsec > 50 && microsec < 80) 
      {
        data |= 1<<bit;
        bit--;
      }
      else if(microsec > 110 && microsec < 140) bit--;
    }
    else
    {
      if(microsec > 50 && microsec < 80) bit--;
      else if(microsec > 110 && microsec < 140) 
      {
        data |= 1<<bit;
        bit--;
      }
    }
    if(bit == -1)
    {
      bit = 7;
      buff[num] = data;
      num++;
      data = 0;
    }
  }
}

 

typeigor
Offline
Зарегистрирован: 04.08.2013

а для чего перегонять из buff ->buff2 ?

 

maksim
Offline
Зарегистрирован: 12.02.2012

Чтобы пока выводится в сериал buff2 можно было принимать данные в buff. Что бы максимально бысто освободить buff для следующего пакета данных. В идеале бы просто организовать FIFO-буфер.

typeigor
Offline
Зарегистрирован: 04.08.2013

Ах вот ты какой...Северный олень...

Вжись не догадался б.

Спасибо...

Причём эталонное устройство выдаёт на пару байтов больше чем есть физически.

Незначащий ноль не пишется...Байта не видно...а он  есть...

maksim
Offline
Зарегистрирован: 12.02.2012

Это просто print байт так выводит.

typeigor
Offline
Зарегистрирован: 04.08.2013

Понятненько...

garmoska89
Offline
Зарегистрирован: 20.12.2011

dai please svoi skype nujna 10 min pomosi ili sto nibuti drugoe , naprimuiu sprositi koe 4o.

ti s etim stalknulsia

sposiba za raniie.

garmoska89
Offline
Зарегистрирован: 20.12.2011

Апрайсин

127486
Offline
Зарегистрирован: 15.02.2018

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

 

typeigor
Offline
Зарегистрирован: 04.08.2013

j1850 типа UART.

Tx и Rx в кучу и на j1850.

127486
Offline
Зарегистрирован: 15.02.2018

Куда на дуньке подключить я знаю. 
Вопрос к источнику сигнала.
У него они в противофазе.

 

Dmti
Dmti аватар
Offline
Зарегистрирован: 13.10.2013

Судя по вашей картинки 6 и 7 нога зеркальны значит берите относительно GND 6 ногу и будет вам счастье (или не будет если есть гальвоническая развязка).

typeigor
Offline
Зарегистрирован: 04.08.2013

На OBD2 разъёме один пин  +J1850.

Его использовал.