Помогите посчитать длительность импульсов.
- Войдите на сайт для отправки комментариев
Пнд, 05/08/2013 - 11:28
Ардуино...
Сигнал...

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

Пробовал методом PulseIn.По отдельности Hight или Low считает...Вместе никак...
Может подскажете метод по изящнее...
Нужно получить A7 C0 03 01 BB 40...
Да и хорошоб возможность и отправить...
Заранее.Best Regards.
В прерывании фиксируйте значение 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; } }Спасибо.
Действительно хорошо...
Только чтото вот код другой пишет...
#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; //импульсы для одометра }Это я использовал для спидометра на запорожец) Всё отлично работает. Есть второй таймер для тахометра.
А причем тут спидометр или тахометр??? Вы не видите что тут организован протокол обмена данными, а не просто импульсы.
в том коде считаеться длительность импульсов (нету времени найти, где именно) помоемму TCNT1 - это и есть длительность в милисекундах
а если тебе нужны коды, то чем это не удел? http://arduino.ru/Reference/Serial/Read
только Serial.println(incomingByte, DEC); измени на Serial.println(incomingByte, HEX);
Вы о чем вообще?
TCNT1 - это и есть длительность в милисекундах
а если тебе нужны коды, то чем это не удел? http://arduino.ru/Reference/Serial/Read
Считать по переходу.
Это протокол J1850.
Только чтото вот код другой пишет...
Предпологаю что как то так
то есть первый и последний импульсы должны быть 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; } } }Да..Зазор сразу поправил...
Код стал стабильным. но не тот...
Пропускает мож пока сериалит...
Начало после конца.
Пороги 34.96.163 и 239.
О...заинвертил и код правильный стал...
Позитив...
А обратно как его...Код этот выдать???
Скорее всего нужно весь пакет сохранять в массив, и только потом выводить в монитор.
Массив хорошо...Только пакеты разной длинны.
Ну так и сделать буфер например на 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; } } }Всё класс...Понял...
Я вижу код...
Да в предыдущем коде 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; } } }а для чего перегонять из buff ->buff2 ?
Чтобы пока выводится в сериал buff2 можно было принимать данные в buff. Что бы максимально бысто освободить buff для следующего пакета данных. В идеале бы просто организовать FIFO-буфер.
Ах вот ты какой...Северный олень...
Вжись не догадался б.
Спасибо...
Причём эталонное устройство выдаёт на пару байтов больше чем есть физически.
Незначащий ноль не пишется...Байта не видно...а он есть...
Это просто print байт так выводит.
Понятненько...
dai please svoi skype nujna 10 min pomosi ili sto nibuti drugoe , naprimuiu sprositi koe 4o.
ti s etim stalknulsia
sposiba za raniie.
Апрайсин
А есть схема включения девайса с протколом j1850 к ардуине?
А то у него же выход балансный.
Через оптрон не работает.
j1850 типа UART.
Tx и Rx в кучу и на j1850.
Куда на дуньке подключить я знаю.
Вопрос к источнику сигнала.
У него они в противофазе.
Судя по вашей картинки 6 и 7 нога зеркальны значит берите относительно GND 6 ногу и будет вам счастье (или не будет если есть гальвоническая развязка).
На OBD2 разъёме один пин +J1850.
Его использовал.