logo elektroda
logo elektroda
X
logo elektroda

Simple PWM generator v2 (ATtiny24)

RomanWorkshop  13 3894 Cool? (+17)
📢 Listen (AI):

TL;DR

  • Zbudowano prosty generator PWM v2 na ATtiny24/44/84 z wyjściem prostokątnym i prezentacją parametrów na monochromatycznym OLED SSD1306.
  • Sterowanie działa w assemblerze, a własne rutyny I2C i OLED obsługują przyciskami S1/S2 zmianę wypełnienia 0–100% oraz częstotliwości.
  • Generator oferuje trzy częstotliwości: 1.25/10/80 kHz, krok wypełnienia 1% i startowe ustawienie 10 kHz przy 50% wypełnienia.
  • Układ działa także bez wykrytego OLED, a po starcie z J1 (FLIP) zwiera obraz o 180°; zasilanie może wynosić 2.7–5.5 V.
  • Najważniejsze ograniczenia to brak ochrony przed odwrotną polaryzacją oraz gorsza stabilność z wewnętrznym RC 8 MHz; pobór prądu sięga 6.5 mA bez OLED i 8 mA z 128x64.
Generated by the language model.
Simple PWM generator with OLED display on a circuit board.
A simple PWM (Pulse-Width Modulation) generator built on an ATtiny24/44/84 microcontroller, supplied with stabilised voltage Vcc=2.7-5.5V (2.4-5.5V if using the "A"/"V" version of the microcontroller). Its output produces a rectangular signal with a selected fixed frequency of 1.25/10/80 kHz and a filling adjustable in the range 0-100%, in 1% steps. The parameters of the output signal are presented on a monochrome OLED display (SSD1306 controller, I2C bus), with a resolution of 128x32/128x64 pixels and address $78 ($3C)/$7A ($3D). I wrote the control program in assembler and it is identical for each of the microcontrollers mentioned.

I recently wrote my own routines in assembler to handle the I2C bus and the OLED display . I was looking for a way to use them in some practical device and so the idea of making this generator came about. I used an ATtiny44 microcontroller in an SO14 enclosure, because I happen to have a lot of them from disassembly. It is the second version of the simple PWM generator I made a few years ago .

Two OLED screens displaying PWM parameters: one normally, the other rotated 180 degrees.
When switched on, a rectangular signal with a frequency of 10 kHz, a filling of 50% and a level dependent on the value of the supply voltage Vcc is obtained at the generator output (connector CON2) (Figure 1). If jumper J1 (FLIP) is short-circuited (ON) during power-up, the displayed image will be rotated 180 degrees (Figure 2). If the OLED display is not detected after power-up, the generator will operate normally without it. A 128x64 display is treated as 128x32, so the image displayed on it has 1-line horizontal gaps (every second horizontal line is blank, causing the image to be stretched vertically).

To reduce/increase the signal fill by 1%, press the S1 (DUTY-)/S2 (DUTY+) button (microstick) briefly (less than 250ms). Pressing and holding down the S1/S2 button for a longer period of time will continuously decrease/increase the fill value at a rate of approx. 4%/s, until the limit value is reached, i.e. 0%/100% respectively. A fill setting of 0%/100%, will force a continuous low/high logic state (GND/Vcc) at the generator output.

To change the frequency of the signal, briefly (less than 1s) press both buttons S1 and S2 simultaneously. The frequency will then change to the next value in the sequence: 10/80/1.25 kHz and so on over and over again. Pressing and holding the S1 and S2 buttons at the same time for a long time will continuously change the frequency value at a rate of approx. 1x/sec until the buttons are released. After each frequency change, the initial signal fill value is always 50% (regardless of the previous setting).

The quartz resonator X1 clocks the microcontroller so that the output signal is fairly accurate/stable in frequency and the time waveforms of the OSCL/OSDA signals are precise/symmetrical with respect to each other. It is also possible to clock the microcontroller with its internal RC oscillator, with a nominal frequency of 8 MHz. The advantage of this solution is that it is then not necessary to mount a resonator X1 and capacitors C3/C4, but a major disadvantage is the very inaccurate/unstable frequency of the output signal and the degraded quality of the time waveforms of the OSCL/OSDA signals. Capacitors C1 and C2 filter the supply voltage. Resistor R2 limits the current drawn directly from the microcontroller's PA7 pin - preventing it from being damaged if the CON2 output is shorted.

