PDA

View Full Version : Beginner Prop questions



Spiral_72
10-28-2011, 08:46 PM
I just opened the Prop, Prop clip, read the manual through, circuits etc. and read quite a lot, what I could find on these forums.

So when the Prop boots up, Cog0 looks for a PC connection first. If it's available, it'll load the program into memory.
This mean the EEPROM is optional as long as I have a good PC connection running Propeller Tool right?
Is there anything I need to do to terminate those open pins on the Prop then?

I'll have more, don't worry :)

Toby Seckshund
10-28-2011, 09:03 PM
Hi and welcome,

The EEPROM is optional and you do not have to put anything in its place. Obviously when you reset or de-power the code in the Prop will be lost.

There is the option in the PropTool software that just loads to RAM and not to EEPROM so that is what you should use.

Duane Degn
10-28-2011, 09:13 PM
Yes, What Toby said.

Spiral_72, Do you really have a Prop Clip and not a Prop Plug?

I purchased a Prop Clip once but it was because the Prop Plugs were out of stock.

I used a small piece of perf board to make a Clip to Plug adapter. The Clip usually stays clipped to the adapter and I use the Plug end to attach it to my Prop boards. I found if diffecult to attach and remove the Prop Clip without the adapter.

Keep the questions coming.

Duane

Spiral_72
10-28-2011, 09:34 PM
Ah, an error on my part. I have the Prop Plug, sorry.

Thank you. I have thing connected on the breadboard now. If the internet connection holds, I'll get the drivers and try some stuff.

Rayman
10-28-2011, 09:35 PM
Welcome Spiral.

I've got more info on the boot sequence on this page (towards the bottom):
http://www.rayslogic.com/propeller/propeller.htm

Toby Seckshund
10-28-2011, 09:40 PM
I would have named the right Fxx key to use but self doubt crept in and then I discovered that my PropTool is being unco-operative. F10 is my vote though.

F7 should get you identification that the software is aware of the Prop's existance.

Rayman
10-28-2011, 09:46 PM
Spiral,
Sounds like you may be setting up on a breadboard...
Here are a couple tips:
Make sure you connect all the Vdd and Gnd pins.
Make sure you have a 1 or 10 uF cap or so close to the propeller chip.
Connect the RES pin to the prop plug and nowhere else.
If you can, check your Vdd to make sure it is about 3.3 VDC.

You might want to read the PE Kit manual (see the sticky thread at the top of this forum).

Phil Pilgrim (PhiPi)
10-28-2011, 10:09 PM
In addition to Rayman's admonitions about filter caps, add a 0.1uF ceramic bypass cap to each Vdd/Vss pin pair right at the pin locations. Also, make sure /BOE is grounded, which enables an internal pullup on /RES.

-Phil

Spiral_72
10-30-2011, 07:14 PM
Thanks y'all. I'll add the caps as recommended. I've been programming the Prop some. At the moment, it blinks an LED every 250ms twenty times, then 50ms a hundred times, then runs through again.

Sorry for the delay, my internet connection has been out all weekend and may not even last through this post.

Anyhoo, right now I have the Prop mounted on my breadboard, running a 5MHz crystal and the Prop Plug. I couldn't download the drivers, but luckily the drivers I used for the BS2 worked on the Prop plug. Maybe it's exactly the same driver I dunno, but I'll leave it alone.

Spin is a bizarre language to me. It'll definitely take some getting used to, I've been dissecting the example code one character at a time.


Question: (actually a mult-part question)
it looks like CNT is the system counter register, a 32bit number which increments every clock cycle. OK so far?
So 32bit is 4.3 Billion
If I'm running a 5MHz crystal, so with the following code, the Prop operating frequency is 80Mhz right?


_clkmode = xtal1 + pll16x ' Feedback and PLL multiplier
_xinfreq = 5_000_000 ' External oscillator = 5 MHz

