Now the simulator mode works with 2 cogs. This can be easily adapted to driving a real 3D printer by changing the functions in the simulator directory.
So what now? Are you going to make it functional?
Referring to the project that I uploaded in Post #210...... Considering all the rearranging I did on the source code, perhaps the incorrect readings are due to these changes. I think I will shorten the GCODE file and see if it pushes the steppers.
In theory I would just have to change the READ, WRITE, SET_INPUT and SET_OUTPUT functions in simulator.c to make it functional. I have some stepper motors, but I've never played around with them. Maybe it time to start wiring up some things.
I've attached a zip file containing the code with all the changes I made. The nice thing is that I've made hardly any changes to the the main portion of the teacup code, and almost all the changes are to the files in the simulator directory.
I had seriously thought about giving up on Teacup, and was exploring the idea of creating my own firmware from scratch, but I have come to the realization that starting from scratch is insane. The truth of the matter is, I now know the Teacup firmware pretty darn well, but just not well enough to make it work yet. So instead of abandoning it, I have decided to learn more about it.
I believe my last attempt was very close to being successful, but I definitely missed something, and I have further come to the conclusion, that in my current arrangement of the code, concerning the program split that I installed, locks are only required for reading and writing to the queue. I further believe that the primary cog is in good working order, because it basically just keeps reading characters and adds items to the queue, but it should lock the queue when adding items.
The queue monitor cog, basically the movement cog, needs to lock the queue while reading it. After reading the queue, this cog should perform the action described by the queue entry. When it has finished processing one entry, it should remove the entry from the queue, and grab the next one. So on and so forth...
One way or the other, it is very, very close now and there is no point in giving up on it. I was just getting a bit irritated and disgusted with the project.
I have come up with an idea or two for cutting down the size, so hopefully that will help.
To help me nail down the remaining problems, I am going to take the last build and cut it down to the absolute minimum, and work from there.
I have temporarily and perhaps permanently abandoned the actual Teacup port, and have steered the Forger firmware down a different path, such as creating my own firmware. At this point, things appear to look fairly promising, but still a bit iffy. However, a subtantial amount of memory can be regained when unnecessary print commands are deleted, as well as unnecessary definitions.
The definitions for axes Z & E are currently fictitious for testing purposes.
To run this project, simply set your sd pin assignments within config.h, under the heading "Propeller Memory Card Assignments" and feed it some GCODE. Besides that, you really shouldn't have any pin problems, because no other pins have been set yet.
Pertaining to the uploaded project of the previous post, I just noticed that some of the values shown on the terminal, for the E axis, are incorrect. I will have to study these results a little more in depth to determine where the error is coming from and if there are additional errors.
This only shows the conditional statements for the E axis, but it would also apply to all axes not shown. During the first two conditions, I should also be ensuring that current_gcode.E_NUM is not equal to 0. So I believe the proceeding code should look more like this:
I believe the corrections mentioned in the previous post has taken care of the errors that I was seeing. I am now uploading a corrected version. This version also displays the required direction of rotation for the motors.
@idbruce:
As to the size problem:
I have not studied the code of TeaCup yet, though it would seem to me if you redid all the control stuff in PASM, making each section fit into a single COG you could use a lot less memory.
Use one COG for all the motor controls (under 300 instructions to control 3 steppers and one servo). Use one cog for all the sensors. Then you have only the G-Code stuff in SPIN, and possibly some communication stuff, and the load hub ram that was used to load the PASM code that is then put into COG mem can be reused for buffers or what ever.
This is why my firmware is mostly in PASM, and none of it needs to be kept in Hub mem.
Over the last couple of days, I have been taking a break from my parser and working a little more on Teacup. In an effort to cut down the size, I trimmed the unnecessary fat from the adafruit_ads1015 library and I have eliminated propellerized.h. It may not work yet, but it now looks like a Propeller application instead of an AVR application
As mentioned ealier, Teacup is written pretty darn lean, and there is not a whole lot of code that you can remove and still remain functional. I could try eliminating some of the supported G and M commands, but I really do not want to do that. So right now, it is propably as small as it is going to get, and it is still too large. However, I do have a new strategy.
My new strategy is similar to my current stragegy, in the fact that the program will be split in two. There are several significant portions of code, but the two main ones are parsing and processing, with the queue being the middleman. As is the current situation, the split will be at the queue. However due to memory concerns, it cannot remain as it is and this is where the new strategy comes into play. It is a basic concept and it should not be to hard to implement. I will be taking the sd reading, serial reading, and GCODE parsing and placing them on one Propeller chip and the rest of the code, which all pertains to processing, will be placed on another Propeller chip. And the only thing that will pass from one chip to the other will be the queue. So one chip will create the queue and the other chip will process the queue.
I believe this should do the trick, but perhaps the processing end may still be too large for one Propeller chip. Only testing will tell.
By adding another Propeller chip, I also gain another advantage, which is the removal of the Propeller Memory Card from the main controller board, thus opening up several IO pins, so that all homing and limit switches can be utilized. In all honesty, it is looking pretty promising, and as mentioned, it should not require too many changes on the current controller board.
I will be taking the sd reading, serial reading, and GCODE parsing and placing them on one Propeller chip and the rest of the code, which all pertains to processing, will be placed on another Propeller chip. And the only thing that will pass from one chip to the other will be the queue. So one chip will create the queue and the other chip will process the queue.
A thought - would it be possible to write the queued data to SDcard/SRAM and use two passes, needing only one Prop ?
Since my last post, I have been trying to make an actual split and I have come to the conclusion, that a split is not possible, like I thought it would be. That firmware is so tightly intermingled, it is just simply unbelievable. Teacup is truly a brilliant peace of code work, but it will be very difficult to actually port it to the Propeller, unless of course Dave does something with the simulator end of things.
The main problem is the way the M codes and various G codes are handled. Some of them are never added to the queue, which was an oversight on my part. If they had added everything to the queue for processing, I believe it would have been a breeze. I do not believe there is a work around for this obstacle.
Besides all the work I have invested, it is really a shame that I could not get this to work for the Propeller. I think it would have been a good thing for Parallax.
Please be advised that I am definitely abandoning the Teacup port and all efforts thereof. However, I will be going forward with the Forger firmware, but not under the source of Teacup.
If anyone is interested in my stopping point, along with further obstacles that need to be overcome, I would be more than happy to discuss these issues, as well as providing the latest project build.
Please be advised that I am definitely abandoning the Teacup port and all efforts thereof. However, I will be going forward with the Forger firmware, but not under the source of Teacup.
If anyone is interested in my stopping point, along with further obstacles that need to be overcome, I would be more than happy to discuss these issues, as well as providing the latest project build.
That is OK. If it may interest you, in the next couple of days I will be posting the firmware I am re-writing for my 3D printer, that uses a single Propeller.
I am debating weather I will continue to process the G-Code in the firmware, or if I will instead use a more compact command structure to send to the printer and process the G-Code on the host system.
The original firmware I wrote was mostly in PASM, the rewrite is almost all spin. The Original did have the G-Code processor in the Propeller, though I think it better to process that on the host side (still open to debate).
It will be a while before I am able to test the rewrite, as it is just bits and pieces at the moment, though if you would like I can start a thread to step through my work in progress.
If it may interest you, in the next couple of days I will be posting the firmware I am re-writing for my 3D printer, that uses a single Propeller.
I am always interested in seeing code that operates machinery, but what I am really interested in is the processing of steps with Bresenham's line drawing algorithm.
I will be starting a new thread soon for my current parser and processor.
I am always interested in seeing code that operates machinery, but what I am really interested in is the processing of steps with Bresenham's line drawing algorithm.
I will be starting a new thread soon for my current parser and processor.
Well I have already started the thread, though code will come later, hopefully today for the Stepper object anyway.
As to the line drawing, you are in luck. My stepper object includes a simplified implementation for the XY plane. I did this to simplify some of the work in controlling the 3D printer.
Bruce, it seems like compiling the G-Code into a stepper file might be the way to go. You could break up the Teacup code into two programs. The first one would write out the information that is currently going to the queue, and the second program would read the queue file and generate the stepper commands. You could run this from one of the OSes that are available for the Prop. I would suggest using spinix, but there are a few other OSes that you can choose from. Or you can run it without an OS by making the first program start the second one when it's done. Of course another way to do it is to run the G-Code compiler on a PC, and then run the stepper program on the Prop.
Yea that won't work with Teacup, it is a lame duck at this point. If you refer to Post #224, you will see that I state that the M codes never make it to the queue and it relies on gcode_process to do a lot of the work, which makes splitting it, almost an impossibility.
In reference to your Post #213, READ, WRITE, SET_INPUT and SET_OUTPUT....
As you know, the definitions were in arduino.h, which was then altered to propellerized.h. During an attempt at code reduction, propellerized.h was completely eliminated. Without the use of the simulator, there were three files using these functions which were forger.c, pinio.c, and pinio.h. These three files were modified to remove all macros and utilize propeller functions from simpletools.h.
Bruce, I don't understand your point. Does your code work with all the changes you made? I made minimal changes, and my code works. You would just have to make a few more additional changes to my code to get it to drive pins. So what were you trying to say in your last post? I don't get it.
In theory I would just have to change the READ, WRITE, SET_INPUT and SET_OUTPUT functions in simulator.c to make it functional.
I was just telling you how I changed my files to eliminate the macros completely.
Does your code work with all the changes you made?
LOL I wish it did.
I made minimal changes, and my code works.
I do not know what you are seeing that I am not. When I run your program with the terminal, I simply get a blue screen. When I type, the terminal displays the characters, but that is it. What's working? I basically have a blue screen. I still don't get it. How are you verifying that it is working?
You would just have to make a few more additional changes to my code to get it to drive pins.
What are the remaining changes that need to be done?
I guess I misinterpreted your "LOL". Yes, of course you have to change config.h to match your hardware. And if you're going to add SD support you may need to remove some features from the Teacup code to get it to fit. Given the difficulties you've had with this code it may be best that you try a different approach. The Teacup code was written for the AVR, and it has a lot of ugly AVR stuff in it. It might be better to just cut your losses and team up with David Saunders. He seems to have a working approach.
I guess I misinterpreted your "LOL". Yes, of course you have to change config.h to match your hardware. And if you're going to add SD support you may need to remove some features from the Teacup code to get it to fit. Given the difficulties you've had with this code it may be best that you try a different approach. The Teacup code was written for the AVR, and it has a lot of ugly AVR stuff in it. It might be better to just cut your losses and team up with David Saunders. He seems to have a working approach.
While I do thank you, it is taking me a bit of time to do my rewrite. I am only have done with the native command processor, and just begining on the G-Code to native command converter (which has to be fast enough to keep ahead of the serial input, as G-Code is a lot bigger than the native command language I created).
While taking a break from my pity party, I thought I would take a moment to summarize the current standing of this project and upload the latest build. As it stands now, I do believe the attached archive is the closest that I have come to a working version, however it is still not working.
The attached archive will generate three (3) warnings during the build process. These warnings are as follows:
And these warnings particularly apply to the processing of M2/M84 and M119 commands within gcode_process.c. Commands M2/M84 have a commented loop, which blocks the use of the "i" variable, and command M119 generates unused variable warnings because limit switches have not been defined in config.h, therefore the variables "open" and "triggered" are currently unused.
Without going into too much detail, this project has reorganized the Teacup firmware in an attempt to bypass the use of interrupts. Basically the main cog creates the movement queue and another cog attempts to read and process the movement queue. In an effort to provide the cleanest project possible for future endeavors, I have removed some of the previous programming, in which I attempted to make the shared variables and structs volatile, however this generated a bunch of warnings due to memcpy. It is my understanding that in order for these variables and structs to be shared between cogs, they must be volatile.
As well as removing some previous programming, I have also reestablished some of the previously removed programming, but more particularly, the original source and header files for the ADS1015 ADC.
While I do believe that my theory of operation should work, the biggest obstacle at this point is overcoming the memory issue, because I cannot troubleshoot any further without overcoming this barrier. The code responsible for processing the queue and movement, resides in queue_monitor.c. Within queue_monitor.c a while loop is currently commented out, because it causes the code to fail severly. At this point, I assuming that this is due to insuffient stack space, until I get the opportunity to prove otherwise. However I suppose the failing code could also be attributed to the code that I am attempting to run, however this code closely matches the original Teacup code. The currently alloted stack size for the queue_monitor cog is a mere 150 int(s), and I just know this is way to small, because this cog handles a lot of code. The current build comes in at "Code Size 28,536 bytes (31,176 total)".
EDIT: Known And Assumed Cog Usage
1) Main (Known)
2) ADS1015 ADC (Assumed)
3) SD Card (Assumed)
4) Queue Monitor (Known)
5) Clock Timer (Known)
6) Full Duplex Serial (Currently Unused, If Enabled Known)
I am looking for any reasonable ideas to decrease program size,
which would allow a larger stack size for the queue_monitor cog.
####WARNING######
If you decide to run this project, please ensure that you set the proper IO pins in config.h!!!
Bruce, I found that my code was overflowing the timer stack. I had only allocated 100 longs for the stack, and it was using 120 longs. This may be why it wasn't working for you. I've increase the timer stack to 200 longs, and it is working fine for me. I also changed the print that was coming from the WRITE routine so it now prints either H# or L#, where H and L represent high and low, and # is the pin number.
Give this code a try and see if it works OK for you. If you type a command like "G1 X1" you should see prints showing the X pin toggling.
Comments
So what now? Are you going to make it functional?
Referring to the project that I uploaded in Post #210...... Considering all the rearranging I did on the source code, perhaps the incorrect readings are due to these changes. I think I will shorten the GCODE file and see if it pushes the steppers.
I've attached a zip file containing the code with all the changes I made. The nice thing is that I've made hardly any changes to the the main portion of the teacup code, and almost all the changes are to the files in the simulator directory.
Absolutely!!! However, be forewarned, your life may change. For better or maybe worse
No luck with that one.
I think I am going to take a break from trying to get this to work and study the math of the firmware for a bit.
I believe my last attempt was very close to being successful, but I definitely missed something, and I have further come to the conclusion, that in my current arrangement of the code, concerning the program split that I installed, locks are only required for reading and writing to the queue. I further believe that the primary cog is in good working order, because it basically just keeps reading characters and adds items to the queue, but it should lock the queue when adding items.
The queue monitor cog, basically the movement cog, needs to lock the queue while reading it. After reading the queue, this cog should perform the action described by the queue entry. When it has finished processing one entry, it should remove the entry from the queue, and grab the next one. So on and so forth...
One way or the other, it is very, very close now and there is no point in giving up on it. I was just getting a bit irritated and disgusted with the project.
I have come up with an idea or two for cutting down the size, so hopefully that will help.
To help me nail down the remaining problems, I am going to take the last build and cut it down to the absolute minimum, and work from there.
The definitions for axes Z & E are currently fictitious for testing purposes.
To run this project, simply set your sd pin assignments within config.h, under the heading "Propeller Memory Card Assignments" and feed it some GCODE. Besides that, you really shouldn't have any pin problems, because no other pins have been set yet.
Now comes the hard part, which is firguring out all the math to implement this code: http://forums.parallax.com/showthread.php/159926-Introducing-quot-SyncroStepper-quot-Syncronization-For-Multi-Axis-Machines. My biggest worry is now cogs, because I believe I will definitely be over by implementing this code, especially with serial input.
Consider the following code:
This only shows the conditional statements for the E axis, but it would also apply to all axes not shown. During the first two conditions, I should also be ensuring that current_gcode.E_NUM is not equal to 0. So I believe the proceeding code should look more like this:
As to the size problem:
I have not studied the code of TeaCup yet, though it would seem to me if you redid all the control stuff in PASM, making each section fit into a single COG you could use a lot less memory.
Use one COG for all the motor controls (under 300 instructions to control 3 steppers and one servo). Use one cog for all the sensors. Then you have only the G-Code stuff in SPIN, and possibly some communication stuff, and the load hub ram that was used to load the PASM code that is then put into COG mem can be reused for buffers or what ever.
This is why my firmware is mostly in PASM, and none of it needs to be kept in Hub mem.
As mentioned ealier, Teacup is written pretty darn lean, and there is not a whole lot of code that you can remove and still remain functional. I could try eliminating some of the supported G and M commands, but I really do not want to do that. So right now, it is propably as small as it is going to get, and it is still too large. However, I do have a new strategy.
My new strategy is similar to my current stragegy, in the fact that the program will be split in two. There are several significant portions of code, but the two main ones are parsing and processing, with the queue being the middleman. As is the current situation, the split will be at the queue. However due to memory concerns, it cannot remain as it is and this is where the new strategy comes into play. It is a basic concept and it should not be to hard to implement. I will be taking the sd reading, serial reading, and GCODE parsing and placing them on one Propeller chip and the rest of the code, which all pertains to processing, will be placed on another Propeller chip. And the only thing that will pass from one chip to the other will be the queue. So one chip will create the queue and the other chip will process the queue.
I believe this should do the trick, but perhaps the processing end may still be too large for one Propeller chip. Only testing will tell.
By adding another Propeller chip, I also gain another advantage, which is the removal of the Propeller Memory Card from the main controller board, thus opening up several IO pins, so that all homing and limit switches can be utilized. In all honesty, it is looking pretty promising, and as mentioned, it should not require too many changes on the current controller board.
A thought - would it be possible to write the queued data to SDcard/SRAM and use two passes, needing only one Prop ?
Since my last post, I have been trying to make an actual split and I have come to the conclusion, that a split is not possible, like I thought it would be. That firmware is so tightly intermingled, it is just simply unbelievable. Teacup is truly a brilliant peace of code work, but it will be very difficult to actually port it to the Propeller, unless of course Dave does something with the simulator end of things.
The main problem is the way the M codes and various G codes are handled. Some of them are never added to the queue, which was an oversight on my part. If they had added everything to the queue for processing, I believe it would have been a breeze. I do not believe there is a work around for this obstacle.
Besides all the work I have invested, it is really a shame that I could not get this to work for the Propeller. I think it would have been a good thing for Parallax.
If anyone is interested in my stopping point, along with further obstacles that need to be overcome, I would be more than happy to discuss these issues, as well as providing the latest project build.
I am debating weather I will continue to process the G-Code in the firmware, or if I will instead use a more compact command structure to send to the printer and process the G-Code on the host system.
The original firmware I wrote was mostly in PASM, the rewrite is almost all spin. The Original did have the G-Code processor in the Propeller, though I think it better to process that on the host side (still open to debate).
It will be a while before I am able to test the rewrite, as it is just bits and pieces at the moment, though if you would like I can start a thread to step through my work in progress.
I am always interested in seeing code that operates machinery, but what I am really interested in is the processing of steps with Bresenham's line drawing algorithm.
I will be starting a new thread soon for my current parser and processor.
As to the line drawing, you are in luck. My stepper object includes a simplified implementation for the XY plane. I did this to simplify some of the work in controlling the 3D printer.
Yea that won't work with Teacup, it is a lame duck at this point. If you refer to Post #224, you will see that I state that the M codes never make it to the queue and it relies on gcode_process to do a lot of the work, which makes splitting it, almost an impossibility.
In reference to your Post #213, READ, WRITE, SET_INPUT and SET_OUTPUT....
As you know, the definitions were in arduino.h, which was then altered to propellerized.h. During an attempt at code reduction, propellerized.h was completely eliminated. Without the use of the simulator, there were three files using these functions which were forger.c, pinio.c, and pinio.h. These three files were modified to remove all macros and utilize propeller functions from simpletools.h.
From the main file
pinio.c
pinio.h
I was just telling you how I changed my files to eliminate the macros completely.
LOL I wish it did.
I do not know what you are seeing that I am not. When I run your program with the terminal, I simply get a blue screen. When I type, the terminal displays the characters, but that is it. What's working? I basically have a blue screen. I still don't get it. How are you verifying that it is working?
What are the remaining changes that need to be done?
What about config.h? Just swap it out for my config.h?
I was not mocking you... I was laughing at the fact that I missed the most important part of your post... but okay
Thank you for the confidence though.
The attached archive will generate three (3) warnings during the build process. These warnings are as follows:
And these warnings particularly apply to the processing of M2/M84 and M119 commands within gcode_process.c. Commands M2/M84 have a commented loop, which blocks the use of the "i" variable, and command M119 generates unused variable warnings because limit switches have not been defined in config.h, therefore the variables "open" and "triggered" are currently unused.
Without going into too much detail, this project has reorganized the Teacup firmware in an attempt to bypass the use of interrupts. Basically the main cog creates the movement queue and another cog attempts to read and process the movement queue. In an effort to provide the cleanest project possible for future endeavors, I have removed some of the previous programming, in which I attempted to make the shared variables and structs volatile, however this generated a bunch of warnings due to memcpy. It is my understanding that in order for these variables and structs to be shared between cogs, they must be volatile.
As well as removing some previous programming, I have also reestablished some of the previously removed programming, but more particularly, the original source and header files for the ADS1015 ADC.
While I do believe that my theory of operation should work, the biggest obstacle at this point is overcoming the memory issue, because I cannot troubleshoot any further without overcoming this barrier. The code responsible for processing the queue and movement, resides in queue_monitor.c. Within queue_monitor.c a while loop is currently commented out, because it causes the code to fail severly. At this point, I assuming that this is due to insuffient stack space, until I get the opportunity to prove otherwise. However I suppose the failing code could also be attributed to the code that I am attempting to run, however this code closely matches the original Teacup code. The currently alloted stack size for the queue_monitor cog is a mere 150 int(s), and I just know this is way to small, because this cog handles a lot of code. The current build comes in at "Code Size 28,536 bytes (31,176 total)".
EDIT: Known And Assumed Cog Usage
1) Main (Known)
2) ADS1015 ADC (Assumed)
3) SD Card (Assumed)
4) Queue Monitor (Known)
5) Clock Timer (Known)
6) Full Duplex Serial (Currently Unused, If Enabled Known)
I am looking for any reasonable ideas to decrease program size,
which would allow a larger stack size for the queue_monitor cog.
####WARNING######
If you decide to run this project, please ensure that you set the proper IO pins in config.h!!!
Give this code a try and see if it works OK for you. If you type a command like "G1 X1" you should see prints showing the X pin toggling.