<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=30&amp;t=10160&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2015-01-14T06:43:16+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=30&amp;t=10160&amp;mode</id>
<entry>
<author><name><![CDATA[Horhe]]></name></author>
<updated>2015-01-14T06:43:16+01:00</updated>
<published>2015-01-14T06:43:16+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10160&amp;p=114071#p114071</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10160&amp;p=114071#p114071"/>
<title type="html"><![CDATA[Re: Driver LED]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10160&amp;p=114071#p114071"><![CDATA[
Niestety, nadal nie wiem, dlaczego zliczanie czasu trwania impulsów nie jest dokładne.Zmienna &quot;liczba_impulsów&quot; tak jakby &quot;drży&quot;, to znaczy mniej więcej pokazuje prawdę, ale są pewne (zdecydowanie za duże) wahania. Oczywiście PLC cały czas podaje taki sam sygnał. Wydaje mi się jednak, że ma to związek z tym, że czas trwania impulsu jest liczony nie w przerwaniu, a w głównej pętli programu i stąd te niedokładności.<br /><br />Poradziłem sobie z problemem w ten sposób, że teraz program sprawdza i zapisuje w przerwaniu wyzwalanym pojawieniem się zbocza, czas między zboczem opadającym a rosnącym. Jest to o wiele dokładniejsze. Dla potomności wklejam poprawiony kod:<br /><br />[syntax=c]/*<br /> * main.c<br /> *<br /> *  Created on: 08-01-2015<br /> *      Author: Horhe<br /> */<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &quot;LCD/lcd44780.h&quot;<br />#include &lt;util/delay.h&gt;<br /><br /><br />#define PLC_PIN (1&lt;&lt;PD6)// definicja pinu do którego podłączony jest sygnał z PLC<br />#define LO_LEVEL !(PIND &amp; PLC_PIN)// makro sprawdzające czy jest stan niski, czyli czy jest wysyłany sygnał z PLC<br /><br />#define K2_PIN (1&lt;&lt;PD2)<br />#define K2_DOWN !(PIND &amp; K1_PIN)<br /><br />#define K1_PIN (1&lt;&lt;PD3)<br />#define K1_DOWN !(PIND &amp; K2_PIN)<br /><br />volatile uint8_t ov_counter;// Zmienna pamiętająca liczbę przekręceń licznika TCNT1<br />volatile uint16_t rising;// Zbocze wznoszące<br />volatile uint16_t falling;// Zbocze opadające<br />volatile uint32_t counts;// Suma wszystkich impulsów trwania sygnału<br /><br />uint8_t  czas = 0;<br /><br /><br /><br />int main (void)<br />{<br />//***************************** ustawienia Timera1  ********************************<br /><br />//Ustawienie preskalera<br /><br />TCCR1B |= (1&lt;&lt;CS11)|(1&lt;&lt;CS10);// 64 1/(8000000/64) = 0,000008 s = 8 us65 535 taktów = 0,52428 s<br />TIMSK |= (1&lt;&lt;TOIE1);// zezwolenie na przerwanie od przepełnienia<br />TIMSK |= (1&lt;&lt;ICIE1);// zezwolenie na przerwanie od zbocza<br />//***************************** koniec ustawień Timera1 *************************************<br /><br /><br />//***************************** ustawienia Timera0 ******************************************<br />TCCR0A |= (1&lt;&lt;WGM01) | (1&lt;&lt;WGM00);//Ustawienie trybu FastPWM<br />TCCR0A |= (1&lt;&lt;COM0B1);// Clear OC0B on Compare Match, set OC0A at TOP<br />TCCR0A |= (1&lt;&lt;COM0A1);// Clear OC0A on Compare Match, set OC0A at TOP<br />TCCR0B |= (1&lt;&lt;CS01);// Preskaler = 1<br />//***************************** koniec ustawień Timera0 *************************************<br /><br />DDRD &amp;= ~PLC_PIN;//Ustawienia pinu wejcia z PLC<br />PORTD |= PLC_PIN;//i podciągnięcie go do VCC<br /><br />sei();<br />while (1)<br />{<br />czas = counts*64/1000;<br />OCR0B=czas;<br />}//end while<br />}//end main<br /><br /><br /><br />//==================== PRZERWANIA ===============================<br /><br />// Przerwanie zwiększające licznik impulsów<br />ISR (TIMER1_OVF_vect)<br />{<br />ov_counter ++;//Zwiększenie zmiennej za każdym razem, gdy licznik timera się przepełni<br />}<br /><br /><br />// Przerwanie od zbocza na pinie PCI<br />ISR (TIMER1_CAPT_vect)<br />{<br />//Jeżeli na pinie PCI jest poziom niski<br />if (LO_LEVEL)<br />{<br />falling = ICR1;// Zapamiętanie czasu zbocza opadającego<br />TCCR1B |= (1&lt;&lt;ICES1);// Ustaw przerwanie wyzwalane zboczem wznoszącym<br />ov_counter = 0;//Kasowanie licznika przepełnień<br />}<br />else<br />{<br />rising = ICR1;// Zapamiętanie czasu zbocza wznoszącego<br />TCCR1B &amp;= ~(1&lt;&lt;ICES1);// Ustaw przerwanie wyzwalane zboczem opadającym<br />counts = ((uint32_t)0xFFFF * (uint32_t)ov_counter + (uint32_t)rising - (uint32_t)falling); //Sumuje wszystkie impulsy<br />}<br />}<br />//==================== KONIEC PRZERWAŃ ===============================[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=7232">Horhe</a> — 14 sty 2015, o 06:43</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Horhe]]></name></author>
<updated>2015-01-11T13:54:48+01:00</updated>
<published>2015-01-11T13:54:48+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10160&amp;p=113708#p113708</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10160&amp;p=113708#p113708"/>
<title type="html"><![CDATA[Driver LED]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10160&amp;p=113708#p113708"><![CDATA[
Witam wszystkich serdecznie. <br />Jest to mój pierwszy post na tym forum, całą moją wiedzę o elektronice gromadzę może od pół roku, i jeszcze miesiąc temu o mikrokontrolerach wiedziałem tylko tyle, że istnieją. Temat mnie bardzo wciągnął, a zaczęło się z powodu czysto praktycznego. <br />Otóż, w nowo budowanym domu wymyśliłem sobie automatykę  posuniętą tak daleko jak się da (i dopóki będzie miało to sens), a wszystko będzie sterowane ze sterownika PLC Wago 750-880. Chciałbym m.in. sterować intensywnością oświetlenia w całym domu, ale niestety profesjonalne drivery oparte o DMX512 lub DALI nie są na moją kieszeń i szukałem alternatywnych rozwiązań. W ten sposób dotarłem do uC, postanowiłem zgłębić wiedzę i sam sobie taki driver zmontować.<br /><br />Założenia są następujące:<br />-Oświetlenie, którym chcę sterować to ledy różnej maści,<br />-Sterownik dostaje sygnał z PLC i na jego podstawie świeci sterowanym ledem z odpowiednią jasnością.<br /><br />Sygnał z PLC może być wysłany na dwa sposoby, które rozważam:<br />1. po RS485 wysyła do konkretnego sterownika led wartość od 0 do 255, a ta zostanie już bezpośrednio podstawiona do rejestru OCRx, co pozwoli na ustawienie wypełnienia sygnału PWM,<br />2. poprzez wysyłanie sygnału prostokątnego o określonej częstotliwości - czas pomiędzy zboczami narastającymi będzie podstawą do ustawienia wartości rejestru OCRx. (Trzeba wspomnieć, że niestety, nie można wysyłać sygnału PWM bezpośrednio z PLC, bo jego maksymalna częstotliwość przełączania to 2kHz, więc do sterowania ledem się nie nadaje.)<br /><br />Docelowo będę starał się wykorzystać pierwszy sposób, ale stan wiedzy jeszcze nie pozwala mi się za to zabrać, dlatego wałkuję drugi sposób i po tak długim wstępie, właśnie z tym chciałbym się zwrócić o pomoc.<br /><br />No to teraz konkrety <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" />.<br />Zmontowałem układ na płytce stykowej, gdzie led podłączyłem anodą do pinu PB3 Atmegi 8, a katodę poprzez rezystor do masy. Pin PC0 jest natomiast zwierany do masy poprzez tranzystor w zależności od sygnału podawanego na bazę z PLC. Tak więc układ banalnie prosty. PLC wysyła sygnał o okresie od 2 do 100 ms.<br /><br />Poniżej kod programu:<br />[syntax=c]/*<br /> * main.c<br /> *<br /> *  Created on: 08-01-2015<br /> *      Author: Horhe<br /> */<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br /><br /><br />volatile int liczba_impulsow;<br /><br /><br />#define PLC_PIN (1&lt;&lt;PC0)//definicja pinu do któego podłączony jest sygnał z PLC<br />#define sygnal !(PINC &amp; PLC_PIN)//makro sprawdzające czy jest stan niski, czyli czy jest wysyłany sygnał z PLC<br /><br /><br /><br />int main (void)<br />{<br /><br /><br /><br />//***************************** ustawienia globalnego timera - tryb normal <br />//<br />TCCR0 |= (1&lt;&lt;CS01) | (1&lt;&lt;CS00);// Ustawienie preskalera 64<br />TCNT0 = 131;// inicjalizacja licznika wartoscą 131 aby zliczał dokładnie 125 impulsów<br />TIMSK |= (1&lt;&lt;TOIE0);// zezwolenie na przerwanie od przepełnienia<br />//***************************** koniec ustawień globalnego timera - tryb normal<br /><br /><br /><br />DDRB |=(1&lt;&lt;PB3); //Ustawienie PB3 jako wyjscie PWM<br />TCCR2 |= (1&lt;&lt;WGM21) | (1&lt;&lt;WGM20);//Ustawienie trybu FastPWM<br />TCCR2 |= (1&lt;&lt;COM21);// Clear OC2 at bottom<br />TCCR2 |= (1&lt;&lt;CS20);//Preskaler =1<br /><br /><br /><br /><br />DDRC &amp;= ~PLC_PIN;//Ustawienia pinu wejcia z PLC<br />PORTC |= PLC_PIN;//i podciągnięcie go do VCC<br /><br /><br />int pierwszy_sygnal = 1;<br />int poprzedni_sygnal = 0;<br /><br /><br />sei();<br /><br /><br />while (1)<br />{<br /><br />if (sygnal == 1) //czy podawany jest sygnał z PLC?<br />{<br />if (poprzedni_sygnal == 0)//jesli w poprzednim przebiegu nie wykryto sygnału, to oznacza to, że teraz jest zbocze narastające<br />{//i trzeba zmierzyć czas jaki upłynął od poprzedniego zbocza narastającego<br /><br />if (pierwszy_sygnal == 1) //jeżeli jest to pierwszy sygnał, to nie będzie punktu odniesienia aby liczyć czas<br />{<br />pierwszy_sygnal = 0;<br />liczba_impulsow = 0;<br /><br />}<br />else<br />{<br />OCR2 = liczba_impulsow;<br />liczba_impulsow = 0;//Zerowanie licznika impulsów<br /><br />}<br /><br />}<br />}<br /><br />poprzedni_sygnal = sygnal;<br /><br />}//end while<br />}//end main<br /><br /><br /><br />// Przerwanie zwiększające licznik impulsów co 1 ms<br />ISR (TIMER0_OVF_vect)<br />{<br />TCNT0 = 131;<br />liczba_impulsow ++;<br />}[/syntax] <br /><br />Problem polega na tym, że impulsy z PLC są podawane ze stałą częstotliwością, a dioda zmienia jasność w sposób przypadkowy, a powinna świecić tak samo. Jak zwiększam częstotliwość impulsów, to dioda przygasa, jak zmniejszam, to dioda się rozjaśnia, ale nigdy nie świeci równomiernie tylko raz jaśniej a raz ciemniej.<br />Prawdopodobnie mam gdzieś błąd w programie, ale siedzę drugi dzień i nie mogę go znaleźć. Generalnie jestem przyzwyczajony do pisania programów na PC, gdzie mogę sobie podejrzeć wartości zmiennych, wykonywać program krok po kroku, więc przy programowaniu uC jest mi trudniej.<br /><br />Bardzo proszę o pomoc. A może ktoś widzi inny sposób wysterowania mojego driverka z PLC to chętnie posłucham.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=7232">Horhe</a> — 11 sty 2015, o 13:54</p><hr />
]]></content>
</entry>
</feed>