PDA

View Full Version : Passing Vars to multiple cogs and back



W9GFO
07-12-2009, 03:29 PM
I think I figured a way to read pulse widths on 6 pins using counters on three cogs.

I've created an object called RX which launches the three cogs. I need to pass the the pins and the pulseWidth variables to the object, they are both arrays.



RX.start(pins, @pulseWidth)



When the new cogs are started they each need two pins for the counters and two variables in which to put the values.

Here is what I tried...



PUB Start (pins, pulsewidth)

cog[ 0] := (cog := cognew(readPins(pins, pulsewidth), @ stack) + 1)
cog[ 1] := (cog := cognew(readPins(pins[ 2], pulsewidth[ 2]), @ stack[100]) + 1)
cog[ 2] := (cog := cognew(readPins(pins[ 4], pulsewidth[ 4]), @ stack[200]) + 1)



PUB readPins (pins, pulsewidth)

ctra[31..26] := %01000 ' set mode to pos detector
ctra[5..0] := pins

ctrb[31..26] := %01000
ctrb[5..0] := pins[ 1]

frqa := 1
frqb := 1

dira[pins]~
dira[pins[ 1]]~

repeat
repeat while pins
phsa~
waitcnt(clkfreq/200)
pulsewidth := phsa/(clkfreq/1_000_000)

repeat while pins[ 1]
phsb~
waitcnt(clkfreq/200)
pulsewidth[ 1] := phsb/(clkfreq/1_000_000)



It is not working on any pins. I suspect that the pulseWidth variable is not getting written to properly, it is not clear to me if I need to use "@" before each "pulseWidth" or something else.
I'm pretty sure I could just write out the code for each cog and each variable but I am trying to figure out how to do it with minimal clutter.

Also, I am not sure if I am passing the pin values to each cog properly...

Rich H

Post Edited (W9GFO) : 7/12/2009 7:34:16 AM GMT

SamMishal
07-12-2009, 08:52 PM
There are a few problems with your code

The line
···· RX.start(pins,·@pulseWidth)
should be
···· RX.start(@pins,·@pulseWidth)

the lines
··ctra[5..0]·:=·pins
and
··ctrb[5..0]·:=·pins[·1]
and
··dira[pins]~
··dira[pins[·1]]~


should be assuming pins is an array of longs....if it is bytes(more efficient) then change to byte
··ctra[5..0]·:=·long[pins][0]
and
··ctrb[5..0]·:=·long[pins][·1]
and
··dira[long[pins][0]]~
··dira[long[pins][·1]]~


the line
···repeat·while·pins
and
···repeat·while·pins[·1]


should be
···repeat·while·long[pins][0]
and
···repeat·while·long[pins][·1]


but also look at the commands WaitPEQ and WaitPNE that do what you are trying to do more efficiently

the lines
···pulsewidth·:=·phsa/(clkfreq/1_000_000)
and
···pulsewidth[·1]·:=·phsb/(clkfreq/1_000_000)


should be
···long[pulsewidth][0]·:=·phsa/(clkfreq/1_000_000)
and
···long[pulsewidth][·1]·:=·phsb/(clkfreq/1_000_000)


Also you are using WAY TOO much stack to each cog....10 to 15 should be OK

Sam

SamMishal
07-12-2009, 09:01 PM
Oh also



the lines

··cog[·0]·:=·(cog·:=·cognew(readPins(pins,·pulsewidth),·@·s tack)·+·1)
··cog[·1]·:=·(cog·:=·cognew(readPins(pins[·2],·pulsewidth[·2]),·@·stack[100])·+·1)
··cog[·2]·:=·(cog·:=·cognew(readPins(pins[·4],·pulsewidth[·4]),·@·stack[200])·+·1)

should be

··cog[·0]·:=·(cog·:=·cognew(readPins(@Long[pins][0],·@long[pulsewidth][0]),·@·stack)·+·1)
··cog[·1]·:=·(cog·:=·cognew(readPins(@Long[pins][·2],·@long[pulsewidth][·2]),·@·stack[100])·+·1)
··cog[·2]·:=·(cog·:=·cognew(readPins(@log[pins][·4],·@long[pulsewidth][·4]),·@·stack[200])·+·1)

W9GFO
07-13-2009, 12:59 AM
Thanks Sam. it is still not working unfortunately. I do have something displayed other than zeros now but the numbers don't makes sense. I expected one number (1520) and the other five fields zero. What I get, after about one minute, is 733805, 0, 7357XX, 0, 735260, 0. The "XX" is because the number runs off the display. The number will be different each time the program is run and it stays the same value.

In case it changes anything, the pins and pulsewidths are declared thusly,



VAR

long pulsewidth[ 6]

DAT

pins LONG 1, 2, 3, 4, 5, 6



In the top level object;



PUB RXinput

repeat until pressed == 0 ' Don't proceed until button let go
ButtonCheck

LCD.clear

RX.start(@pins,@pulseWidth)

repeat

ButtonCheck
debug(pulsewidth[ 0], 4, 1, false, 4, 0) ' (value, X, Y, decimal?, digits, places)
debug(pulsewidth[ 1], 10, 1, false, 4, 0)
debug(pulsewidth[ 2], 16, 1, false, 4, 0)
debug(pulsewidth[ 3], 4, 2, false, 4, 0)
debug(pulsewidth[ 4], 10, 2, false, 4, 0)
debug(pulsewidth[ 5], 16, 2, false, 4, 0)

out(7,pulsewidth[ 0])
out(8,pulsewidth[ 1])
out(9,pulsewidth[ 2])
out(10,pulsewidth[ 3])
out(11,pulsewidth[ 4])
out(12,pulsewidth[ 5])



The RX object;



VAR

byte cog[ 3]
long stack[60]

PUB Start (pins, pulsewidth)

cog[ 0] := cognew(readPins(@long[pins][ 0], @long[pulsewidth][ 0]), @ stack) + 1
cog[ 1] := cognew(readPins(@long[pins][ 2], @long[pulsewidth][ 2]), @ stack[20]) + 1
cog[ 2] := cognew(readPins(@long[pins][ 4], @long[pulsewidth][ 4]), @ stack[40]) + 1

PUB readPins (pins, pulsewidth)

ctra[31..26] := %01000 ' set mode to pos detector
ctra[5..0] := long[pins][ 0]

ctrb[31..26] := %01000
ctrb[5..0] := long[pins][ 1]

frqa := 1
frqb := 1

dira[long[pins][ 0]]~
dira[long[pins][ 1]]~

repeat
repeat while long[pins][ 0]
phsa~
waitcnt(clkfreq/200 + cnt)
long[pulsewidth][ 0] := phsa/(clkfreq/1_000_000)

repeat while long[pins][ 1]
phsb~
waitcnt(clkfreq/200 + cnt)
long[pulsewidth][ 1] := phsb/(clkfreq/1_000_000)

PUB Stop
if cog
cogstop(cog[ 0]~ -1)
cogstop(cog[ 1]~ -1)
cogstop(cog[ 2]~ -1)

Post Edited (W9GFO) : 7/12/2009 5:57:54 PM GMT

SamMishal
07-13-2009, 01:23 AM
Rich,



from a first look there are STILL plenty of errors.....but I am busy rght now and I will

be back home in a few hours...I will point a few just now but there are MANY more....

I will do later

CON

··_clkmode·=·xtal1·+·pll16x
··_xinfreq·=·5_000_000

should be in the TopLevel object

···repeat·while·long[pins][·0]
····phsa~
····waitcnt(clkfreq/200)
····long[pulsewidth][·0]·:=·phsa/(clkfreq/1_000_000)

I think you did not mean to have the three lines under the repeat indented.....no??·

Also the line
····waitcnt(clkfreq/200)

should be·(there two of these)
····waitcnt(clkfreq/200+cnt)

Your Stop method is erroneous....the line
···· if cog

is wrong since cog is pointer and will always be non-zero.....


These lines
··cog[0]·:=·(cog·:=·cognew(readPins(@long[pins][·0],·@long[pulsewidth][·0]),·@·stack)·+·1)
··cog·:=·(cog·:=·cognew(readPins(@long[pins][·2],·@long[pulsewidth][·2]),·@·stack[20])·+·1)
··cog·:=·(cog·:=·cognew(readPins(@long[pins][·4],·@long[pulsewidth][·4]),·@·stack[40])·+·1)

should be

··cog[0]·:=·cognew(readPins(@long[pins][·0],·@long[pulsewidth][·0]),·@·stack)·+·1
··cog[1]·:=·cognew(readPins(@long[pins][·2],·@long[pulsewidth][·2]),·@·stack[20])·+·1
··cog[2]·:=·cognew(readPins(@long[pins][·4],·@long[pulsewidth][·4]),·@·stack[40])·+·1



I will look for more later



Sam

W9GFO
07-13-2009, 01:53 AM
Sheesh what a mess! So much for the great idea late last night...

The top level object is working well, this RX thing is something I'm trying to add.

The indentations were unintentional.
The missing " + cnt" has been fixed.

I changed the cog thing.

Now I get all zeros....

Im having trouble grasping how each cog will know to use different pins and pulseWidth locations.

The initial call passes the addresses to the start method.

RX.start(@pins, @pulsewidth)

The start method then passes those to the three cognews

cog[ 0] := cognew(readPins(@long[pins][ 0], @long[pulsewidth][ 0]), @ stack) + 1
cog[ 1] := cognew(readPins(@long[pins][ 2], @long[pulsewidth][ 2]), @ stack[20]) + 1
cog[ 2] := cognew(readPins(@long[pins][ 4], @long[pulsewidth][ 4]), @ stack[40]) + 1

Each cog is running the same readPins method

readPins (pins, pulsewidth)
" "
ctra[5..0] := long[pins][ 0]

How does the first cog know that long[pins][0] should be a "1" and the second cog know that long[pins][0] should be a "3"?

Rich H

Post Edited (W9GFO) : 7/12/2009 7:06:50 PM GMT

SamMishal
07-13-2009, 08:35 AM
W9GFO said...

How does the first cog know that long[pins][0] should be a "1" and the second cog know that long[pins][0] should be a "3"?

Rich H
Rich,

I am looking at your code now....but I wanted to answer your question.

When you say for example
····· cog[ 1] := cognew(readPins(@long[pins][ 2], @long[pulsewidth][ 2]), @ stack[20]) + 1
the variable pins holds an address to the FIRST number in the list of numbers.

So when you say @long[pins][2] you are saying the address of the 3rd number in the list of numbers that
start at the address whose value is in pins. So now since readpins() expects an adress this is perfectly RIGHT.....and then
when you later say inside readpins()

··· ctra[5..0] := long[pins][ 0]

the value in pins is now the address of the third number in the list of numbers
and Long[pins][0] is the value of that number

the next line
·· ctrb[5..0] := long[pins][1]
means the next long that follows the one that resides at the address that is pointed to by pins which is the 4th number

so you see that the function readpins() will now not care where pins points it will take the long that is at the
address pointed to by pins and the next one. So what you need is to make sure that for each cog to pass it the address
of the 1st of the pairs of numbers. So the first time you are passing the address of the 1st and readpins() will calculate
the address of the second. For the next call you are going to pass the address of the 3rd number and for the third call
you pass it the address of the 5th number and so on.


So knowing the address of the FIRST number (@pins) and you pass it along to the Start method it now can call the
readpins() but each time with the address of the 1st in the pair and
·· @long[pins][0]· is the address of the first number·in the 1st pair
·· @long[pins][2]· is the address of the first number in the 2nd pair
·· @long[pins][4]· is the address of the first number in the 3rd pair

and inside readpins() the address is de-referenced by using
·· Long[pins][0] and long[pins][1]

REMEMEBER pins in the Start method is not the same as the pins in the readpins() method....the confusion is
that you have named them the same name.....I usually prefer to name a variable that will hold an address rather than a value
as e.g. pinsaddress·· or··· pinspointer··· or something similar.

Sam



Post Edited (SamMishal) : 7/13/2009 12:42:39 AM GMT

SamMishal
07-13-2009, 09:42 AM
Hi Rich,

Here is a suggested code that I hope works.....the problem I think is the way you wait for the count....I do not think it
correct·to wait for clkfreq/200· which is 5 milliseconds....now that might count too many pulses or no pulses depending
on the frequency of the signal.....the way I have it is a better way.....you may have difficulty with the |< operator....read about it.
It is basically saying give me a binary value with 1 at the bit which is the Pin number and the rest of the bits are 0.

