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

Sending "packets" using RS-232, is this a good ide

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



Joined: 13 Oct 2007
Posts: 53
Location: Texas

View user's profile Send private message Visit poster's website Yahoo Messenger

Sending "packets" using RS-232, is this a good ide
PostPosted: Wed Aug 18, 2010 6:18 pm     Reply with quote

Hello thanks for all your previous help !

I'm trying to send out tons of data from the pic over a wireless transceiver to another wireless transceiver. Since the data is always pretty much the same I have developed a packet format. I take the data in on the non pic side using C# software that I have created.

Anyway I don't want to convolute the question with too many details.

When I do something like
Code:

unsigned byte test = 0xFF;
printf("%c",test);


Q1:
Does it convert the byte into a char and then send it out? Or does it see that its not in the "char" range and do something else ?

I know I can use "%x" but then I end up sending out two bytes where I only need to send out one. Because 0b11111111 is one byte and 255 decimal or 0xFF hex but if i use the %x then I'm sending out 2 chars which is 16 bits, I don't want to send out twice as much data as i need to !

Q2:
Mainly I'm trying to send 8 bit ADC conversion data, what would be the best way to send this over the UART ? That is what is the best way to send values 0-255 decimal by transmitting only 8 bits of data (plus parity or whatever small overhead rs-232 has).

Thanks, I've been wrestling with this for a while. Just trying to regroup my thoughts and make sure I haven't over/under thought it before I continue.
_________________
Smart people know how stupid they are.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 18, 2010 7:33 pm     Reply with quote

Make a test program and look at the .LST file. What does the following
code do ? It moves 'test' into the W register. Then it waits in a polling
loop, while testing for the TXIF flag to go high. Then it puts the data into
the TXREG, which lets the UART send it out. So, it doesn't change the
value in 'test' before it sends it.
Code:

.................... unsigned byte test = 0xFF; 
.................... 
.................... printf("%c",test); 
0026:  MOVF   test,W
0028:  BTFSS  PIR1.TXIF
002A:  BRA    0028
002C:  MOVWF  TXREG

I compiled this for an 18F452.
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

Re: Sending "packets" using RS-232, is this a good
PostPosted: Wed Aug 18, 2010 8:56 pm     Reply with quote

zonemikel wrote:
Hello thanks for all your previous help !

I'm trying to send out tons of data from the pic over a wireless transceiver to another wireless transceiver....


You can send binary unstructured data or you can send structured data. It really depends on the type of data you are sending and what you want to do in the event of packet loss/corruption, what you mean by "tons of data", the data rate of your wireless link, the reliability of the wireless link and the spare capacity of the link actual bytes per second in versus the baud rate of the link.

If you have a fixed length packet format then you could use a message start delimiter, a fixed length payload, a CRC or other form of payload validation and an end of message delimiter. With this approach you can have the start and end delimiters also embedded in the payload providing your parsing logic was able to resync on false start/end of the message detection.

Two variants on this would be to support a variable length payload by incorporation a length field and another is to use escape processing when if you detect a start or end delimited in the message you immediately prepend it with a escape delimiter which could be the start or end delimited or another character which must also be delimited.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
zonemikel



Joined: 13 Oct 2007
Posts: 53
Location: Texas

View user's profile Send private message Visit poster's website Yahoo Messenger

PostPosted: Wed Aug 18, 2010 10:08 pm     Reply with quote

I made up a packet structure in which it was like

receiver|sender|flags|number|data|CRC

except for the data all those are one byte (at least thats the plan so far) the data will contain bytes also but it will be a few of them holding some ADC values. They are fixed length packets.

On the receiving end i check for the first two bytes before I even start to read the rest of the "packet", in this way you could have multiple devices and senders/receivers (in theroy!).

I'm able to transmit at 19200 baud, and I cant change that.

Its working pretty well so far, I just wanted to be sure I was not setting myself up for failure later. I thought maybe by sending it through printf or putc I was appending something to the data, kind of like the actual byte 1 is 0b00000001 but you can append a 11 to the right side to make it a char 0b11000001.

But as pcmProg pointed out thats not the case (I think thats what you said) but just to be clear when i send 0b00000001 for example
printf("%c", '0x01');
can i expect to receive '0x01' on the other end or '0x31' which is the char '1' thats where my confusion lies.

I know, I know just make a test program. I'll do it tomorrow.

Thanks guys ! If I get something good I'll post it in here for others to use, got a ways to go before that.
_________________
Smart people know how stupid they are.
MikeW



Joined: 15 Sep 2003
Posts: 184
Location: Warrington UK

