PDA

View Full Version : Indexer not indexing...a basic PBP problem??



jellis00
- 24th March 2009, 04:17
I feel rather stupid asking about this very basic Basic problem, but have wasted a full day trying to troubleshoot it.

I have a block in my current coding project that defies my understanding of how PICBasic Pro works. I have been programming in Visual Basic for years and thought that indexing inside of a While...Wend loop in PICBasic Pro would work the same as in Visual Basic. Evidently it doesn't. I have posted the relevent code below and would appreciate someone explaining to me why the indexing I am trying to do isn't working. Here is an explanation of what I thought the code was doing.

Basically what I am trying to do is count the received pulses on a pin during each 10 sec epoch, add the result of each epoch to previous epochs, and when the total accumulation reaches a predefined pulse count that is used as the condition of the While...Wend, to jump out of the loop. Because the indexing is not happening, the loop is continuous And the indexing isn't happening because the count variable is not being added to the index variable in the indexing statement.

As you can see from the code, I initialize a count variable, C1, and a count index, i, to zero before entering the While...End loop.

I then use a COUNT statement to count the incoming pulses on the RA1 pin in PORTA.1 over a period of 10 seconds.

I then write the value in the count variable C1 to EEProm locations 5 & 6 so I can read it as a test after the program runs. My testing shows by this method that the COUNT statement is collecting the pulse count during each 10 second epoch. The total number of pulses is low enough to be contained in only Byte0 of the C1 variable.

I blink a LED one time after each epoch that executes the COUNT statement so I can see the result at end of each epoch if I want to during testing and see what is going on.

Now the next statement is where the PICBasic isn't working as I expected it to.....the statement i = i + C1 is intended to index the variable i for use in the WHILE condition check. What is happening is that the value in C1 is not being added to i in this indexing statement. I know that because I see by reading EEPROM memory after the program is run that the value that is written by the WRITE 8,i statement never stores a value other than zero, which was the original initialization of the index.

My problem is I don't know why the value in C1 is not being added to i in the indexing statement. Is there something I am misunderstanding about PICBasic versus Visual Basic?? I am using this code with a PICkit2 and PIC16F690 chip. Any other suggestions as to how to do this??


'Registers Settings
TRISA = 0 ' Set PORTA pins to outputs
TRISB = 0 ' Set all PORTB and PORTC pins to outputs
TRISC = 0
ANSEL = 0 ' Set all pins to digital
ANSELH = 0
PORTC = 0 ' Preset LEDs off
TRISA.1 =1 ' Set RA1 as input port for meter pulse inputs

'Variables Initialization
k CON 30 ' Calibration factor for flow meter...# pulses per gal
i VAR WORD ' Index used in Gallon counter While loop
C1 VAR WORD ' Storage variable for count from COUNTER

'Start...normal code here
MAIN:

'Send PWM pulse to latching solenoid to open valve
Generates 10 millisec pulse on RC3 output pin
LOW PORTC.3 ' Initialize output pulse polarity
PULSOUT PORTC.3,1000 ' Generate 10 msec pulse to RC3

' Valve should be open at this point and water flowing

' Start measuring output of flow meter at RA1 input pin
C1 = 0 ' Initialize pulse count variable to zero
i = 0 ' Initialize total pulse count index to zero
WRITE 7,i
WHILE i <= 20 ' Assume it takes 20 accumulated pulses for required gallons
' Count the number of pulses from Hall Effect Magnetic Sensor in 10 sec
' epochs and add count from each epoch to total accumulation and then
' shutoff the valve when index reaches While...Wend i <=20 criteria.
Count PORTA.1,10000,C1
WRITE 5,C1.Byte0 ' Write count into EEPROM location 5,6 for post-run count test
WRITE 6,C1.Byte1
'Slowly blink LED during water flow
HIGH PORTC.0 ' If we get here, Blink the LED once
PAUSE 200
LOW PORTC.0
' THIS NEXT STATEMENT IS WHERE THE PROBLEM LIES...i doesn't get
' indexed by value of C1!!
i = i + C1 ' Add count to total accumulation to index loop
WRITE 8,i 'Store result for post-run test
WEND 'When C1 = 20, required gallons have flowed by the meter

ShutValve: 'Send PWM pulse to latching solenoid to close valve
PULSOUT PORTC.3,1000 ' Generate required 10 msec pulse to RC3
END

Archangel
- 24th March 2009, 05:44
Hi jellis00,
Don't know if this is a problem or not, I have never seen it done this way before:
C1.Byte0
C1.Byte1
I have seen it done this way:

C1.HighByte
C1.LowByte

Jerson
- 24th March 2009, 06:10
Jellis