When programming, remember to set the fuse/lock bits appropriately:
1. when the microcontroller will be clocked with the X1 quartz resonator:
FL (Fuse Low): $FF, FH (Fuse High): $DF, FE (Fuse Extended): $FF, LB (Lock Bits): $FF.
2. when the microcontroller is clocked by the internal RC oscillator:
FL (Fuse Low): $E2, FH (Fuse High): $DF, FE (Fuse Extended): $FF, LB (Lock Bits): $FF.

The generator can be supplied with DC voltage Vcc=2.7(2.4)-5.5V from a power supply or from batteries/batteries (e.g. one 18650 type cell). It is not protected in any way against reverse connection of the supply voltage Vcc. Mistaking the polarity of this voltage will damage the microcontroller. Current consumption without OLED display at Vcc=2.7/5V, is a maximum of 2.5/6.5mA (80kHz/99% signal, generator output not loaded). The current consumption with the 128x64 pixel OLED display at Vcc=5V, is 8mA maximum. I assembled the generator on a 45x45mm single-sided board, made by chemical transfer. The board is designed to use a 38x12mm (128x32) or 28x28mm (128x64) display, which has the signals arranged in order: GND, VCC, SCL, SDA. The pull-up resistors for the OSCL/OSDA lines for the OLED were not placed on the generator board, as the display module board contains them. The minimum supply voltage needed to operate the OLED display, is approximately Vcc=1.8V (low brightness).

Printed circuit board with electronic components for a PWM generator. Printed circuit board with ATtiny microcontroller on copper substrate Schematic of a simple PWM generator with an ATtiny microcontroller. .

The attached archive contains: schematic in Eagle, board in DipTrace, source, batch and documentation in PDF. Project page: Link .

PWMtin...7z (167.6 kB)You must be logged in to download this attachment. .

About Author
RomanWorkshop
RomanWorkshop wrote 218 posts with rating 416 , helped 2 times. Been with us since 2013 year.

Comments

androot 11 Feb 2025 22:29

What is the 3-frequency generator used for? For something surely, since this is its second version.... [Read more]

minus3db 12 Feb 2025 07:27

. Then why not add at least a "one leg on plus" Schottky diode? The voltage drop is small and the whole circuit - saved. Or cut one of the power supply paths and solder such a diode there elegantly on... [Read more]

Karol966 12 Feb 2025 10:48

With such a low supply it's a pity to lose that 0.3 - 0.5V rally so it's better to give a P-MOS on the supply, no voltage drop. If you don't know how to do it, just type in google : "reverse polarity... [Read more]

RomanWorkshop 12 Feb 2025 12:08

. It serves the same purpose as a generator with a million frequencies - its usefulness only depends on which specific frequencies the user needs. If someone just happens to need a PWM signal with a frequency... [Read more]

efi222 12 Feb 2025 13:00

I bow to those writing in assembler.... I've been watching your projects for a while now. The boards look like they were made with a thermal transfer. And here is a "cosmetic" question. Why don't you... [Read more]

RomanWorkshop 12 Feb 2025 18:26

. . This probably doesn't happen often, as there aren't many such ;) I don't use thermal transfer, which would probably come out nicer, although it also depends on the quality of the toner.... [Read more]

oscil1 13 Feb 2025 11:36

Why didn't you give some sort of voltage follower on the outputs? That is, glitch. This is a feature of assembler programs - the authors don't want to correct them after a bout with the program,... [Read more]

Anonymous 13 Feb 2025 13:36

And can you show off your oscilloscope measurement ? What is the actual signal at the given frequencies and pwm. [Read more]

RomanWorkshop 13 Feb 2025 17:06

. . I don't need the output buffer. . Interesting theory, but completely wrong. It's not any glitch that needs correcting just that was my assumption, to be in the middle of the fill level adjustment... [Read more]

RomanWorkshop 16 Feb 2025 22:00

. I took measurements of the output signal from a generator supplied with Vcc=5.0V, using a Siglent SDS824X HD oscilloscope (1x probe, 2GSa/s sampling). At each output frequency and when set to any... [Read more]

Sam Sung 19 Feb 2025 17:33

Cool that you shared the project. Did you try to approach the maximum possible communication speed with the OLED display, i.e. 400 kHz? What assembler are you using? Is it not possible to define... [Read more]

RomanWorkshop 19 Feb 2025 18:52

. . No, because my routines only work at 100 kHz. To change their operating frequency, you would have to rewrite them with shorter delays. Then they would definitely not work at lower microcontroller... [Read more]

Arang 10 Dec 2025 16:42

Perfect..thanks. [Read more]

FAQ

