Interface 2015年4月号 第1部 第7章のプログラム

Dependencies:   USBDevice mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /**
00002  *  @file       Main.cpp
00003  *  @brief      Send 1ch waveform and FFT data to PC via USB serial
00004  *  @date       2015.02.24
00005  *  @version    1.0.2
00006  */
00007 #include "mbed.h"
00008 #include "USBSerial.h"
00009 #include "FilterTest.h"
00010 #include "FftTest.h"
00011 
00012 #define ON      (1)
00013 #define OFF     (0)
00014 
00015 #define LED_ON  (0)
00016 #define LED_OFF (1)
00017 
00018 #define BYTE_MASK       (0xFF)
00019 #define INT16_MAX       (32767)
00020 #define INT16_MIN       (-32768)
00021 #define UINT16_MAX      (65535)
00022 #define UINT16_MIN      (0)
00023 
00024 #define SAMPLING_RATE   (0.001)     /* A/D sampling rate (1kHz) */
00025 #define DEC_COUNT       (5)         /* Decimation count (sampling 200Hz)*/
00026 
00027 #define PACKET_HEADER   (0xAA)
00028 #define WAVEFORM_ID     (0x01)
00029 #define FFT_ID          (0x02)
00030 #define PACKET_SIZE     (34)        /* 64 -> 34 for PC to receive waveform data smoothly */
00031 #define PAYLOAD_SIZE    (30)        /* PACKET_SIZE - 4(Header size) */
00032 #define WAV_BUF_NUM     (2)         /* Double buffer */
00033 #define WV_PKT_CNTR_NUM (100)
00034 /*  [ Packet format ]                                               */
00035 /*        ----------------                                          */
00036 /*  0x00 | Header byte    | Fixed value (PACKET_HEADER:0xAA)        */
00037 /*  0x01 | Data type      | ID value    (0x01:Waveform, 0x02:FFT)   */
00038 /*  0x02 | Packet counter | Count value (0to99 < CNTR_SIZE:100)     */
00039 /*  0x03 | Payload size   | Fixed value (DATA_NUM:30)               */
00040 /*  0x04 | Data0 (MSBside)| Short type  (signed, big endian)        */
00041 /*  ...  | ...            |                                         */
00042 /*  0x21 | Data29(LSBside)|                                         */
00043 /*        ----------------                                          */
00044 
00045 #define FFT_LENGTH      (256)       /* FFT data length */
00046 #define FFT_INTERVAL    (200)       /* FFT calc interval */
00047 #define FFT_OVERLAP_LEN (56)        /* FFT overlap length */
00048 #define FFT_BUF_NUM     (2)         /* Double buffer */
00049 #define FFT_SEND_LEN    (90)        /* FFT send data length */
00050 
00051 
00052 Ticker      sampling;               /* Interval timer for A/D sampling */
00053 AnalogIn    wave_in(p20);           /* Waveform input */
00054 USBSerial   serial;
00055 FilterTest  filter;
00056 FftTest     fft;
00057 
00058 /* DIP switch for filter ON/OFF */
00059 DigitalIn   hpf_on(p28);
00060 DigitalIn   lpf_on(p27);
00061 DigitalIn   brf_on(p26);
00062 /*  [ DIP switch ]                                  */
00063 /*    TG-LPC11U35-501         +3.3V                 */
00064 /*  | CN1         CN2 |        ---                  */
00065 /*  |     mbed BD     |         |                   */
00066 /*  |              13 | p28 -/ -+  Hiph pass filter */
00067 /*  |              14 | p27 -/ -+  Low pass filter  */
00068 /*  |              15 | p26 -/ -+  Notch filter     */
00069 /*  |                 |                             */
00070 /*  pull-down is default as below.                  */
00071 /*  http://developer.mbed.org/handbook/DigitalIn    */
00072 /*  It says "By default, the DigitalIn is setup     */
00073 /*          with an internal pull-down resistor."   */
00074 /*  Better to set the pins to pull-up mode and the  */
00075 /*  switch connected to GND.                        */
00076 
00077 /* For debug pins */
00078 DigitalOut  dbg_p21(p21);
00079 DigitalOut  dbg_p22(p22);
00080 DigitalOut  dbg_led1(LED1);
00081 DigitalOut  dbg_led2(LED2);
00082 
00083 /* Variables */
00084 int32_t wav_dec_cntr;                   /* Decimation counter */
00085 
00086 uint8_t wav_pkt_buf[WAV_BUF_NUM][PACKET_SIZE];  /* Waveform packet buffer */
00087 int32_t wav_pkt_idx;                    /* Packet buffer index */
00088 int32_t wav_tgl;                        /* Packet buffer toggle */
00089 int32_t wav_send_flag;                  /* Waveform sending flag */
00090 uint8_t wav_pkt_cntr;                   /* Waveform packet counter */
00091 
00092 float fft_buf[FFT_BUF_NUM][FFT_LENGTH]; /* FFT data buffer */
00093 uint8_t pkt_buf_fft[PACKET_SIZE] = {0}; /* FFT packet buffer */
00094 int32_t fft_dat_idx;                    /* FFT buffer index */
00095 int32_t fft_tgl;                        /* FFT buffer toggle */
00096 int32_t fft_send_flag;                  /* FFT sendign flag */
00097 
00098 float fft_out_re[FFT_LENGTH] = {0.0f};  /* FFT result real */
00099 float fft_out_im[FFT_LENGTH] = {0.0f};  /* FFT result imaginary */
00100 uint16_t fft_res[FFT_SEND_LEN] = {0};   /* FFT result */
00101 
00102 /** Initialize waveform packet buffer
00103  *  @param      tgl    buffer wav_tgl index
00104  *  @param      ctr    packet counter
00105  */
00106 void init_wav_pkt_buf(int32_t tgl, uint8_t ctr)
00107 {
00108     int i;
00109     if(tgl>WAV_BUF_NUM) {
00110         return;
00111     }
00112     wav_pkt_buf[tgl][0] = PACKET_HEADER;
00113     wav_pkt_buf[tgl][1] = WAVEFORM_ID;
00114     wav_pkt_buf[tgl][2] = ctr;              /* Packet counter */
00115     wav_pkt_buf[tgl][3] = PAYLOAD_SIZE;     /* Payload size */
00116     wav_pkt_idx = 4;                        /* Start index of waveform */
00117     for(i=4; i<PACKET_SIZE; i++) {
00118         wav_pkt_buf[tgl][i] = 0;
00119     }
00120 }
00121 
00122 /** Set FFT packet buffer
00123  *  @param      buf    Source data buffer
00124  *  @param      ctr    packet counter
00125  */
00126 void set_fft_pkt_buf(uint16_t* buf, uint8_t ctr)
00127 {
00128     int i;
00129     pkt_buf_fft[0] = PACKET_HEADER;
00130     pkt_buf_fft[1] = FFT_ID;
00131     pkt_buf_fft[2] = ctr;              /* Packet counter */
00132     pkt_buf_fft[3] = PAYLOAD_SIZE;     /* Payload size */
00133     i=0;
00134     while(i<PAYLOAD_SIZE) {
00135         pkt_buf_fft[i + 4] = (uint8_t)((buf[i / 2] >> 8 ) & BYTE_MASK);
00136         i++;
00137         pkt_buf_fft[i + 4] = (uint8_t)(buf[i / 2] & BYTE_MASK);
00138         i++;
00139     }
00140 }
00141 
00142 /** Interval timer for read A/D value
00143  */
00144 void ad_sampling()
00145 {
00146     int32_t wav_temp;
00147     dbg_led2 = lpf_on;  /* for debug */
00148 
00149     /* Read and filter data */
00150     wav_temp = (int32_t)filter.calc( (double)(wave_in.read_u16() - INT16_MAX), hpf_on, lpf_on, brf_on );
00151 
00152     /* Store data */
00153     wav_dec_cntr = (wav_dec_cntr + 1) % DEC_COUNT;
00154     if(wav_dec_cntr == 0) { /* Decimation */
00155 
00156         dbg_p21 = ON;  /* for debug */
00157         /* Waveform */
00158         wav_temp = (wav_temp > INT16_MAX) ? INT16_MAX : wav_temp;
00159         wav_temp = (wav_temp < INT16_MIN) ? INT16_MIN : wav_temp;
00160         wav_pkt_buf[wav_tgl][wav_pkt_idx] = (uint8_t)((wav_temp >> 8 ) & BYTE_MASK);
00161         wav_pkt_idx++;
00162         wav_pkt_buf[wav_tgl][wav_pkt_idx] = (uint8_t)(wav_temp & BYTE_MASK);
00163         wav_pkt_idx++;
00164 
00165         if(wav_pkt_idx >= PACKET_SIZE) {    /* Counter reached */
00166             wav_tgl = !wav_tgl;
00167             wav_pkt_cntr = (wav_pkt_cntr + 1 ) % WV_PKT_CNTR_NUM;
00168             init_wav_pkt_buf(wav_tgl, wav_pkt_cntr);
00169             wav_send_flag = ON;          /* Set flag */
00170         }
00171 
00172         /* FFT */
00173         fft_buf[fft_tgl][fft_dat_idx + FFT_OVERLAP_LEN] = (float)wav_temp;
00174         if(fft_dat_idx >= (FFT_INTERVAL - FFT_OVERLAP_LEN)) {
00175             fft_buf[!fft_tgl][fft_dat_idx + FFT_OVERLAP_LEN - FFT_INTERVAL] = (float)wav_temp;
00176         }
00177 
00178         fft_dat_idx = (fft_dat_idx + 1) % FFT_INTERVAL;
00179         if(fft_dat_idx == 0) {
00180             fft_tgl = !fft_tgl;
00181             fft_send_flag = ON;          /* Set flag */
00182         }
00183 
00184         dbg_p21 = OFF; /* for debug */
00185     }
00186 }
00187 
00188 /** Send data packet
00189  *  @param      p_buf   Data array
00190  *  @param      size    Data length
00191  */
00192 bool send_packet(uint8_t *p_buf, uint16_t size)
00193 {
00194     if(serial.writeable()) {
00195         dbg_p22 = ON;   /* for debug */
00196         serial.writeBlock (p_buf, size);    /* Send data via USB */
00197         dbg_p22 = OFF;  /* for debug */
00198         return true;
00199     } else {
00200         return false;
00201     }
00202 }
00203 
00204 /** Main function
00205  */
00206 int main()
00207 {
00208     int i;
00209     uint16_t fft_temp;
00210 
00211     /* Initialization */
00212     wav_dec_cntr = 0;
00213 
00214     init_wav_pkt_buf(wav_tgl, wav_pkt_cntr);
00215     init_wav_pkt_buf(!wav_tgl, wav_pkt_cntr);
00216     wav_pkt_idx = 0;
00217     wav_tgl = 0;
00218     wav_send_flag = OFF;
00219     wav_pkt_cntr = 0;
00220 
00221     fft_dat_idx = 0;
00222     fft_tgl = 0;
00223     fft_send_flag = OFF;
00224 
00225     dbg_p21 = OFF;
00226     dbg_p22 = OFF;
00227     dbg_led1 = LED_OFF;
00228     dbg_led2 = LED_OFF;
00229 
00230     /* Start interval timer */
00231     sampling.attach(&ad_sampling, SAMPLING_RATE);
00232 
00233     /* Main loop */
00234     while(1) {
00235         /* Waveform */
00236         if(wav_send_flag != OFF) {
00237             /* Send data */
00238             send_packet(wav_pkt_buf[!wav_tgl], (uint16_t)PACKET_SIZE);
00239 
00240             /* Disable interrupt */
00241             __disable_irq();
00242             wav_send_flag = OFF;    /* Clear flag */
00243             __enable_irq();
00244         }
00245 
00246         /* FFT */
00247         if(fft_send_flag != OFF) {
00248             dbg_led1 = LED_ON;      /* for debug */
00249 
00250             /* Calculate FFT and normalized amplitude spectrum */
00251             fft.apply_window(fft_buf[!fft_tgl], fft_buf[!fft_tgl]);
00252             fft.calc_fft(fft_buf[!fft_tgl], fft_out_re, fft_out_im);
00253             fft.calc_power(fft_out_re, fft_out_im, fft_out_re, FFT_SEND_LEN);
00254             fft.calc_amplitude(fft_out_re, fft_out_re, FFT_SEND_LEN);
00255             fft.norm_amplitude(fft_out_re, FFT_SEND_LEN);
00256             for(i=0; i<FFT_SEND_LEN; i++) {
00257                 fft_temp = (fft_out_re[i] > UINT16_MAX) ? UINT16_MAX : (uint16_t)fft_out_re[i];
00258                 fft_temp = (fft_out_re[i] < UINT16_MIN) ? UINT16_MIN : fft_temp;
00259                 fft_res[i] = fft_temp;
00260             }
00261 
00262             /* Send data */
00263             i=0;
00264             while((PAYLOAD_SIZE * i) < FFT_SEND_LEN * sizeof(fft_res[0])) {
00265                 set_fft_pkt_buf((fft_res + (PAYLOAD_SIZE/sizeof(fft_res[0])) * i), i);
00266                 send_packet(pkt_buf_fft, (uint16_t)PACKET_SIZE);
00267                 i++;
00268             }
00269 
00270             /* Disable interrupt */
00271             __disable_irq();
00272             fft_send_flag = OFF;    /* Clear flag */
00273             __enable_irq();
00274 
00275             dbg_led1 = LED_OFF;      /* for debug */
00276         }
00277     }
00278 }