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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2014-06-03T11:39:58+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=31&amp;t=6898&amp;mode</id>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-06-03T11:39:58+01:00</updated>
<published>2014-06-03T11:39:58+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=83177#p83177</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=83177#p83177"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=83177#p83177"><![CDATA[
No właśnie jak jest w trybie Rx to zawsze dochodzi kompletny komunikat, a w Listen jakby przełączał się na Idle zanim odbierze pakiet... Dziwne to trochę, ale chwilowo śledztwo zawieszone.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 3 cze 2014, o 11:39</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2014-06-02T19:37:43+01:00</updated>
<published>2014-06-02T19:37:43+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=83094#p83094</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=83094#p83094"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=83094#p83094"><![CDATA[
<div class="quotetitle">michaak napisał(a):</div><div class="quotecontent"><br />I wygląda na to że działa choć zdarzają się błędy w odbiorze np. wysyłam komendę &quot;GiveVolt&quot;, a dochodzi &quot;GiveVol&quot;.<br /></div><br />Jeżeli błędy się zdarzają to trudno będzie znaleźć przyczynę. Jak zawsze brakuje jednego znaku to znaczy, że błąd jest w funkcji <em>void RFM69_Read(uint8_t * data)</em> lub <em>uint8_t RFM69_Send(uint8_t address, uint8_t * data, uint8_t length)</em><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 2 cze 2014, o 19:37</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-31T19:33:13+01:00</updated>
<published>2014-05-31T19:33:13+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82929#p82929</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82929#p82929"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82929#p82929"><![CDATA[
Nadajnik: co 1s wysyła &quot;GiveVolt&quot; na adres odbiornika.<br />Odbiornik po odebraniu ramki wyrzuca buffer na UART@38400bps, parsuje go - jedno proste strncmp() i odsyła odpowiedź - wartość napięcia.<br /><br />W main.c:<br />[syntax=c]if ( DataReady ) {<br />        uint8_t len;<br />        char string&#91;20&#93;;<br /><br />uart_putstr(buffer);<br />uart_putstr(&quot;\r\n&quot;);<br /><br />        len = strlen(buffer);<br /><br />        if ( !strncmp(buffer, &quot;GiveVolt&quot;, len) ) {<br /><br />       itoa( SupplyVoltage, string, 10 );<br />        RFM69_Send(ReceiverAddress, string, 0);<br />        }<br /><br />        if ( !strncmp(buffer, &quot;GiveTemp&quot;, len) ) {<br /><br />       itoa( Temperature, string, 10 );<br />        RFM69_Send(ReceiverAddress, string, 0);<br />        }<br /><br /><br />    DataReady = 0;<br />    }[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 31 maja 2014, o 19:33</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2014-05-29T20:59:25+01:00</updated>
<published>2014-05-29T20:59:25+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82783#p82783</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82783#p82783"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82783#p82783"><![CDATA[
Nie lepiej sobie dodać parę bitów:<br />[syntax=c]//RegOpMode(0x01)<br />//6<br />#define ListenOn   (1&lt;&lt;6) //Enables Listen mode, should be enabled whilst in Standby mode: 0 ›Off 1 ›On<br />//5<br />#define ListenAbort   (1&lt;&lt;5) //Aborts Listen mode when set together with ListenOn=0. Always reads 0.<br />//4-2 Mode<br />#define SLEEP   (0b000&lt;&lt;2)  //Sleep mode (SLEEP)<br />#define STDBY    (0b001&lt;&lt;2)  //Standby mode (STDBY)<br />#define FS      (0b010&lt;&lt;2)  //Frequency Synthesizer mode (FS)<br />#define TX      (0b011&lt;&lt;2)  //Transmitter mode (TX)<br />#define RX      (0b100&lt;&lt;2)  //Receiver mode (RX)<br /><br />//RegListen1(0x0D)<br />//7-6 ListenResolIdle <br />#define LRI_64us(0b01&lt;&lt;6)//Idle time resolution 64us<br />#define LRI_4_1s(0b10&lt;&lt;6)//Idle time resolution 4.1ms<br />#define LRI_262ms(0b11&lt;&lt;6)//Idle time resolution 4.1ms<br />//5-4 ListenResolRx<br />#define LRR_64us(0b01&lt;&lt;4)//Rx time resolution 64us<br />#define LRR_4_1s(0b10&lt;&lt;4)//Rx time resolution 4.1ms<br />#define LRR_262ms(0b11&lt;&lt;4)//Rx time resolution 4.1ms<br />//3 ListenCriteria<br />#define LC_RssiTr(0&lt;&lt;3)//signal strength is above RssiThreshold<br />#define LC_SyncAdr(1&lt;&lt;3)//signal strength is above RssiThreshold and SyncAddress matched<br />//2-1 ListenEnd<br />#define LE_Rx(0b00&lt;&lt;1) //Rx mode. Listen mode stops and must be disabled <br />#define LE_Mode(0b01&lt;&lt;1)//defined by Mode. Listen mode stops and must be disabled <br />#define LE_Idle(0b10&lt;&lt;1)//Listen mode then resumes in Idle state.[/syntax]<br />Wtedy konfiguracja wygląda prościej:<br />[syntax=c]void RFM69_Listen(void) {<br />        RFM69_write(RegOpMode, STDBY);<br />        RFM69_write(RegListen1, LRI_4_1ms | LRR_4_1ms | LC_SyncAdr | LE_Mode);   <br />        RFM69_write(RegOpMode, ListenOn | STDBY);<br />}<br />void RFM69_StopListen(void) {  <br />        RFM69_write(RegOpMode, ListenAbort | STDBY);<br />        RFM69_write(RegOpMode, STDBY);<br />}[/syntax]<br />Wyłączenie ListenMode powinno być po odebraniu ramki czyli w kodzie przerwania. Wciskanie tego do RFM69_Send jest dziwne moim zdaniem:<br />[syntax=c]ISR(INT0_vect) <br />{<br />if(ActiveTx) //po wysłaniu ramki przejdź w tryb odbioru<br />{<br />ActiveTx = 0;<br />RFM69_Listen();<br />} <br />else //po otrzymaniu ramki odczytaj FIFO<br />{<br />RFM69_StopListen();<br />RFM69_Read(buffer);<br />}<br />}[/syntax]<br />Przy domyślnych mnożnikach i rozdzielczościach 4.1ms wyjdzie 131,2ms odbioru i 1,0045s stanu Idle. Wypadałoby ustawić nadajnik, aby wysyłał ramkę co 100ms, a odbiornik musi wysłać odpowiedź zanim nadajnik zacznie nadawać kolejną ramkę, bo moduł w stanie nadawania nic nie odbierze. Jest też inna technika, gdzie okres wysyłania jest równy stanowi Idle (ale nie sumie stanu odbioru i Idle) wtedy przy czasach dobranych jak opisano raz na 10 wysłanych ramek jedna dotrze do odbiornika, a on będzie miał dużo czasu na odesłanie odpowiedzi. Błędy w odbiorze są niemożliwe skoro jest CRC. Możesz to dokładniej opisać? Co nadajesz i co robisz z odebraną ramką?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 29 maja 2014, o 20:59</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-29T17:03:08+01:00</updated>
<published>2014-05-29T17:03:08+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82763#p82763</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82763#p82763"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82763#p82763"><![CDATA[
Teraz usiłuję skorzystać z listen mode...<br />[syntax=c]/* Ustawia tryb ListenMode */<br />void RFM69_Listen(void) {<br />RFM69_write(RegListen1, 0b10011100);<br />RFM69_write(RegOpMode, 0b01000100);<br />}[/syntax]<br /><br />Teoretycznie teraz jak wyłapie pakiet spełniający warunki to go odbierze, a wygląda jakby nic nie odebrał bo brak reakcji.<br />Jak ustawię na odbiór to jest OK.<br /><br />Edit:<br />Ustawiłem większą wartość dla ListenResolRx bo pewnie przy domyślnych 64us przy niskim baudrate (2400bps) nie nadążał odbierać bajtów synchronizacji przed przejściem z powrotem w Idle.<br />Jednak na otrzymaną komendę brak odpowiedzi...<br /><br />[syntax=c]ISR(INT0_vect) {<br /><br />if(ActiveTx) {<br />ActiveTx = 0;<br />        //RFM69_Standby();<br />        //RFM69_Rx();<br />        RFM69_Listen();<br />    } else {<br />        RFM69_Read(buffer);<br />    }<br />}[/syntax]<br /><br />Edit2:<br />Stworzyłem funkcję:<br />[syntax=c]void RFM69_StopListen(void) {<br />RFM69_write(RegOpMode, 0b00100100);<br />RFM69_write(RegOpMode, 0b00000100);<br />}[/syntax]<br /><br />I zmieniłem w RFM69_Send...<br />[syntax=c]...<br />    ActiveTx = 1;<br />    //RFM69_Standby();<br />    RFM69_StopListen();<br />...[/syntax]<br /><br />I wygląda na to że działa choć zdarzają się błędy w odbiorze np. wysyłam komendę &quot;GiveVolt&quot;, a dochodzi &quot;GiveVol&quot;.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 29 maja 2014, o 17:03</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2014-05-28T17:58:56+01:00</updated>
<published>2014-05-28T17:58:56+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82644#p82644</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82644#p82644"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82644#p82644"><![CDATA[
Było o jeden while za dużo. Flaga SPIF jest zerowana po odczycie rejestru SPSR i następującej po nim operacji na rejestrze SPDR. Kolejny update.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 28 maja 2014, o 17:58</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[michaak]]></name></author>
<updated>2014-05-28T10:31:19+01:00</updated>
<published>2014-05-28T10:31:19+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82604#p82604</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82604#p82604"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82604#p82604"><![CDATA[
Wyglada na to, że odbiornik się zwiesza w trakcie wykonywania  address = RFM69_read(RegFifo); <br />- czyli po drugim odczycie. <br /><br />[syntax=c]void RFM69_Read(uint8_t * data) {<br />    uint8_t length, address;<br />uint8_t i;<br />    ActiveRx = 1;<br />    length = RFM69_read(RegFifo);<br />    address = RFM69_read(RegFifo); // tutaj się zwiesza<br />    for(i = 0; i &lt; length - 1; i++)<br />        data&#91;i&#93; = RFM69_read(RegFifo);<br />    data&#91;i&#93; = '\0';<br />    RFM69_ClearFIFO();<br />    DataReady = length - 1;<br />    ActiveRx = 0;<br />}[/syntax]<br /><br />Nie miałem czasu się wgłębiać dlaczego poprzednia funkcja się zawiesza, ale gdy zmieniłem funkcję RFM69_Read(uint8_t * data) na tą od Szoplera to wszystko zaczęło działać. <br /><br />Podziękowania dla Krauser'a za cenne fragmenty kodu.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=4525">michaak</a> — 28 maja 2014, o 10:31</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2014-05-27T18:57:27+01:00</updated>
<published>2014-05-27T18:57:27+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82554#p82554</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82554#p82554"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82554#p82554"><![CDATA[
W kodzie odbiornika linia <em>RFM69_Rx();</em> powinna być w &quot;ciele&quot; funkcji main za <em>RFM69_Config();</em>, bo teraz to odbiornik jest w trybie standby<br /><br />Jak nie korzystamy z przerwań to kod funkcji main nadajnika może wyglądać na przykład tak:<br />[syntax=c]#define DIO0_IN (PIND &amp; (1&lt;&lt;PD2))<br />#define LED_ON ...<br />#define LED_RED_ON ...<br />#define LED_GREEN_ON ...<br />#define LED_OFF ...<br />#define LED_RED_OFF ...<br />#define LED_GREEN_OFF ...<br /><br />int main(void)<br />{<br />    uint8_t flaga = 0;<br />    //konfiguracja wejść/wyjść<br />    //...<br />    spi_init();<br />    _delay_ms(500); //czas na osiągnięcie gotowości modułu po włączeniu zasilania <br />    RFM69_Config();<br />    RFM69_Rx();<br /><br />while (1) <br />{<br />if (0 == Timer1)<br />{<br />Timer1 = 200; //co 2 sekundy <br />if(0 == flaga)<br />{<br />RFM69_Send(ReceiverAddress, &quot;LED:ON&quot;, 0);<br />flaga = 1;<br />}<br />else<br />{<br />RFM69_Send(ReceiverAddress, &quot;LED:OFF&quot;, 0);<br />flaga = 0;<br />}<br />}<br />if(ActiveTx) //sygnalizacja LED<br />{<br />LED_RED_ON;<br />LED_GREEN_OFF;<br />}<br />else<br />{<br />LED_RED_OFF;<br />LED_GREEN_ON;<br />}<br /><br />#if 1 //jak nie używamy przerwania INT0<br />if(DIO0_IN &amp;&amp; ActiveTx) //ramka została wysłana<br />{<br />ActiveTx = 0;<br />RFM69_Standby();<br />RFM69_Rx();<br />}<br />if(DIO0_IN &amp;&amp; !ActiveTx) //ramka została odebrana<br />{<br />RFM69_Read(buffer); //pobranie z FIFO do bufora<br />}<br />#endif<br /><br />if(DataReady) //dane są gotowe do odbioru<br />{<br />uart_puts(buffer);<br />DataReady = 0;<br />}<br />}<br />}[/syntax]<br />a odbiornika tak:<br />[syntax=c]#define DIO0_IN (PIND &amp; (1&lt;&lt;PD2))<br />#define LED_ON ...<br />#define LED_RED_ON ...<br />#define LED_GREEN_ON ...<br />#define LED_OFF ...<br />#define LED_RED_OFF ...<br />#define LED_GREEN_OFF ...<br /><br />int main(void)<br />{<br />    //konfiguracja wejść/wyjść<br />    //...<br />    spi_init();<br />    _delay_ms(500); //czas na osiągnięcie gotowości modułu po włączeniu zasilania <br />    RFM69_Config();<br />    RFM69_Rx();<br /><br />while (1) <br />{<br />if(ActiveTx) //sygnalizacja LED<br />{<br />LED_RED_ON;<br />LED_GREEN_OFF;<br />}<br />else<br />{<br />LED_RED_OFF;<br />LED_GREEN_ON;<br />}<br /><br />#if 1 //jak nie używamy przerwania INT0<br />if(DIO0_IN &amp;&amp; ActiveTx) //ramka została wysłana<br />{<br />ActiveTx = 0;<br />RFM69_Standby();<br />RFM69_Rx();<br />}<br />if(DIO0_IN &amp;&amp; !ActiveTx) //ramka została odebrana<br />{<br />RFM69_Read(buffer); //pobranie z FIFO do bufora<br />}<br />#endif<br /><br />if(DataReady) //dane są gotowe do przetwarzania<br />{<br />if(0 == strcmp(buffer, &quot;LED:ON&quot;)) <br />{ <br />LED_ON; <br />RFM69_Send(ReceiverAddress, &quot;OK:ON&quot;, 0);<br />}<br />if(0 == strcmp(buffer, &quot;LED:OFF&quot;))<br />{ <br />LED_OFF; <br />RFM69_Send(ReceiverAddress, &quot;OK:OFF&quot;, 0);<br />}<br />DataReady = 0;<br />}<br />}<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 27 maja 2014, o 18:57</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[michaak]]></name></author>
<updated>2014-05-28T13:25:06+01:00</updated>
<published>2014-05-27T14:43:39+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82539#p82539</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82539#p82539"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82539#p82539"><![CDATA[
Witam wszystkich forumowiczów <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> <br />Próbuję zaimplementować całość do atmeg 168, mam problem z odczytem w urządzeniu odbiorczym. Układ nadawczy ma cyklicznie wysyłać dane do odbiornika. Po analizie z oscyloskopem wygląda na to, że jest przerwanie na wyprowadzeniu DIO2 (FifoNotEmpty) w trakcie wysylania i pojawia się sygnał na wyjściu antenowym (wiem że częstotliwość przekracza możliwości oscyloskopu, ale coś się zmienia więc zakładam, że uklada nadawczy działa  <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> )<br /> Problem mam po stronie odbiornika tzn. nie pojawia się przerwanie na wyprowadzeniu DIO0 (PayloadReady), ani na DIO2. Czym to może być spowodowane ?<br /><br />Poniżej zamieszczam listingi do programu:<br /><br />Kod nadajnika:<br /><br />[syntax=c]#define F_CPU 10000000L<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;string.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;inttypes.h&gt;<br />#include &lt;util/delay.h&gt; <br />#include &quot;RFM69registers.h&quot;<br /><br />#define SS(1&lt;&lt;PD1)<br />#define MOSI(1&lt;&lt;PB3)<br />#define MISO(1&lt;&lt;PB4)<br />#define SCK(1&lt;&lt;PB5)<br /><br />#define FXOSC   32UL<br />#define FRF(x)  (x*524288UL/FXOSC)<br /> <br />#define NodeAddress 0x02  //w drugim na odwrot<br />#define ReceiverAddress 0x01 //w drugim na odwrot<br />#define BroadcastAddress 0xFF<br /> <br />//RegOpMode(0x01)<br />//4-2 Mode<br />#define SLEEP   (0b000&lt;&lt;2)  //Sleep mode (SLEEP)<br />#define STDBY    (0b001&lt;&lt;2)  //Standby mode (STDBY)<br />#define FS      (0b010&lt;&lt;2)  //Frequency Synthesizer mode (FS)<br />#define TX      (0b011&lt;&lt;2)  //Transmitter mode (TX)<br />#define RX      (0b100&lt;&lt;2)  //Receiver mode (RX)<br /> <br />//RegDioMapping1(0x25)<br />//7-6 Dio0Mapping<br />#define RxDio0PayloadReady  (0b01&lt;&lt;6)<br />#define TxDio0PackedSend  (0b00&lt;&lt;6)<br /> <br />//RegSyncConfig(0x2e)<br />//7 SyncOn<br />#define SyncON  (1&lt;&lt;7)<br />#define SyncOFF (0&lt;&lt;7)<br />//6 FifoFillCondition<br />//5-3 SyncSize<br />#define Sync8byte   (0b111&lt;&lt;3)<br />//2-0 SyncTol<br /> <br />//RegPacketConfig1(0x37)<br />//7 PacketFormat<br />#define FixedLength     (0&lt;&lt;7 ) //Fixed length<br />#define VariableLength  (1&lt;&lt;7)  //Variable length<br />//6-5 DcFree<br />#define DcFreeOFF   (0b00&lt;&lt;5)   //None (Off)<br />#define Manchester  (0b01&lt;&lt;5)   //Manchester<br />#define Whitening   (0b10&lt;&lt;5)   //Whitening<br />//4 CrcOn<br />#define CrcOFF   (0&lt;&lt;4) //Off<br />#define CrcON   (1&lt;&lt;4) //On<br />//3 CrcAutoClearOff<br />#define ClearON (0&lt;&lt;3)  //Clear FIFO and restart new packet reception<br />#define ClearFF (1&lt;&lt;3)  //Do not clear FIFO. PayloadReady interrupt issued<br />//2-1 AddressFiltering<br />#define AddressOFF    (0b00&lt;&lt;1)   //None (Off)<br />#define AddressNode   (0b01&lt;&lt;1)   //Address field must match NodeAddress<br />#define AddressNodeBroadcast    (0b10&lt;&lt;1)   //Address field must match NodeAddress or BroadcastAddress<br /> <br />const uint8_t RFM69ConfigTable&#91;&#93;&#91;2&#93; = {<br /><br />{REG_BITRATEMSB, 0x34}, //32MHz/0x3410 = 2.4kpbs<br />{REG_BITRATELSB, 0x10},<br />{REG_FDEVMSB, 0x02}, //241*61Hz = 35KHz<br />{REG_FDEVLSB, 0x41},<br />{REG_FRFMSB, 0xD9}, //868MHz<br />{REG_FRFMID, 0x00},<br />{REG_FRFLSB, 0x00},<br />{REG_LNA, 0x88}, //200R Auto gain<br />{REG_RXBW, 0x52}, //83KHz<br />{REG_AFCBW, 0x8B}, //recommended value<br />{REG_DIOMAPPING1, RxDio0PayloadReady},<br />{REG_RSSITHRESH, 0xEC}, //118dBm<br />{REG_PREAMBLEMSB, 0x00}, //5 PreambleBytes<br />{REG_PREAMBLELSB, 0x05},<br />{REG_SYNCCONFIG, SyncON | Sync8byte}, //On, 8B, no errors<br />{REG_SYNCVALUE1, 'A'}, //SyncWord = Network ID<br />{REG_SYNCVALUE2, 'T'},<br />{REG_SYNCVALUE3, 'N'},<br />{REG_SYNCVALUE4, 'E'},<br />{REG_SYNCVALUE5, 'L'},<br />{REG_SYNCVALUE6, '.'},<br />{REG_SYNCVALUE7, 'P'},<br />{REG_SYNCVALUE8, 'L'},<br />{REG_PACKETCONFIG1, VariableLength | Whitening | CrcON | ClearON | AddressNodeBroadcast},<br />{REG_PAYLOADLENGTH, 66},<br />{REG_NODEADRS, NodeAddress},<br />{REG_BROADCASTADRS, BroadcastAddress},<br />{REG_FIFOTHRESH, 0x9F},<br />{RegTestLna, 0x1B}, //Normal sensitivity<br />{REG_TESTDAGC, 0x30}, //Improved DAGC<br />{REG_OPMODE, STDBY}<br />};<br /> <br /> <br /> <br /> <br /> volatile uint8_t ActiveTx, ActiveRx, DataReady;<br /> uint8_t buffer&#91;49&#93;; //bufor z odebranymi danymi ( w main dodac extern buffer&#91;49&#93;; )<br /> <br /> <br />void spi_tx(uint8_t data) {<br />SPDR = data;<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />}<br /><br />uint8_t spi_rx(void) {<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />return SPDR;<br />}<br /> <br />//! zapisuje bajt do modułu pod określony adres<br />/*!<br />\param address - adres docelowy<br />\param data - dane do zapisania<br />*/<br />void RFM69_write(uint8_t address, uint8_t data)<br />{<br />// DDRB|= 0b00000010;<br />// PORTB|= 0b00000010;<br />    PORTD &amp;= ~SS;<br />    SPDR = address | 0x80; //dla zapisu adres ma MSB = 1<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    SPDR = data;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    PORTD |=  SS;<br />}<br /> <br />//! odczytuje bajt z określonego adresu modułu<br />/*!<br />\param address - adres docelowy<br />\return - dane spod adresu<br />*/<br />uint8_t RFM69_read(uint8_t address)<br />{<br />    uint8_t data;<br />    PORTD &amp;= ~SS;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) ); //odczekanie na zakończenie wcześniejszej transmisji<br />    SPDR = address;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    SPDR = 0x00; //dowolna wartość<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    data = SPDR;<br />    PORTD |=  SS;<br />    return data;<br />}<br /> <br />//! ustawia czestotliwosc pracy<br />/*!<br />\param frequency - czestotliwosc FRF(x) np. FRF(868)<br />*/<br />void RFM69_Freq(uint32_t frequency)<br />{<br />    RFM69_write(RegFrfMsb, (uint8_t)(frequency&gt;&gt;16));<br />    RFM69_write(RegFrfMid, (uint8_t)(frequency&gt;&gt;8));<br />    RFM69_write(RegFrfLsb, (uint8_t)frequency);<br />}<br /><br />const uint8_t RFM69RxTable&#91;&#93;&#91;2&#93; = {<br />    {RegDioMapping1, RxDio0PayloadReady},<br />    {RegPaLevel, 0x9F},<br />    {RegTestPa1, 0x55},<br />    {RegTestPa2, 0x70},<br />    {RegOpMode, RX}<br />};<br />const uint8_t RFM69TxTable&#91;&#93;&#91;2&#93; = {<br />    {RegDioMapping1, TxDio0PackedSend},<br />    {RegPaLevel, 0x9F},<br />    {RegTestPa1, 0x55},<br />    {RegTestPa2, 0x70},<br />    {RegOpMode, TX}<br />};<br /><br />//! ustawia domyslne wartosci rejestrow modulu<br /> void RFM69_Config(void) {<br /> for ( uint8_t i = 0; i &lt; sizeof(RFM69ConfigTable)/2; i++)<br /> RFM69_write(RFM69ConfigTable&#91;i&#93;&#91;0&#93;, RFM69ConfigTable&#91;i&#93;&#91;1&#93;);<br /> }<br />//! czysci FIFO modulu<br />/*!<br /> ustawia w tryb odbioru<br />*/<br />void RFM69_ClearFIFO(void) {<br />    RFM69_write(RegOpMode, STDBY); //Entry Standby Mode<br />    RFM69_write(RegOpMode, RX); //Change to Rx Mode<br />}<br />//! ustawia tryb uspienia<br />void RFM69_Sleep(void) {<br />    RFM69_write(RegOpMode, SLEEP); //sleep mode<br />}<br />//! ustawia tryb gotowosci<br />void RFM69_Standby(void) {<br />    RFM69_write(RegOpMode, STDBY); //standby mode<br />}<br />//! ustawia tryb odbioru<br />void RFM69_Rx(void) {<br />    for (uint8_t i = 0; i &lt; sizeof(RFM69RxTable)/2; i++) //config RFM69 RxMode parameters<br />        RFM69_write(RFM69RxTable&#91;i&#93;&#91;0&#93;, RFM69RxTable&#91;i&#93;&#91;1&#93; );<br />}<br /> <br />//! wysyla dane na podany adres wezla<br />/*!<br />\param address - adres wezla<br />\param *data - wskaznik do bufora z danymi<br />\param length - ilosc bajtow do wyslania, jak 0 to bufor traktowany jest jak C-String, max 48 znakow<br />\return - 0 sukces, 1 - za duzo danych, 2 - odbior w toku, 3 - nadawanie w toku<br />*/<br />uint8_t RFM69_Send(uint8_t address, uint8_t * data, uint8_t length) {<br />    if(!length) length = strlen((char *)data);<br />    if(length &gt; 48) return 1;<br />    if(ActiveRx) return 2;<br />    if(ActiveTx) return 3;<br />PORTB&amp;= ~0b00000010;<br />    ActiveTx = 1;<br />    RFM69_Standby();<br />   <br />    RFM69_write(RegFifo, length + 1);<br />    RFM69_write(RegFifo, address);<br />    if(length) //byte data<br />    {<br />        for(uint8_t i = 0; i &lt; length; i++)<br />            RFM69_write(RegFifo, data&#91;i&#93;);<br />    }<br />    else //C-String<br />    {<br />        while(*data)<br />        {<br />            RFM69_write(RegFifo, *data);<br />            data++;<br />        }<br />    }<br />    for (uint8_t i = 0; i &lt; sizeof(RFM69TxTable)/2; i++) //config RFM69 TxMode parameters<br />        RFM69_write(RFM69TxTable&#91;i&#93;&#91;0&#93;, RFM69TxTable&#91;i&#93;&#91;1&#93;);<br />    return 0;<br />}<br />//! odczytuje dane z FIFO modulu do bufora<br />/*!<br /> ustawia zmienna DataReady i umieszca w niej ilosc odebranych bajtow<br />\param *data - wskaznik do bufora z danymi<br />*/<br />void RFM69_Read(uint8_t * data) {<br />    uint8_t length, address;<br />uint8_t i;<br />    ActiveRx = 1;<br />    length = RFM69_read(RegFifo);<br />    address = RFM69_read(RegFifo);<br />    for(i = 0; i &lt; length - 1; i++)<br />        data&#91;i&#93; = RFM69_read(RegFifo);<br />    data&#91;i&#93; = '\0';<br />    RFM69_ClearFIFO();<br />    DataReady = length - 1;<br />    ActiveRx = 0;<br />}<br /> <br /> <br />//! funkcja obslugi przerwania / zbocze narastajace DIO0<br />/*!<br /> obsluguje odbieranie danych i przelaczanie w tryb odbioru<br />*/<br />ISR(INT0_vect)<br />{<br />extern uint8_t buffer&#91;49&#93;;<br />    if(ActiveTx)<br />    {<br />        ActiveTx = 0;<br />        RFM69_Standby();<br />        RFM69_Rx();<br />    }<br />    else<br />    {<br />        RFM69_Read(buffer);<br />    }<br />}<br /><br />void spi_init(void) {<br />DDRD|= SS;<br />PORTD|= SS;<br />DDRB |= MOSI|SCK|(1&lt;&lt;PB2); // PB2 to domyślny CS który musi byc wyjściem inaczej się zwiesza SPI <br />DDRB &amp;=~MISO;<br />SPCR |= (1&lt;&lt;SPE)|(1&lt;&lt;MSTR)|(1&lt;&lt;SPR0);<br />}<br /><br /><br /><br /><br />int main(void)<br />{<br /><br />//konfiguracja spi , przerwan  i modulu<br />spi_init();<br />RFM69_Config();<br />RFM69_Freq(FRF(868));<br /><br /><br />while (1) {<br />_delay_ms(100);<br />RFM69_Send(BroadcastAddress, &quot;ananas&quot;, 0);<br />        ActiveTx = 0;<br />        RFM69_Standby();<br />_delay_ms(100);<br />}<br /><br />}[/syntax]<br /><br />Kod odbiornika:<br />[syntax=c]#define F_CPU 10000000L<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;string.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;inttypes.h&gt;<br />#include &lt;util/delay.h&gt; <br />#include &quot;RFM69registers.h&quot;<br /><br />#define SS(1&lt;&lt;PD1)<br />#define MOSI(1&lt;&lt;PB3)<br />#define MISO(1&lt;&lt;PB4)<br />#define SCK(1&lt;&lt;PB5)<br /><br />#define FXOSC   32UL<br />#define FRF(x)  (x*524288UL/FXOSC)<br /> <br />#define NodeAddress 0x01  //w drugim na odwrot<br />#define ReceiverAddress 0x02 //w drugim na odwrot<br />#define BroadcastAddress 0xFF<br /> <br />//RegOpMode(0x01)<br />//4-2 Mode<br />#define SLEEP   (0b000&lt;&lt;2)  //Sleep mode (SLEEP)<br />#define STDBY    (0b001&lt;&lt;2)  //Standby mode (STDBY)<br />#define FS      (0b010&lt;&lt;2)  //Frequency Synthesizer mode (FS)<br />#define TX      (0b011&lt;&lt;2)  //Transmitter mode (TX)<br />#define RX      (0b100&lt;&lt;2)  //Receiver mode (RX)<br /> <br />//RegDioMapping1(0x25)<br />//7-6 Dio0Mapping<br />#define RxDio0PayloadReady  (0b01&lt;&lt;6)<br />#define TxDio0PackedSend  (0b00&lt;&lt;6)<br /> <br />//RegSyncConfig(0x2e)<br />//7 SyncOn<br />#define SyncON  (1&lt;&lt;7)<br />#define SyncOFF (0&lt;&lt;7)<br />//6 FifoFillCondition<br />//5-3 SyncSize<br />#define Sync8byte   (0b111&lt;&lt;3)<br />//2-0 SyncTol<br /> <br />//RegPacketConfig1(0x37)<br />//7 PacketFormat<br />#define FixedLength     (0&lt;&lt;7 ) //Fixed length<br />#define VariableLength  (1&lt;&lt;7)  //Variable length<br />//6-5 DcFree<br />#define DcFreeOFF   (0b00&lt;&lt;5)   //None (Off)<br />#define Manchester  (0b01&lt;&lt;5)   //Manchester<br />#define Whitening   (0b10&lt;&lt;5)   //Whitening<br />//4 CrcOn<br />#define CrcOFF   (0&lt;&lt;4) //Off<br />#define CrcON   (1&lt;&lt;4) //On<br />//3 CrcAutoClearOff<br />#define ClearON (0&lt;&lt;3)  //Clear FIFO and restart new packet reception<br />#define ClearFF (1&lt;&lt;3)  //Do not clear FIFO. PayloadReady interrupt issued<br />//2-1 AddressFiltering<br />#define AddressOFF    (0b00&lt;&lt;1)   //None (Off)<br />#define AddressNode   (0b01&lt;&lt;1)   //Address field must match NodeAddress<br />#define AddressNodeBroadcast    (0b10&lt;&lt;1)   //Address field must match NodeAddress or BroadcastAddress<br /> <br />const uint8_t RFM69ConfigTable&#91;&#93;&#91;2&#93; = {<br /><br />{REG_BITRATEMSB, 0x34}, //32MHz/0x3410 = 2.4kpbs<br />{REG_BITRATELSB, 0x10},<br />{REG_FDEVMSB, 0x02}, //241*61Hz = 35KHz<br />{REG_FDEVLSB, 0x41},<br />{REG_FRFMSB, 0xD9}, //868MHz<br />{REG_FRFMID, 0x00},<br />{REG_FRFLSB, 0x00},<br />{REG_LNA, 0x88}, //200R Auto gain<br />{REG_RXBW, 0x52}, //83KHz<br />{REG_AFCBW, 0x8B}, //recommended value<br />{REG_DIOMAPPING1, RxDio0PayloadReady},<br />{REG_RSSITHRESH, 0xEC}, //118dBm<br />{REG_PREAMBLEMSB, 0x00}, //5 PreambleBytes<br />{REG_PREAMBLELSB, 0x05},<br />{REG_SYNCCONFIG, SyncON | Sync8byte}, //On, 8B, no errors<br />{REG_SYNCVALUE1, 'A'}, //SyncWord = Network ID<br />{REG_SYNCVALUE2, 'T'},<br />{REG_SYNCVALUE3, 'N'},<br />{REG_SYNCVALUE4, 'E'},<br />{REG_SYNCVALUE5, 'L'},<br />{REG_SYNCVALUE6, '.'},<br />{REG_SYNCVALUE7, 'P'},<br />{REG_SYNCVALUE8, 'L'},<br />{REG_PACKETCONFIG1, VariableLength | Whitening | CrcON | ClearON | AddressNodeBroadcast},<br />{REG_PAYLOADLENGTH, 66},<br />{REG_NODEADRS, NodeAddress},<br />{REG_BROADCASTADRS, BroadcastAddress},<br />{REG_FIFOTHRESH, 0x9F},<br />{RegTestLna, 0x1B}, //Normal sensitivity<br />{REG_TESTDAGC, 0x30}, //Improved DAGC<br />{REG_OPMODE, STDBY}<br />};<br /> <br /> <br /> <br /> <br /> volatile uint8_t ActiveTx, ActiveRx, DataReady;<br /> uint8_t buffer&#91;49&#93;; //bufor z odebranymi danymi ( w main dodac extern buffer&#91;49&#93;; )<br /> <br /> <br />void spi_tx(uint8_t data) {<br />SPDR = data;<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />}<br /><br />uint8_t spi_rx(void) {<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />return SPDR;<br />}<br /> <br />//! zapisuje bajt do modułu pod określony adres<br />/*!<br />\param address - adres docelowy<br />\param data - dane do zapisania<br />*/<br />void RFM69_write(uint8_t address, uint8_t data)<br />{<br />// DDRB|= 0b00000010;<br />// PORTB|= 0b00000010;<br />    PORTD &amp;= ~SS;<br />    SPDR = address | 0x80; //dla zapisu adres ma MSB = 1<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    SPDR = data;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    PORTD |=  SS;<br />}<br /> <br />//! odczytuje bajt z określonego adresu modułu<br />/*!<br />\param address - adres docelowy<br />\return - dane spod adresu<br />*/<br />uint8_t RFM69_read(uint8_t address)<br />{<br />    uint8_t data;<br />    PORTD &amp;= ~SS;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) ); //odczekanie na zakończenie wcześniejszej transmisji<br />    SPDR = address;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    SPDR = 0x00; //dowolna wartość<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    data = SPDR;<br />    PORTD |=  SS;<br />    return data;<br />}<br /> <br />//! ustawia czestotliwosc pracy<br />/*!<br />\param frequency - czestotliwosc FRF(x) np. FRF(868)<br />*/<br />void RFM69_Freq(uint32_t frequency)<br />{<br />    RFM69_write(RegFrfMsb, (uint8_t)(frequency&gt;&gt;16));<br />    RFM69_write(RegFrfMid, (uint8_t)(frequency&gt;&gt;8));<br />    RFM69_write(RegFrfLsb, (uint8_t)frequency);<br />}<br /><br />const uint8_t RFM69RxTable&#91;&#93;&#91;2&#93; = {<br />    {RegDioMapping1, RxDio0PayloadReady},<br />    {RegPaLevel, 0x9F},<br />    {RegTestPa1, 0x55},<br />    {RegTestPa2, 0x70},<br />    {RegOpMode, RX}<br />};<br />const uint8_t RFM69TxTable&#91;&#93;&#91;2&#93; = {<br />    {RegDioMapping1, TxDio0PackedSend},<br />    {RegPaLevel, 0x9F},<br />    {RegTestPa1, 0x55},<br />    {RegTestPa2, 0x70},<br />    {RegOpMode, TX}<br />};<br /><br />//! ustawia domyslne wartosci rejestrow modulu<br /> void RFM69_Config(void) {<br /> for ( uint8_t i = 0; i &lt; sizeof(RFM69ConfigTable)/2; i++)<br /> RFM69_write(RFM69ConfigTable&#91;i&#93;&#91;0&#93;, RFM69ConfigTable&#91;i&#93;&#91;1&#93;);<br /> }<br />//! czysci FIFO modulu<br />/*!<br /> ustawia w tryb odbioru<br />*/<br />void RFM69_ClearFIFO(void) {<br />    RFM69_write(RegOpMode, STDBY); //Entry Standby Mode<br />    RFM69_write(RegOpMode, RX); //Change to Rx Mode<br />}<br />//! ustawia tryb uspienia<br />void RFM69_Sleep(void) {<br />    RFM69_write(RegOpMode, SLEEP); //sleep mode<br />}<br />//! ustawia tryb gotowosci<br />void RFM69_Standby(void) {<br />    RFM69_write(RegOpMode, STDBY); //standby mode<br />}<br />//! ustawia tryb odbioru<br />void RFM69_Rx(void) {<br />    for (uint8_t i = 0; i &lt; sizeof(RFM69RxTable)/2; i++) //config RFM69 RxMode parameters<br />        RFM69_write(RFM69RxTable&#91;i&#93;&#91;0&#93;, RFM69RxTable&#91;i&#93;&#91;1&#93; );<br />}<br /> <br />//! wysyla dane na podany adres wezla<br />/*!<br />\param address - adres wezla<br />\param *data - wskaznik do bufora z danymi<br />\param length - ilosc bajtow do wyslania, jak 0 to bufor traktowany jest jak C-String, max 48 znakow<br />\return - 0 sukces, 1 - za duzo danych, 2 - odbior w toku, 3 - nadawanie w toku<br />*/<br />uint8_t RFM69_Send(uint8_t address, uint8_t * data, uint8_t length) {<br />    if(!length) length = strlen((char *)data);<br />    if(length &gt; 48) return 1;<br />    if(ActiveRx) return 2;<br />    if(ActiveTx) return 3;<br />PORTB&amp;= ~0b00000010;<br />    ActiveTx = 1;<br />    RFM69_Standby();<br />   <br />    RFM69_write(RegFifo, length + 1);<br />    RFM69_write(RegFifo, address);<br />    if(length) //byte data<br />    {<br />        for(uint8_t i = 0; i &lt; length; i++)<br />            RFM69_write(RegFifo, data&#91;i&#93;);<br />    }<br />    else //C-String<br />    {<br />        while(*data)<br />        {<br />            RFM69_write(RegFifo, *data);<br />            data++;<br />        }<br />    }<br />    for (uint8_t i = 0; i &lt; sizeof(RFM69TxTable)/2; i++) //config RFM69 TxMode parameters<br />        RFM69_write(RFM69TxTable&#91;i&#93;&#91;0&#93;, RFM69TxTable&#91;i&#93;&#91;1&#93;);<br />    return 0;<br />}<br />//! odczytuje dane z FIFO modulu do bufora<br />/*!<br /> ustawia zmienna DataReady i umieszca w niej ilosc odebranych bajtow<br />\param *data - wskaznik do bufora z danymi<br />*/<br />void RFM69_Read(uint8_t * data) {<br />    uint8_t length, address;<br />uint8_t i;<br />    ActiveRx = 1;<br />    length = RFM69_read(RegFifo);<br />    address = RFM69_read(RegFifo);<br />    for(i = 0; i &lt; length - 1; i++)<br />        data&#91;i&#93; = RFM69_read(RegFifo);<br />    data&#91;i&#93; = '\0';<br />    RFM69_ClearFIFO();<br />    DataReady = length - 1;<br />    ActiveRx = 0;<br />}<br /> <br /> <br />//! funkcja obslugi przerwania / zbocze narastajace DIO0<br />/*!<br /> obsluguje odbieranie danych i przelaczanie w tryb odbioru<br />*/<br />ISR(INT0_vect)<br />{<br />extern uint8_t buffer&#91;49&#93;;<br />    if(ActiveTx)<br />    {<br />        ActiveTx = 0;<br />        RFM69_Standby();<br />        RFM69_Rx();<br />    }<br />    else<br />    {<br />        RFM69_Read(buffer);<br />    }<br />}<br /><br />void spi_init(void) {<br />DDRD|= SS;<br />PORTD|= SS;<br />DDRB |= MOSI|SCK|(1&lt;&lt;PB2);<br />DDRB &amp;=~MISO;<br />SPCR |= (1&lt;&lt;SPE)|(1&lt;&lt;MSTR)|(1&lt;&lt;SPR0);<br />}<br /><br /><br /><br />int main(void)<br />{<br /><br />//konfiguracja spi , przerwan  i modulu<br />spi_init();<br />RFM69_Config();<br />RFM69_Freq(FRF(868));<br />        RFM69_Rx();<br /><br />while (1) {// pusta pętla<br />  <br />}<br /><br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=4525">michaak</a> — 27 maja 2014, o 14:43</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[wireless]]></name></author>
<updated>2014-05-22T07:18:56+01:00</updated>
<published>2014-05-22T07:18:56+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82066#p82066</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82066#p82066"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82066#p82066"><![CDATA[
BRAWO!!!<br /><br />a może pokusilibyście się napisać jakiś krótki kursik z miganiem diody:<br /><br />&quot;Jak podłączyć i uruchomić RFM69&quot;<br /><br />bo Wasze wywody są dla mnie za mądre  <img src="https://forum.atnel.pl/images/smilies/icon_e_sad.gif" alt=":(" title="Smutny" /> <br />wdzięczność moja byłaby wielka<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=380">wireless</a> — 22 maja 2014, o 07:18</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-21T22:42:23+01:00</updated>
<published>2014-05-21T22:42:23+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82050#p82050</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82050#p82050"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=82050#p82050"><![CDATA[
Doszedłem już do tego <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" />. Działa!<br />[syntax=c]uint8_t RFM69_read(uint8_t address) {<br />  CS_LOW;<br />  spi_transfer(address &amp; 0x7F);<br />  uint8_t value = spi_transfer(0);<br />  CS_HIGH;<br />  return value;<br />}<br /><br />void RFM69_write(uint8_t address, uint8_t value) {<br />  CS_LOW;<br />  spi_transfer(address | 0x80);<br />  spi_transfer(value);<br />  CS_HIGH;<br />}[/syntax]<br /><br />[syntax=c]#if defined (__AVR_ATtiny4313__)<br />void spi_init(void) {<br />//wyjscia<br />SPI_DDR |= (1&lt;&lt;DO) | (1&lt;&lt;SCK) | (1&lt;&lt;CS);<br />SPI_PORT &amp;= ~(1&lt;&lt;SCK);<br />SPI_PORT |= (1&lt;&lt;CS);<br /><br />//wejscia<br />SPI_DDR &amp;= ~(1&lt;&lt;DI);<br />SPI_PORT |= (1&lt;&lt;DI);<br /><br />}<br /><br />void spi_tx(uint8_t data) {<br />USIDR = data;<br />    USISR = (1&lt;&lt;USIOIF); // clear flag<br />    while ( !(USISR &amp; (1&lt;&lt;USIOIF)) ) {<br />    USICR |= (1&lt;&lt;USIWM0)|(1&lt;&lt;USICS1)|(1&lt;&lt;USICLK)|(1&lt;&lt;USITC);<br />    }<br />}<br /><br />uint8_t spi_rx(void) {<br />    USISR = (1&lt;&lt;USIOIF); // clear flag<br />    while ( !(USISR &amp; (1&lt;&lt;USIOIF)) ) {<br />    USICR |= (1&lt;&lt;USIWM0)|(1&lt;&lt;USICS1)|(1&lt;&lt;USICLK)|(1&lt;&lt;USITC);<br />    }<br />return USIDR;<br />}<br /><br />uint8_t spi_transfer(uint8_t data) {<br />USIDR = data;<br />    USISR = (1&lt;&lt;USIOIF); // clear flag<br />    while ( !(USISR &amp; (1&lt;&lt;USIOIF)) ) {<br />    USICR |= (1&lt;&lt;USIWM0)|(1&lt;&lt;USICS1)|(1&lt;&lt;USICLK)|(1&lt;&lt;USITC);<br />    }<br />    return USIDR;<br />}<br /><br />#endif<br /><br />#if defined (__AVR_ATmega644P__)<br /><br />void spi_init(void) {<br />SPI_DDR |= (1&lt;&lt;MOSI) | (1&lt;&lt;SCK) | (1&lt;&lt;CS);<br />    /*SPI_DDR &amp;= ~(1&lt;&lt;MISO);<br />    SPI_PORT |= (1&lt;&lt;CS);*/<br /><br />    SPCR |= (1&lt;&lt;SPE) | (1&lt;&lt;MSTR) | (1&lt;&lt;SPR0);<br />}<br /><br />void spi_tx(uint8_t data) {<br />SPDR = data;<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />}<br /><br />uint8_t spi_rx(void) {<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />return SPDR;<br />}<br /><br />uint8_t spi_transfer(uint8_t bajt) {<br />SPDR = bajt;<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />return SPDR;<br />}<br />#endif[/syntax]<br /><br />[syntax=c]#ifndef SPI_H_<br />#define SPI_H_<br /><br />#define SPI_PORT        PORTB<br />#define SPI_DDR         DDRB<br />#define SPI_PIN         PINB<br /><br />#define CS4<br />#define MOSI          5<br />#define MISO          6<br />#define SCK           7<br /><br />#define DI5<br />#define DO6<br /><br /><br />#define CS_LOWSPI_PORT &amp;= ~(1&lt;&lt;CS)<br />#define CS_HIGHSPI_PORT |= (1&lt;&lt;CS)<br /><br />#define SCK_LOWSPI_PORT &amp;= ~(1&lt;&lt;SCK)<br />#define SCK_HIGHSPI_PORT |= (1&lt;&lt;SCK)<br /><br />void spi_init(void);<br />void spi_tx(uint8_t data);<br />uint8_t spi_rx(void);<br />uint8_t spi_transfer(uint8_t bajt);<br /><br />#endif /* SPI_H_ */[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 21 maja 2014, o 22:42</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2014-05-28T18:00:57+01:00</updated>
<published>2014-05-21T17:48:12+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81991#p81991</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81991#p81991"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81991#p81991"><![CDATA[
Poprawne funkcje zapisu i odczytu dla RFM69, przy wpisywaniu ważne jest ustawienie MSB adresu na 1 (przy okazji update powyżej):<br />[syntax=c]//! zapisuje bajt do modułu pod określony adres<br />/*!<br />\param address - adres docelowy<br />\param data - dane do zapisania<br />*/<br />void RFM69_write(uint8_t address, uint8_t data)<br />{<br />    CS_LOW;<br />    SPDR = address | 0x80; //dla zapisu adres ma MSB = 1<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    SPDR = data;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    CS_HIGH;<br />}<br /><br />//! odczytuje bajt z określonego adresu modułu<br />/*!<br />\param address - adres docelowy<br />\return - dane spod adresu<br />*/<br />uint8_t RFM69_read(uint8_t address)<br />{<br />    uint8_t data;<br />    CS_LOW;<br />    SPDR = address;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    SPDR = 0x00; //dowolna wartość<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    data = SPDR;<br />    CS_HIGH;<br />    return data;<br />}[/syntax]<br />W celu odbioru też należy wysłać 2 bajty. Pierwszy to adres, a drugi jest dowolny, ale dopiero po jego wysłaniu w rejestrze odbiorczym ląduje wartość rejestru RFM69.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 21 maja 2014, o 17:48</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-21T08:47:06+01:00</updated>
<published>2014-05-21T08:47:06+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81917#p81917</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81917#p81917"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81917#p81917"><![CDATA[
CSem akurat steruję ręcznie...<br /><br />Chyba się wyjaśniło <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" />. Mam porąbane funkcje SPI / USI.<br />Mam coś takiego:<br />[syntax=c]uint8_t RFM69_read(uint8_t address) {<br />    uint8_t odbior;<br />SPI_PORT &amp;= ~(1&lt;&lt;CS);<br />spi_tx(address);<br />odbior = spi_rx();<br />SPI_PORT |=  (1&lt;&lt;CS);<br />return odbior;<br />}[/syntax]<br /><br />I różne rezultaty na SPI vs USI <img src="https://forum.atnel.pl/images/smilies/icon_e_biggrin.gif" alt=":D" title="Bardzo szczęśliwy" /><br /><br />[syntax=c]#if defined (__AVR_ATtiny4313__)<br />void spi_init(void) {<br />//wyjscia<br />SPI_DDR |= (1&lt;&lt;DO) | (1&lt;&lt;SCK) | (1&lt;&lt;CS);<br />SPI_PORT &amp;= ~(1&lt;&lt;SCK);<br />SPI_PORT |= (1&lt;&lt;CS);<br /><br />//wejscia<br />SPI_DDR &amp;= ~(1&lt;&lt;DI);<br />SPI_PORT |= (1&lt;&lt;DI);<br /><br />}<br /><br />void spi_tx(uint8_t data) {<br />USIDR = data;<br />    USISR = (1&lt;&lt;USIOIF); // clear flag<br /><br />    while ( !(USISR &amp; (1&lt;&lt;USIOIF)) ) {<br />    USICR |= (1&lt;&lt;USIWM0)|(1&lt;&lt;USICS1)|(1&lt;&lt;USICLK)|(1&lt;&lt;USITC);<br />    }<br />}<br /><br />uint8_t spi_rx(void) {<br />    USISR = (1&lt;&lt;USIOIF); // clear flag<br />    while ( !(USISR &amp; (1&lt;&lt;USIOIF)) ) {<br />    USICR |= (1&lt;&lt;USIWM0)|(1&lt;&lt;USICS1)|(1&lt;&lt;USICLK)|(1&lt;&lt;USITC);<br />    }<br />return USIDR;<br />}<br /><br />uint8_t spi_transfer(uint8_t data) {<br />USIDR = data;<br />    USISR = (1&lt;&lt;USIOIF); // clear flag<br />    while ( !(USISR &amp; (1&lt;&lt;USIOIF)) ) {<br />    USICR |= (1&lt;&lt;USIWM0)|(1&lt;&lt;USICS1)|(1&lt;&lt;USICLK)|(1&lt;&lt;USITC);<br />    }<br />    return USIDR;<br />}<br /><br />#endif<br /><br />#if defined (__AVR_ATmega644P__)<br /><br />void spi_init(void) {<br />SPI_DDR |= (1&lt;&lt;MOSI) | (1&lt;&lt;SCK) | (1&lt;&lt;CS);<br />    /*SPI_DDR &amp;= ~(1&lt;&lt;MISO);<br />    SPI_PORT |= (1&lt;&lt;CS);*/<br /><br />    SPCR |= (1&lt;&lt;SPE) | (1&lt;&lt;MSTR) | (1&lt;&lt;SPR0);<br />}<br /><br />void spi_tx(uint8_t data) {<br />SPDR = data;<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />}<br /><br />uint8_t spi_rx(void) {<br />//SPDR = 0; // Dopiero jak to odkomentuję to SPI i USI działają podobnie...<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />return SPDR;<br />}<br /><br />uint8_t spi_transfer(uint8_t bajt) {<br />SPDR = bajt;<br />while ( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />return SPDR;<br />}<br />#endif[/syntax]<br /><br />SPI (M644P, wysyłanie 0x00 w spi_rx):<br /><a href="http://forum.atnel.pl/_obrazki/o/82/8718478dfed9521d9fc8bf259ab1b9db.jpg"  class="postlink"><img src="http://forum.atnel.pl/_obrazki/o/thumb/82/8718478dfed9521d9fc8bf259ab1b9db.jpg" alt="Obrazek" /></a><br />USI (t4313):<br /><a href="http://forum.atnel.pl/_obrazki/o/82/7cc0a39777dff2b89dba9cef8317e7e2.jpg"  class="postlink"><img src="http://forum.atnel.pl/_obrazki/o/thumb/82/7cc0a39777dff2b89dba9cef8317e7e2.jpg" alt="Obrazek" /></a><br /><br /><br />OMG... znalazłem błąd sprzętowy - przerwa w ścieżce/niedolut. I to tak perfidnie, że na VCC przy samym padzie - ilość prądu jaką dostawał po portach wystarczała na sensowne odpowiedzi po SPI ale nie na nadawanie/odbiór.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 21 maja 2014, o 08:47</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2014-05-20T19:27:18+01:00</updated>
<published>2014-05-20T19:27:18+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81851#p81851</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81851#p81851"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81851#p81851"><![CDATA[
Brakuje ci w kodzie sterowania CS. Jak ten pin jest w stanie wysokim to moduł RFM69 ustawia wyjście MISO w stan wysokiej impedancji i dlatego odczytujesz 0. Taki stan łatwo rozpoznać woltomierzem. Jak mierzysz pomiędzy MISO i GND masz 0V i pomiędzy VCC i MISO też masz 0V.<br />Zwracam jeszcze uwagę na sterowanie CS. Do współpracy z modułem CS zerujesz, wysyłasz 2 bajty i dopiero ustawiasz na 1. Przykład jest w funkcji RFM69_write.<br />Nop'y nie są potrzebne, bo moduł ma szybkie SPI. FSCK maksymalnie 10MHz. Atmel udostępnia gotową bibliotekę <a href="http://www.atmel.com/devices/ATTINY4313.aspx?tab=documents"  class="postlink">AVR319</a>, która się dobrze nadaje, bo pinem SS/CS trzeba dodatkowo sterować.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 20 maja 2014, o 19:27</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-20T14:12:21+01:00</updated>
<published>2014-05-20T14:12:21+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81834#p81834</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81834#p81834"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81834#p81834"><![CDATA[
Jest jakaś szansa zablokowania tych modułów na amen? Bo albo mi się uszkodziły (w sumie z niewiadomych powodów - stykówka i konwerter poziomów na 2x ADuM1402), albo jakoś zablokowały.<br />Dwa mają permanentny stan niski na MISO... jak próbuję odczytać dowolny rejestr to cały czas na analizatorze Saleae dostaję 0x00 w odpowiedzi :/<br />Sam konwerter poziomów sprawny bo jak odłączę moduł i zewrę linię MISO z MOSI po stronie 3V to odbieram to co wysyłam.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 20 maja 2014, o 14:12</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Anonymous]]></name></author>
<updated>2014-05-20T12:20:22+01:00</updated>
<published>2014-05-20T12:20:22+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81825#p81825</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81825#p81825"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81825#p81825"><![CDATA[
Można przecież podejrzeć po kompilacji jak wygląda kod asm w pliku .lss<p>Statystyki: Napisane przez Gość — 20 maja 2014, o 12:20</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-21T09:22:32+01:00</updated>
<published>2014-05-19T21:04:24+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81761#p81761</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81761#p81761"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81761#p81761"><![CDATA[
Obecnie walczę z USI w ATtiny4313 i chyba udało mi się zmusić go do pracy jako SPI (Uwaga dla początkujących: MOSI w USI to DataIN / MISO - DataOUT).<br />Poprzednio próbowałem software SPI, ale średnio to chodziło chyba <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" />. Pokombinuję nieco jeszcze zanim wrzucę tu main.c <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br /><br />Pewnie średnio poprawne (jak ktoś ulepszy/poprawi to będę wdzięczny) - USI jako SPI Master:<br />[syntax=c]#define SPI_PORT        PORTB<br />#define SPI_DDR         DDRB<br />#define SPI_PIN         PINB<br /><br />#define CS4<br />#define MOSI          5<br />#define MISO          6<br />#define SCK           7<br /><br />#define DI5<br />#define DO6[/syntax]<br /><br />[syntax=c]void spi_init(void) {<br />//wyjscia<br />SPI_DDR |= (1&lt;&lt;DO) | (1&lt;&lt;SCK) | (1&lt;&lt;CS);<br />SPI_PORT &amp;= ~(1&lt;&lt;SCK);<br />SPI_PORT |= (1&lt;&lt;CS);<br /><br />//wejscia<br />SPI_DDR &amp;= ~(1&lt;&lt;DI);<br />SPI_PORT |= (1&lt;&lt;DI);<br /><br />}<br /><br />void spi_tx(uint8_t data) {<br />USIDR = data;<br />    USISR = (1&lt;&lt;USIOIF); // clear flag<br /><br />    while ( !(USISR &amp; (1&lt;&lt;USIOIF)) ) {<br />    USICR |= (1&lt;&lt;USIWM0)|(1&lt;&lt;USICS1)|(1&lt;&lt;USICLK)|(1&lt;&lt;USITC);<br />    }<br />}<br /><br />uint8_t spi_rx(void) {<br />    USISR = (1&lt;&lt;USIOIF); // clear flag<br />    for (uint8_t loop=0;loop&lt;8;loop++) {<br />    SPI_PORT |= (1&lt;&lt;SCK);<br />    asm(&quot;nop&quot;);<br />    asm(&quot;nop&quot;);<br />    SPI_PORT &amp;= ~(1&lt;&lt;SCK);<br />    asm(&quot;nop&quot;);<br />    asm(&quot;nop&quot;);<br />    }<br />return USIDR;<br />}<br /><br />uint8_t spi_transfer(uint8_t data) {<br />USIDR = data;<br />    USISR = (1&lt;&lt;USIOIF); // clear flag<br /><br />    while ( !(USISR &amp; (1&lt;&lt;USIOIF)) ) {<br />    USICR |= (1&lt;&lt;USIWM0)|(1&lt;&lt;USICS1)|(1&lt;&lt;USICLK)|(1&lt;&lt;USITC);<br />    }<br />    return USIDR;<br />}[/syntax]<br /><br />Coś się złego dzieje z tymi modułami na stykówce... dwa już odpowiadają zerem <img src="https://forum.atnel.pl/images/smilies/icon_e_sad.gif" alt=":(" title="Smutny" />, albo mi SPI na M644P źle działa, ale w takie cuda to nie uwierzę.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 19 maja 2014, o 21:04</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2014-05-19T19:29:20+01:00</updated>
<published>2014-05-19T19:29:20+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81750#p81750</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81750#p81750"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81750#p81750"><![CDATA[
Na początek w funkcji RFM69_Send można sobie wstawić adres rozgłoszeniowy (BroadcastAddress), wtedy kod obu urządzeń jest identyczny. Byłoby fajnie jakbyś opublikował plik main.c z konfiguracją przerwań i timera.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 19 maja 2014, o 19:29</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-18T21:31:33+01:00</updated>
<published>2014-05-18T21:31:33+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81657#p81657</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81657#p81657"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=81657#p81657"><![CDATA[
Siedzę cały dzień dzisiaj nad tym i niestety bez rezultatów <img src="https://forum.atnel.pl/images/smilies/icon_e_sad.gif" alt=":(" title="Smutny" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 18 maja 2014, o 21:31</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-10T21:22:55+01:00</updated>
<published>2014-05-10T21:22:55+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80769#p80769</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80769#p80769"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80769#p80769"><![CDATA[
Pasmo 868MHz to kilka-naście częstotliwości... od 860.48 do 879.54 MHz.<br />Dobrze, że podałeś:<br />[syntax=c]#define FRF(x)  (x*524288UL/FXOSC)[/syntax]<br /><br />Dla (przykładowo) 862.00MHz będzie FRF = 14123008... tej informacji mi m.in brakowało.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 10 maja 2014, o 21:22</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2014-05-28T18:04:10+01:00</updated>
<published>2014-05-09T21:52:12+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80682#p80682</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80682#p80682"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80682#p80682"><![CDATA[
<div class="quotetitle">szopler napisał(a):</div><div class="quotecontent"><br />Trzeba zobaczyć w tym ich kocim datasheecie co dalej żeby ustawić konkretną częstotliwość i nadawać/odbierać...<br /></div><br />Moduły są produkowane na różne pasma. Ustawianie częstotliwości może wyglądać tak:<br />[syntax=c]#define FXOSC   32UL<br />#define FRF(x)  (x*524288UL/FXOSC)<br /><br />#define NodeAddress 0x01   \\w drugim na odwrot<br />#define ReceiverAddress 0x02  \\w drugim na odwrot<br />#define BroadcastAddress 0xFF<br /><br />//RegOpMode(0x01)<br />//4-2 Mode<br />#define SLEEP   (0b000&lt;&lt;2)  //Sleep mode (SLEEP)<br />#define STDBY    (0b001&lt;&lt;2)  //Standby mode (STDBY)<br />#define FS      (0b010&lt;&lt;2)  //Frequency Synthesizer mode (FS)<br />#define TX      (0b011&lt;&lt;2)  //Transmitter mode (TX)<br />#define RX      (0b100&lt;&lt;2)  //Receiver mode (RX)<br /><br />//RegDioMapping1(0x25)<br />//7-6 Dio0Mapping<br />#define RxDio0PayloadReady  (0b01&lt;&lt;6)<br />#define TxDio0PackedSend  (0b00&lt;&lt;6)<br /><br />//RegSyncConfig(0x2e)<br />//7 SyncOn<br />#define SyncON  (1&lt;&lt;7)<br />#define SyncOFF (0&lt;&lt;7)<br />//6 FifoFillCondition<br />//5-3 SyncSize<br />#define Sync8byte   (0b111&lt;&lt;3)<br />//2-0 SyncTol<br /><br />//RegPacketConfig1(0x37)<br />//7 PacketFormat<br />#define FixedLength     (0&lt;&lt;7 ) //Fixed length<br />#define VariableLength  (1&lt;&lt;7)  //Variable length<br />//6-5 DcFree<br />#define DcFreeOFF   (0b00&lt;&lt;5)   //None (Off)<br />#define Manchester  (0b01&lt;&lt;5)   //Manchester<br />#define Whitening   (0b10&lt;&lt;5)   //Whitening<br />//4 CrcOn<br />#define CrcOFF   (0&lt;&lt;4) //Off<br />#define CrcON   (1&lt;&lt;4) //On<br />//3 CrcAutoClearOff<br />#define ClearON (0&lt;&lt;3)  //Clear FIFO and restart new packet reception<br />#define ClearFF (1&lt;&lt;3)  //Do not clear FIFO. PayloadReady interrupt issued<br />//2-1 AddressFiltering<br />#define AddressOFF    (0b00&lt;&lt;1)   //None (Off)<br />#define AddressNode   (0b01&lt;&lt;1)   //Address field must match NodeAddress<br />#define AddressNodeBroadcast    (0b10&lt;&lt;1)   //Address field must match NodeAddress or BroadcastAddress<br /><br />//! zapisuje bajt do modułu pod określony adres<br />/*!<br />\param address - adres docelowy<br />\param data - dane do zapisania<br />*/<br />void RFM69_write(uint8_t address, uint8_t data)<br />{<br />    CS_LOW;<br />    SPDR = address | 0x80; //dla zapisu adres ma MSB = 1<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    SPDR = data;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    CS_HIGH;<br />}<br /><br />//! odczytuje bajt z określonego adresu modułu<br />/*!<br />\param address - adres docelowy<br />\return - dane spod adresu<br />*/<br />uint8_t RFM69_read(uint8_t address)<br />{<br />    uint8_t data;<br />    CS_LOW;<br />    SPDR = address;<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    SPDR = 0x00; //dowolna wartość<br />    while( !(SPSR &amp; (1&lt;&lt;SPIF)) );<br />    data = SPDR;<br />    CS_HIGH;<br />    return data;<br />}<br /><br />//! ustawia czestotliwosc pracy<br />/*!<br />\param frequency - czestotliwosc FRF(x) np. FRF(868)<br />*/<br />void RFM69_Freq(uint32_t frequency)<br />{<br />    RFM69_write(RegFrfMsb, (uint8_t)(frequency&gt;&gt;16));<br />    RFM69_write(RegFrfMid, (uint8_t)(frequency&gt;&gt;8));<br />    RFM69_write(RegFrfLsb, (uint8_t)frequency);<br />}[/syntax]<br />Moduł konfiguruje się wysyłając tablice złożone z rejestru i wartości do wpisania:<br />[syntax=c]const uint8_t RFM69RxTable&#91;&#93;&#91;2&#93; = {<br />    {RegDioMapping1, RxDio0PayloadReady},<br />    {RegPaLevel, 0x9F},<br />    {RegTestPa1, 0x55},<br />    {RegTestPa2, 0x70},<br />    {RegOpMode, RX}<br />};<br />const uint8_t RFM69TxTable&#91;&#93;&#91;2&#93; = {<br />    {RegDioMapping1, TxDio0PackedSend},<br />    {RegPaLevel, 0x9F},<br />    {RegTestPa1, 0x55},<br />    {RegTestPa2, 0x70},<br />    {RegOpMode, TX}<br />};<br /><br />//! czysci FIFO modulu<br />/*!<br /> ustawia w tryb odbioru<br />*/<br />void RFM69_ClearFIFO(void) {<br />    RFM69_write(RegOpMode, STDBY); //Entry Standby Mode<br />    RFM69_write(RegOpMode, RX); //Change to Rx Mode<br />}<br />//! ustawia tryb uspienia<br />void RFM69_Sleep(void) {<br />    RFM69_write(RegOpMode, SLEEP); //sleep mode<br />}<br />//! ustawia tryb gotowosci<br />void RFM69_Standby(void) {<br />    RFM69_write(RegOpMode, STDBY); //standby mode<br />}<br />//! ustawia tryb odbioru<br />void RFM69_Rx(void) { <br />    for (uint8_t i = 0; i &lt; sizeof(RFM69RxTable)/2; i++) //config RFM69 RxMode parameters<br />        RFM69_write(RFM69RxTable&#91;i&#93;&#91;0&#93;, RFM69RxTable&#91;i&#93;&#91;1&#93; );<br />}[/syntax]<br />Wspomagając się zieloną książką Mirka można sobie w końcu przygotować uniwersalne funkcje do wysyłania i odbioru:<br />[syntax=c]volatile uint8_t ActiveTx, ActiveRx, DataReady;<br />uint8_t buffer&#91;49&#93;; //bufor z odebranymi danymi ( w main dodac extern buffer&#91;49&#93;; )<br /><br />//! wysyla dane na podany adres wezla<br />/*!<br />\param address - adres wezla<br />\param *data - wskaznik do bufora z danymi<br />\param length - ilosc bajtow do wyslania, jak 0 to bufor traktowany jest jak C-String, max 48 znakow<br />\return - 0 sukces, 1 - za duzo danych, 2 - odbior w toku, 3 - nadawanie w toku<br />*/<br />uint8_t RFM69_Send(uint8_t address, uint8_t * data, uint8_t length) {<br />    if(!length) length = strlen((char *)data);<br />    if(length &gt; 48) return 1;<br />    if(ActiveRx) return 2;<br />    if(ActiveTx) return 3;<br />    ActiveTx = 1;<br />    RFM69_Standby();<br />    <br />    RFM69_write(RegFifo, length + 1);<br />    RFM69_write(RegFifo, address);<br />    if(length) //byte data<br />    {<br />        for(uint8_t i = 0; i &lt; length; i++)<br />            RFM69_write(RegFifo, data&#91;i&#93;);<br />    }<br />    else //C-String<br />    {<br />        while(*data)<br />        {<br />            RFM69_write(RegFifo, *data);<br />            data++;<br />        }<br />    }<br />    for (uint8_t i = 0; i &lt; sizeof(RFM69TxTable)/2; i++) //config RFM69 TxMode parameters<br />        RFM69_write(RFM69TxTable&#91;i&#93;&#91;0&#93;, RFM69TxTable&#91;i&#93;&#91;1&#93;);<br />    return 0;<br />}<br />//! odczytuje dane z FIFO modulu do bufora<br />/*!<br /> ustawia zmienna DataReady i umieszca w niej ilosc odebranych bajtow<br />\param *data - wskaznik do bufora z danymi<br />*/<br />void RFM69_Read(uint8_t * data) {<br />    uint8_t length, address;<br />    ActiveRx = 1;<br />    length = RFM69_read(RegFifo);<br />    address = RFM69_read(RegFifo);<br />    for(uint8_t i = 0; i &lt; length - 1; i++)<br />        data&#91;i&#93; = RFM69_read(RegFifo);<br />    data&#91;i&#93; = '\0';<br />    RFM69_ClearFIFO();<br />    DataReady = length - 1;<br />    ActiveRx = 0;<br />}<br /><br /><br />//! funkcja obslugi przerwania / zbocze narastajace DIO0<br />/*!<br /> obsluguje odbieranie danych i przelaczanie w tryb odbioru<br />*/<br />ISR(INT0_vect)<br />{<br />    if(ActiveTx)<br />    {<br />        ActiveTx = 0;<br />        RFM69_Standby();<br />        RFM69_Rx();<br />    }<br />    else<br />    {<br />        RFM69_Read(data);<br />    }<br />}[/syntax]<br />W pliku main powinno się znaleźć:<br />[syntax=c]//konfiguracja spi , przerwań, (usart) i modułu<br />RFM69_Config();<br />RFM69_Freq(FRF(868));<br />RFM69_Rx();<br />while (1) {<br />   if (0 == Timer1)<br />   {<br />      Timer1 = 200; //co 2 sekundy wyslij i wyswietl status<br />      uart_putc(RFM69_Send(ReceiverAddress, &quot;forum.atnel.pl&quot;, 0) + '0'); //na adres  zgodny z NodeAddress w drugim module<br />      uart_puts(&quot;\r\n&quot;);<br />   }<br />   if(DataReady)<br />   {<br />      uart_puts(buffer);<br />      uart_puts(&quot;\r\n&quot;);<br />      DataReady = 0;<br />   }<br />}[/syntax]<br />W konfiguracji należy ustawić odpowiednie adresy i potem się ich trzymać. Tu też można posłużyć się tablicą i odpowiednią funkcją:<br />[syntax=c]const uint8_t RFM69ConfigTable&#91;&#93;&#91;2&#93; = {<br /><br />    {RegBitrateMsb, 0x34}, //32MHz/0x3410 = 2.4kpbs<br />    {RegBitrateLsb, 0x10},<br />    {RegFdevMsb, 0x02}, //241*61Hz = 35KHz<br />    {RegFdevLsb, 0x41},<br />    {RegFrfMsb, 0xD9}, //868MHz<br />    {RegFrfMid, 0x00},<br />    {RegFrfLsb, 0x00},<br />    {RegLna, 0x88}, //200R Auto gain<br />    {RegRxBw, 0x52}, //83KHz<br />    {RegAfcBw, 0x8B}, //recommended value<br />    {RegDioMapping1, RxDio0PayloadReady},<br />    {RegRssiThresh, 0xEC}, //118dBm<br />    {RegPreambleMsb, 0x00}, //5 PreambleBytes<br />    {RegPreambleLsb, 0x05},<br />    {RegSyncConfig, SyncON | Sync8byte}, //On, 8B, no errors<br />    {RegSyncValue1, 'A'}, //SyncWord = Network ID<br />    {RegSyncValue2, 'T'},<br />    {RegSyncValue3, 'N'},<br />    {RegSyncValue4, 'E'},<br />    {RegSyncValue5, 'L'},<br />    {RegSyncValue6, '.'},<br />    {RegSyncValue7, 'P'},<br />    {RegSyncValue8, 'L'},<br />    {RegPacketConfig1, VariableLength | Whitening | CrcON | ClearON | AddressNodeBroadcast},<br />    {RegPayloadLength, 66},<br />    {RegNodeAdrs, NodeAddress},<br />    {RegBroadcastAdrs, BroadcastAddress},<br />    {RegFifoThresh, 0x9F},<br />    {RegTestLna, 0x1B}, //Normal sensitivity<br />    {RegTestDagc, 0x30}, //Improved DAGC<br />    {RegOpMode, STDBY}<br />};<br /><br />//! ustawia domyslne wartosci rejestrow modulu<br />void RFM69_Config(void) {<br />    for ( uint8_t i = 0; i &lt; sizeof(RFM69ConfigTable)/2; i++)<br />        RFM69_write(RFM69ConfigTable&#91;i&#93;&#91;0&#93;, RFM69ConfigTable&#91;i&#93;&#91;1&#93;);<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 9 maja 2014, o 21:52</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[wireless]]></name></author>
<updated>2014-05-06T13:14:32+01:00</updated>
<published>2014-05-06T13:14:32+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80286#p80286</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80286#p80286"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80286#p80286"><![CDATA[
to podobno to samo,<br />tu jest wiele materiałów dla znających się na rzeczy, czyli nie dla mnie  <img src="https://forum.atnel.pl/images/smilies/icon_e_sad.gif" alt=":(" title="Smutny" /> <br /><br /><!-- m --><a class="postlink" href="http://www.semtech.com/wireless-rf/rf-transceivers/sx1231/" >http://www.semtech.com/wireless-rf/rf-t ... rs/sx1231/</a><!-- m --><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=380">wireless</a> — 6 maja 2014, o 13:14</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-07T14:26:41+01:00</updated>
<published>2014-05-06T09:33:41+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80270#p80270</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80270#p80270"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80270#p80270"><![CDATA[
Udało się dogadać z RFM69 - czyta rejestry. Init przechodzi nawet.<br />Trzeba zobaczyć w tym ich kocim datasheecie co dalej żeby ustawić konkretną częstotliwość i nadawać/odbierać...<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 6 maja 2014, o 09:33</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[tczaplinek]]></name></author>
<updated>2014-05-05T23:40:00+01:00</updated>
<published>2014-05-05T23:40:00+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80259#p80259</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80259#p80259"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80259#p80259"><![CDATA[
przerobienie tej biblioteki na AVR nie jest specjalnie trudne - zacznij od zamiany klasy na strukturę (te same parametry) i pozmieniaj tylko referencje w funkcjach <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><br />trzeba też przerobić wszystkie metody Arduinowe niestety, no i bool na uint8_t. Oprócz tego uruchomienie przerwania którym będziemy obsługiwali DIO0 z tej biblioteki. <br /><br />Zabrałem się za RFM69HCW jakiś czas temu, udało mi się w ten weekend uruchomić komunikację między dwoma modułami ale biblioteka jest &quot;porozwalana&quot; i w powijakach. I tylko sztywne Rx, Tx, bez Listen Mode. Jak ogarnę lepiej to mogę się podzielić gdyby się nie udało <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=4269">tczaplinek</a> — 5 maja 2014, o 23:40</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[szopler]]></name></author>
<updated>2014-05-04T21:03:12+01:00</updated>
<published>2014-05-04T21:03:12+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80102#p80102</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80102#p80102"/>
<title type="html"><![CDATA[Re: Transceivery RFM - czego użyć żeby nie żałować? ;)]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=6898&amp;p=80102#p80102"><![CDATA[
No i zacząłem przeportowywać podaną wyżej (&quot;TO&quot;) bibliotekę na AVR... Ciekawe czy coś mi z tego wyjdzie...(?)<br /><br />Edit @ 01:41 - Narazie wiesza się na init <img src="https://forum.atnel.pl/images/smilies/icon_evil.gif" alt=":evil:" title="Zły" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=82">szopler</a> — 4 maja 2014, o 21:03</p><hr />
]]></content>
</entry>
</feed>