|
|
Netherlands
Offline
Tesla Member
Karma: 90
Posts: 9393
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #1 on: June 17, 2011, 02:42:26 am » |
for the newbies, can you give a short description & current state ? TIA, Rob
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 10
Arduino rocks
|
 |
« Reply #2 on: February 28, 2012, 06:06:05 pm » |
I modified the cpp file to work with the mega2560. It was pretty easy. Uses pin 47 same as the 1280. It works but sadly it does not play nice with the servo module (presumably they both use the same timer). /* FreqCounter.h - Using Counter1 for counting Frequency on T1 / PD5 / digitalPin 5 Uses Counter5 on the Mega digitalPin 47
Using Timer2 for Gatetime generation
Martin Nawrath KHM LAB3 Kunsthochschule für Medien Köln Academy of Media Arts http://www.khm.de http://interface.khm.de/index.php/labor/experimente/
History: Dec/08 - V0.0 May/20 modified by mem to support Mega usting T5 /PL2 on digitalPin 47
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include <FreqCounter.h>
unsigned long FreqCounter::f_freq;
volatile unsigned char FreqCounter::f_ready; volatile unsigned char FreqCounter::f_mlt; volatile unsigned int FreqCounter::f_tics; volatile unsigned int FreqCounter::f_period; volatile unsigned int FreqCounter::f_comp;
// 16 bit timer defines added by mem to enable redifining the timer used #if defined(__AVR_ATmega2560__) #define TCCRnA TCCR5A #define TCCRnB TCCR5B #define TCNTn TCNT5 #define TIFRn TIFR5 #define TOVn TOV5 #elif defined(__AVR_ATmega1280__) #define TCCRnA TCCR5A #define TCCRnB TCCR5B #define TCNTn TCNT5 #define TIFRn TIFR5 #define TOVn TOV5 #elif defined (__AVR_ATmega168__) #define TCCRnA TCCR1A #define TCCRnB TCCR1B #define TCNTn TCNT1 #define TIFRn TIFR1 #define TOVn TOV1 #endif #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif
void FreqCounter::start(int ms) {
f_period=ms/2; if (f_comp ==0) f_comp=1;
// hardware counter setup ( refer atmega168.pdf chapter 16-bit counter1) TCCRnA=0; // reset timer/countern control register A TCCRnB=0; // reset timer/countern control register A TCNTn=0; // counter value = 0 // set timer/counter1 hardware as counter , counts events on pin Tn ( arduino pin 5 on 168,47 on Mega ) // normal mode, wgm10 .. wgm13 = 0 sbi (TCCRnB ,CS10); // External clock source on Tn pin. Clock on rising edge. sbi (TCCRnB ,CS11); sbi (TCCRnB ,CS12);
// timer2 setup / is used for frequency measurement gatetime generation // timer 2 presaler set to 256 / timer 2 clock = 16Mhz / 256 = 62500 Hz TCCR2A=0; TCCR2B=0; cbi (TCCR2B ,CS20); sbi (TCCR2B ,CS21); sbi (TCCR2B ,CS22);
//set timer2 to CTC Mode cbi (TCCR2A ,WGM20); sbi (TCCR2A ,WGM21); cbi (TCCR2B ,WGM22); OCR2A = 124;
f_ready=0; // reset period measure flag f_tics=0; // reset interrupt counter sbi (GTCCR,PSRASY); // reset presacler counting TCNT2=0; // timer2=0 TCNTn=0; // Countern = 0
cbi (TIMSK0,TOIE0); // disable Timer0 //disable millis and delay sbi (TIMSK2,OCIE2A); // enable Timer2 Interrupt
TCCRnB = TCCRnB | 7; // Counter Clock source = pin Tn , start counting now
}
//****************************************************************** // Timer2 Interrupt Service is invoked by hardware Timer2 every 2ms = 500 Hz // 16Mhz / 256 / 125 = 500 Hz // here the gatetime generation for freq. measurement takes place:
ISR(TIMER2_COMPA_vect) { // multiple 2ms = gate time = 100 ms if (FreqCounter::f_tics >= FreqCounter::f_period) { // end of gate time, measurement ready
// GateCalibration Value, set to zero error with reference frequency counter delayMicroseconds(FreqCounter::f_comp); // 0.01=1/ 0.1=12 / 1=120 sec TCCRnB = TCCRnB & ~7; // Gate Off / Counter Tn stopped cbi (TIMSK2,OCIE2A); // disable Timer2 Interrupt sbi (TIMSK0,TOIE0); // enable Timer0 again // millis and delay FreqCounter::f_ready=1; // set global flag for end count period
// calculate now frequeny value FreqCounter::f_freq=0x10000 * FreqCounter::f_mlt; // mult #overflows by 65636 FreqCounter::f_freq += TCNTn; // add countern value FreqCounter::f_mlt=0;
} FreqCounter::f_tics++; // count number of interrupt events if (TIFRn & 1) { // if Timer/Counter n overflow flag FreqCounter::f_mlt++; // count number of Countern overflows sbi(TIFRn,TOVn); // clear Timer/Counter n overflow flag } // PORTB = PORTB ^ 32; // int activity test }
|
|
|
|
« Last Edit: February 28, 2012, 11:22:01 pm by doug metzler »
|
Logged
|
|
|
|
|
Washington
Offline
God Member
Karma: 20
Posts: 717
Firefox & Arduino rocks
|
 |
« Reply #3 on: February 28, 2012, 09:44:35 pm » |
replace the < and > with [ and ] to make the code tags work.
|
|
|
|
|
Logged
|
Avoid throwing electronics out as you or someone else might need them for parts or use. Solid state rectifiers are the only REAL rectifiers. Resistors for LEDS!
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 10
Arduino rocks
|
 |
« Reply #4 on: February 28, 2012, 11:23:31 pm » |
Thanks for the tip - I went back and edited. I find it ironic that there are 35 buttons to put different smileys in the message but not one button to put code in the message.
DougM
|
|
|
|
|
Logged
|
|
|
|
|
Washington
Offline
God Member
Karma: 20
Posts: 717
Firefox & Arduino rocks
|
 |
« Reply #5 on: February 29, 2012, 01:04:59 am » |
Thanks for the tip - I went back and edited. I find it ironic that there are 35 buttons to put different smileys in the message but not one button to put code in the message.
DougM
Actually there is one (it looks like a '#') but once you get the hang of it, it is easier just to type code tags. I might check out the code alittle later if I have time, it looks interesting.
|
|
|
|
|
Logged
|
Avoid throwing electronics out as you or someone else might need them for parts or use. Solid state rectifiers are the only REAL rectifiers. Resistors for LEDS!
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 94
|
 |
« Reply #6 on: March 22, 2012, 06:18:42 pm » |
There is a workoround for use with servo library?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 3
|
 |
« Reply #7 on: July 31, 2012, 08:55:28 am » |
A bit confused. I grabbed the 'latest' version which appears to be V1.2. Will it work with a 2560, or do I need to use the cpp that Doug contributed above?
|
|
|
|
|
Logged
|
|
|
|
|
USA
Offline
God Member
Karma: 14
Posts: 644
|
 |
« Reply #8 on: July 31, 2012, 09:52:15 am » |
There is a workoround for use with servo library?
I'm by far not the most accomplished low-level embedded programmer on these forums, but here's my take. It's unlikely for the UNO, as the Frequency Counter Library relies heavily on Timer1 and Timer2. For the Mega boards, it could be possible to use the Servo Library with pins in the banks associated with Timer3 and Timer4 (i.e. the timers not used by the Frequency Counter Library). Even so, it may still require some changes to one or both libraries. However, I don't have a Mega board available to experiment with at this time.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 1
|
 |
« Reply #9 on: August 25, 2012, 03:47:28 pm » |
Hi all, I'd like to ask the question why it is necessary to disable Timer0 before starting the counting process?
- Michael
|
|
|
|
|
Logged
|
|
|
|
|
Rapa Nui
Offline
God Member
Karma: 16
Posts: 888
Pukao hats cleaning services
|
 |
« Reply #10 on: August 26, 2012, 12:01:37 pm » |
|
|
|
|
|
Logged
|
|
|
|
|
Deep south of Italy
Offline
Faraday Member
Karma: 6
Posts: 2954
The quieter you become, the more you can hear
|
 |
« Reply #11 on: October 19, 2012, 03:01:11 am » |
hi, do you think it's possible to modify the lib in order to be able to read also the duty cycle? we could use two interrupts , one for the rising edge and one for the fallig so at the end of the measure we could count both events and then do the proper calculations?
|
|
|
|
|
Logged
|
|
|
|
|
Left Coast, CA (USA)
Offline
Brattain Member
Karma: 279
Posts: 15316
Measurement changes behavior
|
 |
« Reply #12 on: October 19, 2012, 09:22:28 am » |
Hi all, I'd like to ask the question why it is necessary to disable Timer0 before starting the counting process?
- Michael
Most likely because the free running timer0 interrupts used by the arduino start-up code to support the delay() and millis() and micros() function would add a element of variable latency to responding to the timer interrupt used by the frequency counter function.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 2
|
 |
« Reply #13 on: October 22, 2012, 07:04:35 pm » |
Hi, I'm trying to use Arduino Uno with 2 flow sensors. They pulse at 3300 per litre. I have them hooked up to pins 4 and 5 on my arduino. My question is can I use FreqCounter to read each one separately and over a 1 second period? I have looked through the code and I can't see anywhere to allocate the pins I want it to read..
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 2
|
 |
« Reply #14 on: October 22, 2012, 07:31:19 pm » |
Hi, I'm trying to use Arduino Uno with 2 flow sensors. They pulse at 3300 per litre. I have them hooked up to pins 4 and 5 on my arduino. My question is can I use FreqCounter to read each one separately and over a 1 second period? I have looked through the code and I can't see anywhere to allocate the pins I want it to read.. I've had a quite look through the C++ coding. If I change every occurance of T1 with the relevant T number for pin4 or 6? If anyone knows where i can find those T numbers that would be awesome 
|
|
|
|
|
Logged
|
|
|
|
|
|