/* Directly create your own sounds using a bit of math! This code uses frequency modulation like tone() command setting pin HIGH and LOW. Volume cannot be easily controlled using this technique. Also, each moment of time has only a single frequency. To produce any type of sound like the PCM library can do, hardware timers must be used. I do not use them here. On nearly all Arduino models, the timers tick at 16 MHz (16 times every us), whereas basic math operations seem to take at least 4 us, and micros() has a resolution of 4 us (much larger than 1/16 us). For controlling a passive buzzer, earbuds, or line out. Use a 220 ohm resistor in series with passive buzzer or earbuds. Use something like a 100,000 ohm resistor for line out to reduce voltage below 2 V. Select the type of sound by choosing which of the "t = " lines is uncommented in loop(). Except for the 400 Hz constant tone, all of my sounds use the complete 80 Hz to 2000 Hz range. Note that, for most models of Arduino, double and float are the same thing giving only 6 to 7 digits of precision, which causes sound distortion when millis() gets large (after about 1000 seconds). So I have to use the modulo operation when calling millis(). (c) 2018 Bradley Knockel */ const byte pin = 8; // how long is each pulse in milliseconds // good values: 200, 1000, 2000 unsigned long int period=1000; void setup() { pinMode(pin,OUTPUT); } float val; // from 0 to 1 float per = period; // in milliseconds unsigned long int t; // half the period of the sound wave in microseconds unsigned long int timee=micros(); // keeping track of time in microseconds void loop() { val = (millis()%period)/per; // sin^2(t) -> t //t = 250 + int(6000.0*pow(sin(PI*val),2.0)); // sin(t) -> t //t = 250 + int(6000.0*(sin(2.0*PI*val)+1.0)/2.0); // sin(e^t) -> t // works well with longer period //t = 250 + int(6000.0*(sin(2.0*PI*exp(val)*20.0)+1.0)/2.0); // decimalPart(t) -> t //t = 250 + int(6000.0*val); // decimalPart(t) -> f t = 1000000.0/(160.0 + 3840.0*val); // decimalPart(-t) -> t //t = 250 + int(6000.0*(1.0-val)); // decimalPart(-t) -> f //t = 1000000.0/(160.0 + 3840.0*(1.0-val)); // e^(decimalPart(t)) -> t // e^(-decimalPart(t)) -> f //t = exp(log(250.0)+log(25.0)*val); // e^(-decimalPart(t)) -> t // e^(decimalPart(t)) -> f //t = exp(log(250.0)+log(25.0)*(1-val)); // e^(sin(t)) -> t //t = exp(log(250.0)+log(25.0)*(sin(2.0*PI*val)+1.0)/2.0); // 400 Hz tone //t = 1000000/(2*400); while(micros() < timee) {} digitalWrite(pin, HIGH); timee += t; while(micros() < timee) {} digitalWrite(pin, LOW); timee += t; }