Pages: [1]   Go Down
Author Topic: sine, wave, saw-tooth, triangle wave generator code needed  (Read 4653 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 538
Posts: 27081
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Jr. Member
**
Karma: 2
Posts: 97
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34143
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
// 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);
 
}
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34143
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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?
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 351
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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. smiley
Logged

10 LET Loop=Infinite
20 GO TO 10

Montreal
Offline Offline
Faraday Member
**
Karma: 29
Posts: 2590
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You may study this project : http://www.pyroelectro.com/tutorials/waveform_generator/
Code posted: http://www.pyroelectro.com/tutorials/waveform_generator/software.html
Than customize for your needs.
Logged

2nd star on the right
Offline Offline
Full Member
***
Karma: 0
Posts: 103
Everything I am is classified under the official secreats act!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Sorry for the noobish post but my knowledge is 10 years out of date!

Santa Fe, NM
Offline Offline
Newbie
*
Karma: 0
Posts: 12
in case of fire break glass
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perhaps GinSing Board?

http://www.ginsingsound.com
Logged

Pages: [1]   Go Up
Jump to: