One byte at a time?
stelath_shadow9
Posts: 23
Project: To send single byte commands to prop via bluetooth to control whatever (servo in this case)
Problem: In the code below the commands are "a" for forward then back ward rotation of servo. "u" for temporary clockwise rotation of servo. and "d" for temporary counter clockwise rotation. However, when sending these characters I must send multiple characters to turn the servo i.e. "aa", "uuu", and "dddd" respectively.
The weird part is, every "command" byte I put in to the code must be typed one more time than the last programmed command. for example I must always type "aa" in order to get back and forth motion, and that is the first command programmed into the code. The 2nd command "u" must always be entered "uuu" in order for CW rotation and the command "d" must always be typed in "dddd" for ccw rotation.
As you can see, for every command added to the code I must add an extra one of those characters in order to execute the command, when Ideally what I would like is to only type the character once.
Im not sure what the issue is. I am using the parallax serial terminal code in order to bring the character in.
Any ideas?
p.s. Some of the code is very ugly. I am still attempting to learn spin code a little at a time, so I rely a lot on other crutches like the BS2.spin code or pst.spin. I am mainly shooting for functionality though.
Problem: In the code below the commands are "a" for forward then back ward rotation of servo. "u" for temporary clockwise rotation of servo. and "d" for temporary counter clockwise rotation. However, when sending these characters I must send multiple characters to turn the servo i.e. "aa", "uuu", and "dddd" respectively.
The weird part is, every "command" byte I put in to the code must be typed one more time than the last programmed command. for example I must always type "aa" in order to get back and forth motion, and that is the first command programmed into the code. The 2nd command "u" must always be entered "uuu" in order for CW rotation and the command "d" must always be typed in "dddd" for ccw rotation.
As you can see, for every command added to the code I must add an extra one of those characters in order to execute the command, when Ideally what I would like is to only type the character once.
Im not sure what the issue is. I am using the parallax serial terminal code in order to bring the character in.
Any ideas?
p.s. Some of the code is very ugly. I am still attempting to learn spin code a little at a time, so I rely a lot on other crutches like the BS2.spin code or pst.spin. I am mainly shooting for functionality though.
{{ . }} obj bs2: "bs2" pst: "parallax serial terminal" VAR CON _clkmode = xtal1 + pll16x ' System clock → 80 MHz _xinfreq = 5_000_000 ' Using 5 MHz external crystal oscillator servoPin = 17 ' Servo signal to this I/O pin-change if needed PUB starting pst.start(9600) centerservo cogstop (0) Pub centerservo pst.rxflush pst.charin if pst.charin=="a" pst.str(string("Moving",13)) here elseif pst.charin=="u" up elseif pst.charin=="d" down else centerservo centerservo pri up bs2.Freqout_set(17,50) waitcnt(89_000_000+cnt) bs2.freqout_set(17,0) centerservo Pri Down bs2.Freqout_set(17,1900) waitcnt(75_000_000+cnt) bs2.freqout_set(17,0) centerservo Pri here bs2.Freqout_set(17,50) waitcnt(89_000_000+cnt) bs2.freqout_set(17,0) waitcnt(82_000_000+cnt) bs2.Freqout_set(17,1900) waitcnt(75_000_000+cnt) bs2.freqout_set(17,0) centerservo
Comments
Or better yet
Another thing, use a servo control object.
In post #15) of my QuickStart servo tester thread is a super simple servo demo. Use the demo as a guide on how to use the servo object. There's also a servo demo in the _demo folder of the Prop Tool's library.
The servo control object will take care of pulsing the servo at 50 Hz so you don't have to worry about refreshing the servo.
I'm not sure why you use the cog stop command but I doubt you need it.
What Propeller board are you using?
Post #3 of my index has links to Propeller tutorials.
Your method "centerservo" is calling itself: Worse still it is being called by some routines that it calls. This is not good and I am surprised it works for very long at all as that will eat up all the stack and crash. Where you have written "centerservo" it is not just jumping to centerservo like a GOTO in BASIC, it is doing a subrotine call to cenerservo which will use stack space each time-
You need to put this stuff into a loop using "repeat"
Also you should only read the command byte once into a variable and the test it's value to decide what to do. something like:
Those "up" and "down" commands should just return not call back to "doCommands" or whatever.
To get around the this you can either change the method to public or use the RxCount method to see if a character has been received.
I often use the RxCount like this:
The above code doesn't block the program. I doubt you need this in your present program but I think it can be a very useful tool.
The code:
could have used a different variable than "character" I generally just use the same variable for the count as I do for the received byte so I don't need to make a new variable.
The code you posted works...kind of. I just tested it out. BUT It still requires 2 bytes i.e. "aa" rather than just "a" to execute the command and when I try to use another command such as "u" for up it I still have to type "uu" and it merely mimics the "a" command
So in this code Im not sure what is supposed to go before the ":" but if i leave it blank it says "expected an expression term"
Put you "here" or "up" calls where I typed "' do b stuff".
I left out a colon after the "b" earlier. I'm fixing this typo.
Indentation is really important in Spin. Don't indent when it's not needed. It helps a lot if you follow the convention changing your indentations two spaces at a time.
At any rate thank you a million for your help. I didnt realize that by trying to reference to pst.charin I was actually executing the command again. here is the updated code.
For example:
The above code will repeat forever but will not add anything to x. To get the code adding one to x to be repeated, it needs to be indented.
The above code will continually add one to x.
I don't understand how your servo code works at all. I don't understand why you're setting frequencies to control the servo. Depending on what servos you're using, you may be damaging them.
Do you know how servos work? (This isn't meant to rude, you've stated you're just beginning and I'm wondering if you understand about how to use pulses to control servos.)
The servo code I linked to earlier is pretty basic. If there's a part of the code you don't understand let us know. You really really should use a servo driver to control your servo.
BTW, While I agree BS2_Functions is a crutch (it's useful to see how some things are done on the Prop), I don't think Pst.Spin is a crutch. It's a tool. You certainly don't want to have to write your own serial driver to send debug messages.
Im using the prop activity board.
The next step I need to figure out is why this code will not work with a normal stand alone prop1
After looking at BS2_Functions a bit more, I see it uses the cog's counters to send a continuous frequency out on a pin. This technique apparently works with analog servos, but it won't work with digital servos or ESCs.
I'll suggest again that you take a look at a proper servo driving object. It will end up saving you a lot of trouble particularly if you want to drive more than two servos per cog.
Does you stand alone Prop have a crystal?
I'd suggest replacing the constants.
The Freqout_set method isn't going to produce an accurate frequency without a crystal. The servo object I've been suggesting also won't work correctly without a crystal.
You were correct to remove the xin and clkmode settings. There are a couple of clock settings which can be used without a crystal. Take a look at RCSLOW and RCFAST in the Propeller manual. I personally always use a crystal since it makes serial communicating (and a lot of other things) easier.
Whats odd is Instead of using the servo portion of the code I decided to try and make an LED blink. Something simple. I paste that code in But I couldn't get it to work . BUT, if i loaded the code to blink an LED or something all on its own, it worked fine.