There seems to be some inconsistency in your code. Before the while, you write 7,i
In the while, you do i=i+c1 followed by write 8,i The variable i being a word sized entity would write to 8,9. Is this what you're seeing? Location 8 will always read 0 since the high byte of i would be zero (you're counting till 20 only). Other than this, the only reason for not breaking out of the code will be C1 never catches any counts.

Jerson

Ioannis
- 24th March 2009, 07:35
Also I don't like the pause 200 inside the loop. Are you sure you are not missing any events there?

Ioannis

Archangel
- 24th March 2009, 07:54
Jellis

There seems to be some inconsistency in your code. Before the while, you write 7,i
In the while, you do i=i+c1 followed by write 8,i The variable i being a word sized entity would write to 8,9. Is this what you're seeing? Location 8 will always read 0 since the high byte of i would be zero (you're counting till 20 only). Other than this, the only reason for not breaking out of the code will be C1 never catches any counts.

Jerson
Hi Jerson,
So he would need to do write 8,i.HighByte Write 9,i.LowByte ?
EDIT: thinking about it . . . if he is only counting to 20, why use a word variable at all, should be a byte , Now I get it.

Jerson
- 24th March 2009, 13:50
Hi Joe

The initial write is to locations 7 and 8. The write inside the while loop is to 8,9. So, the location that I assume he's looking at is 7 this obviously wouldn't change from 0.

Archangel
- 24th March 2009, 16:33
Hi Joe

The initial write is to locations 7 and 8. The write inside the while loop is to 8,9. So, the location that I assume he's looking at is 7 this obviously wouldn't change from 0. Hi Jerson, I get that, if you store your lawnmower in your own garage, looking next door will likely not find it. I am curious though, his statement :
WRITE 5,C1.Byte0 ' Write count into EEPROM location 5,6 for post-run count test
WRITE 6,C1.Byte1
is this valid in PBP ? And my second question pertains to his declaring i as WORD, Wouldn't he write it as var.lowbyte ?

jellis00
- 24th March 2009, 16:49
Thanks to the excellent advice from you guys, I modified the code and it now works in the form shown below. Notice I also changed the processing epoch of the COUNT loop and reduced the Pause, because of one of your comments. With this sampling rate of the sensor pulse input rate I shouldn't miss any events. Even if I miss a couple, this resolution will adequately support the application.

I am also going to continue to use WORD rather than BYTE for the variables since the production version may encounter more than 256 events during the combined epochs.

When I finally understood from your comments that WRITE was overwriting the EEPROM address that I was using to see if the indexer was indexing with a HighByte that was continuously zero, I was able to solve the problem. Actually, the indexer statement was working....I just couldn't see that it was by the way I was trying to monitor it.
Can't tell you all enough how much I appreciate your help in resolving this problem! As a long term Visual Basic programmer, my faith in PBP is restored!
:D


'Registers Settings
TRISA = 0 ' Set PORTA pins to outputs
TRISB = 0 ' Set all PORTB and PORTC pins to outputs
TRISC = 0
ANSEL = 0 ' Set all pins to digital
ANSELH = 0
PORTC = 0 ' Preset LEDs off
TRISA.1 =1 ' Set RA1 as input port for meter pulse inputs

'Variables Initialization
switchstate var bit ' Stores value of last measured switchstate
k CON 60 ' Calibration factor for flow meter...# pulses per gal
i VAR WORD ' Index used in Gallon counter Repeat...Until loop
C1 VAR WORD ' Storage variable for count from COUNTER

'Start...normal code here
MAIN:
'Send PWM pulse to latching solenoid to open valve
'Generates 10 millisec pulse on RC3 output pin
LOW PORTC.3 ' Initialize output pulse polarity
PULSOUT PORTC.3,1000 ' Generate 10 msec pulse to RC3

' Valve should be open at this point and water flowing

' Start measuring output of flow meter at RA1 input pin
C1 = 0 ' Initialize pulse count variable to zero
i = 0 ' Initialize total pulse count index to zero
REPEAT ' Assume it takes k accumulated pulses for required gallons
' Count the number of pulses from Hall Effect Magnetic Sensor in 5 sec
' epochs and add count from each epoch to total accumulation and then
' shutoff the valve when count meets i>k criteria.
Count PORTA.1,5000,C1
'WRITE 5,C1.HighByte ' Write count into EEPROM location 5,6 during
'WRITE 6,C1.LowByte ' pre-production testing
'Slowly blink LED during water flow
HIGH PORTC.0 ' If we get here, Blink the LED once
PAUSE 100
LOW PORTC.0
i = i + C1 ' Add count to total pulse accumulation indexer
'When i >= k, required gallons have flowed by the meter
UNTIL i > k
'WRITE 7,i.HighByte 'Store result as test of code..not in production
'Write 8,i.LowByte
GoTo ShutValve

