Page 1 of 1

Console.ReadLine and getqueuestr

Posted: 24 March 2009, 13:16 PM
by sturgessb
Hi Guys

Am I missing something or is it not possible to use Console.ReadLine on a com port other than Com1?

getqueuestr is not as useful in my application as I want to easily read complete lines terminated by LF.

Cheers

Ben

Re: Console.ReadLine and getqueuestr

Posted: 24 March 2009, 13:42 PM
by mikep
The console functions and Debug.Print are restricted to Com1 (the system queues) and are provided as a convenience. You will need to do your own parsing of the data on other COM ports.

Re: Console.ReadLine and getqueuestr

Posted: 24 March 2009, 14:36 PM
by dkinzer
sturgessb wrote:I want to easily read complete lines terminated by LF.
The function shown below extracts characters from a queue and transfers them to a line accumulation queue. When a linefeed is transferred, the contents of the line accumulation queue is returned as a string and the accumulation queue is cleared. A zero length string is returned on all calls before the linefeed is seen. The downside of this method is that it incurs the additional storage for the line accumulation queue.

Code: Select all

Function GetQueueLine(ByRef iq() as Byte, ByRef lq() as Byte) as String
  GetQueueLine = ""
  Do While (StatusQueue(iq))
    Dim b as Byte
    Call GetQueue(iq, b, SizeOf(b))
    Call PutQueueByte(lq, b)
    If (b = &H0a) Then
      ' extract the accumulated line from the queue and clear it
      GetQueueLine = GetQueueStr(lq)
      Call ClearQueue(lq)
      Exit Do
    End If
  Loop
End Function
A second alternative is to use knowledge of the structure of a queue in order to detect when the queue contains a linefeed. The code below, written in C, returns the length of the first line in the queue or zero if the queue is empty or does not yet contain a linefeed. When the function returns a non-zero value, use that value as the second parameter to GetQueueStr() to extract the line from the queue.

Generally speaking, using code that is dependent on implementation details is not recommended. However, it is unlikely that the details of the queue implementation will change.

Code: Select all

#c
/*
 ** GetQueueLineLength
 *
 * This function returns the number of bytes up to and including
 * the first linefeed in a given queue.  If the queue is empty or
 * does not yet contain a linefeed, zero is returned.
 *
 * Interrupts are disable during the scanning process.
 *
 */
uint16_t
GetQueueLineLength(uint8_t *q)
{
  uint16_t len = 0;
  Queue *qp = (Queue *)q;
  if (qp != NULL)
  {
    uint8_t sreg = SREG;
    cli();
    uint16_t cnt = qp->cnt;
    uint16_t idx = qp->tail;
    while (cnt--)
    {
      if (++idx >= qp->cap)
        idx = 0;
      if (qp->queue[idx] == 0x0a)
      {
        // found a linefeed, compute line length
        len = qp->cnt - cnt;
        break;
      }
    }
    SREG = sreg;
  }
  return(len);
}
#endc

Declare Function GetQueueLineLength(ByRef q() as Byte) as UnsignedInteger

Posted: 24 March 2009, 17:44 PM
by sturgessb
Thanks Don I will implement this.

Re: Console.ReadLine and getqueuestr

Posted: 24 March 2009, 18:08 PM
by dkinzer
sturgessb wrote:I want to easily read complete lines terminated by LF.
This topic got me to thinking that it might be useful to have a function that will search a queue for an arbitrary character, returning the "index" of the first occurrence. The API could be something like this:

Code: Select all

Function FindQueue(ByRef q() as Byte, ByVal val as Byte) as UnsignedInteger
A return value of zero would mean that the byte value is not present. Otherwise, the value would indicate how many bytes are in the queue up to and including the sought value. As with the example code in my earlier post, the return value could be used with GetQueueStr() or GetQueue() to retrieve the data preceding and or including the sought value.

Posted: 24 March 2009, 19:27 PM
by sturgessb
That would be very useful yes.

Posted: 24 March 2009, 19:28 PM
by sturgessb

Code: Select all

Function GetQueueLine(ByRef iq() as Byte, ByRef lq() as Byte) as String
  GetQueueLine = ""
  Do While (StatusQueue(iq))
  debug.print "1"
    Dim b as Byte
	debug.print "2"
    Call GetQueue(iq, b, SizeOf(b))
	debug.print "3"
    Call PutQueueByte(lq, b)
	debug.print "4"
    If (b = &H0a) Then
      ' extract the accumulated line from the queue and clear it
      GetQueueLine = GetQueueStr(lq)
      Call ClearQueue(lq)
      Exit Do
    End If
  Loop
End Function
Im running the function above, and its stopping at Call PutQueueByte(lq, b), any ideas why?

I know that 'b' has a value at that point and the lq queue exists

If I change it so that its saving the data into a string rather than a queue it works, odd.

Cheers

Ben

Posted: 24 March 2009, 19:54 PM
by sturgessb
hmm when i said it worked with string i was jumping the gun a bit, here is the output.

Code: Select all

T,1,11.34

C,1412,1590,1522,1540,0,0,0,0
S,443,222,0,28,0
G,0,90.0,0.0,137.0,0,0,0




G,0,90.0,0.0,137.0,0,0,0
.34

C,1412,1590,1522,1540,0,0,0,0
,443,221,0,29,0
As you can see its bit of a mess, each line should begin with a letter, so it seems im missing data[/code]

Posted: 24 March 2009, 19:55 PM
by dkinzer
sturgessb wrote:Im running the function above, and its stopping at Call PutQueueByte(lq, b), any ideas why?
My conjecture is that the queue you're attempting to insert into hasn't been initialized (using OpenQueue()).

Using a String is a good alternative, perhaps slightly slower.

Posted: 25 March 2009, 12:48 PM
by sturgessb
right you are!