Another source of confusion might be the use of SPR register......read about it but basically
··· SPR[8] is the same as saying·CTRA and SPR[9] is the same as CTRB but with the SPR[] you can use a for-loop
··· so SPR[8+i] := .....····· is the same as saying CTRA :=.....· when i is 0 and CTRB := .... when i = 1

Also notice how the mode and pin are set in one expression.....this is necessary since SPR cannot be addressed bit by bit

Here is my suggested code.....I think this would work.....as I said the only REAL difference from your final code is the way it
waits for a pulse.



VAR
byte cog[ 3]
long stack[60]
long uS

PUB Start (pins_array_address, pulsewidth_array_address)|i
uS := clkfreq/1_000_000
Stop 'call the stop method to stop cogs tha may be already started
repeat i from 0 to 2
cog[i] := cognew(readPins(@long[pins_array_address][i*2], @long[pulsewidth_array_address][i*2]), @ stack[i*20]) + 1

PUB readPins (pins_address, pulsewidth_address)| i,p1,p2
repeat i from 0 to 1
spr[8+i] := %01000 << 26 + long[pins_address][i] 'set the mode and pin for ctra/b
spr[10+i] := 1 ' set frqa/b

p1 := long[pins_address][0]
p2 := long[pins_address][1]
dira[p1]~
dira[p2]~

repeat
waitPEQ(0 , |< p1,0) 'wait for low state
phsa~
waitPEQ(|< p1, |< p1,0) 'wait for high state ie pulse start on Pin1
waitPEQ(0 , |< p1,0) 'wait for low state i.e. pulse ended
long[pulsewidth_address][0] := phsa/uS

waitPEQ(0 , |< p2,0) 'wait for low state
phsb~
waitPEQ(|< p2, |< p2,0) 'wait for high state ie pulse start on Pin2
waitPEQ(0 , |< p2,0) 'wait for low state i.e. pulse ended
long[pulsewidth_address][1] := phsb/uS

PUB Stop | i
repeat i from 0 to 2
if cog[i]
cogstop(cog[i]~ -1)


Post Edited (SamMishal) : 7/13/2009 2:17:59 AM GMT

SamMishal
07-13-2009, 10:21 AM
Hi Rich,



I have changed the code a little since I posted it.....so please copy it again if you have
copied before you got this message.



I missed a few things.....oops....

Sam

W9GFO
07-13-2009, 11:19 AM
Thanks Sam, I just got back but will surely study it closely later on.

The idea for the wait clkfreq/200 was that the pulses will go high for between 500 and 2500 uS. The frequency is 50 hz.

My intention was that if the signal was high it was to remain in the repeat loop until it went low. If it was low then start counting but not for more than 5 mS (3 mS would be better) because I wanted to count only one pulse each time through. If nothing was connected to that pin it would not go high, would not increment the counter and would not hang. It is important that it not wait for the high state for more than a few mS because the high state might not happen.

I loaded the code, I get 1517 on the first three and 1516 on the other three pins, no matter what the input - even with no input. It's a step in the right direction.

I'm gonna dig into it tomorrow.

Rich H

Post Edited (W9GFO) : 7/13/2009 4:39:48 AM GMT

SamMishal
07-13-2009, 06:09 PM
Hi Rich,

OK....getting there....·the reason you are getting counts on the other ones is I think that you are not using a Pullup or pull down
(pullup is usually better) resistors on the pins. The propeller does not have internal pullups/downs.

When an input pin is floating the pin will get noise and usually a signal on a neighbouring pin will show up on the floating pin.

What you need is a pullup resistor (10K) on the pins. Then the pins that are not connected will always have a
high on them............................but then you have a problem with the code since it will hang...........

Since each cog counts the first pin then the second you will get a problem since if either is not connected
the cog will sit there forever wating (waitPQE) for the pin to go low and since you have a pull up it will not
even if you had a pull down the next waitpeq is waiting for high so it will still hang.

The problem is not with cogs that have both pins not connected since the cog will just sit there doing nothing
and that does not matter since you are not using it. Just make sure you always Zero the pulsewidth before you
start counting. Add these line before the repeat statement.
····· Long[pulsewidth_address][0]~
····· Long[pulsewidth_address][1]~

This way you always know the pins are not connected since the corresponding pulsewidth pair of values will be zero.

The real problem is with a cog that has one of the pins connnected but not the other.

