compile error of Frequency Measure with Arduino DUE

Hello, now I'm going to make a sine wave generator which has 7 segment LED displays the frequency
with Arduino DUE.
However, I have failed to compile the code which I found on the web.

I need some advice to fix it.

I have a plan to combined my source code and the frequency measurement code on the web.

my code

#include "Waveforms.h"

#define oneHzSample 1000000/maxSamplesNum
#define DATA 11
#define LATCH 10
#define CLOCK 9

//  0b11111110   DP
//  0b11111101   A
//  0b11111011   B
//  0b11110111   C
//  0b11101111   D
//  0b11011111   E
//  0b10111111   F
//  0b01111111   G

static const int num[] {
  0b10000001,   //ZERO
  0b11110011,   //ONE
  0b01001001,   //TWO
  0b01100001,   //THREE
  0b00110011,   //FOUR
  0b00100101,   //FIVE
  0b00000101,   //SIX
  0b11110001,   //SEVEN
  0b00000001,   //EIGHT
  0b00100001,   //NINE
  0b10000001,   //ZERO

  0b11110010,   //ONE DOT
  0b01001000,   //TWO DOT
  0b01100000,   //THREE DOT
  0b00110010,   //FOUR DOT
  0b00100100,   //FIVE DOT
  0b00000100,   //SIX DOT
  0b11110000,   //SEVEN DOT
  0b00000000,   //EIGHT DOT
  0b00100000,   //NINE DOT
};

int count;
int digits[] = {4, 3, 2};
int LEDdigit[] = {0, 0, 0}; //storage for digits to be displayed
int LEDdecimal[] = {0, 0, 0}; //storage for decimal indicators
byte scanDigit = 0; //tells which digit to display
unsigned int start;  //changed from int to unsigned int
unsigned int timer; //changed from int to unsigned int
unsigned int scanTimer; //timer for display scanning
unsigned int volume;
float frequency;
//int interval = 5000;
int interval = 100; //update the display once each second
int blinkingtime = 10;
int del = 10;int i = 0;
double startmicros;
volatile int wave1 = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(DATA, OUTPUT);
  pinMode(LATCH, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(DAC1,OUTPUT);
  analogWriteResolution(12);  // set the analog output resolution to 12 bit (4096 levels)
  analogReadResolution(12);   // set the analog input resolution to 12 bit 
  analogRead(A0);
  //start = millis();
  timer = millis(); //start time for the timer
  scanTimer = millis(); //start the display scan timer
}

void loop()
{
  start = millis();
  volume = map(analogRead(A0), 0, 4095, 0, oneHzSample);
  volume = constrain(volume, 0, oneHzSample);

  if ((start - scanTimer) >= del) //digit scanning timer
  {
    scanTimer = start; //reset the timer
    scanDigit++;       //display the next digit
    if (scanDigit >= 3) {
      scanDigit = 0;
    }
    digit(scanDigit, LEDdigit[scanDigit], LEDdecimal[scanDigit]);
  }

  //while  (millis() - start < interval)  //this will loop on the code constantly for the duration of interval
  if ((start - timer) >= interval)  //this will execute the code once when interval in reached
  {
    timer = start; //reset the timer     //time in elapsed seconds
    LEDdigit[0] = (volume % 1000) / 100;
    LEDdigit[1] = (volume % 100) / 10;
    LEDdigit[2] = (volume % 10)  ;
    //looks like you may have the digits out of order
  }
  sineWave();
}

void digit(int d, int n, int DP)
{ //turn all digits off, digit states are HIGH
  for (int i = 0; i < 3; i++) digitalWrite(digits[i], LOW); //changed from HIGH to LOW to disable the digits
  digitalWrite(LATCH, LOW);                                //add 128 for decimal point
  shiftOut(DATA, CLOCK, MSBFIRST, num[n]);
  digitalWrite(LATCH, HIGH);                               //change display pattern
  digitalWrite(digits[d], HIGH);                           //changed from LOW to HIGH here  //turn digit on, digit state LOW
}

void sineWave() {
  frequency = 1/(5555.7*pow(volume,-0.952));
  volume = map(analogRead(A0), 0, 4095, 0, oneHzSample);   
  volume = constrain(volume, 0, oneHzSample);
  if (micros() - startmicros >= frequency/39*volume)
  {
  startmicros = micros();
  analogWrite(DAC1, waveformsTable[wave1][i]);  // write the selected waveform on DAC1

  i++;
  if(i == maxSamplesNum)  // Reset the counter to repeat the wave
    i = 0;
  startmicros = micros();
  }
}

Waveforms.h

#ifndef _Waveforms_h_
#define _Waveforms_h_

#define maxWaveform 4
#define maxSamplesNum 120

static int waveformsTable[maxWaveform][maxSamplesNum] = {
  // Sin wave
  {
    0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1,
    0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4,
    0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc,
    0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f,
    0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a,
    0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a,
    0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d,
    0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a,
    0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2,
    0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf,
    0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4,
    0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794
  }
  ,

};

#endif m

Frequency Measurement code on the web

/* Frequency & Period Measurement for Arduino
 * Measure frequency on pin 25.
 * Generate frequency for testing on pin 7.
 *
 * Based on the original example from:
 * KHM 2010 /  Martin Nawrath
 * Kunsthochschule fuer Medien Koeln
 * Academy of Media Arts Cologne
 */
#include "FreqPeriodDue.h"

double lfrq;
long int pp;
//Use pin 25 for a faster interrupt since it's the first pin on PIOD.
int periodPin = 25;
int frequency = 40000; //Frequency to generate on pin 7.

void setup() {
  Serial.begin(115200);
  FreqPeriod::begin(periodPin); 
  Serial.println("FreqPeriod Library Test");

  //Generate frequency on pin 7 to be measured.
  startPWM(frequency, PIOC, PIO_PERIPH_B, PIO_PC23, PIO_DEFAULT, 6);
}

void loop() {
  pp = FreqPeriod::getPeriod();
  if (pp){
  
    Serial.print("period: ");
    Serial.print(pp);
    Serial.print(" 1/42us  /  frequency: ");

    lfrq= 42000000 / pp;
    Serial.print(lfrq);
    Serial.print(" Hz");
    Serial.println();
  }

}

void startPWM(uint32_t frequency, Pio* port, EPioType pinType, uint32_t pin, uint32_t pinConfig, uint32_t pwmChannel)
{
  uint32_t rc = frequency * 2;
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk(PWM_INTERFACE_ID);
  //Set clock A to frequency in hz.
  PWMC_ConfigureClocks(rc, 0, VARIANT_MCK);
  //Changes the port and pin over to the requested peripheral.
  PIO_Configure(port, pinType, pin, pinConfig);
  //Set prescaler (PWM_CMR_CPRE_CLKA), alignment (0) and polarity (0).
  PWMC_ConfigureChannel(PWM_INTERFACE, pwmChannel, PWM_CMR_CPRE_CLKA, 0, 0);
  //Set period to 1MHz divided by the desired frequency.
  PWMC_SetPeriod(PWM_INTERFACE, pwmChannel, 2);
  //Set duty cycle to half of the period.
  PWMC_SetDutyCycle(PWM_INTERFACE, pwmChannel, 1); //50% high, 50% low
  PWMC_EnableChannel(PWM_INTERFACE, pwmChannel);
}

FreqPeriodDue.h

/*
  FreqPeriodDue.h
  
  Based loosely on the FreqPeriod library from:
  FreqPeriod.h - Library for a Frequency Measurement c.
  Created by Martin Nawrath, KHM Lab3, June. 2010
  Released into the public domain.
*/

#ifndef FreqPeriod_h
#define FreqPeriod_h

#include "Arduino.h"

