logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Knight rider - jak to działa?

skynet77 10 Gru 2009 22:40 2943 10
REKLAMA
  • #1 7372550
    skynet77
    Poziom 10  
    Witam !
    Przeszukałem chyba całe forum i nie mogę nic znaleźć.
    Czy ktoś z Was nie ma aby kawałka kodu w C jak obsłużyć np 3 diody LED aby powstał efekt knight rider?
    Chodzi PWM itd, jestem początkujący i chciał bym przestudiować kawałek takiego kodu a nie moge znaleźć w C ;/
    Proszę o pomoc.
  • REKLAMA
  • #2 7372923
    mirekk36
    Poziom 42  
    Bo i nie znajdziesz za bardzo takiego gotowca .... za to warto spróbować napisać samemu - tym bardziej, że w C to będzie pikuś.

    tworzysz sobie nawet kilku kanałowy PWM a potem kilka diod na całej linijce sterujesz tymi kilkoma kanałami. Pierwsza najjaśniejsza, druga ciemniejsza , trzecia jeszcze ciemniejsza itd

    Plus różne inne kombinacje

    Ale najpierw warto może opanować sam PWM i sprzętowy i programowy. Wtedy gwarantuję ci , że pomysł jak to dalej zrobić sam ci się pojawi w głowie ;)
  • REKLAMA
  • #3 7373050
    AVRowiec
    Poziom 18  
    albo daj kilka diodek każda do innego portu i równolegle do diody kondensator - będzie powoli przygasać :)
    mało profesjonalne rozwiązanie ale zawsze jakieś.
  • REKLAMA
  • #4 7374178
    skynet77
    Poziom 10  
    Dzięki AVRowiec, przemyślałem wcześniej takie rozwiązanie, ale wole wykonać to programowo ;)
    Z resztą jak powiedział mirekk36, lepiej pokombinować z PWMem, cóż, skoro nie ma gotowca, trzeba coś wymyślić samemu :D
    Ale sprzętowe wykorzystanie PWMa chyba nie jest ważne w knight rider prawda ?
    Bo PWM wykona program w uC. Jeśli dobrze zrozumiałem, to dla każdej diody (albo grupy diod- 1 kanał, trzeba wykonać osobną sekwencje ? )

    '' skoro taki pikuś'' to....Czy mógłby proszę któryś z WAS napisać mi chociaż kawałeczek kodu do obsługi PWM ?
    :)(Taki jeden poprawny segment dla jednego kanału)
    Nie chcę gotowca, a jedynie zobaczyć jak wygląda poprawny kod, tym bardziej ze nigdzie nie znalazłem takiego projektu w C :(
  • Pomocny post
    #5 7374295
    gigipawel
    Poziom 15  
    Jaki masz procesor ?
    Proponuję 2313 ma 4 sprzętowe PWM. A jak masz np atmege8 czy 16 to tylko 3.

    Proponuje od generowania sprzętowego PWMa.
    A tu jest super objaśnione dla jednej diody http://mlab.taik.fi/paja/?p=466 .
    Chyba lepszego linku z PWMem nie ma na necie.
  • REKLAMA
  • #6 7375805
    skynet77
    Poziom 10  
    ....dzięki gigipaweł !
    O takie coś właśnie mi chodziło Smile
    Jestem w posiadaniu zaledwie ATmegi8 ale i tak mogę coś pokombinować.
    Mam rozumieć że 3 kanały PWM to tylko 3 komplety diod sterowanych PWMem tak ?
    Czyli jednym słowem efekt wyjdzie lichutko Very Happy
    Ale mi chodzi przecież o naukę a nie o ''boski efekt''
    Tak więc dzięki.
  • #7 7383865
    regrom
    Poziom 16  
    Najlepszy knight rider jaki widziałem,jeśli chodzi o powolne wygaszenie led




    Uzyskanie takiego efektu PWM, wymaga pewnie programowego napisania PWM.
  • #8 7384462
    skynet77
    Poziom 10  
    Wow, no rzeczywiście fajnie wykonane i elegancko się wygaszają !
    Dopiero zaczołem przerabiać przykład który zapodał kolega gigipaweł, ale do takiego efektu daleka droga.

    Chyba że ktoś z forum już wykonał taki projekt i równie ładnie działał.
    Z resztą dla większości tych którzy znają programowanie troszkę więcej niż ''początki''
    myśle że to nie problem.
  • #9 7385658
    mirekk36
    Poziom 42  
    Skynet77 --> Jako przedsmak - wiesz czego ;) - proszę bardzo.

    Bardzo prosty i na szybko tzn tak na kolanie napisany jakiś tam jeden efekt NightRider na 4 diodach LED. Procek ATmega168. Bo taki hardware akurat miałem pod ręką ;)

    Filmik jest troszkę kiepskiej jakości i może tego aż tak dobrze nie widać ale przesuwają się ładnie 3 zapalone o różnym stopniu jasności diody LED.

    1sza - jasność na maxa
    2ga - świeci sporo ciemniej
    3cia - ledwo co świeci

    i proszę bardzo ;)

    Tak jak wspominałem wyżej wystarczyło trzasnąć sobie w takim akurat przypadku 4kanałowy programowy zwykły PWM na jednym Timerze i tylko programowo jakoś tam przesuwać te zapalene w odpowidniej kolejności i jasności diodki LED






    a poniżej - taki ala kodzik na szybko spłodzony na kolanie - więc mało jakoś tam zoptymalizowany ale to nie istotne w tym przykładzie ;)




    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <inttypes.h>
    
    #define LED1ON PORTB &= ~(1<<2)
    #define LED2ON PORTB &= ~(1<<3)
    #define LED3ON PORTB &= ~(1<<4)
    #define LED4ON PORTB &= ~(1<<5)
    
    #define LED1OFF PORTB |= (1<<2)
    #define LED2OFF PORTB |= (1<<3)
    #define LED3OFF PORTB |= (1<<4)
    #define LED4OFF PORTB |= (1<<5)
    
    
    #define czekaj 80
    #define LEWO 0
    #define PRAWO 1
    
    
    volatile uint8_t k1=0, k2=0, k3=0, k4=0;
    
    uint8_t tab[4] = {255,80,4};
    uint8_t org[4] = {0,0,0,0};
    
    void setTAB(void)
    {
    	k1 = org[0];
    	k2 = org[1];
    	k3 = org[2];
    	k4 = org[3];
    }
    
    
    void shiftLR(uint8_t d)
    {
    	uint8_t i, j;
    	int8_t head = 3;
    	uint8_t b;
    
    	for(i=0;i<7;i++)
    	{
    		b=0-head;
    
    		for(j=0;j<4;j++)
    		{
    			if (head>=0)
    			{
    				if (j>=head)
    				{
    					if(d)
    					{
    						if (b<3) org[3-j]=tab[b];
    						else org[3-j]=0;
    					}
    					else
    					{
    						if (b<3) org[j]=tab[b];
    						else org[j]=0;
    					}
    				}
    				else
    				{
    					if(d) org[3-j] = 0;
    					else org[j] = 0;
    				}
    			}
    			else
    			{
    				if(d)
    				{
    					if (b<3) org[3-j]=tab[b];
    					else org[3-j]=0;
    				}
    				else
    				{
    					if (b<3) org[j]=tab[b];
    					else org[j]=0;
    				}
    			}
    
    			b++;
    		}
    		head--;
    
    		setTAB();
    		_delay_ms(czekaj);
    	}
    }
    
    
    //***************************** PĘTLA GŁÓWNA *************************************
    int main(void)
    {
    	TCCR2B |= (1<<CS20);
    	TIMSK2 |= (1<<TOIE2);
    	DDRB |= 0x3c;
    	PORTD |= 0x3c;
    	sei();
    
    	setTAB();
    	while(1)
    	{
    		shiftLR(LEWO);
    		_delay_ms(100);
    		shiftLR(PRAWO);
    		_delay_ms(100);
    	}
    }
    //**************************************************************************
    
    
    
    
    //------------------------- PRZERWANIE TIMER2 OVF
    ISR(TIMER2_OVF_vect)
    {
    	static uint8_t f = 0;
    
    	if (k1<=f) LED1OFF; else LED1ON;
    	if (k2<=f) LED2OFF; else LED2ON;
    	if (k3<=f) LED3OFF; else LED3ON;
    	if (k4<=f) LED4OFF; else LED4ON;
    	f++;
    }
    
    // QUNIEC ;)
  • #10 7390540
    skynet77
    Poziom 10  
    :please: szacun ! .....no nie wygląda na trudne ale chyba się wstrzymam bo jak widzę te wszystkie ''na kolanie zrobione'' linijki to ciary przechodzą ;)

    Teraz dopiero się wystraszyłem! hahahaha, jęśli to jest przedsmak tego co mnie czeka, to już się boje.:shocked:

    Ale dzięki wielkie, udowodniłeś mi że wkrótce być może sam taki prog napisze :)

    PS. Mam nadzieje że ten program nie będzie działał na ATmedze8 ani 16, bo w symulatorze wyskakują mi dziwne błędy :D
  • #11 7390653
    mirekk36
    Poziom 42  
    Ten program będzie działał na dowolnym procku AVR nawet na najmniejszym ATtiny - bo kod po skompilowaniu zajmuje niewiele ponad 1kb pamięci ;) .... jedyne co trzeba zrobić to zmienić w nim odpowiednie rejestry tak aby dopasować go do danego procka. Ale później jak sam zobaczysz takie dostosowywanie programu to pikuś. Oczywiście zdziwienie twoje może budzić tylko ta dziwna funkcja shiftRL() - ale nią się nie przejmuj - później wyjaśnię o co chodzi. I gwarantuję że i bez takich zagmatwanych z pozoru funkcji też można sobie poradzić z różnymi efektami NightRider'a ;)
REKLAMA