Author | Rob Jansen, Copyright © 2018..2018, all rights reserved. |
Adapted-by | Rob Jansen, small bug fix in transmiter. |
Compiler | 2.4q6 |
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. Also see sources for more information on Virtual Wire. A standard 433 MHz transmitter and 433 MHz receiver was used for testing this driver. This driver was created and tested for the following PICs: -) 12F617 at 8 MHz -) 16F1823/25 at 32 MHz -) 16F1455 at 48 MHz -) 18F14K50 at 48 MHz In order to support more PICs, the _vw_timer_setup (Timer2) initialization routine has to be extended. Since the driver can be used for transmission or reception, a transmit only version and receive only version were extracted.
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 variables and procedure that indicate the number of bad and good received messages were removed to save data space. This includes the message count which was also removed. *) The maximum message length was reduced to 10 to save data space. *) 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 receiption 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 not ultimate flexible. Instead 2 values, 1000 bit/s and 2000 bits/s, can be selected. For devices running at 8 MHz select the 1000 bits/s bitrate. The lower the bitrate the higher the range.
No dependency found
const byte VW_HEADER_LEN = 8
const byte VW_RAMP_INC_ADVANCE = (VW_RAMP_INC + VW_RAMP_ADJUST)
var byte vw_rx_count = 0
const byte symbols_c[] =
const byte vw_tx_header_buf[VW_HEADER_LEN]
var word vw_rx_bits = 0
var word data_2
const byte VW_SPEED_2000 = 125
const byte VW_RAMP_TRANSITION = VW_RX_RAMP_LEN/2
const byte VW_RX_SAMPLES_PER_BIT = 8
const byte VW_MAX_PAYLOAD = VW_MAX_MESSAGE_LEN - 3
var byte vw_rx_integrator = 0
var bit vw_rx_sample = false
var byte vw_tx_index = 0
const byte VW_RAMP_ADJUST = 9
var byte vw_tx_sample = 0
const byte symbols_d[] =
var bit vw_rx_last_sample = false
var byte vw_tx_bit = 0
const byte VW_SPEED_1000 = 250
const byte VW_RAMP_INC = (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
var bit vw_tx_enabled = false
var bit vw_rx_active = FALSE
var byte vw_rx_bit_count = 0
const byte VW_RAMP_INC_RETARD = (VW_RAMP_INC - VW_RAMP_ADJUST)
var byte vw_rx_return_buf[VW_MAX_PAYLOAD]
var bit vw_rx_done = FALSE
var byte this_byte
var byte vw_tx_rx_buf[VW_MAX_MESSAGE_LEN * 2]
var byte vw_rx_len = 0
var bit vw_rx_enabled = FALSE
var byte vw_tx_len = 0
var bit vw_tx_header = false
const byte VW_RX_RAMP_LEN = 160
var byte vw_rx_pll_ramp = 0
vw_rx_start()
vw_setup(byte in bitrate)
vw_tx_stop()
vw_rx_stop()
timer2_interrupt()
vw_wait_rx()
vw_wait_tx()
vw_have_message() return bit
vw_get_message(byte in out len) return bit
vw_send(byte in buf[], byte in len) return bit
vw_tx_active() return bit
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
const byte VW_RAMP_INC_ADVANCE = (VW_RAMP_INC + VW_RAMP_ADJUST)
Internal ramp adjustment parameter
var byte vw_rx_count = 0
The incoming message expected length
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 vw_rx_bits = 0
Last 12 bits received, so we can look for the start symbol
var word data_2
No documentation found
const byte VW_SPEED_2000 = 125
2000 bits/second
const byte VW_RAMP_TRANSITION = VW_RX_RAMP_LEN/2
Internal ramp adjustment parameter
const byte VW_RX_SAMPLES_PER_BIT = 8
Number of samples per bit.
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 = 0
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 bit vw_rx_sample = false
Current receiver sample
var byte vw_tx_index = 0
Index of he next symbot to send. Ranges from 0 to VW_Tx_Len
const byte VW_RAMP_ADJUST = 9
Internal ramp adjustment parameter
var byte vw_tx_sample = 0
Sample number for the transmitter. Runs 0 to 7 during one bit interval.
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 bit vw_rx_last_sample = false
Last receivers sample.
var byte vw_tx_bit = 0
Bit number of next bot to send
const byte VW_SPEED_1000 = 250
Selection of bitrates.
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
var bit vw_tx_enabled = false
Indicates if the transmitter is active.
var bit vw_rx_active = FALSE
Flag indicates if we have seen the start symbol of a new message and are in the processes of reading and decoding it
var byte vw_rx_bit_count = 0
How many bits of message we have received. Ranges from 0 to 12
const byte VW_RAMP_INC_RETARD = (VW_RAMP_INC - VW_RAMP_ADJUST)
Internal ramp adjustment parameter
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 bit vw_rx_done = FALSE
Flag to indicate that a new message is available
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_rx_len = 0
The incoming message buffer length received so far
var bit vw_rx_enabled = FALSE
Flag to indicate the receiver PLL is to run
var byte vw_tx_len = 0
Number of symbols in VW_Tx_Buf to be sent
var bit vw_tx_header = false
Indicates that the header must be transmitted first.
const byte VW_RX_RAMP_LEN = 160
The size of the receiver ramp. Ramp wraps modulo this number
var byte vw_rx_pll_ramp = 0
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.
vw_rx_start()
Enable the receiver. When a message becomes available, vw_rx_done flag is set, and vw_wait_rx() will return.
vw_setup(byte in bitrate)
This procedure initialized the timer 2 that is used for creating the pulse time interrupt. This has to be VW_RX_SAMPLES_PER_BIT times the bit time.
vw_tx_stop()
Stop the transmitter, call when all bits are sent
vw_rx_stop()
Disable the receiver
timer2_interrupt()
This is the interrupt service routine called when timer2 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_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_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_timer_setup(byte in bitrate)
Intialize Timer 2 to generate the RF bit time.
vw_have_message() return bit
Return true if there is a message available
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_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_tx_active() return bit
Return true if the transmitter is active
_vw_calc_crc(word in crc, byte in data) return word
Calculate new crc over given data. Formula is: Xexp16 + Xexp12 + Xexp5 + 1