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