50hz 50 percent duty pwm

hi guys
im new to arduino.i want to make two complementary pwms with 50Hz Frequency and 50 % duty in arduino uno.Plss help :slight_smile:

This page may be of use to you along with this one

Just be aware that playing with with the timers and interrupts may also play havoc with other time critical functions.

You may have to adjust values to keep some timer values eg. delays back in line with expectations.

can u post the code??

What code ?
That is up to YOU to write !

I gave you two quite useful links.

Google is also good at finding answers too for specific questions.

If you have money people will write it for you in one of the other sections.

Try this, we've been discussing it in another topic

byte pin8 = 8;
byte pin9 = 9;
unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedMicros;
unsigned long halfPeriod = 5000UL; // microseconds, x 2 = 10mS = 100 Hz

void setup() {
pinMode (pin8, OUTPUT);
digitalWrite (pin8, HIGH);
pinMode (pin9, OUTPUT);
digitalWrite (pin9, LOW);
currentMicros = micros();
previousMicros = currentMicros;
}

void loop() {
while (1) {
currentMicros = micros();
elapsedMicros = currentMicros - previousMicros;
if (elapsedMicros >= halfPeriod) {
PINB = PINB | 0b00000011; // toggle D9 & D8
//also try this: atomic and is likely fewer instructions and faster.
// PINB |= 0b00000001;
// PINB |= 0b00000010;

previousMicros = previousMicros + halfPeriod;
}
}
}[code]
Adjust the halfPeriod value to make it run slower.

@crossroads
sir i tried to sense a voltage value and i want this 50hz 50%duty pwm to be activated only if voltage is greater than a particular voltage(874 adc value).beow that both pins duty should be zero.but when i run the code i am getting 100% duty signal at output when the voltage is below the threshhold value.pls help…

code is this

byte pin8 = 8;
byte pin9 = 9;
unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedMicros;
unsigned long halfPeriod = 10000UL; // microseconds, x 2 = 10mS = 100 Hz

void setup()
{
Serial.begin(9600);

currentMicros = micros();
previousMicros = currentMicros;
}
void loop() 
{
  
int volt=analogRead(A0);
float voltage = volt /204.6/11;
Serial.println(volt);
if (volt>874)
while (1) 
{

currentMicros = micros();
elapsedMicros = currentMicros - previousMicros;
if (elapsedMicros >= halfPeriod) 
{
PINB = PINB | 0b00000011; // toggle D9 & D8
//also try this: atomic and is likely fewer instructions and faster.
// PINB |= 0b00000001;
// PINB |= 0b00000010;

previousMicros = previousMicros + halfPeriod;
}
}
else
{
}
}

Lack of indentation in your code makes it impossible to figure out what belongs to what. Please format your code properly making it readable.

I can't do anything until I get home to try the code and see what it does with an Arduino.

I do see that you're missing pinMode's for the outputs in setup():

byte pin8 = 8;
byte pin9 = 9;
unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedMicros;
unsigned long halfPeriod = 10000UL; // microseconds, x 2 = 10mS = 100 Hz

void setup()
{
  Serial.begin(9600);

  // make the 2 pins outputs and give them initial levels
  pinMode (8, OUTPUT);
  digitalWrite (8, HIGH);
  pinMode (9, OUTPUT);
  digitalWrite (9, LOW);

  currentMicros = micros();
  previousMicros = currentMicros;
}
void loop()
{
  int volt = analogRead(A0);
  float voltage = volt / 204.6 / 11; //what's this do?
  Serial.println(volt);
  if (volt > 874) {
    while (1)
    {
      currentMicros = micros();
      elapsedMicros = currentMicros - previousMicros;
      if (elapsedMicros >= halfPeriod)
      {
        PINB = PINB | 0b00000011; // toggle D9 & D8
        //also try this: atomic and is likely fewer instructions and faster.
        // PINB |= 0b00000001;
        // PINB |= 0b00000010;

        previousMicros = previousMicros + halfPeriod;
      }
    }
  }
}

As it is set up now, once the voltage is > 874 it starts toggling the outputs and never reads the voltage again. Is that the intent?

That was a mistake sir.But even with the correction the outputs of the pins remain high (ie 100% duty)
when the voltage sensed is less than threshold value(ie 874 adc value).what i want is the output of the pins should be 0% duty(ie no pwm) when below threshold value(ie 874 adc value) and the pins should be 50% duty 50hz complimentary pulse when above threshold value(ie 874 adc value).

sreehariijk:
hi guys
im new to arduino.i want to make two complementary pwms with 50Hz Frequency and 50 % duty in arduino uno.Plss help :slight_smile:

I'd set up a 100Hz timer interrupt, and on each timer interrupt handling I'd switch an OUTPUT from HIGH to LOW and vice versa

Try this then. I increased the serial port speed, make sure you update your serial monitor.