//#define FR_USE_TC3
#define FR_USE_TC4
//#define FR_USE_TC5

#if defined(FR_USE_TC3) //Timer clock 3
  #define FR_USE_TC_IRQ   TC3_IRQn
  #define FR_USE_TC     TC1
  #define FR_USE_CH     0
  #define FR_TIMER_INTR_NAME  TC3_Handler
#elif defined(FR_USE_TC4) //Timer clock 4
  #define FR_USE_TC_IRQ   TC4_IRQn
  #define FR_USE_TC     TC1
  #define FR_USE_CH     1
  #define FR_TIMER_INTR_NAME  TC4_Handler
#elif defined(FR_USE_TC5) //Timer clock 5
  #define FR_USE_TC_IRQ   TC5_IRQn
  #define FR_USE_TC     TC1
  #define FR_USE_CH     2
  #define FR_TIMER_INTR_NAME  TC5_Handler
#endif

namespace FreqPeriod {


extern volatile unsigned char  f_capt;
extern volatile unsigned long capta;
extern volatile unsigned long captd;
extern volatile unsigned int ocnt;
  
  void FreqPulse();
  void begin(int periodPin);
  unsigned long getPeriod();  
}

#endif

Please post the full error message that you receive

The error massage says like this.

sketch\FrequencyMeasureFromGitHub.ino.cpp.o: In function `loop':

C:\Users\kent\Documents\Arduino\FrequencyMeasureFromGitHub/FrequencyMeasureFromGitHub.ino:28: undefined reference to `FreqPeriod::getPeriod()'

sketch\FrequencyMeasureFromGitHub.ino.cpp.o: In function `setup':

C:\Users\kent\Documents\Arduino\FrequencyMeasureFromGitHub/FrequencyMeasureFromGitHub.ino:20: undefined reference to `FreqPeriod::begin(int)'

collect2.exe: error: ld returned 1 exit status

I suspect that you have attempted to mangle the FreqPeriodDue library into being a sketch and somehow messed it up along the way.

Let's start from scratch to make sure everything is done correctly:

  • Download the FreqPeriodDue library https://github.com/enternoescape/Arduino-FreqPeriod-Due/archive/master.zip.
  • (In the Arduino IDE) Sketch > Include Library > Add .ZIP Library
  • Click on the downloaded file
  • Click "Open".
  • Wait for the message to be shown on the bar above the "Library added to your libraries. Check "Include Library" menu.".
  • File > Examples > Arduino-FreqPeriod-Due-master > Examples > FreqPeriod

Now that you have correctly installed the library, the example sketch (and any sketch you write using the library) will now be able to compile.

I have succeeded to compile the "FrePeriod".

Thank you for the advice. I'll continue my work.

You're welcome. I'm glad to hear it's working now. Enjoy!
Per

Sorry, I have built a sine wave generator with frequency measurement and LED display code.
However it has not worked well as I have supposed.

Sorry I have posted a wrong URL.
This URL is the correct one.

I think "attachInterrupt" may be needed to fix it.

Wold you give me some advice?

main code

#include "Waveforms.h"
#include <FreqPeriodDue.h>

#define oneHzSample 1000000/maxSamplesNum
#define DATA 11
#define LATCH 10
#define CLOCK 9

//  0b11111110   DP
//  0b11111101   A
//  0b11111011   B
//  0b11110111   C
//  0b11101111   D
//  0b11011111   E
//  0b10111111   F
//  0b01111111   G

static const int num[] {
  0b10000001,   //ZERO
  0b11110011,   //ONE
  0b01001001,   //TWO
  0b01100001,   //THREE
  0b00110011,   //FIX
  0b11110001,   //SEVEN
  0b00000001,   //EIGHT
  0b00100001,   //NINE
  0b10000001,   //ZERO

  0b11110010,   //ONE DOT
  0b01001000,   //TWO DOT
  0b01100000,   //THREE DOT
  0b00110010,   //FOUR DOT
  0b00100100,   //FIVE DOT
  0b00000100,   //SIX DOT
  0b11110000,   //SEVEN DOTOUR
  0b00100101,   //FIVE
  0b00000101,   //S
  0b00000000,   //EIGHT DOT
  0b00100000,   //NINE DOT
};

int count;
int digits[] = {4, 3, 2};
int LEDdigit[] = {0, 0, 0}; //storage for digits to be displayed
int LEDdecimal[] = {0, 0, 0}; //storage for decimal indicators
byte scanDigit = 0; //tells which digit to display
unsigned int start;  //changed from int to unsigned int
unsigned int timer; //changed from int to unsigned int
unsigned int scanTimer; //timer for display scanning
unsigned int volume = 50;
//int interval = 5000;
int interval = 100; //update the display once each second
int blinkingtime = 10;
int del = 10;int i = 0;
double startmicros;
volatile int wave1 = 0;
int lfrq;
long int pp;
int periodPin = 25;
int frequency = 40000;
const int plusbuttonPin = 53;
const int minusbuttonPin = 52;
int buttonStateplus = 0;
int buttonStateminus = 0;


void setup()
{
  Serial.begin(9600);
  FreqPeriod::begin(periodPin); 
  startPWM(frequency, PIOC, PIO_PERIPH_B, PIO_PC23, PIO_DEFAULT, 6);
  pinMode(DATA, OUTPUT);
  pinMode(LATCH, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(DAC1,OUTPUT);
  pinMode(plusbuttonPin,INPUT_PULLUP);
  pinMode(minusbuttonPin,INPUT_PULLUP);
  //start = millis();
  timer = millis(); //start time for the timer
  scanTimer = millis(); //start the display scan timer
}

void loop()
{
  pp = FreqPeriod::getPeriod();
  if (pp){
      lfrq= 42000000 / pp;
  }
  
  start = millis();
  volume = constrain(volume, 50, 100);

  if ((start - scanTimer) >= del) //digit scanning timer
  {
    scanTimer = start; //reset the timer
    scanDigit++;       //display the next digit
    if (scanDigit >= 3) {
      scanDigit = 0;
    }
    digit(scanDigit, LEDdigit[scanDigit], LEDdecimal[scanDigit]);
  }

  //while  (millis() - start < interval)  //this will loop on the code constantly for the duration of interval
  if ((start - timer) >= interval)  //this will execute the code once when interval in reached
  {
    timer = start; //reset the timer   
    LEDdigit[0] = (lfrq % 1000) / 100;
    LEDdigit[1] = (lfrq % 100) / 10;
    LEDdigit[2] = (lfrq % 10)  ;
  }
  sineWave();
  attachInterrupt(52,button,CHANGE);
  attachInterrupt(53,button,CHANGE);
}

void digit(int d, int n, int DP)
{ //turn all digits off, digit states are HIGH
  for (int i = 0; i < 3; i++) digitalWrite(digits[i], LOW); //changed from HIGH to LOW to disable the digits
  digitalWrite(LATCH, LOW);                                //add 128 for decimal point
  shiftOut(DATA, CLOCK, MSBFIRST, num[n]);
  digitalWrite(LATCH, HIGH);                               //change display pattern
  digitalWrite(digits[d], HIGH);                           //changed from LOW to HIGH here  //turn digit on, digit state LOW
}

void sineWave() { 
  volume = constrain(volume, 10, 1000);
  if (micros() - startmicros >= volume)
  {
  startmicros = micros();
  analogWrite(DAC1, waveformsTable[wave1][i]);  // write the selected waveform on DAC1

  i++;
  if(i == maxSamplesNum)  // Reset the counter to repeat the wave
    i = 0;
  startmicros = micros();
  }
}

void startPWM(uint32_t frequency, Pio* port, EPioType pinType, uint32_t pin, uint32_t pinConfig, uint32_t pwmChannel)
{
  uint32_t rc = frequency * 2;
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk(PWM_INTERFACE_ID);
  //Set clock A to frequency in hz.
  PWMC_ConfigureClocks(rc, 0, VARIANT_MCK);
  //Changes the port and pin over to the requested peripheral.
  PIO_Configure(port, pinType, pin, pinConfig);
  //Set prescaler (PWM_CMR_CPRE_CLKA), alignment (0) and polarity (0).
  PWMC_ConfigureChannel(PWM_INTERFACE, pwmChannel, PWM_CMR_CPRE_CLKA, 0, 0);
  //Set period to 1MHz divided by the desired frequency.
  PWMC_SetPeriod(PWM_INTERFACE, pwmChannel, 2);
  //Set duty cycle to half of the period.
  PWMC_SetDutyCycle(PWM_INTERFACE, pwmChannel, 1); //50% high, 50% low
  PWMC_EnableChannel(PWM_INTERFACE, pwmChannel);
}

void button()
{
  buttonStateplus = digitalRead(plusbuttonPin);
  if (buttonStateplus == LOW){
    volume = volume+1;  
  } 
  buttonStateminus = digitalRead(minusbuttonPin);
  if (buttonStateminus == LOW){
    volume = volume-1;
  }
}

FreqPeriodDue.h

/*
  FreqPeriodDue.h
  
  Based loosely on the FreqPeriod library from:
  FreqPeriod.h - Library for a Frequency Measurement c.
  Created by Martin Nawrath, KHM Lab3, June. 2010
  Released into the public domain.
*/

#ifndef FreqPeriod_h
#define FreqPeriod_h

#include "Arduino.h"

//#define FR_USE_TC3
#define FR_USE_TC4
//#define FR_USE_TC5

#if defined(FR_USE_TC3) //Timer clock 3
  #define FR_USE_TC_IRQ   TC3_IRQn
  #define FR_USE_TC     TC1
  #define FR_USE_CH     0
  #define FR_TIMER_INTR_NAME  TC3_Handler
#elif defined(FR_USE_TC4) //Timer clock 4
  #define FR_USE_TC_IRQ   TC4_IRQn
  #define FR_USE_TC     TC1
  #define FR_USE_CH     1
  #define FR_TIMER_INTR_NAME  TC4_Handler
#elif defined(FR_USE_TC5) //Timer clock 5
  #define FR_USE_TC_IRQ   TC5_IRQn
  #define FR_USE_TC     TC1
  #define FR_USE_CH     2
  #define FR_TIMER_INTR_NAME  TC5_Handler
#endif

namespace FreqPeriod {


extern volatile unsigned char  f_capt;
extern volatile unsigned long capta;
extern volatile unsigned long captd;
extern volatile unsigned int ocnt;
  
  void FreqPulse();
  void begin(int periodPin);
  unsigned long getPeriod();  
}

#endif

Waveforms.h

#ifndef _Waveforms_h_
#define _Waveforms_h_

#define maxWaveform 4
#define maxSamplesNum 120

static int waveformsTable[maxWaveform][maxSamplesNum] = {
  // Sin wave
  {
    0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1,
    0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4,
    0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc,
    0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f,
    0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a,
    0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a,
    0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d,
    0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a,
    0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2,
    0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf,
    0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4,
    0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794
  }
  ,

};

#endif m

However it has not worked well as I have supposed

The video that you linked to provides no information as to what should happen as opposed to what does happen when you run it.

More details please

What do you expect that using an interrupt would achieve ?

Sorry.

I'm going to make a sine wave generator which frequency ("volume" on the source code) controlled with buttons. However, the sound is not smooth supposed to be, the displayed frequency is unsteady, and buttons don't work well as sensibility.

I have posted Wrong URL.

this URL is what I have just wanted to post.

The signal of DAC channel acts like this.

I had forgot to write “analogWriteResolution(12);” in the setup function.
Then the analog output has made clear sine wave.