Just so I understand, 4.3 Billion / 80MHz is 53.7 minutes......So if my Prop is doing something according to the counter register, and at 53.7 minutes I could have an error in my routine because the counter rolls over?

Rayman
10-30-2011, 08:01 PM
I think you've got it, but it's 53 seconds, not minutes...

Spiral_72
10-30-2011, 10:28 PM
Duh, seconds... Thank you.

Duane Degn
10-31-2011, 01:42 AM
So if my Prop is doing something according to the counter register, and at 53.7 minutes I could have an error in my routine because the counter rolls over?

Yes, sort of. You do need to be mindful of the clock roll over on some things. The counter doesn't go from zero to 4+ billion, it goes from -2 Billion to +2 Billion and back to -2 billion at roll over.

You don't have to worry about roll over when you use waitcnt (as long as you don't want to wait more the 53.7 seconds).

You do need to be careful about the way you compare times.


time := cnt ' time is a long
interval := 8_000_000 ' 1/10 of a second
repeat

' Do sometime every loop
if cnt - time > interval
time += interval ' increase time by a tenth of a second
' Do something only if a tenth of a second has passed.


The above code works even if cnt rolls over.

Below is an example of how not to do it.

interval := 8_000_000 ' 1/10 of a second
time := cnt + interval
repeat
' Do something every loop
if time > cnt
time += interval
' Do something most times after a tenth of a second
' But there will likely be a problem
' when the cnt rolls over


If you obey a few rules, you don't have to worry about roll over.

The new "auto save" feature just saved this post.

My internet stopped working and I thought I had lost what I had just written. Thanks Bump and others.

I'm not going to click "Preview Post" since last time it eat (temporarily) my post.

Duane

Spiral_72
10-31-2011, 05:39 PM
Very nice. Thank you for the examples. This makes perfect sense.

.... which brings about another question I've not been able to find a concise answer to:

PUB routine1
variable123 := 456

Could the := be called a "Local variable" to be and only can be used inside a block? That is to say, if you have multiple blocks named routine1, routine2 and routine3...... the variable123 was declared inside routine1 so it is not valid for use in another block? Can I use define the same variable name inside another block and trust it to be a separate variable? (I dunno why I would, seems like that would be confusing)


And yes, thank you to Parallax for the autosave feature!!! I dunno how many times I've been in the middle of posting something and it dropped for any number of reasons.

Duane Degn
10-31-2011, 05:53 PM
Yes, you can reuse local variable names. Many of my methods have a local variable named "localIndex".

I frequently add the prefix "local" to my local variable names since I don't want to have to remember which variables are local and which are global.

All local variables are longs.

Here's the syntax.


PUB Routine1 | localIndex, localVariable, x, i

There is a default local variable "result" with each method. result starts out zero but all the other local variables need to be initialized. Global variables start out zero.

I think you've learned by now that ":=" is the assignment operator. Constants are assigned with "=". To check if two things are equal, you use "==".

Watch out for

if x := y
'do something
The above wont produce a compiler error (some wish it would). But it wont compare the two numbers.

Duane

Spiral_72
11-01-2011, 02:05 AM
Hooray. Thanks to all the help, Duane's code and a lot of reading :) I didn't use OBEX routines simply because I want to learn Spin rather than just make it work.

Here's a servo routine entered one researched command at a time. It (is supposed to ) sweeps the servo from 500us to 1000us position. I don't think the math is right though:
The servo is not running smoothly, so I expect my PULSFREQ math is wrong
The servo runs fast on one extreme, slow on the other.... which is strange because this code is based on the same principle as my BS programs doing the same thing.

BUT it does work.... barely :)



'' Servo run routine Oct31,11
'' Spiral_72 @ Parallax forums

CON

_clkmode = xtal1 + pll16x ' Feedback and PLL multiplier
_xinfreq = 5_000_000 ' External oscillator = 5 MHz