byte pin8 = 8;
byte pin9 = 9;
unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedMicros;
unsigned long halfPeriod = 10000UL; // microseconds, x 2 = 10mS = 100 Hz

int volt;
int old_volt;
byte toggle;

void setup()
{
  Serial.begin(115200); // incresase serial print speed

  // make the 2 pins outputs and give them initial levels
  pinMode (8, OUTPUT);
  digitalWrite (8, HIGH);
  pinMode (9, OUTPUT);
  digitalWrite (9, LOW);

  currentMicros = micros();
  previousMicros = currentMicros;
}
void loop()
{
  volt = analogRead(A0); // this may limit the waveform, taking ~ 110uS
  if (volt != old_volt) { // only print if the value changes
    Serial.println(volt);
    old_volt = volt; // save new value

    if (volt > 874) {
      toggle = 1; // set flag to permit toggling
      digitalWrite (8, HIGH); // set initial states of outputs
      digitalWrite (9, LOW);
    }
    else {
      toggle = 0; // do not permit toggling
      digitalWrite (8, LOW); // outputs low
      digitalWrite (9, LOW);
    }
  }
  if (toggle == 1) {
    currentMicros = micros();
    elapsedMicros = currentMicros - previousMicros;
    if (elapsedMicros >= halfPeriod)
    {
      PINB = PINB | 0b00000011; // toggle D9 & D8
      //also try this: atomic and is likely fewer instructions and faster.
      // PINB |= 0b00000001;
      // PINB |= 0b00000010;

      previousMicros = previousMicros + halfPeriod;
    }
  }
}

As I understand both pin8 and pin9 are PWM outputs (interesting how first two variables pin8 and pin9 are instantiated, but not used in the sketch - there it's simply 8 and 9). Pin 8 is set HIGH in setup(), so will remain HIGH (i.e. 100% duty cycle) until the voltage reached 874 the first time. Both should be set to LOW here.

Use the tone() function, let's say on pin 2
Set pin 3 to the compliment of what's on pin 2

https://www.arduino.cc/en/Reference/Tone

.

"interesting how first two variables pin8 and pin9 are instantiated, but not used in the sketch - there it's simply 8 and 9"
That's just me losing track of what I had going on. Don't read anything into it.

Forgot to change both to Low to start, good catch.

byte pin8 = 8;
byte pin9 = 9;
unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedMicros;
unsigned long halfPeriod = 10000UL; // microseconds, x 2 = 10mS = 100 Hz

int volt;
int old_volt;
byte toggle;

void setup()
{
  Serial.begin(115200); // incresase serial print speed

  // make the 2 pins outputs and give them initial levels
  pinMode (pin8, OUTPUT);
  digitalWrite (pin8, LOW);
  pinMode (pin9, OUTPUT);
  digitalWrite (pin9, LOW);

  currentMicros = micros();
  previousMicros = currentMicros;
}
void loop()
{
  volt = analogRead(A0); // this may limit the waveform, taking ~ 110uS
  if (volt != old_volt) { // only print if the value changes
    Serial.println(volt);
    old_volt = volt; // save new valut

    if (volt > 874) {
      toggle = 1; // set flag to permit toggling
      digitalWrite (pin8, HIGH); // set initial states of outputs
      digitalWrite (pin9, LOW);
    }
    else {
      toggle = 0; // do not permit toggling
      digitalWrite (pin8, LOW); // outputs low
      digitalWrite (pin9, LOW);
    }
  }
  if (toggle == 1) {
    currentMicros = micros();
    elapsedMicros = currentMicros - previousMicros;
    if (elapsedMicros >= halfPeriod)
    {
      PINB = PINB | 0b00000011; // toggle D9 & D8
      //also try this: atomic and is likely fewer instructions and faster.
      // PINB |= 0b00000001;
      // PINB |= 0b00000010;

      previousMicros = previousMicros + halfPeriod;
    }
  }
}

I don't see how tone() helps:
"Only one tone can be generated at a time. If a tone is already playing on a different pin, the call to tone() will have no effect. If the tone is playing on the same pin, the call will set its frequency. "

"NOTE: if you want to play different pitches on multiple pins, you need to call noTone() on one pin before calling tone() on the next pin."

This just opens as a blank page for me, could be a network issue:
https://code.google.com/archive/p/rogue-code/wikis/ToneLibraryDocumentation.wiki#Ugly_Details

I read the OP wanted complementary signals 50Hz 50% duty cycle.
tone(2,50); would do this on pin 2.
Then digitalWrite(3, !digitalRead(2)); would give pin 3 the complement of pin 2.

Maybe I am missing something.

.

There would be a (small, possibly unknown) delay setting the other pin.

Yes, even using an inverter would have some delay.

I guess we really need to know 'exactly' what is expected.

.

@crossroads
sir i tried ur code but its sensing and giving pwms as per conditions.But the duty and frequency of pwm is not 50% and 50hz.Its continously changing.Actually this pulse is for an inverter.Figure of pulse is also attached. Pls help...