1

I am using an ATTiny88 to drive a PWM device. First of all, digging through the literature, it's hard to tell what the differences between the ATTiny85 and ATTiny88 are, and the vast majority of references are for the ATTiny85.

In this particular case, I am using D10 on the ATTiny88 for PWM output. The PWM frequency needs to be above 5KHz, so I am going to issue the command:

TCCR1B = TCCR1B & 0b11111000 | 0x01;

which I am given to understand will set a PWM frequency of 31KHz on D10. Please let me know if this is not correct. Meanwhile, I also need to use the micros() function:

const int pulseDelay = 183;
unsigned long MicroSeconds = micros();
while(micros() - MicroSeconds < pulseDelay){} // 1/2 period of Bell
if (Enable) {digitalWrite(14, 1);} // If Enable = True, send high pulse to Bell, else Bell is silent
while(micros() - MicroSeconds < pulseDelay){} // 1/2 period of Bell
digitalWrite(14,0);

In this case, it is probably best not to use an interrupt blocking call.

EDIT: I wrote a short driver to test things out:

#include <Arduino.h>
#define True 1
#define False 0
#define Bell 14 // Bell port
#define LED 10 // Intensity Port
int Intensity = 25;
void Beep(bool Enable, float Delay)
{
 const int pulseDelay = 183; // 1/2 period of Bell pulse in microseconds
 int Span = Delay * 2732;
 for (int x = 0; x < Span; x++)
 {
 unsigned long MicroSeconds = micros();
 while(micros() - MicroSeconds < pulseDelay){} // 1/2 period of Bell
 digitalWrite(Bell, 1); // Send high pulse to Bell
 while(micros() - MicroSeconds < pulseDelay){} // 1/2 period of Bell
 digitalWrite(Bell,0); // Send low pulse to bell
 }
}
void setup()
{
 pinMode(LED, OUTPUT);
 analogWrite(LED, Intensity); // Set initial Intensity
 pinMode(Bell, OUTPUT); // Set Bell as output
// TCCR1B = TCCR1B & 0b11111000 | 0x01; <=========== remove comment to test the call
}
void loop()
{
 Intensity += 25;
 if (Intensity > 255) {Intensity = 25;}
 analogWrite(LED, Intensity);
 Beep(True, 2);
}

When I remove the comment, the Arduino runs extremely hot. D10 goes to 1 Volt with a lot of very high frequency noise and stays there. D10 outputs a 5 KHz signal with a very narrow but fairly constant pulse width.

asked Sep 6, 2024 at 23:15
3
  • The micros() function relies on the Timer0 overflow interrupt to increment the microseconds counter. If you disable interrupts, micros() won't update correctly. Commented Sep 8, 2024 at 16:14
  • If the MCU gets hot, and if an output stays midway between LOW and HIGH, then you have an electrical problem. Typically an excessive load (too low impedance) on the pin. Unplug whatever is connected to D10, then look at what is coming out of that pin. Commented Sep 11, 2024 at 7:16
  • You are making a number of unwarranted assumptions. The main one is D10 is connected to something. The Arduino is not connected to anything but USB power during this testing. It turns out the Arduino is bad - internally shorted. I am fairly certain the unit was good prior to testing. Either this is a coincidence, or issuing TCCR1B = TCCR1B & 0b11111000 | 0x01; caused something inside the Arduino to fry. I don't want to try changing any prescalers again until the issue is resolved. Commented Sep 16, 2024 at 13:00

1 Answer 1

2

The ATTiny85 and ATTiny88 are pretty different devices. The ATTiny85 is an 8-pin MCU, whereas the ATTiny88 has 28 pins, and is pretty similar (but slower) to the ATmega328P you would find on an Uno.

Regarding the effect of the prescaler on micros(), it all depends on the core you are using. I am not Aware of a standard Arduino core for the ATTiny88, but most AVR cores use Timer 0 for millis(), micros() and delay(). If you change its prescaler, all these functions will be affected. The other timers don't pose this problem.


Edit 1: If I understand correctly, you are using this core frm MH-ET LIVE. This is very similar to the standard AVR Arduino core. It also configures the Timer 0 prescaler to 64. If you change this prescaler, micros() and friends will count wrong with an error factor that is exactly 64/prescaler. For example, if you set the prescaler to 1 (i.e. no prescaler), micros() will count 64 times too fast.

