Help to get Sine wave in this code

I finally managed to get a Tap Tempo code working (with help of an example found on the web).
The output of this Tap Tempo PWM is square wave. But since I would like to use it in a musical context (as an LFO) i want to add a Sine Wave to and maybe others.

I tried to apply this simple line in the code:

for(counter=0; counter<=255; counter+=25)
{analogWrite(3, counter)

This worked in an other code but not in this one.

Here is the code i use:

#include <LCD4Bit.h>

/*
    Tap Tempo
*/
LCD4Bit lcd = LCD4Bit(2);

void setup()
{
  pinMode( 2, INPUT );   /* tap button - press it to set the tempo */ 
  pinMode( 3, OUTPUT );  /* tempo display light - shows the current tempo */
  Serial.begin(9600);
  lcd.init();
  StartupMessage();
}

void StartupMessage()
{
  lcd.clear();
  lcd.cursorTo (1, 2);
  lcd.printIn ("RoBo DIGITAL");
  delay(1000);
  lcd.cursorTo (2, 0);
  lcd.printIn ("Tap Tempo LFO v1");
  delay(1000);
  lcd.clear();
  lcd.printIn ("Knob1 = Subdivision");
  delay(1000);
  lcd.clear();
  lcd.printIn ("Knob2 = Depth");
  delay(1000);
  lcd.clear();
  lcd.printIn ("Knob3 = Waveshape");
  delay(1000);
  lcd.clear();
  lcd.printIn ("Footsw = TT");
  delay(1000);
  lcd.clear();
}

const int     potSub = 0;
const int     potDepth = 1;
const int     potWave = 2;
int           Waveshape;
int           Square;
int           Sub;
int           depth;
int           lastTapState = LOW;  /* the last tap button state */
unsigned long currentTimer[2] = { 500, 500 };  /* array of most recent tap counts */
unsigned long timeoutTime = 0;  /* this is when the timer will trigger next */

unsigned long indicatorTimeout; /* for our fancy "blink" tempo indicator */


void checkSub()
{
  int v = analogRead (potSub);
  if(v >= 0 && v <=255)
  {
    Sub = 1; // sixteen
  }
  else if (v >= 255 && v <=510)
  {
    Sub = 2; // eight
  }
  else if (v >= 510 && v <=765)
  {
    Sub = 3; // dotted eight
  }
    else if (v >765)
  {
    Sub = 4; // quarter
  }
  updateDisplay();
}

void updateDisplay()
{
lcd.cursorTo(1, 0);
if (Sub == 1)
{
lcd.printIn ("Subd = 1/16");
}
else if (Sub == 2)
{
  lcd.printIn ("Subd = 1/8 ");
}
else if (Sub == 3)
{
  lcd.printIn ("Subd = 1/8*");
}
else if (Sub == 4)
{
  lcd.printIn ("Subd = 1/4 ");
}
}

   
void loop()
{
  /* read the button on pin 12, and only pay attention to the
     HIGH-LOW transition so that we only register when the
     button is first pressed down */
  int tapState = digitalRead( 2 );
  Serial.println(tapState);
  if( tapState == LOW && tapState != lastTapState )
  {
    tap(); /* we got a HIGH-LOW transition, call our tap() function */
  }
  lastTapState = tapState; /* keep track of the state */
  
  /* check for timer timeout */
  if( millis() >= timeoutTime )
  {
    /* timeout happened.  clock tick! */
    Waveshape = analogRead(potWave)/4;
    indicatorTimeout = millis() + (Waveshape);  /* this sets the time when LED 13 goes off */
    /* and reschedule the timer to keep the pace */
    rescheduleTimer();
  }
  
depth = analogRead (potDepth)/4;

  /* display the tap blink on LED 3 */

  if( millis() < indicatorTimeout ) 
    {
      analogWrite( 3, 255 );
      }
  else 
   {
      analogWrite( 3, depth);
   }
}

unsigned long lastTap = 0; /* when the last tap happened */
void tap()
{
  /* we keep two of these around to average together later */
  currentTimer[1] = currentTimer[0];
  currentTimer[0] = millis() - lastTap;
  lastTap = millis();
  timeoutTime = 0; /* force the trigger to happen immediately - sync and blink! */
  Serial.println(lastTap);
}

void rescheduleTimer()
{
    /* set the timer to go off again when the time reaches the 
       timeout.  The timeout is all of the "currentTimer" values averaged
       together, then added onto the current time.  When that time has been
       reached, the next tick will happen...
    */
    checkSub();
    timeoutTime = millis() + (((currentTimer[0] + currentTimer[1])/8)*Sub);
}

Now this is where the square wave is generated.

  if( millis() < indicatorTimeout ) 
    {
      analogWrite( 3, 255 );
      }
  else 
   {
      analogWrite( 3, depth);
   }

Now how can i add a sine wave to this. I can not use a delay here to.
The ms is stored in currentTimer[0] and [1]. But i can’t use them like this:

for (counter = 0; counter <= 255; counter += 25)
{
analogWrite (3, counter);
delay (currentTimer[1]);
}
for (counter = 255; counter >=0; counter -= 25)
{
analogWrite (3, counter);
delay (currentTimer[1]);

Hope i made it clear here if not feel free to jump in. bye the way i use pin 3 for the PWM, does that one work with millis()?

best regards
Ronald

I think that might give you a triangle wave, assuming you feed it through a suitable filter. The times I’ve seen a sine wave generated digitally, they use a DAC with a lookup table. The table contains appropriate values for the sine.

Remember, PWM isn’t really an analog output. It’s a square wave of variable duty cycle. It needs to go through a filter to smooth it out.