RS232 Parity Bits

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 2 and 3.

Moderators: Benj, Mods

Post Reply
PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

RS232 Parity Bits

Post by PINTO »

Hi Mark,

Does the RS232 support the "Even and Odd" Parity bits?

How can I change the Parity?

If I use None and set Hyperterminal to none works Ok, but if I change Hyperterminal to Odd or Even doesn't work.

Any Help?

Thanks


Pinto

Mark
Posts: 209
Joined: Thu Oct 19, 2006 11:46 am
Location: Bakewell, UK
Has thanked: 20 times
Been thanked: 16 times
Contact:

Post by Mark »

Hi Pinto,

Whilst the PIC chips can be used to generate parity bits Flowcode does not. Flowcode outputs a start bit, an 8 bit value and a stop bit, but for reception purposes one or two stop bits make little difference.

If you need parity then you will need to generate a C-code routine to calculate the parity bit and add it into the USART code.

The USARTis explained well here :

http://ww1.microchip.com/downloads/en/D ... /usart.pdf

and if you read the boost C manual

http://www.sourceboost.com/Products/Boo ... boostc.pdf

there are in built commands to make it all that much easier.


However, I have found that unless you are forced to use parity or hardware handshaking then, by keeping at 9600 baud comms are effective and error free for PIC to PC communications. Bear in mind that handshaking and parity are there for bulk communications over long distances, the contents of a PIC rarely approach these limits. Further handsaking can led to timing problems and hang ups, just set a large buffer to catch all the data (not relevant to Hyperterminal).

So unless you need to, just use the RS232 component and set Hyperterminal to : no hardware flow control (i.e. no handshaking) (Connect to -> Configure -> = menu)and in 'Append line feeds to line ends' (ASCII setup = menu) plus of course the correct baud rate (sam page as nhfc eg 9600, 8, none, 1, ).

Hope this helps,

Mark

Steve, do you agree?
Go with the Flow.

PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

Post by PINTO »

Hello Mark,

Thanks for the info.
I read both documents that you suggested but I'm still in the dark!!!

I need to send 2 bites to a Pc running comm's @ Baud Rate 300bps, Parity EVEN, Stop Bits 1, No Handshaking.

The reason for the 300bps Baud rate is that the Pc is running an old network of sensors to a distance of about 3Km.

What we want to do is to test a new driver on the network running on a different PC.

The original driver has a polling cycle of 40 seconds and only uses 8 seconds the remaining 32 seconds is inactive.

What we are doing is transfering the network to the second pc for 20 seconds as soon as the original Pc has stopped polling.

In order to prevent the SCADA System from graying out the tab's when the network is handed over to the original Pc we have to send a code to the second Pc to make the SCADA System think that the comm's are still Ok.

Al of the above works Ok except that the second Pc is not reading the correct code that the Pic is sedding because of the Parity bit setting.

If you could be a bit more specific of were and how to set the parity bit either by using a C rotine or and preferable on the compiler settings I would appreciate.

Please bear in mind that I only started using FlowCode (partime) about 2 months ago and have no progaming experience, apart from basics.

Thank you


Pinto

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hello Pinto

This will allow you to send and receieve RS232 code using even parity. The baud rate will be 300 assuming that a crystal speed of 4MHz is used.

Add the following code to the supplementary code window available from the Edit menu.

Definitions and Function Declerations

Code: Select all

char ReceiveRS232Char(char timeout);
void SendRS232Char(char Char, char Parity);
Function Implementations

Code: Select all

void SendRS232Char(char Char, char Parity)
{
	    //GetSendRS232CharCode
	#define fc_rsSTATUS_LOOP      0
	#define fc_rsSTATUS_TIMEOUT   1
	#define fc_rsSTATUS_RXBYTE    2
	   set_bit(txsta, TXEN);
	   while ((pir1 & (1<< TXIF)) == 0);
                   txsta.TX9D = Parity;
	   txreg = Char; 
}

