Other Parts Discussed in Thread: MSP430G2553
A
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
ADC reads time domain information so you don't need to find code where the frequency is showed but you want to find where it (time domain samples) comes out of ADC. You shall search google first and find similar "self made oscilloscope" projects, look how they are built and how they actually work.
Hi,
Have you got even part of the solution for your project?
I got something similar to solve, in the msp430 user folder there is a an audio function which can record your voice or sound and transform it from time domain to frequency domain using FFT (fast fourier transform) function. I think to make it display only time domain I will just need to disable the FFT function?
Also for your additional functions, do you have the code or even a flow chart o how you solved it?
Thanks for any answer!
Hi,
Basically, the 1st question is to use the MSP430 as an Oscilloscope, showing time domain sine wave depending on the voice. So I need to write at the bottom of the following program plot voice[i] as y axis, i as x axis. Part of the code is pasted below, can you write a function at the bottom of the code that will plot voice[1] on the y axis and i on the x axis?
/**********************************************************************//**
* @file FFT.c
*
* Copyright 2010 Texas Instruments, Inc.
***************************************************************************/
#include "msp430.h"
#include "MSP-EXP430F5438_HAL\hal_MSP-EXP430F5438.h"
#include "UserExperience_F5438A.h"
#include "FFT.h"
#include "FFT_430.h"
int FBuff[512],outer;
unsigned short index1;
unsigned int voice_data[1024];
unsigned int index;
const int bit_rev_index[]={0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,
0xD0,0x30,0xB0,0x70,0xF0,0x08,0x88,0x48,0xC8,0x28,0xA8,
0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,0x04,
0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,
0x34,0xB4,0x74,0xF4,0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,
0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,0x02,0x82,
0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,
0xB2,0x72,0xF2,0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,
0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,0x06,0x86,0x46,
0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,
0x76,0xF6,0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,
0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,0x01,0x81,0x41,0xC1,
0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,
0xF1,0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,
0x59,0xD9,0x39,0xB9,0x79,0xF9,0x05,0x85,0x45,0xC5,0x25,
0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,
0xDD,0x3D,0xBD,0x7D,0xFD,0x03,0x83,0x43,0xC3,0x23,0xA3,
0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,0x0B,
0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,
0x3B,0xBB,0x7B,0xFB,0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,
0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,0x0F,0x8F,
0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,
0xBF,0x7F,0xFF};
int imag, real,real_abs,imag_abs,mag,max,min;
int FFT_data[512];
unsigned int FFT_Image[1344];
/**********************************************************************//**
* @brief Sets up board for recording from microphone
*
* @param none
*
* @return none
*************************************************************************/
void shutdownRecorder(void)
{
halLcdSetBackLight(lcdBackLightLevelSettingLOCAL);
// Power-down MSP430 modules
TBCTL = 0; // Disable Timer_B
ADC12CTL1 &= ~ADC12CONSEQ_2; // Stop conversion immediately
ADC12CTL0 &= ~ADC12ENC; // Disable ADC12 conversion
ADC12CTL0 = 0x00; // Switch off ADC12
ADC12IE = 0x00;
AUDIO_PORT_OUT &= ~MIC_POWER_PIN; // Turn of MIC
AUDIO_PORT_SEL &= ~MIC_INPUT_PIN;
}
void setupRecorder()
{
AUDIO_PORT_OUT |= MIC_POWER_PIN;
AUDIO_PORT_OUT &= ~MIC_INPUT_PIN;
AUDIO_PORT_SEL |= MIC_INPUT_PIN;
UCSCTL8 |= MODOSCREQEN;
ADC12CTL0 &= ~ADC12ENC; // Disable conversions to configure ADC12
ADC12CTL0 = ADC12ON + ADC12SHT02; // Configure ADC12 to sample a sequence of channels, once
ADC12CTL1 = ADC12SHP + ADC12CONSEQ_2 + ADC12SSEL_2 + ADC12SHS_3;
ADC12CTL2 = ADC12RES_0; // Select 8-bit resolution
ADC12MCTL0 = MIC_INPUT_CHAN | ADC12EOS;
ADC12CTL0 |= ADC12ENC; // Enable
ADC12IE = BIT0;
// Initialize Timer_B to be used as ADC12 trigger
TBCTL = TBSSEL_2 + TBCLR; // Use SMCLK as Timer_B source
TBCCR0 = 2047; // Initialize TBCCR0 (period register)
TBCCR1= 2047 - 100; // Initialize TBCCR1 (ADC12 trigger)
TBCCTL0 = 0x0000;
TBCCTL1 = OUTMOD_7;
TBCCTL2 = 0x0000;
TBCCTL3 = 0x0000;
TBCCTL4 = 0x0000;
TBCCTL5 = 0x0000;
TBCCTL6 = 0x0000;
}
/**********************************************************************//**
* @brief Runs the FFT app. Performs the FFT and displays it to the screen.
*
* @param none
*
* @return none
*************************************************************************/
void FFTrecorder(void)
{
unsigned int i, j;
unsigned int mask = 0x0000;
fftISR = 1;
// Initialize FFT variables
buf_index = 0;
for(i=0; i<1344; i++) {
FFT_Image[i] = 0x0000;
}
halLcdClearScreen();
halLcdPrintLine(" FFT DEMO ", 0, 0 );
halLcdPrintLine("0", 8, 0 );
halLcdPrintLineCol("Fs 2", 8, 13, 0 );
halLcdLine(120, 107, 126, 97, PIXEL_ON);
halLcdHLine(0, 138, 96, PIXEL_ON);
halButtonsInit( BUTTON_ALL );
halButtonsInterruptEnable( BUTTON_ALL );
buttonsPressed = 0;
setupRecorder();
while(!buttonsPressed)
{
TBCCTL1 &= ~CCIFG;
TBCTL |= MC0; //start timer B
__bis_SR_register(LPM0_bits + GIE);
__no_operation();
TBCTL &= ~MC0;
if (buf_index == 512)
for (i=0;i<512;i++)
voice_data[i] = buffer[i];
else
for (i=0;i<512;i++)
voice_data[i] = buffer[i + 512];
// FILL IN CODE HERE THAT PLOTS voice[i] on y axis, and [i] on x axis.
// USE halLcdLine(120, 107, 126, 97, PIXEL_ON); FROM ABOVE TO DRAW THE GRAPH.
shutdownRecorder();
}
Hi,
Basically use the microphone as input device and it draws a graph voice_data[i] on y axis and i on x axis. x is time passing, y is voice amplitude. That is the time domain. I think I need a permanet for loop that uses the function halLCDline(x1, x2, y1, y2, grayscale) to draw onto the LCD screen.
The code provided is teh frequency domain after Fast Fourier Transform, we need to disable this FFT_prog() and draw the time domain function instead.
Can you help?
Hi Jackie,
Someone told me that I need to scale it because the values are over a thousand while the LCD screen is just a 138 * 108.
How do I scale it? divide i by a number to shrink it?
One of the question is that I need to code an automatic scaling function that will make the wave fit he LCD screen automatically.
Regards,
M
{
while(1)
if (j<(84-Vdata[i]*2))
FFT_Image[((i-1)/8)+j*16] &= ~mask;
else
FFT_Image[((i-1)/8)+j*16] |= mask;
}
try adding this in it should scale it to an 1/8 of the size
Where exactly do I add that in?
Is it inside the for loop? Above or below the line: halLcdLine(i, voice_data[i], i + 1, voice_data[i + 1], PIXEL_ON);
Hi,
I declared the variables, j, mask, and change the Vdata[i] to FFT_data[i].
I put that code in right below the halLCDline function, nothing appears on the LCD screen:
for (i=0;i<256;i++)
{
halLcdLine(i, voice_data[i], i + 1, voice_data[i + 1], PIXEL_ON);
}
{
while(1)
if (j<(84-FFT_data[i]*2))
FFT_Image[((i-1)/8)+j*16] &= ~mask;
else
FFT_Image[((i-1)/8)+j*16] |= mask;
}
This code draws the lines of voice amplitude but it does not refresh and erase the lines so each iteration, more and more lines are drawn onto the LCD until it's all black. How do I refresh the screen after each iteration? Someone told me it's something to do with // halLcdLine(i, voice_data[i], i + 1, voice_data[i + 1], PIXEL_OFF);
but ive tried and it doesn't erase the lines.
/**********************************************************************//**
* @file FFT.c
*
* Copyright 2010 Texas Instruments, Inc.
***************************************************************************/
#include "msp430.h"
#include "MSP-EXP430F5438_HAL\hal_MSP-EXP430F5438.h"
#include "UserExperience_F5438A.h"
#include "FFT.h"
#include "FFT_430.h"
int FBuff[512],outer;
unsigned short index1;
unsigned int voice_data[1024];
unsigned int index;
const int bit_rev_index[]={0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,
0xD0,0x30,0xB0,0x70,0xF0,0x08,0x88,0x48,0xC8,0x28,0xA8,
0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,0x04,
0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,
0x34,0xB4,0x74,0xF4,0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,
0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,0x02,0x82,
0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,
0xB2,0x72,0xF2,0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,
0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,0x06,0x86,0x46,
0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,
0x76,0xF6,0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,
0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,0x01,0x81,0x41,0xC1,
0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,
0xF1,0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,
0x59,0xD9,0x39,0xB9,0x79,0xF9,0x05,0x85,0x45,0xC5,0x25,
0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,
0xDD,0x3D,0xBD,0x7D,0xFD,0x03,0x83,0x43,0xC3,0x23,0xA3,
0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,0x0B,
0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,
0x3B,0xBB,0x7B,0xFB,0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,
0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,0x0F,0x8F,
0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,
0xBF,0x7F,0xFF};
int imag, real,real_abs,imag_abs,mag,max,min;
int FFT_data[512];
unsigned int FFT_Image[1344];
/**********************************************************************//**
* @brief Sets up board for recording from microphone
*
* @param none
*
* @return none
*************************************************************************/
void shutdownRecorder(void)
{
halLcdSetBackLight(lcdBackLightLevelSettingLOCAL);
// Power-down MSP430 modules
TBCTL = 0; // Disable Timer_B
ADC12CTL1 &= ~ADC12CONSEQ_2; // Stop conversion immediately
ADC12CTL0 &= ~ADC12ENC; // Disable ADC12 conversion
ADC12CTL0 = 0x00; // Switch off ADC12
ADC12IE = 0x00;
AUDIO_PORT_OUT &= ~MIC_POWER_PIN; // Turn of MIC
AUDIO_PORT_SEL &= ~MIC_INPUT_PIN;
}
void setupRecorder()
{
AUDIO_PORT_OUT |= MIC_POWER_PIN;
AUDIO_PORT_OUT &= ~MIC_INPUT_PIN;
AUDIO_PORT_SEL |= MIC_INPUT_PIN;
UCSCTL8 |= MODOSCREQEN;
ADC12CTL0 &= ~ADC12ENC; // Disable conversions to configure ADC12
ADC12CTL0 = ADC12ON + ADC12SHT02; // Configure ADC12 to sample a sequence of channels, once
ADC12CTL1 = ADC12SHP + ADC12CONSEQ_2 + ADC12SSEL_2 + ADC12SHS_3;
ADC12CTL2 = ADC12RES_0; // Select 8-bit resolution
ADC12MCTL0 = MIC_INPUT_CHAN | ADC12EOS;
ADC12CTL0 |= ADC12ENC; // Enable
ADC12IE = BIT0;
// Initialize Timer_B to be used as ADC12 trigger
TBCTL = TBSSEL_2 + TBCLR; // Use SMCLK as Timer_B source
TBCCR0 = 2047; // Initialize TBCCR0 (period register)
TBCCR1= 2047 - 100; // Initialize TBCCR1 (ADC12 trigger)
TBCCTL0 = 0x0000;
TBCCTL1 = OUTMOD_7;
TBCCTL2 = 0x0000;
TBCCTL3 = 0x0000;
TBCCTL4 = 0x0000;
TBCCTL5 = 0x0000;
TBCCTL6 = 0x0000;
}
/**********************************************************************//**
* @brief Runs the FFT app. Performs the FFT and displays it to the screen.
*
* @param none
*
* @return none
*************************************************************************/
void FFTrecorder(void)
{
unsigned int i;
// unsigned int mask = 0x0000;
fftISR = 1;
// Initialize FFT variables
buf_index = 0;
// for(i=0; i<1344; i++) {
// FFT_Image[i] = 0x0000;
// }
halLcdClearScreen();
halLcdPrintLine(" FFT DEMO ", 0, 0 );
halLcdPrintLine("0", 8, 0 );
halLcdPrintLineCol("Fs 2", 8, 13, 0 );
halLcdLine(120, 107, 126, 97, PIXEL_ON);
halLcdHLine(0, 138, 96, PIXEL_ON);
halButtonsInit( BUTTON_ALL );
halButtonsInterruptEnable( BUTTON_ALL );
buttonsPressed = 0;
setupRecorder();
while(!buttonsPressed)
{
TBCCTL1 &= ~CCIFG;
TBCTL |= MC0; //start timer B
__bis_SR_register(LPM0_bits + GIE);
__no_operation();
TBCTL &= ~MC0;
if (buf_index == 512)
for (i=0;i<512;i++)
voice_data[i] = buffer[i];
else
for (i=0;i<512;i++)
voice_data[i] = buffer[i + 512];
/* FFT_prog(); // Perform FFT and store
for (i=0;i<256;i++)
{
index=bit_rev_index[i];
real=FBuff[2*index];
imag=FBuff[2*index+1];
if(real < 0)
real_abs=~real+1;
else
real_abs=real;
if(imag < 0)
imag_abs=~imag+1;
else
imag_abs=imag;
if(real_abs >= imag_abs)
{
max=real_abs;
min=imag_abs;
}
else
{
max=imag_abs;
min=real_abs;
}
mag=max+3*(min>>3); */
for (i=0;i<256;i++)
{
halLcdLine(i, voice_data[i], i + 2, voice_data[i + 2], PIXEL_ON);
// halLcdLine(i, voice_data[i], i + 1, voice_data[i + 1], PIXEL_OFF);
}
//prepare the image of the FFT for display
//// for (i=1;i<128;i++)
// {
//// switch(i%8)
//// {
//// case 1: mask = 0x0003; break;
//// case 2: mask = 0x000C; break;
//// case 3: mask = 0x0030; break;
//// case 4: mask = 0x00C0; break;
//// case 5: mask = 0x0300; break;
//// case 6: mask = 0x0C00; break;
//// case 7: mask = 0x3000; break;
//// case 0: mask = 0xC000; break;
//// default: mask = 0x0000; break;
//// }
// for (j=0; j<84; j++)
// {
// if (j<(84-FFT_data[i]*2))
// FFT_Image[((i-1)/8)+j*16] &= ~mask;
// else
// FFT_Image[((i-1)/8)+j*16] |= mask;
// }
// }
// halLcdImage(FFT_Image, 16, 84, 1, 12); //display the image
}
// fftISR = 0;
shutdownRecorder();
}
I hope you find the answers soon. for i have not a clue how to fix it. if you find the answer you seek please let me know.
here's an easier one, how do i change sampling rate on below code? and then another question for this exercise is:
Provide signal FFT functionality (note: this is dependent on sampling rate)?
**Attention** This is a public forum