CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

send and receive with virtual wire library for PIC16F628A

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
aydi



Joined: 11 Aug 2010
Posts: 12

View user's profile Send private message

send and receive with virtual wire library for PIC16F628A
PostPosted: Sun Mar 12, 2017 4:20 am     Reply with quote

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);
   }
   
}
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 12, 2017 5:22 am     Reply with quote

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
aydi



Joined: 11 Aug 2010
Posts: 12

View user's profile Send private message

PostPosted: Sun Mar 12, 2017 5:38 am     Reply with quote

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);
         
      }
       
   }
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 12, 2017 6:02 am     Reply with quote

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
aydi



Joined: 11 Aug 2010
Posts: 12

View user's profile Send private message

PostPosted: Sun Mar 12, 2017 11:54 am     Reply with quote

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");
        }
         
      }
       
   }
aydi



Joined: 11 Aug 2010
Posts: 12

View user's profile Send private message

PostPosted: Sun Mar 12, 2017 11:57 am     Reply with quote

[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.
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Mar 12, 2017 12:58 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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