FAQ
Hi
i'm trying to develop a little procedure to send a SMS via AT commands; i
found goserial package to connect to serial and a test with loop back works.
When i try to use a modem write function work but read function don't wait
the response from modem ?
Are there someone that use this packages??
I don't know the syscall in windows so the following piece of code is for
me "mysterious" ...

func (p *serialPort) Read(buf []byte) (int, error) {
if p == nil || p.f == nil {
return 0, fmt.Errorf("Invalid port on read %v %v", p, p.f)
}

p.rl.Lock()
defer p.rl.Unlock()

if err := resetEvent(p.ro.HEvent); err != nil {
return 0, err
}
var done uint32
err := syscall.ReadFile(p.fd, buf, &done, p.ro)
  // fmt.Printf("\np.fd %+v,\nbuf %+v,\nbuf %s done %+v, p.ro %+v
\n",p.fd,buf,buf,done,p.ro)
if err != nil && err != syscall.ERROR_IO_PENDING {
return int(done), err
}
return getOverlappedResult(p.fd, p.ro)
}


How can i wait the response from modem ?
A curiosity.. Why some functions, like syscall.ReadFile, is not present in
web documentation?

Alex

--

Search Discussions

  • Brainman at Nov 11, 2012 at 11:11 pm

    On Monday, 12 November 2012 09:26:27 UTC+11, alex martin wrote:

    ... read function don't wait the response from modem ?
    It is not clear to me what your problem is. If you like help, just post
    small program for us to demonstrate your issue.
    ... Are there someone that use this packages??
    I think, I looked at this package long time ago.
    ... I don't know the syscall in windows so the following piece of code is
    for me "mysterious" ...

    I always look at the source code so see what it does. Also see, for
    example, http://msdn.microsoft.com/en-us/library/ff802693.aspx for "why",
    especially "Overlapped I/O" section.
    ... How can i wait the response from modem ?
    I could be wrong, but I think (*goserial.serialPort).Read should work for
    you.
    ... Why some functions, like syscall.ReadFile, is not present in web
    documentation?

    Are you referring to http://tip.golang.org/pkg/syscall/ ? If you are, it is
    running "godoc -http=:80" command on platform other them windows. And godoc
    command only shows packages for the platform it runs on. syscall package
    looks different on different platforms. You could use godoc command on you
    computer to see what you need. Alternatively, just look at the source files.

    Alex

    --
  • Alex martin at Nov 12, 2012 at 3:27 am
    Hi Alex
    thank for links
    ... read function don't wait the response from modem ?
    When i send a command to modem by go-serial Write i want to read the
    response; when i do this my example not read all chars at first time so i
    do iterate until there aren't chars in buffer
    ie

    ->ATE0
    <-OK

    this is the pieces of main

    1 c := &serial.Config{Name: "COM26", Baud: 115200}
    2 s, err := serial.OpenPort(c)
    3 if err != nil {
    4 log.Fatal(err)
    5 }
    6
    7 n, err := s.Write([]byte("ATE0\r\n"))
    8 if err != nil {
    9 log.Fatal(err)
    10 }

    11 buf := make([]byte, 128)
    12 n, err = s.Read(buf)
    13 if err != nil {
    14 log.Fatal(err)
    15 }
    16 fmt.Printf("\nbuffer %v\nbuffer %s", buf[:n],buf[:n])

    the result of Read is

    buffer [13]
    buffer

    when i repeat two time rows from 12 to 16 the result is

    buffer [13]
    buffer
    buffer [10 79 75 13 10]
    buffer
    OK

    The function *func* (p *serialPort)* Read*(buf []byte) (int, error) read
    <CR> and <NL>OK<CR><NL> in two step.
    I always look at the source code so see what it does. Also see, for
    example, http://msdn.microsoft.com/en-us/library/ff802693.aspx for "why",
    especially "Overlapped I/O" section.

    Thank, i was looking for some information about overlapping because Read
    function call,after syscall.ReadFile, a func called
    "getOverlappedResult(p.fd, p.ro)"
    Are you referring to http://tip.golang.org/pkg/syscall/ ?
    Yes, I don't know *"godoc -http=:80", *great tips

    Alex







    --
  • Brainman at Nov 12, 2012 at 4:10 am

    On Monday, 12 November 2012 14:20:00 UTC+11, alex martin wrote:

    ... i want to read the response; when i do this my example not read all
    chars at first time so i do iterate until there aren't chars in buffer

    I think you do not have clear plan of attack. You say you want to read
    "response", but, I think< you aren't clear what "response" means.

    Considering you are talking to a modem, what I would do is say that all
    modem replies are "lines" = sequence of bytes with byte=13 at the end. Then
    I would write a function to read one line (read byte by byte and check if
    it is 13 and exit if it is). Then I would write a function that reads a
    sequence of lines until I get line of "OK", then that sequence is a "modem
    response" to your command. You could analyze these to determine modem state.

    I could be wrong about value of line end (13), it might be 10 instead.
    Also, if you use 13, then you should ignore 10, and vice verse. As far as I
    remember modems could do one or the other or both. They could also "echo"
    commands you send, or they can accept them without "echo". It is all can be
    configure in the modem. So you should be aware.

    Hope it helps.

    Alex

    --
  • Alex martin at Nov 12, 2012 at 5:20 am
    Alex I'm sorry for my awful english.
    I think you do not have clear plan of attack
    I expected that Read function read all buffer, not some char. Tarmigan on
    the following reply explain the reason
    Considering you are talking to a modem, what I would do is say that all
    modem replies are "lines" = sequence of bytes with byte=13 at the end. Then
    I would write a function to read one line (read byte by byte and check if
    it is 13 and exit if it is). Then I would write a function that reads a
    sequence of >lines until I get line of "OK", then that sequence is a "modem
    response" to your command. You could analyze these to determine modem state

    I'm arrived at the same conclusion, i search "OK<CR><NL>" string with
    bytes.Index.. If position is <> -1 the string is not present so i continue
    to read.

    On Monday, November 12, 2012 5:10:13 AM UTC+1, brainman wrote:
    On Monday, 12 November 2012 14:20:00 UTC+11, alex martin wrote:

    ... i want to read the response; when i do this my example not read all
    chars at first time so i do iterate until there aren't chars in buffer

    I think you do not have clear plan of attack. You say you want to read
    "response", but, I think< you aren't clear what "response" means.

    Considering you are talking to a modem, what I would do is say that all
    modem replies are "lines" = sequence of bytes with byte=13 at the end. Then
    I would write a function to read one line (read byte by byte and check if
    it is 13 and exit if it is). Then I would write a function that reads a
    sequence of lines until I get line of "OK", then that sequence is a "modem
    response" to your command. You could analyze these to determine modem state.

    I could be wrong about value of line end (13), it might be 10 instead.
    Also, if you use 13, then you should ignore 10, and vice verse. As far as I
    remember modems could do one or the other or both. They could also "echo"
    commands you send, or they can accept them without "echo". It is all can be
    configure in the modem. So you should be aware.

    Hope it helps.

    Alex
    --
  • Tarmigan Casebolt at Nov 12, 2012 at 4:13 am
    Protip: CC the author of the package when you have questions about it.
    On Sun, Nov 11, 2012 at 7:20 PM, alex martin wrote:

    Hi Alex
    thank for links

    ... read function don't wait the response from modem ?
    When i send a command to modem by go-serial Write i want to read the
    response; when i do this my example not read all chars at first time so i
    do iterate until there aren't chars in buffer
    ie

    ->ATE0
    <-OK

    this is the pieces of main

    1 c := &serial.Config{Name: "COM26", Baud: 115200}
    2 s, err := serial.OpenPort(c)
    3 if err != nil {
    4 log.Fatal(err)
    5 }
    6
    7 n, err := s.Write([]byte("ATE0\r\n"))
    8 if err != nil {
    9 log.Fatal(err)
    10 }

    11 buf := make([]byte, 128)
    12 n, err = s.Read(buf)
    13 if err != nil {
    14 log.Fatal(err)
    15 }
    16 fmt.Printf("\nbuffer %v\nbuffer %s", buf[:n],buf[:n])

    the result of Read is

    buffer [13]
    buffer

    when i repeat two time rows from 12 to 16 the result is

    buffer [13]
    buffer
    buffer [10 79 75 13 10]
    buffer
    OK
    If I understand your description, I think that is working as intended. (At
    some point I would like to add more tests and functionality to the package,
    but what you're interested in should work.)

    Reading a fixed number of bytes from a serial port can take
    an indeterminate amount of time. The indended behavior of goserial Read()
    is this:
    If NO bytes can be read, then block until at least 1 byte is available.
    If ANY bytes can be read, then read as many bytes as possible without
    blocking, and return those bytes.

    With this low-level behavior you should be able to build the behavior you
    want. If you know how many bytes you expect, you could wrap it in
    io.ReadFull or io.ReadAtLeast, but you should also think about how to
    timeout if those bytes don't come back. You could construct a
    ReadFullOrTimeout function for yourself but that functionality is not in
    the goserial package. But you might also want to make a
    ReadUntilNewlineOrTimeout function or something. It's application
    specific, so you will need to write that wrapper yourself.

    Thanks,
    Tarmigan

    --
  • Notnot at Jul 1, 2013 at 11:52 pm
    Hello, hijacking an old thread, I stumbled upon it while researching an
    issue I'm having.

    Reading a fixed number of bytes from a serial port can take
    an indeterminate amount of time. The indended behavior of goserial Read()
    is this:
    If NO bytes can be read, then block until at least 1 byte is available.
    If ANY bytes can be read, then read as many bytes as possible without
    blocking, and return those bytes.
    This would be the behavior I would like to see, but on my system (Ubuntu)
    it doesn't work that way. Instead of blocking until data can be read from
    the tty file, serial Read() returns an error io.EOF almost all the time, if
    there isn't new data available. I'm new to serial port programming so I
    thought this behavior could be 'normal'. I worked my way around the issue
    by calling time.Sleep() after getting an io.EOF and trying again. I don't
    quite like this polling mechanism, and i would rather see that serial
    Read() would do the proper blocking. Is this a bug in your serial package
    on linux?



    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dave Cheney at Jul 2, 2013 at 12:05 am
    -1 for hijacking an old thread -- start a new one please.
    On Tue, Jul 2, 2013 at 9:52 AM, notnot wrote:
    Hello, hijacking an old thread, I stumbled upon it while researching an
    issue I'm having.
    Reading a fixed number of bytes from a serial port can take an
    indeterminate amount of time. The indended behavior of goserial Read() is
    this:
    If NO bytes can be read, then block until at least 1 byte is available.
    If ANY bytes can be read, then read as many bytes as possible without
    blocking, and return those bytes.

    This would be the behavior I would like to see, but on my system (Ubuntu) it
    doesn't work that way. Instead of blocking until data can be read from the
    tty file, serial Read() returns an error io.EOF almost all the time, if
    there isn't new data available. I'm new to serial port programming so I
    thought this behavior could be 'normal'. I worked my way around the issue by
    calling time.Sleep() after getting an io.EOF and trying again. I don't quite
    like this polling mechanism, and i would rather see that serial Read() would
    do the proper blocking. Is this a bug in your serial package on linux?



    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.
  • Jan Mercl at Jul 2, 2013 at 5:43 am

    On Tue, Jul 2, 2013 at 1:52 AM, notnot wrote:
    This would be the behavior I would like to see, but on my system (Ubuntu) it
    doesn't work that way. Instead of blocking until data can be read from the
    tty file, serial Read() returns an error io.EOF almost all the time, if
    there isn't new data available. I'm new to serial port programming so I
    thought this behavior could be 'normal'. I worked my way around the issue by
    calling time.Sleep() after getting an io.EOF and trying again. I don't quite
    like this polling mechanism, and i would rather see that serial Read() would
    do the proper blocking. Is this a bug in your serial package on linux?
    Setting the port (its fd actually) to non-block mode should solve the
    EOF on no data problem. See for example [1].

       [1]: https://github.com/schleibinger/sio/blob/master/sio.go#L86

    -j

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.
  • Erwin at Jul 2, 2013 at 9:47 am
    Jan, thanks for pointing me to that serial IO package. Its an interesting
    one because it doesn't use CGO. Linux only though, and the software I am
    writing might have to run on OS X as well. Perhaps its not that hard to
    implement a syscall only implementation for OS X, I'll see.

    I guess I figured out why I was having the issues with
    github.com/tarm/goserial. This package is supposed to set /dev/tty* to
    blocking mode, but that wasn't working as expected, probably because
    the /dev/tty* file was already opened by another program (the Arduino
    serial monitor) in non-blocking mode. When I continued testing this
    morning, without the Arduino monitoring software running, I no longer get
    the io.EOF :)






    On 2 July 2013 07:43, Jan Mercl wrote:
    On Tue, Jul 2, 2013 at 1:52 AM, notnot wrote:
    This would be the behavior I would like to see, but on my system
    (Ubuntu) it
    doesn't work that way. Instead of blocking until data can be read from the
    tty file, serial Read() returns an error io.EOF almost all the time, if
    there isn't new data available. I'm new to serial port programming so I
    thought this behavior could be 'normal'. I worked my way around the issue by
    calling time.Sleep() after getting an io.EOF and trying again. I don't quite
    like this polling mechanism, and i would rather see that serial Read() would
    do the proper blocking. Is this a bug in your serial package on linux?
    Setting the port (its fd actually) to non-block mode should solve the
    EOF on no data problem. See for example [1].

    [1]: https://github.com/schleibinger/sio/blob/master/sio.go#L86

    -j
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 11, '12 at 10:26p
activeJul 2, '13 at 9:47a
posts10
users6
websitegolang.org

People

Translate

site design / logo © 2023 Grokbase