You asked:

Exactly how will using TCCR1B = TCCR1B & 0b11111000 | 0x01; affect the micros() function?

It will not affect it at all. The TCCR1B register belongs to Timer 1, whereas, as explained above, the Arduino timing function rely on Timer 0.


Edit 2: Answering the new questions that appeared in a comment.

which timer controls the PWM on port 10 on the ATTiny88

There is no pin that is unambiguously named "pin 10" on the ATtiny88. Then, the answer to this question depends on what you mean by "pin 10", which in turn depends on the core you are using. You wrote you are using the "MH-ET LIVE Tiny88(16.0MHz) core". I found no core with that exact name (a link to your core would have been helpful!). The closets matches I found are the one I already mentioned from MH-ET LIVE, and Spence Konde’s ATTinyCore. The latter defines a board named "ATtiny88 (Micronucleus, MH-ET t88 w/16MHz CLOCK)".

If you are indeed using one of these, they both define "pin 10" as PB2, which is the same as OC1B (output compare of Timer 1, channel B). Hence, it’s PWM capability is controlled by Timer 1.

what command should I use to get 5KHz PWM on that port.

There are various options, depending on the choice of PWM mode and prescaler. Here is one possibility:

/* Configure Timer 1 for phase correct PWM at 5 kHz. */
void setup() {
 DDRB |= _BV(PB2); // set pin 10 = PB2 = OC1B as output
 TCCR1A = _BV(COM1B1) // non-inverting PWM on pin OC1B
 | _BV(WGM11); // select mode 10: phase correct PWM...
 TCCR1B = _BV(WGM13) // ...with TOP = ICR1.
 | _BV(CS10); // clock at F_CPU
 ICR1 = 1600; // period = 2 * 1600 clock cycles = 0.2 ms
}

For controlling the duty cycle, you have to write a number between 0 (for a signal continuously LOW) and 1600 (continuously HIGH) to the register OCR1B. For example:

/* Ramp the duty cycle from 0% to 100%. */
void loop() {
 for (int duty = 0; duty <= 1600; duty++) {
 OCR1B = duty;
 delayMicroseconds(1000);
 }
}

I tested this on an Uno, which has a very similar pinout as the ATtiny88 and, as far as I can tell, identical Timer 1 implementations.

answered Sep 7, 2024 at 7:13
8
  • Why slower? Supposedly the ATTiny88 uses the ATmega328, at least if I am reading the ads correctly. I also gather only D9 and D10 are hardware PWM (plus my board design already uses D10). I am using the MH-ET LIVE Tiny88(16.0MHz) core. It is the only one I have been able to get to work with these boards. If there is a different core that will work better, I am game to try it. Exactly how will using TCCR1B = TCCR1B & 0b11111000 | 0x01; affect the micros() function? I can handle if the function counts in 8, 16, 32... μseconds rather than 1 as long as I know what the factor is. Commented Sep 7, 2024 at 17:48
  • According to its datasheet, the ATtiny88 can be clocked up to 12 MHz. Looks like the board you mention is overclocking it. It may still work just fine. Commented Sep 7, 2024 at 22:36
  • The main question essentially remains unanswered. Stipulating that Timer0 controls the millis() and micros() registers for the ATTiny88, should the prescaler be set for timer0 or timer1 to control the PWM frequency on the ATTiny88? Right now, I am getting 490Hz on the PWM port (D10). I need 16 times that. Commented Sep 16, 2024 at 13:07
  • @LesRhorer: I think I clearly answered the question in the title: changing the prescaler for Timer 0 affects micros(); changing the prescaler for Timer 2 does not. Commented Sep 16, 2024 at 19:39
  • Well, OK, fair enough, I suppose. The wording was not perhaps direct to the eventual point. The salient questions are which timer controls the PWM on port 10 on the ATTiny88 and what command should I use to get 5KHz PWM on that port. Perhaps the ultimate question is whether I should switch to an Arduino Nano, instead of the ATTiny88? Commented Sep 19, 2024 at 13:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.