Writing your code Your code should continuously read from the Arduino in an infinite loop. The code will stop when you press CTRL-C. Create an uint8_t array of 512 elements. For every iteration of the loop, read in 512 bytes into the array - as before, the read function may not return 512 bytes at once, so you will need to keep track of how many bytes you have received and keep calling read until you get 512 bytes. When you get to 512 bytes, call the dft function to calculate and display the DFT as histogram. I have also provided this dift function in the dftlib.c file. Note, that it is called dft not fft because it doesn't actually use the Fast Fourier Transform algorithm to calculate the DFT. This dft function expects three arguments - the array of uint8_t data items which you read from the Arduino, an array of double items into which dft puts the frequency values, and the size of the array. After calling dft, you should call dft_print, which will display the frequency spectrum. This dft_print function expects two arguments - the array of double items that was filled in by dft and the size of the array. The skeleton code can be downloaded from Compile and run your program as follows. Use the -03 option to enable maximum optimization. Otherwise, the DFT calculations may be too slow. $ gcc -03 -o dataread dataread.c dftlib.c $ ./dataread /dev/ttyS2 000 *** 022 ****** 047 ***** 071 096 **** 120 *** 142 ** 167 ** 191* 216* 240* 262 + 287* 311+ 336- 360- 382- 407 -- 431 + 456+ The numbers on the left represent the frequency and the bars that go the right represent the intensity of the frequency in the received signal. When you run the code, you should be able to see what frequencies are in the signal. If you press and hold down the button, you will see the frequencies change. #include #include #include #include #include #include void dft(uint8_t*, double*, int); void dft_print(double*, int, double); #define N 512 int main(int argc, char **argv) { char *port = argv[1]; /* Open the file */ int fd = open(port, O_RDONLY); // code to set communication rate to 9600 bits per second struct termios tio; tcgetattr(fd, &tio); cfset speed(&tio, B9600); tcsetattr(fd, 0, &tio); // reopen the serial port so that the speed change takes effect close(fd); fd = open(port, O_RDONLY); if (fd < 0) { } perror("Could not open port"); exit(-1); uint8_t data[N]; double dftdata[N]; // TODO create a loop that continuously // // reads N bytes from fd into the data array calls the dft function to create the frequency values calls the dft_print function to print the DFT close(fd); }

C++ Programming: From Problem Analysis to Program Design
8th Edition
ISBN:9781337102087
Author:D. S. Malik
Publisher:D. S. Malik
Chapter5: Control Structures Ii (repetition)
Section: Chapter Questions
Problem 30SA
icon
Related questions
Question

Write a program that acquires data from a data source and calculates and displays the Discrete Fourier
Transform associated with that data. In this case, the Arduino will generate a signal, that is sampled by the ADC and then sent to the computer
over the serial port. The  Arduino  code is :

int lookup_index = 0;
#define SIN_FREQ 100
long sin_freq = SIN_FREQ;
#define LOOKUP_ARRAY_SIZE 128UL
#define PWM_RESOLUTION 8
#if PWM_RESOLUTION <= 8
  #define PWM_t uint8_t
#else
  #define PWM_t uint16_t
#endif

PWM_t *lookup_array;

// lookup array for sin(2pi f t)
PWM_t lookup_array1[LOOKUP_ARRAY_SIZE] =
{
    127, 133, 139, 146, 152, 158, 164, 170, 176, 181, 187, 192, 198, 203, 208,
    212, 217, 221, 225, 229, 233, 236, 239, 242, 244, 247, 249, 250, 252, 253,
    253, 254, 254, 254, 253, 253, 252, 250, 249, 247, 244, 242, 239, 236, 233,
    229, 225, 221, 217, 212, 208, 203, 198, 192, 187, 181, 176, 170, 164, 158,
    152, 146, 139, 133, 127, 121, 115, 108, 102, 96, 90, 84, 78, 73, 67, 62, 56,
    51, 46, 42, 37, 33, 29, 25, 21, 18, 15, 12, 10, 7, 5, 4, 2, 1, 1, 0, 0, 0, 1,
    1, 2, 4, 5, 7, 10, 12, 15, 18, 21, 25, 29, 33, 37, 42, 46, 51, 56, 62, 67,
    73, 78, 84, 90, 96, 102, 108, 115, 121
};