char ReceiveRS232Char(char timeout)
{
	    //GetReceiveRS232CharCode
	#define fc_rsSTATUS_LOOP      0
	#define fc_rsSTATUS_TIMEOUT   1
	#define fc_rsSTATUS_RXBYTE    2
	   char delay1 = 0;
	   char delay2 = 0;
	   char dummy = 0;
	   char retVal = 255;
	   char bWaitForever = 0;
	   char rxStatus = fc_rsSTATUS_LOOP;
	   if (timeout == 255)
	   {
	       bWaitForever = 1;
	   }

	   set_bit(rcsta, CREN);

	   while (rxStatus == fc_rsSTATUS_LOOP)
	   {
	       if ((pir1 & (1 << RCIF)) != 0)
	       {
	           //received a Char
	           rxStatus = fc_rsSTATUS_RXBYTE;
	       } else {
	           if (bWaitForever == 0)
	           {
	               //don't wait forever, so do timeout thing...
	               if (timeout == 0)
	               {
	                   rxStatus = fc_rsSTATUS_TIMEOUT;
	                   #ifdef fc_rs232_debug
	                       //FCD_RS2320_SendRS232Char('<');
	                       //FCD_RS2320_SendRS232Char('t');
	                       //FCD_RS2320_SendRS232Char('i');
	                       //FCD_RS2320_SendRS232Char('m');
	                       //FCD_RS2320_SendRS232Char('e');
	                       //FCD_RS2320_SendRS232Char('o');
	                       //FCD_RS2320_SendRS232Char('u');
	                       //FCD_RS2320_SendRS232Char('t');
	                       //FCD_RS2320_SendRS232Char('>');
	                   #endif
	               } else {
	                   //decrement timeout
	                   delay1--;
	                   if (delay1 == 0)
	                   {
	                           timeout--;
	                   }
	               }
	           }
	       }
	   }

	   if (rxStatus == fc_rsSTATUS_RXBYTE)
	   {
	       if ((rcsta & (1 <<FERR)) != 0)
	       {
	           dummy = rcreg;      //need to read the rcreg to clear FERR
	           #ifdef fc_rs232_debug
	               FCD_RS2320_SendRS232Char('<');
	               FCD_RS2320_SendRS232Char('F');
	               FCD_RS2320_SendRS232Char('E');
	               FCD_RS2320_SendRS232Char('R');
	               FCD_RS2320_SendRS232Char('R');
	               FCD_RS2320_SendRS232Char('>');
	           #endif
	       } else {
	       if ((rcsta & (1 << OERR)) != 0)
	           {
	               //need to read the rcreg to clear error
	               clear_bit(rcsta, CREN);
	               set_bit(rcsta, CREN);
	               #ifdef fc_rs232_debug
	                   FCD_RS2320_SendRS232Char('<');
	                   FCD_RS2320_SendRS232Char('O');
	                   FCD_RS2320_SendRS232Char('E');
	                   FCD_RS2320_SendRS232Char('R');
	                   FCD_RS2320_SendRS232Char('R');
	                   FCD_RS2320_SendRS232Char('>');
	               #endif
	           } else {
	               retVal = rcreg; //no error, so rx byte is valid
	               #ifdef fc_rs232_echo
	                   FCD_RS2320_SendRS232Char(retVal);
	               #endif
	           }
	       }
	   }
	   return (retVal);
}
Then using a C code block add the following code to the beginning of your program

Code: Select all

txsta = 0; // 8-bit, async, low speed, off
txsta.TX9 = 1; //enable 9th tx bit
spbrg = 207; // set the baud rate
rcsta = 0;              // 8-bit, disabled
rcsta.RX9 = 1; //enable 9th rx bit
set_bit(rcsta, SPEN);   // turn on serial interface
You can then send data from the PICmicro with a C code code block and the following flowcode byte variables : Data, Parity

Code: Select all

SendRS232Char(FCV_DATA, FCV_PARITY);

User avatar
Steve
Matrix Staff
Posts: 3426
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Post by Steve »

Hello Pinto,

Unfortunately, the RS232 component as it stands does not allow you to have parity. You would need to implement your own C code to do this and embed it into your Flowcode program.

It is a feature I will add to the list of Flowcode improvements, as it will add useful functionality, but I don't anticipate that we will implement it soon.

You will need to calculate the parity from the bits yourself, and set the TX9D bit of the <txsta> register to this parity bit. You will also need to set up this register to send 9-bits of data by setting the TX9 bit to 1.

It should be relatively simple to modify a Flowcode program to do this for you.

You would need to calculate the parity bit and set or clear the TX9D bit of the txsta register to this appropriate parity - do this just before you send a byte using the "SendRS232" macro.

You will also need to add the following extra initialisation code for the RS232 component (put the following into a C icon at the beginning of your "main" flowchart):

Code: Select all

set_bit(txsta, TX9);
I've not tried this, but it should work. Calculating the parity bit will be a relatively tricky exercise for a novice programmer - perhaps someone else can help here...

PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

Post by PINTO »

Hi Benj,

Thanks for your help so far.

Could you explain the last bit of your program?
eg.
You can then send data from the PICmicro with a C code code block and the following flowcode byte variables : Data, Parity
Code:
SendRS232Char(FCV_DATA, FCV_PARITY);

Say for instance I would like to send h81 h00 (Device Adress)followd by h3D hFB (Dummy Data). Were the Parity bit fit?

Thank You


Pinto

Thanks to Steve as well for his bit but didn't seem to make any difference on the way that the code compiled?

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hello Pinto

The parity calculation is fairly tricky so instead of working out all the code I have just allowed it to be input by hand so for example.

Data to be sent
h81 h00 h3D hFB

C code Block

Code: Select all

SendRS232Char(0x81, 0); //Number is odd 
SendRS232Char(0x00, 1); //Number is even 
SendRS232Char(0x3D, 0); //Number is odd 
SendRS232Char(0xFB, 0); //Number is odd
The code to work out the parity might look something like this

