• Email
  • Forum

RFM12B - łatwiejsze niż myślisz

Zbuduj stację METEO :)

Z RMF12B sprawa jest naprawdę nieskomplikowana.
Trzeba tylko mieć minimalne pojęcie jak skonstruowane są instrukcje.

Tych modułów nie użyjemy dopóki nie wyślemy im szeregu instrukcji ustawiających np. częstotliwość i moc nadawania. Taką samą instrukcją przełącza się moduł z odbioru na nadawanie lub w drugą stronę. Nie ma tu jakiegoś odpowiedzialnego za to Pinu. Moduł trzeba podłączyć pod magistralę SPI.

Posłużę się przykładem..

Dostałem kiedyś do naprawy wyświetlacz z kościoła (będzie opisany na stronie ze względu na inną ciekawostkę). Organista wpisuje z drugiego końca kościoła trzycyfrową liczbę która ma się ukazać na wyświetlaczu. Program musiałem napisać od nowa bo padnięty był procesor i starego programu odzyskać się nie dało. Dane do wyświetlacza przesyłane są RS485 i zrobiłem to najprościej jak umiałem. Jeśli chcę ustawić trzecią cyfrę to wysyłam ją jako 30+cyfra, jeśli drugą to 20+cyfra, a pierwszą 10+cyfra. Przykładowo na wyświetlacz ma trafić 739 -> wysyłam 37,23,19 Podobnie jest w RFM12 - komenda jest połączona z adresem pod który ma trafić (co ustawiasz i wartość).

Tabu..

Okazuje się, że nie musisz się tak martwić jak skonstruowac te komendy. Istnieje do tego kalkulator Online na stronie internetowej. Klik w obrazek przeniesie Cię tam.
Niemniej ten temat można sobie opracować raz i napisać sobie całe bloki kodu które potem będą się wykonywały automatycznie "zawołane tylko" jedną komendą. Na przykład "Init_rfm" ustawi nam wszystkie parametry potrzebne do odbioru.

[Rozmiar: 92858 bajtów]

Stronę chyba można zapisać bo piszą, że wszystkie obliczenia dokonują się lokalnie w przeglądarce. Nie próbowałem.

Dawca..

Żeby zbudować zdalny czujnik temperatury przydałby się jakiś przykład. Okazuje się że ludzie szukają przykładów po całej sieci Internet a wszystko mają pod nosem na swoim dysku! Tak.. gotowe rozwiązanie jest w samplach do Bascom w folderze JEENODE . Na potrzeby tego przewodnika i polskie realia przerobiłem co nieco i poskracałem.

Do zbudowania czujnika użyłem ATmega8L zasilanej dwoma bateriami AAA. Litera "L" oznacza że procesor może pracować przy tak niskim napięciu. Kod do nadajnika ma może z 3KB i mógłby być mniejszy ale zostawiłem tam obsługę odbioru ponieważ uważam, że nie ma sensu zmniejszać kodu do ATtiny skoro ATmega8 jest najtańsza i kosztuje 5zł :)

RFM12 miałem w wersji DP znaczy z wtyczką. Nie miałem jednak takiej wtyczki pod ręką (może z airbag samochodowego by podeszła) Przylutowałem się więc do niego. Gdybym teraz miał kupić RFM12 to wybrałbym wersję SMD bo ma na pokładzie plażę z analogowym sygnałem siły odebranego sygnału który można wykorzystać..tu go nie ma (można odczytać cyfrowo). Tak więc łączymy te same piny którymi normalnie programujemy ATmege. Jako że nie dorobiłem się jeszcze programatora na 3,3V a na takim napięciu pracuje RFM12 wpadłem na pomysł by wpinać go w złącze programujące. Tym sposobem programując procesor muszę wyjąć RFM12 i nic mu nie będzie od 5v z programatora. Tak więc podłączyłem się jak na zdjęciach niżej.

