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 support@ccsinfo.com

problem with int32 type data transmission

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



Joined: 23 Apr 2008
Posts: 22

View user's profile Send private message

problem with int32 type data transmission
PostPosted: Thu May 01, 2008 7:41 am     Reply with quote

hi all;
i want to transmit int32 type data from pic to pic.

there're puts(),putc(),printf() RS232 comments but none of them is suitable.how can transmit and receive int32 type data?

thanks...
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Thu May 01, 2008 8:07 am     Reply with quote

RS232 only knows bytes. Any other data type must be converted to bytes to go through the UART. Look at make8() and make32().
_________________
The search for better is endless. Instead simply find very good and get the job done.
bittersweet



Joined: 23 Apr 2008
Posts: 22

View user's profile Send private message

PostPosted: Thu May 01, 2008 2:18 pm     Reply with quote

Hi again,
I achieved int 32 type data transmission with make8() make32() commands, but I have a new problem. when I transmit int32 type data, changeable values are being received.for ex. i transmit 6000 but i receive 1000.i couldn't synchronize transmitter and receiver.i don't know the length of delay after putc().

here's the codes:

Code:

// transmitter code:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay (clock=4000000)
#use rs232 (baud=2400, xmit=PIN_C6)

unsigned int16 tmrSayac= 0;
unsigned int32 ArabaVarZaman_ms = 0;
unsigned int32 ArabaYokZaman_ms = 0;
unsigned int1  arabaVar = true;
unsigned int   arabaSayac = 0;
unsigned int16 KontrolSuresi = 0;
unsigned int32 OrtYokZaman=0;
unsigned int32 OrtVarZaman=0;
unsigned int32 TopVarZaman=0;
unsigned int32 TopYokZaman=0;


void main()
{
   delay_ms(20);
   enable_interrupts(int_RB);
   enable_interrupts(int_timer1);
   enable_interrupts(int_timer0);
   enable_interrupts(global);

   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_CCP1(CCP_OFF);
   setup_CCP2(CCP_OFF);


   setup_timer_0(RTCC_internal | RTCC_div_256);
   set_timer0(0);

   setup_timer_1(T1_internal | T1_div_by_8);
   set_timer1(15535);

   set_tris_b(0x10);

   while(1)
   {if (KontrolSuresi>=500)

    {
     delay_ms(35);
     putc(make8(OrtVarZaman,0));
     delay_ms(35);
     putc(make8(OrtVarZaman,1));
     delay_ms(35);
     putc(make8(OrtVarZaman,2));
     delay_ms(35);
     putc(make8(OrtVarZaman,3));
     delay_ms(35);
     putc(arabaSayac);
     delay_ms(35);
    }
   }
}


#int_RB
void kesmeAltFonk()
{
   if(input(pin_b4))     
   {
       arabaVar = true;
       arabaSayac++;
       ArabaYokZaman_ms = ((tmrSayac * 500) + (get_timer1()*8-15535) / 100);  //ms cinsinden toplam geçen zaman
       TopYokZaman=ArabaYokZaman_ms+TopYokZaman;
       OrtYokZaman=TopYokZaman/arabaSayac;
       set_timer1(15535);
       tmrSayac = 0;

   }
   else 
   {
      arabaVar = false;
      ArabaVarZaman_ms = ((tmrSayac * 500) + (get_timer1()*8-15535) / 100);
      TopVarZaman=ArabaVarZaman_ms+TopVarZaman;
      OrtVarZaman=TopVarZaman/arabaSayac;
      set_timer1(15535);
      tmrSayac = 0;
   }
}

#int_timer1
void tmr1Kesme()
{
   tmrSayac++;

}



#int_timer0
void tmr0Kesme()
{
   KontrolSuresi++;

   if(KontrolSuresi>=600)
   {
      KontrolSuresi=0;

      set_timer0(0);
      OrtVarZaman=0;
      OrtYokZaman=0;
      arabaSayac=0;
   }
}





Code:

//Receiver code
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay (clock=4000000)
#use rs232 (baud=2400, rcv=PIN_C7)
#include <lcd.c>


unsigned int32 OrtVarZaman;

unsigned int v1;
unsigned int v2;
unsigned int v3;
unsigned int v4;

unsigned int arabasayisi;


void main()
{
   delay_ms(20);
   enable_interrupts(int_RB);
   enable_interrupts(int_timer1);
   enable_interrupts(int_timer0);
   enable_interrupts(global);

   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_CCP1(CCP_OFF);
   setup_CCP2(CCP_OFF);
   setup_timer_1(T1_DISABLED);

   lcd_init();

   while(1)
   {
    v1=getc();
    v2=getc();
    v3=getc();
    v4=getc();
    arabasayisi=getc();

    OrtVarZaman=make32(v4,v3,v2,v1);

    printf(lcd_putc,"\f OVZ=%ul",OrtVarZaman);
    delay_ms(1500);
    printf(lcd_putc,"\f Arabasayisi=%u",arabasayisi);
    delay_ms(1500);

   }
}



PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 01, 2008 2:35 pm     Reply with quote

See this thread which discusses problems with changing int16 or int32
global variables inside an interrupt service routine, and accessing them
as bytes outside of the interrupt routine. It also has solutions to it.
Follow the links.
http://www.ccsinfo.com/forum/viewtopic.php?t=32668

Code:
#use rs232 (baud=2400, xmit=PIN_C6)

#use rs232 (baud=2400, rcv=PIN_C7)

These two lines are creating software UARTs. That's not as good as
a hardware UART. If an interrupt occurs in the middle of a byte
(transmitted or received), it will be corrupted.
Change both of those lines to this:
Code:
#use rs232 (baud=2400, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

Then you will have a hardware UART, that is also protected against
locking up if there is a receiver overrun error.
bittersweet



Joined: 23 Apr 2008
Posts: 22

View user's profile Send private message

PostPosted: Thu May 01, 2008 4:20 pm     Reply with quote

i tried
Code:

#use rs232 (baud=2400, xmit=PIN_C6, rcv=PIN_C7, ERRORS)


but the problem couldn't been solved...if u can help me, i'll be satisfied...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 01, 2008 4:28 pm     Reply with quote

But what about this part:

See this thread which discusses problems with changing int16 or int32
global variables inside an interrupt service routine, and accessing them
as bytes outside of the interrupt routine. It also has solutions to it.
Follow the links.
http://www.ccsinfo.com/forum/viewtopic.php?t=32668
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Thu May 01, 2008 5:28 pm     Reply with quote

You have a fundamental problem of synchronization. If you start off synchronized and if the receiver processes every character that is sent by the transmitter, then you will stay synchronized. But there is no way to get synchronized if you are ever out of synchronization. And your receiver, the way it is written, cannot keep up with all the data that is being transmitted, because of the LCD stuff, so it will always lose synchronization.

Why do you have delay_ms(35); after every character in the transmitter? The receiver is perfectly capable of receiving 5 bytes at full speed, the way you have written the receiver code. If you want to have a delay, put a single delay after all 5 bytes have been sent. That is when your receiver takes more time. Currently there is a 70 msec. total delay between the last byte of one packet and the first byte of the next packet. This is clearly not long enough if you want to allow the receiver to receive everything. Your receiver code has at least 3000 msec. of delay that I can see. During that time, your transmitter has sent many many packets that you have missed. It is no wonder that you are losing synchronization.

Here is what I suggest: You can keep the transmitter the way it is, except you can eliminate the unnecessary delay_ms(35), and just put a single delay_ms(80) after the last byte. Your are going to miss lots of data in the receiver. That is just the way it goes. But after the receiver processes a packet, it should re-acquire synchronization by reading bytes and measuring the time between bytes received. Throw away all bytes you receive until you find two bytes that are more than 60 msec. apart. Then take the second of those two bytes as v1 and keep going from there.

Robert Scott
Real-Time Specialties
bittersweet



Joined: 23 Apr 2008
Posts: 22

View user's profile Send private message

PostPosted: Fri May 02, 2008 2:13 am     Reply with quote

first, i eliminated delay_ms(35) and put a single delay_ms(80) after sending 5 bytes...but the problem is still going on.also, i couldn't understand
Quote:

Throw away all bytes you receive until you find two bytes that are more than 60 msec. apart. Then take the second of those two bytes as v1 and keep going from there.


when i simulate the program,i sent OVZ=4000 and ArabaSayisi=1.
but i received first OVZ=2440 and ArabaSayisi=1, then OVZ=256 and ArabaSayisi=192...i have to see only one OVZ and ArabaSayisi...
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Fri May 02, 2008 9:00 am     Reply with quote

bittersweet wrote:
.. i couldn't understand
Quote:

Throw away all bytes you receive until you find two bytes that are more than 60 msec. apart. Then take the second of those two bytes as v1 and keep going from there.


If you want to re-acquire synchronization after missing a lot of characters, then you have to detect that 80 msec. pause somehow. You must use a timer or some other means to measure the time between the arrival of characters at the receiver. Then you will know when you are seeing the 80 msec. gap, and then you can start receiving the next 5-byte packet.

Again, by the time your receiver is ready to read another 5 bytes, many many bytes have already come and have been ignored because you weren't reading while you were writing to the LCD. So the next byte that the receiver reads is probably not going to be the beginning of a 5-byte packet. That is why you need to discard characters in the receiver code until you find the first character of a 5-byte packet, and the only way to do that is by measuring timing, unless you totally re-define how you are sending data so that each packet starts with a unique byte that cannot appear anywhere in the data.

Robert Scott
Real-Time Specialties
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Fri May 02, 2008 9:07 am     Reply with quote

For example the NEMA strings that most GPS units send always start with $, and that is the only place $ is used. So the receiving software can start by throwing away characters until it finds the $ and then it knows it is at the start of a new GPS message.
_________________
The search for better is endless. Instead simply find very good and get the job done.
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