1) Take the number being sent and half it
2) If you have a whole number or the two halves are equal then even parity = 1 / odd parity = 0
3) If you have a fraction or the two halves are different then even parity = 0 / odd parity = 1

To use flowcode variables in a C code block you need to capitalise the name and add FCV_ to the beginning.

Eg. Variable "count" becomes "FCV_COUNT"

Mark
Posts: 209
Joined: Thu Oct 19, 2006 11:46 am
Location: Bakewell, UK
Has thanked: 20 times
Been thanked: 16 times
Contact:

Calculating Parity

Post by Mark »

As Benj says calculating parity needs some though. However, the method is directed to binary math and not decimal math. Hence, when, translated into binary manipulation the whole thing is more simple.

Hence, try this link :

http://www.piclist.com/techref/microchi ... parity.htm

Hope this helps,

Mark
Go with the Flow.

PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

Post by PINTO »

Thanks Guys,

Impressive stuff, I mean the service.

I would buy FlowCode over again for this kind of service, (I've read other postings).

Anyway I've tried Benj and Steven's suggestions and I stickked with Steven's it's simpler for what I want to do (no offence to you Benj).

I would like to thank Mark as well for his info.

Keep it up


Pinto

User avatar
Steve
Matrix Staff
Posts: 3426
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Post by Steve »

Thanks for your kind words, Pinto. And I'll notch that one up as a point to me!

PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

Post by PINTO »

Good morning Benj,

I'm now one step up and experimenting with your code.

I can send code eg.

Code: Select all

SendRS232Char(0x81, 0); //Number is odd
.
But when I try to receive eg

Code: Select all

ReceiveRS232Char
than the compiler reports the followig:
J:\A Master Slave Pc\FlowCode\ENV_TX.c(198:18): error: arguments of 'ReceiveRS232Char' don't match the parameters of call
J:\A Master Slave Pc\FlowCode\ENV_TX.c(198:2): error: failed to generate expression
J:\A Master Slave Pc\FlowCode\ENV_TX.c(199:18): error: arguments of 'ReceiveRS232Char' don't match the parameters of call
J:\A Master Slave Pc\FlowCode\ENV_TX.c(199:2): error: failed to generate expression
ENV_TX.c success

failure

Return code = 1

Flowcode was unable to compile the flowchart's C code due to the following errors:


If your flowchart contains C code, please review this carefully. If your flowchart contains no C-code or you have thoroughly reviewed the code, contact Technical Support.

FINISHED
I want to compare the received code with the station ID eg.

If the master sends 0X81 0X00 (Slave ID) and I've the number 0X81 0X00 preset on the slave I want the slave to respond by sendding 0X3D 0xFB.

I'm not sure how to setup the variables in flow code to compare the two numbers?

Could you help?

A bit furstrating at times but I'm getting there.


Thanks



Pinto

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hello Pinto

To call the RS232 Receive function you need a line of C code like this.

Code: Select all

FCV_RX =  ReceiveRS232Char(255); //Stores RS232 Char into variable rx
To compare two numbers you can use a descision flowchart symbol with

rx = temp

Where rx is the received RS232 char
and temp is a pre stored variable

Or you can use a C Code Block with the same variables as follows

Code: Select all

if (FCV_RX == FCV_TEMP)
{
                //They are equal
}
else
{
                //They are not equal
}

PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

Post by PINTO »

Hi Benj,

Thanks for your help but once again I need ti pick your brain.....
I've wrote the flowcode program with the code as per your suggestions and compiled it and run it on my simulator and worked ok.
I've 4 PIC's 16F628 running and communicating with each other and simulate ok but when I program the code into the actual PIC the program hangs. If I remove the C code Box

Code: Select all

FCV_RX =  ReceiveRS232Char(255); //Stores RS232 Char into variable rx
from the program the PIC works and process the rest of the logic without hanging eg. the interrupt IRB0 works and the rest of the IO works as well.
How does the PIC know that is to receive code?
I would like to send you the flowcode program and if have a minute to have a look at it you may be able to spot the problem, rather than trying to explaining it in words.

Thanks




Pinto

PINTO
Flowcode v5 User
Posts: 71
Joined: Fri Nov 03, 2006 2:28 pm
Location: RSA
Been thanked: 1 time
Contact:

Changing numbers of bits from 8 to 7

Post by PINTO »

Hello Ben.

I need your help once again.

I do I change the number of bits from 8 to 7 on your example.

The rest of the protocol remains the same.

Regards


Pinto

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Post by Benj »

Hello Pinto

The example I gave is useing the hardware UART which can either be set to use 8 or 9 bits. Therefore you cannot use 7 bits unless you use a bit banging method. What I suggest is that you keep the routine the same and just use 7 of the bits on the receivers. eg if the byte is < 128 then you know the most significant bit is clear. then if you want to send an instruction byte or simthing different you can check if the byte is > 127 which will mean the MSb is set.

Post Reply