One solution is to connect the other pin to the same signal. this way both pair will count the same signal.
So always either connect both pair to different signals or to the same signal.

Another (better) solution is to use this code instead.....make sure you have pullup resistors.
The red text is new stuff.


VAR
byte cog[ 3]
long stack[60]
long uS, WaitTime

PUB Start (pins_array_address, pulsewidth_array_address)|i
uS := clkfreq/1_000_000
WaitTime := clkfreq/200 'choose this time carefully
Stop 'call the stop method to stop cogs tha may be already started
repeat i from 0 to 2
cog[i] := cognew(readPins(@long[pins_array_address][i*2], @long[pulsewidth_array_address][i*2]), @ stack[i*20]) + 1

PUB readPins (pins_address, pulsewidth_address)| i,p1,p2
repeat i from 0 to 1
spr[8+i] := %01000 << 26 + long[pins_address][i] 'set the mode and pin for ctra/b
spr[10+i] := 1 ' set frqa/b

p1 := long[pins_address][0]
p2 := long[pins_address][1]
dira[p1]~
dira[p2]~
long[pulsewidth_address][0]~ 'add these lines to the code to make sure the count is zeroed
long[pulsewidth_address][1]~
repeat
if not WaitSignalState(0,P1,WaitTime) 'assuming you have pullups
phsa~
waitPEQ(|< p1, |< p1,0) 'wait for high state ie pulse start on Pin1
waitPEQ(0 , |< p1,0) 'wait for low state i.e. pulse ended
long[pulsewidth_address][0] := phsa/uS

if not WaitSignalState(0,P2,WaitTime) 'assuming you have pullups
phsb~
waitPEQ(|< p2, |< p2,0) 'wait for high state ie pulse start on Pin2
waitPEQ(0 , |< p2,0) 'wait for low state i.e. pulse ended
long[pulsewidth_address][1] := phsb/uS

Pri WaitSignalState(State,PinNo,TimeOut):TimedOut|T
T := TimeOut+cnt
repeat until ina[PinNo] == State or cnt => T
if Cnt => T
TimedOut := True

PUB Stop | i
repeat i from 0 to 2
if cog[i]
cogstop(cog[i]~ -1)


If you use the WaitSignalState subroutine to replace the other WaitPEQ statements you will not get an accurate
pulsewidth measurement due to the time it takes the code to execute....with a 50 Hz signal it does not matter much
since the propeller is VERY fast but waitpeq is the best way to go for more accuracy and to be able to capture
faster frequencies.

Samuel


Post Edited (SamMishal) : 7/13/2009 10:21:17 AM GMT

W9GFO
07-14-2009, 04:39 AM
Hmmm, needing pull up/pull down resistors completely escaped me. I have 4k7 ohm resistors on each pin to the header but that doesn't help with floating eh? Pull ups would be easier for me to add but I think pull downs are more appropriate. These six pins that I am using are the same six which are otherwise used for servo outputs. If they are pulled high I think that would interfere with the servo signals. If I pulled them low with a high value resistor that should allow outgoing servo pulses to do their thing. Would a 470 k ohm resistor be too high for a pull down?

I ran the above code, without adding any resistors and the results were identical to last time. The first 2 pins are getting a solid signal, the rest are floating. Shouldn't at least the first two pins be reporting the correct pulse width even though the rest of the pins are floating?

Rich H

SamMishal
07-14-2009, 05:56 AM
W9GFO said...
·but I think pull downs are more appropriate. These six pins that I am using are the same six which are otherwise used for servo outputs. If they are pulled high I think that would interfere with the servo signals.
Yes I should say so....pull downs would be better in this case.....but watch out for the logic of the operation...
it waits for low then high then low......if there is no signal then the low will be there anyway due to the pull down.....

So you will have to wait for low using WaitPEQ since that is guranteed....but then use the subroutine WaitSignalState using
the high state then wait for low using WaitPEQ......I will show code below.


W9GFO said...
·Would a 470 k ohm resistor be too high for a pull down?

I don't think so...I always use 10K....but 470K should be fine.....

W9GFO said...

I ran the above code, without adding any resistors and the results were identical to last time. The first 2 pins are getting a solid signal, the rest are floating. Shouldn't at least the first two pins be reporting the correct pulse width even though the rest of the pins are floating?

