Подсчет импульсов за 1 секунду
- Войдите на сайт для отправки комментариев
Пнд, 20/10/2014 - 14:04
Добрый уважаемые знатоки. Собран детектор гамма квантов, на выходе импульсы от 1 до 5 вольт. Подскажите пожалуйста как ардуиной посчитать, колличество импульсов в секунду.
Таймер и прерывания например.
А можно поточнее, я в ардуино вообще не соображаю.
Ну если длина импульса много больше чем длина такта ардуины (16 мГц) тогда просто ждете начало импульса, плюсуете к счетчику еденицу, ждете конец импульса, проверяете сколько прошло времени. как проходит одна секунда так счетчик и покажет количество импульсов. А узнать сколько прошло время поможет millis()
Спасибо за помощь. По моим подсчетам в секунду должно проходить порядка 30 импульсов, при нормальном фоне. Длина импульса намного меньше такта ардуины. Как правильнее делать?
Вот так я мегой импульсы считал. https://github.com/radjah/arduino/blob/master/interrupt/test_timer/test_...
Спасибо. Попробую чего-нибудь написать, потом спрашу.
Всем добрый день. Почивав форумы понял, что нужно использовать 2 прерывания, внешнее прерывание по приходу импульса (attachInterrupt(0, функция увеличивающее кол-во импульсов на 1, RISING);),все ли я правильно понял? Второе прерывание по времени через каждую секунду. Не могу сообразить как правильно сделать прерывание по времени, помогите пожалуйста.
да зачем 2 прерывание. у тебя такие низкие входные частоты, что можно просто использовать millis
Скетч для автомобильного тахометра:
const int tachPIN=2; const unsigned long sampleTime=1000; const int maxRPM = 10200; void setup() { pinMode(tachPIN, INPUT); digitalWrite(tachPIN, HIGH); //Turns on pullup resistor on pin. Serial.begin(9600); } void loop() { int rpm=getRPM(); Serial.print("RPM: "); Serial.print(rpm); Serial.print("\n"); } int getRPM() { // sample for sampleTime in millisecs int kount=0; boolean kflag=LOW; unsigned long currentTime=0; unsigned long startTime=millis(); while (currentTime<=sampleTime) { if (digitalRead(tachPINPin)==HIGH) { kflag=HIGH; } if (digitalRead(tachPINPin)==LOW && kflag==HIGH) { kount++; kflag=LOW; } currentTime=millis()-startTime; } int kount2rpm = int(60000./float(sampleTime))*kount; return kount2rpm; }Спасибо, попробую разобраться что здесь.
Корректно ли будет вот так:
#include <LiquidCrystal.h> // Буду использовать дисплей, без I2C #include <TimerOne.h> volatile int colImp = 0; // Счетчик импульсов volatile int T = 0; const int ledPin = 9; // Подаю импульсы на 9 ножку void setup() { pinMode(ledPin, INPUT); digitalWrite(ledPin, LOW); // Сомневаюсь что нужно HIGH или LOW attachInterrupt(1, D2Int, RISING);// Прерывание по приходу импульса Timer1.initialize(1000000); // Таймер на 1 секундe Timer1.attachInterrupt(D3Int); Serial.begin(9600); } void loop() { if (T == 1) // Если прошла 1 секунда тогда { Serial.print(colImp); colImp = 0; //обнуляем колличество накопленных импульсов T = 0; // сбрасываем T } } void D2Int() { colImp++; // увеличиваем на 1 колличество импульсов } void D3Int() { T = 1; // по прошествию 1 сек }Могу ли я прямо в фунуции D3Int()-прерывания по времени, выводить информацию в порт или на дисплей.
http://arduino.ru/Reference/AttachInterrupt
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. Возможна потеря данный передаваемых по последовательному соединению (Serial data) в момент выполнения функциии обработки прерывания. Переменные, изменяемые в функции, должным быть объявлены как volatile.
вот, 1 секунда без извращений (только библиотеку скачайте)
#include "MsTimer2.h" void setup() { MsTimer2::set(1000, flash); // 1000 ms = 1 s MsTimer2::start(); } void flash(void) { /*вызывается строго раз в секунду*/ }Спасибо. Можно еще вопрос по
Всем добрый день, извиняюсь за тупость, не могу понять почему программа не считает импульсы. Собрал устройство, импульсы идут ровные 5 Вольт (смотрю осцилографом).
#include <MsTimer2.h> volatile int colImp = 0; // Счетчик импульсов volatile int T = 0; const int ledPin = 12; // Подаю импульсы на 9 ножку void setup() { pinMode(ledPin, INPUT); digitalWrite(ledPin, HIGH); // Сомневаюсь что нужно HIGH или LOW attachInterrupt(1, D2Int, RISING);// Прерывание по приходу импульса MsTimer2::set(1000, flash); // 1000 ms = 1 s MsTimer2::start(); Serial.begin(9600); } void loop() { if (T == 1) // Если прошла 1 секунда тогда { Serial.print(colImp); colImp = 0; //обнуляем колличество накопленных импульсов T = 0; // сбрасываем T } } void D2Int() { colImp++; // увеличиваем на 1 колличество импульсов } void flash(void) //*вызывается строго раз в секунду*/ { T = 1; // по прошествию 1 сек }у меня одного странно выглядит?
Нет, у меня тоже весь экран вни "забит" кодом, точнее дублем кода.
ТС, попробуйте не использовать пин 1, возьмите другие, кроме 0 и 1.
pin 1 - допустил "описку", там 12. Использую ардуино Nano, на D12 подключаю провод с импульсами.
Таймер для выставления флага? Но нахрена?
Затолкай туда же запись посчитанных импульсов в переменную для вывода и обнуление счетчика, а в лупе только вывод оставь.
Как то так?
void loop() { Serial.print(T); } void D2Int() { colImp++; // увеличиваем на 1 колличество импульсов } void flash() //*вызывается строго раз в секунду*/ { T = colImp; // по прошествию 1 сек colImp = 0; //обнуляем колличество накопленных импульсов }Я думаю, что проблема тут, только не понимаю в чем.
Нашел ряд ошибок:
1. Nano внешнее прерывание на D2 и D3.
2. Неправильно написал colImp++, надо было наоборот.
Замыкаю D2 на 5 вольт все срабатывает заходит в прерывание, а с устройства не импульсы не берет, завтра увеличу амплитуду импульсов.
LOW если ловишь такой импульс _П_ Прерывание на RISING для начала импульса или FALLING для конца импульса.
HIGH в противоположном случае.
По идее ардуина должна ловить импульсы от 2,4 вольт.
Спасибо Radjah. Импульсы такие _П_. Я правильно понимаю, что прерывание в виде attachInterrupt(1, D2Int, RISING) мне должно быть достаточно.
Ну это зависит от того, что тебе посчитать надо. Если целые импульсы, то FALLING (спад), если фронты, то RISING (нарастание).
Нужно считать колличество целые импульсы _П_, не могу понять в чем проблема, пробовал и FALLING и RISING.
Я вот так мутил https://github.com/radjah/arduino/blob/master/interrupt/test_timer/test_...
А вот так импульсы другой ардуиной делал https://github.com/radjah/arduino/blob/master/interrupt/gen_random/gen_r...
На название не смотри :)
не бейте ногами сильно не удержался скопипастю веселье :)
я вижу только один косячек перевода "летучие" unsigned
#есть <TimerOne.h> #есть <CyberLib.h> #есть <Проволоки.h> #есть <LCD.h> #есть <LiquidCrystal_I2C.h> // Порты LCD #определить LCD_I2C_ADDR 0x27 #определить Подсветка 3 #определить LCD_EN 2 #определить LCD_RW 1 #определить LCD_RS 0 #определить LCD_D4 4 #определить LCD_D5 5 #определить LCD_D6 6 #определить LCD_D7 7 LiquidCrystal_I2C lcd(LCD_I2C_ADDR, LCD_EN, LCD_RW, LCD_RS, LCD_D4, LCD_D5, LCD_D6, LCD_D7); летучие долго int count = 0; // Счетчик летучие долго int oldcount = 0; // Для вычисления скорости летучие float скорость = 0; // Значение скорости void установки() { // D3 на ввод D3_In; D3_High; // Прерывание по нарастанию attachInterrupt(1, D2Int, RISING); // Таймер на 4 секунды Timer1.инициализировать(1000000); Timer1.attachInterrupt(Calcspeed); // Запуск дисплея lcd.начать(20, 4); lcd.setBacklightPin(ПОДСВЕТКА, ПОЗИТИВНЫЕ); lcd.setBacklight(Высокая); // Шаблон lcd.ясно(); lcd.setCursor(0,1); lcd.печать("Скорость: "); lcd.дома(); Серийный.начать(9600); } void цикл() { lcd.дома(); // Буферы для вывода на дисплей char cnt[20] = ""; // Счетчик char СПД[13] = ""; // Скорость // Счетчик в строку sprintf(cnt, "Граф: %13lu", count); lcd.печать(cnt); // Скорость в строку dtostrf(скорость, 13, 2, СПД); lcd.setCursor(7,1); lcd.печать(СПД); Серийный.печать(count); Серийный.печать(" "); Серийный.println(скорость); // Задержка delay_ms(1000); } void D2Int() { // Приращение счетчика по прерыванию count++; } void Calcspeed(){ // Вычисление скорости скорость = float(граф - oldcount); oldcount = count; }Спасибо, я уже пытался использовать этот код, но импульсы не считает, разбираюсь с желязякой.
Всем спасибо, проблема была в железяке, подсаживало импульсы до 2 вольт. Все примеры рабочие.
И какой же окончательный (правильный) код???
А разве нельзя засекать время между импульсами в течение какого-то времени. Количество импульсов в секунду равно обратной величине времени между импульсами. Допустим, за секунду нам удалось засечь время между импульсами пять раз, быстренько считаем среднее значение частоты импульсов и выводим на экран, продолжая следить за импульсами, прошла секунда выводим новое значение и так далее.
Ну это так...просто размышление...как вариант.
Добрый вечер) нужна помощь в написании кода. Суть работы в том что к ардуино подсоеденем датчик расхода топлива, мне нужно что бы ардуино считывал импульсы с датчика и по ком порту передавал их на ПК. Спасибо)
> нужна помощь
Показывай код или в "Ищу исполнителя"
CODE or GTFO
проблема в том что я не знаю с чего даже начать, т.к зелен в программировании, может датите пару советов?
проблема в том что я не знаю с чего даже начать, т.к зелен в программировании, может датите пару советов?
Для начала прочитать это. Потом составить алгоритм своей хотелки и попробовать его описать программой. Когда начнутся затыки, обратиться с наработанным кодом и описанием проблемы на форум.
Спасибо)