View difference between Paste ID: 2rPJFu4B and ns6y7eSK
SHOW: | | - or go back to the newest paste.
1
/*********************************************************************************************************************
2
	PESIT EEE 6th Sem Mini Project
3
	May 2013
4
	
5
	ELECTRONIC GUITAR TUNER
6
	
7
	Tested on: Arduino Uno
8
	Main Algorithm Used: Autocorrelation (for fundamental frequency)
9
	Software version: 1.0.1
10
	
11
	Test Parameters: 
12
	INPUT: Emulated Acoustic guitar sound from Guitar Pro V5 (for windows)
13
	SIGNAL FLOW: Computer Audio out->Operational Amplifier->Arduino Uno->7 Segment Display
14
	
15
	USNs:	1PI10EE009
16
			1PI10EE026
17
			1PI10EE019
18
*********************************************************************************************************************/						
19
20
21
/*****************************************************************************
22
				DECLARATIONS
23-
							DECLARATIONS
23+
24
25
#define N 200 //Buffer Size
26
#define sampleF 38500//Hz
27
#define display_time 5000//ms
28
29
30
byte incomingAudio, bIndex=N-1;
31
int buffer[N];
32
long int corr[N], corrMin;
33
long int t_old, t_new = millis();
34
int i, j, minIndex,s;
35
int Freq=0;
36
boolean clipping = 0, flag = 0;
37
38
39
const int A  = 110,		//These are the standard note frequencies
40
      As = 116,			//At the lowest octave
41
      B  = 123,
42
      C  = 131,
43
      Cs = 139,
44
      D  = 147,
45
      Ds = 156,
46
      E  = 165,
47
      F  = 171,
48
      Fs = 185,
49
      G  = 196,
50
      Gs = 208;
51
int note = A;
52
int deviation = 0;
53
bool dev; 		//Higher or lower from the correct note
54
bool correct;   //To show that the guitar is in tune
55
56
/*****************************************************************************
57
		FUNCTION TO COMPUTE FUNDAMENTAL FREQUENCY
58-
					FUNCTION TO COMPUTE FUNDAMENTAL FREQUENCY
58+
59
60
void compute(void){
61
  //Autocorrelate and find minimum point
62
  minIndex=0;
63
  for(i=0; i<=N-1; i++){
64
    corr[i] = 0;
65
    for(j=0; j<=N-1; j++){
66
      s = j+i;
67
      if((j+i)>(N-1))
68
          s = (j+i) - (N-1);
69
      corr[i] = corr[i] + (int)buffer[j]*buffer[s];
70
    }  
71
      if(corr[i]<corr[minIndex])
72
        minIndex = i;
73
    
74
  }
75
76
  //Calculate Frequency
77
  Freq = sampleF/(minIndex*2);    
78
}
79
80
81
/*****************************************************************************
82
			PITCH DETECTION FUNCTION
83-
							PITCH DETECTION FUNCTION
83+
84
85
void pitch(void){
86
	/*
87
	This function is used to find the pitch after finding frequency and display the
88
	outputs on the 7 segment display and the LEDs	
89
	*/
90
	
91
	const float t = 0.035; //tolerance band for note
92
	const float t2 = 0.01; //tolerance band for correct note                
93
	int octave = 1;
94
	  
95
	//FIND OCTAVE
96
	if(Freq > Gs*1)
97
		octave = 2;
98
	if(Freq > Gs*2)
99
		octave =4;
100
	if(Freq > Gs*4)
101
		octave = 8;
102
103
	/*FIND PITCH
104
	  The following portion is equivalent to checking if 'Freq'
105
	  lies within a certain band around the given note.
106
	  The width of this band is set by 't' (a percentage value)
107
	  Check if: 
108
	       (input_note) lies within required_note +/- (percentage*required_note) 
109
	*/
110
	  
111
	  if( Freq > (A*octave)*(1-t) && Freq < (A*octave)*(1+t) ){
112
		note = A;
113
		//Signal the 7 seg display with the letter in each of these if statements.
114
		seven_seg_A();
115
		}
116
	  else  if( Freq > (As*octave)*(1-t) && Freq < (As*octave)*(1+t) ){
117
		note = As;
118
		seven_seg_As();
119
		}
120
	  else  if( Freq > (B*octave)*(1-t) && Freq < (B*octave)*(1+t) ){
121
		note = B;
122
		seven_seg_B();
123
		}
124
	  else  if( Freq > (C*octave)*(1-t) && Freq < (C*octave)*(1+t) ){
125
		note = C;
126
		seven_seg_C();
127
		}
128
	  else  if( Freq > (Cs*octave)*(1-t) && Freq < (Cs*octave)*(1+t) ){
129
		note = Cs;
130
		seven_seg_Cs();
131
		}
132
	  else  if( Freq > (D*octave)*(1-t) && Freq < (D*octave)*(1+t) ){
133
		note = D;
134
		seven_seg_D();
135
		}
136
	  else  if( Freq > (Ds*octave)*(1-t) && Freq < (Ds*octave)*(1+t) ){
137
		note = Ds;
138
		seven_seg_Ds();
139
		}
140
	  else  if( Freq > (E*octave)*(1-t) && Freq < (E*octave)*(1+t) ){
141
		note = E;
142
		seven_seg_E();
143
		}
144
	  else  if( Freq > (F*octave)*(1-t) && Freq < (F*octave)*(1+t) ){
145
		note = F;
146
		seven_seg_F();
147
		}
148
	  else  if( Freq > (Fs*octave)*(1-t) && Freq < (Fs*octave)*(1+t) ){
149
		note = Fs;
150
		seven_seg_Fs();
151
		}
152
	  else  if( Freq > (G*octave)*(1-t) && Freq < (G*octave)*(1+t) ){
153
		note = G;
154
		seven_seg_G();
155
		}
156
	  else  if( Freq > (Gs*octave)*(1-t) && Freq < (Gs*octave)*(1+t) ){
157
		note = Gs;
158
		seven_seg_Gs();
159
		}
160
	  
161
	  //DISPLAY
162
	  deviation = Freq - note*octave;
163
	  if (abs(deviation) < t2*note){
164
		 correct = 1;      //in tune
165
		 //Serial.print(" ");
166
		 //Serial.println("Correct");
167
		 }
168
	  else{
169
		correct = 0;      //not in tune
170
		if((deviation)>0){
171
		  //Serial.print(" ");
172
		  //Serial.println("Note = deviated HIGH");
173
		  dev = HIGH;
174
		}
175
		else {
176
			// Serial.print(" ");
177
			//Serial.println("Deviated Low");
178
			dev = LOW;
179
		}
180
	}
181
}
182
/***************END OF PITCH DETECTION FUNCTION****************/
183
184
185
/******************************************************************************
186
			FUNCTIONS FOR 7 SEGMENT DISPLAY
187-
						FUNCTIONS FOR 7 SEGMENT DISPLAY
187+
188
189
//These are used to display the specific note on the 7 segment display
190
void seven_seg_A(void){
191
  digitalWrite(9, LOW);
192
  digitalWrite(8, LOW);
193
  digitalWrite(7, LOW);
194
  digitalWrite(6, HIGH);
195
  digitalWrite(5, LOW);
196
  digitalWrite(4, LOW);
197
  digitalWrite(3, LOW);
198
  digitalWrite(2, HIGH);
199
  if(correct == 1)
200
  {
201
    digitalWrite(12,LOW);
202
    digitalWrite(11,HIGH);
203
    digitalWrite(10,LOW);
204
  }
205
  else if(correct == 0)
206
  {
207
    if(dev == HIGH)
208
    {
209
      digitalWrite(12,LOW);
210
      digitalWrite(11,LOW);
211
      digitalWrite(10,HIGH);
212
    }
213
    else if(dev == LOW)
214
    {
215
      digitalWrite(12,HIGH);
216
      digitalWrite(11,LOW);
217
      digitalWrite(10,LOW);
218
    }
219
  }
220
}
221
222
void seven_seg_As(void){
223
	digitalWrite(9, LOW);
224
	digitalWrite(8, LOW);
225
	digitalWrite(7, LOW);
226
	digitalWrite(6, HIGH);
227
	digitalWrite(5, LOW);
228
	digitalWrite(4, LOW);
229
	digitalWrite(3, LOW);
230
	digitalWrite(2, LOW);
231
	if(correct == 1)
232
	  {
233
		digitalWrite(12,LOW);
234
		digitalWrite(11,HIGH);
235
		digitalWrite(10,LOW);
236
	  }
237
	  else if(correct == 0)
238
	  {
239
		if(dev == HIGH)
240
		{
241
		  digitalWrite(12,LOW);
242
		  digitalWrite(11,LOW);
243
		  digitalWrite(10,HIGH);
244
		}
245
		else if(dev == LOW)
246
		{
247
		  digitalWrite(12,HIGH);
248
		  digitalWrite(11,LOW);
249
		  digitalWrite(10,LOW);
250
		}
251
	  }
252
	}
253
254
void seven_seg_B(void){
255
	digitalWrite(9, HIGH);
256
	digitalWrite(8, HIGH);
257
	digitalWrite(7, LOW);
258
	digitalWrite(6, LOW);
259
	digitalWrite(5, LOW);
260
	digitalWrite(4, LOW);
261
	digitalWrite(3, LOW);
262
	digitalWrite(2, HIGH);
263
	if(correct == 1)
264
	  {
265
		digitalWrite(12,LOW);
266
		digitalWrite(11,HIGH);
267
		digitalWrite(10,LOW);
268
	  }
269
	  else if(correct == 0)
270
	  {
271
		if(dev == HIGH)
272
		{
273
		  digitalWrite(12,LOW);
274
		  digitalWrite(11,LOW);
275
		  digitalWrite(10,HIGH);
276
		}
277
		else if(dev == LOW)
278
		{
279
		  digitalWrite(12,HIGH);
280
		  digitalWrite(11,LOW);
281
		  digitalWrite(10,LOW);
282
		}
283
	  }
284
	}
285
286
void seven_seg_C(void){
287
	digitalWrite(9, HIGH);
288
	digitalWrite(8, HIGH);
289
	digitalWrite(7, HIGH);
290
	digitalWrite(6, LOW);
291
	digitalWrite(5, LOW);
292
	digitalWrite(4, HIGH);
293
	digitalWrite(3, LOW);
294
	digitalWrite(2, HIGH);
295
	if(correct == 1)
296
	  {
297
		digitalWrite(12,LOW);
298
		digitalWrite(11,HIGH);
299
		digitalWrite(10,LOW);
300
	  }
301
	  else if(correct == 0)
302
	  {
303
		if(dev == HIGH)
304
		{
305
		  digitalWrite(12,LOW);
306
		  digitalWrite(11,LOW);
307
		  digitalWrite(10,HIGH);
308
		}
309
		else if(dev == LOW)
310
		{
311
		  digitalWrite(12,HIGH);
312
		  digitalWrite(11,LOW);
313
		  digitalWrite(10,LOW);
314
		}
315
	  }
316
	}
317
318
void seven_seg_Cs(void){
319
	digitalWrite(9, HIGH);
320
	digitalWrite(8, HIGH);
321
	digitalWrite(7, HIGH);
322
	digitalWrite(6, LOW);
323
	digitalWrite(5, LOW);
324
	digitalWrite(4, HIGH);
325
	digitalWrite(3, LOW);
326
	digitalWrite(2, LOW);
327
	if(correct == 1)
328
	  {
329
		digitalWrite(12,LOW);
330
		digitalWrite(11,HIGH);
331
		digitalWrite(10,LOW);
332
	  }
333
	  else if(correct == 0)
334
	  {
335
		if(dev == HIGH)
336
		{
337
		  digitalWrite(12,LOW);
338
		  digitalWrite(11,LOW);
339
		  digitalWrite(10,HIGH);
340
		}
341
		else if(dev == LOW)
342
		{
343
		  digitalWrite(12,HIGH);
344
		  digitalWrite(11,LOW);
345
		  digitalWrite(10,LOW);
346
		}
347
	  }
348
	}
349
350
void seven_seg_D(void){
351
	digitalWrite(9, HIGH);
352
	digitalWrite(8, LOW);
353
	digitalWrite(7, LOW);
354
	digitalWrite(6, LOW);
355
	digitalWrite(5, LOW);
356
	digitalWrite(4, HIGH);
357
	digitalWrite(3, LOW);
358
	digitalWrite(2, HIGH);
359
	if(correct == 1)
360
	  {
361
		digitalWrite(12,LOW);
362
		digitalWrite(11,HIGH);
363
		digitalWrite(10,LOW);
364
	  }
365
	  else if(correct == 0)
366
	  {
367
		if(dev == HIGH)
368
		{
369
		  digitalWrite(12,LOW);
370
		  digitalWrite(11,LOW);
371
		  digitalWrite(10,HIGH);
372
		}
373
		else if(dev == LOW)
374
		{
375
		  digitalWrite(12,HIGH);
376
		  digitalWrite(11,LOW);
377
		  digitalWrite(10,LOW);
378
		}
379
	  }
380
	}
381
382
void seven_seg_Ds(void){
383
	digitalWrite(9, HIGH);
384
	digitalWrite(8, LOW);
385
	digitalWrite(7, LOW);
386
	digitalWrite(6, LOW);
387
	digitalWrite(5, LOW);
388
	digitalWrite(4, HIGH);
389
	digitalWrite(3, LOW);
390
	digitalWrite(2, LOW);
391
	if(correct == 1)
392
	  {
393
		digitalWrite(12,LOW);
394
		digitalWrite(11,HIGH);
395
		digitalWrite(10,LOW);
396
	  }
397
	  else if(correct == 0)
398
	  {
399
		if(dev == HIGH)
400
		{
401
		  digitalWrite(12,LOW);
402
		  digitalWrite(11,LOW);
403
		  digitalWrite(10,HIGH);
404
		}
405
		else if(dev == LOW)
406
		{
407
		  digitalWrite(12,HIGH);
408
		  digitalWrite(11,LOW);
409
		  digitalWrite(10,LOW);
410
		}
411
	  }
412
	}
413
414
void seven_seg_E(void){
415
	digitalWrite(9, LOW);
416
	digitalWrite(8, HIGH);
417
	digitalWrite(7, HIGH);
418
	digitalWrite(6, LOW);
419
	digitalWrite(5, LOW);
420
	digitalWrite(4, LOW);
421
	digitalWrite(3, LOW);
422
	digitalWrite(2, HIGH);
423
	if(correct == 1)
424
	  {
425
		digitalWrite(12,LOW);
426
		digitalWrite(11,HIGH);
427
		digitalWrite(10,LOW);
428
	  }
429
	  else if(correct == 0)
430
	  {
431
		if(dev == HIGH)
432
		{
433
		  digitalWrite(12,LOW);
434
		  digitalWrite(11,LOW);
435
		  digitalWrite(10,HIGH);
436
		}
437
		else if(dev == LOW)
438
		{
439
		  digitalWrite(12,HIGH);
440
		  digitalWrite(11,LOW);
441
		  digitalWrite(10,LOW);
442
		}
443
	  }
444
	}
445
	
446
void seven_seg_F(void){
447
	digitalWrite(9, LOW);
448
	digitalWrite(8, HIGH);
449
	digitalWrite(7, HIGH);
450
	digitalWrite(6, HIGH);
451
	digitalWrite(5, LOW);
452
	digitalWrite(4, LOW);
453
	digitalWrite(3, LOW);
454
	digitalWrite(2, HIGH);
455
	if(correct == 1)
456
	  {
457
		digitalWrite(12,LOW);
458
		digitalWrite(11,HIGH);
459
		digitalWrite(10,LOW);
460
	  }
461
	  else if(correct == 0)
462
	  {
463
		if(dev == HIGH)
464
		{
465
		  digitalWrite(12,LOW);
466
		  digitalWrite(11,LOW);
467
		  digitalWrite(10,HIGH);
468
		}
469
		else if(dev == LOW)
470
		{
471
		  digitalWrite(12,HIGH);
472
		  digitalWrite(11,LOW);
473
		  digitalWrite(10,LOW);
474
		}
475
	  }
476
	}
477
478
void seven_seg_Fs(void){
479
	digitalWrite(9, LOW);
480
	digitalWrite(8, HIGH);
481
	digitalWrite(7, HIGH);
482
	digitalWrite(6, HIGH);
483
	digitalWrite(5, LOW);
484
	digitalWrite(4, LOW);
485
	digitalWrite(3, LOW);
486
	digitalWrite(2, LOW);
487
	if(correct == 1)
488
	  {
489
		digitalWrite(12,LOW);
490
		digitalWrite(11,HIGH);
491
		digitalWrite(10,LOW);
492
	  }
493
	  else if(correct == 0)
494
	  {
495
		if(dev == HIGH)
496
		{
497
		  digitalWrite(12,LOW);
498
		  digitalWrite(11,LOW);
499
		  digitalWrite(10,HIGH);
500
		}
501
		else if(dev == LOW)
502
		{
503
		  digitalWrite(12,HIGH);
504
		  digitalWrite(11,LOW);
505
		  digitalWrite(10,LOW);
506
		}
507
	  }
508
	}
509
510
void seven_seg_G(void){
511
	digitalWrite(9, LOW);
512
	digitalWrite(8, LOW);
513
	digitalWrite(7, LOW);
514
	digitalWrite(6, LOW);
515
	digitalWrite(5, HIGH);
516
	digitalWrite(4, LOW);
517
	digitalWrite(3, LOW);
518
	digitalWrite(2, HIGH);
519
	if(correct == 1)
520
	  {
521
		digitalWrite(12,LOW);
522
		digitalWrite(11,HIGH);
523
		digitalWrite(10,LOW);
524
	  }
525
	  else if(correct == 0)
526
	  {
527
		if(dev == HIGH)
528
		{
529
		  digitalWrite(12,LOW);
530
		  digitalWrite(11,LOW);
531
		  digitalWrite(10,HIGH);
532
		}
533
		else if(dev == LOW)
534
		{
535
		  digitalWrite(12,HIGH);
536
		  digitalWrite(11,LOW);
537
		  digitalWrite(10,LOW);
538
		}
539
	  }
540
	}
541
542
void seven_seg_Gs(void){
543
	digitalWrite(9, LOW);
544
	digitalWrite(8, LOW);
545
	digitalWrite(7, LOW);
546
	digitalWrite(6, LOW);
547
	digitalWrite(5, HIGH);
548
	digitalWrite(4, LOW);
549
	digitalWrite(3, LOW);
550
	digitalWrite(2, LOW);
551
	if(correct == 1)
552
	  {
553
		digitalWrite(12,LOW);
554
		digitalWrite(11,HIGH);
555
		digitalWrite(10,LOW);
556
	  }
557
	  else if(correct == 0)
558
	  {
559
		if(dev == HIGH)
560
		{
561
		  digitalWrite(12,LOW);
562
		  digitalWrite(11,LOW);
563
		  digitalWrite(10,HIGH);
564
		}
565
		else if(dev == LOW)
566
		{
567
		  digitalWrite(12,HIGH);
568
		  digitalWrite(11,LOW);
569
		  digitalWrite(10,LOW);
570
		}
571
	  }
572
	}
573
574
void blank(void){
575
	//Blanks out the 7 Segment display
576
	digitalWrite(10, LOW);
577
	digitalWrite(11, LOW);
578
	digitalWrite(12, LOW);
579
	digitalWrite(9, HIGH);
580
	digitalWrite(8, HIGH);
581
	digitalWrite(7, HIGH);
582
	digitalWrite(6, HIGH);
583
	digitalWrite(5, HIGH);
584
	digitalWrite(4, HIGH);
585
	digitalWrite(3, HIGH);
586
	digitalWrite(2, HIGH);
587
	}
588
	
589
void test(void){
590
	  //To test the 7 Segment display
591
	  seven_seg_A();
592
	  delay(500);
593
	  seven_seg_As();
594
	  delay(500);
595
	  seven_seg_B();
596
	  delay(500);
597
	  seven_seg_C();
598
	  delay(500);
599
	  seven_seg_Cs();
600
	  delay(500);
601
	  seven_seg_D();
602
	  delay(500);
603
	  seven_seg_Ds();
604
	  delay(500);
605
	  seven_seg_E();
606
	  delay(500);
607
	  seven_seg_F();
608
	  delay(500);
609
	  seven_seg_Fs();
610
	  delay(500);
611
	  seven_seg_G();
612
	  delay(500);
613
	  seven_seg_Gs();
614
	  delay(500);
615
	  blank();
616
	}	
617
	
618
/***************END OF 7 SEG FUNCTIONS****************/
619
620
/*****************************************************************************
621
				SETUP
622-
								SETUP
622+
623
624
void setup(){
625
  pinMode(13,OUTPUT);//led clipping indicator pin
626
  cli();	//disable interrupts
627
  
628
  //set up continuous sampling of analog pin 0
629
  ADCSRA = 0;			 //clear ADCSRA and ADCSRB registers
630
  ADCSRB = 0;
631
  ADMUX |= (1 << REFS0); //set reference voltage
632
  ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
633
  ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
634
  //ADCSRA |= (1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0);
635
  ADCSRA |= (1 << ADATE); //enabble auto trigger
636
  ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
637
  ADCSRA |= (1 << ADEN); //enable ADC
638
  ADCSRA |= (1 << ADSC); //start ADC measurements
639
  sei();//enable interrupts
640
  
641
  
642
  Serial.begin(9600);
643
}
644
  
645
646
/*****************************************************************************
647
			INTERRUPT SERVICE ROUTINE
648-
						INTERRUPT SERVICE ROUTINE
648+
649
ISR(ADC_vect) {//when new ADC value ready
650
  incomingAudio = ADCH;//store 8 bit value from analog pin 0
651
652
  //t_new = millis();
653
  if (incomingAudio == 0 || incomingAudio == 255){//if clipping
654
    digitalWrite(13,HIGH);//set pin 13 high
655
    clipping = 1;//currently clipping
656
  }
657
  
658
  //Store in buffer                            //Works
659
  if(bIndex!=N-1){
660
    buffer[bIndex] = incomingAudio;
661
    bIndex++;
662
  }
663
  else{
664
    bIndex = 0;
665
    //flag = 1;
666
  }
667
}
668
669
/***************END OF INTERRUPT SERVICE ROUTINE**************/
670
  
671
/*****************************************************************************
672
					LOOP
673-
								LOOP
673+
674
675
void loop(){
676
    
677
    if (clipping){//if currently clipping
678
      clipping = 0;//
679
      digitalWrite(13,LOW);//turn off clipping led indicator (pin 13)
680
      }
681
  
682
	cli();
683
	compute();
684
    //To print results on serial monitor
685
    //Serial.print(Freq);
686
    //Serial.println(" hz");
687
	sei();
688
689
690
}
691
692
/***************END OF LOOP**************/