![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
aydi
Joined: 11 Aug 2010 Posts: 12
|
send and receive with virtual wire library for PIC16F628A |
Posted: Sun Mar 12, 2017 4:20 am |
|
|
good morning,
please i tested the virtualwire library example sited in this link : http://www.enide.net/webcms/?page=virtualwire-for-pic
it's ok, every thing work very well when i tried to send a message text "HELLO from PIC" as specified.
But when i tried to send this kind of message : const char text2[] = {0x38,0x34,0x35,'\0'};
i received this : 845-02 fkm PCi
why i didn't receive just 845. why it add -02 fkm PCi which is a part from the last message that i send.
Also when i put 0x38,0x34,0x35 between two quotations i received them very well but for me i want to send my data like that text= {0x38,0x34,0x35,0x35,'\0'};
because i can't change it to add two quotations " ". this data came from an other function like that.
thanks an advance
the messages that i send are:
const char text[] = "Hello from PIC";
const char text1[] = "HELLO2 fkm PCic";
const char text2[] = {0x38,0x34,0x35,0x35,'\0'};
the received result is:
Hello from PIC
HELLO2 fkm PCi
845-02 fkm PCi
the source code of the transmitter is below:
Code: | #include <htc.h>
#include "virtualwire.h"
#include <stdio.h>
#include <string.h>
__CONFIG(MCLREN & PWRTEN & BOREN & LVPDIS & WDTDIS & INTIO);
void interrupt global_isr(void)
{
if(T0IF)
vw_isr_tmr0();
}
void delay(unsigned int delay)
{
while(delay--);
}
void main(void)
{
const char text[] = "Hello from PIC";
const char text1[] = "HELLO2 fkm PCic";
const char text2[] = {0x38,0x34,0x35,'\0'};
CMCON = 0x07; // analog comparator disabled
VRCON = 0x00; // voltage reference module disabled
vw_setup(600);
while(1)
{
vw_send(text, sizeof(text)-1);
delay(20000);
vw_send(text1, sizeof(text1)-1);
delay(20000);
vw_send(text2, sizeof(text2)-1);
delay(20000);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Sun Mar 12, 2017 5:22 am |
|
|
From your post it looks like the transmitter code is OK, as the correct characters are sent for the first message.
Without seeing the receiver code, I'm guessing that you're not clearing the rcv buffer, or it's the wrong size for the incoming data. There can be several reasons but those are my top 2, aside from hardware.
As the library was written on another compiler, have you modified every line to be correct for the CCS C compiler?
Also I don't see the PICtype header, it should be #1 line of code
And... is this REAL Hardware ?
Jay |
|
![](templates/subSilver/images/spacer.gif) |
aydi
Joined: 11 Aug 2010 Posts: 12
|
|
Posted: Sun Mar 12, 2017 5:38 am |
|
|
I try to adapt the virtual wire library to the ccs compiler. I also add interrupt in pin_b0 in order to resynchronize the receiver at the beginning of the incoming message.
The baudrate is selected to 600 and i try to eliminate the parts that i don't need in order to save memory space.
I worked very hard (many hours) in order to adapt the receiver, but the problem is still here.
Thanks in advance.
Code: |
#include <16F628A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4M)
#use RS232( baud=9600, parity=N, xmit=PIN_B2, rcv=PIN_B1, bits=8)
#byte OPTION_REG =0x81
#byte TMR0 =0x01
#byte INTCON=0x0b
int1 edge_b0=0,ddat=1;
int1 vw_rx_sample=0,vw_rx_last_sample=0;
int8 count=0;
typedef unsigned int16 uint16_t;
//typedef unsigned char uint8_t;
typedef unsigned int8 uint8_t;
static uint8_t vw_rx_integrator = 0;
static uint8_t vw_rx_pll_ramp = 0;
static uint16_t vw_rx_bits = 0;
static int vw_rx_active = 0;
static uint8_t vw_rx_count = 0;
static uint8_t vw_rx_bit_count = 0;
static uint8_t vw_rx_len = 0;
static volatile int vw_rx_done = 0;
static uint8_t text[24];
const uint8_t symbols[] = {
0xd, 0xe, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,
0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x32, 0x34
};
static uint8_t vw_tx_buf[24 * 2];
uint8_t vw_symbol_6to4(uint8_t symbol)
{
uint8_t i;
// Linear search :-( Could have a 64 byte reverse lookup table?
for (i = 0; i < 16; i++)
if (symbol == symbols[i])
return i;
return 0; // Not found
}
//-------------------------------vw_pll
void vw_pll(void)
{
// Integrate each sample
uint8_t this_byte,this_byte1,this_byte2;
// output_high(pin_B5);
if (vw_rx_sample)
{vw_rx_integrator++; }//output_bit(PIN_C1,1);
// else output_low(PIN_C1);
if (vw_rx_sample != vw_rx_last_sample)
{
// Transition, advance if ramp > 80, retard if < 80
// vw_rx_pll_ramp += ((vw_rx_pll_ramp < VW_RAMP_TRANSITION)? VW_RAMP_INC_RETARD: VW_RAMP_INC_ADVANCE);
if(vw_rx_pll_ramp < 80)
vw_rx_pll_ramp +=11;
else
vw_rx_pll_ramp +=29;
vw_rx_last_sample = vw_rx_sample;
}
else
{
// No transition
// Advance ramp by standard 20 (== 160/8 samples)
vw_rx_pll_ramp += 20;
}
if (vw_rx_pll_ramp >= 160)
{
// Add this to the 12th bit of vw_rx_bits, LSB first
// The last 12 bits are kept
vw_rx_bits >>= 1;
// Check the integrator to see how many samples in this cycle were high.
// If < 5 out of 8, then its declared a 0 bit, else a 1;
if (vw_rx_integrator >= 5)
vw_rx_bits |= 0x800;
vw_rx_pll_ramp -= 160;
vw_rx_integrator = 0; // Clear the integral for the next cycle
if (vw_rx_active)
{
// We have the start symbol and now we are collecting message bits,
// 6 per symbol, each which has to be decoded to 4 bits
vw_rx_bit_count++;
if (vw_rx_bit_count >= 12)
{
// Have 12 bits of encoded message == 1 byte encoded
// Decode as 2 lots of 6 bits into 2 lots of 4 bits
// The 6 lsbits are the high nybble
this_byte1=vw_rx_bits & 0x3f;
this_byte=vw_symbol_6to4(this_byte1);
this_byte1=this_byte<<4;
this_byte=vw_rx_bits >> 6;
this_byte2=vw_symbol_6to4(this_byte);
this_byte=this_byte1|this_byte2;
//this_byte =((vw_symbol_6to4(vw_rx_bits & 0x3f)) << 4) | (vw_symbol_6to4(vw_rx_bits >> 6));
// The first decoded byte is the byte count of the following message
// the count includes the byte count and the 2 trailing FCS bytes
// REVISIT: may also include the ACK flag at 0x40
if (vw_rx_len == 0)
{
// The first byte is the byte count
// Check it for sensibility. It cant be less than 4, since it
// includes the bytes count itself and the 2 byte FCS
vw_rx_count = this_byte;
if ((vw_rx_count < 4) || (vw_rx_count > 24))
{
// Stupid message length, drop the whole thing
vw_rx_active = 0;
return;
}
}
vw_tx_buf[vw_rx_len] = this_byte;
//for (i=0; i < len; i++)
// printf("%x\n",vw_tx_buf[vw_rx_len]);
vw_rx_len++;
if (vw_rx_len >= vw_rx_count)
{
// Got all the bytes now
vw_rx_active = 0;
vw_rx_done = 1; // Better come get it before the next one starts
ddat=1;
}
vw_rx_bit_count = 0;
}
}
// Not in a message, see if we have a start symbol
else if (vw_rx_bits == 0xb38)
{
// Have start symbol, start collecting message
vw_rx_active = 1;
vw_rx_bit_count = 0;
vw_rx_len = 0;
vw_rx_done = 0; // Too bad if you missed the last message
}
}
// output_bit(PIN_B5,0);
}
//--------------------rcv
int vw_have_message(void)
{
return vw_rx_done;
}
#define lo8(x) ((x)&0xff)
#define hi8(x) ((x)>>8)
uint16_t _crc_ccitt_update (uint16_t crc, uint8_t data)
{
data ^= lo8 (crc);
data ^= data << 4;
return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4)
^ ((uint16_t)data << 3));
}
uint16_t vw_crc(uint8_t *ptr, uint8_t count)
{
uint16_t crc = 0xffff;
while (count > 0)
{crc = _crc_ccitt_update(crc, *ptr++);
count--;}
return crc;
}
#int_Ext
void SII_RB0()
{
if(ddat==1)
{
//if(edge_b0 ==1) {
//edge_b0=0;
// output_high(pin_B4);
// Ext_int_edge(0,L_to_H);
// vw_rx_sample=0;
vw_rx_sample=input_state(PIN_B0);
ddat=0;
}
/*
else {
//output_high(pin_B4);
edge_b0=1;
Ext_int_edge(0,H_to_L);
vw_rx_sample=1;
}*/
else return;
}
/*void inter_isr_tmr0(void)
{
TMR0+=-198;
vw_pll();
}*/
#int_timer0
void timer0_isr(void)
{
TMR0+=-198;
vw_rx_sample=input_state(PIN_B0);
vw_pll();
// inter_isr_tmr0(vw_rx_sample);
// count++;
}
void delay(unsigned int delay)
{
while(delay--);
}
void main(void)
{
int i=0,tt=0;
uint8_t len = 24;
uint8_t rxlen;
uint16_t varr=0;
//port_b_pullups(true);
bit_set(OPTION_REG,0);
bit_set(OPTION_REG,1);
bit_set(OPTION_REG,2);
bit_set(OPTION_REG,3);
bit_set(OPTION_REG,4);
bit_clear(OPTION_REG,5);
bit_set(OPTION_REG,6);
bit_set(OPTION_REG,7);
TMR0 = 50;
Ext_int_edge(0,L_to_H);
enable_Interrupts(Int_Ext);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
ddat=1;
while(true)
{
if (vw_have_message())
{
varr=vw_crc(vw_tx_buf, vw_rx_len);
// printf("varr=%lx\r\n",varr);
if(varr == 0xf0b8)
// if (vw_recv(text, &len))
{
for (i=1; i <15; i++)
printf("%c",vw_tx_buf[i]);//putchar(text[i]);
}
vw_rx_done = 0;
printf("\r\n");
}
// delay(1000);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Sun Mar 12, 2017 6:02 am |
|
|
You've got 2 areas that are problems.
1) the RF modules. They are difficult to get working 100%. You need the correct antenna, orientation, power supply,etc. AND the software needs to be properly coded. While inexpensive (cheap, $2) they require a lot of effort to get almost working.
2) code translation. There's a lot of code that can be converted into simpler CCS code,which may help, it'll certainly be easier to read and understand. Also when you comment out code, it's best to delete it. If you don't 1) it's hard to read and 2) if the closing comment is put in the wrong place, good code gets left out.
I know cost is a huge factor but have a look at the HC-12 RF modules. They ARE simply RF modems. serial in->RF RF>-serial out. Good for about 1Km. NO fancy program, just 'print' to the serial pin they are attached to.
You might want to spend some time googling ' PIC C 433 RF modules'. I'm sure others have cut real CCS C code for these devices. Maybe check the 'code library' here !
edit: here's one link to look at...
http://ccspicc.blogspot.ca/2016_09_01_archive.html
Jay |
|
![](templates/subSilver/images/spacer.gif) |
aydi
Joined: 11 Aug 2010 Posts: 12
|
|
Posted: Sun Mar 12, 2017 11:54 am |
|
|
Here is a cleaned version of my code.
Also you will find a scanned screen of my simulation. You will see that the vw_pll program sometimes take a little more time (see the encircled red part) when you compared with the others blue impulsions. The time between two successive blue impulsions is the time between two interruption of the timer0 (200us).
My question is why? I guess that is the reason why sometimes my frames are corrupted.
Thanks in advance.
[img]<a href="http://www.zimagez.com/zimage/schematic2.php" target="_blank" title="Simulation_image1"><img src="http://www.zimagez.com/miniature/schematic2.png" alt="Simulation_image1" /></a>[/img]
Why it work for some frame and not for other ?
Code: |
#include <16F628A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4M)
#use RS232( baud=9600, parity=N, xmit=PIN_B2, rcv=PIN_B1, bits=8)
#byte OPTION_REG =0x81
#byte TMR0 =0x01
#byte INTCON=0x0b
int1 edge_b0=0,ddat=1;
int1 vw_rx_sample=0,vw_rx_last_sample=0;
int8 count=0;
typedef unsigned int16 uint16_t;
typedef unsigned int8 uint8_t;
static uint8_t vw_rx_integrator = 0;
static uint8_t vw_rx_pll_ramp = 0;
static uint16_t vw_rx_bits = 0;
static int vw_rx_active = 0;
static uint8_t vw_rx_count = 0;
static uint8_t vw_rx_bit_count = 0;
static uint8_t vw_rx_len = 0;
static volatile int vw_rx_done = 0;
static uint8_t text[24];
static uint8_t vw_tx_buf[24 * 2];//-------received buffer
//---------------------------the table of the 4bits to 6bits conversion
const uint8_t symbols[] = {
0xd, 0xe, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,
0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x32, 0x34
};
uint8_t vw_symbol_6to4(uint8_t symbol)
{
uint8_t i;
// Linear search :-( Could have a 64 byte reverse lookup table?
for (i = 0; i < 16; i++)
if (symbol == symbols[i])
return i;
return 0; // Not found
}
// Called 8 times per bit period
// 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
void vw_pll(void)
{
uint8_t this_byte,this_byte1,this_byte2;
if (vw_rx_sample)
{vw_rx_integrator++; }
if (vw_rx_sample != vw_rx_last_sample)
{
// Transition, advance if ramp > 80, retard if < 80
if(vw_rx_pll_ramp < 80)
vw_rx_pll_ramp +=11;
else
vw_rx_pll_ramp +=29;
vw_rx_last_sample = vw_rx_sample;
}
else
{
// No transition
// Advance ramp by standard 20 (== 160/8 samples)
vw_rx_pll_ramp += 20;
}
if (vw_rx_pll_ramp >= 160)
{
// Add this to the 12th bit of vw_rx_bits, LSB first
// The last 12 bits are kept
vw_rx_bits >>= 1;
// Check the integrator to see how many samples in this cycle were high.
// If < 5 out of 8, then its declared a 0 bit, else a 1;
if (vw_rx_integrator >= 5)
vw_rx_bits |= 0x800;
vw_rx_pll_ramp -= 160;
vw_rx_integrator = 0; // Clear the integral for the next cycle
if (vw_rx_active)
{
// We have the start symbol and now we are collecting message bits,
// 6 per symbol, each which has to be decoded to 4 bits
vw_rx_bit_count++;
if (vw_rx_bit_count >= 12)
{
// Have 12 bits of encoded message == 1 byte encoded
// Decode as 2 lots of 6 bits into 2 lots of 4 bits
// The 6 lsbits are the high nybble
this_byte1=vw_rx_bits & 0x3f;
this_byte=vw_symbol_6to4(this_byte1);
this_byte1=this_byte<<4;
this_byte=vw_rx_bits >> 6;
this_byte2=vw_symbol_6to4(this_byte);
this_byte=this_byte1|this_byte2;
// The first decoded byte is the byte count of the following message
// the count includes the byte count and the 2 trailing FCS bytes
// REVISIT: may also include the ACK flag at 0x40
if (vw_rx_len == 0)
{
// The first byte is the byte count
// Check it for sensibility. It cant be less than 4, since it
// includes the bytes count itself and the 2 byte FCS
vw_rx_count = this_byte;
if ((vw_rx_count < 4) || (vw_rx_count > 24))
{
// Stupid message length, drop the whole thing
vw_rx_active = 0;
return;
}
}
vw_tx_buf[vw_rx_len] = this_byte;
vw_rx_len++;
if (vw_rx_len >= vw_rx_count)
{
// Got all the bytes now
vw_rx_active = 0;
vw_rx_done = 1; // Better come get it before the next one starts
ddat=1;
}
vw_rx_bit_count = 0;
}
}
// Not in a message, see if we have a start symbol
else if (vw_rx_bits == 0xb38)
{
// Have start symbol, start collecting message
vw_rx_active = 1;
vw_rx_bit_count = 0;
vw_rx_len = 0;
vw_rx_done = 0; // Too bad if you missed the last message
}
}
}
int vw_have_message(void)
{
return vw_rx_done; //----if the data is ready vw_rx_done=1 see the above vw_pll program
}
//---------------------------------the beginning of the CRC check program
#define lo8(x) ((x)&0xff)
#define hi8(x) ((x)>>8)
uint16_t _crc_ccitt_update (uint16_t crc, uint8_t data)
{
data ^= lo8 (crc);
data ^= data << 4;
return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4)
^ ((uint16_t)data << 3));
}
uint16_t vw_crc(uint8_t *ptr, uint8_t count)
{
uint16_t crc = 0xffff;
while (count > 0)
{crc = _crc_ccitt_update(crc, *ptr++);
count--;}
return crc;
}
//---------------------------end of the CRC _check program
#int_Ext
void SII_RB0()
{
if(ddat==1)
{
vw_rx_sample=input_state(PIN_B0);//RB0 is the input_data_pin (vw_rx_sample);just we will read the
ddat=0; //first rising edge of the message
}
else return;
}
//----------------------every 200us we have an interrupt
//----------------------each bit is sampled eight time before the second bitcoming
#int_timer0
void timer0_isr(void)
{
TMR0+=-198;
vw_rx_sample=input_state(PIN_B0); //---input data
vw_pll(); //---call the function which decode the coming frame
}
void main(void)
{
int i=0;
uint16_t varr=0;
bit_clear(OPTION_REG,5); // T0CS=0
TMR0 = 50; //initial value of the timer0
Ext_int_edge(0,L_to_H);
enable_Interrupts(Int_Ext);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
ddat=1;
while(true)
{
if (vw_have_message())
{
varr=vw_crc(vw_tx_buf, vw_rx_len);
if(varr == 0xf0b8)
{
for (i=1; i <15; i++)
printf("%c",vw_tx_buf[i]);
}
vw_rx_done = 0;
printf("\r\n");
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
aydi
Joined: 11 Aug 2010 Posts: 12
|
|
Posted: Sun Mar 12, 2017 11:57 am |
|
|
[img]http://www.zimagez.com/zimage/schematic2.php[/img]
[url]<a href="http://www.zimagez.com/zimage/schematic2.php" target="_blank" title="Simulation_image1">schematic</a>[/url]
This is a direct link to the scanned screen. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Sun Mar 12, 2017 12:58 pm |
|
|
1st 'simulation'. If this is ISIS/Proteus , sorry can't help. it is well documented that it's a very,very unreliable 'simulator'.
2nd hardware. Are the rf devices rated for 5 volts? Some are some are not. I'm assuming the PIC is running at 5 volts?
3rd try the CCS C programs.....I showed one link to a pair, so there must be more....
Jay |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|