LED_PIN = 12 ' Set LED indicator pin
SERVO_PIN = 15 ' Set servo signal pin
SERVO_START = 500 ' Servo start pos
SERVO_END = 1000 ' Servo end pos
SERVO_STEP = 5 ' Number to increment servo position
PULSFREQ = 50 ' Update servo frequency

PUB ServoMove | Spos ' Declare a PUBlic method block named "name" - can also be PRIvate
dira[LED_PIN]~~ ' Set pin 12 to output
dira[SERVO_PIN]~~ ' Set pin 15 to output
repeat
repeat Spos from SERVO_START to SERVO_END step SERVO_STEP
outa[SERVO_PIN]~~ ' Set servo signal line HIGH
waitcnt(clkfreq / Spos + cnt) ' Wait Spos microseconds WAIT FOR COUNTER VALUE (1/4 SEC + CURRENT SYSTEM COUNTER REGISTER VALUE)
outa[SERVO_PIN]~ ' Set servo signal line LOW
! outa[LED_PIN] ' Alternate LED state or blink LED half of servo update frequency
waitcnt(clkfreq / PULSFREQ + cnt) ' Wait to hold servo update frequency
'Reverse servo direction
repeat Spos from SERVO_END to SERVO_START step SERVO_STEP
outa[SERVO_PIN]~~ ' Set servo signal line HIGH
waitcnt(clkfreq / Spos + cnt) ' Wait Spos microseconds WAIT FOR COUNTER VALUE (1/4 SEC + CURRENT SYSTEM COUNTER REGISTER VALUE)
outa[SERVO_PIN]~ ' Set servo signal line LOW
! outa[LED_PIN] ' Alternate LED state or blink LED half of servo update frequency
waitcnt(clkfreq / PULSFREQ + cnt) ' Wait to hold servo update frequency




Edit: Hmmm After some more research I'm not sure I understand what's going on. According to my calculations the servo signal is held high for 1ms to 2ms or a maximum of 10% the 20ms frequency, but what I'm seeing is more like 50% slow down at SERVO_END

clkfreq / 500 = 2ms right?
clkfreq / 1000 = 1ms right?

Apparently I need to get out my scope to see what's going on. I'm feeding an HS-55 HiTech micro servo which appears to have a 120 degree position range.

Edit again:
According to the HS-55 data sheet (at least how I'm reading it), the valid positioning range is 1500us +/- 400us or +/- 40 degrees
I suppose could explain why I'm seeing non-linear positioning at the extremes, so I corrected the START / END to 525 and 910 which should be 1100us and 1900us. The non-linearity is still there so I'm going to assume the 1ms variance in the pulse frequency is the cause. I need to get out my scope though.

Last edit:
I changed to code around to save the counter value upon entering the routine to give a true 20ms period.... It's still the same. Either my code isn't doing what I think or the servo is not linear. Time for the scope, I promise..... but I learned a lot of code and functionality with this little exercise.

Duane Degn
11-01-2011, 07:04 PM
Spiral_72,

Yeah, my internet works again!

I was completely off-line for half a day.

The non-linear behavior is likely caused by the slowness of Spin.

There's a good reason to use objects from the OBEX (and good reasons for doing it yourself). The OBEX servo drivers either use PASM and/or counters (not the system clock) so they are fast enough to give precise pulses.

I think you can be reasonably sure, if your servos move at all, that your code is probably okay (I just glanced at it).

Have you seen BS_Functions (or something like that) in the OBEX?

When I first started to control servos with the Prop, I used the "PulseOut" method in BS_Functions. I strongly suggest, if you do use BS_Functions to not use it as a crutch for very long. You need to "Free Your Mind" and start thinking in parallel. I think BS_Functions can make beginning Prop users think they are back with their good old Stamps and not embrace all that is the Propeller.

Aren't you glad my internet is working again? You would have missed this philosophic mumbo jumbo.

Duane

(Thank you "Auto-Save", you saved me again.)

Edit: off to watch all those robot videos now I have decent speed again.)

