logo elektroda
logo elektroda
X
logo elektroda

Simple PWM generator v2 (ATtiny24)

RomanWorkshop 2913 12
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • 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 Download (167.6 kB) .

    Cool? Ranking DIY
    About Author
    RomanWorkshop
    Level 14  
    Offline 
    RomanWorkshop wrote 211 posts with rating 399, helped 2 times. Been with us since 2013 year.
  • ADVERTISEMENT
  • #2 21435666
    androot
    VIP Meritorious for electroda.pl
    What is the 3-frequency generator used for? For something surely, since this is its second version....
  • #3 21435861
    minus3db
    Level 12  
    Quote:
    It is not protected in any way against reverse connection of the Vcc supply voltage. Mistaking the polarity of this voltage will damage the microcontroller
    .
    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 the surface.
  • ADVERTISEMENT
  • #4 21436079
    Karol966
    Level 31  
    >>21435861 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 protection mosfet" and look in the graphic, for this voltage you only need 1 element, it is important that it is low voltage/ logic-level For more current-hungry circuits I use for example the AO3413. Wholesale it costs pennies, in retail it doesn't make a tragedy either.

    Of course, I approve my own construction and these 3 fixed frequencies suggest a specific purpose, so it is possible to understand the construction of such a circuit, because otherwise, the cost of a ready-made one is a dozen or so zlotys (well, with shipping max 29 zlotys)
    PWM signal generator with LCD display and control buttons .

    There's always the explanation that it's for training and it just boasts :) .
  • #5 21436191
    RomanWorkshop
    Level 14  
    >>21435666 .
    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 of 1.25/10/80 kHz, then this generator is perfect for them ;) The output signal has pretty good performance. The oscilloscope shows steep slopes, a nominal fill value to 2 decimal places (the third digit changes) and an equally accurate frequency, which of course depends on the quartz resonator used.

    >>21435861 .
    As much as possible, a protection diode could be used, but I have dispensed with it precisely to avoid a voltage drop of more than 200mV, which can be important especially at low supply voltages. In the previous version, I used a low-voltage MOSFET transistor as protection - I have now omitted it to avoid complicating the circuit unnecessarily. I have assumed that it is not allowed to go wrong - after all, it's only two wires, what can go wrong? ;)

    >>21436079 .
    The generator was created mainly for educational reasons, the desire to make practical use of previously developed routines and to manage the backlog of microcontrollers. There is a lot to be learned from the included source code. - Of course, this will only be done by programmers familiar with assembler.
  • #6 21436270
    efi222
    Level 19  
    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 print descriptions on the PCB side of the components? The look of the devices would certainly benefit.
  • ADVERTISEMENT
  • #7 21436769
    RomanWorkshop
    Level 14  
    >>21436270 .

    Quote:
    I bow down to those writing in assembler...
    .
    This probably doesn't happen often, as there aren't many such ;)

    Quote:
    The plates look like they were done with a thermal transfer.

    I don't use thermal transfer, which would probably come out nicer, although it also depends on the quality of the toner. I use chemical transfer (cold) without using an iron, which I last held in my hands somewhere in my primary school days when I tried to iron clothes.

    Quote:
    Why don't you print descriptions on the PCB side of the components?
    .
    Because I'm making one prototype board for myself and nice markings don't matter to me, but the time spent to make them does. It's quicker and easier to write the necessary markings with a marker pen, rather than messing around with an extra transfer that won't change anything about the performance of the device anyway.
  • ADVERTISEMENT
  • #8 21437638
    oscil1
    Level 21  
    Why didn't you give some sort of voltage follower on the outputs?

    RomanWorkshop wrote:
    After any frequency change, the initial fill value of the signal is always 50% (regardless of the previous setting).


    That is, glitch. This is a feature of assembler programs - the authors don't want to correct them after a bout with the program, because then there is a good chance of a new one
    RomanWorkshop wrote:
    It is not protected in any way against reverse connection of the Vcc supply voltage. Mistaking the polarity of this voltage will damage the microcontroller.
    .
    glitches.

    RomanWorkshop wrote:
    It is not protected in any way against reverse connection of the Vcc supply voltage. Mistaking the polarity of this voltage will damage the microcontroller.
    .
    Why present an underdeveloped design?
  • #9 21437830
    Anonymous
    Level 1  
  • #10 21438108
    RomanWorkshop
    Level 14  
    >>21437638 .

    Quote:
    Why didn't you give some voltage follower on the outputs?
    .
    I don't need the output buffer.

    Quote:
    So glitch. It's a feature of assembler programs - authors don't want to fix them after fighting the program, because then there's a good chance of a new one
    .
    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 range after a frequency change. In order for the initial fill value to be different or remain unchanged after a frequency change, you only need to modify or remove one 2-byte instruction (I encourage you to analyse the very short and simple program code).
    Writing programs in assembler is a struggle? For me it is sheer pleasure - creating new routines, fitting them into the overall code, or optimising them by even 2 bytes gives great satisfaction. In assembler you have full control and can change everything, almost like in the Matrix ;) .

    Quote:
    glitches.

    I don't need reverse polarity protection either.

    Quote:
    Why present an underdeveloped project?
    .
    For me, this project is fully working and completed at this point, which does not mean that everyone will like the solutions I have adopted. Therefore, the project is made available with sources and anyone who sees something useful in it can change it to suit their needs.

    Still apropos of those recently popular glitches - the PWM signal is generated entirely in hardware by timer/counter TC0, which operates in "Fast PWM" mode. In this mode, double buffering of the OCR0x registers is active, which only allows their value to change when the counter reaches the top/bottom count value. This prevents asymmetrical PWM pulses of odd length from appearing on the output, so that the output signal is free of noise (glitches). Thank you for your attention.

    >>21437830 .

    Quote:
    Are you able to show off your oscilloscope measurement ? What is the actual signal at the given frequencies and pwm.

    As soon as I have time and still have the oscilloscope made available to me (Siglent SDS824X HD - nice equipment, but I have no comparison, e.g. with cheaper models), I will make measurements and screenshots as much as possible.
  • #11 21442678
    RomanWorkshop
    Level 14  
    >>21437830 .

    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 fill level in the 1-99% range, the output signal had a uniform level of about 5.04V, a nominal fill/frequency value to 2 decimal places and similar rise/fall edge times of about 90ns.

    Square wave signal 5V on a Siglent SDS824X HD oscilloscope Oscilloscope screen showing a rectangular waveform with amplitude 5.03958 V and frequency 10.001214 kHz. Oscilloscope screen showing a square wave with amplitude 5.04167V, frequency 80.00964 kHz, with rise and fall times around 90 ns. .
  • #12 21446912
    Sam Sung
    Level 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 macros there? With them you could improve readability by eliminating machine code insertions (I mean .dw $C000,0 instead of rjmp + nop) and repeated sequences with #if CLK==4. And where is WaitU5m10 defined?

    It seems to me that what the code labelled "Sending START/Repeated START condition and OLED address to I2C bus" is doing is simply looking for the display on the I²C bus once at address 78h, then 7Ah. Maybe I'm clinging, but calling it " repeated START " is a stretch (no transmission occurred on address 78h).

    Added after 1 [hour] 4 [minutes]: .

    You control the SCL line similarly to SDA - that is, strong zero, weak one. Would it be possible to set SCL as an output instead and switch PORTA? Wouldn't that improve the steepness of the rising edge of the clock?
  • #13 21447109
    RomanWorkshop
    Level 14  
    >>21446912 .

    Quote:
    Did you try to approach the maximum possible communication speed with the OLED display, which is 400 kHz?
    .
    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 frequencies (4-6 MHz, 8 MHz is also questionable), due to the instruction execution time.

    Quote:
    What assembler are you using? Is it not possible to define macros there?
    .
    I am currently using "AVR macro assembler 2.2.7". Of course it is possible to define macros, only they do not shorten anything in my code anymore. I used the notation ".dw $C000,0" to fit 2 instructions in one line of code. With the #if / #else / #endif instructions, the program code is compiled conditionally - you can't put them in macros and overall it wouldn't change the size of the program, but it would certainly make the code less readable. The label "WaitU5m10" is located in 415 lines of the source code.

    Quote:
    Maybe I'm nitpicking, but calling this a "repeated START" is a stretch (no transmission occurred on address 78h).

    The code from under the label "OLEDsta" is used twice in the procedure "OLEDclr" cleaning the OLED screen and "OLEDwr0" displaying the ASCIIZ string from memory. Then a second START condition is sent, during the already ongoing transmission to the OLED display (to switch it to receive the graphic data string). Thus, a repeated START condition is sent.

    Quote:
    You control the SCL line similarly to SDA - i.e. strong zero, weak one. Would it be possible to set SCL as an output instead and switch PORTA? Wouldn't that improve the steepness of the rising edge of the clock?
    .
    You can't control the I2C bus lines like this - when a line is not active (no low state), it must be in a high impedance state (open collector/drain). If the microcontroller output controlling the SCL/SDA line had a high state, and at that time another device set it to a low state, current would flow from the microcontroller output - bus operation would be disrupted. Similarly, if the microcontroller output had a low state that would still block the bus. The microcontroller does not have dedicated open collector/drain outputs, so the pins controlling the SCL/SDA lines need to be set to a high impedance state.

Topic summary

A simple PWM generator utilizing the ATtiny24/44/84 microcontroller is discussed, featuring a stabilized voltage supply of 2.7-5.5V and capable of producing fixed frequencies of 1.25, 10, and 80 kHz with adjustable duty cycles from 0-100%. The output signal parameters are displayed on a monochrome OLED screen (SSD1306, I2C interface). The creator implemented custom assembler routines for I2C and OLED control, emphasizing the generator's utility for specific frequency needs. Suggestions for circuit improvements include adding a Schottky diode for voltage drop reduction and using a P-MOS for reverse polarity protection. The output signal's performance was validated with an oscilloscope, showing consistent voltage levels and rapid rise/fall times. The discussion also touches on the assembly programming techniques and the design choices made for the prototype.
Summary generated by the language model.
ADVERTISEMENT