Data AcQuisition And Real-Time Analysis
Scope - Spectrum - Spectrogram - Signal Generator
Software for Windows
Science with your Sound Card!
The following is from the Daqarta Help system:



Spectrum Analyzer

Signal Generator

(Absolutely FREE!)


Pitch Tracker


DaqMusiq Generator
(Free Music... Forever!)

Engine Simulator

LCR Meter

Remote Operation

DC Measurements

True RMS Voltmeter

Sound Level Meter

Frequency Counter
    Spectral Event

    MHz Frequencies

Data Logger

Waveform Averager


Post-Stimulus Time
Histogram (PSTH)

THD Meter

IMD Meter

Precision Phase Meter

Pulse Meter

Macro System

Multi-Trace Arrays

Trigger Controls


Spectral Peak Track

Spectrum Limit Testing

Direct-to-Disk Recording



Frequency response

Distortion measurement

Speech and music

Microphone calibration

Loudspeaker test

Auditory phenomena

Musical instrument tuning

Animal sound

Evoked potentials

Rotating machinery


Product test

Contact us about
your application!

Arduino_Counter Mini-App


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.

Once you have edited these parameters, click the Save Macro button below the Edit window. This will return you to the main Macro List where you can hit the Run button.

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.

Arduino_Counter Macro Listing:


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
ELSE.               ;Else high or low duration only
    UE=UF<<4 + UP       ;(h10 +UP) = LOW, UP = HIGH

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#T=2                    ;Use timeouts

QT=0                        ;Total pulse count
A=0                         ;Running average freq
IF.QC=<=0                   ;Positive TC only

    Port=$(hFE) + $(UT) + $(US) + $(UE)     ;Request event time

    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
            IF.Key?$=0             ;If no SHIFT key
                WaitTrace=                 ;Allow trace update
                LoopBreak=2        ;Else exit loop

    IF.Port?n=0                ;Any bytes read?
        LoopBreak=2                ;Exit if not (SHIFT hit)

;    UC=Port?c                  ;Pin number (not used)

    Port#D1=h87                 ;Get number of timeouts

    F=1e6 / U0
    IF.A=0                      ;First pass?
        A=F                         ;Initialize average freq
        A=A - (A/QC) + (F/QC)       ;Else apply TC
    IF.Q7=>0                    ;Timeout on this pass?
        Mtr0="Timeout!"             ;Show error, don't count
        IF.UF=<2                    ;High or low duration only?
            QT=QT+1                     ;Count pulse
                Mtr0=U0 + " usec HIGH" +n _
                    +QT + " Count"
                Mtr0=U0 + " usec LOW" +n _
                    +QT + " Count"
        ELSE.                       ;Else show frequency
            Mtr0=U0 + " usec" +n _
                +A + " Hz"
    WaitSecs=H                  ;Holdoff delay for pulse/burst count
Mtr0="<<"                   ;Clear Mtr0 title
Port#T=0                    ;End COM timeouts
Port#O=0                    ;Close COM port

See also DaqPort Arduino Sketch, USB / Serial Communications Port Access


Questions? Comments? Contact us!

We respond to ALL inquiries, typically within 24 hrs.
Over 35 Years of Innovative Instrumentation
© Copyright 2007 - 2023 by Interstellar Research
All rights reserved