Spiral_72
11-01-2011, 09:00 PM
The non-linear behavior is likely caused by the slowness of Spin.


Oh my. That doesn't sound good. So does this mean, rule of thumb is Spin for program control and assembly for routines of any decent speed? I looked at PASM briefly, it doesn't look too different from my old Motorola and Intel assembly coding days.



I think you can be reasonably sure, if your servos move at all, that your code is probably okay (I just glanced at it).
Have you seen BS_Functions (or something like that) in the OBEX? When I first started to control servos with the Prop, I used the.........


Well, I tried all the tricks I knew and it still acted the same.
No, honestly I didn't even know what OBEX was until last night I realized you called routines in your code that I couldn't find. It sounds like I need to stay away from BS_Functions though. I understand what you mean my "Crutch". It sounds like I either need to read more manuals or get a lot more experience with the Prop. I've been programming the Prop like any other uC (BS, old Atmel, etc) with the Prop Manual as my only reference. I suppose my initial ideas of the Prop have been: Do a bunch of stuff really fast to in one cog, times eight

I'm glad the internet is working again for you. Check out Erco's PETMAN pics and video over in the Robots section. Very cool stuff!

Duane Degn
11-01-2011, 09:27 PM
I realized you called routines in your code that I couldn't find.

I'm pretty all the objects I used are in the "library" folder installed with the Propeller Tool.


It sounds like I need to stay away from BS_Functions though.

Actually, I'd sugguest you look through the object. It shows how to do things with the Prop that only require a single command with the Basic Stamp.


Check out Erco's PETMAN pics and video over in the Robots section. Very cool stuff!

Yes, amazing. I've commented on it already.

You have the basic idea of using Spin for program flow but use PASM drivers to take care of stuff that needs to happen fast.

I never worked with assembly with any processor or controller prior to learning PASM. It took a while to get my head around what was happening with memory. PASM (as I'm sure other assembly languages) requires one to break down a process into very basic steps. It was fun when I finally got hub RAM and cog RAM straight. PASM is initially stored in hub RAM but needs to be loaded (launched) into a cog before it can be executed. Once PASM code is running in a cog, and you don't need to relaunch the same code, you can use the section of memory used to hold the initial code for data storage. I have a modified version of Tim Moore's four port serial object that uses the code area as rx buffers. This allows 512 byte rx buffers without increasing the size of the code much (but at the lose of being able to relaunch the driver).

Duane

Spiral_72
11-02-2011, 02:24 AM
In the Library folder? Thank you Duane. I apparently have something set up incorrectly.

Duane Degn
11-02-2011, 03:13 AM
In the Library folder? Thank you Duane. I apparently have something set up incorrectly.

On my computer the library folder is located: C:\Program Files (x86)\Parallax Inc\Propeller Tool v1.3\Library

You can also find it from within the Propeller Tool. There's a little drop down menu about the directory tree (top left); "Propeller Library" is the first option.

Make sure and check out the "_Demos" sub folder.

Duane

Spiral_72
11-02-2011, 12:51 PM
I'd rather not disclose the reason I could not get your program to work <cough> rather that it wiggles fifteen servos nicely + one holding center.

So I'm going to dissect your code some more, see how it ticks, and continue working toward my biped control!

Spiral_72
11-02-2011, 08:21 PM
If you would be so kind, could you affirm/answer the following. My terminology may not be exactly right yet.

Your code Servo111027h, post #59 of my build thread in the Robots section

The program uses three cogs
A) Cog0 contains your program, program control/passing data/ calling the other modules, etc. Cog0 because the Prop always starts in cog0
B) Cog1? Contains the DebugLoop routine via cognew(DebugLoop, @debugStack). This cog is started in the main program
if this is true, where does the Simple_Serial module reside?

C) Cog2? contains the Servo32v7 module. This cog is started in the Servo32v7 module itself by calling Servo.Start (Servo32v7.Start)

