As mentioned earlier I have looked at a method of adding ROMS, which are the PASM only image of an object that gets loaded into into a cog. Previously I compiled these inline in Tachyon but now in V5.4 I have removed them altogether and instead compile them each as separate files which are saved as a binary and then converted to Intel hex format. These files are then copied and pasted into the terminal the same as source code except the hex file is loaded and appended to the ROMS in upper EEPROM. So you can add new ROMs very easily and just to prove it I have added a TV ROM and the SIDCOG ROM. New ROMs can be added at anytime, even to a prebuilt Tachyon image.
Jim!
By default all numbers are decimal but numbers can be forced to decimal with a # prefix if need be, although this is redundant with the way Tachyon is used. There are no suffix operators in Tachyon but these are the prefixes:
You can mix symbols in with the digits as long as the number ends in a digit (1,000.00 or even #P27).
Although there is an LCDEMIT word it is a private word used by the parallel LCD module and these headers are reclaimed after EXTEND is loaded. If you want to connect to a 19200 baud serial LCD on P6 for example then define a word that describes your device and then simply refer to it like this:
pub SERLCD 19200 SERBAUD 6 SERIAL ;
SERLCD PRINT" Hello World" CON
We can mix other serial devices at other baud rates or if this is the only one you don't need to specify 19200 SERBAUD each time, although it probably won't make much difference.
If you are typing interactively at the console you need to use CON to return the output stream which was diverted to SERLCD back to the console terminal otherwise the LCD will be displaying all the console interactions instead of the terminal.
EDIT: Maybe you were trying to define LCDEMIT but omitted the : symbol or the more readable "pub" word.....
pub <name> defines a new Forth word (same as : but pub is clear and legible)
pri <name> is the same as pub except it sets a private attribute in the header so that RECLAIM can strip all private words.
pre <name> also sets the immediate attribute so that this word always executes immediately (IF THEN BEGIN AGAIN etc)
Previously I have included a handful of cog images for VGA and UARTs etc within the Prop tool compiled Tachyon kernel which are later extracted and copied to upper EEPROM as named "ROMs" (during EXTEND), ready to be loaded by name at runtime into a cog. As the title suggests V5.4 no longer has ROMs, but what if you need a special function like VGA or UARTs etc? Now you can either make your own since it is purely PASM with a dummy pub to keep the Prop tool happy, that is then compiled to a binary and then converted to an Intel hex file, or you can use one of the hex files already available in the ROMS folder. All I do with the hex file is add a "SAVEROM" line at the start and it is all ready to copy and paste into the terminal. When you do it saves the hex file as a binary image (which includes the ROM name header) onto the end of other ROMs in upper EEPROM. There are many examples of loading these ROMs and BREAKOUT.FTH shows how the VGA ROM is loaded and used for creating a playable video game.
The hex file for the full-duplex UART ROM looks like this:
The first 24 bytes which are part of the Spin header (Prop tool is Spin-centric) are stripped prior to saving.
A link to the latest binary which includes EASYFILE is now provided in my sig.
btw - EASYFILE will auto-mount a FAT32 card but to prevent errors on systems without SD cards or with SD cards on different pins I now detect when all SDPINS have been set to zero (default) and if so, skip SD handling. Just setup your board by specifying the 4 pins as part of a long using the IP notation so that a quick-start board would specify in the format &ce.miso.mosi.sck with "&11.08.10.09 SDPINS" which locks in the new pinout and will automount on next boot or with MOUNT.
Peter,
Thanks for the clarification. I set up my first attempts by entering what I found in "Introduction to Tachyon"
9600d SERBAUD \ Set this once and BACKUP if you like to set the default
: LCDEMIT 6 SEROUT ; \ Define an EMIT for the LCD
' LCDEMIT uemit W! \ find the code field address for our LCD EMIT and set the output vector to it
You might want to revisit this and see what I was doing wrong. using pub to define a word is ver helpful. I tested the code in your post and it worked. Now to figure out how to send the control characters such as #17 backlight on, #18 backlight off, $0D home.
Thanks
Jim
Jim - from what I could tell you were omitting the : colon symbol which is normally the "word" that starts a new definition. But colon and full stops etc don't always stand out so I also use pub instead plus the other variations.
V5 only uses a prefix to force the number to a base and i prefer to always stay in decimal mode so i only need to prefix non-decimal numbers. You can always force a pin number like P26 to be recognised as a number if you use the # as a prefix
I've made a couple of small changes to the intro and now it's late. There's only so much time in a day and a night
I got to thinking about my SERVO32 module that can handle up to 32 servos at the same time at at 400Hz update rate. Could I reduce the memory footprint and also make it a bit more flexible? So I did a very simple sequential step through 32 entry loop which I believe is "better" since it does the same job, has a much finer resolution and fully adjustable range up to 6.55ms/output and takes only 78 code bytes plus 64 bytes of data memory. The calculation time to set an output is also very fast (about 21us) plus it can be customized for a mix of different servos very easily.
Also it is easy to start up as you don't need a table or any other parameters, just a spare cog, so if you use cog 3 you type "3 RUNSERVOS" which starts up the servo task in cog 3. This will cycle through a table of 32 16-bit words which hold the timing for each output. If the timing is zero the entry is ignored. To set P15 to 90' simply type "90 15 DEGREES". The more servos you run the slower the update rate per channel but even with 8 servos set for maximum at 180' (8 FROM 8 FOR 180 I DEGREES NEXT) the update rate is still over 50Hz.
REQUEST - If anyone is running several and/or different servos can you load the V5.4 binary (or copy and paste this code) and try it out please?
64 bytes servos
pub RUNSERVOS ( cog -- )
RUN:
BEGIN
31 BEGIN
DUP 2* servos + W@
?DUP IF 3 << OVER HIGH WAITX DUP LOW THEN
DUP WHILE 1- REPEAT
DROP 1500 us
AGAIN
;
pub DEGREES ( degrees pin -- ) SWAP 666 * 60000 + 3 >> SWAP
pub SERVO! ( 16b pin ) 2* servos + W! ;
BTW - I've removed the Character LCD, the ANYKEY keypad scanner, and the basic VGA interface from EXTEND as they are easy enough to add to the end of any extensions, and so therefore easy to FORGET. The binaries however will include them, but at the end of code memory for that reason. The standard EXTEND will leave 9468 bytes free not including the 2K buffers plus about another 600 bytes in data memory.
Peter,
I hooked up 3 servos. Two cheap ones and and a quality one using your newest Servo Driver they all worked well.
Are you going to add the driver to Extend?
Thanks Jason & Ken, I had already replaced the servo driver in EXTEND (current binary as well) with this version as it seems more practical and the timing looked good on the scope. I think that even with 16 servos running at maximum this would still be fast enough as I get a figure of around 25Hz for 2.25ms x16 (+1ms). This version is so much simpler plus I have the option of finer control over a longer period (if needed) and the DEGREES word is really just a version for the 180' servo from Parallax that I found the info on. I would expect that 90' and 360' servos would have their own words or at least pass that parameter.
Is there a better word for DEGREES? Perhaps POSITION used like this: 90 180 5 POSITION where 90 is the angle/position we want, 180' is the servo type, and 5 is the pin. I looked at the timing for a 360' servo and basically it had this spec of 50 Hz 1280–1720 µs. So that is quite different from the 180' Parallax servo. Would each servo type require a setting or extra parameters? Maybe if the 360' type was on pin 7 we could set it up initially with "1280 1720 360 7 SETSERVO" so that the POSITION word would lookup those parameters instead of defaults.
I tested 3 servos. Two were continuous rotation and the last was a 180 degree micro servo.
I setup several words to make life easy for testing.
I was initially interested in finding the deadzone for the two continuous rotation servos so i could make words for the SLOWEST clockwise and counter-clockwise movement.
Below are the servo names, their basic stats and my results.
* I did NOT test or use the feedback signal on this servo yet.
3 RUNSERVOS
: ss 2 DEGREES ; - ss = SpinServo :-) Very easy to type too!
: cw 85 ss ; -cw = clockwise
: ccw 93 ss ; -ccw = counter-clockwise
: off 90 ss ; - off places the servo in the deadband and thus movement stops.
The deadband for this servo lays in degrees 86-92.
Putting the "angle" just outside the deadband makes the continuous rotation servos move their SLOWEST.
I just ran this one through the full 180 degrees in 10 degree increments.
Like this:
... 0 ss ok
... 10 ss ok
... 20 ss ok
... 30 ss ok
... 40 ss ok
... 50 ss ok
etc.
This is working great Peter !!
This is a really great example of how Forth can "talk to the hardware" !
You can make a few words very quickly to do your tests and then FORGET them and make the word(s) that fit your application.
Another fun discovery:
After I upgraded the board to 5r4, I cut and pasted the EXTEND file.
IT WORKED !!
I've made NO changes to my setup!
Weird and Cool at the same time ;-)
Is there a better word for DEGREES? Perhaps POSITION used like this: 90 180 5 POSITION where 90 is the angle/position we want, 180' is the servo type, and 5 is the pin. I looked at the timing for a 360' servo and basically it had this spec of 50 Hz 1280–1720 µs. So that is quite different from the 180' Parallax servo. Would each servo type require a setting or extra parameters? Maybe if the 360' type was on pin 7 we could set it up initially with "1280 1720 360 7 SETSERVO" so that the POSITION word would lookup those parameters instead of defaults.
I'm thinking that only adding a way to preset the full frequency range (1280 to 1720us for example) would be needed. Part of RUNSERVOS perhaps?
The programmer should define the deadband as it varies slightly from servo to servo anyway (even of the same model)
I have a project on the go and I'm trying to use servos instead of steppers (smaller, lighter, cheaper and don't require an additional driver circuit). For my application I'm testing the servos to find the smallest movement it can make cw and ccw.
This is what I came up with for the Parallax Feedback 360:
: testcw FOR cw 50 ms off NEXT ;
: testccw FOR ccw 50 ms off NEXT ;
99 testcw
155 testccw
(The "cw", "ccw" and "off" words are detailed in my last post)
I varied the delay time in the FOR loop to see what the smallest increment would be that actually moved the servo. It turned out to be 50 ms.
I then wrote my "test" words so that I could see how many "movements" I can make in one complete rotation.
99 and 155 are my results.
You will notice that cw and ccw are NOT symmetrical. Standard fare for continuous rotation servos.
I like the 180 to 0 degree "notation" for servo movement even for the continuous rotation servos.
For these servos, there are really only 5 "positions" you need to define:
-Deadband or No movement
-Slowest movement (just outside of deadband on either side)
-Fastest movement (both extremes of the the frequency range)
Speed adjustment will always be approximate and the 180 to 0 degree notation works great here I think.
Thanks for the testing and feedback Jason. Don't be afraid to type :
99 FOR cw 50 ms off NEXT
directly from the terminal since this is one of the cool features of Tachyon begin able to run Q&D one liners and knowing that the way it is typed and works in an interactive line is exactly the way it works when it's compiled into a word.
Am I reading you correctly in that you aren't using these servos for positioning but varying the speed? It would be easy enough to have a word that would do that and the resolution of the servo timing is 1us so I wonder if you continually increment the 1us timing intervals how slow it would go. Try:
1280 FROM 640 FOR I 2 SERVO! 5 ms NEXT
I like to create aliases, especially for testing so instead of DEGREES I could type S instead. Use ALIAS like this, it doesn't use up any more code space.
ALIAS DEGREES S
5 S or 2 S etc are just as easy to type then.
I think that if all the servos were the same you could pass this parameter to RUNSERVOS but if you want flexibility and being able to mix types you would need a SETSERVO. Even if they were all the same you could just set them all quickly with:
32 FOR 1280 1720 360 I SETSERVO NEXT
BTW, I always try to use the forum's code tags to make sure it the text is clear and intact.
Am I reading you correctly in that you aren't using these servos for positioning but varying the speed? It would be easy enough to have a word that would do that and the resolution of the servo timing is 1us so I wonder if you continually increment the 1us timing intervals how slow it would go. Try:
1280 FROM 640 FOR I 2 SERVO! 5 ms NEXT
My project will be using a servo for positioning. I simply felt that your 180 to 0 degree approach still works great for a continuous rotation servo.
Could you explain this code snippet a bit. I've been looking through the Glossary of Words but I haven't an explanation of how FROM works. Maybe I just missed it.
Your right though. I do want to find the value closest to the deadband that will still move the servo. The smaller the increment the better!
I would love to have some support with documentation! It's a big task and the glossary really needs to be brought up to date.
Back in V4 I think I felt that DO LOOP was was taking too much room in the cog whereas FOR NEXT could do the same job if I enhanced it a little. Normally FOR NEXT is a simple counted loop without access to a loop index, so I made it an index that started FROM a default of 0 but if you used FROM before the FOR it would use that value for the index I. But there is also +LOOP that gets used so I felt that I could do the same with the value to increment the loop index by which by default is 1, so I have BY to set this up plus there is no time wasted in each loop pushing and popping a value to increment by. Now there isn't any need for DO LOOP since most of the time we would always start from 0 and incremented by 1 anyway so a 0 DO LOOP became a simple FOR NEXT. The main difference from LOOP which compares the index with the loop limit is that NEXT is still a simple DJNZ as this line from the source shows:
forNEXT djnz _for,#ANEXT wz ' loop for cnt times (regardless of increment)
There's a slight speed penalty now when you enter and exit the FOR NEXT loop since it has to push/pop four parameters in slow hub memory. Those parameters are:
' TOP of LOOP STACK in COG REGISTERS
_next long 0 ' loop branch address
_for long 1 ' loop count
_by long 1 ' loop step
_from long 0 ' loop index
Unlike all Forths I know, the FOR NEXT aren't substituted with runtime versions at compile time, but FOR and NEXT are simple Tachyon opcodes and don't need to resolve a loop branch since the branch address is latched by FOR and all NEXT has to do on its DJNZ is move that address _next to the IP with this code:
ANEXT if_nz add _from,_by ' increment index by loop increment
if_nz mov IP,_next ' continue loop '
jmp unext
So in the example (BTW, the 640 was a typo):
1280 FROM 440 FOR I 2 SERVO! 5 ms NEXT
the loop index I would start from 1280 rather than the default of 0, as this is the minimum servo timing (1280–1720 µs) we would use and then after 440 FOR NEXT loops we would exit on the maximum of 1720. But I'm not sure how those continuous 360' servos work, I guess you could go back to 1280us to get it to keep moving in the same direction.
the loop index I would start from 1280 rather than the default of 0, as this is the minimum servo timing (1280–1720 µs) we would use and then after 440 FOR NEXT loops we would exit on the maximum of 1720. But I'm not sure how those continuous 360' servos work, I guess you could go back to 1280us to get it to keep moving in the same direction.
This is what a continuous rotation servo would do if we moved from one end of the range to the other.
1280us - This turns the servo at it's Fastest rate Counter Clock wise.
-as the value increases the servo will turn slower and slower
1480us - This turns the servo at it's Slowest rate Counter Clock wise.
-Between 1480 and 1520, the servo does not move. This is the Deadband.
1520us - This turns the servo at it's Slowest rate Clock wise.
-as the value increases the servo will turn faster and faster
1720us - This turns the servo at it's Fastest rate Clock wise.
As for documentation, I would love to help ;-)
I plan on using TACHYON a lot more now and I would be writing documentation for myself anyway.
Would you be willing to make a google doc for an "Introduction to Tachyon 5r4" ? You could copy the 4.7 Introduction into it as a starting point.
I would like to contribute to a Tachyon User Guide in a Topic-Description-Examples style.
I've written LOTS of technical documentation for teaching new users (for many things).
My available time to contribute will be intermittent but I do want to contribute :-)
I've removed any reference to 4.7 from the document and updated the revision line to 5.4. If you would like to edit the master document just go there and login with a Google account and request to edit. If you could help, that would be super.
Peter,
I've been having problems with MacOS version of the loader in PropellerIDE, so I sometimes use the loader from SimpleIDE (PropLoader) which works much better on the Mac except that it now produces an error message when attempting to download Tachyon .binary files, says they're invalid .binary files.
Had some issues with 5r4, Would not compile wiith PROP Tool. So I went in and stripped out all of the 6.25 MHz constants along with the 10MHz stuff. Finally able to Install along with latest Extend. I am a Happy camper. Had additional issues with FDTI drivers see "Prop Plug Died.
Jim
Hi Mike, I tried a few different methods to see if I could reproduce your problem and now this morning I've found PropLoader v1.0-37 (2017-09-29 14:48:50 gc4205c0) and tried it out too. Unfortunately I haven't been able to reproduce this problem. Which binary are you using?
peter@peter-XPS-15-9550:~/Dropbox/Tachyon/V5/binaries$ ./proploader -p /dev/ttyUSB0 TACHYON5r4.binary
Opening file 'TACHYON5r4.binary'
Stepping down to 460800 baud
Stepping down to 230400 baud
Stepping down to 115200 baud
Using single-stage download
Downloading file to port /dev/ttyUSB0
32768 bytes sent
Verifying RAM
Download successful!
peter@peter-XPS-15-9550:~/Dropbox/Tachyon/V5/binaries$
Peter,
I was checking out your rom routines and was wondering how they are generated and how to erase them. After I loaded UART I wanted to erase it but the things I tried did not work? To make a rom do you
build in spin or asm file and save the binary before converting to hex and feeding it to TF. I loaded the new V4.5 and extend with no luck.
Ken
Ken, ROMS used to be located at $E000 but I now have moved them down to $C000 so you can erase them very easily with:
$C000 $4000 $FF EFILL
The SAVEROM word looks for the ROM header but if there is none after an erase it will set one up and then append the following hex file. You can copy and paste any of the hex files in the ROMS folder.
Hi Peter,
I have been playing with Tachyon in the interactive mode and have it printing the time from RTC to the serial LCD display with use of EMIT and PRINT" words now is time to take the leap and write some code to run in a seperate cog to keep the LCD updated on a per second rate. My question is; does the system keep a second copy of the serout vector in the new cog or do I have to issue a CON every time I write to the LCD. Don't want any of the console commands going to the LCD but hate to have to write "print" routines for seperate serial output.
Thanks for all you do and I hope that Jason is able to get some progress made on the docs.
Jim - these I/O vectors are user variables so each has their own copy. If you start a new cog for the LCD then there is no need to use CON as you won't be using the console for that cog.
A simple example:
pub CLOCK RUN: LCD BEGIN HOME .TIME CR .DATE 100 ms AGAIN ;
Jim - In the case of HOME (normally an ANSI terminal sequence) you might just issue the sequence to take the LCD home but avoid clearing the LCD because this is seen as flicker, maybe just clear it during init. Rather than waiting 1 second or a change of event you could just refresh the display every 100 ms and keep it simple.
pub CLOCK RUN: LCD $0C EMIT BEGIN 1 EMIT .TIME CR .DATE 100 ms AGAIN ;
If you just want to print hours and minutes type:
TIME@ 100 / .AS" ##:##"
But you can look at the source for .DT (Print Date Time) which normally prints in the format "Mon, 20 Aug 2018 08:55:21 AEST" and customize one to suit the LCD display. The .AS" is a very flexible print routine and you can insert text and controls in there as well.
Peter,
Thanks for all the input. I had a little time to play this morning and I tried a couple of different versions of "CLOCK". The one that worked the best for me, put a $0C after the 100 ms delay and before the again. I was working with it in the interactive mode and all was working well except that after I typed "3 CLOCK I would see the clock start and the console say ok, but from there on the console appeared to be frozen. No more time to play today will experiment more next chance I get. This is getting exciting!
Jim - I see that I forgot to give that cog its own hub registers, mainly for number formatting and emit/key etc. Just add "$180 8 COG!" after the RUN: part. The "8 COG!" tells that cog (in my case 3) to use $180 for its hub register space vs $100 for COG 0.
This is my test code with a dummy LCD.
pub LCD EMIT: DROP ;
pub CLOCK RUN: $180 8 COG! LCD $0C EMIT BEGIN 1 EMIT .TIME CR .DATE 100 ms AGAIN ;
Note - some tasks that we run in a cog don't require their own hub registers but any character I/O will. The registers include emit/key, number output, base, serbaud etc.
Comments
Will 5r4 load in a 32G QS board?
Jim
Here is looking over my shoulder:
19200D ??? SERBAUD ok
... LCDEMIT ??? S 6SE SEROUT ;
... LCDEMIT ??? uemit W!: ??? ok
... PRINT KCDENUT ???
... LCDEMIT ???
... SERBAUD ok
... 19200d ??? SERBAUD ok
... LCDEMIT ??? 6 SEROUT ;
... LCDEMIT ??? uemit W!
a Spin file will print "hello world" on LCD on Pin 6
Jim
By default all numbers are decimal but numbers can be forced to decimal with a # prefix if need be, although this is redundant with the way Tachyon is used. There are no suffix operators in Tachyon but these are the prefixes: You can mix symbols in with the digits as long as the number ends in a digit (1,000.00 or even #P27).
Although there is an LCDEMIT word it is a private word used by the parallel LCD module and these headers are reclaimed after EXTEND is loaded. If you want to connect to a 19200 baud serial LCD on P6 for example then define a word that describes your device and then simply refer to it like this: We can mix other serial devices at other baud rates or if this is the only one you don't need to specify 19200 SERBAUD each time, although it probably won't make much difference.
If you are typing interactively at the console you need to use CON to return the output stream which was diverted to SERLCD back to the console terminal otherwise the LCD will be displaying all the console interactions instead of the terminal.
EDIT: Maybe you were trying to define LCDEMIT but omitted the : symbol or the more readable "pub" word.....
pub <name> defines a new Forth word (same as : but pub is clear and legible)
pri <name> is the same as pub except it sets a private attribute in the header so that RECLAIM can strip all private words.
pre <name> also sets the immediate attribute so that this word always executes immediately (IF THEN BEGIN AGAIN etc)
Previously I have included a handful of cog images for VGA and UARTs etc within the Prop tool compiled Tachyon kernel which are later extracted and copied to upper EEPROM as named "ROMs" (during EXTEND), ready to be loaded by name at runtime into a cog. As the title suggests V5.4 no longer has ROMs, but what if you need a special function like VGA or UARTs etc? Now you can either make your own since it is purely PASM with a dummy pub to keep the Prop tool happy, that is then compiled to a binary and then converted to an Intel hex file, or you can use one of the hex files already available in the ROMS folder. All I do with the hex file is add a "SAVEROM" line at the start and it is all ready to copy and paste into the terminal. When you do it saves the hex file as a binary image (which includes the ROM name header) onto the end of other ROMs in upper EEPROM. There are many examples of loading these ROMs and BREAKOUT.FTH shows how the VGA ROM is loaded and used for creating a playable video game.
The hex file for the full-duplex UART ROM looks like this: The first 24 bytes which are part of the Spin header (Prop tool is Spin-centric) are stripped prior to saving.
A link to the latest binary which includes EASYFILE is now provided in my sig.
btw - EASYFILE will auto-mount a FAT32 card but to prevent errors on systems without SD cards or with SD cards on different pins I now detect when all SDPINS have been set to zero (default) and if so, skip SD handling. Just setup your board by specifying the 4 pins as part of a long using the IP notation so that a quick-start board would specify in the format &ce.miso.mosi.sck with "&11.08.10.09 SDPINS" which locks in the new pinout and will automount on next boot or with MOUNT.
Peter,
Thanks for the clarification. I set up my first attempts by entering what I found in "Introduction to Tachyon" You might want to revisit this and see what I was doing wrong. using pub to define a word is ver helpful. I tested the code in your post and it worked. Now to figure out how to send the control characters such as #17 backlight on, #18 backlight off, $0D home.
Thanks
Jim
V5 only uses a prefix to force the number to a base and i prefer to always stay in decimal mode so i only need to prefix non-decimal numbers. You can always force a pin number like P26 to be recognised as a number if you use the # as a prefix
I've made a couple of small changes to the intro and now it's late. There's only so much time in a day and a night
LCD 17 EMIT will turn on the backlight etc
I got to thinking about my SERVO32 module that can handle up to 32 servos at the same time at at 400Hz update rate. Could I reduce the memory footprint and also make it a bit more flexible? So I did a very simple sequential step through 32 entry loop which I believe is "better" since it does the same job, has a much finer resolution and fully adjustable range up to 6.55ms/output and takes only 78 code bytes plus 64 bytes of data memory. The calculation time to set an output is also very fast (about 21us) plus it can be customized for a mix of different servos very easily.
Also it is easy to start up as you don't need a table or any other parameters, just a spare cog, so if you use cog 3 you type "3 RUNSERVOS" which starts up the servo task in cog 3. This will cycle through a table of 32 16-bit words which hold the timing for each output. If the timing is zero the entry is ignored. To set P15 to 90' simply type "90 15 DEGREES". The more servos you run the slower the update rate per channel but even with 8 servos set for maximum at 180' (8 FROM 8 FOR 180 I DEGREES NEXT) the update rate is still over 50Hz.
REQUEST - If anyone is running several and/or different servos can you load the V5.4 binary (or copy and paste this code) and try it out please?
BTW - I've removed the Character LCD, the ANYKEY keypad scanner, and the basic VGA interface from EXTEND as they are easy enough to add to the end of any extensions, and so therefore easy to FORGET. The binaries however will include them, but at the end of code memory for that reason. The standard EXTEND will leave 9468 bytes free not including the 2K buffers plus about another 600 bytes in data memory.
I have 3 different servos I can try.
Jason
I hooked up 3 servos. Two cheap ones and and a quality one using your newest Servo Driver they all worked well.
Are you going to add the driver to Extend?
Thanks Ken..
Is there a better word for DEGREES? Perhaps POSITION used like this: 90 180 5 POSITION where 90 is the angle/position we want, 180' is the servo type, and 5 is the pin. I looked at the timing for a 360' servo and basically it had this spec of 50 Hz 1280–1720 µs. So that is quite different from the 180' Parallax servo. Would each servo type require a setting or extra parameters? Maybe if the 360' type was on pin 7 we could set it up initially with "1280 1720 360 7 SETSERVO" so that the POSITION word would lookup those parameters instead of defaults.
I setup several words to make life easy for testing.
I was initially interested in finding the deadzone for the two continuous rotation servos so i could make words for the SLOWEST clockwise and counter-clockwise movement.
Below are the servo names, their basic stats and my results.
Parallax Feedback 360
-Control signal: PWM, 3–5 V 50 Hz, 1280–1720 µs
-Deadband: 1480–1520 µs (+/- 10)
-Feedback signal: PWM, 3.3V, 910 Hz, 2.7–97.1% duty cycle
* I did NOT test or use the feedback signal on this servo yet.
3 RUNSERVOS
: ss 2 DEGREES ; - ss = SpinServo :-) Very easy to type too!
: cw 85 ss ; -cw = clockwise
: ccw 93 ss ; -ccw = counter-clockwise
: off 90 ss ; - off places the servo in the deadband and thus movement stops.
The deadband for this servo lays in degrees 86-92.
Putting the "angle" just outside the deadband makes the continuous rotation servos move their SLOWEST.
FiTec 5103R Continuous Rotation
-Control Signal: 4.8V-6V, 500us - 2500us
: cw 83 ss ;
: ccw 87 ss ;
: off 85 ss ;
The deadband for this servo lays in degrees 85-86.
FiTec micro Servo 180degree
-Pulse: 900us-2100us
-Dead zone: ~1500us
: cw 83 ss ;
: ccw 87 ss ;
: off 85 ss ;
I just ran this one through the full 180 degrees in 10 degree increments.
Like this:
... 0 ss ok
... 10 ss ok
... 20 ss ok
... 30 ss ok
... 40 ss ok
... 50 ss ok
etc.
This is working great Peter !!
This is a really great example of how Forth can "talk to the hardware" !
You can make a few words very quickly to do your tests and then FORGET them and make the word(s) that fit your application.
Another fun discovery:
After I upgraded the board to 5r4, I cut and pasted the EXTEND file.
IT WORKED !!
I've made NO changes to my setup!
Weird and Cool at the same time ;-)
Jason
I'm thinking that only adding a way to preset the full frequency range (1280 to 1720us for example) would be needed. Part of RUNSERVOS perhaps?
The programmer should define the deadband as it varies slightly from servo to servo anyway (even of the same model)
I have a project on the go and I'm trying to use servos instead of steppers (smaller, lighter, cheaper and don't require an additional driver circuit). For my application I'm testing the servos to find the smallest movement it can make cw and ccw.
This is what I came up with for the Parallax Feedback 360:
: testcw FOR cw 50 ms off NEXT ;
: testccw FOR ccw 50 ms off NEXT ;
99 testcw
155 testccw
(The "cw", "ccw" and "off" words are detailed in my last post)
I varied the delay time in the FOR loop to see what the smallest increment would be that actually moved the servo. It turned out to be 50 ms.
I then wrote my "test" words so that I could see how many "movements" I can make in one complete rotation.
99 and 155 are my results.
You will notice that cw and ccw are NOT symmetrical. Standard fare for continuous rotation servos.
I like the 180 to 0 degree "notation" for servo movement even for the continuous rotation servos.
For these servos, there are really only 5 "positions" you need to define:
-Deadband or No movement
-Slowest movement (just outside of deadband on either side)
-Fastest movement (both extremes of the the frequency range)
Speed adjustment will always be approximate and the 180 to 0 degree notation works great here I think.
Jason
Am I reading you correctly in that you aren't using these servos for positioning but varying the speed? It would be easy enough to have a word that would do that and the resolution of the servo timing is 1us so I wonder if you continually increment the 1us timing intervals how slow it would go. Try:
I like to create aliases, especially for testing so instead of DEGREES I could type S instead. Use ALIAS like this, it doesn't use up any more code space. 5 S or 2 S etc are just as easy to type then.
I think that if all the servos were the same you could pass this parameter to RUNSERVOS but if you want flexibility and being able to mix types you would need a SETSERVO. Even if they were all the same you could just set them all quickly with:
BTW, I always try to use the forum's code tags to make sure it the text is clear and intact.
My project will be using a servo for positioning. I simply felt that your 180 to 0 degree approach still works great for a continuous rotation servo.
Could you explain this code snippet a bit. I've been looking through the Glossary of Words but I haven't an explanation of how FROM works. Maybe I just missed it.
Your right though. I do want to find the value closest to the deadband that will still move the servo. The smaller the increment the better!
Jason
Back in V4 I think I felt that DO LOOP was was taking too much room in the cog whereas FOR NEXT could do the same job if I enhanced it a little. Normally FOR NEXT is a simple counted loop without access to a loop index, so I made it an index that started FROM a default of 0 but if you used FROM before the FOR it would use that value for the index I. But there is also +LOOP that gets used so I felt that I could do the same with the value to increment the loop index by which by default is 1, so I have BY to set this up plus there is no time wasted in each loop pushing and popping a value to increment by. Now there isn't any need for DO LOOP since most of the time we would always start from 0 and incremented by 1 anyway so a 0 DO LOOP became a simple FOR NEXT. The main difference from LOOP which compares the index with the loop limit is that NEXT is still a simple DJNZ as this line from the source shows: There's a slight speed penalty now when you enter and exit the FOR NEXT loop since it has to push/pop four parameters in slow hub memory. Those parameters are:
Unlike all Forths I know, the FOR NEXT aren't substituted with runtime versions at compile time, but FOR and NEXT are simple Tachyon opcodes and don't need to resolve a loop branch since the branch address is latched by FOR and all NEXT has to do on its DJNZ is move that address _next to the IP with this code:
So in the example (BTW, the 640 was a typo): the loop index I would start from 1280 rather than the default of 0, as this is the minimum servo timing (1280–1720 µs) we would use and then after 440 FOR NEXT loops we would exit on the maximum of 1720. But I'm not sure how those continuous 360' servos work, I guess you could go back to 1280us to get it to keep moving in the same direction.
This is what a continuous rotation servo would do if we moved from one end of the range to the other.
As for documentation, I would love to help ;-)
I plan on using TACHYON a lot more now and I would be writing documentation for myself anyway.
Would you be willing to make a google doc for an "Introduction to Tachyon 5r4" ? You could copy the 4.7 Introduction into it as a starting point.
I would like to contribute to a Tachyon User Guide in a Topic-Description-Examples style.
I've written LOTS of technical documentation for teaching new users (for many things).
My available time to contribute will be intermittent but I do want to contribute :-)
Jason
I've removed any reference to 4.7 from the document and updated the revision line to 5.4. If you would like to edit the master document just go there and login with a Google account and request to edit. If you could help, that would be super.
I've been having problems with MacOS version of the loader in PropellerIDE, so I sometimes use the loader from SimpleIDE (PropLoader) which works much better on the Mac except that it now produces an error message when attempting to download Tachyon .binary files, says they're invalid .binary files.
Jim
I was checking out your rom routines and was wondering how they are generated and how to erase them. After I loaded UART I wanted to erase it but the things I tried did not work? To make a rom do you
build in spin or asm file and save the binary before converting to hex and feeding it to TF. I loaded the new V4.5 and extend with no luck.
Ken
I have been playing with Tachyon in the interactive mode and have it printing the time from RTC to the serial LCD display with use of EMIT and PRINT" words now is time to take the leap and write some code to run in a seperate cog to keep the LCD updated on a per second rate. My question is; does the system keep a second copy of the serout vector in the new cog or do I have to issue a CON every time I write to the LCD. Don't want any of the console commands going to the LCD but hate to have to write "print" routines for seperate serial output.
Thanks for all you do and I hope that Jason is able to get some progress made on the docs.
Jim
A simple example: To start up the clock in cog 3.
Thanks
Jim
But you can look at the source for .DT (Print Date Time) which normally prints in the format "Mon, 20 Aug 2018 08:55:21 AEST" and customize one to suit the LCD display. The .AS" is a very flexible print routine and you can insert text and controls in there as well.
Thanks for all the input. I had a little time to play this morning and I tried a couple of different versions of "CLOCK". The one that worked the best for me, put a $0C after the 100 ms delay and before the again. I was working with it in the interactive mode and all was working well except that after I typed "3 CLOCK I would see the clock start and the console say ok, but from there on the console appeared to be frozen. No more time to play today will experiment more next chance I get. This is getting exciting!
Jim
This is my test code with a dummy LCD.
Note - some tasks that we run in a cog don't require their own hub registers but any character I/O will. The registers include emit/key, number output, base, serbaud etc.
Replying from my phone at work. Lol oh yeah hub space for variables quite useful.
Jim