<?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=8&amp;t=10597&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2015-02-10T20:24:59+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=8&amp;t=10597&amp;mode</id>
<entry>
<author><name><![CDATA[programek]]></name></author>
<updated>2015-02-10T20:24:59+01:00</updated>
<published>2015-02-10T20:24:59+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118304#p118304</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118304#p118304"/>
<title type="html"><![CDATA[Re: Problem z ADC]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118304#p118304"><![CDATA[
Zmieniłem SR na 1, a skoro nie używam uśredniania to zmodyfikowałem jeszcze funkcję <strong>get_vol</strong>:<br />[syntax=c]// zamiana ADC na napięcie<br />void get_vol( uint16_t adc, TVOL * voltage ) {<br /><br /><br />voltage-&gt;adc_mid = adc;<br /><br />uint16_t wynik = ( adc * (uint32_t)voltage-&gt;ref_v ) / voltage-&gt;ref_adc;<br /><br />div_t divmod = div(wynik, 100);<br />itoa( divmod.quot, voltage-&gt;v1, 10 );<br />itoa( divmod.rem, voltage-&gt;v2, 10);<br /><br />if( divmod.rem &lt; 10 ) {<br />voltage-&gt;v2&#91;0&#93;='0';<br />voltage-&gt;v2&#91;1&#93;=divmod.rem+'0';<br />}<br /><br />voltage-&gt;v1&#91;2&#93;=0;<br />voltage-&gt;v2&#91;2&#93;=0;<br />}[/syntax]<br /><br /><strong><span style="color: #808000">------------------------ [ Dodano po: kilkunastu sekundach ]</span></strong><br /><br />Dzięki za szybką pomoc <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1526">programek</a> — 10 lut 2015, o 20:24</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[JanuszT]]></name></author>
<updated>2015-02-10T18:23:59+01:00</updated>
<published>2015-02-10T18:23:59+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118277#p118277</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118277#p118277"/>
<title type="html"><![CDATA[Re: Problem z ADC]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118277#p118277"><![CDATA[
Witam<br /><br />Kurde, ale jak zacząłem, to dopiszę (-: . Kolega powyżej ma rację (-: . Ponieważ &quot;idx&quot; masz jako &quot;static&quot;, to kolejne pola tablicy próbek zapisujesz przy kolejnych wywołaniach tej funkcji. Dopiero powyżej wywołania o numerze &quot;SR&quot; obliczasz średnią z zebranych próbek napięcia, przed tym wywołaniem wartości zerowe w niezapełnionych polach tablicy powodują przekłamanie.<br /><br />Pozdrawiam<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=4367">JanuszT</a> — 10 lut 2015, o 18:23</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[jacekk232]]></name></author>
<updated>2015-02-10T18:16:27+01:00</updated>
<published>2015-02-10T18:16:27+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118273#p118273</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118273#p118273"/>
<title type="html"><![CDATA[Re: Problem z ADC]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118273#p118273"><![CDATA[
W funkcji get_vol() jest zastosowane uśrednianie wyniku. Wyniki ładowane są do tablicy <strong>sr</strong>. Do wyliczenia średniej są brane wartości z wszystkich komórek tej tablicy. Więc jaki może być wynik średniej jeśli w tablicy jest jeden wynik pomiaru lub dwa a reszta jest pusta? Właściwy wynik pojawi się wtedy wszystkie komórki tablicy napełnią się wynikami pomiarów. I dlatego uśrednione napięcie wolno narasta.<br /><br />Jeśli chcesz aby wynik pojawiał się szybciej a nie chcesz rezygnować z uśredniania to albo zmniejsz wielkość tablicy sr albo zwiększ częstotliwość odczytów z ADC. Wtedy tablica sr szybciej się napełni a tym samym uśrednione napięcie osiągnie właściwą wartość.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=204">jacekk232</a> — 10 lut 2015, o 18:16</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[programek]]></name></author>
<updated>2015-02-10T17:33:18+01:00</updated>
<published>2015-02-10T17:33:18+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118266#p118266</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118266#p118266"/>
<title type="html"><![CDATA[Problem z ADC]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10597&amp;p=118266#p118266"><![CDATA[
Witam <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> <br />Piszę właśnie program do mojego robota ( line followera ) i potrzebuje mierzyć napięcie akumulatora ( a także napięcie na wyjściach czujników ).<br /><br />Oglądnąłem pierwsze cztery poradniki z serii Mirka o ADC.<br />Pobrałem kod, lekko zmodyfikowałem i rozdzieliłem na pliki:<br /><br /><br />main.c<br />[syntax=c]/*<br /> * main.c<br /> *<br /> *  Created on: 30 sty 2015<br /> *      Author: Dominik<br /> */<br /> <br /> <br />#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br /> <br />#include &quot;LCD/lcd44780.h&quot;<br />#include &quot;ADC/adc.h&quot;<br /> <br /> <br />int main(void) <br />{<br />        lcd_init(); <br />        lcd_cls();<br /> <br />        lcd_str(&quot;start...&quot;);<br /> <br />        _delay_ms(500);<br /> <br />        // inicjalizacja ADC<br />        ADCSRA |= (1&lt;&lt;ADEN); // włącz ADC<br />        ADCSRA |= (1&lt;&lt;ADPS2)|(1&lt;&lt;ADPS1)|(1&lt;&lt;ADPS0); // preskaler = 128<br />        ADMUX |= REF_VCC;       // ustawiamy wewn. źr odn. VCC<br /> <br /> <br />        accu1_vol.ref_adc = 780;        // zmierzona wartość ADC<br />        accu1_vol.ref_v = 742;          // wartość mierzonego napięcia<br /> <br />        lcd_locate(0,0);<br />        lcd_str(&quot;Napiecie&quot;);<br /> <br />        uint16_t wynik=0;<br /> <br /> <br />    while(1)<br />    {<br />        wynik = pomiar( PA7 );          // dokonujemy pomiaru na kanale PA5<br /> <br />        get_vol( wynik, &amp;accu1_vol );   // zamiana ADC na napięcie i uśrednianie<br /> <br />        lcd_locate(1,1);<br /> <br />        lcd_str( accu1_vol.v1 );        // jednostki i dziesiątki zmierzonego napięcia<br />        lcd_str( &quot;.&quot;);<br />        lcd_str( accu1_vol.v2 );        // część ułamkowa zmierzonego napięcia<br />        lcd_str( &quot; V       &quot;);<br /> <br />        _delay_ms( 250 );<br /> <br />    }<br />}[/syntax]<br /><br />adc.c<br />[syntax=c]/*<br /> * adc.c<br /> *<br /> *  Created on: 9 lut 2015<br /> *      Author: Dominik<br /> */<br /> <br /> <br />#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;stdlib.h&gt;<br /> <br />#include &quot;adc.h&quot;<br /> <br />uint16_t min=1024, max, diff;<br /> <br /> <br />// pomiar napięcia<br />uint16_t pomiar( uint8_t kanal ) {<br /> <br />        ADMUX = (ADMUX &amp; 0b11111000) | kanal;<br /> <br />        ADCSRA |= (1&lt;&lt;ADSC);  // start konwersji<br /> <br />        while( ADCSRA &amp; (1&lt;&lt;ADSC) );<br /> <br />        return ADCW;<br />}<br /> <br /> <br />// zamiana ADC na napięcie i uśrednianie<br />void get_vol( uint16_t adc, TVOL * voltage ) {<br /> <br />        static uint16_t sr&#91;SR&#93;;<br />        static uint8_t idx;<br />        uint32_t sr1=0;<br />        uint8_t i;<br /> <br />        sr&#91; idx++ &amp; (SR-1) &#93; = adc;<br /> <br />//      sr&#91;idx&#93; = adc;<br />//      idx++;<br />//      if(idx&gt;7) idx=0;<br /> <br />//      if( idx &amp; (SR-1) ) return;<br /> <br />        for(i=0; i&lt;SR; i++) sr1+=sr&#91;i&#93;;<br />        sr1 /= SR;<br /> <br />        voltage-&gt;adc_mid = sr1;<br /> <br /> <br />        uint16_t wynik = ( sr1 * (uint32_t)voltage-&gt;ref_v ) / voltage-&gt;ref_adc;<br /> <br />        div_t divmod = div(wynik, 100);<br />        itoa( divmod.quot, voltage-&gt;v1, 10 );<br />        itoa( divmod.rem, voltage-&gt;v2, 10);<br /> <br />        if( divmod.rem &lt; 10 ) {<br />                voltage-&gt;v2&#91;0&#93;='0';<br />                voltage-&gt;v2&#91;1&#93;=divmod.rem+'0';<br />        }<br /> <br />        voltage-&gt;v1&#91;2&#93;=0;<br />        voltage-&gt;v2&#91;2&#93;=0;<br />}[/syntax]<br /><br />adc.h<br />[syntax=c]/*<br /> * adc.h<br /> *<br /> *  Created on: 9 lut 2015<br /> *      Author: Dominik<br /> */<br /> <br />#ifndef ADC_ADC_H_<br />#define ADC_ADC_H_<br /> <br />#define SR 16   // rozmar bufora do celów uśredniania<br /> <br />// definicje bitów odpowiedzialnych za wybór źródła odniesienia<br />#define REF_256 (1&lt;&lt;REFS1)|(1&lt;&lt;REFS0)<br />#define REF_VCC (1&lt;&lt;REFS0)<br /> <br />// typ strukturalny na potrzeby przeliczania napięć z ADC do stringów<br />// v1 - część przed przecinkiem<br />// v2 - część po przecinku<br />typedef struct {<br />        uint16_t adc_mid;       // uśredniona wartość ADC<br />        uint16_t ref_adc;       // środkowy zakres wartości ADC odpowiadającej zmierzonemu niżej napięciu<br />        uint16_t ref_v;         // środkowy zakres napięcia * 100 (czyli np dla 6,5V ---&gt; 650)<br />        char v1&#91;3&#93;;<br />        char v2&#91;3&#93;;<br />} TVOL;<br /> <br />TVOL accu1_vol;                 // zmienna strukturalna na potrzeby np jednego kanału<br /> <br />uint16_t pomiar( uint8_t kanal );<br />void get_vol( uint16_t adc, TVOL * voltage );<br /> <br />#endif /* ADC_ADC_H_ */[/syntax]<br /><br />Dlaczego pierwszy pomiar napięcia jest rzędu 1V, dopiero po kilku czy tak kilkunastu obiegach pętli na wyświetlaczu pojawia się prawidłowy pomiar?<br /><br />Przy kodzie takim jak wyżej nie jest to problemem, ale docelowo w robocie chcę aby pomiar napięcia z akumulatora był dokonywany np co min, a więc chciałbym mieć np funkcję <strong>pomiar_zasilania(); </strong> i aby po jej wykonaniu na lcd pojawiło się napięcie zasilania. <br /><br />No i tu jest problem, ponieważ jak wywołam taką funkcję:<br /><br />[syntax=c]void jakas_funkcja ( void ) <br />{<br />        wynik = pomiar( PA7 );          // dokonujemy pomiaru na kanale PA7<br /> <br />        get_vol( wynik, &amp;accu1_vol );   // zamiana ADC na napięcie i uśrednianie<br /> <br />        lcd_locate(1,1);<br /> <br />        lcd_str( accu1_vol.v1 );        // jednostki i dziesiątki zmierzonego napięcia<br />        lcd_str( &quot;.&quot;);<br />        lcd_str( accu1_vol.v2 );        // część ułamkowa zmierzonego napięcia<br />        lcd_str( &quot; V       &quot;);<br />}[/syntax]<br />To na lcd dostaję np 0,5V Dlaczego??<br />Jedyne rozwiązanie jakie mi przychodzi do głowy to aby w funkcji wyżej dać np pętlę for ( obiegająca np 15 razy ), ale tu pojawia się kolejny kłopot ponieważ pomiary z czujników odbiciowych muszą być wykonywane jak najszybciej.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1526">programek</a> — 10 lut 2015, o 17:33</p><hr />
]]></content>
</entry>
</feed>