View user's profile Send private message

PostPosted: Thu Aug 19, 2010 12:21 am     Reply with quote

I did a similar thing years ago, but I also added a messagenumber, which was simply an incrementing number from the previous message, so it started at 0-255 and rolled over.

That way when you do the error checking and resending etc, you don't mistake the resend for a new message.

Your flags byte is just a part of the data bytes, so you don't need to highlight it in the basic format, better to define that in the data byte format.

startof packet|receiver|sender|messagenumber|numberofdatabytes|data|CRC|end of packet

Start of packet is typically STX, end of packet is ETX characters.

Also, you will need to check every character going out for STX and ETX in the stream, and if found send it twice, and of course remove it at the other end, to enable those characters to not be interpreted as real STX or ETX (its called byte stuffing).

Hope thats clear.

The main thing is to try to think of all possible errors, and cater for them.

Mike


Last edited by MikeW on Thu Aug 19, 2010 1:06 am; edited 1 time in total
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Aug 19, 2010 12:58 am     Reply with quote

MikeW wrote:
(its called bit stuffing).


It is called byte stuffing. Bit stuffing is a lower level mechanism used by some link layer protocols.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
zonemikel



Joined: 13 Oct 2007
Posts: 53
Location: Texas

View user's profile Send private message Visit poster's website Yahoo Messenger

PostPosted: Thu Aug 19, 2010 7:33 am     Reply with quote

Quote:
The main thing is to try to think of all possible errors, and cater for them.


oh is that all ! Wink

The flags are not part of the header so I see why you say they could be part of the "data", its just that the "data" is just a few chars/bytes anyway and each one is explicitly defined. My "data" consists of about 6 different bytes from different ADC conversions. The flag on the incoming packet tells the pic which adc conversions to send in the outgoing packet.

I'll see how far I can get today.
_________________
Smart people know how stupid they are.
zonemikel



Joined: 13 Oct 2007
Posts: 53
Location: Texas

View user's profile Send private message Visit poster's website Yahoo Messenger

Finally found out whats wrong !!!
PostPosted: Thu Aug 19, 2010 2:04 pm     Reply with quote

well after ripping my hair out all morning i finally found out what is going wrong.

I made the pic parrot back the packet from the computer, everything works Great except . . . as soon as we get to any values higher than 0x3F the pic stays stuck at 0x3F or even seems to flood over into the next var.

so if i send the packet (in hex separated by '.'s)
31.31.80.73.00.00.00.
i get back from the pic
31.31.3F.3F.00.00.00.

3F just happens to be 0b00111111 so that must have some thing to do with it. I've tried unsigned char, char and unsigned int8 they all seem to do the same thing.

Code:

// the variables
   #define incPKT_sz 8          // incoming packet size
   #define outPKT_sz 8          // outgoing packet size
   char incPKT[incPKT_sz];       // x byte incoming packet
   char outPKT[outPKT_sz];       // x byte outgoing packet
   int8 pktIndex = 0;            // packet index (see interrupt RDA)

// the part that stores the packet
#int_rda
void serial_isr() {
   incPKT[pktIndex] = fgetc(wireless);

   // if it is for us then start filling buffer, else we stay at 0
   if(pktIndex == 0 && incPKT[pktIndex] == ID){
      pktIndex++;}
   // if it is from the server we want to lisetn too then continue
   else if(pktIndex == 1 && incPKT[pktIndex] == serverID){
      pktIndex++; }
   // if its for us from the guy we want to listen too get it !
   else if(pktIndex < incPKT_sz && pktIndex > 1){
      pktIndex++; }
   // if we are on 63 we have received 64 bytes our packet is done
   else if(pktIndex >= incPKT_sz){
      state = NEWPACKET;       // set new packet to 1 so we process the packet
      if(pktCount < 255){pktCount++;}else{pktCount = 0;} // int8 max = 255
      pktIndex = 0;     // reset our index
   }else{
      pktIndex = 0;     // first two bytes were incorrect, start over
   }// end if
}

// the part that sends the packet back (note its the same as the rx'ed packet)
void sendPacket(int1 increment){       // send the packet out
   if(increment && pktCount < 255){                      // if they want to increment the pkt cnt
      pktCount++;                      // increment it
      outPKT[3] = pktCount;            // update packet
   } else if(increment){
      pktCount = 0;                     // 0 it
      outPKT[3] = pktCount;            // update packet
   }
     
   for(i=0; i <= outPKT_sz; i++){
      putc(incPKT[i], wireless);
   }
}



