-
-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PWM on digital pin 2 acts strange #29
Comments
A little more testing shows that this code works fine: uint16_t ledPin = 2;
void setup()
{
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
}
void loop()
{
for(uint16_t i = 1; i < 256; i++)
{
analogWrite(ledPin, i);
delay(10);
}
for(uint16_t j = 255; j > 0; j--)
{
analogWrite(ledPin, j);
delay(10);
}
} However if I uncomment It seems like this is related to when |
I had a short look on the functions, but I also see no problem. |
I suspect there might be a bug in the new and experimental toolchain (1.6.200). Too bad the 328PB isn't supported by the older toolchain (1.6.20). |
There seems to be a hardware bug on timer 3+4 and the port register has to be written to 1 in order to get the output compare working: http://www.avrfreaks.net/comment/1717946#comment-1717946 I have also tested the serial number printing and it is working with 1.6.200 for me. |
OK. Seems like a workaround is necessary in order to get PWM pin pin 2 working properly. I think the fix below should be OK. I only own one ATmega328PB chip, with date code 1550. Do you know if this silicon error have been fixed in newer chips? #if defined(TCCR3A) && defined(COM3B1)
case TIMER3B:
// connect pwm to pin on timer 3, channel B
PORTD |= _BV(PD2);
sbi(TCCR3A, COM3B1);
OCR3B = val; // set pwm duty
break;
#endif
#if defined(TCCR4A) && defined(COM4B1)
case TIMER4B:
// connect pwm to pin on timer 4, channel B
PORTD |= _BV(PD2);
sbi(TCCR4A, COM4B1);
OCR4B = val; // set pwm duty
break;
#endif |
I have tested it with one of our boards and I have to check the date code, but I think it is newer. In the datasheet (errata) is also nothing about it.
|
Why use the sbi macro? It generates the same assembly code as "regular" bitwise operations. As far as I know the earlier version of the gcc tool chain wasn't properly optimized for the AVR architecture, and didn't "understood" that bitwise operations could be converted into sbi and cbi instructions. Here's an avrfreaks thread about the topic: http://www.avrfreaks.net/forum/sbi-cbi
|
Because it is used in the Arduino source code and the chance that a pull-request is accepted is better, when the coding style/formatting is the same. |
Well, good point.. |
The date code of my mega328PB where the issue also exists is 1619. |
I have had the same issue but solved it and have the explanation. The fix is trivial, finding it took three days. SummaryThe "output compare modulator" is used when either output compare There is a line in the datasheet which says this, but it's actually pretty well hidden and I didn't find it until writing this note. Even if you noticed the section on Output Modulation, you might not have read it in detail if you weren't intending to use it. There is no bug except in the documentation. ExplanationTimer 3 and Timer 4 each has two output compare registers, A and B. Enabling the output comparison pins is done with the The obvious way to get, say, simple PWM from This is the surpise: It appears that when References: ATMega328PB datasheet DS40001906 rev C Feb 2018. See figure 22.2, p247. What I've called The following is the description given at Section 22.2 for the modulator with my edits of what I believe it should say.
The line at 19.11.8 TC3 Control Register A and 19.11.15 TC4 Control Register A (p198) are very easily missed, and should be a note in the tables 19.8, 19.13 etc.
Honestly it's a great feature, but it really needs flagging! TestingTested on bare ATMega328PB datecode 2239 with the following: No output on Pin 32
Output on Pin 32
|
Hi!
I'm working on an implementation for the ATmega48PB/88PB/168PB/328PB family and stumbled upon an issue I want to discuss. First you'll have to merge the pending PR in order to reproduce the issue.
The issue is PWM on digital pin 2 (PD2). It doesn't matter if TIMER3B or TIMER4B is used (in pins_arduino.h), the problem is the same. When running the Fade.ino example, the pin only "fades down" from 255-0, not up again like it should. If I change the boundaries from 0->10 and 255->200, it won't output any signal. I've attached my oscilloscope to verify this.
My implementation uses its own Arduino core files, but I haven't been able to figure out what's wrong. Any idea?
Here's a GIF to show you what's going on:
The text was updated successfully, but these errors were encountered: