Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
f11:technik:arduino:programme:arduino-side-tone-generator [2018/12/27 08:29] 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:// | ||
- | und zwei Ausgängen deren Pegel unabhängig von einander regelbar ist enstanden.\\ | ||
- | \\ | ||
- | Schaltbild: | ||
- | |||
- | {{f11: | ||
- | \\ | ||
- | 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:// | ||
- | 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:// | ||
- | fand letzlich die Nutzung eines ARDUINO internen Timers der beim Überlauf einen Interrupt erzeugt Anwendung.\\ | ||
- | 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 eventuell enstprechend anzupassen.\\ | ||
- | \\ | ||
- | |||
- | < | ||
- | /* | ||
- | 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:// | ||
- | | ||
- | December 2018 Kai DM3KB | ||
- | */ | ||
- | |||
- | // Analog Pins | ||
- | // | ||
- | int potPin = 0; // input pin for the potentiometer A0 Hardware Pin 19 | ||
- | |||
- | // Digital Pins | ||
- | // | ||
- | int | ||
- | int | ||
- | int | ||
- | int | ||
- | |||
- | // 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; | ||
- | |||
- | |||
- | void setup() | ||
- | { | ||
- | // initialize the digital pin as an output. | ||
- | pinMode(tonePin, | ||
- | pinMode(outpin, | ||
- | pinMode(led, | ||
- | | ||
- | // Setup control input pins | ||
- | pinMode(keyin, | ||
- | | ||
- | // Setup control output pins | ||
- | digitalWrite(led, | ||
- | |||
- | // Timer 1, set up to enable Overflow interrupt after 65536 with prescale 1 | ||
- | noInterrupts(); | ||
- | TCCR1A = 0; // set entire TCCR0A register to 0 | ||
- | TCCR1B = 0; // set entire TCCR0B register to 0 | ||
- | TCNT1 = 39168; | ||
- | TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10); // set 1 as Prescale-Wert | ||
- | TIMSK1 |= (1 << TOIE1); | ||
- | interrupts(); | ||
- | | ||
- | // | ||
- | } | ||
- | |||
- | // Interrupt -andler for | ||
- | // Timer1 Overflow | ||
- | ISR(TIMER1_OVF_vect) | ||
- | { | ||
- | TCNT1 = LTCNT1; | ||
- | 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, | ||
- | digitalWrite(outpin, | ||
- | } | ||
- | else { | ||
- | //Play negative wave part | ||
- | digitalWrite(tonePin, | ||
- | digitalWrite(outpin, | ||
- | } | ||
- | } | ||
- | wave = !wave; | ||
- | } | ||
- | |||
- | // 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!!!) | ||
- | // Enable Interrupt | ||
- | |||
- | if (timerstat == 0 ) { | ||
- | // | ||
- | playflag = 1; | ||
- | timerstat = 1; | ||
- | } | ||
- | if ( ledstat == 0 ) { | ||
- | digitalWrite(led, | ||
- | ledstat = 1; | ||
- | } | ||
- | // Read tone frequency from Poti and map to sutialbe values | ||
- | val = analogRead(potPin); | ||
- | |||
- | // 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 | ||
- | // I 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); | ||
- | | ||
- | // 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 ) { | ||
- | // | ||
- | playflag = 0; | ||
- | timerstat = 0; | ||
- | } | ||
- | wave = 0; | ||
- | // But check Speed-Potentiometer | ||
- | val = analogRead(potPin); | ||
- | LTCNT1 = map(val, 0, 1023, 39168, 55625); | ||
- | | ||
- | if ( ledstat == 1 ) { | ||
- | digitalWrite(led, | ||
- | ledstat = 0; | ||
- | } | ||
- | } | ||
- | } | ||
- | } | ||
- | // End | ||
- | </ |