Duane Degn
11-02-2011, 09:40 PM
If you would be so kind, could you affirm/answer the following. My terminology may not be exactly right yet.

Your code Servo111027h, post #59 of my build thread in the Robots section

The program uses three cogs
A) Cog0 contains your program, program control/passing data/ calling the other modules, etc. Cog0 because the Prop always starts in cog0
B) Cog1? Contains the DebugLoop routine via cognew(DebugLoop, @debugStack). This cog is started in the main program
if this is true, where does the Simple_Serial module reside?

C) Cog2? contains the Servo32v7 module. This cog is started in the Servo32v7 module itself by calling Servo.Start (Servo32v7.Start)

You're correct about the number of cogs being used.

The proper name for your "module" is "object". It's important to know the difference between objects and cogs. Objects are a convient way of packaging code; they are independent of cogs. Objects may launch zero, one or more cogs.

The Object Simple_Serial doesn't launch a cog. This comes at the price of not being able to receive data at the same time as sending data. FullDuplexSerial (FDX) is a commonly used serial driver that does launch a cog. You can lose the benifets of FDX when it's transmit (tx) buffer fills. When the tx buffer is full, FDX waits until there is room in the buffer before control returns to the parent object.

I though Simple_Serial was a better choice than FDX in the servo program.

The command cognew(DebugLoop, @debugStack) launches a Spin interpreter into a cog. The actual code that is executed remains in the hub. Only PASM code gets loaded into a cog.

You're right about Servo32v7's start method. It starts a cog.

A Spin program always starts in cog0 at the first public method.

Cogs can be restarted once they have been stopped. I usually just worry about how many cogs I have left; I don't worry about keeping track of the cogs' numbers (IDs).

Duane

Spiral_72
11-15-2011, 02:22 AM
Another question I'm searching for the answer to:

I'm using the Simple_Serial object, are there any formatting options I can use like the BS Debug function??? I'm able to send character "1" which seems to clear the screen, 13 is a carriage return, but can I tell it to print row & column??

Thank you again.

Duane Degn
11-15-2011, 02:29 AM
Parallax Serial Terminal lists some of these control character.


CON
''
'' Parallax Serial Terminal
'' Control Character Constants
''─────────────────────────────────────
CS = 16 ''CS: Clear Screen
CE = 11 ''CE: Clear to End of line
CB = 12 ''CB: Clear lines Below
HM = 1 ''HM: HoMe cursor
PC = 2 ''PC: Position Cursor in x,y
PX = 14 ''PX: Position cursor in X
PY = 15 ''PY: Position cursor in Y
NL = 13 ''NL: New Line
LF = 10 ''LF: Line Feed
ML = 3 ''ML: Move cursor Left
MR = 4 ''MR: Move cursor Right
MU = 5 ''MU: Move cursor Up
MD = 6 ''MD: Move cursor Down
TB = 9 ''TB: TaB
BS = 8 ''BS: BackSpace

BP = 7 ''BP: BeeP speaker

Spiral_72
11-15-2011, 02:43 AM
I dunno where you found that, but thank you. That made a huge improvement on my debug screen.

Phil Pilgrim (PhiPi)
11-15-2011, 02:43 AM
If you use the "Parallax Serial Terminal" object instead of SimpleSerial, you have access to the above functions as method calls or as named constants, viz: pst#HM.

-Phil

Duane Degn
11-15-2011, 02:59 AM
I almost like PST as a terminal object.

I can't figure out why they made RxCheck and StrToBase private methods. Without RxCheck you lose a lot of the benefits of having a serial object run in a seperate cog. StrToBase is a very useful method. It's great for all sort of uses besides just retrieving numbers from a terminal.

@Phil, I used SimpleSerial in a demo program I wrote for Spiral_72. I thought (and still think) it was a better fit for the way it was used than using one of the other serial objects. I personally don't use SimpleSerial very often. I usually use a modified version (http://forums.parallax.com/showthread.php?129714-Tim-Moore-s-pcFullDuplexSerial4FC-with-larger-(512-byte)-rx-buffer) of Tim Moore's four port serial object.

