Comms Problems - RS232

For questions and comments on programming in general. And for any items that don't fit into the forums below.

Moderators: Benj, Mods

Post Reply
mmaguire
Posts: 9
Joined: Wed Dec 09, 2009 11:40 pm

Comms Problems - RS232

Post by mmaguire »

Hi
I am having difficulty getting good communications via rs232 components and 2 industrial RDID readers

- Chip 18f2620 - 20MHz - Config File attached
- problem - want to read two readers - so using hardware Rx/Tx on C7/C6 and software rs232 on C4/C5
- Hardware checked with oscilloscope - right signals to right pins!
-Have got the hardware working (baud rate on readers is high - 115200 &not changeable) but software component dropped into the same functioning senario doesn't work.
- Set time out to 255 (for ever) and below this to no avail
-Attached reader program- (also this simulates correctly but appears to calculate the check_bit incorrectly with live data.

Will the software RS232 component operate at 115200? should I up my processor speed to 40MHz - permittted on 18F2620

Any help appreciated -

Mick
Attachments
Raw_Data.txt
Sample of reader data (here in blochs of 16 bytes (hex) words are 15 bytes from header to Check_bit (Xor preceeding 14 bits)
(68.71 KiB) Downloaded 341 times
Config1.TXT
Configuration
(4.25 KiB) Downloaded 324 times
Supervisor_Rev8.4_CommSuccess.fcf
RFID Reader File
(16.48 KiB) Downloaded 371 times

Sean
Valued Contributor
Valued Contributor
Posts: 548
Joined: Tue Jun 26, 2007 11:23 am
Has thanked: 6 times
Been thanked: 44 times

Re: Comms Problems - RS232

Post by Sean »

Hello,

115200 is outside the range of Baud rates considered for the software implementation of the RS232 component.

The RS232 component calculates the delays used in the C code to maintain timing accuracy for the tx and rx macros. These are based on a range of standard clock frequencies and Baudrates around 4800 to 19200.

It might be possible to manually set a software delay value that will operate at the required Baud rate and clock frequency. Especially if you have access to an oscilloscope.

The calculated delay value is passed to the component as the parameter %r. This can be accessed using the 'Custom Code' facility in the 'Properties panel':

Select the software RS232 component on the panel and click on the three dots '...' next to the 'Custom Code' option on the 'Properties Panel'. This will open the 'Customize Component Code' panel.

Select the '[Defines]' macro and click on the 'Edit Code' button. This will open the 'Edit Custom Code' panel containing the relevant code from the RS232 component.

A section of code headed '#if (%m_UART == 0)' contains the required software Baud rate delay definition (starting at line 53 approximately).

The line '#define %m_SW_BAUD %r' can be edited to replace %r with a constant value (suggest starting at 10).

Use a test program to transmit bytes of data that will show the Baud rate being generated on an oscilloscope (data = 0x55), and re-edit the constant value until the Baud rate correct. The same timing is used by the receive macro.

Using a higher chip clock frequency will allow a larger delay value to be used, also allowing a finer adjustment resolution.

mmaguire
Posts: 9
Joined: Wed Dec 09, 2009 11:40 pm

Re: Comms Problems - RS232

Post by mmaguire »

Thank you for this avenue Sean, Will revert when I get it working (or not!)!

Mick

mmaguire
Posts: 9
Joined: Wed Dec 09, 2009 11:40 pm

Re: Comms Problems - RS232

Post by mmaguire »

Sean,
I have had some success with this by increasing clock reequency to 40MHz oscillator and using the scope. The %rvalue - 5 -was nearest to the 8.7e-6 (115200kbs) needed. Notwithstanding getting close to this figure - when transmitting 0x55 as suggested an artifact was present on the scope trace - namely a variation in period of a couple of % - when triggered at 50% of value - it appeared as 1 rising edge - and approximate equat mark/space three three falling edges - its quite reproducable!!

Comms were hit and miss with this arrangement - with very high error rate - so I took another tack

I culled some code from the net for a software uart and knocked it into shape implementing it as supplementary code: It compiles fine and on the send routine seems to offer seemingly greater resolution on the length of the bitdelay (0x12) - guess what, a more limited version of the trailing edge issue is also exibited here. Is this a software thing or the way the scope is triggered?? Seems like tilling loop s slightly longer or shorter one on some cycles

On an easier note - hopefully - how do I access my (FCV_Rcv_Byte) function return from outside the c block - it does not appear in variables - thought it compiles and I don't know how to use the returned variable from another non c block part of my program

Lastly - I have delcared FCV_Rcv_Byte as a char - is this equivalent to a byte data type in Flowcode

Many thanks - will be deligetd to post entire solution when I get it going!




char Rcv_RS232 (char FCV_Rcv_Byte);
void SER_INIT();
void XMIT_RS232(char FCV_Snd_byte);
void Start_Delay();
void Bit_Delay();






void SER_INIT()
{
asm
{
BCF _trisc, 4; //set C4 as an output
BSF _trisc, 5; //set C5 as an input
BSF _portc, 4; //set C4 high
}
}

void XMIT_RS232(char FCV_Snd_Byte)
{
char FCV_Xmit_Byte;
char FCV_Bit_Cntr;


asm
{
MOVF _FCV_Snd_Byte, W
MOVWF _FCV_Xmit_Byte //move W to Xmit_Byte
MOVLW 0x08; //set 8 bits out
MOVWF _FCV_Bit_Cntr
BCF _portc, 4
CALL Bit_Delay
Ser_Loop:
RRCF _FCV_Xmit_Byte , F //send one bit
BTFSS _status, C
BCF _portc, 4
BTFSC _status, C
BSF _portc, 4
CALL Bit_Delay
DECFSZ _FCV_Bit_Cntr , F //test if all done
GOTO Ser_Loop
BSF _portc, 4
CALL Bit_Delay

}
}




char Rcv_RS232(char FCV_Rcv_Byte)
{
char FCV_Bit_Cntr;

asm
{
Start_Bit_wait:
BTFSC _portc, 5; //wait for start bit
GOTO Start_Bit_wait;
CALL Start_Delay; //do half bit time delay
BTFSC _portc, 5; //check still in start bit
GOTO Start_Bit_wait;
MOVLW 0x08; //set up to read 8 bits
MOVWF _FCV_Bit_Cntr;
CLRF _FCV_Rcv_Byte;
Next_RcvBit:
CALL Bit_Delay
BTFSS _portc, 5;
BCF _status , C;
BTFSC _portc, 5;
BSF _status , C;
RRCF _FCV_Rcv_Byte, F
DECFSZ _FCV_Bit_Cntr , F ; //test if all done
GOTO Next_RcvBit
CALL Bit_Delay
MOVF _FCV_Rcv_Byte, W

}
return(FCV_Rcv_Byte);

}


void Start_Delay()
{
char FCV_Delay_Count;

asm
{


MOVLW 0x9
MOVWF _FCV_Delay_Count
Start_wait:
NOP
DECFSZ _FCV_Delay_Count , F
GOTO Start_wait;

}
}


void Bit_Delay()
{
char FCV_Delay_Count;

asm
{

MOVLW 0x12
MOVWF _FCV_Delay_Count
Bit_wait:
NOP
DECFSZ _FCV_Delay_Count , F
GOTO Bit_wait;

}

}

Sean
Valued Contributor
Valued Contributor
Posts: 548
Joined: Tue Jun 26, 2007 11:23 am
Has thanked: 6 times
Been thanked: 44 times

Re: Comms Problems - RS232

Post by Sean »

Hello Mick,

Yes, the C char and Flowcode Byte are the same variable type. The compiler is configured to default char variables to the unsigned type.

If you want a variable to shared between Flowcode and C, the variable should be declared in Flowcode:

If you create the Flowcode byte variable Rcv_Byte, Flowcode will declare the global char variable FCV_RCV_BYTE in the C code. This can now be accessed in either environment.

If you create a variable as a Flowcode macro local variable, the prefix will be FCL_

The timing problems you are finding are probably due to the fact that the chip is running close to its limits. Even if you are clocking it at 40MHz, it will only be able to perform a maximum of 87 asm instructions per loop of the code. Any change in the instructions performed in each loop - due to branch decisions - will have a significant effect on timing unless all branch options are matched.

Electrical conditions might also have an affect at these frequencies. The electrical load, including any cables, could be reducing the switching speed of the outputs.
It should be possible to create a simpler program that consistantly toggles the output at the required frequency (no decisions or branches), to indicate if the timing problems are software or hardware related.

mmaguire
Posts: 9
Joined: Wed Dec 09, 2009 11:40 pm

Re: Comms Problems - RS232

Post by mmaguire »

Thanks again Sean,

On the timing issues - the hardware usart produces a nice clean square wave on the scope. When I swap it in, the software XMIT_RS232 produces the artifact I described. For the consistency I removed the branches and just toggled -portc4 bcf - delay - bsf - delay - and get a lovely clean waveform - I guess it's the software?

On a broader note - if a software usart is to work (at all) with 115200bps - is my general approach corrrect or should I look at modifying the flowcode software component provided - is there anything else I could do to modify it - that comes to mind? Outside the %r variable?

Thanks
Mick

PS I am delighted with Matrix responsivness - its getting rarer!! If I can get this going - will post up solution - another contributer 'pinto' was trying to do something similar in the past, so may be useful-

Sean
Valued Contributor
Valued Contributor
Posts: 548
Joined: Tue Jun 26, 2007 11:23 am
Has thanked: 6 times
Been thanked: 44 times

Re: Comms Problems - RS232

Post by Sean »

Hello Mick,

I have had a look at the asm code for the transmit function. Measures seem to have been taken to ensure that loop timings are consistant. Jitter should be no more than one or two instruction periods per bit period.

The four main sections of the transmit code are:
Start bit
<loop>
Data = 0
Data = 1
<loop end>
Stop bit

The Start and Stop bit timings are not too critical in this case.
There is a minor difference in the edge timings for Data = 0 and Data = 1 (a low output seems to be generated a couple of instructiuon periods before a high output would be in each loop), resulting in a slight difference between the mark and space widths (approx 4.5% at this Baud rate).

There are ways to balance branches exactly using 'nop' commands to extend shorter branches.

In general, your approach to this problem looks good.
You should be able to use your new asm code to customize the equivalent macros in the software instance of the RS232 macro (initialization, transmit, receive, delay), allowing you to call the functions directly from Flowcode as macros.
Alternatively you could write them into a new 'custom' component.

mmaguire
Posts: 9
Joined: Wed Dec 09, 2009 11:40 pm

Re: Comms Problems - RS232

Post by mmaguire »

Hi Sean,
Alas, I am still struggling with this.
- The send routine works but the receive still des not;
- The Rcv_RS232(Rcv_Byte); function seems to return a static value 0x32 :: the hardware usart does work and displays 0x55 characters
- the routine reads in 15 bytes into a byte array and then desplays them in rapid succession then loops
- I am supplying a square wave with bit width 8.6 uS (about 56kHz) - also have a streaming RS232 source with a recognisable pattern of 15 hex values.

****-Am I calling the function correctly?
-I have checked the RRCF or RRNCF -instruction - I dont believe we are checking for a carry on status so shouldn't matter here
-The function is returnng something (0x32) so it must be finding a start bit - - else it waits for ever or watchdog reset
-Pretty positive hardware is ok, portc 5 should be input.- polarity of bits?

-when I power up repeadly seems to return one static byte and stick with it.
- Any other ideas??

Many thanks- It shouldn't be this hard?
Attachments
SV_Rev8.8_CommsMacro.fcf
Routine to read and display
(18.38 KiB) Downloaded 337 times

Sean
Valued Contributor
Valued Contributor
Posts: 548
Joined: Tue Jun 26, 2007 11:23 am
Has thanked: 6 times
Been thanked: 44 times

Re: Comms Problems - RS232

Post by Sean »

Hi Mick,

The program you posted seems to be close to working. There are some issues with the sharing of variables between Flowcode and C.
I hope to be able to look into this further tomorrow.

mmaguire
Posts: 9
Joined: Wed Dec 09, 2009 11:40 pm

Re: Comms Problems - RS232

Post by mmaguire »

Thank you Sean- I am grateful for any help in this.

Regards

Mick

Sean
Valued Contributor
Valued Contributor
Posts: 548
Joined: Tue Jun 26, 2007 11:23 am
Has thanked: 6 times
Been thanked: 44 times

Re: Comms Problems - RS232

Post by Sean »

Hello Mick

I have attached an modified copy of your program.
SV_Rev8.9_CommsMacro.fcf
(17.12 KiB) Downloaded 346 times
The main changes are in the loading of the received data into the array, and the exchange of data between Flowcode and C/asm.

I have removed the FCV prefix from the variables that can not be seen by Flowcode.

I have also removed the parameter passed into the receive function. The received byte should be handled correctly by the Return() instruction.

The program compiles successfully, but has not been tested yet.

mmaguire
Posts: 9
Joined: Wed Dec 09, 2009 11:40 pm

Re: Comms Problems - RS232

Post by mmaguire »

Thank you Sean, Will test now and revert!

Mick

mmaguire
Posts: 9
Joined: Wed Dec 09, 2009 11:40 pm

Re: Comms Problems - RS232

Post by mmaguire »

Hi Sean,
Eventually - routine working! Thank you for all your help. Just a note - I had to capitalise the send variable in question to get it operating. Will post up final solution when done for others to check out. If there is a general posting or material on the transfer of variables between flowcode and c could you direct me to it, - this was the rock I was perishing on. Now for getting the check bits to operate!

Mick

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:

Re: Comms Problems - RS232

Post by Benj »

Hi Mick

I don't think there is a detailed explaination of going between C and Flowcode variables so Ill explain here.

Flowcode variables are stored in c with a capitalised name and the prefix FCV_

eg Flowcode variable "ben" would become "FCV_BEN" when referenced via C code.

mmaguire
Posts: 9
Joined: Wed Dec 09, 2009 11:40 pm

Re: Comms Problems - RS232

Post by mmaguire »

Thanks for that Ben,
Last question - I know treating a string as a byte array for the purposes of calculation is ok. What about treating a byte array as a string within flowcode? My reason for asking is I wish to populate a byte array from a datastream - a byte at a time - eg ReceiveData[15] (as byte array) but to use, particularly, the compare$ function to compare the incoming value with a pre populated -eg SetPointValue - (as string)?
Is there an alternative way to compare byte arrays? Can I populate a string, one byte at a time? Any help or direction greatly appreciated!! BTW this forum is excellent - have got my colleagues to look at flowcode.

Mick

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:

Re: Comms Problems - RS232

Post by Benj »

Hello Mick

I would use the string variable type as there is no way of easily comparing byte arrays at the moment.

You should be able to put your incoming byte into a byte variable eg temp.

Then in a string manipulation you can do something similar to this to add the contents of the byte to the string data.

string_var = string_var + temp

Thanks for the recognition and also yes please spread the word that Flowcode is out there and a great solution to embedded problems :)

Post Reply