So you are saying that you connected signals to the first two pins and left the others unconnected?
And you are saying that they did not report the correct pulse width?....what were the results?


Anyway I think you should put the pull downs and then try again.....replace the lines of the repeat block with the following
(since now you have pull downs)



repeat
waitPEQ(0 , |< p1,0) 'wait for low state
phsa~
if not WaitSignalState(1,P1,WaitTime) 'wait for high with time out assuming you have pulldowns
waitPEQ(0 , |< p1,0) 'wait for low state i.e. pulse ended
long[pulsewidth_address][0] := phsa/uS

waitPEQ(0 , |< p2,0) 'wait for low state
phsb~
if not WaitSignalState(1,P2,WaitTime) 'wait for high with time out assuming you have pulldowns
waitPEQ(0 , |< p2,0) 'wait for low state i.e. pulse ended
long[pulsewidth_address][1] := phsb/uS


·Samuel
·

W9GFO
07-14-2009, 01:45 PM
Ok, I decided to take a step back and get the function working on one cog before trying to get all three going. I started a fresh program, all in one object.

The code below is working quite nicely. I had to add (3) to the pulsewidth value to make it correct.

Interestingly enough, if I disconnect one of the leads - the last reading remains. If it is started up with a lead disconnected it will read zero. That's good news for me, I really didn't want to have to add pull downs. However if there is a cable connected - which doesn't have the other end connected - then the readings go crazy. Touching the pin also makes the reading erratic, even coming close to touching it does ~ 2mm away. Since it seems to be steady otherwise, I don't think I'll bother with the pull downs at this point.

Now to add the other four counters...





PUB main | p1,p2

uS := clkfreq/1_000_000
WaitTime := uS * 20000

ctra[31..26] := %01000 ' set mode to pos detector
ctra[5..0] := pin[ 1] ' Pin 1

ctrb[31..26] := %01000
ctrb[5..0] := pin[ 2] ' Pin 2

frqa := 1
frqb := 1

dira[pin[ 1]]~
dira[pin[ 2]]~

p1 := pin[ 1]
p2 := pin[ 2]

LCD.str(string("Counters set! "))
waitcnt(clkfreq + cnt)
LCD.clear

repeat
waitPEQ(0 , |< p1,0) 'wait for low state
phsa~
if not WaitSignalState(1,P1,WaitTime) 'wait for high with time out assuming you have pulldowns
waitPEQ(0 , |< p1,0) 'wait for low state i.e. pulse ended
pulsewidth[0] := phsa/uS + 3

waitPEQ(0 , |< p2,0) 'wait for low state
phsb~
if not WaitSignalState(1,P2,WaitTime) 'wait for high with time out assuming you have pulldowns
waitPEQ(0 , |< p2,0) 'wait for low state i.e. pulse ended
pulsewidth := phsb/uS + 3

debug(pulsewidth[ 0], 4, 1, false, 4, 0) '(value, X, Y, decimal?, digits, places)
debug(pulsewidth[ 1], 10, 1, false, 4, 0)

Pri WaitSignalState(State,PinNo,TimeOut):TimedOut|T
T := TimeOut+cnt
repeat until ina[PinNo] == State or cnt => T
if Cnt => T
TimedOut := True




Rich H

Post Edited (W9GFO) : 7/14/2009 6:08:27 AM GMT

W9GFO
07-14-2009, 03:31 PM
This is weird. It works right up to the point where it displays "Cogs started" then just stays there. The display doesn't clear and it doesn't display the next string.

Whoa... wait a minute! After almost two minutes the screen clears, then 50 seconds later "No worky!!!" appears. Then, almost two more minutes pass and the "N" vanishes... Another minute goes by and the "o" disappears... Another couple goes by and I get a zero in place of the "w"...... At the 12 minute mark I get another zero in place of the 2nd "!"... zzzzzzzzzzzzzzzzz

I'm at 16 minutes into this program and the 3rd zero just showed up. That would be the third debug in the repeat loop.

Seems like something funny going on in the LCD object but I haven't even opened that file in weeks. Nope, I loaded another program that uses that object and it is fine.

It's like the cnt has to rollover before it executes each instruction. It took nearly thirty minutes to make it's way through the repeat loop for the first time.

The entire code is below for your amusement.




CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000


