[Gambas-user] help with inherits using serial port

Tobias Boege taboege at gmail.com
Wed Aug 1 18:06:48 CEST 2018


On Wed, 01 Aug 2018, PICCORO McKAY Lenz wrote:
> i feel that i are the only that ask for real problems or my questions are
> outside of this world
> 

That's it, I guess, kind of. I can only speak for myself of course, but
I got the impression from some threads in recent months that you don't
really know what you are doing in Gambas on a fundamental and architectural
level and then it takes more elaborate answers to be helpful. In addition
to that, your questions take me, personally, more effort than others to
get behind before I even think of answering, so I mostly ignore them
altogether. Instead of posting a real-world question with your awkward
real-world code, spend some time to distill the essence of what your
problem is and ask a more generic question, or break it into multiple
questions. On the upside, your English wasn't a problem for me this time.

> 2018-07-31 17:15 GMT-04:00 PICCORO McKAY Lenz <mckaygerhard at gmail.com>:
> 
> > hello, today I have another case, I want to implement inheritance to the
> > common code with the serial port printing.
> >
> > What I want to do is to have the procedures to open, close and write to
> > the serial port in one class, and two others that inherit these functions,
> > then one of the inheritors writes "A" to the port while the other writes
> > "B" to the port but the writing functions should be called the same...
> >

This sounds like a perfectly good plan. Inheritance does exactly that.
If you want to confirm that it works, write simple classes first,
with your desired methods, derive a few classes, override methods and
most importantly have everything just print text, like in the attached
example. That way, you don't have the complexity of a SerialPort to
deal with just to see if inheritance fits your design.

> > i attached project with minimal comments hope someone will help with this!
> >
> > the firts problem its that i received "'canot write "stream are closed"
> > why?
> >

The opening of the serial port may have failed. Your pringeneric.op()
function has this:

  Try SComm.Open()
  Catch
    Print "error device" & Error.Text

Since you use Try, the error will be shadowed and you don't get error
reporting via Catch, i.e. you won't know if opening failed. That's exactly
what Try does: ignore errors. My normal user has no permissions to access
/dev/ttyS0 and that error is ignored by your code, leading to another
error later. It may be different on your system, but be sure to check it
and remove the Try.

> > the second problem its that i cannot got any stream event when i do not
> > have stream errors
> >

Well, try again once you're sure that the port opens at all. Then, the
next issue that I can spot is that you declare the event name "SComm" but
don't use it at all to intercept events. No wonder you don't get any.

I also see the question

> Print printodev.dataread ' why here  the inhereits does not prin the printer buffer?

in the code. The function that reads data is this wonderous figment:

  Public Sub rp()
    Dim buffers As String = ""
    Dim timedout As Boolean = False
    Dim timetout As Long
    timetout = Val(Format$(Now, "nnss"))
    Do
      Sleep 0.1
      Read #SComm, buffers, Lof(SComm)
      Sleep 0.1
      dataread = dataread & buffers
      timedout = ((Val(Format$(Now, "nnss")) - timetout) > 0.5)
    Loop Until (timedout)
  End

This is not how you read something from a stream and it is certainly
not how you do a timeout. What happens when you enter this routine
at 17:59:59? Then timetout will be 5959, but a second later your
timestamp stand-in will be 0000 in the computation of time*d*out.
You have just created an infinite loop because there is no value
of Format$(..., "nnss") that you can subtract 5959 from to give
you a positive value -- except maybe leap seconds, which I guess
are sometimes displayed as "59:60". BTW, why do you compare to 0.5
specifically (because you subtract integers, you'll always get a
clean integer, no need for fractions)?

You can use DateDiff() to compare the value of Now() at different
times and even save the conversion to Integer via String:

  start = Now
  Do
    Wait 0.1
    Read #SComm, buffers, Lof(SComm)
    dataread &= buffers
  Loop Until DateDiff(start, Now, gb.Millisecond) > 500

And even then, this is polling. I'm not even sure how Read behaves
when Lof is zero but reading would block. You *might* want to make
SComm.Blocking = False if you need to poll, but if your device and
program design don't require synchronous data processing, I would
prefer to use the SComm_Read event instead, kind of bouncing back
to your previous question.

Regards,
Tobi

[1] https://lists.gambas-basic.org/pipermail/user/2018-July/064864.html

PS: You didn't ask for this, but it caught my attention:

> Private printodev As Variant

in printermanager. The Variant is too generic. A Variant can hold anything,
so it works, but it won't tell anyone reading the code that printodev is
actually an instance of printobixolo or printoepson. Luckily, you use
inheritance. You can declare printodev to be of the common type that
printobixolo and printoepson inherit from:

> Private printodev As pringeneric

-- 
"There's an old saying: Don't change anything... ever!" -- Mr. Monk


More information about the User mailing list