0

I'm trying to provide a sinusoidal wave using PWM modulation. my circuit is comprised of the following:

  1. Arduino Uno
  2. H bridge - controls the direction (pins 4,5) and the PWM voltage (PWM pin 6)
  3. Solenoid motor - the sine output should be fed to the motor

I saw some guides online, but most of them use Sinewave tables and low-level code that I couldn't quite comprehend, so I have decided to give it a try with some more trivial code as followed:

const int DIR1_PIN = 4;
const int DIR2_PIN = 5;
const int PWM_PIN = 6;
const int LED_PIN = 9;

const int numSamples = 20;
const int sampleFreq = 2000;
const float pi = 3.1415;
float f = 1; // signal frequency
float T = 1/f; 
float dt = T/numSamples;
int sineSignal[numSamples]; // sine values would be added here
int dir1Array[numSamples]; // 11....100....0 indicates direction
int dir2Array[numSamples]; // 00....011....1 indicates other direction

void setup()
{

  pinMode(LED_PIN, OUTPUT); // the led is just an indicator to what the output is
  pinMode(DIR1_PIN, OUTPUT);
  pinMode(DIR2_PIN, OUTPUT);
  pinMode(PWM_PIN, OUTPUT);

  for (int n = 0; n < numSamples; n++)
  {
    sineSignal[n] = abs((int) (255 * (sin(2 * pi * f * n * dt))));
    if (n < numSamples / 2)
    {
      dir1Array[n] = HIGH;
      dir2Array[n] = LOW;
    }
    else
    {
      dir1Array[n] = LOW;
      dir2Array[n] = HIGH;
    }
  }
}

void loop()
{
  for (int n = 0; n < numSamples; n++)
  {
    analogWrite(LED_PIN, sineSignal[n]);
    analogWrite(PWM_PIN, sineSignal[n]);
    digitalWrite(DIR1_PIN, dir1Array[n]);
    digitalWrite(DIR2_PIN, dir2Array[n]);
    delay(sampleFreq); // not quite sure how the delay affects the frequency f
  }
}

long story short, this code does not allow me to control the frequency f (getting the same output for different values of f)

any Idea on how to generate such output for varying f? how should one set up a delay call, if even?

Thank you!

Hadar Sharvit
  • 333
  • 2
  • 10
  • 1
    Is your sine wave data only 20 samples for a whole cycle? At `numSamples` per cycle, and frequency `f` being cycles/s that says you want to output `numSamples * f` samples every second, which means the delay in your `for` loop should be `1/(f * numSamples)` converted to milliseconds. – lurker May 06 '21 at 14:10
  • thanks for your advice. I would try using `dt = 1/(f*numSamples)` as the delay. do you have any idea what is the total delay? (given the fact that analogWrite is given with 980Hz) – Hadar Sharvit May 07 '21 at 16:54
  • The PWM frequency has no bearing on how much time `analogWrite` takes. Why don't you print `micros()` to time your loop? If the timing is that critical you should consider a timer interrupt instead of a `for` loop with a delay. – lurker May 07 '21 at 17:40
  • I'm more concerned with the frequency because the entire thing should be connected to a solenoid, which needs high frequency to work apparently – Hadar Sharvit May 07 '21 at 20:12
  • 1
    Like I say, the calculation I gave will give the right theoretical frequency. The `loop` runs plenty fast enough for a solenoid. If you are concerned about timing, make some measurements. – lurker May 07 '21 at 21:46

0 Answers0