VAR
long pulsewidth[6]
long uS, WaitTime
long stack[60]
byte cog
DAT
pin LONG 1, 2, 3, 4, 5, 6

OBJ
LCD : "LCD_16X2_8BIT"

PUB Init

LCD.start
waitcnt(clkfreq/4 + cnt)
LCD.clear
LCD.str(string("RX test v 0.2 "))
waitcnt(clkfreq + cnt)
LCD.clear

main

PUB main | i

uS := clkfreq/1_000_000
WaitTime := uS * 20000

Stop 'call the stop method to stop cogs that may be already started
repeat i from 0 to 2
cog[ i] := cognew(readPins(@long[pin][i*2], @long[pulsewidth][i*2]), @ stack[i*20]) + 1

LCD.str(string("Cogs started")) ' ********** here is where it slows waaaaaaay down **************
waitcnt(clkfreq + cnt)
LCD.clear
LCD.str(string("No worky!!!!"))

repeat
debug(pulsewidth[ 0], 4, 1, false, 4, 0) '(value, X, Y, decimal?, digits, places)
debug(pulsewidth[ 1], 10, 1, false, 4, 0)
debug(pulsewidth[ 2], 16, 1, false, 4, 0)
debug(pulsewidth[ 3], 4, 2, false, 4, 0)
debug(pulsewidth[ 4], 10, 2, false, 4, 0)
debug(pulsewidth[ 5], 16, 2, false, 4, 0)

PUB readPins (pins_address, pulsewidth_address)| i,p1,p2

repeat i from 0 to 1
spr[8+i] := %01000 << 26 + long[pins_address][ i] 'set the mode and pin for ctra/b
spr[10+i] := 1 ' set frqa/b

p1 := long[pins_address][ 0]
p2 := long[pins_address][ 1]
dira[p1]~
dira[p2]~
long[pulsewidth_address][ 0]~ 'add these lines to the code to make sure the count is zeroed
long[pulsewidth_address][ 1]~
repeat
waitPEQ(0 , |< p1,0) 'wait for low state
phsa~
if not WaitSignalState(1,P1,WaitTime) 'wait for high with time out assuming you have pulldowns
waitPEQ(0 , |< p1,0) 'wait for low state i.e. pulse ended
long[pulsewidth_address][ 0] := phsa/uS

waitPEQ(0 , |< p2,0) 'wait for low state
phsb~
if not WaitSignalState(1,P2,WaitTime) 'wait for high with time out assuming you have pulldowns
waitPEQ(0 , |< p2,0) 'wait for low state i.e. pulse ended
long[pulsewidth_address][ 1] := phsb/uS


PUB Stop | i
repeat i from 0 to 2
if cog[ i]
cogstop(cog[ i]~ -1)

Pri WaitSignalState(State,PinNo,TimeOut):TimedOut|T
T := TimeOut+cnt
repeat until ina[PinNo] == State or cnt => T
if Cnt => T
TimedOut := True

PUB debug(value, X, Y, dec, digits, places) | divisor, number, spaces ' uS, 1, 12 true, 3

divisor := 1
number := 10

if dec

repeat places
divisor *= 10 ' calculate divisor based upon decimal places

repeat digits - 1
IF value/divisor > number -1 ' figure out how many digits are in number
x-- ' move x left to accomodate number if needed - keeping decimal in the same place
number *= 10 ' digits must be high enough to handle largest possible number or else number will get
' shifted when printed

LCD.move(X, Y) ' Position Cursor
LCD.dec(value / divisor) ' Print Whole Part
LCD.str(string(".")) ' Print Decimal Point

number := 10
repeat places - 1

IF value//divisor < divisor/number
LCD.dec (0)
number *= 10

