Ground-Bot to ZX-40n
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
Ground-Bot to ZX-40n
Now that my GBOT with PID control is complete, I'm ready to focus on GBOT90. Here I plan to rotate the ground-bot 90 degrees at have it balance on its two wheels. I do not plan on using gyros, only a single IR range sensor. Specifically a GP2D120 (4-30cm) for best resolution. Because the system will be unstable, the control system will likely require more compensation beyond PID, and the current GBOT update rate is down to ~100Hz. So I plan to switch over to the ZX-40n device. Is the 40A code completely portable to the native device? I suspect the PWM intialization will be different.
Here's a link to the current GBOT: (notice effects of P-control vs. PID)
http://www.youtube.com/watch?v=uTh2DBWAbPs
Here's the thread leading up to this point. (pictures included)
http://www.zbasic.net/forum/about1258.html
Here's a link to the current GBOT: (notice effects of P-control vs. PID)
http://www.youtube.com/watch?v=uTh2DBWAbPs
Here's the thread leading up to this point. (pictures included)
http://www.zbasic.net/forum/about1258.html
Last edited by liam.zbasic on 18 February 2010, 22:29 PM, edited 1 time in total.
Re: GBOT to ZX-40n
Your ZX-40a code will almost certainly compile without error for the ZX-40n and it will probably run without problems (at least as well as it does now). Since the native mode device is faster, it is possible that a latent problem will arise that was masked by slower execution. Similarly, depending on the type of I/O you're doing you might have to add some delays to allow communication with external devices to work.liam.zbasic wrote:Is the 40A code completely portable to the native device?
- Don Kinzer
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
The only GBOT inputs are the IR range sensors, which are "analog" devices. In reality, their update rate is only ~25Hz. It was an issue with the ZX-40A, and I took care of it with a butterworth filter and no long needed delay() functions. I may have to increase the filter order for the native device. I hope I still don't need delays. Will the PWM output need special treatment?
I can think of no reason that it won't work exactly the same with the code you have now. After all, the timers on the mega644 (ZX-40a) and mega644P (ZX-40n) are virtually identical and the two devices run at the same main clock frequency.liam.zbasic wrote:Will the PWM output need special treatment?
- Don Kinzer
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
The Integral control in the PID controller is not as innocuous as I thought. The ground-bot tracker crashed into a wall. It should have maintained a distance of 10 inches. When sufficiently far from a wall, the I-control accumulates a huge integrated error and quickly passes through the setpoint and strikes a wall. The integrator should have been reset at the setpoint but was probably missed due to IR noise and a very tight deadzone (0.125"). The solution is to put a limiter on the integrator and/or increase the deadzone. I'll try the limiter first.
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
I recompiled the program written for the ZX-40a to the native version. I expected the compiled code to grow by roughly a factor of two, but not a factor of ~10. Also, not sure why persistent memory grows from zero to 32.
Device: 40A 40N
Code (bytes): 1828 15134
RAM (bytes): 74 252
Persistent Mem (bytes): 0 32
I did not change the code whatsoever, simply recompiled from 40A to 40N with version 2.8.7.
The program makes use of structured variables, PWM, atan, and arrays, and some function calls. The main code length is 280 lines; roughly 30% are comments and blank lines for legibility. Is the growth factor of ~10 reasonable?
Device: 40A 40N
Code (bytes): 1828 15134
RAM (bytes): 74 252
Persistent Mem (bytes): 0 32
I did not change the code whatsoever, simply recompiled from 40A to 40N with version 2.8.7.
The program makes use of structured variables, PWM, atan, and arrays, and some function calls. The main code length is 280 lines; roughly 30% are comments and blank lines for legibility. Is the growth factor of ~10 reasonable?
This is the integral "windup" that I talked about. Many times the PID copnstants assume a certain sampling frequency. There is a relationship between the sampling frequency and the speed at which the measured variable(s) can change. It sounds as if the faster native mode processor is going through the PID calculations faster so the integral value grows faster. It may be useful to use a timer on the PID loop so that it goes through the loop at a specified frequency regardless of the processor type.liam.zbasic wrote:The Integral control in the PID controller is not as innocuous as I thought. The ground-bot tracker crashed into a wall.
This is one of the latent problems that Don was referring to. You need to limit the range of the I term to that value which corresponds to full scale PID output. There are 2 values you might want to use.
1) The value that gives full output assuming zero speed on the P and D terms.
2) the value that gives full output with the CURRENT P and D terms.
3) some arbitrary lower value than either one or both of these.
-Tony
Larger code size is one of the drawbacks to native mode. Consider that a simple "do nothing" program with an empty Main() compiles to 23 bytes for the ZX-40a but is 3276 bytes for the ZX-40n. While this 142x growth may be initially shocking, it is important to realize that it is not representative of all programs.liam.zbasic wrote:I expected the compiled code to grow by roughly a factor of two, but not a factor of ~10.
The difference in size is mainly attributed to the difference in implementation. In VM devices, some very complex code like InputCapture() can be added to your application while growing the code size by only a dozen bytes or so. This is because all that is needed is the code to push parameters on the stack and then invoke the System Library routine that resides in the VM firmware. In contrast, invoking InputCapture() for a native mode device adds not only the calling code but all of the code implementing InputCapture() as well.
If you call InputCapture() a second time in your VM application, your code size will grow by the same amount as it did with the first call. In a native mode application, a second invocation only adds the additional calling sequence code because the implementation code has already been added.
For native mode devices, the persistent memory size shown includes the part reserved for system use. For VM devices, it does not. The situation is similar for RAM use. Part of the RAM use shown reflects variables statically allocated by the run-time code. Although we could subtract the 32 bytes of persistent memory in order to shown only the persistent data defined by your application, there is no practical way to do the same for RAM.liam.zbasic wrote:Also, not sure why persistent memory grows from zero to 32.
That factor is not unusual for small programs. The smaller program the higher the multiplication factor. I have a mid-sized ZBasic application that compiles to 18053 for a ZX-24a and 30872 for the ZX-24n; a multiplier of 1.7.liam.zbasic wrote:Is the growth factor of ~10 reasonable?
You should also keep in mind the fact that the maximum code size for a typical ZX-40a is 32K bytes while it is 60K for a ZX-40n.
- Don Kinzer
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
Just for the sake of argument, if I wrote my code directly in AVR GCC and I'm an average C programmer, would that code length be significantly smaller than the ZBASIC translated native code? Are there some inherent inefficiencies with the ZBASIC translator that cause repeated code, excess overhead, etc. that would otherwise not be present in GCC code? Thanks.
No. However, if you wrote your code directly in C you would not need to include, for example, the RTC and multi-tasking and other ZBasic-specific overhead (assuming that you didn't specifically need them). In an earlier post, I mentioned that a "do nothing" ZBasic program compiled for the ZX-40n is about 3700 bytes of code. In contrast, a "do nothing" program written entirely in C for a mega644P is only 194 bytes. It is possible to create a "do nothing" program that is even smaller by using some special tricks.liam.zbasic wrote:Are there some inherent inefficiencies with the ZBASIC translator that cause repeated code, excess overhead, etc. that would otherwise not be present in GCC code?
The comparison described in the preceding paragraph may provide a bit of insight but it is not very useful otherwise. If you were to code your application in C for a mega644P using avr-gcc you would have to write your own code for any pieces needed, e.g. interrupt-driven serial I/O, PWM, input capture, RTC, etc. I would aver that when you finally arrived at a finished application it wouldn't be much different in size than the same application written in ZBasic for the ZX-40n. Moreover, I suspect that it would take significantly longer to produce the first finished application written in C. A second and subsequent applications would likely be faster to produce assuming that you could re-use significant parts of previous applications.
My opinion is that you are unnecessarily concerned with the initial code size differences. As the application gets larger the ratio of the VM and native mode sizes will tend to get smaller. That, coupled with the fact that you have nearly twice the code space available on a ZX-40n, should mitigate code-size concerns.
- Don Kinzer
I agree 200% This is the beauty of the ZX platform!!! And, the ability to reuse code will not be as advantageous as you might think because you wrote it efficiently for a specific application the first time. For a different application, your needs will be slightly different, requiring a small but significant re-write and, even worse, debugging!dkinzer wrote:I would aver that when you finally arrived at a finished application it wouldn't be much different in size than the same application written in ZBasic for the ZX-40n. Moreover, I suspect that it would take significantly longer to produce the first finished application written in C.
-Tony
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
Just so that you know, I tried the AVR GCC approach. After that experience, I found it cheaper (in terms of my time) to pay more for the ZX chip with a killer compiler than to pay less for a blank chip with difficult compiler support. Its not like I need hundreds of chips anyway. I considered BASCOM, but their language is too archaic. I must admit Arduino is very attractive, however I don't like the open source environment. Too loose.
We have customers that use ZX devices for applications with significant production volumes. For moderate volumes, we recommend using a ZX device like the ZX-40n or ZX-44n because they are more cost effective. We do offer volume discounts that can make the price very attractive.liam.zbasic wrote:Its not like I need hundreds of chips anyway
When one gets to very high volumes, it might make sense to convert to using raw AVR chips; you'd have to do an analysis of the additional development and maintenance costs to determine the volume at which the cost become more favorable.
- Don Kinzer
-
- Posts: 163
- Joined: 24 March 2008, 23:33 PM
- Location: Southern California (Blue)
Yes, it has been considered. However, this is not as simple a proposition as it might at first seem due to the operating frequency dependency of the RTC, multi-tasking and many of the ZX Library routines.liam.zbasic wrote:Have you considered selling the ZBasic compiler separately [...]?
- Don Kinzer