| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| bittersweet 
 
 
 Joined: 23 Apr 2008
 Posts: 22
 
 
 
			    
 
 | 
			
				| problem with int32 type data transmission |  
				|  Posted: Thu May 01, 2008 7:41 am |   |  
				| 
 |  
				| 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
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu May 01, 2008 8:07 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu May 01, 2008 2:18 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu May 01, 2008 2:35 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu May 01, 2008 4:20 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu May 01, 2008 4:28 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu May 01, 2008 5:28 pm |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri May 02, 2008 2:13 am |   |  
				| 
 |  
				| 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
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri May 02, 2008 9:00 am |   |  
				| 
 |  
				|  	  | 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
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Fri May 02, 2008 9:07 am |   |  
				| 
 |  
				| 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.
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |