sine, wave, saw-tooth, triangle wave generator code needed

I'm trying to make 4 tone generators one for each of the sound waves I mentioned in the title using the arduino uno, would anybody be willing to help me?

I need each tone generator to have two potentiometers, one that controls pitch and perhaps ranges over 3 octaves and the second potentiometer should control the tone in a pulsing fashion ranging from perhaps 2 or 3 seconds to 0 (a continuous tone)

If anyone can help with at last one of the wave forms please do.
It's for an art project and anybody that helps me achieve my goal will of course receive acknowledgement.

Are you willing to use an external ADC?
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en024015

have a look at this:
http://wiki.openmusiclabs.com/wiki/MiniArDSP

if it looks like something that would work for you, i can give pointers on how to modify it to make variable frequencies. there is already a 16b sinewave lookup table included with the library.

I'm looking for the simplest way to make the 4 wave forms separately with only one potentiometer instead of two. My major problem is i don't understand code very well. I'm extremely new and basicly need someone to hold my hand the whole way through this.

matthewhickey:
I'm extremely new and basicly need someone to hold my hand the whole way through this.

The thing is that it is not a simple thing to do. Any hand holding, would I suspect, would amount to someone doing it for you.

Yes you can do it with an arduino but you could achieve the same effect very much simpler without by building the tone generators from operational amplifiers.

i need to add a potentiometer that controls the speed of the tone beeping on and off

// Wavetable Synth
// Adapted by Becky Stewart from
// mechomaniac.com
 
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
 
// Map all the input and output pins
#define potPin 0
#define speakerPin 11
#define buttonPin 7
 
 
#define INTERRUPT_PERIOD 512
#define FINT (F_CPU / INTERRUPT_PERIOD) // 16kHz?
#define FS (FINT)
 
// sine lookup table pre-calculated
prog_uchar PROGMEM sinetable[256] = {
  128,131,134,137,140,143,146,149,152,156,159,162,165,168,171,174,
  176,179,182,185,188,191,193,196,199,201,204,206,209,211,213,216,
  218,220,222,224,226,228,230,232,234,236,237,239,240,242,243,245,
  246,247,248,249,250,251,252,252,253,254,254,255,255,255,255,255,
  255,255,255,255,255,255,254,254,253,252,252,251,250,249,248,247,
  246,245,243,242,240,239,237,236,234,232,230,228,226,224,222,220,
  218,216,213,211,209,206,204,201,199,196,193,191,188,185,182,179,
  176,174,171,168,165,162,159,156,152,149,146,143,140,137,134,131,
  128,124,121,118,115,112,109,106,103,99, 96, 93, 90, 87, 84, 81, 
  79, 76, 73, 70, 67, 64, 62, 59, 56, 54, 51, 49, 46, 44, 42, 39, 
  37, 35, 33, 31, 29, 27, 25, 23, 21, 19, 18, 16, 15, 13, 12, 10, 
  9,  8,  7,  6,  5,  4,  3,  3,  2,  1,  1,  0,  0,  0,  0,  0,  
  0,  0,  0,  0,  0,  0,  1,  1,  2,  3,  3,  4,  5,  6,  7,  8,  
  9,  10, 12, 13, 15, 16, 18, 19, 21, 23, 25, 27, 29, 31, 33, 35, 
  37, 39, 42, 44, 46, 49, 51, 54, 56, 59, 62, 64, 67, 70, 73, 76, 
  79, 81, 84, 87, 90, 93, 96, 99, 103,106,109,112,115,118,121,124
};
 
// lookup table for output waveform
unsigned char wavetable[256];
 
unsigned int frequencyCoef = 100;
bool soundEnabled = true;
bool soundPWM = false;
bool soundOn = false;
 
int currentVoice = 0;
 
/*----------------------------------------------------
 functions to handle converting PCM to PWM and 
 outputting sound
 ----------------------------------------------------*/
 
// This is called at sampling freq to output 8-bit samples to PWM
ISR(TIMER1_COMPA_vect)
{
  static unsigned int phase0;
  static unsigned int sig0;
  static unsigned char flag = 0;
  static unsigned int tempphase;
 
  if (soundPWM)
  {
    tempphase = phase0 + frequencyCoef;
    sig0 = wavetable[phase0>>8];
    phase0 = tempphase;
    OCR2A = sig0; // output the sample
  } 
  else { //square wave 
    flag ^= 1;
    digitalWrite(speakerPin, flag);
  }
}      
 
 
 
void setupPWMSound()
{
  // Set up Timer 2 to do pulse width modulation on the speaker pin.
  // Use internal clock (datasheet p.160)
  ASSR &= ~(_BV(EXCLK) | _BV(AS2));
  // Set fast PWM mode  (p.157)
  TCCR2A |= _BV(WGM21) | _BV(WGM20);
  TCCR2B &= ~_BV(WGM22);
  // Do non-inverting PWM on pin OC2A (p.155)
  // On the Arduino this is pin 11.
  TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
  TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
  // No prescaler (p.158)
  TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
  // Set initial pulse width to the first sample.
  OCR2A = 0;
  // Set up Timer 1 to send a sample every interrupt.
  cli();
  // Set CTC mode (Clear Timer on Compare Match) (p.133)
  // Have to set OCR1A *after*, otherwise it gets reset to 0!
  TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
  TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
  // No prescaler (p.134)
  TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
  // Set the compare register (OCR1A).
  // OCR1A is a 16-bit register, so we have to do this with
  // interrupts disabled to be safe.
  OCR1A = INTERRUPT_PERIOD;
  // Enable interrupt when TCNT1 == OCR1A (p.136)
  TIMSK1 |= _BV(OCIE1A);
  sei();
  soundPWM = true;
}
 
void startSound()
{
  // Enable interrupt when TCNT1 == OCR1A (p.136)  
  cli();
  TIMSK1 |= _BV(OCIE1A);
  sei();
  soundOn = true;
} 
 
void stopSound()
{
  cli();  
  // Disable playback per-sample interrupt.
  TIMSK1 &= ~_BV(OCIE1A);
  sei();
  soundOn = false;
}
 
void setFrequency(unsigned int freq)
{
  if (soundPWM) {
    unsigned long templong = freq;
    frequencyCoef = templong * 65536 / FS;
  } 
  else {
    unsigned long periode = F_CPU/(2*freq); //multiply by 2, because its only toggled once per cycle
    cli();
    OCR1A = periode;
  }
}
 
/*----------------------------------------------------
 functions to determine the wavetable content
 ----------------------------------------------------*/
void loadVoice(int voice)
{
  if(soundOn) // if sound is on
  {
    stopSound(); // turn sound off
  }
  switch (voice)
  {
  // sine
  case 0:
    sineWave();
    break;
  // sawtooth
  case 1:
    sawtoothWave();
    break;
  // triangle
  case 2:
    triangleWave();
    break;
  // square
  case 3:
    squareWave();
    break;
  }
  if(!soundPWM) 
  {
    setupPWMSound();
  }
  startSound(); // start sound again
}
 
void sineWave()
{
  for (int i = 0; i < 256; ++i) {
    wavetable[i] = pgm_read_byte_near(sinetable + i);
  }
}
 
void sawtoothWave()
{
  for (int i = 0; i < 256; ++i) {
    wavetable[i] = i; // sawtooth
  }
}
 
 
void triangleWave()
{
  for (int i = 0; i < 128; ++i) {
    wavetable[i] = i * 2;
  }
  int value = 255;
  for (int i = 128; i < 256; ++i) {
    wavetable[i] = value;
    value -= 2;
  }
}
 
void squareWave()
{
  for (int i = 0; i < 128; ++i) {
    wavetable[i] = 1;
  }
  for (int i = 128; i < 256; ++i) {
    wavetable[i] = 0;
  }
}
 
/*----------------------------------------------------
 setup and loop functions
 ----------------------------------------------------*/
int prevButtonValue = 0;
 
void setup()
{ 
  pinMode(speakerPin, OUTPUT); 
  pinMode(buttonPin, INPUT); 
  // Choose one signal type to initially load into wavetable
  // 0 - sine
  // 1 - sawtooth
  // 2 - triangle
  // 3 - square  
  loadVoice(currentVoice);
} 
 
 
void loop() 
{
  // read all sensor values
  int inputButtonValue = digitalRead(buttonPin);
  // if button is pressed wasn't pressed before
  if(inputButtonValue == HIGH && inputButtonValue != prevButtonValue)
  {
     currentVoice = (currentVoice + 1) %4;
     loadVoice(currentVoice);
 
  }
  prevButtonValue = inputButtonValue;
 
  //read from potentiometer
  int inputPotValue = analogRead(potPin); 
  int freq = map(inputPotValue, 0, 1023, 440, 1760); 
  setFrequency(freq);
  delay(50);
 
}

i need to add a potentiometer that controls the speed of the tone beeping on and off

Was that a question?
What was the code?
I assume it is some random code you found. What effort have you put in so far?

What you want, would probably better done with analog electronics, if you dont master coding.
Also ( out of subject, but related to post) :Am impressed with the work on ArDSP... Low level solution for the maths.

Mike : I came to appreciate your posts more and more with time. :slight_smile:

You may study this project : Arduino Waveform Generator - Introduction | PyroElectro - News, Projects & Tutorials
Code posted: Arduino Waveform Generator - Software | PyroElectro - News, Projects & Tutorials
Than customize for your needs.

Without knowing more, It looks like the OP is building the generator input stage for a SID chip

Perhaps GinSing Board?

http://www.ginsingsound.com