TL;DR: At 80 kHz this ATtiny PWM generator still shows about 90 ns edges, and the designer says the signal is "free of noise (glitches)". It suits anyone needing a small, low-power PWM source with fixed 1.25/10/80 kHz outputs, 1% duty steps, and optional SSD1306 OLED readout. [#21442678]

Why it matters: This thread explains not just what the generator does, but why its timing choices, protection trade-offs, and software I2C design matter in real builds.

Option Parts needed Main advantage Main drawback Best fit
External quartz resonator X1 X1 + C3/C4 Accurate, stable output frequency; precise, symmetrical OSCL/OSDA timing More parts Measurement-focused build
Internal 8 MHz RC oscillator No X1, no C3/C4 Simpler assembly Inaccurate, unstable frequency; worse OSCL/OSDA timing Minimal-part prototype
Schottky diode protection 1 diode Simple reverse-polarity protection Loses about 0.3-0.5 V Higher-voltage margin
P-channel MOSFET protection 1 MOSFET Very low voltage loss Slightly more design effort Low-voltage supply

Key insight: The project is intentionally simple: hardware timer PWM gives clean output, while omitted extras like output buffering or reverse-polarity protection reflect deliberate trade-offs, not unfinished design.

Quick Facts

  • Supply range is 2.7-5.5 V, or 2.4-5.5 V with the "A/V" MCU version; the output level follows Vcc. [#21435356]
  • The generator offers 1.25 kHz, 10 kHz, and 80 kHz PWM, with 0-100% duty control in 1% steps; startup defaults to 10 kHz and 50% duty. [#21435356]
  • Power draw without OLED reaches about 2.5 mA at 2.7 V and 6.5 mA at 5 V; with a 128x64 SSD1306 at 5 V, total current is about 8 mA max. [#21435356]
  • Measured at Vcc = 5.0 V on a Siglent SDS824X HD with 2 GSa/s sampling, the output reached about 5.04 V and showed roughly 90 ns rise and fall times. [#21442678]
  • The PCB is a 45 x 45 mm single-sided board for 128x32 or 128x64 OLED modules using I2C addresses 0x3C or 0x3D and pin order GND, VCC, SCL, SDA. [#21435356]

What is the practical use of a simple PWM generator with only three fixed frequencies: 1.25 kHz, 10 kHz, and 80 kHz?

It is useful when you specifically need one of those three frequencies and want a compact standalone PWM source. The designer states that if a user needs 1.25/10/80 kHz, this generator is a perfect fit, and its usefulness depends on matching that requirement. He also built it for education, reuse of existing assembler routines, and practical use of spare ATtiny44 chips from disassembly. [#21436191]

How do the S1 and S2 buttons work in the ATtiny24/44/84 PWM generator for changing duty cycle and frequency?

S1 and S2 change duty cycle individually and frequency together. 1. Briefly press S1 or S2 for less than 250 ms to change duty by 1%. 2. Hold S1 or S2 to ramp duty at about 4%/s toward 0% or 100%. 3. Press both buttons for less than 1 s to step frequency through 10/80/1.25 kHz; hold both to cycle at about 1 change per second. [#21435356]

Why does this PWM generator reset the duty cycle to 50% after every frequency change instead of keeping the previous setting?

It resets to 50% because that behavior was chosen intentionally, not because of a bug. The designer wanted the signal to return to the middle of the adjustment range after each frequency change. He adds that changing this behavior only requires modifying or removing one 2-byte instruction, so keeping the previous duty was possible but not desired in this version. [#21438108]

What output signal quality can be expected from the ATtiny44 PWM generator in terms of voltage level, frequency accuracy, duty-cycle accuracy, and rise/fall times?

You can expect a clean 5 V-class square wave with close-to-nominal timing when powered from 5.0 V. Measured results showed about 5.04 V output level, nominal duty and frequency accurate to 2 decimal places, and similar rise/fall times of about 90 ns. Those measurements were taken at all three output frequencies and for duty settings from 1% to 99% using a Siglent SDS824X HD and a 1x probe. [#21442678]

How do I set the correct fuse bits for an ATtiny24/44/84 when using an external quartz resonator versus the internal 8 MHz RC oscillator?

Use one fuse set for quartz and another for the internal RC oscillator. With an external quartz resonator, set FL=$FF, FH=$DF, FE=$FF, LB=$FF. With the internal 8 MHz RC oscillator, set FL=$E2, FH=$DF, FE=$FF, LB=$FF. The designer explicitly lists both configurations for ATtiny24/44/84 programming. [#21435356]

Quartz resonator vs internal RC oscillator in an ATtiny PWM generator — which is better for frequency stability and OLED I2C timing?

The external quartz resonator is better when you need stable PWM frequency and precise OLED timing. The designer says X1 makes the output frequency fairly accurate and stable, and keeps OSCL/OSDA timing precise and symmetrical. The internal 8 MHz RC oscillator removes X1, C3, and C4, but causes inaccurate, unstable output frequency and visibly degraded I2C timing quality. [#21435356]

What is Fast PWM mode in AVR timers, and how does double buffering of OCR registers help prevent PWM glitches?

Fast PWM mode is the AVR timer mode that generates PWM in hardware and updates compare values safely at defined timer boundaries. "Fast PWM mode is a timer/counter operating mode that generates a hardware PWM waveform, with buffered compare updates synchronized to the counter cycle." Here, double buffering lets OCR0x change only when the counter reaches top or bottom, preventing odd-length asymmetric pulses. The designer explicitly says this keeps the output signal free of glitches. [#21438108]

What is a repeated START condition on the I2C bus, and how is it used with an SSD1306 OLED display?

A repeated START is a second START sent without ending the current I2C transfer with STOP. In this project, the OLED routine first addresses the SSD1306 and later sends another START during the ongoing transmission to switch the display into graphic-data reception. The designer explains that the code under label OLEDsta is reused in screen-clear and text-display procedures, and that the second START is issued during the same transaction. [#21447109]

How can I add reverse-polarity protection to a 2.7-5.5 V ATtiny-based circuit without losing too much voltage?

Use a low-voltage P-channel MOSFET if you want protection with almost no voltage loss. One commenter notes that losing 0.3-0.5 V is undesirable at such low supply voltages, so a P-MOS on the supply makes more sense than a diode. The designer confirms he used a low-voltage MOSFET in the previous version, but omitted it here to keep the circuit simpler. [#21436079]

Schottky diode vs P-channel MOSFET for reverse-polarity protection in a low-voltage microcontroller project — which solution makes more sense?

A P-channel MOSFET makes more sense when the circuit runs from only 2.7-5.5 V and every few hundred millivolts matter. The thread contrasts a Schottky diode, which is simple but drops about 0.3-0.5 V, with a P-MOS solution that avoids that loss. One commenter even suggests the AO3413 as a cheap low-voltage logic-level example for higher-current circuits. [#21436079]

How do I connect an SSD1306 OLED module to this PWM generator, including supported resolutions, I2C addresses, and pin order?

Connect an SSD1306 OLED over I2C using GND, VCC, SCL, SDA in that exact module pin order. The project supports 128x32 and 128x64 pixel displays and checks addresses 0x3C and 0x3D. The board does not include pull-up resistors for the OLED I2C lines because the display module already contains them, and the minimum supply needed for the OLED itself is about 1.8 V at low brightness. [#21435356]

Why is a 128x64 SSD1306 OLED treated as 128x32 in this project, and why do blank horizontal lines appear on the display?

It happens because the software renders only a 128x32 image area even when a 128x64 module is attached. The designer states that a 128x64 display is treated as 128x32, so every second horizontal line stays blank. That creates 1-line horizontal gaps and makes the visible image appear stretched vertically instead of fully using the taller panel. [#21435356]

What happens if the OLED display is not detected at startup in this ATtiny24 PWM generator, and how can I troubleshoot it?

The generator still works normally without the OLED if startup detection fails. Check three things first: 1. confirm the OLED uses address 0x3C or 0x3D; 2. verify pin order is GND, VCC, SCL, SDA; 3. make sure the module provides I2C pull-ups, because this board does not. The thread also notes the generator searches for the display on 78h and then 7Ah, which correspond to those two 7-bit I2C addresses. [#21447109]

How fast can software I2C routines in AVR assembler drive an SSD1306 OLED, and what limits increasing the bus speed from 100 kHz toward 400 kHz?

In this project, the software I2C routines run at 100 kHz, not 400 kHz. The designer says increasing speed would require rewriting the routines with shorter delays, and then they would stop working reliably at lower MCU clocks such as 4-6 MHz; even 8 MHz would be questionable. So the limiting factor is instruction timing in the assembler delay loops, not the SSD1306 alone. [#21447109]

How do open-drain or high-impedance control methods for SDA and SCL work in software I2C on AVR, and why is driving the lines actively high a bad idea?

Software I2C on AVR should pull SDA and SCL low actively, then release them to high impedance so pull-up resistors create logic high. "Open-drain/high-impedance control is a bus-driving method that forces a strong low state, but never drives a strong high state, allowing shared pull-up operation without contention." The designer warns that driving a line high while another device drives it low would cause current flow, disrupt the bus, and potentially block communication. [#21447109]
Generated by the language model.
%}