Anyone know whats going on ? i guess for testing i'll try and limit my values to less than 64, but thats why my ADC values are coming back weird .. i was wondering why the hell they were all 3F i thought the error was elsewhere.

thanks !
_________________
Smart people know how stupid they are.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 19, 2010 2:52 pm     Reply with quote

I would test it with a much more simple echo program.
Try something like this:
Code:

#include <16F877.H>
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//====================================
void main()
{
char c;

while(1)
  {
   c = getc();
   putc(c);
  }

}
zonemikel



Joined: 13 Oct 2007
Posts: 53
Location: Texas

View user's profile Send private message Visit poster's website Yahoo Messenger

PostPosted: Thu Aug 19, 2010 5:18 pm     Reply with quote

Well this is weird !!! Sometimes it does and sometimes it does not.

This is my code (all of it), I'm on a 16F887.
Code:

#include <16F887.h>        // basic header for this pic
#device adc=8              // adc of 8 bits so 0=0v 256=vref(5v?)

// fuses, if brownout at 4v when we turn on motors we get brownout
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP, BORV21
#use delay(clock=4000000)  // 4MHz clock

#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,STOP=1)

unsigned char test = 0;

void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   //Setup_Oscillator parameter not selected from Intr Oscillotar Config tab
   
   // TODO: USER CODE!!
   while(1){
   delay_ms(500);
   printf("11");
   putc('\x3F');
   putc('\x4F');
   putc(test);
   putc(test);
   putc(test);
   putc(test);
   test++; 
   }

}

It seems to count past 0x3F then kind of get stuck on it later on
31.31.3F.4F.3F.3F.3F.
In fact it counts to 7F then stays on 3F for a while longer then if you wait long enough it will start counting from 0 again ?

I'm lost as to why it would do that, maybe I partially burnt up my pic and its causing this erratic behavior.
_________________
Smart people know how stupid they are.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 19, 2010 5:40 pm     Reply with quote

Quote:
31.31.3F.4F.3F.3F.3F.

What device and/or program are you using to receive and display this data ?
Also your data above has dots (periods) in it. I don't see anything in
your test program that sends those characters.
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Thu Aug 19, 2010 6:14 pm     Reply with quote

Also check the Data Bits and the Stop Bit configuration -must be 8 and 1 respectively- of the "device and/or
program are you using to receive and display the data".
zonemikel



Joined: 13 Oct 2007
Posts: 53
Location: Texas

View user's profile Send private message Visit poster's website Yahoo Messenger

PostPosted: Thu Aug 19, 2010 7:43 pm     Reply with quote

Quote:
What device and/or program are you using to receive and display this data ?
Also your data above has dots (periods) in it. I don't see anything in
your test program that sends those characters.


I'm using my own c# program. It counts all the way to 7F and then all of them go to 3F for a period (im sure the rest of the increments to FF) and then it starts again at 0x00. I add the dots in with my c# program to make things more clear. My program displays 80 and FF in hex just fine i know that for sure because of other variables it is displaying using the same functions.

I'll modify the test program to send chars 0xFF and before that to see if its my c# program mangling up the data.

Besides that I made sure all my flags/vars etc were below 3F and everything is working great.
_________________
Smart people know how stupid they are.
zonemikel



Joined: 13 Oct 2007
Posts: 53
Location: Texas

View user's profile Send private message Visit poster's website Yahoo Messenger

PostPosted: Tue Aug 24, 2010 4:06 pm     Reply with quote

Finally found out what was wrong.

In my receiving c# program I was using ascii encoding which only supports 127 chars.

I tried switching to UTF8 and unicode but they still seem to have problems understanding whats coming out of the pic.

I also tried using LONG_DATA, but I'm not sure if thats what I'm supposed to do. It does not seem to help.

I think i should be using UTF8. I would hate to have to doctor the chars coming out of the pic and have 50% overhead just so that c# gets a 16bit char.

Anyone else run into these types of problems ?

EDIT ------------- UPDATE

I'll just edit so I dont bump, but i do want closure to this thread. I ended up using encoding.UTF8 and it works. Not really sure where I was going wrong, I think it was in using strings so I could do .indexOf stuff. Anyway Use bytes for your buffers and such.

Anyone who does this later, use UTF8 encoding not ASCII. Unless you only want 127 values. If your returning a readADC thats 8 bit and its value is anywhere above 127 C# would return 127 if you have ascii encoding (which is default).

Yet again it was a C# problem not a Pic or C problem. I find that with all the "wonderful" intellisence and dot operators its really hard to find out whats really going on sometimes.
_________________
Smart people know how stupid they are.
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