Errors in code

Hi all,

I'm new to this forum as well as using Arduino; I am trying to generate a 8 kHz sine wave that can be modulated to transmit data. I have numerous sites that have code that can be use to generate a sine wave using the DDS method. The problem is when I compile the code, I am getting two errors, they are undefined reference to 'setup' and 'loop'. If anyone can help with this problem it would be greatly appreciated. Thanks in advance.

(deleted)

See the setup() and loop() functions - you must declare and use them in your code.

Pete

Sorry, here is the code I tried using:

/*
 *
 * DDS Sine Generator mit ATMEGS 168
 * Timer2 generates the  31250 KHz Clock Interrupt
 *
 * KHM 2009 /  Martin Nawrath
 * Kunsthochschule fuer Medien Koeln
 * Academy of Media Arts Cologne

 */

#include "avr/pgmspace.h"

// table of 256 sine values / one sine period / stored in flash memory
PROGMEM  prog_uchar sine256[]  = {
  127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
  242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
  221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,
  76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,
  33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124

};
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

int ledPin = 13;                 // LED pin 7
int testPin = 7;
int t2Pin = 6;
byte bb;

double dfreq;
// const double refclk=31372.549;  // =16MHz / 510
const double refclk=31376.6;      // measured

// variables used inside interrupt service declared as voilatile
volatile byte icnt;              // var inside interrupt
volatile byte icnt1;             // var inside interrupt
volatile byte c4ms;              // counter incremented all 4ms
volatile unsigned long phaccu;   // pahse accumulator
volatile unsigned long tword_m;  // dds tuning word m

void setup()
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
  Serial.begin(115200);        // connect to the serial port
  Serial.println("DDS Test");

  pinMode(6, OUTPUT);      // sets the digital pin as output
  pinMode(7, OUTPUT);      // sets the digital pin as output
  pinMode(11, OUTPUT);     // pin11= PWM  output / frequency output

  Setup_timer2();

  // disable interrupts to avoid timing distortion
  cbi (TIMSK0,TOIE0);              // disable Timer0 !!! delay() is now not available
  sbi (TIMSK2,TOIE2);              // enable Timer2 Interrupt

  dfreq=1000.0;                    // initial output frequency = 1000.o Hz
  tword_m=pow(2,32)*dfreq/refclk;  // calulate DDS new tuning word 

}
void loop()
{
  while(1) {
     if (c4ms > 250) {                 // timer / wait fou a full second
      c4ms=0;
      dfreq=analogRead(0);             // read Poti on analog pin 0 to adjust output frequency from 0..1023 Hz

      cbi (TIMSK2,TOIE2);              // disble Timer2 Interrupt
      tword_m=pow(2,32)*dfreq/refclk;  // calulate DDS new tuning word
      sbi (TIMSK2,TOIE2);              // enable Timer2 Interrupt 

      Serial.print(dfreq);
      Serial.print("  ");
      Serial.println(tword_m);
    }

   sbi(PORTD,6); // Test / set PORTD,7 high to observe timing with a scope
   cbi(PORTD,6); // Test /reset PORTD,7 high to observe timing with a scope
  }
 }
//******************************************************************
// timer2 setup
// set prscaler to 1, PWM mode to phase correct PWM,  16000000/510 = 31372.55 Hz clock
void Setup_timer2() {

// Timer2 Clock Prescaler to : 1
  sbi (TCCR2B, CS20);
  cbi (TCCR2B, CS21);
  cbi (TCCR2B, CS22);

  // Timer2 PWM Mode set to Phase Correct PWM
  cbi (TCCR2A, COM2A0);  // clear Compare Match
  sbi (TCCR2A, COM2A1);

  sbi (TCCR2A, WGM20);  // Mode 1  / Phase Correct PWM
  cbi (TCCR2A, WGM21);
  cbi (TCCR2B, WGM22);
}