[Rozmiar: 16743 bajtów] [Rozmiar: 16291 bajtów]

Niekonieczne okazało się dodanie rezystora 10K pomiędzy VCC a FSK (miałem ale zdemontowałem po próbach - niemniej dodaj jeśli uważasz że potrzebny). Widziałem dziesiątki schematów w których był, ale nie ma go w JeeNode..

Podłączamy więc tak jak kończą się wyrazy I do I, a O do O
MISO-SDO
MOSI-SDI
INT0-nIRQ
SS(select w SPI= PB.2 w mega8) - nSEL
Oczywiście zasilanie.

Proszę sprawdź jeszcze kilka razy bo pomimo dobrych chęci mógł się wkraść błąd.
Do PC.0 podłączamy czujnik temperatury DS18B20. Ja mam tam też diodę której użyłem do debugowania i naprawdę się przydała. Okazało się że Watchdog się tam przydaje i nie powinienem go wyłączać. W momencie gdy rozłączyłem RFM12 od płytki procesor się zawieszał nie mogąc skomunikować się z nadajnikiem. Jeśli więc w warunkach polowych na chwilę układ straciłby kontakt z RFM12 zawiesiłby się. Watchdog w takim przypadku zresetuje procesor.

Program jest przykładowy i uproszczony więc uprasza się malkontentów o powstrzymanie się od wydawania opinii. Ważne że działa i ma pokazać że uruchomienie RFM12B nie jest trudne. Każdy może potem pójść dalej.

Stacja bazowa ma zasilanie sieciowe więc potrzebowała regulatora napięcia na 3,3V (jest ukryty pod wyświetlaczem) Ta płytka za 4zł to mój poligon :) Mam tam różne konfiguracje, nawet FuseBit Doctora. Zmierzam do tego, że w tym przykładzie obydwa procesory pracują na zasilaniu 3,3V nawet Wyświetlacz. Jeśli więc ktoś ma 5V na procesorze lub wyświetlaczu to musi RFM12B podłączyć przez "LevelShifter" - konwerter napięć - na razie odsyłam do googli. Mi tak było przy niedzieli najprościej zbudować osobny układ.

[Rozmiar: 16743 bajtów] [Rozmiar: 16291 bajtów]

Poniżej kody źródłowe. Jeśli będa niejasności proszę zapytać. Kody, w celu skrócenia, mają odjęte część opisów. Jeśli chcesz są w folderze Sampli do Bascom JEENODE.

Jak widać działa i nie taki diabeł straszny jak go malują .. wystarczy się rozejrzeć.

Nadajnik sensor z czujnikiem DS18B20
$regfile = "m8def.dat"
$crystal = 8000000                                          '8MHz
$hwstack = 70
$swstack = 70
$framesize = 160
'$noramclear
Config Submode = New
Config Watchdog = 512                                       '512ms
Start Watchdog
'---------Constants-------------------------------------------------------------
Const Hard = 1
Const Soft = 0
Const Spi_mode = Hard
Const Sensor_id = 2
'CONFIGURATION SETTING
Const Configuration_setting = &H80D7                        '434.00MHz BARTek
'Const Configuration_setting = &H80E7                        '868MHz, 12pF, Enable TX Register, Enable Rx Fifo
Const Enable_receiver = &H82D9                              'Also Enable Low Battery Detector
Const Enable_transmitter = &H8279                           'Also Enable Low Battery Detector
'FREQUENCY SETTING
Const Rfm12b_frequency = &HA640                             '434.00MHz BARTek
'Const Rfm12b_frequency = &HA7C0                             '869,92MHz
'BAUDRATE (DATARATE)
Const Baudrate = &HC611
Const Receiver_control = &H94A2
Const Data_filter = &HC2AC
Const Init_fifo = &HCA81
Const Enable_fifo = &HCA83
Const Auto_frequ_control = &HC483
Const Tx_control = &H9850
Const Pll_settings = &HCC57
Const Wakeup_timer = &HE000
Const Low_duty_cycle = &HC800
Const Dummy_byte = &HAA
Const Tramsmit_write_command = &HB8                         'SPI TX command high byte
Const Rfm12_software_reset = &HFE00                         'Software reset: Sending FE00h command to the chip triggers software reset. For more details see the Reset modes section.
Const Sleep_mode = &H8205                                   'RFM12B SLEEP MODE
Const Ffit = 7                                              'FFIT Bit in Status Register
'---------Variables-------------------------------------------------------------
Dim Count As Byte
Dim Temp As Byte
Dim Cmd(2) As Byte
Dim Sdi(2) As Byte
Dim Stat(2) As Byte                                         'Array for Status Register Bytes
'RECEIVE ARRAY
Dim Rx(8) As Byte
'TRANSMITT ARRAY
Dim Tx(8) As Byte
Dim Fifo(4) As Byte
Dim Rxcounter As Byte
Dim Abort As Bit : Reset Abort
Dim Ds18b20_integer_temp As Integer
Dim Ds18b20_single_temp As Single
Dim 1_wire_string As String * 7
Dim Crc8_value As Byte
Dim Ds18b20_scratchpad(9) As Byte
Dim 1_wire_sensor_id(8) As Byte
Dim Number_of_1_wire_devices As Word
Dim 1_wire_toggle As Bit : Reset 1_wire_toggle
Dim Send_byte As Byte
Dim Four_second_tick As Bit : Four_second_tick = 0
Dim W As Word
Dim Rfm12b_data_ready As Bit
'---------Interfaces------------------------------------------------------------
'Config SPI for RFM12
#if Spi_mode = Hard
    Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0 , Spiin = 0
#else
    Config Spi = Soft , Din = Pinb.4 , Dout = Portb.3 , Ss = Portb.2 , Clock = Portb.5       'ATMEGA328P
#endif
Spiinit

'1-Wire interface
1_wire_pin Alias Portc.0                                    'PIN for 1-Wire
Config 1wire = 1_wire_pin                                   'use this pin
Number_of_1_wire_devices = 1wirecount()
'Print "Number_of_1_wire_devices = " ; Number_of_1_wire_devices
1_wire_sensor_id(1) = 1wsearchfirst()

'---------Ports-----------------------------------------------------------------
Config Portd.2 = Input
Nirq Alias Pind.2

Config Int0 = Falling                                       'PD2 = RFM12 Nirq
On Int0 Nirq_isr
Enable Int0

'---------Timer-----------------------------------------------------------------
Config Timer1 = Timer , Prescale = 1024
On Timer1 Timer_irq
Const Timer_preload = 34287                                 '4 second tick at 8MHz clock
Enable Timer1

Config Portb.1 = Output
Led Alias Portb.1
Set Led
'---------SUB functions---------------------------------------------------------
' Config Submode = New  is used !
'By Value
Sub Rfm12b_cmd(byval Tmp As Word)
   Cmd(2) = Low(tmp)
   Cmd(1) = High(tmp)
   Spiout Cmd(1) , 2
End Sub

'By Reference
Sub Rfm12b_cmd_ref(tmp As Word)
   Cmd(2) = Low(tmp)
   Cmd(1) = High(tmp)
   Spiout Cmd(1) , 2
End Sub

Sub Rfm12b_read_status()
   Disable Interrupts
   Cmd(2) = &H00
   Cmd(1) = &H00
   Spiout Cmd(1) , 2                                        'Write &H0000 to read status register
   Spiin Stat(1) , 2                                        'Read the 2 Status Register Bytes
   Enable Interrupts
End Sub

'By Reference
Sub Rfm12b_spi_send(sdi_byte As Byte)
   Disable Interrupts
   Bitwait Nirq , Reset
   Sdi(1) = Tramsmit_write_command                          '&HB8
   Sdi(2) = Sdi_byte
   Spiout Sdi(1) , 2
   Enable Interrupts
End Sub

'By Value
Sub Rfm12b_spi_send_val(byval Sdi_byte As Byte)
   Disable Interrupts
   Bitwait Nirq , Reset
   Sdi(1) = Tramsmit_write_command                          '&HB8
   Sdi(2) = Sdi_byte
   Spiout Sdi(1) , 2
   Enable Interrupts
End Sub


Sub Rfm12_set_output_power(byval Out_power As Word)         '0 = Max output
    'Transmit Control Command [&H9850] = (Sign = Pos Frequency Shift, Deviation = 90KHz, Power Out = 0dB maximum
    Select Case Out_power
     Case 0 :
        Out_power = &H9850
      '  Print #1 , "Max Outut"                    ' Max output (-0dB)
     Case 1 :
        Out_power = &H9851
      '  Print #1 , "-3dB"                         '  (-3dB)
     Case 2 :
        Out_power = &H9852
      '  Print #1 , "-6dB"                         '  (-6dB)
     Case 3 :
        Out_power = &H9854
      '  Print #1 , "-12dB"                        '  (-12dB)
     Case 4 :
        Out_power = &H9855
     '   Print #1 , "-18dB"                        '  (-18dB)
     Case 5 :
        Out_power = &H9856
     '   Print #1 , "-21dB"                        '  (-21dB)
    End Select

    Call Rfm12b_cmd(out_power)
End Sub


Function Rfm12_low_batt_value(byval Batt_val As Byte) As Word
    Select Case Batt_val
      Case 0 : Rfm12_low_batt_value = &HC005                '2.7 Volt  , 1MHz
      Case 1 : Rfm12_low_batt_value = &HC008                '3.0 Volt  , 1MHz
      Case 2 : Rfm12_low_batt_value = &HC00A                '3.2 Volt  , 1MHz
      Case 3 : Rfm12_low_batt_value = &HC00C                '3.4 Volt  , 1MHz
      Case Else : Rfm12_low_batt_value = &HC000             '2.2 Volt   , 1MHz
    End Select
End Function


Sub Rfm12_init()

   Call Rfm12b_cmd(&H0000)                                  'intitial SPI transfer added to avoid power-up problem
   W = Rfm12_low_batt_value(0)                              '0 = 2.7 Volt
   Call Rfm12b_cmd_ref(w)                                   'Low Battery Detect @ 2.7 Volt , Clock from AVR = appx. 1 MHz
   Call Rfm12b_cmd(configuration_setting)                   'Configuration Settings Command, 868MHz, 12pF, Enable TX Register, Enable Rx Fifo
   Call Rfm12b_cmd(enable_receiver)                         'power management: enable receiver, disable clock output
   Call Rfm12b_cmd(rfm12b_frequency)                        '869,92MHz
   Call Rfm12b_cmd(baudrate)                                'Datarate
   Call Rfm12b_cmd(receiver_control)                        'Receiver Control Command
   Call Rfm12b_cmd(data_filter)                             'Data Filter Command
   Call Rfm12b_cmd(auto_frequ_control)                      'AFC
   Call Rfm12b_cmd(tx_control)
   Call Rfm12b_cmd(pll_settings)
   Call Rfm12_set_output_power(0)                           'Transmit Control Command [&H9850] = (Sign = Pos Frequency Shift, Deviation = 90KHz, Power Out = 0dB maximum
   Call Rfm12b_cmd(wakeup_timer)                            'Wake Up Timer Command
   Call Rfm12b_cmd(low_duty_cycle)                          'Low Duty Cycle Command
   Call Rfm12b_cmd(enable_fifo)                             'enable FIFO

End Sub


Sub Rfm12_send(byval Number_of_bytes As Byte)
     Local Count_ As Byte
      Disable Interrupts
      'TX, send Bytes
      Call Rfm12b_cmd(&H0000)                               'read status
      Call Rfm12b_cmd(enable_transmitter)                   'Enable SENDER , DISABLE RECEIVER
      Call Rfm12b_spi_send_val(&Haa)                        'Preamble
      Call Rfm12b_spi_send_val(&Haa)                        'Preamble
      Call Rfm12b_spi_send_val(&H2d)                        'SYNCHRON WORD (HIGH BYTE)   --> 'SYNCHRON PATTERN = 2 Byte = &H2DD4
      Call Rfm12b_spi_send_val(&Hd4)                        'SYNCHRON WORD (LOW BYTE)

      '3 Bytes Data
      For Count_ = 1 To Number_of_bytes
        Call Rfm12b_spi_send(tx(count_))
      Next Count_
      'Dummy Bytes
      'send 2 dummy bytes to empty TX FIFO
      Call Rfm12b_spi_send_val(dummy_byte)                  'DUMMY BYTE
      Call Rfm12b_spi_send_val(dummy_byte)                  'DUMMY BYTE
      Call Rfm12b_cmd(enable_receiver)                      'ENABLE RECEIVER, DISABLE TRANSMITTER
      Enable Interrupts
End Sub

Enable Interrupts


Main_programm:                                              'just a label

Reset Watchdog

         Call Rfm12_init()

   Do
Reset Watchdog


     If Rfm12b_data_ready = 1 Then
        Reset Rfm12b_data_ready
     End If

         If Four_second_tick = 1 Then
            Four_second_tick = 0

            Toggle 1_wire_toggle                            'toggle between 1-wire convert command and read scratchpad

          If 1_wire_toggle = 0 Then
            1wreset                                         'reset the device
            1wwrite &H55                                    'skip ROM command
            1wwrite 1_wire_sensor_id(1) , 8                 'write ROM Code of Unit
            1wwrite &H44                                    'convert command

          Else

            1wreset                                         'reset the device
            1wwrite &H55                                    'skip ROM command
            1wwrite 1_wire_sensor_id(1) , 8                 'write ROM Code of Unit
            1wwrite &HBE                                    'read scratchpad
            Ds18b20_scratchpad(1) = 1wread(9)               'Read 9 Data-Bytes

            Crc8_value = Crc8(ds18b20_scratchpad(1) , 8)

             If Crc8_value = Ds18b20_scratchpad(9) Then     'Passt CRC8 ?
               Tx(2) = Ds18b20_scratchpad(1)                'Nur wenn CRC8 passt !
               Tx(3) = Ds18b20_scratchpad(2)                'Nur wenn CRC8 passt !

               Ds18b20_integer_temp = Makeint(ds18b20_scratchpad(1) , Ds18b20_scratchpad(2))
               Ds18b20_single_temp = Ds18b20_integer_temp * 0.0625

               '---------------RFM12----DATA-----------
               Tx(1) = Sensor_id                            'Sensor ID
               'Tx(2) 1 -wire Sensor
               'Tx(3) 1 -wire Sensor
               Tx(4) = 0
               Tx(5) = 0
               Tx(6) = 0
               Tx(7) = 0
               Tx(8) = Crc8(tx(1) , 7)                      'CRC8 der 7 Bytes

                Toggle Led

               'Send 8 Bytes
               Call Rfm12_send(8)                           'Send 8 Bytes


              End If
           End If
         End If

         If Nirq = 0 Then Gosub Nirq_isr                    'This is to avoid RFM "hang-up's" due to bad RX quality
     Loop

End                                                         'end program

Nirq_isr:
  If Nirq = 0 Then                                          'check NIRQ is really low
    Call Rfm12b_read_status()                               'Read the RFM12B Status Register

    If Stat(1).ffit = 1 Then                                'Bit 7 is the FFIT Bit
' FFIT = The number of data bits in the RX FIFO has reached the pre-programmed limit (Can be cleared by any of the FIFO read methods)
       Incr Rxcounter
       Spiin Fifo(1) , 3
       Rx(rxcounter) = Fifo(3)

       If Rxcounter = 2 Then                                'we wait for 2 Bytes
           Rxcounter = 0
           Set Rfm12b_data_ready
           'Clear FIFO
           Call Rfm12b_cmd(init_fifo)                       'init FIFO
           Call Rfm12b_cmd(enable_fifo)                     'enable FIFO
       End If
    End If
  End If

Return

Timer_irq:
    Timer1 = Timer_preload                                  '4 second tick at 8MHz clock
    Set Four_second_tick
    'Toggle Led
Return
		
Baza odbiornik z wyświetlaczem
$regfile = "m328pdef.dat"
$crystal = 8000000                                          '8MHz
$hwstack = 80
$swstack = 80
$framesize = 100

Config Watchdog = 512                                       '1 Second
Start Watchdog

Config Submode = New
'---------Variables-------------------------------------------------------------
Dim Count As Byte
Dim Temp As Byte
Dim Cmd(2) As Byte
Dim Sdi(2) As Byte
Dim Stat(2) As Byte                                         'Array for Status Register Bytes
'RECEIVE ARRAY
Dim Rx(8) As Byte
'TRANSMITT ARRAY
Dim Tx(8) As Byte
Dim Fifo(4) As Byte
Dim Rxcounter As Byte
Dim Ds18b20_integer_temp As Integer
Dim Ds18b20_single_temp As Single
Dim 1_wire_string As String * 7
Dim W As Word

'Config SPI for RFM12 for ATMEGA328P
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 4 , Noss = 0 , Spiin = 0
Spiinit
'Config LCD
Config Lcdpin = Pin , Db4 = Portc.1 , Db5 = Portc.2 , Db6 = Portc.3 , Db7 = Portc.4 , E = Portc.0 , Rs = Portc.5
Config Lcd = 20 * 4
Cursor Off Noblink
Cls
'---------Ports-----------------------------------------------------------------
Config Portd.2 = Input
Nirq Alias Pind.2
'---------Interrupts------------------------------------------------------------
Config Int0 = Falling                                       'PD2 = RFM12 Nirq
On Int0 Nirq_isr
Enable Int0
'---------Constants-------------------------------------------------------------
Const Sensor_id = 20
Const Configuration_setting = &H80D7

Const Enable_receiver = &H82D9
Const Enable_transmitter = &H8279

Const Rfm12b_frequency = &HA640
Const Baudrate = &HC611
Const Receiver_control = &H94A2
Const Data_filter = &HC2AC
Const Init_fifo = &HCA81
Const Enable_fifo = &HCA83
Const Auto_frequ_control = &HC483
Const Tx_control = &H9850
Const Pll_settings = &HCC57

Const Wakeup_timer = &HE000
Const Low_duty_cycle = &HC800
Const Dummy_byte = &HAA
Const Tramsmit_write_command = &HB8
Const Rfm12_software_reset = &HFE00
Const Sleep_mode = &H8205
Const Ffit = 7

Sub Rfm12_init()
   Disable Int0
   Call Rfm12b_cmd(&H0000)                                  'intitial SPI transfer added to avoid power-up problem
   W = Rfm12_low_batt_value(4)                              '0 = 2.7 Volt  4 = 2.2 Volt
   Call Rfm12b_cmd_ref(w)                                   'Low Battery Detect @ 2.7 Volt , Clock from AVR = appx. 1 MHz
   Call Rfm12b_cmd(configuration_setting)                   'Configuration Settings Command, 868MHz, 12pF, Enable TX Register, Enable Rx Fifo
   Call Rfm12b_cmd(enable_receiver)                         'power management: enable receiver, disable clock output
   Call Rfm12b_cmd(rfm12b_frequency)                        '869,92MHz
   Call Rfm12b_cmd(baudrate)                                'Datarate
   Call Rfm12b_cmd(receiver_control)                        'Receiver Control Command
   Call Rfm12b_cmd(data_filter)                             'Data Filter Command
   Call Rfm12b_cmd(auto_frequ_control)                      'AFC
   Call Rfm12b_cmd(tx_control)
   Call Rfm12b_cmd(pll_settings)
   Call Rfm12_set_output_power(0)                           'Transmit Control Command [&H9850] = (Sign = Pos Frequency Shift, Deviation = 90KHz, Power Out = 0dB maximum
   Call Rfm12b_cmd(wakeup_timer)                            'Wake Up Timer Command
   Call Rfm12b_cmd(low_duty_cycle)                          'Low Duty Cycle Command
   Call Rfm12b_cmd(enable_fifo)                             'enable FIFO
   Enable Int0
End Sub

Sub Rfm12b_spi_send_val(byval Sdi_byte As Byte)
   Disable Int0
   Bitwait Nirq , Reset
   Sdi(1) = Tramsmit_write_command                          '&HB8
   Sdi(2) = Sdi_byte
   Spiout Sdi(1) , 2
   Enable Int0
End Sub

Sub Rfm12_send(byval Number_of_bytes As Byte)
     Local Count_ As Byte
      Disable Int0
      'TX, send Bytes
      Call Rfm12b_cmd(&H0000)                               'read status
      Call Rfm12b_cmd(enable_transmitter)                   'Enable SENDER , DISABLE RECEIVER
      Call Rfm12b_spi_send_val(&Haa)                        'Preamble
      Call Rfm12b_spi_send_val(&Haa)                        'Preamble
      Call Rfm12b_spi_send_val(&H2d)                        'SYNCHRON WORD (HIGH BYTE)   --> 'SYNCHRON PATTERN = 2 Byte = &H2DD4
      Call Rfm12b_spi_send_val(&Hd4)                        'SYNCHRON WORD (LOW BYTE)
      '3 Bytes Data
      For Count_ = 1 To Number_of_bytes
        Call Rfm12b_spi_send(tx(count_))
      Next Count_
      'Dummy Bytes
      'send 2 dummy bytes to empty TX FIFO
      Call Rfm12b_spi_send_val(dummy_byte)                  'DUMMY BYTE
      Call Rfm12b_spi_send_val(dummy_byte)                  'DUMMY BYTE
      Call Rfm12b_cmd(enable_receiver)                      'ENABLE RECEIVER, DISABLE TRANSMITTER
      Enable Int0
End Sub

Sub Rfm12b_cmd(byval Tmp As Word)
   Disable Int0
   Cmd(2) = Low(tmp)
   Cmd(1) = High(tmp)
   Spiout Cmd(1) , 2
   Enable Int0
End Sub

Sub Rfm12b_read_status()
   Cmd(2) = &H00
   Cmd(1) = &H00
   Spiout Cmd(1) , 2                                        'Write &H0000 to read status register
   Spiin Stat(1) , 2                                        'Read the 2 Status Register Bytes
End Sub

Sub Rfm12b_spi_send(sdi_byte As Byte)
   Disable Int0
   Bitwait Nirq , Reset
   Sdi(1) = Tramsmit_write_command                          '&HB8
   Sdi(2) = Sdi_byte
   Spiout Sdi(1) , 2
   Enable Int0
End Sub

Sub Rfm12b_cmd_ref(tmp As Word)
   Disable Int0
   Cmd(2) = Low(tmp)
   Cmd(1) = High(tmp)
   Spiout Cmd(1) , 2
   Enable Int0
End Sub

Sub Rfm12_set_output_power(byval Out_power As Word)         '0 = Max output
    'Transmit Control Command [&H9850] = (Sign = Pos Frequency Shift, Deviation = 90KHz, Power Out = 0dB maximum
    Select Case Out_power
     Case 0 :
        Out_power = &H9850
      '  Print #1 , "Max Outut"                    ' Max output (-0dB)
     Case 1 :
        Out_power = &H9851
      '  Print #1 , "-3dB"                         '  (-3dB)
     Case 2 :
        Out_power = &H9852
      '  Print #1 , "-6dB"                         '  (-6dB)
     Case 3 :
        Out_power = &H9854
      '  Print #1 , "-12dB"                        '  (-12dB)
     Case 4 :
        Out_power = &H9855
     '   Print #1 , "-18dB"                        '  (-18dB)
     Case 5 :
        Out_power = &H9856
     '   Print #1 , "-21dB"                        '  (-21dB)
    End Select

    Call Rfm12b_cmd(out_power)
End Sub

Function Rfm12_low_batt_value(byval Batt_val As Byte) As Word
    Select Case Batt_val
      Case 0 : Rfm12_low_batt_value = &HC005                '2.7 Volt  , 1MHz
      Case 1 : Rfm12_low_batt_value = &HC008                '3.0 Volt  , 1MHz
      Case 2 : Rfm12_low_batt_value = &HC00A                '3.2 Volt  , 1MHz
      Case 3 : Rfm12_low_batt_value = &HC00C                '3.4 Volt  , 1MHz
      Case Else : Rfm12_low_batt_value = &HC000             '2.2 Volt   , 1MHz
    End Select
End Function

Enable Interrupts

'********************** ZACZYNAMY ***********************************************
Call Rfm12_init()                                           'RFM12B Initilization

  Lcd "Czekam..."
Reset Watchdog
 Do

Reset Watchdog

 If Rxcounter = 8 Then                                      'wait until 8 byte received
            Rxcounter = 0

            Call Rfm12b_cmd(init_fifo)                      'Init FIFO
            Call Rfm12b_cmd(enable_fifo)                    'enable FIFO

              Select Case Rx(1)                             'Sensor ID

               Case 2:                                      'Sensor 2

                         'There is a DS18B20 connected to Sensor 2 so we caluclate the temperature here
                         Ds18b20_integer_temp = Makeint(rx(2) , Rx(3))
                         Ds18b20_single_temp = Ds18b20_integer_temp * 0.0625
                         1_wire_string = Fusing(ds18b20_single_temp , "#.#")
                          Cls
                          Lcd "Temperatura " ; 1_wire_string ; Chr(223) ; "C "
                         'RFM12B Master Send back an Acknowledge to the Jee Node  (Send 2 Bytes)
                         Tx(1) = Sensor_id
                         Tx(2) = &B11111110                 'Send Ack = 254
                         Call Rfm12_send(2)                 'Send 2 Bytes

                End Select


  End If                                                    'If Rxcounter = 8 Then


   If Nirq = 0 Then Gosub Nirq_isr                          'This is to avoid RFM "hang-up's" due to bad RX quality

       Loop

End                                                         'end program

Nirq_isr:
  If Nirq = 0 Then                                          'check NIRQ is really low
     Call Rfm12b_read_status()                              'Read the RFM12B Status Register

    If Stat(1).ffit = 1 Then                                'Bit 7 is the FFIT Bit
     ' FFIT = The number of data bits in the RX FIFO has reached the pre-programmed limit (Can be cleared by any of the FIFO read methods)
       Incr Rxcounter
       Spiin Fifo(1) , 3
       Rx(rxcounter) = Fifo(3)
    End If
  End If

Return
		

Te kody do obsługi mogły by być dużo krótsze ale te są w pewnym stopniu uniwersalne. Można zmieniać moc nadawanego sygnału i różne inne. W przykładzie parametry te są wpisane na sztywno. Wyłączyłem też sprawdzanie poziomu naładowania baterii a nie odjąłem komentarza o włączeniu. W każdym bądź razie chodzi o to, że Wykrycie niskiego stanu naładowania baterii wywołuje przerwanie którego obsługi tu nie implementowałem.

Email

Jeśli mogę w czymś pomóc, napisz.