Phil Pilgrim (PhiPi)
11-15-2011, 03:31 AM
Duane,

Yeah, there are other "singularities" in the PST object that mystify me. For instance, why didn't the authors just use out or tx instead of char to be compatible with other serial I/O routines? And why not just use the constant names that we're already familiar with: HOME and CLS, instead of HM and CS? It seems as if every object has to be developed in isolation without considering anything that came before. Well, at least they kept the values of the constants the same as those used by the PBASIC DEGUG screen. And the beauty of open source is that if we don't like it, we can change it.

-Phil

Spiral_72
11-17-2011, 01:01 AM
Alright here's another one for you. I CANNOT find the answer for this and it's bugging me...... not that it actually matters, but more that I don't know why:

My program runs just like I anticipate with:
Mainloop
PUB MainLoop | nextFrameTime, framelen ' This method is being executed in cog #0.


but if I delete the "Mainloop" line, the program no longer works!? I don't understand. Mainloop is undoubtedly a label, but I don't see where it's referenced anywhere. A search in the Prop Manual gives nothing so I assume it's not a reserved word.

I have several other PUB designations labelled "Setup", "DebugLoop" and Dec(value) but they do not have a label like MainLoop does.

Phil Pilgrim (PhiPi)
11-17-2011, 01:21 AM
The first PUB method in your top-level object starts automatically. You can call other methods in the object just by naming them (assuming they have no arguments). By deleting the "MainLoop" line, you're deleting a call to the MainLoop method, which is why it doesn't execute.

-Phil

Spiral_72
11-17-2011, 01:52 AM
The first PUB method in your top-level object starts automatically. You can call other methods in the object just by naming them (assuming they have no arguments). By deleting the "MainLoop" line, you're deleting a call to the MainLoop method, which is why it doesn't execute.

-Phil
OOOOOOooooh!

so Mainloop is not a label, it's an implied "GOTO" Mainloop...... which executes the PUB Mainloop

Phil Pilgrim (PhiPi)
11-17-2011, 02:16 AM
Not GOTO, but GOSUB, if you want to relate it to PBASIC terminology.

-Phil

Spiral_72
11-24-2011, 12:54 AM
One more question.... I think I already know the answer, but I can't think of a way to prove it:

nextFrameTime := cnt + clkfreq / 50
.......
do something that takes longer than 50ms
.......
waitcnt( clkfreq + nextFrameTime )


The program will just fall through the waitcnt because the elapsed time has already passed right?

Duane Degn
11-24-2011, 02:12 AM
Spiral_72,

I'm guessing your 50ms is really 20ms?

And, waitcnt( clkfreq + nextFrameTime ) should be waitcnt(nextFrameTime)?

waitcnt( clkfreq + nextFrameTime ) would wait 1.02 seconds since nextFrameTime was set.

You do want to make sure you don't use waitcnt on a time that has already passed. If the time has passed, the program will freeze until rollover (about 54 seconds @ 80MHz).

I'm assuming you want to know how to check if 20ms (or some other time) has passed.




frameInterval := clkfreq / 50
time := cnt
repeat
if cnt - time > frameInterval
time += frameInterval
' do stuff you want done after 20ms has passed
' do stuff all the time

The above will check to see if the 20ms interval has passed and then reset the time so you can detect the passage of the subsequent interval.


Yes

ratronic
11-24-2011, 02:17 AM
Spiral_72 if you use waitcnt with a value that the current CNT just passed it will hang there for another ~53 seconds (if your running @ 80mhz) before continueing. CNT is 32bit. 4,294,967,295/80,000,000 = 53.6870911875 seconds.

Spiral_72
11-24-2011, 12:01 PM
ARG! Thank you both. Now that you point it out, this was a silly question! and one that I should have known the answer.