// lookup array for sin(2pi f t) + sin(4pi f t)
PWM_t lookup_array2[LOOKUP_ARRAY_SIZE] =
{
    127, 136, 146, 155, 164, 173, 181, 189, 196, 204, 210, 216, 221, 226, 230,
    233, 236, 238, 239, 239, 239, 238, 236, 234, 231, 227, 223, 219, 214, 209,
    203, 197, 191, 184, 178, 172, 165, 159, 153, 147, 141, 135, 130, 125, 121,
    117, 114, 111, 108, 106, 105, 104, 104, 104, 104, 105, 106, 108, 110, 112,
    115, 118, 121, 124, 127, 130, 133, 136, 139, 142, 144, 146, 148, 149, 150,
    150, 150, 150, 149, 148, 146, 143, 140, 137, 133, 129, 124, 119, 113, 107,
    101, 95, 89, 82, 76, 70, 63, 57, 51, 45, 40, 35, 31, 27, 23, 20, 18, 16, 15,
    15, 15, 16, 18, 21, 24, 28, 33, 38, 44, 50, 58, 65, 73, 81, 90, 99, 108, 118
};

ISR(TIMER1_COMPA_vect)
{
    long temp = lookup_array[lookup_index];
    OCR1B = ((temp * (OCR1A+1)) / (1<<PWM_RESOLUTION));
    lookup_index = (lookup_index + 1) % LOOKUP_ARRAY_SIZE;
}

void init_ocr(int freq)
{
    unsigned long pwm_freq = LOOKUP_ARRAY_SIZE * freq;
    OCR1A = (16000000UL/1/pwm_freq)-1;
}

void InitTimer1(void)
{
    TCCR1A = (1<<WGM11) | (1<<WGM10); // Fast PWM mode
    TCCR1B = (1<<WGM13) | (1<<WGM12); // Fast PWM mode
    init_ocr(sin_freq);
    TIMSK1 = (1<<OCIE1A);   // Enable Timer 0 Compare A ISR
    TCCR1A |= (1<<COM1B1);  // Set OC1B (PB2) pin to clear on compare match
    TCCR1B |= 1;            // prescaler 8, start timer

    DDRB |= (1<<DDB2);      // PB2 (PWM)
}

