Tone generator with JavaScript. Frequencymeter with Arduino

Hello friends,

in this message I posted an extension to generate tones:

Now we are going to build a tone generator using JavaScript and measure its frequency with Arduino.

If you want you can take a look at my tutorial in Spanish:
http://kio4.com/arduino/6B_Frecuencimetro.htm

We'll start with Arduino...

1 Like

1.- Frequency meter with Arduino.

int input=12;

int high_time;
int low_time;
float time_period;
float frequency;

void setup()
{
Serial.begin(9600);
pinMode(input,INPUT);
}

void loop(){
high_time=pulseIn(input,HIGH);
low_time=pulseIn(input,LOW);

time_period=high_time+low_time;
time_period=time_period/1000;
frequency=1000/time_period;
Serial.println(frequency);
delay(1000);
}		

2.- Connections. Amplifier.

  • The sound signal that comes out through the headphone jack of mobile phones usually has a maximum voltage of about 200 mV.

  • Arduino works with 5V digital inputs, so we need an amplifier to turn the voltage up from 200mV to 5V.

  • The amplifier can work in cut/saturation, it does not need to be linear amplification

  • We will use this amplifier module: module LM386

3.- Tone generator with JavaScript.

I adapted this code from this website:

sonido2.html

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head><body>
<body>
<!-- <button onclick='beep();'>Play</button> -->
<script>
    datos =  window.AppInventor.getWebViewString(); // Entrada de datos.
    datos = datos + ":";  
  
    valores = datos.split(":"); 
    frequency = valores[0];
    type = valores[1];
	volume = valores[2];
    duration = valores[3];

audioCtx = new(window.AudioContext || window.webkitAudioContext)();
function beep() {

  var oscillator = audioCtx.createOscillator();
  var gainNode = audioCtx.createGain();
  oscillator.connect(gainNode);
  gainNode.connect(audioCtx.destination);
  
  gainNode.gain.value = volume;
  oscillator.frequency.value = frequency;
  oscillator.type = type;

  oscillator.start();

  setTimeout(
    function() {
      oscillator.stop();
    },
    duration
  );
};

 beep()
</script>
</body>			

4.- App Inventor code.

p67B_JavaScript_generadortonoi.aia (8.3 KB)

- Serial Monitor.

We introduce a 1000 Hz signal, observe the error.

5.- Other code.

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head><body>
<body>
 <button onclick='play();'>Play</button>
<script>
var frequency = 1000;
var data = {
    1: {duration:500, sleep:1000},
    0: {duration:500, sleep:500}
}
var audio = new(window.AudioContext || window.webkitAudioContext)();

//function creates an Oscillator. In this code we are creating an Oscillator for every tune, which help you control the gain. 
//If you want, you can try creating the Oscillator once and stopping/starting it as you wish.
function createOscillator(freq, duration) {
    var attack = 10, //duration it will take to increase volume full sound volume, makes it more natural
        gain = audio.createGain(),
        osc = audio.createOscillator();

    gain.connect(audio.destination);
    // gain.gain.setValueAtTime(0, audio.currentTime); //change to "1" if you're not fadding in/out
    // gain.gain.linearRampToValueAtTime(1, audio.currentTime + attack / 1000); //remove if you don't want to fade in
    // gain.gain.linearRampToValueAtTime(0, audio.currentTime + duration / 1000); //remove if you don't want to fade out
	gain.gain.value = 4;

    osc.frequency.value = freq;
    osc.type = "sine";
    osc.connect(gain);
    osc.start(0);


    setTimeout(function() {
        osc.stop(0);
        osc.disconnect(gain);
        gain.disconnect(audio.destination);
    }, duration)
}

function play() {
    //your pattern
    var song = [1,0,0,0,0];       

    timeForNext = 0;
    for (i=0;i<song.length;i++){            
        duration = data[song[i]].duration;
        //use timeout to delay next tune sound
        window.setTimeout(function(){
            createOscillator(frequency, duration);
        },timeForNext);         
        timeForNext+=data[song[i]].sleep;       
    }
}

//play the music
play();
</script>
</body>										
			

With the arrival of the runJavascript block for the Webviewer, it is now possible to play a tone/tones with an empty, hidden webviewer:


(note: I have shown the four options for "type")

Draggable Procedure

Example JS playing a 1 second sine wave of A4
var frequency = 440; 
var type = 'sine'; 
var volume = 0.5; 
var duration = 1000; 
var audioCtx = new AudioContext(); 
var oscillator = audioCtx.createOscillator();   
var gainNode = audioCtx.createGain();   
oscillator.connect(gainNode);   
gainNode.connect(audioCtx.destination);      
gainNode.gain.value = volume;   
oscillator.frequency.value = frequency;   
oscillator.type = type;    
oscillator.start();    
setTimeout(     function() {      
 oscillator.stop();    
 },     
duration   );
1 Like

(added to FAQ)