Go Down

Topic: PWM help! (Read 1 time) previous topic - next topic

engineer_abc

Feb 17, 2017, 03:50 pm Last Edit: Feb 17, 2017, 04:01 pm by engineer_abc
Hi everyone,

I have been looking up online and trying to have an output as the bottom picture in my attachments.
Can anyone guide me through how I can tackle the problem? Thanks!

septillion

Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

engineer_abc

The image is uploaded!

septillion

So 20Hz (cause I don't know hz) PWM with variable duty cycle?

Start by making a 20Hz PWM signal. I would say millis() is perfectly fine for something that slow.

Next, although it gives a sample-and-hold aspect, instead of a fixed on period I would simply sample (analogRead() ) the signal the moment you make the output high and use that (after doing the math) as the on time.

Alternatively you could make a 20 Hz "saw tooth" (aka, increment a variable from 0 to max in 1/20 second) and sample the input all the time and compare it to the "saw tooth". That's a bit more correct for what you show but will take a lot more process power from the Arduino.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Robin2

Image from Original Post so we don't have to download it. See this  Image Guide



...R
Two or three hours spent thinking and reading documentation solves most programming problems.

engineer_abc

Thanks for your reply, septilion.

Yes, it is a 20Hz PWM with variable duty cycle.

How can I make a 20Hz PWM signal? I read online about times (i.e TCCR0B = TCCR0B & B11111000 | B00000101;    // set timer 0 divisor to  1024 for PWM frequency of    61.04 Hz) but I do not know how to change into a desired frequency.

I do not catch the next step... Did you mean I have to create the signal and feed into the Arduino?

Yes, I read about how a sine wave comparing with a 'saw tooth' can generate my desired signal but I really don't know how to do it inside the Arduino.

I am really new to this and this is my first project on it. Thanks for your patient.

AWOL

#6
Feb 17, 2017, 05:16 pm Last Edit: Feb 17, 2017, 05:17 pm by AWOL
Quote
How can I make a 20Hz PWM signal?
Have a look at the blink without delay example in the IDE.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

septillion

For 20Hz, forget about timers, see:
I would say millis() is perfectly fine for something that slow.
A good staring point for using millis() is blink without delay.

And for the second step, I assumed the sinus came from an external source. Then can you tell us where the +-2Hz red signal and 20Hz yellow signal come from?
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

engineer_abc

Thank you AWOL and septilion.

The red and yellow signal are just a Matlab simulation to get the visualization of the desired signal.

septillion

But what exactly do you want? Which of the signals?

The bottom one? That's just a 20Hz PWM modulated with a 2Hz sine. So only that? No input?
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

engineer_abc

Yes, the input is only an analogue signal from a pressure sensor. I need the bottom signal to drive a linear resonant actuator. This is achieved by putting in a bottom signal into a 'driver IC' which will then generate an ac signal for the linear resonant actuator.

Thanks for the reply.

septillion

If you have a input signal (I guess the red?) then what I said in replay #3 still holds. Sample that input signal and determine the on length of the PWM.

But you might want to switch to micros() instead of millis because 20Hz = 50ms. So timing that with ms will only give a resolution of 50.

You could also do it with a counter and interrupts. It's a bit more precise but it's s lot more work and more complicated.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

cattledog

#12
Feb 18, 2017, 08:00 pm Last Edit: Feb 18, 2017, 08:30 pm by cattledog
@septillion
Quote
Sample that input signal and determine the on length of the PWM.
But you might want to switch to micros() instead of millis because 20Hz = 50ms.
Here's a simple approach that may work if the pwm values at 20Hz can be created with a higher frequency pwm. I'm not sure how the input to the LRA driver works. If each pulse needs to be a created with a digitalWrite with a varying total on/off time = 50 ms than this approach is probably not correct.


Code: [Select]
/******** Sine wave parameters ********/
#define PI4     4*3.14159 // 2 sine wave cycles
#define AMP     127     // PWM Multiplication factor for the sine wave
#define OFFSET  128   // Offset shifts wave to just positive values

/******** Lookup table ********/
#define LENGTH 20 // The length of the waveform lookup table
byte wave[LENGTH]; // waveform values for PWM

const byte pulsePin = 9;

void setup() {
  Serial.begin(115200);
  pinMode(pulsePin, OUTPUT);

  /******** Populate the waveform lookup table ********/
  for (byte i = 0; i < LENGTH; i++)
  {
    float v = (AMP * sin(((PI4 / LENGTH) * i)));
    wave[i] = byte(v + OFFSET);  // Store value as integer
    //Serial.println(wave[i]);
  }

}

void loop() {
  static unsigned long lastPulseTime;
  static byte i = 0;
  if (micros() - lastPulseTime >= 50000ul) //20Hz
  {
    lastPulseTime += 50000ul;
    analogWrite(pulsePin, wave[i]);
    //Serial.print(i);
    //Serial.print('\t');
   // Serial.println(wave[i]);
    i++;
    if (i == LENGTH - 1)
      i = 0;
  }
}

engineer_abc

Thanks for the replies septilion and cattledog.

The input from the pressure sensors will be changing randomly so it would not be in any form of a sine wave. I am just going to produce the PWM signal solely by the Arduino microcontroller...

cattledog

OK. Is this correct.

You have a varying analog input from a pressure sensor.
You want to map that value to a duty cycle 0>100%.
You want to output a 20Hz PWM with that duty cycle.

The output is used as an input to a controller/driver chip for a linear resonance actuator.

Can you provide a link to the chip you are using. 20Hz as an input frequency seems low.



Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy