Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
reference.txt@0:166e0710d217, 2017-01-27 (annotated)
- Committer:
- kenjiArai
- Date:
- Fri Jan 27 04:07:01 2017 +0000
- Revision:
- 0:166e0710d217
Morse code (CW) decoder program. Original source is made by Hjalmar Skovholm Hansen OZ1JHM. The program uses the Goertzel Algorithm.
;
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| kenjiArai | 0:166e0710d217 | 1 | //--------------------------------------------------------------------------------------------------------------------------------------------------- |
| kenjiArai | 0:166e0710d217 | 2 | // http://www.skovholm.com/decoder11.ino |
| kenjiArai | 0:166e0710d217 | 3 | //--------------------------------------------------------------------------------------------------------------------------------------------------- |
| kenjiArai | 0:166e0710d217 | 4 | |
| kenjiArai | 0:166e0710d217 | 5 | /////////////////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 6 | // CW Decoder made by Hjalmar Skovholm Hansen OZ1JHM VER 1.01 // |
| kenjiArai | 0:166e0710d217 | 7 | // Feel free to change, copy or what ever you like but respect // |
| kenjiArai | 0:166e0710d217 | 8 | // that license is http://www.gnu.org/copyleft/gpl.html // |
| kenjiArai | 0:166e0710d217 | 9 | // Discuss and give great ideas on // |
| kenjiArai | 0:166e0710d217 | 10 | // https://groups.yahoo.com/neo/groups/oz1jhm/conversations/messages // |
| kenjiArai | 0:166e0710d217 | 11 | /////////////////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 12 | |
| kenjiArai | 0:166e0710d217 | 13 | /////////////////////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 14 | // Read more here http://en.wikipedia.org/wiki/Goertzel_algorithm // |
| kenjiArai | 0:166e0710d217 | 15 | // if you want to know about FFT the http://www.dspguide.com/pdfbook.htm // |
| kenjiArai | 0:166e0710d217 | 16 | /////////////////////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 17 | |
| kenjiArai | 0:166e0710d217 | 18 | #include <LiquidCrystal.h> |
| kenjiArai | 0:166e0710d217 | 19 | |
| kenjiArai | 0:166e0710d217 | 20 | /////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 21 | // select the pins used on the LCD panel / |
| kenjiArai | 0:166e0710d217 | 22 | /////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 23 | // LiquidCrystal lcd(RS, E, D4, D5, D6, D7) // |
| kenjiArai | 0:166e0710d217 | 24 | /////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 25 | |
| kenjiArai | 0:166e0710d217 | 26 | LiquidCrystal lcd(12, 11, 5, 4, 3, 2); |
| kenjiArai | 0:166e0710d217 | 27 | |
| kenjiArai | 0:166e0710d217 | 28 | const int colums = 20; /// have to be 16 or 20 |
| kenjiArai | 0:166e0710d217 | 29 | const int rows = 4; /// have to be 2 or 4 |
| kenjiArai | 0:166e0710d217 | 30 | |
| kenjiArai | 0:166e0710d217 | 31 | int lcdindex = 0; |
| kenjiArai | 0:166e0710d217 | 32 | int line1[colums]; |
| kenjiArai | 0:166e0710d217 | 33 | int line2[colums]; |
| kenjiArai | 0:166e0710d217 | 34 | |
| kenjiArai | 0:166e0710d217 | 35 | //////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 36 | // Define 8 specials letters // |
| kenjiArai | 0:166e0710d217 | 37 | //////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 38 | |
| kenjiArai | 0:166e0710d217 | 39 | byte U_umlaut[8] = {B01010,B00000,B10001,B10001,B10001,B10001,B01110,B00000}; // 'ワ' |
| kenjiArai | 0:166e0710d217 | 40 | byte O_umlaut[8] = {B01010,B00000,B01110,B10001,B10001,B10001,B01110,B00000}; // 'ヨ' |
| kenjiArai | 0:166e0710d217 | 41 | byte A_umlaut[8] = {B01010,B00000,B01110,B10001,B11111,B10001,B10001,B00000}; // 'ト' |
| kenjiArai | 0:166e0710d217 | 42 | byte AE_capital[8] = {B01111,B10100,B10100,B11110,B10100,B10100,B10111,B00000}; // 'ニ' |
| kenjiArai | 0:166e0710d217 | 43 | byte OE_capital[8] = {B00001,B01110,B10011,B10101,B11001,B01110,B10000,B00000}; // 'リ' |
| kenjiArai | 0:166e0710d217 | 44 | byte fullblock[8] = {B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111}; |
| kenjiArai | 0:166e0710d217 | 45 | byte AA_capital[8] = {B00100,B00000,B01110,B10001,B11111,B10001,B10001,B00000}; // 'ナ' |
| kenjiArai | 0:166e0710d217 | 46 | byte emtyblock[8] = {B00000,B00000,B00000,B00000,B00000,B00000,B00000,B00000}; |
| kenjiArai | 0:166e0710d217 | 47 | |
| kenjiArai | 0:166e0710d217 | 48 | int audioInPin = A1; |
| kenjiArai | 0:166e0710d217 | 49 | int audioOutPin = 10; |
| kenjiArai | 0:166e0710d217 | 50 | int ledPin = 13; |
| kenjiArai | 0:166e0710d217 | 51 | |
| kenjiArai | 0:166e0710d217 | 52 | float magnitude ; |
| kenjiArai | 0:166e0710d217 | 53 | int magnitudelimit = 100; |
| kenjiArai | 0:166e0710d217 | 54 | int magnitudelimit_low = 100; |
| kenjiArai | 0:166e0710d217 | 55 | int realstate = LOW; |
| kenjiArai | 0:166e0710d217 | 56 | int realstatebefore = LOW; |
| kenjiArai | 0:166e0710d217 | 57 | int filteredstate = LOW; |
| kenjiArai | 0:166e0710d217 | 58 | int filteredstatebefore = LOW; |
| kenjiArai | 0:166e0710d217 | 59 | |
| kenjiArai | 0:166e0710d217 | 60 | |
| kenjiArai | 0:166e0710d217 | 61 | /////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 62 | // The sampling frq will be 8928 on a 16 mhz // |
| kenjiArai | 0:166e0710d217 | 63 | // without any prescaler etc // |
| kenjiArai | 0:166e0710d217 | 64 | // because we need the tone in the center of the bins // |
| kenjiArai | 0:166e0710d217 | 65 | // you can set the tone to 496, 558, 744 or 992 // |
| kenjiArai | 0:166e0710d217 | 66 | // then n the number of samples which give the bandwidth // |
| kenjiArai | 0:166e0710d217 | 67 | // can be (8928 / tone) * 1 or 2 or 3 or 4 etc // |
| kenjiArai | 0:166e0710d217 | 68 | // init is 8928/558 = 16 *4 = 64 samples // |
| kenjiArai | 0:166e0710d217 | 69 | // try to take n = 96 or 128 ;o) // |
| kenjiArai | 0:166e0710d217 | 70 | // 48 will give you a bandwidth around 186 hz // |
| kenjiArai | 0:166e0710d217 | 71 | // 64 will give you a bandwidth around 140 hz // |
| kenjiArai | 0:166e0710d217 | 72 | // 96 will give you a bandwidth around 94 hz // |
| kenjiArai | 0:166e0710d217 | 73 | // 128 will give you a bandwidth around 70 hz // |
| kenjiArai | 0:166e0710d217 | 74 | // BUT remember that high n take a lot of time // |
| kenjiArai | 0:166e0710d217 | 75 | // so you have to find the compromice - i use 48 // |
| kenjiArai | 0:166e0710d217 | 76 | /////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 77 | |
| kenjiArai | 0:166e0710d217 | 78 | float coeff; |
| kenjiArai | 0:166e0710d217 | 79 | float Q1 = 0; |
| kenjiArai | 0:166e0710d217 | 80 | float Q2 = 0; |
| kenjiArai | 0:166e0710d217 | 81 | float sine; |
| kenjiArai | 0:166e0710d217 | 82 | float cosine; |
| kenjiArai | 0:166e0710d217 | 83 | float sampling_freq=8928.0; |
| kenjiArai | 0:166e0710d217 | 84 | float target_freq=558.0; /// adjust for your needs see above |
| kenjiArai | 0:166e0710d217 | 85 | float n=48.0; //// if you change her please change next line also |
| kenjiArai | 0:166e0710d217 | 86 | int testData[48]; |
| kenjiArai | 0:166e0710d217 | 87 | |
| kenjiArai | 0:166e0710d217 | 88 | ////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 89 | // Noise Blanker time which // |
| kenjiArai | 0:166e0710d217 | 90 | // shall be computed so // |
| kenjiArai | 0:166e0710d217 | 91 | // this is initial // |
| kenjiArai | 0:166e0710d217 | 92 | ////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 93 | int nbtime = 6; /// ms noise blanker |
| kenjiArai | 0:166e0710d217 | 94 | |
| kenjiArai | 0:166e0710d217 | 95 | long starttimehigh; |
| kenjiArai | 0:166e0710d217 | 96 | long highduration; |
| kenjiArai | 0:166e0710d217 | 97 | long lasthighduration; |
| kenjiArai | 0:166e0710d217 | 98 | long hightimesavg; |
| kenjiArai | 0:166e0710d217 | 99 | long lowtimesavg; |
| kenjiArai | 0:166e0710d217 | 100 | long startttimelow; |
| kenjiArai | 0:166e0710d217 | 101 | long lowduration; |
| kenjiArai | 0:166e0710d217 | 102 | long laststarttime = 0; |
| kenjiArai | 0:166e0710d217 | 103 | |
| kenjiArai | 0:166e0710d217 | 104 | char code[20]; |
| kenjiArai | 0:166e0710d217 | 105 | int stop = LOW; |
| kenjiArai | 0:166e0710d217 | 106 | int wpm; |
| kenjiArai | 0:166e0710d217 | 107 | |
| kenjiArai | 0:166e0710d217 | 108 | |
| kenjiArai | 0:166e0710d217 | 109 | //////////////// |
| kenjiArai | 0:166e0710d217 | 110 | // init setup // |
| kenjiArai | 0:166e0710d217 | 111 | //////////////// |
| kenjiArai | 0:166e0710d217 | 112 | void setup() { |
| kenjiArai | 0:166e0710d217 | 113 | |
| kenjiArai | 0:166e0710d217 | 114 | //////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 115 | // The basic goertzel calculation // |
| kenjiArai | 0:166e0710d217 | 116 | //////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 117 | int k; |
| kenjiArai | 0:166e0710d217 | 118 | float omega; |
| kenjiArai | 0:166e0710d217 | 119 | k = (int) (0.5 + ((n * target_freq) / sampling_freq)); |
| kenjiArai | 0:166e0710d217 | 120 | omega = (2.0 * PI * k) / n; |
| kenjiArai | 0:166e0710d217 | 121 | sine = sin(omega); |
| kenjiArai | 0:166e0710d217 | 122 | cosine = cos(omega); |
| kenjiArai | 0:166e0710d217 | 123 | coeff = 2.0 * cosine; |
| kenjiArai | 0:166e0710d217 | 124 | |
| kenjiArai | 0:166e0710d217 | 125 | /////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 126 | // define special characters // |
| kenjiArai | 0:166e0710d217 | 127 | /////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 128 | lcd.createChar(0, U_umlaut); // German |
| kenjiArai | 0:166e0710d217 | 129 | lcd.createChar(1, O_umlaut); // German, Swedish |
| kenjiArai | 0:166e0710d217 | 130 | lcd.createChar(2, A_umlaut); // German, Swedish |
| kenjiArai | 0:166e0710d217 | 131 | lcd.createChar(3, AE_capital); // Danish, Norwegian |
| kenjiArai | 0:166e0710d217 | 132 | lcd.createChar(4, OE_capital); // Danish, Norwegian |
| kenjiArai | 0:166e0710d217 | 133 | lcd.createChar(5, fullblock); |
| kenjiArai | 0:166e0710d217 | 134 | lcd.createChar(6, AA_capital); // Danish, Norwegian, Swedish |
| kenjiArai | 0:166e0710d217 | 135 | lcd.createChar(7, emtyblock); |
| kenjiArai | 0:166e0710d217 | 136 | lcd.clear(); |
| kenjiArai | 0:166e0710d217 | 137 | |
| kenjiArai | 0:166e0710d217 | 138 | Serial.begin(115200); |
| kenjiArai | 0:166e0710d217 | 139 | pinMode(ledPin, OUTPUT); |
| kenjiArai | 0:166e0710d217 | 140 | lcd.begin(colums, rows); |
| kenjiArai | 0:166e0710d217 | 141 | for (int index = 0; index < colums; index++){ |
| kenjiArai | 0:166e0710d217 | 142 | line1[index] = 32; |
| kenjiArai | 0:166e0710d217 | 143 | line2[index] = 32; |
| kenjiArai | 0:166e0710d217 | 144 | } |
| kenjiArai | 0:166e0710d217 | 145 | |
| kenjiArai | 0:166e0710d217 | 146 | } |
| kenjiArai | 0:166e0710d217 | 147 | |
| kenjiArai | 0:166e0710d217 | 148 | /////////////// |
| kenjiArai | 0:166e0710d217 | 149 | // main loop // |
| kenjiArai | 0:166e0710d217 | 150 | /////////////// |
| kenjiArai | 0:166e0710d217 | 151 | void loop() { |
| kenjiArai | 0:166e0710d217 | 152 | |
| kenjiArai | 0:166e0710d217 | 153 | ///////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 154 | // The basic where we get the tone // |
| kenjiArai | 0:166e0710d217 | 155 | ///////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 156 | |
| kenjiArai | 0:166e0710d217 | 157 | for (char index = 0; index < n; index++) |
| kenjiArai | 0:166e0710d217 | 158 | { |
| kenjiArai | 0:166e0710d217 | 159 | testData[index] = analogRead(audioInPin); |
| kenjiArai | 0:166e0710d217 | 160 | } |
| kenjiArai | 0:166e0710d217 | 161 | for (char index = 0; index < n; index++){ |
| kenjiArai | 0:166e0710d217 | 162 | float Q0; |
| kenjiArai | 0:166e0710d217 | 163 | Q0 = coeff * Q1 - Q2 + (float) testData[index]; |
| kenjiArai | 0:166e0710d217 | 164 | Q2 = Q1; |
| kenjiArai | 0:166e0710d217 | 165 | Q1 = Q0; |
| kenjiArai | 0:166e0710d217 | 166 | } |
| kenjiArai | 0:166e0710d217 | 167 | float magnitudeSquared = (Q1*Q1)+(Q2*Q2)-Q1*Q2*coeff; // we do only need the real part // |
| kenjiArai | 0:166e0710d217 | 168 | magnitude = sqrt(magnitudeSquared); |
| kenjiArai | 0:166e0710d217 | 169 | Q2 = 0; |
| kenjiArai | 0:166e0710d217 | 170 | Q1 = 0; |
| kenjiArai | 0:166e0710d217 | 171 | |
| kenjiArai | 0:166e0710d217 | 172 | //Serial.print(magnitude); Serial.println(); //// here you can measure magnitude for setup.. |
| kenjiArai | 0:166e0710d217 | 173 | |
| kenjiArai | 0:166e0710d217 | 174 | /////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 175 | // here we will try to set the magnitude limit automatic // |
| kenjiArai | 0:166e0710d217 | 176 | /////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 177 | |
| kenjiArai | 0:166e0710d217 | 178 | if (magnitude > magnitudelimit_low){ |
| kenjiArai | 0:166e0710d217 | 179 | magnitudelimit = (magnitudelimit +((magnitude - magnitudelimit)/6)); /// moving average filter |
| kenjiArai | 0:166e0710d217 | 180 | } |
| kenjiArai | 0:166e0710d217 | 181 | |
| kenjiArai | 0:166e0710d217 | 182 | if (magnitudelimit < magnitudelimit_low) |
| kenjiArai | 0:166e0710d217 | 183 | magnitudelimit = magnitudelimit_low; |
| kenjiArai | 0:166e0710d217 | 184 | |
| kenjiArai | 0:166e0710d217 | 185 | //////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 186 | // now we check for the magnitude // |
| kenjiArai | 0:166e0710d217 | 187 | //////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 188 | |
| kenjiArai | 0:166e0710d217 | 189 | if(magnitude > magnitudelimit*0.6) // just to have some space up |
| kenjiArai | 0:166e0710d217 | 190 | realstate = HIGH; |
| kenjiArai | 0:166e0710d217 | 191 | else |
| kenjiArai | 0:166e0710d217 | 192 | realstate = LOW; |
| kenjiArai | 0:166e0710d217 | 193 | |
| kenjiArai | 0:166e0710d217 | 194 | ///////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 195 | // here we clean up the state with a noise blanker // |
| kenjiArai | 0:166e0710d217 | 196 | ///////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 197 | |
| kenjiArai | 0:166e0710d217 | 198 | if (realstate != realstatebefore){ |
| kenjiArai | 0:166e0710d217 | 199 | laststarttime = millis(); |
| kenjiArai | 0:166e0710d217 | 200 | } |
| kenjiArai | 0:166e0710d217 | 201 | if ((millis()-laststarttime)> nbtime){ |
| kenjiArai | 0:166e0710d217 | 202 | if (realstate != filteredstate){ |
| kenjiArai | 0:166e0710d217 | 203 | filteredstate = realstate; |
| kenjiArai | 0:166e0710d217 | 204 | } |
| kenjiArai | 0:166e0710d217 | 205 | } |
| kenjiArai | 0:166e0710d217 | 206 | |
| kenjiArai | 0:166e0710d217 | 207 | //////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 208 | // Then we do want to have some durations on high and low // |
| kenjiArai | 0:166e0710d217 | 209 | //////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 210 | |
| kenjiArai | 0:166e0710d217 | 211 | if (filteredstate != filteredstatebefore){ |
| kenjiArai | 0:166e0710d217 | 212 | if (filteredstate == HIGH){ |
| kenjiArai | 0:166e0710d217 | 213 | starttimehigh = millis(); |
| kenjiArai | 0:166e0710d217 | 214 | lowduration = (millis() - startttimelow); |
| kenjiArai | 0:166e0710d217 | 215 | } |
| kenjiArai | 0:166e0710d217 | 216 | |
| kenjiArai | 0:166e0710d217 | 217 | if (filteredstate == LOW){ |
| kenjiArai | 0:166e0710d217 | 218 | startttimelow = millis(); |
| kenjiArai | 0:166e0710d217 | 219 | highduration = (millis() - starttimehigh); |
| kenjiArai | 0:166e0710d217 | 220 | if (highduration < (2*hightimesavg) || hightimesavg == 0){ |
| kenjiArai | 0:166e0710d217 | 221 | hightimesavg = (highduration+hightimesavg+hightimesavg)/3; // now we know avg dit time ( rolling 3 avg) |
| kenjiArai | 0:166e0710d217 | 222 | } |
| kenjiArai | 0:166e0710d217 | 223 | if (highduration > (5*hightimesavg) ){ |
| kenjiArai | 0:166e0710d217 | 224 | hightimesavg = highduration+hightimesavg; // if speed decrease fast .. |
| kenjiArai | 0:166e0710d217 | 225 | } |
| kenjiArai | 0:166e0710d217 | 226 | } |
| kenjiArai | 0:166e0710d217 | 227 | } |
| kenjiArai | 0:166e0710d217 | 228 | |
| kenjiArai | 0:166e0710d217 | 229 | /////////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 230 | // now we will check which kind of baud we have - dit or dah // |
| kenjiArai | 0:166e0710d217 | 231 | // and what kind of pause we do have 1 - 3 or 7 pause // |
| kenjiArai | 0:166e0710d217 | 232 | // we think that hightimeavg = 1 bit // |
| kenjiArai | 0:166e0710d217 | 233 | /////////////////////////////////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 234 | |
| kenjiArai | 0:166e0710d217 | 235 | if (filteredstate != filteredstatebefore){ |
| kenjiArai | 0:166e0710d217 | 236 | stop = LOW; |
| kenjiArai | 0:166e0710d217 | 237 | if (filteredstate == LOW){ //// we did end a HIGH |
| kenjiArai | 0:166e0710d217 | 238 | if (highduration < (hightimesavg*2) && highduration > (hightimesavg*0.6)){ /// 0.6 filter out false dits |
| kenjiArai | 0:166e0710d217 | 239 | strcat(code,"."); |
| kenjiArai | 0:166e0710d217 | 240 | Serial.print("."); |
| kenjiArai | 0:166e0710d217 | 241 | } |
| kenjiArai | 0:166e0710d217 | 242 | if (highduration > (hightimesavg*2) && highduration < (hightimesavg*6)){ |
| kenjiArai | 0:166e0710d217 | 243 | strcat(code,"-"); |
| kenjiArai | 0:166e0710d217 | 244 | Serial.print("-"); |
| kenjiArai | 0:166e0710d217 | 245 | wpm = (wpm + (1200/((highduration)/3)))/2; //// the most precise we can do ;o) |
| kenjiArai | 0:166e0710d217 | 246 | } |
| kenjiArai | 0:166e0710d217 | 247 | } |
| kenjiArai | 0:166e0710d217 | 248 | |
| kenjiArai | 0:166e0710d217 | 249 | if (filteredstate == HIGH){ //// we did end a LOW |
| kenjiArai | 0:166e0710d217 | 250 | |
| kenjiArai | 0:166e0710d217 | 251 | float lacktime = 1; |
| kenjiArai | 0:166e0710d217 | 252 | if(wpm > 25)lacktime=1.0; /// when high speeds we have to have a little more pause before new letter or new word |
| kenjiArai | 0:166e0710d217 | 253 | if(wpm > 30)lacktime=1.2; |
| kenjiArai | 0:166e0710d217 | 254 | if(wpm > 35)lacktime=1.5; |
| kenjiArai | 0:166e0710d217 | 255 | |
| kenjiArai | 0:166e0710d217 | 256 | if (lowduration > (hightimesavg*(2*lacktime)) && lowduration < hightimesavg*(5*lacktime)){ // letter space |
| kenjiArai | 0:166e0710d217 | 257 | docode(); |
| kenjiArai | 0:166e0710d217 | 258 | code[0] = '\0'; |
| kenjiArai | 0:166e0710d217 | 259 | Serial.print("/"); |
| kenjiArai | 0:166e0710d217 | 260 | } |
| kenjiArai | 0:166e0710d217 | 261 | if (lowduration >= hightimesavg*(5*lacktime)){ // word space |
| kenjiArai | 0:166e0710d217 | 262 | docode(); |
| kenjiArai | 0:166e0710d217 | 263 | code[0] = '\0'; |
| kenjiArai | 0:166e0710d217 | 264 | printascii(32); |
| kenjiArai | 0:166e0710d217 | 265 | Serial.println(); |
| kenjiArai | 0:166e0710d217 | 266 | } |
| kenjiArai | 0:166e0710d217 | 267 | } |
| kenjiArai | 0:166e0710d217 | 268 | } |
| kenjiArai | 0:166e0710d217 | 269 | |
| kenjiArai | 0:166e0710d217 | 270 | ////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 271 | // write if no more letters // |
| kenjiArai | 0:166e0710d217 | 272 | ////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 273 | |
| kenjiArai | 0:166e0710d217 | 274 | if ((millis() - startttimelow) > (highduration * 6) && stop == LOW){ |
| kenjiArai | 0:166e0710d217 | 275 | docode(); |
| kenjiArai | 0:166e0710d217 | 276 | code[0] = '\0'; |
| kenjiArai | 0:166e0710d217 | 277 | stop = HIGH; |
| kenjiArai | 0:166e0710d217 | 278 | } |
| kenjiArai | 0:166e0710d217 | 279 | |
| kenjiArai | 0:166e0710d217 | 280 | ///////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 281 | // we will turn on and off the LED // |
| kenjiArai | 0:166e0710d217 | 282 | // and the speaker // |
| kenjiArai | 0:166e0710d217 | 283 | ///////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 284 | |
| kenjiArai | 0:166e0710d217 | 285 | if(filteredstate == HIGH){ |
| kenjiArai | 0:166e0710d217 | 286 | digitalWrite(ledPin, HIGH); |
| kenjiArai | 0:166e0710d217 | 287 | tone(audioOutPin,target_freq); |
| kenjiArai | 0:166e0710d217 | 288 | } |
| kenjiArai | 0:166e0710d217 | 289 | else{ |
| kenjiArai | 0:166e0710d217 | 290 | digitalWrite(ledPin, LOW); |
| kenjiArai | 0:166e0710d217 | 291 | noTone(audioOutPin); |
| kenjiArai | 0:166e0710d217 | 292 | } |
| kenjiArai | 0:166e0710d217 | 293 | |
| kenjiArai | 0:166e0710d217 | 294 | ////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 295 | // the end of main loop clean up// |
| kenjiArai | 0:166e0710d217 | 296 | ///////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 297 | updateinfolinelcd(); |
| kenjiArai | 0:166e0710d217 | 298 | realstatebefore = realstate; |
| kenjiArai | 0:166e0710d217 | 299 | lasthighduration = highduration; |
| kenjiArai | 0:166e0710d217 | 300 | filteredstatebefore = filteredstate; |
| kenjiArai | 0:166e0710d217 | 301 | } |
| kenjiArai | 0:166e0710d217 | 302 | |
| kenjiArai | 0:166e0710d217 | 303 | |
| kenjiArai | 0:166e0710d217 | 304 | //////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 305 | // translate cw code to ascii // |
| kenjiArai | 0:166e0710d217 | 306 | //////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 307 | |
| kenjiArai | 0:166e0710d217 | 308 | void docode(){ |
| kenjiArai | 0:166e0710d217 | 309 | if (strcmp(code,".-") == 0) printascii(65); |
| kenjiArai | 0:166e0710d217 | 310 | if (strcmp(code,"-...") == 0) printascii(66); |
| kenjiArai | 0:166e0710d217 | 311 | if (strcmp(code,"-.-.") == 0) printascii(67); |
| kenjiArai | 0:166e0710d217 | 312 | if (strcmp(code,"-..") == 0) printascii(68); |
| kenjiArai | 0:166e0710d217 | 313 | if (strcmp(code,".") == 0) printascii(69); |
| kenjiArai | 0:166e0710d217 | 314 | if (strcmp(code,"..-.") == 0) printascii(70); |
| kenjiArai | 0:166e0710d217 | 315 | if (strcmp(code,"--.") == 0) printascii(71); |
| kenjiArai | 0:166e0710d217 | 316 | if (strcmp(code,"....") == 0) printascii(72); |
| kenjiArai | 0:166e0710d217 | 317 | if (strcmp(code,"..") == 0) printascii(73); |
| kenjiArai | 0:166e0710d217 | 318 | if (strcmp(code,".---") == 0) printascii(74); |
| kenjiArai | 0:166e0710d217 | 319 | if (strcmp(code,"-.-") == 0) printascii(75); |
| kenjiArai | 0:166e0710d217 | 320 | if (strcmp(code,".-..") == 0) printascii(76); |
| kenjiArai | 0:166e0710d217 | 321 | if (strcmp(code,"--") == 0) printascii(77); |
| kenjiArai | 0:166e0710d217 | 322 | if (strcmp(code,"-.") == 0) printascii(78); |
| kenjiArai | 0:166e0710d217 | 323 | if (strcmp(code,"---") == 0) printascii(79); |
| kenjiArai | 0:166e0710d217 | 324 | if (strcmp(code,".--.") == 0) printascii(80); |
| kenjiArai | 0:166e0710d217 | 325 | if (strcmp(code,"--.-") == 0) printascii(81); |
| kenjiArai | 0:166e0710d217 | 326 | if (strcmp(code,".-.") == 0) printascii(82); |
| kenjiArai | 0:166e0710d217 | 327 | if (strcmp(code,"...") == 0) printascii(83); |
| kenjiArai | 0:166e0710d217 | 328 | if (strcmp(code,"-") == 0) printascii(84); |
| kenjiArai | 0:166e0710d217 | 329 | if (strcmp(code,"..-") == 0) printascii(85); |
| kenjiArai | 0:166e0710d217 | 330 | if (strcmp(code,"...-") == 0) printascii(86); |
| kenjiArai | 0:166e0710d217 | 331 | if (strcmp(code,".--") == 0) printascii(87); |
| kenjiArai | 0:166e0710d217 | 332 | if (strcmp(code,"-..-") == 0) printascii(88); |
| kenjiArai | 0:166e0710d217 | 333 | if (strcmp(code,"-.--") == 0) printascii(89); |
| kenjiArai | 0:166e0710d217 | 334 | if (strcmp(code,"--..") == 0) printascii(90); |
| kenjiArai | 0:166e0710d217 | 335 | |
| kenjiArai | 0:166e0710d217 | 336 | if (strcmp(code,".----") == 0) printascii(49); |
| kenjiArai | 0:166e0710d217 | 337 | if (strcmp(code,"..---") == 0) printascii(50); |
| kenjiArai | 0:166e0710d217 | 338 | if (strcmp(code,"...--") == 0) printascii(51); |
| kenjiArai | 0:166e0710d217 | 339 | if (strcmp(code,"....-") == 0) printascii(52); |
| kenjiArai | 0:166e0710d217 | 340 | if (strcmp(code,".....") == 0) printascii(53); |
| kenjiArai | 0:166e0710d217 | 341 | if (strcmp(code,"-....") == 0) printascii(54); |
| kenjiArai | 0:166e0710d217 | 342 | if (strcmp(code,"--...") == 0) printascii(55); |
| kenjiArai | 0:166e0710d217 | 343 | if (strcmp(code,"---..") == 0) printascii(56); |
| kenjiArai | 0:166e0710d217 | 344 | if (strcmp(code,"----.") == 0) printascii(57); |
| kenjiArai | 0:166e0710d217 | 345 | if (strcmp(code,"-----") == 0) printascii(48); |
| kenjiArai | 0:166e0710d217 | 346 | |
| kenjiArai | 0:166e0710d217 | 347 | if (strcmp(code,"..--..") == 0) printascii(63); |
| kenjiArai | 0:166e0710d217 | 348 | if (strcmp(code,".-.-.-") == 0) printascii(46); |
| kenjiArai | 0:166e0710d217 | 349 | if (strcmp(code,"--..--") == 0) printascii(44); |
| kenjiArai | 0:166e0710d217 | 350 | if (strcmp(code,"-.-.--") == 0) printascii(33); |
| kenjiArai | 0:166e0710d217 | 351 | if (strcmp(code,".--.-.") == 0) printascii(64); |
| kenjiArai | 0:166e0710d217 | 352 | if (strcmp(code,"---...") == 0) printascii(58); |
| kenjiArai | 0:166e0710d217 | 353 | if (strcmp(code,"-....-") == 0) printascii(45); |
| kenjiArai | 0:166e0710d217 | 354 | if (strcmp(code,"-..-.") == 0) printascii(47); |
| kenjiArai | 0:166e0710d217 | 355 | |
| kenjiArai | 0:166e0710d217 | 356 | if (strcmp(code,"-.--.") == 0) printascii(40); |
| kenjiArai | 0:166e0710d217 | 357 | if (strcmp(code,"-.--.-") == 0) printascii(41); |
| kenjiArai | 0:166e0710d217 | 358 | if (strcmp(code,".-...") == 0) printascii(95); |
| kenjiArai | 0:166e0710d217 | 359 | if (strcmp(code,"...-..-") == 0) printascii(36); |
| kenjiArai | 0:166e0710d217 | 360 | if (strcmp(code,"...-.-") == 0) printascii(62); |
| kenjiArai | 0:166e0710d217 | 361 | if (strcmp(code,".-.-.") == 0) printascii(60); |
| kenjiArai | 0:166e0710d217 | 362 | if (strcmp(code,"...-.") == 0) printascii(126); |
| kenjiArai | 0:166e0710d217 | 363 | ////////////////// |
| kenjiArai | 0:166e0710d217 | 364 | // The specials // |
| kenjiArai | 0:166e0710d217 | 365 | ////////////////// |
| kenjiArai | 0:166e0710d217 | 366 | if (strcmp(code,".-.-") == 0) printascii(3); |
| kenjiArai | 0:166e0710d217 | 367 | if (strcmp(code,"---.") == 0) printascii(4); |
| kenjiArai | 0:166e0710d217 | 368 | if (strcmp(code,".--.-") == 0) printascii(6); |
| kenjiArai | 0:166e0710d217 | 369 | |
| kenjiArai | 0:166e0710d217 | 370 | } |
| kenjiArai | 0:166e0710d217 | 371 | |
| kenjiArai | 0:166e0710d217 | 372 | ///////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 373 | // print the ascii code to the lcd // |
| kenjiArai | 0:166e0710d217 | 374 | // one a time so we can generate // |
| kenjiArai | 0:166e0710d217 | 375 | // special letters // |
| kenjiArai | 0:166e0710d217 | 376 | ///////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 377 | void printascii(int asciinumber){ |
| kenjiArai | 0:166e0710d217 | 378 | |
| kenjiArai | 0:166e0710d217 | 379 | int fail = 0; |
| kenjiArai | 0:166e0710d217 | 380 | if (rows == 4 and colums == 16)fail = -4; /// to fix the library problem with 4*16 display http://forum.arduino.cc/index.php/topic,14604.0.html |
| kenjiArai | 0:166e0710d217 | 381 | |
| kenjiArai | 0:166e0710d217 | 382 | if (lcdindex > colums-1){ |
| kenjiArai | 0:166e0710d217 | 383 | lcdindex = 0; |
| kenjiArai | 0:166e0710d217 | 384 | if (rows==4){ |
| kenjiArai | 0:166e0710d217 | 385 | for (int i = 0; i <= colums-1 ; i++){ |
| kenjiArai | 0:166e0710d217 | 386 | lcd.setCursor(i,rows-3); |
| kenjiArai | 0:166e0710d217 | 387 | lcd.write(line2[i]); |
| kenjiArai | 0:166e0710d217 | 388 | line2[i]=line1[i]; |
| kenjiArai | 0:166e0710d217 | 389 | } |
| kenjiArai | 0:166e0710d217 | 390 | } |
| kenjiArai | 0:166e0710d217 | 391 | for (int i = 0; i <= colums-1 ; i++){ |
| kenjiArai | 0:166e0710d217 | 392 | lcd.setCursor(i+fail,rows-2); |
| kenjiArai | 0:166e0710d217 | 393 | lcd.write(line1[i]); |
| kenjiArai | 0:166e0710d217 | 394 | lcd.setCursor(i+fail,rows-1); |
| kenjiArai | 0:166e0710d217 | 395 | lcd.write(32); |
| kenjiArai | 0:166e0710d217 | 396 | } |
| kenjiArai | 0:166e0710d217 | 397 | } |
| kenjiArai | 0:166e0710d217 | 398 | line1[lcdindex]=asciinumber; |
| kenjiArai | 0:166e0710d217 | 399 | lcd.setCursor(lcdindex+fail,rows-1); |
| kenjiArai | 0:166e0710d217 | 400 | lcd.write(asciinumber); |
| kenjiArai | 0:166e0710d217 | 401 | lcdindex += 1; |
| kenjiArai | 0:166e0710d217 | 402 | } |
| kenjiArai | 0:166e0710d217 | 403 | |
| kenjiArai | 0:166e0710d217 | 404 | void updateinfolinelcd(){ |
| kenjiArai | 0:166e0710d217 | 405 | ///////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 406 | // here we update the upper line // |
| kenjiArai | 0:166e0710d217 | 407 | // with the speed. // |
| kenjiArai | 0:166e0710d217 | 408 | ///////////////////////////////////// |
| kenjiArai | 0:166e0710d217 | 409 | |
| kenjiArai | 0:166e0710d217 | 410 | int place; |
| kenjiArai | 0:166e0710d217 | 411 | if (rows == 4){ |
| kenjiArai | 0:166e0710d217 | 412 | place = colums/2;} |
| kenjiArai | 0:166e0710d217 | 413 | else{ |
| kenjiArai | 0:166e0710d217 | 414 | place = 2; |
| kenjiArai | 0:166e0710d217 | 415 | } |
| kenjiArai | 0:166e0710d217 | 416 | if (wpm<10){ |
| kenjiArai | 0:166e0710d217 | 417 | lcd.setCursor((place)-2,0); |
| kenjiArai | 0:166e0710d217 | 418 | lcd.print("0"); |
| kenjiArai | 0:166e0710d217 | 419 | lcd.setCursor((place)-1,0); |
| kenjiArai | 0:166e0710d217 | 420 | lcd.print(wpm); |
| kenjiArai | 0:166e0710d217 | 421 | lcd.setCursor((place),0); |
| kenjiArai | 0:166e0710d217 | 422 | lcd.print(" WPM"); |
| kenjiArai | 0:166e0710d217 | 423 | } |
| kenjiArai | 0:166e0710d217 | 424 | else{ |
| kenjiArai | 0:166e0710d217 | 425 | lcd.setCursor((place)-2,0); |
| kenjiArai | 0:166e0710d217 | 426 | lcd.print(wpm); |
| kenjiArai | 0:166e0710d217 | 427 | lcd.setCursor((place),0); |
| kenjiArai | 0:166e0710d217 | 428 | lcd.print(" WPM "); |
| kenjiArai | 0:166e0710d217 | 429 | } |
| kenjiArai | 0:166e0710d217 | 430 | |
| kenjiArai | 0:166e0710d217 | 431 | } |
| kenjiArai | 0:166e0710d217 | 432 | |
| kenjiArai | 0:166e0710d217 | 433 | //--------------------------------------------------------------------------------------------------------------------------------------------------- |
| kenjiArai | 0:166e0710d217 | 434 | // http://archive.eetindia.co.in/www.eetindia.co.in/STATIC/DOWNLOAD/09banks.txt |
| kenjiArai | 0:166e0710d217 | 435 | //--------------------------------------------------------------------------------------------------------------------------------------------------- |
| kenjiArai | 0:166e0710d217 | 436 | // Listing 1 A Goertzel implementation |
| kenjiArai | 0:166e0710d217 | 437 | |
| kenjiArai | 0:166e0710d217 | 438 | #include <stdio.h> |
| kenjiArai | 0:166e0710d217 | 439 | #include <math.h> |
| kenjiArai | 0:166e0710d217 | 440 | |
| kenjiArai | 0:166e0710d217 | 441 | #define FLOATING float |
| kenjiArai | 0:166e0710d217 | 442 | #define SAMPLE unsigned char |
| kenjiArai | 0:166e0710d217 | 443 | |
| kenjiArai | 0:166e0710d217 | 444 | #define SAMPLING_RATE 8000.0 //8kHz |
| kenjiArai | 0:166e0710d217 | 445 | #define TARGET_FREQUENCY 941.0 //941 Hz |
| kenjiArai | 0:166e0710d217 | 446 | #define N 205 //Block size |
| kenjiArai | 0:166e0710d217 | 447 | |
| kenjiArai | 0:166e0710d217 | 448 | FLOATING coeff; |
| kenjiArai | 0:166e0710d217 | 449 | FLOATING Q1; |
| kenjiArai | 0:166e0710d217 | 450 | FLOATING Q2; |
| kenjiArai | 0:166e0710d217 | 451 | FLOATING sine; |
| kenjiArai | 0:166e0710d217 | 452 | FLOATING cosine; |
| kenjiArai | 0:166e0710d217 | 453 | |
| kenjiArai | 0:166e0710d217 | 454 | SAMPLE testData[N]; |
| kenjiArai | 0:166e0710d217 | 455 | |
| kenjiArai | 0:166e0710d217 | 456 | /* Call this routine before every "block" (size=N) of samples. */ |
| kenjiArai | 0:166e0710d217 | 457 | void ResetGoertzel(void) |
| kenjiArai | 0:166e0710d217 | 458 | { |
| kenjiArai | 0:166e0710d217 | 459 | Q2 = 0; |
| kenjiArai | 0:166e0710d217 | 460 | Q1 = 0; |
| kenjiArai | 0:166e0710d217 | 461 | } |
| kenjiArai | 0:166e0710d217 | 462 | |
| kenjiArai | 0:166e0710d217 | 463 | /* Call this once, to precompute the constants. */ |
| kenjiArai | 0:166e0710d217 | 464 | void InitGoertzel(void) |
| kenjiArai | 0:166e0710d217 | 465 | { |
| kenjiArai | 0:166e0710d217 | 466 | int k; |
| kenjiArai | 0:166e0710d217 | 467 | FLOATING floatN; |
| kenjiArai | 0:166e0710d217 | 468 | FLOATING omega; |
| kenjiArai | 0:166e0710d217 | 469 | |
| kenjiArai | 0:166e0710d217 | 470 | floatN = (FLOATING) N; |
| kenjiArai | 0:166e0710d217 | 471 | k = (int) (0.5 + ((floatN * TARGET_FREQUENCY) / SAMPLING_RATE)); |
| kenjiArai | 0:166e0710d217 | 472 | omega = (2.0 * PI * k) / floatN; |
| kenjiArai | 0:166e0710d217 | 473 | sine = sin(omega); |
| kenjiArai | 0:166e0710d217 | 474 | cosine = cos(omega); |
| kenjiArai | 0:166e0710d217 | 475 | coeff = 2.0 * cosine; |
| kenjiArai | 0:166e0710d217 | 476 | |
| kenjiArai | 0:166e0710d217 | 477 | printf("For SAMPLING_RATE = %f", SAMPLING_RATE); |
| kenjiArai | 0:166e0710d217 | 478 | printf(" N = %d", N); |
| kenjiArai | 0:166e0710d217 | 479 | printf(" and FREQUENCY = %f,\n", TARGET_FREQUENCY); |
| kenjiArai | 0:166e0710d217 | 480 | printf("k = %d and coeff = %f\n\n", k, coeff); |
| kenjiArai | 0:166e0710d217 | 481 | |
| kenjiArai | 0:166e0710d217 | 482 | ResetGoertzel(); |
| kenjiArai | 0:166e0710d217 | 483 | } |
| kenjiArai | 0:166e0710d217 | 484 | |
| kenjiArai | 0:166e0710d217 | 485 | /* Call this routine for every sample. */ |
| kenjiArai | 0:166e0710d217 | 486 | void ProcessSample(SAMPLE sample) |
| kenjiArai | 0:166e0710d217 | 487 | { |
| kenjiArai | 0:166e0710d217 | 488 | FLOATING Q0; |
| kenjiArai | 0:166e0710d217 | 489 | Q0 = coeff * Q1 - Q2 + (FLOATING) sample; |
| kenjiArai | 0:166e0710d217 | 490 | Q2 = Q1; |
| kenjiArai | 0:166e0710d217 | 491 | Q1 = Q0; |
| kenjiArai | 0:166e0710d217 | 492 | } |
| kenjiArai | 0:166e0710d217 | 493 | |
| kenjiArai | 0:166e0710d217 | 494 | |
| kenjiArai | 0:166e0710d217 | 495 | /* Basic Goertzel */ |
| kenjiArai | 0:166e0710d217 | 496 | /* Call this routine after every block to get the complex result. */ |
| kenjiArai | 0:166e0710d217 | 497 | void GetRealImag(FLOATING *realPart, FLOATING *imagPart) |
| kenjiArai | 0:166e0710d217 | 498 | { |
| kenjiArai | 0:166e0710d217 | 499 | *realPart = (Q1 - Q2 * cosine); |
| kenjiArai | 0:166e0710d217 | 500 | *imagPart = (Q2 * sine); |
| kenjiArai | 0:166e0710d217 | 501 | } |
| kenjiArai | 0:166e0710d217 | 502 | |
| kenjiArai | 0:166e0710d217 | 503 | /* Optimized Goertzel */ |
| kenjiArai | 0:166e0710d217 | 504 | /* Call this after every block to get the RELATIVE magnitude squared. */ |
| kenjiArai | 0:166e0710d217 | 505 | FLOATING GetMagnitudeSquared(void) |
| kenjiArai | 0:166e0710d217 | 506 | { |
| kenjiArai | 0:166e0710d217 | 507 | FLOATING result; |
| kenjiArai | 0:166e0710d217 | 508 | |
| kenjiArai | 0:166e0710d217 | 509 | result = Q1 * Q1 + Q2 * Q2 - Q1 * Q2 * coeff; |
| kenjiArai | 0:166e0710d217 | 510 | return result; |
| kenjiArai | 0:166e0710d217 | 511 | } |
| kenjiArai | 0:166e0710d217 | 512 | |
| kenjiArai | 0:166e0710d217 | 513 | /*** End of Goertzel-specific code, the remainder is test code. */ |
| kenjiArai | 0:166e0710d217 | 514 | |
| kenjiArai | 0:166e0710d217 | 515 | /* Synthesize some test data at a given frequency. */ |
| kenjiArai | 0:166e0710d217 | 516 | void Generate(FLOATING frequency) |
| kenjiArai | 0:166e0710d217 | 517 | { |
| kenjiArai | 0:166e0710d217 | 518 | int index; |
| kenjiArai | 0:166e0710d217 | 519 | FLOATING step; |
| kenjiArai | 0:166e0710d217 | 520 | |
| kenjiArai | 0:166e0710d217 | 521 | step = frequency * ((2.0 * PI) / SAMPLING_RATE); |
| kenjiArai | 0:166e0710d217 | 522 | |
| kenjiArai | 0:166e0710d217 | 523 | /* Generate the test data */ |
| kenjiArai | 0:166e0710d217 | 524 | for (index = 0; index < N; index++) |
| kenjiArai | 0:166e0710d217 | 525 | { |
| kenjiArai | 0:166e0710d217 | 526 | testData[index] = (SAMPLE) (100.0 * sin(index * step) + 100.0); |
| kenjiArai | 0:166e0710d217 | 527 | } |
| kenjiArai | 0:166e0710d217 | 528 | } |
| kenjiArai | 0:166e0710d217 | 529 | |
| kenjiArai | 0:166e0710d217 | 530 | /* Demo 1 */ |
| kenjiArai | 0:166e0710d217 | 531 | void GenerateAndTest(FLOATING frequency) |
| kenjiArai | 0:166e0710d217 | 532 | { |
| kenjiArai | 0:166e0710d217 | 533 | int index; |
| kenjiArai | 0:166e0710d217 | 534 | |
| kenjiArai | 0:166e0710d217 | 535 | FLOATING magnitudeSquared; |
| kenjiArai | 0:166e0710d217 | 536 | FLOATING magnitude; |
| kenjiArai | 0:166e0710d217 | 537 | FLOATING real; |
| kenjiArai | 0:166e0710d217 | 538 | FLOATING imag; |
| kenjiArai | 0:166e0710d217 | 539 | |
| kenjiArai | 0:166e0710d217 | 540 | printf("For test frequency %f:\n", frequency); |
| kenjiArai | 0:166e0710d217 | 541 | Generate(frequency); |
| kenjiArai | 0:166e0710d217 | 542 | |
| kenjiArai | 0:166e0710d217 | 543 | /* Process the samples */ |
| kenjiArai | 0:166e0710d217 | 544 | for (index = 0; index < N; index++) |
| kenjiArai | 0:166e0710d217 | 545 | { |
| kenjiArai | 0:166e0710d217 | 546 | ProcessSample(testData[index]); |
| kenjiArai | 0:166e0710d217 | 547 | } |
| kenjiArai | 0:166e0710d217 | 548 | |
| kenjiArai | 0:166e0710d217 | 549 | /* Do the "basic Goertzel" processing. */ |
| kenjiArai | 0:166e0710d217 | 550 | GetRealImag(&real, &imag); |
| kenjiArai | 0:166e0710d217 | 551 | |
| kenjiArai | 0:166e0710d217 | 552 | printf("real = %f imag = %f\n", real, imag); |
| kenjiArai | 0:166e0710d217 | 553 | |
| kenjiArai | 0:166e0710d217 | 554 | magnitudeSquared = real*real + imag*imag; |
| kenjiArai | 0:166e0710d217 | 555 | printf("Relative magnitude squared = %f\n", magnitudeSquared); |
| kenjiArai | 0:166e0710d217 | 556 | magnitude = sqrt(magnitudeSquared); |
| kenjiArai | 0:166e0710d217 | 557 | printf("Relative magnitude = %f\n", magnitude); |
| kenjiArai | 0:166e0710d217 | 558 | |
| kenjiArai | 0:166e0710d217 | 559 | /* Do the "optimized Goertzel" processing */ |
| kenjiArai | 0:166e0710d217 | 560 | magnitudeSquared = GetMagnitudeSquared(); |
| kenjiArai | 0:166e0710d217 | 561 | printf("Relative magnitude squared = %f\n", magnitudeSquared); |
| kenjiArai | 0:166e0710d217 | 562 | magnitude = sqrt(magnitudeSquared); |
| kenjiArai | 0:166e0710d217 | 563 | printf("Relative magnitude = %f\n\n", magnitude); |
| kenjiArai | 0:166e0710d217 | 564 | |
| kenjiArai | 0:166e0710d217 | 565 | ResetGoertzel(); |
| kenjiArai | 0:166e0710d217 | 566 | } |
| kenjiArai | 0:166e0710d217 | 567 | |
| kenjiArai | 0:166e0710d217 | 568 | /* Demo 2 */ |
| kenjiArai | 0:166e0710d217 | 569 | void GenerateAndTest2(FLOATING frequency) |
| kenjiArai | 0:166e0710d217 | 570 | { |
| kenjiArai | 0:166e0710d217 | 571 | int index; |
| kenjiArai | 0:166e0710d217 | 572 | |
| kenjiArai | 0:166e0710d217 | 573 | FLOATING magnitudeSquared; |
| kenjiArai | 0:166e0710d217 | 574 | FLOATING magnitude; |
| kenjiArai | 0:166e0710d217 | 575 | FLOATING real; |
| kenjiArai | 0:166e0710d217 | 576 | FLOATING imag; |
| kenjiArai | 0:166e0710d217 | 577 | |
| kenjiArai | 0:166e0710d217 | 578 | printf("Freq=%7.1f ", frequency); |
| kenjiArai | 0:166e0710d217 | 579 | Generate(frequency); |
| kenjiArai | 0:166e0710d217 | 580 | |
| kenjiArai | 0:166e0710d217 | 581 | /* Process the samples. */ |
| kenjiArai | 0:166e0710d217 | 582 | for (index = 0; index < N; index++) |
| kenjiArai | 0:166e0710d217 | 583 | { |
| kenjiArai | 0:166e0710d217 | 584 | ProcessSample(testData[index]); |
| kenjiArai | 0:166e0710d217 | 585 | } |
| kenjiArai | 0:166e0710d217 | 586 | |
| kenjiArai | 0:166e0710d217 | 587 | /* Do the "standard Goertzel" processing. */ |
| kenjiArai | 0:166e0710d217 | 588 | GetRealImag(&real, &imag); |
| kenjiArai | 0:166e0710d217 | 589 | |
| kenjiArai | 0:166e0710d217 | 590 | magnitudeSquared = real*real + imag*imag; |
| kenjiArai | 0:166e0710d217 | 591 | printf("rel mag^2=%16.5f ", magnitudeSquared); |
| kenjiArai | 0:166e0710d217 | 592 | magnitude = sqrt(magnitudeSquared); |
| kenjiArai | 0:166e0710d217 | 593 | printf("rel mag=%12.5f\n", magnitude); |
| kenjiArai | 0:166e0710d217 | 594 | |
| kenjiArai | 0:166e0710d217 | 595 | ResetGoertzel(); |
| kenjiArai | 0:166e0710d217 | 596 | } |
| kenjiArai | 0:166e0710d217 | 597 | |
| kenjiArai | 0:166e0710d217 | 598 | int main(void) |
| kenjiArai | 0:166e0710d217 | 599 | { |
| kenjiArai | 0:166e0710d217 | 600 | FLOATING freq; |
| kenjiArai | 0:166e0710d217 | 601 | |
| kenjiArai | 0:166e0710d217 | 602 | InitGoertzel(); |
| kenjiArai | 0:166e0710d217 | 603 | |
| kenjiArai | 0:166e0710d217 | 604 | /* Demo 1 */ |
| kenjiArai | 0:166e0710d217 | 605 | GenerateAndTest(TARGET_FREQUENCY - 250); |
| kenjiArai | 0:166e0710d217 | 606 | GenerateAndTest(TARGET_FREQUENCY); |
| kenjiArai | 0:166e0710d217 | 607 | GenerateAndTest(TARGET_FREQUENCY + 250); |
| kenjiArai | 0:166e0710d217 | 608 | |
| kenjiArai | 0:166e0710d217 | 609 | /* Demo 2 */ |
| kenjiArai | 0:166e0710d217 | 610 | for (freq = TARGET_FREQUENCY - 300; freq <= TARGET_FREQUENCY + 300; freq += 15) |
| kenjiArai | 0:166e0710d217 | 611 | { |
| kenjiArai | 0:166e0710d217 | 612 | GenerateAndTest2(freq); |
| kenjiArai | 0:166e0710d217 | 613 | } |
| kenjiArai | 0:166e0710d217 | 614 | |
| kenjiArai | 0:166e0710d217 | 615 | return 0; |
| kenjiArai | 0:166e0710d217 | 616 | } |
| kenjiArai | 0:166e0710d217 | 617 | |
| kenjiArai | 0:166e0710d217 | 618 | //--------------------------------------------------------------------------------------------------------------------------------------------------- |
| kenjiArai | 0:166e0710d217 | 619 | // End of reference source code |
| kenjiArai | 0:166e0710d217 | 620 | //--------------------------------------------------------------------------------------------------------------------------------------------------- |