![]() |
|
Delicka PWM signalu - Printable Version +- Audioweb.cz (https://www.audioweb.cz) +-- Forum: Ostatní (https://www.audioweb.cz/forumdisplay.php?fid=16) +--- Forum: Smetiště (https://www.audioweb.cz/forumdisplay.php?fid=21) +--- Thread: Delicka PWM signalu (/showthread.php?tid=25663) |
Delicka PWM signalu - Wili - 5. 1. 2026 Potreboval by som urobit zapojenie ktore znizi duty cycle o 5%. (nemusi to byt presne 5, +- par percent hore dole nevadi) Napada niekoho ako? existuje nejake jednoduche a elegantne riesenie? Nejake jednoduche RC znie lakavo ale podla mna nebude fungovat dobre, pretoze len oreze hranu signalu a znepresni pwm. Programovat MCU som sa chcel vyhnut ale mozno to inak nepojde? Mozno existuje nejaky cmos co to dokaze? nieco ako delicka pre frekvenciu ale na duty... cosi som vymyslal s 555kou cez trigger ale akonahle chcem menit duty ma to fixne nastavene casy a s tym to asi nepojde. Mate nejaky napad ako na to?Mam pwm signal (cca 25kHz) ktoreho frekvenciu nechcem menit a jeho duty cycle sa dynamicky casto meni. (regulacia ventilatora) z tohto pwm chcem vytvorit novy pwm signal rovnakej frekvencie ale jemne znizeneho duty cycle. Delicka PWM signalu - jardag69 - 5. 1. 2026 Co na to řekne AI, když se jí zeptáš? Odečíst určitý pevný čas ti nestačí? Delicka PWM signalu - Wili - 5. 1. 2026 ai je z elektro blba jak tago... jardag69 napsal:Odečíst určitý pevný čas ti nestačí? nechapem co tym myslis, ved ano odcitat / znizit duty, ale nie pevny cas, chcem to dynamicke. Chcem to univerzalne, aby to fungovalo aj pri 20k aj pri 30k pwmku, a ci to pwm bude 90 alebo 10... stale minus 5 Delicka PWM signalu - jardag69 - 5. 1. 2026 Jasně. Prostě -5% z délky signálu. Na to jsem sám zvědavej. I kdyby se to řešilo pomocí nějakého chytrého obvodu, tak to asi nebude v reálu. Pokud se to PWM nemění nijak rychle, tak by asi nevadilo, že by se to o jeden impulz zpozdilo. Ale byla by to pakárna. Obvod by změřil délku impulzu, provedl by přepočet a s příchodem dalšího pulzu, by vygeneroval pulz o těch 5% kratší. Měl by stačit https://www.kondik.cz/io-atmega328p-au/?srsltid=AfmBOormvZR9GGqtStLNK462gVze3d8Y_R55KKQwh6jhduhXBKFw2GzG Copilot mi i napsal program :o) Ale asi to chce brat s rezervou :o) // ATmega328P: měření PWM na PD2 (INT0), výstup zkráceného pulzu na PB1 (OC1A, Arduino D9) // Předpoklad: F_CPU = 16 MHz #define F_CPU 16000000UL #include <avr/io.h> #include <avr/interrupt.h> #include <stdint.h> #include <util/delay.h> volatile uint16_t start_ticks = 0; volatile uint16_t measured_ticks = 0; volatile uint16_t new_ticks = 0; volatile uint8_t have_new_ticks = 0; volatile uint8_t waiting_to_generate = 0; int main(void) { // Pin setup DDRB |= (1 << PB1); // PB1 (OC1A, Arduino D9) jako výstup PORTB &= ~(1 << PB1); // výstup LOW // INT0 (PD2) jako vstup (default), zapnout interní pull-up pokud chceš: // PORTD |= (1 << PD2); // Timer1: normal mode, prescaler = 1 (no prescaling) TCCR1A = 0x00; TCCR1B = (1 << CS10); // prescaler = 1 // necháme Timer1 běžet volně (TCNT1) // INT0: trigger on any logical change (ISC01=0, ISC00=1) EICRA |= (1 << ISC00); EICRA &= ~(1 << ISC01); EIFR |= (1 << INTF0); EIMSK |= (1 << INT0); // Disable compare interrupt initially TIMSK1 &= ~(1 << OCIE1A); sei(); while (1) { // hlavní smyčka může být prázdná; vše řeší ISR // případně sem můžeš přidat diagnostiku, LED, atd. _delay_ms(1000); } return 0; } // INT0 ISR: detekce náběhu i sestupu na PD2 ISR(INT0_vect) { uint8_t pin = PIND & (1 << PD2); uint16_t now = TCNT1; if (pin) { // rising edge: začátek pulzu start_ticks = now; // Pokud máme spočtenou new_ticks z předchozího pulzu, vygenerujeme zkrácený pulz nyní if (have_new_ticks) { // nastav výstup HIGH PORTB |= (1 << PB1); // naplánuj compare na (now + new_ticks) uint16_t target = now + new_ticks; OCR1A = target; // povolit compare interrupt TIMSK1 |= (1 << OCIE1A); // označit, že jsme použili new_ticks have_new_ticks = 0; } } else { // falling edge: konec pulzu -> změřit délku measured_ticks = now - start_ticks; // spočítat 95% uint32_t tmp = (uint32_t)measured_ticks * 95UL; tmp = tmp / 100UL; if (tmp == 0) tmp = 1; // zajistit alespoň 1 tick new_ticks = (uint16_t)tmp; have_new_ticks = 1; } } // Timer1 Compare A ISR: vypnout výstup ISR(TIMER1_COMPA_vect) { // clear output PORTB &= ~(1 << PB1); // disable compare interrupt until next pulse TIMSK1 &= ~(1 << OCIE1A); } Delicka PWM signalu - Wili - 5. 1. 2026 jo cez procesor s ai programom to mi tiez napadlo ale az ako posledna moznost |