bitshift mapping a number with sine wave generator

so i found this sine wave sketch and i want to make it adjustable. reading through documentation, I’m trying to take a number that is a bit shift in the sketch and map it to a pot. everything I’ve tried has disabled the first mapped pot in the sketch. heres the code:

as you read below, the number i want to map from 1-28 with a pot is this portion:

icnt=phaccu >> 24; <<this number. refer to rest of code below.

#include "avr/pgmspace.h"

// table of 256 sine values / one sine period / stored in flash memory
PROGMEM  prog_uchar sine256[]  = {

#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


  // 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;
 tword_m = dfreq;
tword_m = map(tword_m, 0, 140032752, 0, 1023 );      // 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("  ");

   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 (this is also what i want to map from 1-28)
                         // 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

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

Such a long program and so little explanation.

truthfully i dont understand everything going on inside it. i know what number causes the result i want, and i want a way to map it according to pot values. refer above for specifics

Can you make this a bit less complicated by using the sin function?

i do not understand at all how to apply that.

Tell us what you are trying to do again. The first time you mentioned in OP didn't make sense. What is a bit shift? Does the pot control something, and what?

basically its shifting within binary. i think. i mentioned the line of code from my sketch, which was this:

phaccu=phaccu+tword_m; // soft DDS, phase accu with 32 bits

icnt=phaccu >> 24; // this number, 24, i want to be able to become adjustable with mapped values from a pot with a min or 1 and max of 28.

hope this clarified a bit.

You're trying to vary the position of the binary point in your phase accumulator?

FYI: This probably won't give you precise results because the pow function does not work well with integers.

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

You could define a long integer like this:

const int64_t TWO_E32 = 0x100000000LL;

and then use:


For your question about the bit shift, you could try this:

icnt=phaccu >> map(analog_value, 0,1023, 0,28 );

where analog_value is the value from analogRead.


The size of the sine table to use less space can be folded see -,69723.0.html -