//******************************************************************
// Timer2 Interrupt Service at 31372,550 KHz = 32uSec
// this is the timebase REFCLOCK for the DDS generator
// FOUT = (M (REFCLK)) / (2 exp 32)
// runtime : 8 microseconds ( inclusive push and pop)
ISR(TIMER2_OVF_vect) {

  sbi(PORTD,7);          // Test / set PORTD,7 high to observe timing with a oscope

  phaccu=phaccu+tword_m; // soft DDS, phase accu with 32 bits
  icnt=phaccu >> 24;     // use upper 8 bits for phase accu as frequency information
                         // read value fron ROM sine table and send to PWM DAC
  OCR2A=pgm_read_byte_near(sine256 + icnt);    

  if(icnt1++ == 125) {  // increment variable c4ms all 4 milliseconds
    c4ms++;
    icnt1=0;
   }   

 cbi(PORTD,7);            // reset PORTD,7
}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

That compiles fine for me.

(deleted)

Thanks for all of your help; I don't know why the code wasn't compiling, but I took your suggestion and used the code I posted and there were no errors, very frustrating. Generating the sine wave was the first step, my team is trying to modulate and then demodulate this sine wave to transmit two bits. Does anyone know of an easy way to do this using the existing code?

Hey! My brain just suddenly crashed into gear when it scanned a piece of your code.

      tword_m=pow(2,32)*dfreq/refclk;  // calulate DDS new tuning word

You are using an AD9851 - in a DDS-60 perhaps??

The modulation scheme depends to some extent upon what you are using to receive and demodulate the signal. You culd make life easy for yourself and use something as trivial as on/off keying similar to Morse Code. Or, a bit more complex, you could use something like AFSK where you modulate the 8kHz with one of two tones to represent zero and one. The problem is that these and more complicated schemes require FFT code. There is some FFT code for the Arduino but I have only used it in a static situation where I generated a signal and then did the FFT and displayed the result. Doing it on-the-fly is probably possible but I wouldn't want to have to do it.

Pete

You just change the frequency of the 8KHz tone a little to say 8.1KHz for a zero and back to 8.0KHz for a one.
That is called frequency modulation FM.
Changing the amplitude is anther way drop it by 30% for a zero and back up to full power for a one. That is called amplitude modulation AM.

The carrier is not really high enough for AFSK (audio frequency shift keying) but you do not need to use an FFT to generate it. Also AFSK is not a modulation method as such. It is done by either FM or AM of a tone on a carrier.

There are other modulation methods as well but all are derivatives of AM or FM.

You just change the frequency of the 8KHz tone a little to say 8.1KHz for a zero and back to 8.0KHz for a one.
That is called frequency modulation FM

That is Frequency Shift Keying because it is just toggling between two frequencies. It is FM in the sense that FSK is just an extreme form of FM, shifting abruptly between two frequencies rather than changing the frequency up and down smoothly as you would when sending audio.

but you do not need to use an FFT to generate it

I meant for decoding but I didn't make that clear.

The carrier is not really high enough for AFSK

You can do it. See my example of modulating a 240Hz tone on a 1280Hz "carrier" in my post "Playing with FFT" in the Science and Measurement forum.

Pete

Code:
but you do not need to use an FFT to generate it

I meant for decoding but I didn't make that clear.

You don't need an FFT to decode it either. Years ago I made an RTTY demodulator that was basically an AFSK demodulator. This was done with a simple FM discriminator. You can also do it with an exclusive OR logic gate, a slope filter, or a tone decoder. Yes you can use an FFT as well but this is way over kill for something that simple.

See my example of modulating a 240Hz tone on a 1280Hz "carrier"

Yes you can do that but most of the time AFSK is done on carries very much greater than the modulating frequency. There is little or no practical use / advantage in modulating a 240Hz tone on a 1207Hz carrier is there.

Thanks for all the input; this is for an underwater communication device, so as long as transmitter can send the signal, the lower the frequency the better. We originally wanted to use PSK to modulate the sine wave and we have done so in Simulink, my problem is that I'm not that strong of a programmer. All the theory and math, I'm ok with and using Simulink is not a problem. Trying to do this in C on a arduino is giving me all kinds of problems. Thanks again for all of your input and suggestions.