LCD.dec (value//divisor)

else
spaces := 1

repeat digits - 1
IF value > number -1
spaces ++
number *= 10
LCD.move(X - digits + 1, Y)
repeat digits - spaces
LCD.str(string(" "))
LCD.dec(value)

Post Edited (W9GFO) : 7/14/2009 7:45:05 AM GMT

SamMishal
07-14-2009, 05:28 PM
W9GFO said...
Ok, I decided to take a step back and get the function working on one cog before trying to get all three going. I started a fresh program, all in one object.

Always a goood idea....start small.....build up gradually....debug each step along the way

W9GFO said...
The code below is working quite nicely. I had to add (3) to the pulsewidth value to make it correct.
·That is because the time it takes the SPIN code to do its work....also the signal itself may not be as accurate as you
·think if you have rounded values as you normally have to do with the NCO modes.


W9GFO said...
Interestingly enough, if I disconnect one of the leads - the last reading remains. If it is started up with a lead disconnected it will read zero.

·The setting of the pulsewidth fields to zero happens only once outside of the repeat loop and thus if it reads for a while and then you disconnect the
·signal the clearing will not happen again since it is now inside of the repeat loop and will never clear the pulsewidths again.

W9GFO said...
Interestingly enough, if I disconnect one of the leads - the last reading remains. If it is started up with a lead disconnected it will read zero. That's good news for me, I really didn't want to have to add pull downs. However if there is a cable connected - which doesn't have the other end connected - then the readings go crazy. Touching the pin also makes the reading erratic, even coming close to touching it does ~ 2mm away. Since it seems to be steady otherwise, I don't think I'll bother with the pull downs at this point.

·What you are describing is a CLASSIC situation of what happens when you have a floating input. The capacitance of the extra lead and your fingers
·can make it read 1 and zeros.....this is why you REALLY should have pullup/down resistors.....

But at least you have demonstrated that the code works and that the PRINCIPLE of the algorithm works and counts correctly.

.....now to go on to the weird stuff you are getting below......I will look at it later but I now have to go out......

For now try the program without the call to Stop....see what happens....Let me know


Sam


Post Edited (SamMishal) : 7/14/2009 9:43:58 AM GMT

SamMishal
07-14-2009, 07:14 PM
W9GFO said...



PUB main | i

uS := clkfreq/1_000_000
WaitTime := uS * 20000

Stop 'call the stop method to stop cogs that may be already started
repeat i from 0 to 2
cog[ i] := cognew(readPins(@long[pin][i*2], @long[pulsewidth][i*2]), @ stack[i*20]) + 1

LCD.str(string("Cogs started")) ' ********** here is where it slows waaaaaaay down **************
waitcnt(clkfreq + cnt)
LCD.clear



The problem is the line marked in red......
You are not any more passing the address of the address......so the line should now be like this
···· cog[i] := cognew(readPins(@pin[i*2], @pulsewidth[i*2]), @ stack[i*20]) + 1

The previous format was if you were passing the address of pin and pulsewidth to the "main" method........since now you are
not doing that and main has access to the arrays then you pass each cog the address of the pairs directly.......

Try the change and see....

The reason for the delays you were seeing is that in fact the whole program was being reset continously
and was being restarted all over again......that is because ......well too complicated to explain....but it is due
to the wrong address was being passed to the cogs.....


Sam


Post Edited (SamMishal) : 7/14/2009 11:29:13 AM GMT

W9GFO
07-15-2009, 12:13 AM
Ahhh, much better now. Thanks.

Still confused about the slow behavior, it didn't appear to be resetting...

I'm heading out now, later on I want to add some code to zero the pulsewidths if they are out of range (or with pulldowns, a wire is disconnected) and make this into a separate object. I'll refer to previous code to see if I can get the "@Long" in the right places.

Rich H

W9GFO
07-16-2009, 04:29 AM
Hey Sam, I was going to PM you with this but I can't send attachments in a PM.

Here is the RX object and a "RX_demo" to show how it works.

Thanks for all your help!

The problem I had before where it would show 1516 and 1517 turned out to be because the servo32 object was still sending pulses to those pins. I've learned that the servo 32 object isn't perfect in that the pulses it sends out are not exactly the same on all pins, even when they are supposed to be.

I added a few lines of code to deal with the floating inputs when they are not connected.

I'd like to upload this to the Obex, take a look at it and see if I have acknowledged you properly.

Thanks,

Rich H

SamMishal
07-16-2009, 04:51 AM
W9GFO said...
Thanks for all your help!


I'd like to upload this to the Obex, take a look at it and see if I have acknowledged you properly.


Hi Rich,

You are very welcome and THANKS A LOT for acknowledging me, you did not have to do that.....I am extremely· happy to have been
of help....just repaying my debt to others who have helped me.....

I am glad it is all working well.

It seems like an interesting and useful tool, you have done good work!

Best wishes

Samuel
·