 |
|
 |
| Parallax Forums > Public Forums > Propeller Chip > LCD Code Simplification | Forum Quick Jump
|
 |  StefanL38 Registered Member
        Date Joined Sep 2006 Total Posts : 957 | Posted 11/6/2009 8:53 AM (GMT -8) |   | I'm a friend of discovering solution by yourself. So as a first hint: Do understand what a "PUB-method" does in general ?
read a little bit in the manual about "PUB" I think this will get you ahead. If you don't understand it - come back with a new and more concrete questions
best regards
Stefan | | Back to Top | | |
 |  lonesock Registered Member

       Date Joined May 2008 Total Posts : 284 | Posted 11/6/2009 9:04 AM (GMT -8) |   | The propeller manual doesn't seem to cover this in the string section, but you can use string like this:
ptr := string( 1, 2, 3, 4, "Add in some text", 13, "And another line", 13 ) The exception is that you can not send a 0 value, as strings are zero-terminated in Spin.
Jonathan
(sorry Stefan, I was going to point to the manual, but it's wasn't overly helpful) lonesock Piranha are people too. | | Back to Top | | |
  |  Todd Chapman Registered Member

       Date Joined May 2006 Total Posts : 1538 | Posted 11/6/2009 9:45 AM (GMT -8) |   | Instead of retyping all that stuff each time just create a new PUB ( as hinted ) whereas the caller just sends one line:
MultiLineMethod(0,0,"hello world", etc, etc, etc, etc ...., terminate)
PUB MultiLineMethod(row, line, string1, sring2, string3, string4 etc etc etc etc etc ) ' do the work for row ' do the work for line ' do the work for string1 ' do the work for string2 ' do the work ' do the work ' do the work ' do the work
You could have a long list of possible 'work' lines, and use some termination scheme to RETURN if a parameter is designated as a terminating value.
This obviously needs to be thought out but this should set you on an easier path.
Another use for PUB while we are on it...
Say you don't like typing out waitcnt(80_000_000 + cnt) a thousands of times in your life of using the Propeller, do this instead:
PUB w(time)
waitcnt(time + cnt)
Then when you need to make a wait you just call w(80_000_000), much shorter and faster to type.
Use PUBs to reduce manual redundant input when a pre-coded method will just receive parameters and do all the work.Post Edited (Todd Chapman) : 11/6/2009 5:51:16 PM GMT | | Back to Top | | |
 |  StefanL38 Registered Member
        Date Joined Sep 2006 Total Posts : 957 | Posted 11/6/2009 11:02 AM (GMT -8) |   | OK, I made a quick review of the chapter about "PUB" in the manual. Does say not very much for real newbies.
The fundamental sense of a STRUCTURED programming language is to build complex commands out of basic commands.
You can imagine this similar to a mechanical machine. The mechanical machine is build by many parts. Screws, ball-bearings, axles, etc. Each part has a basic function. A screw has the function of "keeping two parts together". A ballbearing has the function of "making the axle turning with ease". All parts mounted together in a certain way result in a car or a handdrillmachine or whatever - which do very complex things compared to what a single part can "do"
And on that general level of explanation it is the same with "PUB"s.
SPIN has a basic set of commands. And you can use this basic set of commands to create more powerful and or complex commands In the mechanical analogon a car has functional sub-parts like "motor", "gearbox", "current-generator" etc. etc.
So f.e. the gearbox has a housing that keeps all parts inside the gearbox together. On the level of the car as a whole thing. it is not interesting what happens inside the gearbox If the gearbox is broken one solution is to replace the whole gearbox. If you do so the details inside the gearbox doesn't matter. It's only interesting what size has the gearbox and what is the diameter of the shaft and what is the profile of the shaft. If this does fit to the motor everything is OK. And you can understand a "PUB" similar to the gearbox-housing.
If you write a piece of spincode
CON InitCommandMode = 254 SetCursorPos = 71
PUB WriteToLCD(Col,Row,StringPointer)
LCD.tx(InitCommandMode) LCD.tx(SetCursorPos ) ‘’Set Cursor Position LCD.tx(Col) ‘’Column Position LCD.tx(Row) ‘’Row Position LCD.str(StringPointer)
The PUB "WriteToLCD" holds the more basic commands like lcd.tx(254) etc. together.
Now you can use the PUB-Method named "WriteToLCD" in this way
WriteToLCD(9,3,string("Hello World"))
and this one line of code replaces
LCD.tx(254) LCD.tx(71) ‘’Set Cursor Position LCD.tx(9) ‘’Column Position LCD.tx(3) ‘’Row Position LCD.str(string(“Hello World”))
This principle can be nested almost endlessly. (until you run out of memory) This means now you could create another PUB-method
PUB LCD_Hello_Screen(StringPointerName)
WriteToLCD(1,1,string("Hello")) WriteToLCD(6,1,StringPointerName) WriteToLCD(1,2,string("how are you doing ?")) WriteToLCD(1,3,string("my batteryvoltage is OK"))
and call this method
LCD_Hello_Screen(string("Paul"))
and the result on the LCD will be
Hello Paul how are you doing ? my batteryvoltage is OK
If you take a look into almost any object-file like in the FullDuplexSerial-object you will find "PUB-methods" all over and PUBs using other PUBs
This is like some screws (containing a head and the "winding") and axles, ballbearings, toothwheels) build the gearbox and the gearbox is just a sub-unit of the car And those cars maybe belong to a company delivering pizza.
best regards
StefanPost Edited (StefanL38) : 11/6/2009 7:12:55 PM GMT | | Back to Top | | |
 |  MagIO2 Registered Member
        Date Joined Mar 2009 Total Posts : 595 | Posted 11/6/2009 11:32 AM (GMT -8) |   | | Giving such a good lesson, you also should have mentioned what this means for the stack space to make it perfect. Otherwise your lesson will very soon end in frustration ;o) | | Back to Top | | |
   |  StefanL38 Registered Member
        Date Joined Sep 2006 Total Posts : 957 | Posted 11/6/2009 12:48 PM (GMT -8) |   | @MagIO2:
