variable 'FIndexOut' might have not been initialized

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
garryp4
Posts: 126
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

variable 'FIndexOut' might have not been initialized

Post by garryp4 » Thu Mar 08, 2012 1:01 am

I'm trying to get the ISRRX to work. When I compile I get a warning "variable 'FIndexOut' might have not been initialized". A search of the forum had one reference to this and the3 fix was to initialize the ISRRX module. I do have the statement but still get the error.

Code: Select all

// device and clock...                                                                                                                                                                                                                                         
Device = 18F8722
Clock  = 32


// import modules...
Include "USART.bas"
Include "USART2.bas"
Include "convert.bas"
Include "UTILS.BAS"
Include "ISRRX.BAS"

// declare ports
Dim 
  green         As PORTJ.1,             ' Green LED output
  red           As PORTJ.2              ' Red LED output
  
// declare variables
Private Dim
  data_str      As String(10)
 
'****************************************************************
Private Sub LED()
  High(red)
  DelayMS(30)
  Low(red)
  High(green)
  DelayMS(30)
  Low(green)
End Sub  
'****************************************************************
Sub OnData()
  High(red)
  ISRRX.ReadStr(data_str,10)
                                                          
End Sub
'****************************************************************
'****************************************************************
'****************************************************************

OSCCON  = $FC
OSCTUNE = $C0
ADCON0  = $00
ADCON1  = $0F

USART.SetBaudrate(br9600)
ISRRX.Initialize(@OnData)


Low(green)
Low(red)

LED

USART.Write("I'M ALIVE",10,13)
DelayMS(2)

'****************************************************************
MAIN:

  ISRRX.Start
  
  While red = 0
  Wend
  
  USART.Write(data_str, 10,13)
  
  GoTo MAIN
Thanks

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Thu Mar 08, 2012 10:50 am

Change your OnData() routine from a sub to an event...

Code: Select all

event OnData()
  High(red)
  ISRRX.ReadStr(data_str,10)
end event

.....

ISRRX.Initialize(OnData)
That will make the warning go away.

However, you should probably rethink having the ISRRX.ReadStr() call in there though.

ReadStr() is a blocking function and won't return until it sees the termination character (a LF in this case), but the event will be called by the OnRx() interrupt each time a character is received.

You probably want to move the ReadStr() call into your main loop before the USART.Write() call. That way, it'll wait there until it sees a line-feed.

garryp4
Posts: 126
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

Post by garryp4 » Thu Mar 08, 2012 6:49 pm

Jerry:

Thanks, again, for the quick and accurate help. I The purpose of the circuit is to monitor a serial line for instructions from a factory automation system. The instructions can be from 6 to 12 characters long and I have no control over a terminator character. Unfortunately it is probably easier to accommodate what is sent vs trying to get the message sent. Some wheels turn mighty slow. Anyway, I planned for the interrupt routine to capture the complete received instruction as there is nothing to do until it is all received.

Just as you said, changing from Sub to Event did fix the error. I have been playing around with the code for a bit and am stuck again.

Code: Select all

// device and clock...                                                                                                                                                                                                                                         
Device = 18F8722
Clock  = 32


// import modules...
Include "USART.bas"
Include "USART2.bas"
Include "convert.bas"
Include "UTILS.BAS"
Include "ISRRX.BAS"

// declare ports
Dim 
  green         As PORTJ.1,             ' Green LED output
  red           As PORTJ.2              ' Red LED output
  
// declare variables
Private Dim
  data_str      As String(12),
  lp1           As Byte,
  lp2           As Byte
 
'****************************************************************
Private Sub LED()
  High(red)
  DelayMS(30)
  Low(red)
  High(green)
  DelayMS(30)
  Low(green)
End Sub  
'****************************************************************
Event OnData()
  ISRRX.Stop
  data_str(0) = USART.ReadByte
  While USART.DataAvailableTIMEOUT(10) = TRUE
    data_str(lp1) = USART.ReadByte
    Inc(lp1)
  Wend
  High(red)                                                          
End Event
'****************************************************************

OSCCON  = $FC
OSCTUNE = $C0
ADCON0  = $00
ADCON1  = $0F

USART.SetBaudrate(br9600)
USART2.SetBaudrate(br9600)
ISRRX.Initialize(OnData)

Low(green)
Low(red)

LED

USART2.Write("I'M ALIVE",10,13)
DelayMS(2)

'****************************************************************
MAIN:

  ISRRX.Start
  lp1 = 1
  High(green)
  
  While red = 0
  Wend

  Low(green)
  DELAYMS(500)  
  For lp2 = 0 To lp1 
    USART2.Write(data_str(lp2))
  Next
  USART2.Write(10,13,DECTOSTR(LP1),10,13)
  LOW(RED)  
  ISRRX.Start  
  
  While true
  Wend
I included setting the LED's so could see when lines have been executed. Now everything works except I loose the first character from the received serial instruction. The count (lp1) is also 9 when 10 characters were sent. Any suggestions are definitely greatly appreciated.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Thu Mar 08, 2012 7:08 pm

The instructions can be from 6 to 12 characters long and I have no control over a terminator character
Since the messages are variable size, how do you know when one ends and another begins?

Does the system send anything to delimit messages or do you have to look at the content to figure out how long a message is?

garryp4
Posts: 126
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

Post by garryp4 » Thu Mar 08, 2012 7:35 pm

Jerry:

The circuit is to set up recipes for a 'legacy' production tool in a semiconductor manufacturing facility. 'Legacy' it the bean-counter term. The rest of us just call them old. What I'm doing is hijacking data lines and select lines and decoding two 7 segment display signals to determine the current recipe and pulsing an 'up' or 'down' line to change as needed. The automation system send me a recipe # and product position # and I set up the tool. The whole sequence is initiated by me when I sense a position occupied switch and send a message off to the automation system. So all but 1 instruction from the system is actually initiated by me so I do not have to worry about receiving messages on the fly. There is one 'STATUS' instruction that can be prompted by the equipment operator but that would not happen very often or when the other setup is happening.

Again, thanks for the help.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Fri Mar 09, 2012 12:23 am

You want to watch mixing ISRRX and USART calls. The interrupt handler in ISRRX already reads the usart and buffers up chars for you, so if you're using it you want to make sure you read chars from its buffer, and not the USART.

Perhaps something like this as an example, although there's bunches of different ways of doing it. Beware... code's completely untested.

Code: Select all

// device and clock...                                                                                                                                                                                                                                         
device = 18F8722
clock  = 32


// import modules...
include "USART.bas"
include "USART2.bas"
include "convert.bas"
include "UTILS.BAS"
include "ISRRX.BAS"

// declare ports
dim
  green         as PORTJ.1,             ' Green LED output
  red           as PORTJ.2              ' Red LED output
 
// declare variables
private dim
  data_str      as string(12),
  lp1           as byte,
  idle_time     as byte,
  got_msg       as boolean
 
'****************************************************************
private sub LED()
  high(red)
  delayms(30)
  low(red)
  high(green)
  delayms(30)
  low(green)
end sub 
'****************************************************************
' we don't really do anything here except turn on the red led each 
' time we receive a char
event OnData()
  high(red)
end event
'****************************************************************

OSCCON  = $FC
OSCTUNE = $C0
ADCON0  = $00
ADCON1  = $0F

USART.SetBaudrate(br9600)
USART2.SetBaudrate(br9600)

low(green)
low(red)

LED()

ISRRX.Initialize(OnData)

USART2.Write("I'M ALIVE",10,13)
delayms(2)

'****************************************************************

MAIN:
    idle_time = 0
    lp1 = 0                                 // input char count
    got_msg = false
    high(green)
 
    // wait here until we see the first char...
    while (ISRRX.DataAvailable() = false)
    wend

    // gather up chars until we get an entire message or 100ms elapses
    while (got_msg = false)
        if (ISRRX.DataAvailable()) then         // check to see if a char is available
            low(red)                            // turn off the red led
            data_str(lp1) = ISRRX.ReadByte()    // if so, read it and put into our buffer
            inc(lp1)                            // next position in the buffer
        else
            idle_time = idle_time + 1           // no new chars
            delayms(1)
        endif

        if (idle_time > 100) then               // we've been idle for 100msec with no chars...
            if (lp1 > 0) then                   // we have chars in our buffer...
                got_msg = true                  // exit loop and process msg
            endif
        endif
    wend

    // got_msg is true
    low(green)                          // drop green to indicate we're sending
    data_str(lp1) = 0                   // null-terminate the buffer string
    USART2.Write(data_str)              // send the string to usart2
    USART2.Write(10,13,DECTOSTR(LP1),10,13)     // and the count

    goto main

garryp4
Posts: 126
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

Post by garryp4 » Sat Mar 10, 2012 3:00 pm

Jerry:

Thanks again for the quick reply. Seems an issue is I just don't understand how the ISRRX module works. After your last message I changed the event call to:

Code: Select all

'****************************************************************
Event OnData()
  ISRRX.Stop
  data_str(0) = isrrx.dataByte
  While USART.DataAvailableTimeout(10) = TRUE
    data_str(lp1) = USART.ReadByte
    Inc(lp1)
  Wend
  High(red)                                                          
End Event
'****************************************************************
It seems to work just fine. I do have to ask about your caution of mixing the USART and ISRRX. What problems would you expect to see?

Again, thanks for your help. I believe I now owe you 3 cold one's for this and previous help.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sat Mar 10, 2012 4:11 pm

I do have to ask about your caution of mixing the USART and ISRRX. What problems would you expect to see?
All sorts of mysterious things.

ISRRX provides an interrupt-driven receiver for the uart. Its job is to work behind the scenes and automatically read characters as they come in over the serial port. It puts these characters into its own local buffer (the FBuffer() array), and you can read them at your leisure.

Contrast this to the regular uart module. There, if you're busy doing something time consuming and don't call USART.Read() often/fast enough, you'll lose characters because the hardware can only buffer up two of them before you begin to drop characters.

The OnData() event you're playing around with is called from inside the uart's interrupt routine after it's read the character and before it puts it into the buffer. Take a look at the example in the help file for an idea of how you can use the event. I wouldn't do anything to touch the actual uart hardware unless you really know what you're doing, or wait around since that'll block anything else from running.

garryp4
Posts: 126
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

Post by garryp4 » Thu Mar 29, 2012 11:29 am

Jerry:

Right again. Mixing ISRRX and USART seemed to cause problems when using an LCD. No idea why but when I commented out the LCD code it worked again.

An your 'untested' code ran just as commented! I cut, paste, compile, ran.

I sure wish I could properly thank you for this and previous help. It is very appreciated

Post Reply