Тахометр

g00d
Offline
Зарегистрирован: 16.12.2011

Делаю тахометр для авто и ни черта не выходит. Причем глюк очень странный.

Имеем:

- Arduino Mega2560

- схему и принцип работы с hardlock.org.ua/viewtopic.php

Простую программу для проверки схемы:

volatile int rpm=0;
 
void setup() 
{
  attachInterrupt(0, rpmCount, CHANGE);
  Serial.begin(115200);
}

void rpmCount()
{
  rpm++;
}

void loop()
{
  Serial.println(rpm);
  rpm=0;
  delay(1000);
}

По итогу прога запускается, но при включении двигателя после 5-10 замеров виснет наглухо. Причем виснет так, что помогает только перепрошивка.

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

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

Имхо код мне кажется вообще не о чём. В COM порте всегда 0.
Как то делал часы на индикаторах там как минимум строчек 100 кода.
 

g00d
Offline
Зарегистрирован: 16.12.2011

Давайте по существу.

Это не готовый тахометр, это просто кусок кода после которого все виснет наглухо. Я хочу найти причину этого зависания!

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

Попробуй закомментируй delay(100);
И поменяй Serial.begin(9600);
 

g00d
Offline
Зарегистрирован: 16.12.2011

 Пробовал и то и то.

Так же пробовал отключать прерыванияна момент исполнения инструкций - то же без результата.

step962
Offline
Зарегистрирован: 23.05.2011

g00d пишет:

Причем виснет так, что помогает только перепрошивка.

Что, и выключение/включение не помогает?

g00d
Offline
Зарегистрирован: 16.12.2011

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

Mastino
Offline
Зарегистрирован: 03.12.2011

код другой напиши, этот так и так работать не будет, если даже и виснут не будет

g00d
Offline
Зарегистрирован: 16.12.2011

 Спасибо за ценнейший комментарий, но код работает 100%. Смотрите внимательней или учите матчасть.

Сейчас проверил с кнопкой - не виснет собака, все ок. Вот из за шумного сигнала на входе возможно такое?

carduino.ru
Offline
Зарегистрирован: 06.12.2011

Попробуй всесто int rpm    uint16_t rpm

g00d
Offline
Зарегистрирован: 16.12.2011

 Завтра попробую. Логики правда не вижу, но возможно поможет. У меня там на не более 200 гц.

Mastino
Offline
Зарегистрирован: 03.12.2011

g00d пишет:

 Спасибо за ценнейший комментарий, но код работает 100%. Смотрите внимательней или учите матчасть.

Сейчас проверил с кнопкой - не виснет собака, все ок. Вот из за шумного сигнала на входе возможно такое?

эта тема уже сто раз обсуждалась на arduino.cc..
digitalRead или interrupts не подходят.
нужно использовать pulseIn

g00d
Offline
Зарегистрирован: 16.12.2011

 Хм, гляну про pulseIn.

Но зуб даю, что на идеальном сигнале с генератора все работает и на мой проге. Сам лично весь день сегодня гоняю.

step962
Offline
Зарегистрирован: 23.05.2011

Mastino пишет:

эта тема уже сто раз обсуждалась на arduino.cc..
digitalRead или interrupts не подходят.
нужно использовать pulseIn

Реализация функции PulseIn:

unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
// uint8_t its shorthand for: a type of unsigned integer of length 8 bits
{
     // cache the port and bit of the pin in order to speed up the
     // pulse width measuring loop and achieve finer resolution.  calling
     // digitalRead() instead yields much coarser resolution.
     uint8_t bit = digitalPinToBitMask(pin);
     uint8_t port = digitalPinToPort(pin);
     uint8_t stateMask = (state ? bit : 0);
     unsigned long width = 0; // keep initialization out of time critical area
     // convert the timeout from microseconds to a number of times through
     // the initial loop; it takes 16 clock cycles per iteration.
     unsigned long numloops = 0;
     unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
     // wait for any previous pulse to end
     while ((*portInputRegister(port) & bit) == stateMask)
       {
                   if (numloops++ == maxloops)
               {
                 return 0;
               }
       }

     // wait for the pulse to start
     while ((*portInputRegister(port) & bit) != stateMask)
       {
                   if (numloops++ == maxloops)
               {
                 return 0;
               }
       }

     // wait for the pulse to stop
     while ((*portInputRegister(port) & bit) == stateMask)
       {
           width++;
                   if (numloops++ == maxloops)
               {
                 return 0;
               }
       }

     // convert the reading to microseconds. The loop has been determined
     // to be 10 clock cycles long and have about 16 clocks between the edge
     // and the start of the loop. There will be some error introduced by
     // the interrupt handlers.
     return clockCyclesToMicroseconds(width * 10 + 16); <== needs change
}

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

carduino.ru
Offline
Зарегистрирован: 06.12.2011

g00d пишет:

 Завтра попробую. Логики правда не вижу, но возможно поможет. У меня там на не более 200 гц.

Это на случай если переполнение произойдет

Хотя учитывая твою частоту и задерджу в 1 сек, то переполнения не будет. На Arduino Mega 2560 так и делаю

carduino.ru
Offline
Зарегистрирован: 06.12.2011

Вот нашел  правильную реализацию тахометра или спидометра

g00d
Offline
Зарегистрирован: 16.12.2011

Короче тему можно переместить в "Аппаратные вопросы"

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