Asii "SUB" (Hex 1a) char causing problems
Asii "SUB" (Hex 1a) char causing problems
#1
Posted 01 June 2009 - 05:34 PM
Software uses "Windows -1252" unicode char ecoding.
Hardware path is: Micro-controller (HCS12X) - FT232 (FTDI USB to "COM3")- VB.net via normal serialport type software.
Note that all other data values display perfectly with this one exception.
Any ideas greatly appreciated.
(Originally posted in VB6 Forum by accident)
#3
Posted 01 June 2009 - 08:20 PM
mark.bottomley, on 1 Jun, 2009 - 07:46 PM, said:
Thanks for the reply Mark. Is the "configuration field' you mention accessed via the SerialPort properties box or some other mechanism?
#4
Posted 26 August 2009 - 10:20 AM
i have read the first post from RDR...
I have exactly the same problem and the same hardware configuration...
i use a microcontroller, a USB to serial cable (with FTDI chip) and a c# application to read data...
the problem is with the 0x1a / 26 / EOF char...in a 800 byte stream...
Some people use a separate thread to read the bytes...
look @
http://social.msdn.m...14-bd2aee7fc7e3
http://social.msdn.m...f5-e78cdd797cec
but i need a fast communication (~4000 bytes/sec with crc control)...
so i can't wait for this "misterious serial crush"....
any news rdr?
#6
Posted 26 August 2009 - 12:56 PM
encoding checked...i have change the encoding with alle the standards (try UNICODE,UT8 etc...) and all the internet suggest encoding (1252 for example) ==> no result...
I use the "readbyte" or the "read with 1 byte"...i try the "read with more byte" too...
it's not so simple guys belive me
or maybe I'm stupid dunno lol
This post has been edited by barby: 26 August 2009 - 12:56 PM
#8
Posted 26 August 2009 - 10:34 PM
T3hC13h, on 26 Aug, 2009 - 04:49 PM, said:
the right answer is:
Yes it fires. The problem is that the comBuffer from the position where is the 0x1A to is not filled.
For example, this is the content of the comBuffer if there isn't the 0x1A:
7E 4B 00 00 13 A0 64 1F 01 01 99 19 D3 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 F1 FF
And this is ther is 0x1A:
7E 24 00 00 13 A0 54 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Maybe if i wait, the missing bytes arrived...
But now my question...my protocoll speed (remember that i have attached a microcontroller) is function of the number of 0x1A in the packet??? Are we crazy???
An alternative solution, can be (like I did in a .Net application) to use an alternative OCX for serial comunication...
Can avoid the problem?
Can be integrated into a C# Express edition?
Do you know a valid OCX for C#?
I used this http://home.comcast..../NETCommOCX.htm in the past...
Help a cheap firmware guy
#9
Posted 27 August 2009 - 01:15 AM
Like barby I have tried all manner of "fixes", none of which are 100% effective.
Today I tried reading one byte at a time using a FOR - NEXT loop rather than the serialport.read direct to a byte array. This improved the situation but now I periodically get gross errors in the data like "22,608" rather than say "150".
It would appear that the data is always read correctly into the comms buffer (at least) but the error occurs when the buffer is read into a byte array. When the "transfer" encounters the h1A it aborts the read beyond that point. Doing single byte transfers seems to fix that problem but now creates these periodic data errors.
Not sure if all this helps but I'm willing to try anything to fix the problem.
#11
Posted 27 August 2009 - 01:42 PM
If SerialPort1.ReceivedBytesThreshold = 33 Then ' 33 bytes received
SerialPort1.Read(sadj, 0, 17) 'this is the ASCII block (as string)
For bnum = 0 To 15
SerialPort1.Read(sdata, bnum, 0) 'read the data bytes one at a time
Next bnum
sadj(0) = " "
label1.Text = sadj ' display the text string
flags2 = sdata(15) ' define the flags byte
If Not flags2 And &H4 Then ' do next if bit = 0
lhighbyte = sdata(0)
llowbyte = sdata(1) ' form into 16 bit word
lrpm = (lhighbyte * &H100) Or llowbyte 'hex to decimal conversion
Label2.Text = (CStr("RPM " & lrpm)) ' display the result
#12
Posted 27 August 2009 - 02:26 PM
2: This loop:
For bnum = 0 To 15 SerialPort1.Read(sdata, bnum, 0) Next bnum
doesn't do anything, all it does is read 0 bytes 16 times. Replace the 0 with a 1.
#14
Posted 27 August 2009 - 11:14 PM
const UInt16 RX_BUFF_SIZE = 4096;
const UInt16 REQUEST_SIZE = 800;
public Form1()
{
InitializeComponent();
serialPort1.BaudRate = 115200;
serialPort1.DataBits = 8;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.ReadTimeout = 100;
serialPort1.WriteTimeout = 100;
serialPort1.ReadBufferSize = RX_BUFF_SIZE;
serialPort1.ReceivedBytesThreshold = REQUEST_SIZE;
serialPort1.Handshake = System.IO.Ports.Handshake.None;
//serialPort1.Encoding = System.Text.Encoding.GetEncoding(28591);
//serialPort1.Encoding = System.Text.Encoding.GetEncoding(1252);
//serialPort1.Encoding = System.Text.Encoding.GetEncoding("Windows-1252");
serialPort1.DiscardNull = false;
serialPort1.DtrEnable = false;
serialPort1.RtsEnable = false;
//serialPort1.BaseStream.ReadTimeout = 10; //???
}
// === DUMP button click EVENT ===//
private void button1_Click(object sender, EventArgs e)
{
serialPort1.Close();
serialPort1.PortName = comboBox1.Text;
//try to open
try
{
serialPort1.Open();
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
return;
}
Load_Timers();
Load_Retry();
//SEND START COMMAND : set Address & Size
Mem_Adr = 0; Mem_Size_Req = REQUEST_SIZE;
send_cmd_on_serial_port(Mem_Adr, Mem_Size_Req);
// manage controls to receive
Flag_Start = true;
}
//============ SERIAL PORT DATA RECEIVE FUNCTION ============//
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (Flag_Start == true)
{
if (manage_new_packet() == true)
{
// ===> OK <=== //
Load_Timers(); //re load
Load_Retry(); //re load
Log_packets++;
if (Flag_End == false)
{
Mem_Size_Req = REQUEST_SIZE;
send_cmd_on_serial_port(Mem_Adr, Mem_Size_Req);
}
} //if NOK, wait timer expiration for retry
}
}
private bool manage_new_packet()
{
UInt16 len_data, len_for_crc;
SERIAL_CMD cmd;
UInt16 crc;
UInt16 i;
//check serial port status
if (serialPort1.IsOpen == false)
{
Clear_RX(true);
return(false);
}
//Read serial port bytes
while (serialPort1.BytesToRead != 0)
{
RX_buff[idx_rx] = (byte)serialPort1.ReadByte();
idx_rx++;
if (idx_rx >= RX_BUFF_SIZE) //protection
{
Clear_RX(true);
Log_errors = "buffer overflow";
return (false);
}
}
//Check packet parameters
[...buffer analisys...]
Clear_RX();
}
//============ SERIAL PORT DATA "CLEAR RX PARAMETERS" ============//
private void Clear_RX(bool dummy)
{
UInt16 i;
serialPort1.DiscardInBuffer(); //free the buffer from data...
for (i = 0; i < RX_BUFF_SIZE; i++)
RX_buff[i] = 0;
idx_rx = 0; //clear Rx index
}
with this code and no 0x1A in the packets all works fine...
now i try some adjustments for 0x1A...but (for me) it's anyway a huge serial component bug
This post has been edited by barby: 27 August 2009 - 11:15 PM
#15
Posted 28 August 2009 - 03:26 AM
The receivedbytes.threshold is required for my code to distinguish between two blocks of incoming data packets of different lengths, works fine for that pupose. I'm sure .bytestoread would also work fine.
#16
Posted 28 August 2009 - 04:49 AM
my code modified:
serialPort1.BaudRate = 115200;
serialPort1.DataBits = 8;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.ReadTimeout = 10;
serialPort1.WriteTimeout = 10;
serialPort1.ReadBufferSize = RX_BUFF_SIZE;
serialPort1.ReceivedBytesThreshold = 8;
serialPort1.Handshake = System.IO.Ports.Handshake.None;
//serialPort1.Encoding = System.Text.Encoding.GetEncoding(28591);
//serialPort1.Encoding = System.Text.Encoding.GetEncoding(1252);
//serialPort1.Encoding = System.Text.Encoding.GetEncoding("Windows-1252");
serialPort1.DiscardNull = false;
serialPort1.DtrEnable = false;
serialPort1.RtsEnable = false;
//============ SERIAL PORT DATA "MANAGE PACKET RECEIVED" ============//
public bool manage_new_packet()
{
UInt16 len_data, len_for_crc;
SERIAL_CMD cmd;
UInt16 crc;
UInt16 i;
//check serial port status
if (serialPort1.IsOpen == false)
{
Clear_RX();
return(false);
}
//check message
if (serialPort1.BytesToRead >= 1)
{
RX_buff[0] = (byte)serialPort1.ReadByte();
idx_rx++;
cmd = (SERIAL_CMD)RX_buff[0];
if (cmd != SERIAL_CMD.SERIAL_DUMP_REPLY_TO_PC)
{
Clear_RX();
return (false);
}
}
else
return (false);
if (serialPort1.BytesToRead < REQUEST_SIZE)
{
int Timer_tmp = System.Environment.TickCount;
do
{
//wait...
} while (Timer_tmp + 100 > System.Environment.TickCount);
if (serialPort1.BytesToRead < REQUEST_SIZE)
{
Clear_RX();
return (false);
}
}
//Read serial port bytes
while (serialPort1.BytesToRead != 0)
{
RX_buff[idx_rx] = (byte)serialPort1.ReadByte();
idx_rx++;
if (idx_rx >= RX_BUFF_SIZE) //protection
{
Clear_RX();
Log_errors = "buffer overflow";
return (false);
}
}
//process result
....
....
now it works fine, IF there are not too many 0x1A in the packet...
I explain, on 800 byte, if there are about 100 bytes with 0x1A value it works correctly...
If more bytes are 0x1A, the serial go in OVERRUN error:
//============ SERIAL PORT DATA RECEIVE ERROR ============//
private void serialPort1_ErrorReceived(object sender, System.IO.Ports.SerialErrorReceivedEventArgs e)
{
int dummy;
Log_errors = "Serial Error";
while (serialPort1.BytesToRead != 0)
dummy = serialPort1.ReadByte();
}
And i get a overrun error
Now i make another experiment, stay tuned
#18
Posted 31 August 2009 - 10:35 PM
RDR, on 28 Aug, 2009 - 02:22 PM, said:
I'm out of town for a couple of days but will watch your progress with interest when I return.
RDR
I've to fix some other work in these days!
when I come back to the problem and i choose the final solution I will post my code!
my last ideas are two:
1) substitute the serial port component of .Net enviroment with another one (or another dll dunno)
2) try to read the serial data in a separate timer. Now the serial data is read in the serial port receive handler
#19
Posted 08 September 2009 - 11:59 AM
I have a similar issue when receiving multiple 0x1A byte transmissions.
I am using C# with a USB to 485 converter that contains a FT245 chip.
Just curious...cause I am very stumped. I am uncertain if it is .NET or the chip with the problem.
#20
Posted 08 September 2009 - 03:14 PM
Shell1366, on 8 Sep, 2009 - 11:59 AM, said:
I have a similar issue when receiving multiple 0x1A byte transmissions.
I am using C# with a USB to 485 converter that contains a FT245 chip.
Just curious...cause I am very stumped. I am uncertain if it is .NET or the chip with the problem.
Hi Shell1366. The common factor with all these problems so far appears to be the FTDI chip. I use the FT232RL in my application with vb.net.
It seems strange that no one else has (had) a problem with 0x1a when using comms in either C#, VB etc, only those using the FDTI chips.
I just did a quick test using Hyper Terminal to receive a block of text with some embedded 0x1a bytes. Hyper Terminal processed it perfectly fine and just displayed right-pointing arrow characters when it encountered the 1a bytes. A hex view of the text was perfectly correct. Note that HT uses the same virtual comm port (VCP) as my VB app. Not sure what to conclude from all that.
Has anyone tried using the dll's for these chips rather than the VCP's. I'm not sure how to incorporate a dll into VB so would appreciate some advice or comment on that.

Add Reply




MultiQuote

| 


