Can SpinBasic provide microsecond accuracy?
CuriousOne
Posts: 931
Hello.
For some time critical applications, I need basic language programmable mcu. As I started with basic stamp, I shortly discovered it is no good for high speed measurements. So I migrated to Melabs Picbasic Pro, which is very basic stamp syntax compatible (most basic stamp code can be directly copy-pasted), but since being compiler, offers far better speeds. At least I though so, but recently, I needed very simple task to do:
1. pulsout PIN 1
2. wait 100 microseconds
3. pulsout PIN 2
The real life tests showed totally disappointing results.
PIC16F628A - took about 270 microseconds before ending of pulse on PIN 1 and begining of new pulse on PIN 2.
OK I tested the 1 microsecond delay. It took 200 microseconds on PIC16F628A @ 4Mhz, and 48 microseconds on PIC12F683 @ 4mhz!
So, this is total flop, so now I'm seeking for another, more precise solution, but with basic language. Will SpinBasic handle such tasks?
For some time critical applications, I need basic language programmable mcu. As I started with basic stamp, I shortly discovered it is no good for high speed measurements. So I migrated to Melabs Picbasic Pro, which is very basic stamp syntax compatible (most basic stamp code can be directly copy-pasted), but since being compiler, offers far better speeds. At least I though so, but recently, I needed very simple task to do:
1. pulsout PIN 1
2. wait 100 microseconds
3. pulsout PIN 2
The real life tests showed totally disappointing results.
PIC16F628A - took about 270 microseconds before ending of pulse on PIN 1 and begining of new pulse on PIN 2.
OK I tested the 1 microsecond delay. It took 200 microseconds on PIC16F628A @ 4Mhz, and 48 microseconds on PIC12F683 @ 4mhz!
So, this is total flop, so now I'm seeking for another, more precise solution, but with basic language. Will SpinBasic handle such tasks?
Comments
I think you mean PropBasic.
I generates assembly code that does 12.5 ns resolution. Is that good enough?
By calling Waitcnt, one can get pretty darn small. But there is a limit due to the interpreter's overhead of looking up words in the Forth dictionary.
I figure the lower limit was about 2500 clocks on a 80Mhz crystal. You can figure out exactly how many microseconds that is.
You do have to deduct a constant factor for the call to the word. I was using something like 324 clocks. If you are interested I need to write up a procedure for getting precise delays to the exact number of cycles desired. But it is doable and verifiable in pfth.
So you can get an exact number, but the crystal will vary by as much as 3% due to temperature changes. To control that is a whole separate issue.
pfth is ANSI Forth, not Basic or a Basic-like language.
Code in PASM will take it to the most precise limit.
Edit: Mike Green is awesome. What he said!
Regarding the assembly code, I can say, I can do same with picbasic pro, and in fact, I can arm timers, enable interrupts and so on, so get precise 100us delay there also, but this all requires so called "low level" programming, which I don't want to do.
And for PropBasic, say I did some complicated realtime code. When being compiled, will compiler analyze my code for speed issues and will say when experience something difficult "hey, this can't be run in time fragment your code requries?"
I think you would have to ask Bean directly in this forum:
http://forums.parallax.com/showthread.php/118611-Download-PropBASIC-here...-00.01.14-July-27-2011?highlight=PropBasic
Here's a search for other good links:
http://forums.parallax.com/search.php?searchid=1380959
i.e. can compiler say, this code will run in defined speed values or not?
But here is an application note: http://www.parallaxsemiconductor.com/sites/default/files/appnotes/AN009-ExecutionTime-v1.0_0.pdf
monitor a toggling I/O pin is occasionally the handiest way to time Spin or Propeller
Assembly code. " There is no way to use so called 8 "cogs" to guarantee specified timing outputs, right?
Remember, we don't have interrupts to spoil the timing. And we have 2 very capable timers per cog and we can even use the vga to generate outputs too.
Each pasm instruction takes 50ns but we can wait on a pin change or timer with a 12.5ns resolution. There are a few instructions that take longer, but all are deterministic.
All the higher level languages have overheads and are much harder to time. But if you divide your code carefully into sections, then most likely there will only be a tiny part that needs pasm, and you place this in its own cog.
So more info please.
- Monitor PIN 1, if it gets high, in no less than 1 microsecond, pulse PIN 2 with 10 microsecond pulse.
- Count the time from the PIN 2 rising edge, and when it reaches 1/2/4/8/16/etc (pre-defined by user) microseconds, pulse PIN 3 with 10 microsecond pulse.
- Loop
I was able to solve this task using cheap PIC microcontroller, but I needed usage of digital scope, and fine hand tuning of timings to get the desired result.
The question is, whenever there is such a solution, which, without usage of expensive or complicated microcontrollers, will allow me to directly write code with timings shown and above, and timings will be correct, no need for further tweaking or usage of scope?
You'll need a little more code than this ... to set the predefined time delay needed ... to initialize the I/O pins ... to make sure pin 1 is low before starting the loop ... stuff like that.
The test for pin 1 high has a granularity of 3 x 4 x 12.5ns = 150ns. This could be trimmed to 100ns with a little effort.
The Propeller has a very simple and easy method of controlling timing. But without understanding what it is and how it works, microseconds can be a bit tricky.
IN PASM, you get exactly what you want.
But in all higher level languages, there is some overhead that creeps in and needs to reconciled. It is not hard to do.
If you feel that someone else should just make all that go away, you are likely to always be a bit disappointed by any computer language you use.
If that example is all you need to do inside a PIC, it isn't much to program that in assembly.
I get down to about 31.25 usecs with exact result in pfth, but if I need better I would have to use PASM.
Maybe it can be provided in a compiled language. But when I created a word to do that in pfth, there is a constant amount of system overhead added to the 10usec delay.
The nice thing about Forth is that I don't have to use a scope to see this. I can just do it interactively. Once I determine the overhead that crept in, I just can deduct that amount from my delay and have precise repeatable results.
At 1 msec, the overhead is insignificant and nobody seems to care... but at 10usec, the same overhead is a large addition to the timing.
++++
The bottom line is whether you want to learn to use what the Propeller offers or wait for someone to write the 'prefect pause' for you. You might wait quite long as the people that need precise timing tend find life simpler in PASM than in BASIC.
The smaller your delay interval, the bigger the potential error is. What may seem like a nice flat line to you is really a very flat curve with long delays and big hook at the usec end of the curve.
What?
There are 8 cores and you can have parallel execution. How does the compilers inability to write the low level code you want make any of that marketing PR?
I wondered the same thing.
8 cores, parallel processing IS the hardware. No marketing hype.
All Application Notes are available here:
http://www.parallaxsemiconductor.com/appnotes
Try www.piclist.com for PIC solutions. Mike Prego wrote a good book on programing PICs in assembler... buy it used as it is out of print.
Parallax provides the software for FREE, and has worked with precise timing in the Propeller from the start. It even does video. But the reality is that if you want to mess around with usecs, you are going to have to assembler to get it right.
Still, you won't get as much performance out of a PIC16F84 as a Propeller. The Propeller has more of everything.
I've written a lot of code for the Propeller including some doing sub-microsecond timing and I've been impressed with how straightforward and reliable it is.
If you don't need the multi-processing, sure ... why pay for it? If you have to deal with ASM, you can certainly do it cheaper. On the other hand, the Propeller has a good instruction set, very straightforward. As mentioned, it's designed for precise timing and signal processing type applications, among others. I like its ability to do debugging on-chip. I can run a TV video text driver in one cog and display data from other cogs with small snippets of code added to my code. Similarly, I can run a PS/2 keyboard interface in another cog and store data in memory for my routines to use ... change parameters on the fly, etc. It's not quite the sort of symbolic debugger you can run on a PC, but it's close and more than adequate. Although it's not free (but cheap), Hanno's ViewPort is a nice PC-based debugger that can function as a logic analyzer and can be used to monitor variables and change parameters as well.
If you're into it, you can run the Propeller as a stand-alone system using Sphinx which works with a TV, PS/2 keyboard, and an SD card or micro-SD card for mass storage. It includes a Spin compiler and an assembler. The TV / keyboard interface needs a couple of resistors and capacitors and the SD card interface just needs a socket.
In Spin you can do it like that: The pulse and pause times will be precise to ~200ns because Spin executes from HubRam and has to synchronize to the Hub slot for the cog.
There will be a minimal pause time in Spin (maybe 2us), and the compiler will not warn you if you go lower, but then you can do the same in Assembly down to maybe 100ns minimal time).
Andy