Data AcQuisition And Real-Time AnalysisScope - Spectrum - Spectrogram - Signal Generator
Software for Windows
Science with your Sound Card!
Contact us about
The Arduino_Counter macro mini-app is a demonstration of some of the features of the 0xFE Event / Race Timer function of the DaqPort Arduino Sketch that is included with Daqarta. It is deliberately not as sophisticated as the DaquinOscope or DC Chart Recorder mini-apps, which make extensive use of Custom Controls, Multitasking, and macro subroutines.
Here there are no controls at all; you have to edit variables at the start of the macro code to change operational modes, parameters, and pin usage. Instead of multitasking, it uses a simple loop to wait for data returns while still allowing continuous display updates.
However, the result of these simplifications is that the code is all in one listing, and is much easier to understand and customize for your own purposes.
The Arduino_Counter can measure waveform period and frequency, or high or low pulse widths. It can count single-pulse events or multi-pulse bursts. Although it uses the digital inputs of the Arduino, which normally expect 0-5V rectangular waves, by adding the simple AC-to-DC Input Level Shifter and Limiter circuit it can easily accomodate AC analog signals such as sound card outputs.
Due to the nature of the Arduino's internal timekeeping, the Arduino_Counter resolution is limited to 4 microseconds. Waveform period measurements have a lower limit of about 20 microseconds. This puts an upper limit for frequency measurements of about 50 kHz, although best accuracy is below about 8 kHz. Frequency measurements use an adjustable 'time constant' averaging system to reduce jitter and improve accuracy.
Using the default microsecond time reporting, the upper limit on period measurements is theoretically 2^31-1 microseconds, or 35.8 minutes. If millisecond timing is selected instead, this becomes 596.5 hours.
As an event counter, the upper limit is 2^31-1 or 2,147,483,647 events.
The Arduino_Counter macro mini-app is included with Daqarta. To run it, first hit CTRL+F8 to open the Macro Dialog. Then scroll the Macro List down and double-click on Arduino_Counter. (There is no single-letter ID for Hot Key access, as there is for the mini-apps at the top of the list.)
However, before you use Arduino_Counter, you may want to change certain parameters that are set near the start of the macro. To edit these, single-click on Arduino_Counter to select it without running it, then click the Edit button.
(Note that you can open this Help topic by selecting Arduino_Counter as above, then clicking the Help button below the list, next to Run. Or, once you have opened the Edit dialog, you can click the duplicate Help button near the upper right.)
The default setup assumes that the input to be measured is on digital pin 7, set via variable UP. You can use any pin 2-12 here.
The Signal pin is an output that is activated during the timed interval, which is the full cycle in period and frequency mode, or only the specified high or low pulse width. This pin is set via US, which defaults to 13 to use the Arduino's on-board LED. You can use any pin 2-13 here, as long as it is not the same as the UP input pin.
Variable UF sets the mode:
0 = High pulse/event duration 1 = Low pulse/event duration 2 = Full-cycle period and frequency
QC is the integer time constant that is applied to the frequency display to reduce jitter. The default is 10. The higher the value, the lower the jitter, but the slower the response to a sudden frequency change,
UW is the Wait timeout, which is a safety feature to prevent the counter from waiting forever in the case of a missing input signal. This should be set to at least twice the longest expected period, in integer seconds. The default is 2, to allow periods up to 1 second.
Variable H is the Holdoff interval, in seconds. This is a floating-point variable (unlike the above integers) so fractional seconds are allowed. You can enter values like H=20m to get a Holdoff of 20 milliseconds. Holdoff is only applied in pulse/event modes 0 and 1. The purpose is to allow counting or measuring only the first of each burst of pulses, such as might be seen in a stream of tone bursts, or a bouncing mechanical switch contact. In such cases Holdoff should be set longer than any individual burst or bounce duration, so that the next measurement isn't attempted in the midst of an ongoing burst or bounce.
When the Arduino_Counter starts up it invokes the _ComDev_Scan macro subroutine to locate the COM port used by the Arduino. If _ComDev_Scan hasn't run previously, either by prior use of Arduino_Counter, DaquinOscope, DC_Chart_Recorder, or some other macro, or it hasn't run with the same Arduino in the same USB socket, there may be a brief delay while the ports are scanned. On subsequent runs with the same device in the same socket, _ComDev_Scan will immediately return the proper port from its stored list.
On some versions of Arduino boards, there may be a 2-second initialization delay the first time the board is used in the current Daqarta session. A "Waiting for Arduino init..." message will appear during this delay. Other than the (undocumented) need for this delay, these boards run fine.
Arduino_Counter will then show a custom meter with the message "Waiting for Trig...". (You may not notice this if the trigger is detected quickly.)
The title bar of the meter will be "Hit SHIFT to exit Arduino_Counter". The meter will then show the period or pulse width in microseconds, and below that the frequency in Hz or the ongoing pulse count.
The meter readings will be updated after every measurement, which may take up to 2 waveform periods in frequency mode.
Hit the SHIFT key to exit. (You can actually use any of the shift keys, including Ctrl and ALT.) The meter will persist to show the final reading; click its [x] to close it.
;<Help=H4924 UP=7 ;Pin 2-12 for Event/Trig US=13 ;LED on pin 13, single event timing UF=2 ;0 = high duration, 1 = low, 2=freq QC=10 ;Time constant (Freq display) UW=2 ;Wait timeout limit, secs H=0 ;Holdoff delay for pulse counting, secs Posn#0="Ardu" ;Specify Arduino only Posn#1=0 ;Device count, 0 = first found @_ComDev_Scan ;Find and open device port IF.UF=2 ;Frequency mode? UT=h20 + UP ;Trig pin UP, h20=wait if not ready UE=UP ELSE. ;Else high or low duration only UT=0 UE=UF<<4 + UP ;(h10 +UP) = LOW, UP = HIGH ENDIF. Port=$(hD0 + UP) + $(h42) ;Trig/Event INPUT_PULLUP Port=$(hD0 + US) + $(h41) ;Signal to OUTPUT Port=$(hD0 + US) + $(h00) ;Signal off to start Port=$(hF0) + "W" + $w(-UW) ;Wait timeout, secs Mtr0="<<Hit SHIFT to exit Arduino_Counter" Mtr0="Waiting for Trig..." Port#Ti=1 ;Return immediately if no data Port#Tm=1 Port#Tc=0 Port#T=2 ;Use timeouts QT=0 ;Total pulse count A=0 ;Running average freq IF.QC=<=0 ;Positive TC only QC=1 ENDIF. WHILE.Key?$=0 Port=$(hFE) + $(UT) + $(US) + $(UE) ;Request event time UN=0 WHILE.UN=<(UW / 10m) ;Wait a few secs max U0=Port?5 ;Try to read data IF.Port?n=!0 ;Any bytes read? LoopBreak=2 ;OK if so ELSE. IF.Key?$=0 ;If no SHIFT key WaitTrace= ;Allow trace update ELSE. LoopBreak=2 ;Else exit loop ENDIF. ENDIF. UN=UN+1 WEND. IF.Port?n=0 ;Any bytes read? LoopBreak=2 ;Exit if not (SHIFT hit) ENDIF. ; UC=Port?c ;Pin number (not used) Port#D1=h87 ;Get number of timeouts Q7=Port?2 F=1e6 / U0 IF.A=0 ;First pass? A=F ;Initialize average freq ELSE. A=A - (A/QC) + (F/QC) ;Else apply TC ENDIF. IF.Q7=>0 ;Timeout on this pass? Mtr0="Timeout!" ;Show error, don't count ELSE. IF.UF=<2 ;High or low duration only? QT=QT+1 ;Count pulse IF.UF=0 Mtr0=U0 + " usec HIGH" +n _ +QT + " Count" ELSE. Mtr0=U0 + " usec LOW" +n _ +QT + " Count" ENDIF. ELSE. ;Else show frequency Mtr0=U0 + " usec" +n _ +A + " Hz" ENDIF. ENDIF. WaitSecs=H ;Holdoff delay for pulse/burst count WEND. Mtr0="<<" ;Clear Mtr0 title Port#T=0 ;End COM timeouts Port#O=0 ;Close COM port
Questions? Comments? Contact us!We respond to ALL inquiries, typically within 24 hrs.
Over 35 Years of Innovative Instrumentation
© Copyright 2007 - 2021 by Interstellar Research
All rights reserved