void setup() {
  // put your setup code here, to run once:
  lookup_array = lookup_array2;
  InitTimer1();
  pinMode(13,OUTPUT);
  lookup_index = 0;
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  int data = analogRead(0);
  Serial.write(data >> 2);

  if (lookup_array != lookup_array2 && digitalRead(5)==HIGH) {
    digitalWrite(13,HIGH);
    lookup_array = lookup_array2;
  }
  else if (lookup_array != lookup_array1 && digitalRead(5)==LOW) {
    digitalWrite(13,LOW);
    lookup_array = lookup_array1;
  }
}
Writing your code
Your code should continuously read from the Arduino in an infinite loop. The code will stop when you
press CTRL-C. Create an uint8_t array of 512 elements. For every iteration of the loop, read in 512
bytes into the array - as before, the read function may not return 512 bytes at once, so you will need to
keep track of how many bytes you have received and keep calling read until you get 512 bytes. When
you get to 512 bytes, call the dft function to calculate and display the DFT as histogram. I have also
provided this dift function in the dftlib.c file. Note, that it is called dft not fft because it doesn't
actually use the Fast Fourier Transform algorithm to calculate the DFT. This dft function expects three
arguments - the array of uint8_t data items which you read from the Arduino, an array of double
items into which dft puts the frequency values, and the size of the array. After calling dft, you should
call dft_print, which will display the frequency spectrum. This dft_print function expects two
arguments - the array of double items that was filled in by dft and the size of the array.
The skeleton code can be downloaded from
Compile and run your program as follows. Use the -03 option to enable maximum optimization.
Otherwise, the DFT calculations may be too slow.
$ gcc -03 -o dataread dataread.c dftlib.c
$ ./dataread /dev/ttyS2
000
***
022 ******
047 *****
071
096 ****
120 ***
142 **
167 **
191*
216*
240*
262 +
287*
311+
336-
360-
382-
407 --
431 +
456+
The numbers on the left represent the frequency and the bars that go the right represent the intensity of
the frequency in the received signal. When you run the code, you should be able to see what frequencies
are in the signal. If you press and hold down the button, you will see the frequencies change.
Transcribed Image Text:Writing your code Your code should continuously read from the Arduino in an infinite loop. The code will stop when you press CTRL-C. Create an uint8_t array of 512 elements. For every iteration of the loop, read in 512 bytes into the array - as before, the read function may not return 512 bytes at once, so you will need to keep track of how many bytes you have received and keep calling read until you get 512 bytes. When you get to 512 bytes, call the dft function to calculate and display the DFT as histogram. I have also provided this dift function in the dftlib.c file. Note, that it is called dft not fft because it doesn't actually use the Fast Fourier Transform algorithm to calculate the DFT. This dft function expects three arguments - the array of uint8_t data items which you read from the Arduino, an array of double items into which dft puts the frequency values, and the size of the array. After calling dft, you should call dft_print, which will display the frequency spectrum. This dft_print function expects two arguments - the array of double items that was filled in by dft and the size of the array. The skeleton code can be downloaded from Compile and run your program as follows. Use the -03 option to enable maximum optimization. Otherwise, the DFT calculations may be too slow. $ gcc -03 -o dataread dataread.c dftlib.c $ ./dataread /dev/ttyS2 000 *** 022 ****** 047 ***** 071 096 **** 120 *** 142 ** 167 ** 191* 216* 240* 262 + 287* 311+ 336- 360- 382- 407 -- 431 + 456+ The numbers on the left represent the frequency and the bars that go the right represent the intensity of the frequency in the received signal. When you run the code, you should be able to see what frequencies are in the signal. If you press and hold down the button, you will see the frequencies change.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
void dft(uint8_t*, double*, int);
void dft_print(double*, int, double);
#define N 512
int main(int argc, char **argv)
{
char *port = argv[1];
/* Open the file */
int fd = open(port, O_RDONLY);
// code to set communication rate to 9600 bits per second
struct termios tio;
tcgetattr(fd, &tio);
cfset speed(&tio, B9600);
tcsetattr(fd, 0, &tio);
// reopen the serial port so that the speed change takes effect
close(fd);
fd = open(port, O_RDONLY);
if (fd < 0) {
}
perror("Could not open port");
exit(-1);
uint8_t data[N];
double dftdata[N];
// TODO create a loop that continuously
//
//
reads N bytes from fd into the data array
calls the dft function to create the frequency values
calls the dft_print function to print the DFT
close(fd);
}
Transcribed Image Text:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <termios.h> #include <fcntl.h> void dft(uint8_t*, double*, int); void dft_print(double*, int, double); #define N 512 int main(int argc, char **argv) { char *port = argv[1]; /* Open the file */ int fd = open(port, O_RDONLY); // code to set communication rate to 9600 bits per second struct termios tio; tcgetattr(fd, &tio); cfset speed(&tio, B9600); tcsetattr(fd, 0, &tio); // reopen the serial port so that the speed change takes effect close(fd); fd = open(port, O_RDONLY); if (fd < 0) { } perror("Could not open port"); exit(-1); uint8_t data[N]; double dftdata[N]; // TODO create a loop that continuously // // reads N bytes from fd into the data array calls the dft function to create the frequency values calls the dft_print function to print the DFT close(fd); }
AI-Generated Solution
AI-generated content may present inaccurate or offensive content that does not represent bartleby’s views.
steps

Unlock instant AI solutions

Tap the button
to generate a solution

Similar questions
  • SEE MORE QUESTIONS
Recommended textbooks for you
C++ Programming: From Problem Analysis to Program…
C++ Programming: From Problem Analysis to Program…
Computer Science
ISBN:
9781337102087
Author:
D. S. Malik
Publisher:
Cengage Learning
Programming Logic & Design Comprehensive
Programming Logic & Design Comprehensive
Computer Science
ISBN:
9781337669405
Author:
FARRELL
Publisher:
Cengage