ShutValve: 'Send PWM pulse to latching solenoid to close valve
PULSOUT PORTC.3,1000 ' Generate required 10 msec pulse to RC3

' Valve should be closed at this point and no water flowing

' Put code here to test if flow meter has stopped as an indication that
' no water is flowing...is a double check on valve closure.
C1 = 0 ' Reset pulse counter to zero
Count PORTA.1,10000,C1 ' Collect meter pulse input, if any, for 10 secs
IF C1 > 0 Then
' Water is still flowing...close the valve!
PULSOUT PORTC.3,1000 ' Command valve solenoid to close
ENDIF

' Put code here to put Microcontroller back to Sleep State to wait for
' next Interrupt
SLEEP = 65,535
END

Archangel
- 24th March 2009, 16:53
Thanks to the excellent advice from you guys, I modified the code and it now works in the form shown below. Notice I also changed the processing epoch of the COUNT loop and reduced the Pause, because of one of your comments. With this sampling rate of the sensor pulse input rate I shouldn't miss any events. Even if I miss a couple, this resolution will adequately support the application.

I am also going to continue to use WORD rather than BYTE for the variables since the production version may encounter more than 256 events during the combined epochs.

When I finally understood from your comments that WRITE was overwriting the EEPROM address that I was using to see if the indexer was indexing with a HighByte that was continuously zero, I was able to solve the problem. Actually, the indexer statement was working....I just couldn't see that it was by the way I was trying to monitor it.
Can't tell you all enough how much I appreciate your help in resolving this problem! As a long term Visual Basic programmer, my faith in PBP is restored!
:D


'Registers Settings
TRISA = 0 ' Set PORTA pins to outputs
TRISB = 0 ' Set all PORTB and PORTC pins to outputs
TRISC = 0
ANSEL = 0 ' Set all pins to digital
ANSELH = 0
PORTC = 0 ' Preset LEDs off
TRISA.1 =1 ' Set RA1 as input port for meter pulse inputs

'Variables Initialization
switchstate var bit ' Stores value of last measured switchstate
k CON 60 ' Calibration factor for flow meter...# pulses per gal
i VAR WORD ' Index used in Gallon counter Repeat...Until loop
C1 VAR WORD ' Storage variable for count from COUNTER

'Start...normal code here
MAIN:
'Send PWM pulse to latching solenoid to open valve
'Generates 10 millisec pulse on RC3 output pin
LOW PORTC.3 ' Initialize output pulse polarity
PULSOUT PORTC.3,1000 ' Generate 10 msec pulse to RC3

' Valve should be open at this point and water flowing

' Start measuring output of flow meter at RA1 input pin
C1 = 0 ' Initialize pulse count variable to zero
i = 0 ' Initialize total pulse count index to zero
REPEAT ' Assume it takes k accumulated pulses for required gallons
' Count the number of pulses from Hall Effect Magnetic Sensor in 5 sec
' epochs and add count from each epoch to total accumulation and then
' shutoff the valve when count meets i>k criteria.
Count PORTA.1,5000,C1
'WRITE 5,C1.HighByte ' Write count into EEPROM location 5,6 during
'WRITE 6,C1.LowByte ' pre-production testing
'Slowly blink LED during water flow
HIGH PORTC.0 ' If we get here, Blink the LED once
PAUSE 100
LOW PORTC.0
i = i + C1 ' Add count to total pulse accumulation indexer
'When i >= k, required gallons have flowed by the meter
UNTIL i > k
'WRITE 7,i.HighByte 'Store result as test of code..not in production
'Write 8,i.LowByte
GoTo ShutValve

ShutValve: 'Send PWM pulse to latching solenoid to close valve
PULSOUT PORTC.3,1000 ' Generate required 10 msec pulse to RC3

' Valve should be closed at this point and no water flowing

' Put code here to test if flow meter has stopped as an indication that
' no water is flowing...is a double check on valve closure.
C1 = 0 ' Reset pulse counter to zero
Count PORTA.1,10000,C1 ' Collect meter pulse input, if any, for 10 secs
IF C1 > 0 Then
' Water is still flowing...close the valve!
PULSOUT PORTC.3,1000 ' Command valve solenoid to close
ENDIF

' Put code here to put Microcontroller back to Sleep State to wait for
' next Interrupt
SLEEP = 65,535
END

Hi jellis00,
My question was, . . . actually, answered in this final cut of your code. Thank You