Now Scilab's Bugzilla with LDAP : if you have an account on ATOMS or fileexchange, you can log here with it!
Note You need to log in before you can comment on or make changes to this bug.
Details
Bug # 3829
Hello, I try to u...
Status: RESOLVED WONTFIX
Product: Scilab software
Classification: Unclassified
Component: Strings
Relevant URL: URL
 
Reported: 2008-12-06 23:16 CET
Modified: 2010-04-29 13:53 CEST (History)
: PC
: All OS
: 5.0.2 final version
: P5 Minor

:
:
:
  Show dependency treegraph
See Also:
People
Reporter: Artur
Assigned To: Enrico SEGRE
5 users (show)

Detailed description of the problem
-- Bug description --


Hello,

I try to use the Serialtoolbox of Enrico Segre 
(http://www.weizmann.ac.il/home/fesegre/scistuff/Serial.tgz)
it's the only toolbox that run under SciLab 5.x.This toolbox is written in TCL.
I can send some data via RS232
to a nother PC, but the second PC receive some different data and I can not
send and receive a ascii(0)!(ascii(0) could be a problem of the toolbox)

I think it's a problem of TCL "fconfigure -translation binary".
So the translation works false. 
Look at example. I hope that is the right site to post that problem and hope
you can help me to avoid that 'bug', if not please send me a link to a right
forum or TCL bug tracking site.


-- Scilab error message --


just for sending ascii(0)

st=writeserial(h,ascii(0));
!--error 999 
TCL_EvalStr,  at line 1
    missing close-brace
    while executing
"set writeresult [catch {puts -nonewline file9d11ac8 {"
at line      11 of function writeserial called by :  
writeserial(h,ascii(0))


-- How to reproduce the bug --


(you need the serialtoolbox to reproduce the "bug")
for example:

kmd=[109 112 102 205 204 140 63 205 204 140 63 205 204 140 63 205 204 140 63...
205 204 140 63 205 204 140 63 16 3];

hnd=openserial(5,"19200,n,8,1","binary");

k = ascii(kmd)

k = mpfÍÌŒ?ÍÌŒ?ÍÌŒ?ÍÌŒ?ÍÌŒ?ÍÌŒ?

st=writeserial(hnd,k)

read data on second PC:

r=readserial(hnd2)

r=mpfÍ??Í??Í??Í??Í??Í??

r=ascii(r)
r=109 112 102 205 12 --- 63 205 12 --- 63 205 12 --- 63 205 12 --- 63 205 12 
--- 63 205 12 --- 63 16 3
(--- are bissing bytes and 12 is false too)

I can not use that received data, cause it's faulty.

Attachments

Comments
Comment 1 Enrico SEGRE 2008-12-07 10:47:01 CET
The first thing which occurs to me is that this might be another manifestation
of bug 2520 (after all, not a bug, but logical tcl behavior). readserial() just
uses TCL_GetVar.

As for \0's, a side effect of C \null string termination either in tcl or in
the scilab glue: 

-->TCL_SetVar("a",ascii([1 0 2 3]))
 ans  =

  T  

-->ascii(TCL_GetVar("a"))                
 ans  =

    1.  


However there should be workarounds, otherwise the serial toolbox is simply not
fit, no excuses. I'd have a look under the tcl command "binary", and would
perhaps resort in the serial toolbox to pass the data as numeric array
(inefficient but failsafe). As already written privately to the OS, I just need
some time ahead for it, I'll be travelling next week.

Enrico
Comment 2 Artur 2008-12-07 20:36:05 CET
I have opened a com port with 'mopen' and send the same kmd with the 'mfprintf'

fd=mopen('COM5','r+');
(i wondert that mopen opend a comport with this handle(19200,0,8,1))

mfprintf(fd,'%s',ascii(kmd)) (kmd look at Steps to reproduce the bug)

I get the same kmd-vector on my second PC, but the ascii(0) problem still
there.

mfprintf sends nothing after ascii(0)

like:

kmd=[109 112 102 205 204 140 63 205 204 140 63 205 204 140 0 0 63...
205 204 140 63 205 204 140 63 16 3];

after: mfprintf(fd,'%s',ascii(kmd))

i get just [109 112 102 205 204 140 63 205 204 140 63 205 204 140]
Comment 3 Enrico SEGRE 2008-12-07 21:47:30 CET
(In reply to comment #2)
> I have opened a com port with 'mopen' and send the same kmd with the 'mfprintf'
> 
> fd=mopen('COM5','r+');

that might be a windows only contraption , i.e. not a solution, if it ever
seems to work.

> mfprintf(fd,'%s',ascii(kmd)) (kmd look at Steps to reproduce the bug)
> 
> I get the same kmd-vector on my second PC, but the ascii(0) problem still
> there.

most likely also \0 terminated C-like strings here too. Anyway, that is another
route.

As for the TCL way, I'm thinking at a workaround like this (to be tested yet)

function result=writeserial(h,buf)
   if ~exists("buf","local") then 
      TCL_EvalStr("set writeresult [catch {flush "+h+"}]")
   else
      TCL_EvalStr("set writeresult [catch {puts -nonewline "+h+..
                  " [binary format c* {"+mprintf(ascii(buf),%d)+..
                  "}]; flush "+h+"}]")
   end
   result=-eval(TCL_GetVar("writeresult"));
endfunction

TODO is to test it, to figure out the solution for setserial (with binary scan,
perhaps), to repackage the toolbox...
Comment 4 Enrico SEGRE 2008-12-07 22:10:33 CET
Correction:

function result=writeserial(h,buf)
   if ~exists("buf","local") then 
      TCL_EvalStr("set writeresult [catch {flush "+h+"}]")
   else
      TCL_EvalStr("set writeresult [catch {puts -nonewline "+h+..
                  " [binary format c* {"+msprintf(" %d",ascii(buf(:))')+..
                  "}]; flush "+h+"}]")
   end
   result=-eval(TCL_GetVar("writeresult"));
endfunction


And for readserial something along the lines of:

function buf=readserial(h,n)
   if ~exists("n","local") then
     N=serialstatus(h); n=N(1)
   end
   TCL_EvalStr("binary scan [read "+h+" "+string(n)+"] c* ttybuf")
   buf=ascii(TCL_GetVar("ttybuf"));
// convert signed to unsigned chars here??
endfunction


But I have nothing to test it on at the moment.
Btw, I have assumed format c*, since I'm not awae of serial formats wider than
8bits.

Enrico
Comment 5 Artur 2008-12-08 00:08:11 CET
(In reply to comment #4)
Hmm... think I have to describe my kmd-vector.
It consists of a string convert to ascii. ( the first three numbers and the
rest are axis positions).

For example: 

kmd=[uint8(ascii('mpf')) uint8([205 204 140 63 205 204 140 63 205 204 140 ... 
0 0 63 205 204 140 63 205 204 140 63 16 3])];
// the axis position is a ieee754 format 
//A=ftoieee754(1.1) <---- ftoieee754 is a handcoded function
//A= 205 204 140 63
Now I have to send the kmd to my real-time-OS. If the rtos read the kmd-vector
it must the same as I send it.


>       TCL_EvalStr("set writeresult [catch {puts -nonewline "+h+..
>                   " [binary format c* {"+msprintf(" %d",ascii(buf(:))')+..
>                   "}]; flush "+h+"}]")

in the kmd-vector are the first three numbers ascii-coded and at this line it
will be coded back. Ascii([109 112 102 205 204 140 63]) try to code back to mpf
and the axis to ascii(). (type string '%s')
I tried to replace '%d' with '%s' but i get a result = -1


> And for readserial something along the lines of:

>    buf=ascii(TCL_GetVar("ttybuf"));
The rtos send at the end 'Transmission OK'/'Transmission FAULT' in ascii-code
(at the beginning mybe sends position coordinates )
for example:
Transmission OK =>84 114 97 110 115 109 105 115 115 105 111 110 32 79 75

and with 'buf=ascii(TCL_GetVar("ttybuf"));' the numbers will be code to ascii
back
for example: the 84 will be code back to [56 52].
At the first version of the readserial function I got the 'Transmission FAULT'
sentence not the ascii-code after reading the port.

I know that is really difficult and I thank you again for the help.
Comment 6 Enrico SEGRE 2008-12-08 14:55:29 CET
(In reply to comment #5)
> (In reply to comment #4)
> Hmm... think I have to describe my kmd-vector.

Not really. My goal is to fix the functions so that any string of (8bit)
characters is supported, irrespective of the purpose.

> It consists of a string convert to ascii. ( the first three numbers and the
> rest are axis positions).
> 
> For example: 
> 
> kmd=[uint8(ascii('mpf')) uint8([205 204 140 63 205 204 140 63 205 204 140 ... 
> 0 0 63 205 204 140 63 205 204 140 63 16 3])];

wait - writetoserial expects a string argument. In principle I could make it
accepting a numeric array as well, and silently avoid to recast it to numbers,
depending on the type of the argument. However, in the attempted fix (provided
it ever works) I gave above, I assumed that kmd was a string. Remember that
ascii(number)=string and ascii(string)=number.

> and the axis to ascii(). (type string '%s')
> I tried to replace '%d' with '%s' but i get a result = -1

no, %d. I want numbers there. I want that the command passed to TCL_EvalStr
looks like


puts -nonewline file123ab678 [binary format c* {205 204 140 63 205 204 }]

> > And for readserial something along the lines of:
> 
> >    buf=ascii(TCL_GetVar("ttybuf"));
> The rtos send at the end 'Transmission OK'/'Transmission FAULT' in ascii-code
> (at the beginning mybe sends position coordinates )
> for example:
> Transmission OK =>84 114 97 110 115 109 105 115 115 105 111 110 32 79 75
> 
> and with 'buf=ascii(TCL_GetVar("ttybuf"));' the numbers will be code to ascii
> back
> for example: the 84 will be code back to [56 52].

If there are \x00's in this string, TCL_GetVar will see them as end of string.
That's the point. If by chance some sequence of bytes (where typically the
first is>128) makes sense as multibyte character in the current encoding,
TCL_GetVar will try to render it as an exotic character, mangling the data. And
if it flags a multibyte character, but does not make sense, TCL_GetVar will
replace it wit - - - or ? ? ?, still bad.

That's why readserial should be rewritten, IIUC as above - but I have to test
it when I have some time; as above, it might very well be broken.
Comment 7 Artur 2008-12-08 17:31:54 CET
Yes you're right with the writeserial (at Comment #6), I'm sorry . The solution
that you written in Comment #4 works and I can transmit the data without
misstakes.

I recognised that the function ascii() and char() have some problems with 0
too.

ascii([84 114 97 0 110 115 109])
ans = Tra

//but the length of ans still 7

k=ascii(ans)
k = 84 114 97 0 110 115 109


The same with the function char():

char([84 114 97 0 110 115 109])
ans = Tra
Comment 8 Enrico SEGRE 2008-12-08 18:13:48 CET
(In reply to comment #7)
> Yes you're right with the writeserial (at Comment #6), I'm sorry . The solution
> that you written in Comment #4 works and I can transmit the data without
> misstakes.
> 
> I recognised that the function ascii() and char() have some problems with 0
> too.
> 
> ascii([84 114 97 0 110 115 109])
> ans = Tra
>
> //but the length of ans still 7
> 
> k=ascii(ans)
> k = 84 114 97 0 110 115 109
> 
> 
> The same with the function char():
> 
> char([84 114 97 0 110 115 109])
> ans = Tra

That is a (display?) bug of scilab 5, I guess once more because of the use of C
string functions rather than Fortran for the display. In 4.1.2

 -->ascii([84 114 97 0 110 115 109])
 ans  =

 Transm   

-->ascii(ans)
 ans  =

    84.    114.    97.    0.    110.    115.    109.  

Would you be so kind to open a separate bug for this?
Enrico
Comment 9 Enrico SEGRE 2008-12-08 23:03:13 CET
> At the first version of the readserial function I got the 'Transmission FAULT'
> sentence not the ascii-code after reading the port.


Would you try out this one, which has some chance of working?

function buf=readserial(h,n)
   if ~exists("n","local") then
     N=serialstatus(h); n=N(1)
   end
   TCL_EvalStr("binary scan [read "+h+" "+string(n)+"] c* ttybuf")
   buf=ascii(evstr(TCL_GetVar("ttybuf")));
endfunction


If it does, when I can I'll post a corrected toolbox. Perhaps with tcl
variables in a protected namespace, or some other improvement.
Enrico
Comment 10 Artur 2008-12-10 10:26:43 CET
(In reply to comment #9)


> Would you try out this one, which has some chance of working?
> 
> function buf=readserial(h,n)
>    if ~exists("n","local") then
>      N=serialstatus(h); n=N(1)
>    end
>    TCL_EvalStr("binary scan [read "+h+" "+string(n)+"] c* ttybuf")
>    buf=ascii(evstr(TCL_GetVar("ttybuf")));
> endfunction

The readserial works and shows the rigth sentence until a zero. (bug of ascii)
Comment 11 Enrico SEGRE 2008-12-18 18:19:53 CET
(In reply to comment #10)

> The readserial works and shows the rigth sentence until a zero. (bug of ascii)

you mean: it retrieves the string including the zeros [please check with
ascii(readserial()) ] but the string is not displayed beyond the zeroes because
of the *display* bug, correct?
Comment 12 Enrico SEGRE 2008-12-18 18:32:46 CET
(In reply to comment #11)
 but the string is not displayed beyond the zeroes because
> of the *display* bug, correct?

besides, bug 3831 is solved now       
Comment 13 Enrico SEGRE 2009-01-12 10:13:36 CET
For the record, I've repackaged the corrections as Serial-0.2 and put it on
http://www.weizmann.ac.il/home/fesegre/scistuff.html. The help files are still
in 4.x format, as long as I cant't figure out how to build help in scilab 5
[nor I'm sure that the process works anymore with 4.1.2]; should I succeed,
someday I might include both help formats in the package, and builder/loader
working for both versions.
I don't close the bug yet as I'd like to test the functions once more, which I
might do as soon as someone drops on my table a serial instrument whatsoever.
Enrico
Comment 14 Vincent COUVERT 2010-04-29 13:53:56 CEST
As this bug refers is not a Scilab bug, I set it to WONTFIX.