Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

f11:technik:arduino:programme:arduino-side-tone-generator [2018/12/27 09:15]
dm3kb
f11:technik:arduino:programme:arduino-side-tone-generator [2019/09/29 12:03]
Zeile 1: Zeile 1:
-====== Side-Tone Generator für PCW Fistcheck ====== 
  
-Für das reglmässige Gebe-Training mit der Hand-Taste ist für die Nutzung von PWC-Fistcheck \\ 
-(Ernst F. Schroeder DJ7HS https://www.qsl.net/dj7hs/download.htm) ein Side-Tone Generator auf ARDUINO Basis mit regelbarer Frequenz \\ 
-und zwei Ausgängen deren Pegel unabhängig von einander regelbar ist enstanden.\\ 
-\\ 
-Schaltbild:\\ 
- 
-{{f11:technik:arduino:programme:arduinosidetonegenerator.png}} 
-\\ 
-Da hier der Einfachheit halber für jeden Ausgang ein eigender ARDUINO Pin genutzt wurde ist der Sketch etwas komplexer ausgefallen.\\ 
-Die allseits beliebte und bekannte Arduino Funktion [[https://www.arduino.cc/reference/de/language/functions/advanced-io/tone |tone()]] scheitert leider 
-mit der Ausgabe an den zweiten Pin.\\ 
-Da die Frequenz aber auch veränderbar sein sollte wenn der Ton ausgegeben wird und Ansätze mit delay bzw. der Abfrage von [[https://forum.arduino.cc/index.php?topic=503368.0| milis()]] unbefriedigend in der Ton-Qualität waren (Knacken) fand letzlich die Nutzung eines Interrupt-Handlers eines\\ 
-ARDUINO internen Timers der beim Überlauf eben jenen Interrupt erzeugt und die ensprechende Sub-Routine für die Interrupt Behandlung anspringt Anwendung.\\ 
-Der Vorteil dabei ist das der Timer wesentlich genauer ist als die delay() Funktion die einfach nur wartet und den Arduino zum Nichtstun verdammt.\\ 
-Der Timer wird vom Prozessor-Takt (16 Mhz) unabhängig vom Arduino Code hochgezählt. Beim Überlauf über 65536 wird der entsprechende Interrupt ausgelöst.\\ 
-Der Arduino unterbricht nun seine main-loop und behandelt erst mal den Code in der Interrupt-Handler Routine um danach an der Stelle in der Main-Loop\\ 
-fortzufahren an der der Interrupt zugeschlagen hat.\\ 
-Details dazu z.B.: \\ 
-https://www.instructables.com/id/Arduino-Timer-Interrupts/ \\ 
-und \\ 
-https://www.robotshop.com/community/forum/t/arduino-101-timers-and-interrupts/13072 \\ 
-\\ 
-Auf ein Beispiel aus dem Leben übertragen ist es so als wenn jemand den ganzen Tag am Fenster sitzt und auf den Post-Boten wartet.\\ 
-Alternativ kommt er jede Minute oder alle zwei zurück ans Fenster um zu schauen ob der Post-Bote da ist.\\ 
-Das ist nicht wirklich effektiv.\\ 
-Wie elegant ist es doch seine Aufgaben zu erledigen, und sich von der Türklingel (Dem Interrupt) dazu rufen zu lassen das Nötige mit dem Post-Boten zu regeln.\\ 
-\\ 
-Der Sketch unten ist dokumentiert und wird auf einem ARDUINO Nano genutzt.\\ 
-Andere Vertreter aus der ARDUINO Familie sind sicher auch möglich, der Code ist dann aber eventuell enstprechend anzupassen.\\  
- \\ 
- 
-<code> 
-/* 
-  CW Side-Tone genarator with adjustable frequency and two outputs (One for head-phones and one for PC-SoundCard 
-  The code has been written to train Morse-Code with straight key and check with Precision CW Fistcheck  
-  From Ernst F. Schroeder DJ7HS see https://www.qsl.net/dj7hs/download.htm 
-   
-  December 2018 Kai DM3KB 
- */ 
-  
-// Analog Pins 
-// 
-int potPin = 0;    // input pin for the potentiometer A0 Hardware Pin 19 
- 
-// Digital Pins 
-// 
-int         tonePin  = 10;       // Tone output to headphone pin D10 Hardware Pin 13 
-int         outpin   = 5;        // Tone output to PC pin D05  Hardware Pin 8 
-int         keyin    =  6;       // Input from Key pin D06  Hardware Pin 9 
-int         led      = 13;       // LED Pin D13 Hardware Pin 16 
- 
-// Declare Variables 
-int val = 0;       // variable to store the value read from the potentiometer 
-int wave = 1;     // variable to flag half wave 
-int timerstat = 0; // Timer Status Flag  
-int playflag = 0; //  Play Tone Flag 
-int ledstat = 0;  //  LED Status Flag 
-unsigned long LTCNT1;    // variable for Timer1 pre-set to match of halve-wave of a frequency 
- 
- 
-void setup() 
-{ 
-  // initialize the digital pin as an output. 
-  pinMode(tonePin, OUTPUT); // declare the tonePin as an OUTPUT 
-  pinMode(outpin, OUTPUT); // declare the outpin as an OUTPUT 
-  pinMode(led, OUTPUT);  // declare the ledPin as an OUTPUT   
-   
-  // Setup control input pins 
-  pinMode(keyin, INPUT);        
-   
-  // Setup control output pins 
-  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW 
-  
-  // Timer 1, set up to enable Overflow interrupt after 65536 with prescale 1 
-  noInterrupts();           // Switch of all Interrupts  
-  TCCR1A = 0;               // set entire TCCR0A register to 0 
-  TCCR1B = 0;               // set entire TCCR0B register to 0 
-  TCNT1 = 39168;            // Pre-Inizialize the Timer1 
-  TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10); // set 1 as Prescale-Wert 
-  TIMSK1 |= (1 << TOIE1);   // Activate Timer Overflow Interrupt  
-  interrupts();             // Enable all Interrupts again 
-   
-  //Serial.begin(9600);      // open the serial port at 9600 bps: 
-} 
- 
-// Interrupt -Handler for  
-// Timer1 Overflow 
-ISR(TIMER1_OVF_vect)         
-{ 
-  TCNT1 = LTCNT1;             // Init counter again with actual value from Poti           
-  if (playflag == 1) { 
-    // If play Flag valid (1) play  
-    // square-wave to both output pins with timing read from Potentiometer which meet the frequency 
-    if (wave == 1) { 
-      //Play positive wave part 
-      digitalWrite(tonePin, HIGH); 
-      digitalWrite(outpin, HIGH); 
-    } 
-    else { 
-      //Play negative wave part 
-      digitalWrite(tonePin, LOW); 
-      digitalWrite(outpin, LOW); 
-    } 
-  } 
-  wave = !wave;   // Toggel wave Flag  
-} 
- 
-// The (Main) loop routine runs over and over again forever: 
-void loop() 
-{ 
-  // Check if Key is pressed 
-    if (digitalRead(keyin)== LOW){ 
-    wave = 1; 
-    while(digitalRead(keyin)== LOW){ 
-      // As long key in is LOW (Key is pressed so we need an output!!!)  
-      
-      if (timerstat == 0 ) { 
-        //Serial.print(" = : Enable Interrupt Play\n"); 
-        playflag = 1; 
-        timerstat = 1; 
-      } 
-      if ( ledstat == 0 ) { 
-        digitalWrite(led, HIGH);    // turn the LED on by making the voltage HIGH 
-        ledstat = 1; 
-      } 
-      // Read tone frequency from Poti and map to sutialbe values 
-      val = analogRead(potPin);    // read the value from the sensor 
-      
-      // TCNT1 is the pre-set for the timer to start. 
-      // So Timer1 will count starting from 39168 or 55625 or any value in between and creating an  
-      // Overflow Interrupt when reaching 65536 
-      // It needs to be set to time that a halve wave of the frequency need. 
-      // Formula is here: 65536 - (65536 - 16000000 / 1 / 350 / 2) 
-      //                  Max Value of Timer  - ( Max Value of Timer / Arduino Clock Rate / PreScale / Frequency in Hz / 2 ) 
-      LTCNT1 = map(val, 0, 1023, 39168, 55625);  //Map to value for TCNT1: 350 Hz = 39168 - 1250 Hz = 55625 
-     
-      // Generate square-wave to both output pins with frequency read from Potentiometer 
-      // by Timer1 Interrupt routine ISR(TIMER1_OVF_vect)   
-       
-    } 
-  } 
-   
-    if (digitalRead(keyin)== HIGH){ 
-    while(digitalRead(keyin)== HIGH){ 
-      // Key has bee released so no output 
-      if ( timerstat == 1 ) { 
-        //Serial.print(" = : Disable Interrupt Play\n"); 
-        playflag = 0; 
-        timerstat = 0; 
-      } 
-      wave = 0; 
-      // But check Speed-Potentiometer 
-      val = analogRead(potPin);    // read the value from the sensor 
-      LTCNT1 = map(val, 0, 1023, 39168, 55625);  //Map to value for TCNT1: 350 Hz = 39168 - 1250 Hz = 55625 
-       
-      if ( ledstat == 1 ) { 
-        digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW 
-        ledstat = 0; 
-      } 
-    } 
-  } 
-} 
-// End 
-</code> 
- 
-Zurück zu: [[F11:Arduino:Programme|f11:technik:arduino:start#Programme]] 
f11/technik/arduino/programme/arduino-side-tone-generator.txt · Zuletzt geändert: 2019/09/29 12:03 (Externe Bearbeitung)
CC Attribution-Noncommercial-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0