Getting PWM example working - Nano

I uploaded a simple PWM example to a Nano and modified it such that I would expect to so a sawtooth (PWM coded of course) at pin A3 (I'm using sigrok pulseview with the D0 input clipped to pin A3 of the Nano) but I don't see a signal. Just an always high level.

This is the code:



// Program B for Nano2 – Changed frequency on Pin 3 :
int i=0;
void setup() {

TCCR2B = TCCR2B & B11111000 | B00000001; // for PWM frequency of 3921.16 Hz
pinMode(3,OUTPUT);

}

void loop() {

analogWrite(3,i);
i+=1;
if(i==256)
  i=0;
}

Why do you expect something at pin A3, if you output the signal to the pin D3 in the code?

1 Like

Ah yes, sorry. My fault.

The part will not produce a sawtooth waveform unless there is external circuitry to shape it. I can understand a sawtooth wave form but I cannot fathom a sawtooth PWM, variable frequency yes. By definition PWM is pulse width. You can use a comparator and a sawtooth waveform generator to create a PWM signal.

http://www.eprojectszone.com/how-to-generate-a-sawtooth-and-a-triangle-wave-with-arduino/

Sure it gotta be filtered. I thought this needn't to be mentioned. But PWM wise programmed in this example is a ramp (sawtooth).

The problem is the those that reply don't know your level of experience. We try not to assume.

It's my understanding that you are using a Nano. In which case A3 is not a PWM capable pin.

You did confirm that it was a fault, but never mentioned the exact correction that you made. If you're still using A3, see above. Else state that you're now checking pin 3 ( D3) instead of A3.

I (erroneously) said, I was expecting the PWM at A3, but programmed D3 (3). The program as posted, gives a PWM output at D3. Nonetheless the output looks a bit strange at the beginning:


And the end of the loop doesn't look clean, either.

With this being the actual code:



// Program B for Nano2 – Changed frequency on Pin 3 :
int i=0;
void setup() {

TCCR2B = TCCR2B & B11111000 | B00000001; // for PWM frequency of 3921.16 Hz
pinMode(3,OUTPUT);
delayMicroseconds(1000);

}

void loop() {

analogWrite(3,i);
i+=1;
if(i==255)
  i=0;
  delayMicroseconds(10);
}

Did you want that 10uS delay in every cycle through loop, or only at i==255?
indentation is irrelevant in C++ to the compiler, but your usage suggests you intended it to be part of the if clause.

As for this, was your intent i++?

@camsysca

Both constructs will increment i by 1 :wink:

  delayMicroseconds(10);

Did you want that 10uS delay in every cycle through loop, or only at i==255?
indentation is irrelevant in C++ to the compiler, but your usage suggests you intended it to be part of the if clause.

@camsysca : if I had wanted to have a delay only in the "if", I would have written ( :wink:):

if(i==255)
  i=0,delayMicroseconds(10);

> i+=1;

As for this, was your intent i++?

Yes.

NB: this is C, not python and indentation may get garbled sometimes in the course of copy/paste. But indentation is irrelevant in C, other than good for legibility.

For the sake of peace I've sent the piece of code through Unix $ indent -br -ci4 t.txt

void 
loop()
{
	analogWrite(3, i);
	i += 1;
	if (i == 255)
		i = 0;
	delayMicroseconds(10);
}

My questions were to ascertain user intent and understanding, not challenge language or impugn the user. Sorry to offend, but your problem lies elsewhere, as does your assistance.

I thought the topic is "project guidance". Anyway, leaving animosities aside, in the pulse diagram I posted, wouldn't one actually expect 255 pulses rather than far less as seen in the picture?

And what missing assistance is concerned, I cannot see me failing in that. I posted that I was using Data pin 3 and I even posted a pulse train.

255? - nope
Accordingly the code from post #9 you use PWM with freq 3.9KHz, thus the duration of PWM period will be

1sec / 3921 = 255 uS (microSeconds)

But with this you change the timer settings every 10 microseconds... - you just don't let the timer run for a full period.

Hmm. In how far does delayMicroseconds influence the PWM pulse duration ? Is there only one timer?

PWM cycle is not affected by the delayMicroseconds(), but by the fact that you run the analogWrite() statement in a loop with a interval of 10 us between different OCRx values

? I didn't have any, so nothing left aside. I simply didn't see that I can help you. Good luck!

Check the comments in the data sheet on double buffering of the Timer2 output compare registers. If double buffering is not enabled, I believe you can expect to see glitches when trying to update them at the wrong times, or too quickly.

I was interpreting the "your problem lies elsewhere" as some remark "besides the rails" :slight_smile: