Author | Rob Jansen, Copyright © 2018..2019, all rights reserved. |
Adapted-by | |
Compiler | 2.5r2 |
Library for sending and receiving data over an RF Link based on Virtual Wire. The driver implements a Phase Locked Loop to increase sensitivity and so extend the range of the connection. Next to that it uses a special encoding format for the bit pattern to stay DC neutral. See sources for more information on Virtual Wire. A standard 433 MHz transmitter and 433 MHz receiver was used for testing this driver using a maximum bitrate of 2000 bits/s. In order to use this driver the main program must have the following defined (this to make this driver PIC independent): -) An alias for the tranmission pin vw_tx_pin. -) An alias for the receive pin vw_rx_pin. -) Initializing a timer that is used for transmission and reception. The timer must run at 8 times the bitrate. -) An interrupt routine of the used timer which must call the vw_service() procedure. A transmitter only and receiver only version is also available to save data space and code space for use in smaller PICs.
http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
Changes to the original driver that was created for Arduino: *) From C converted to JAL. This required an extra receive buffer because of the lack of pointers which could not pass a receive buffer. *) The inverting of the output and input signal was removed. *) The 6 to 4 conversion was changed into a look-up table to improve speed. *) The maximum message length was reduced to 10 to save data space but can be changed by the user by setting VW_MAX_MESSAGE_LEN to another value. *) The transmission header was moved from data to constant as to decrease the size of the transmit buffer and so save data space. *) The transmission buffer and reception buffer were combined into one buffer to save data space. This can be done since the original driver does not support transmission and reception at the same time. *) The bit rate is defined by the user by initializing the used timer.
No dependency found
var byte vw_rx_bit_count
const byte VW_HEADER_LEN = 8
var byte vw_tx_sample
var bit vw_rx_last_sample
const byte VW_RAMP_INC_RETARD = (VW_RAMP_INC - VW_RAMP_ADJUST)
var byte vw_rx_pll_ramp
var bit vw_rx_active
var bit vw_tx_header
const byte symbols_c[] =
const byte vw_tx_header_buf[VW_HEADER_LEN]
var word data_2
var byte vw_tx_index
var bit vw_rx_enabled
const byte VW_MAX_PAYLOAD = VW_MAX_MESSAGE_LEN - 3
var byte vw_rx_integrator
var dword vw_rx_bad
var word vw_rx_bits
const byte VW_RX_SAMPLES_PER_BIT = 8
var dword vw_rx_good
const byte VW_RAMP_INC = (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
const byte VW_RAMP_ADJUST = 9
const byte symbols_d[] =
var byte vw_rx_count
const byte VW_RX_RAMP_LEN = 160
const byte VW_RAMP_INC_ADVANCE = (VW_RAMP_INC + VW_RAMP_ADJUST)
var byte vw_rx_len
var bit vw_tx_enabled
var byte vw_rx_return_buf[VW_MAX_PAYLOAD]
var byte vw_tx_bit
var bit vw_rx_sample
var byte this_byte
var byte vw_tx_rx_buf[VW_MAX_MESSAGE_LEN * 2]
var byte vw_tx_len
var bit vw_rx_done
const byte VW_RAMP_TRANSITION = VW_RX_RAMP_LEN/2
vw_rx_start()
vw_service()
vw_tx_stop()
vw_rx_stop()
vw_wait_rx()
vw_wait_tx()
vw_reset_rx_good_bad_count()
vw_init()
vw_get_message(byte in out len) return bit
vw_tx_active() return bit
vw_send(byte in buf[], byte in len) return bit
vw_get_rx_good() return dword
vw_get_rx_bad() return dword
vw_have_message() return bit
var byte vw_rx_bit_count
How many bits of message we have received. Ranges from 0 to 12
const byte VW_HEADER_LEN = 8
Outgoing message bits grouped as 6-bit words 36 alternating 1/0 bits, followed by 12 bits of start symbol Followed immediately by the 4-6 bit encoded byte count, message buffer and 2 byte FCS Each byte from the byte count on is translated into 2x6-bit words Caution, each symbol is transmitted LSBit first, but each byte is transmitted high nybble first
var byte vw_tx_sample
Sample number for the transmitter. Runs 0 to 7 during one bit interval.
var bit vw_rx_last_sample
Last receivers sample.
const byte VW_RAMP_INC_RETARD = (VW_RAMP_INC - VW_RAMP_ADJUST)
Internal ramp adjustment parameter
var byte vw_rx_pll_ramp
PLL ramp, varies between 0 and VW_RX_RAMP_LEN-1 (159) over VW_RX_SAMPLES_PER_BIT (8) samples per nominal bit time. When the PLL is synchronised, bit transitions happen at about the 0 mark.
var bit vw_rx_active
Flag indicates if we have seen the start symbol of a new message and are in the processes of reading and decoding it
var bit vw_tx_header
Indicates that the header must be transmitted first.
const byte symbols_c[] =
4 bit to 6 bit symbol converter table for coding Used to convert the high and low nibbles of the transmitted data into 6 bit symbols for transmission. Each 6-bit symbol has 3 1s and 3 0s with at most 3 consecutive identical bits
const byte vw_tx_header_buf[VW_HEADER_LEN]
Transmit header to synchronize the receiver.
var word data_2
No documentation found
var byte vw_tx_index
Index of he next symbot to send. Ranges from 0 to VW_Tx_Len
var bit vw_rx_enabled
Flag to indicate the receiver PLL is to run
const byte VW_MAX_PAYLOAD = VW_MAX_MESSAGE_LEN - 3
The maximum payload length, count (1) and FCS (2) must be subtracted.
var byte vw_rx_integrator
This is the integrate and dump integral. If there are <5 0 samples in the PLL cycle the bit is declared a 0, else a 1
var dword vw_rx_bad
Number of bad messages received and dropped due to bad lengths. Only available in complete virtual wire driver for testing purposes.
var word vw_rx_bits
Last 12 bits received, so we can look for the start symbol
const byte VW_RX_SAMPLES_PER_BIT = 8
Number of samples per bit.
var dword vw_rx_good
Number of good messages received. Only available in complete virtual wire driver for testing purposes.
const byte VW_RAMP_INC = (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
Ramp adjustment parameters Standard is if a transition occurs before VW_RAMP_TRANSITION (80) in the ramp, the ramp is retarded by adding VW_RAMP_INC_RETARD (11) else by adding VW_RAMP_INC_ADVANCE (29) If there is no transition it is adjusted by VW_RAMP_INC (20) Internal ramp adjustment parameter
const byte VW_RAMP_ADJUST = 9
Internal ramp adjustment parameter
const byte symbols_d[] =
Conversion table for 6 to 4 symbol decoding using a lookup table. We only need to indicate the values from the encoding table. Without lookup table the conversion would take too long.
var byte vw_rx_count
The incoming message expected length
const byte VW_RX_RAMP_LEN = 160
The size of the receiver ramp. Ramp wraps modulo this number
const byte VW_RAMP_INC_ADVANCE = (VW_RAMP_INC + VW_RAMP_ADJUST)
Internal ramp adjustment parameter
var byte vw_rx_len
The incoming message buffer length received so far
var bit vw_tx_enabled
Indicates if the transmitter is active.
var byte vw_rx_return_buf[VW_MAX_PAYLOAD]
The buffer to copy the return message to for the main program. This buffer is smaller than the combined vw_tx_rx_buf since it only holds data no symbol.s
var byte vw_tx_bit
Bit number of next bot to send
var bit vw_rx_sample
Current receiver sample
var byte this_byte
No documentation found
var byte vw_tx_rx_buf[VW_MAX_MESSAGE_LEN * 2]
Transmit and receive buffer. The symbol buffer for transmission is combined with the data buffer for reception.
var byte vw_tx_len
Number of symbols in VW_Tx_Buf to be sent
var bit vw_rx_done
Flag to indicate that a new message is available
const byte VW_RAMP_TRANSITION = VW_RX_RAMP_LEN/2
Internal ramp adjustment parameter
vw_rx_start()
Enable the receiver. When a message becomes available, vw_rx_done flag is set, and vw_wait_rx() will return.
vw_service()
This is the service routine that must be called by the main program when the timer overflows. Its job is to output the next bit from the transmitter (every 8 calls) and to call the PLL code if the receiver is enabled.
vw_tx_stop()
Stop the transmitter, call when all bits are sent
vw_rx_stop()
Disable the receiver
vw_wait_rx()
Wait for the receiver to get a message Busy-wait loop until the ISR says a message is available can then call vw_get_message()
vw_wait_tx()
Wait for the transmitter to become available Busy-wait loop until the ISR says the message has been sent
vw_reset_rx_good_bad_count()
Reset the good and bad received message count
vw_init()
Initialize the virtual wire driver.
_vw_pll()
Called 8 times per bit period by the timer interrupt routine Phase locked loop tries to synchronise with the transmitter so that bit transitions occur at about the time vw_rx_pll_ramp is 0 Then the average is computed over each bit period to deduce the bit value
vw_get_message(byte in out len) return bit
Get the last message received (without byte count or FCS) Copy at most len bytes, set len to the actual number copied Return true if there is a message and the FCS is OK The data is copied to a receive buffer.
vw_tx_active() return bit
Return true if the transmitter is active
vw_send(byte in buf[], byte in len) return bit
Wait until transmitter is available and encode and queue the message into vw_tx_buf The message is raw bytes, with no packet structure imposed It is transmitted preceded a byte count and followed by 2 FCS bytes
vw_get_rx_good() return dword
Return the number of good received messages count.
vw_get_rx_bad() return dword
Return the number of bad messages received and dropped due to bad lengths.
vw_have_message() return bit
Return true if there is a message available
_vw_calc_crc(word in crc, byte in data) return word
Calculate new crc over given data. Formula is: Xexp16 + Xexp12 + Xexp5 + 1
16f1825 | 16f1825_virtual_wire_receiver.jal |
16f1825 | 16f1825_virtual_wire_transmitter.jal |