hm - it's not clear to me what you mean by STACKspace in this case. Maybee I have "tomatos on my eyes" ) and I have to learn something important to close a gap of knowledge about programming in SPIN.
Defining complex methods and coding callings of these methods in most cases saves HUB-RAM-memory.
So please can you explain what you mean by
"this means for the stack space to make it perfect. Otherwise your lesson will very soon end in frustration ;o)"
I really don't understand and I appreciate if you explain it to me.
best regards
Stefan | | Back to Top | | |
  |  StefanL38 Registered Member
        Date Joined Sep 2006 Total Posts : 957 | Posted 11/6/2009 11:11 PM (GMT -8) |   | Hello MagIO,
I understand what you mean. And in the backround of my head I was aware of that. So what confused me was that you wrote "...lesson will very SOON end in frustration" I imagined write a small demoprogram with nested method-calls 4 or 5 levels deep and you have already a problem.
I remember some threads discussing on that issue and that for an exact caclulation the worst case of nesting has to be found. I did a research on the forum but I did not find a formula to calculate the stackspace required per one call. X bytes for every parameter, y bytes for the method itself etc.
If somebody has this formula HANDY I would appreciate if he could post it here. I have no idea how much it will be 1 long per parameter ? 2 or 10 longs for the method ?? I really don't know
best regards
Stefan | | Back to Top | | |
 |  MagIO2 Registered Member
        Date Joined Mar 2009 Total Posts : 595 | Posted 11/7/2009 12:53 AM (GMT -8) |   | Yes, you can have a very small demo which already runs into that problem. You just have to run a function in a new COG (COG 1) where you only give it 10 longs of stack-space. As mentioned, the stack of the 'main' SPIN interpreter (COG 0) is placed behind the last variable/dat. So, for such a small program the two stacks are very close and if COG 1 accidently exceeds the limit it will write into the stack of COG 0.
As stacks are not cleaned up you can test that with an easy program. Simply initialize the stack with $a5a5a5a5, run the functions and see how many bytes of the stack no longer have that value. I think there is an object in ObExchange for that.
I think the SPIN interpreter is flexible. If the value you have to pass fits into a byt it will only use a byte on stack. So, I'd expect that a function without parameters needs 6 bytes (2 for return adress and 4 for return-value). For each local variable you need a long (the variables you define with a | after the function name/parameter list). | | Back to Top | | |
   | Forum Information | Currently it is Friday, November 20, 2009 10:14 PM (GMT -8) There are a total of 393,733 posts in 55,521 threads. In the last 3 days there were 83 new threads and 703 reply posts. View Active Threads
| | Who's Online | This forum has 17687 registered members. Please welcome our newest member, mark09. 51 Guest(s), 4 Registered Member(s) are currently online. Details Zoot, Chris Savage (Parallax), Nick McClick, Highlandtinker |
Forum powered by dotNetBB v2.42EC SP2.02 dotNetBB © 2000-2009 |
|
|