Parallax Forums
  HomeLog InRegisterCommunity CalendarSearch the ForumHelp
   
Parallax Forums > Public Forums > Propeller Chip > LCD Code Simplification  Forum Quick Jump
 
New Topic Post Reply Printable Version
[ << Previous Thread | Next Thread >> ] | Show Newest Post First ]

IRobot2
Registered Member



Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Feb 2005
Total Posts : 37
 
   Posted 11/6/2009 8:32 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
I am using the Matrix Orbital LCD (LK204-25) from Parallax (30058) connected to my prop. To communicate with it I am using the FullDuplexSerial Object from the Obex. I am currently using statements like this:

LCD.tx(254)
LCD.tx(71) ‘’Set Cursor Position
LCD.tx(9) ‘’Column Position
LCD.tx(3) ‘’Row Position
LCD.str(string(“Hello World”))

As you can see this takes up a lot of space (and time). Is there any way to simplify this into one line? I have page after page of this just to display basic things. All the commands I took right out of the manual. Any help or thoughts would be greatly appreciated.


Alex Burke
"Beware of computer programmers that carry screwdrivers." -Leonard Brandwein

Back to Top
 

StefanL38
Registered Member

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Sep 2006
Total Posts : 957
 
   Posted 11/6/2009 8:53 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
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



Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined May 2008
Total Posts : 284
 
   Posted 11/6/2009 9:04 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
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
 

IRobot2
Registered Member



Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Feb 2005
Total Posts : 37
 
   Posted 11/6/2009 9:22 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
Thanks Stefan and Jonathan, I will look into this a little closer. I agree with the attitude of helping some one figure out the answer instead of just giving it to them. Makes it much more rewarding for both parties. I just needed a pointer in the right direction. If that does not get me anywhere I will post back with specifics. Thanks again -


Alex Burke
"Beware of computer programmers that carry screwdrivers." -Leonard Brandwein

Back to Top
 

Todd Chapman
Registered Member



Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined May 2006
Total Posts : 1538
 
   Posted 11/6/2009 9:45 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
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

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Sep 2006
Total Posts : 957
 
   Posted 11/6/2009 11:02 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
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

Stefan

Post Edited (StefanL38) : 11/6/2009 7:12:55 PM GMT

Back to Top
 

MagIO2
Registered Member

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Mar 2009
Total Posts : 595
 
   Posted 11/6/2009 11:32 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
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
 

chris jones
Registered Member

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Sep 2009
Total Posts : 145
 
   Posted 11/6/2009 11:49 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
hello
 
i am not sure if this will help you out or not i have used this code and it works for me you might have to do some editing.
 
 
Back to Top
 

IRobot2
Registered Member



Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Feb 2005
Total Posts : 37
 
   Posted 11/6/2009 12:17 PM (GMT -8)    Quote This PostAlert An Admin About This Post.
@Stefan - Wow - That is exactly what I have been looking for around a month now. It helps me out not only with my LCD problem but really answers many questions I have had for a while now. Like you said it is all about learning the little things because they all add up to something much larger. I really appreciate you taking the time to send that my direction.

Thanks every one for all your help. I just shrunk the amount of code I had by about 3/4. Funny how learning something so small can save you days of headache!


Alex Burke
"Beware of computer programmers that carry screwdrivers." -Leonard Brandwein

Back to Top
 

StefanL38
Registered Member

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Sep 2006
Total Posts : 957
 
   Posted 11/6/2009 12:48 PM (GMT -8)    Quote This PostAlert An Admin About This Post.
@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
 

MagIO2
Registered Member

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Mar 2009
Total Posts : 595
 
   Posted 11/6/2009 1:18 PM (GMT -8)    Quote This PostAlert An Admin About This Post.
The stack is a memory area used for passing parameters, return value and return adress to/from SPIN functions and for the local variables of a function.

For each function you call you need some memory on the stack (even if it does not have parameters/local variables). The main SPIN interpreter has the whole not used HUB-RAM as stack-space. For each other SPIN function that you start in a new COG, you have to give a stack adress that it can use. (See description of cognew).

If you create a function that calls a function that calls a function that calls ..... you need more and more stack-space for each level. If you don't know that it will very soon become a problem. Because when stackspace is to small a function-call can overwrite memory that's been used otherwise. For example one stack overwrites another stack. Thus the return values and return adress might be overwritten. This can lead to very curious results.

Post Edited (MagIO2) : 11/6/2009 9:28:02 PM GMT

Back to Top
 

StefanL38
Registered Member

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Sep 2006
Total Posts : 957
 
   Posted 11/6/2009 11:11 PM (GMT -8)    Quote This PostAlert An Admin About This Post.
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

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Mar 2009
Total Posts : 595
 
   Posted 11/7/2009 12:53 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
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
 

BradC
Gronk



Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Jul 2007
Total Posts : 1577
 
   Posted 11/7/2009 2:49 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
MagIO2 said...


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).


No. Each function call takes 2 longs (4 words) for the internal management, plus one long for the return value (whether you assign it or not), One long for each parameter and one long for each local variable. Return Value, Parameters and Local variables are all longs and are treated the same. The only difference is the interpreter zeros the return value and writes the parameters prior to invoking the method call.


If you always do what you always did, you always get what you always got.

Back to Top
 

StefanL38
Registered Member

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Sep 2006
Total Posts : 957
 
   Posted 11/7/2009 5:39 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
OK

If I count right for my example above


      2 longs 'call of method WriteToLCD
      1 long  'returnvalue of method WriteToLCD
      3 longs '3 parameters of method WriteToLCD WriteToLCD(Col,Row,StringPointer)


      2 longs 'call of method LCD_Hello_Screen
      1 long  'returnvalue of LCD_Hello_Screen(StringPointerName)
      1 longs '1 parameter of method LCD_Hello_Screen(StringPointerName)
     --
 Sum 10 longs


10 longs / 8188 longs = 0.12 % of the HUB-RAM-space
that's what I thought. As long as the whole program does not use 90% of the HUB-RAM the danger of running out of memory is small

Your abo(expletive)e right MagIO when starting another cog with the command cognew you have to take care that the stackspace for the new cog
is big enough

best regards

Stefan
Back to Top
 

MagIO2
Registered Member

Email Address Not AvailablePersonal Homepage Not AvailablePrivate Messaging Not AvailableAIM Not AvailableICQ Not AvailableY! Not AvailableMSN Not Available
Date Joined Mar 2009
Total Posts : 595
 
   Posted 11/7/2009 6:37 AM (GMT -8)    Quote This PostAlert An Admin About This Post.
@BradC:
Thanks for refreshing my DRAM ;o)
 
@Stefan:
You only miss to count the calls to LCD.tx .. and whatever these functions might call. So, when calling the function in a new COG having only 10 longs stack it could already cause trouble.
 
All I want to say:
If you nest function calls you need to know what it means for the stack. And if you add a level you should double-check the stack sizes for your SPIN COGs that use this branch of the code.   

Post Edited (MagIO2) : 11/7/2009 2:49:30 PM GMT

Back to Top
 
[ << Previous Thread | Next Thread >> ]
New Topic Post Reply Printable Version
 
Forum Information
Currently it is Friday, November 20, 2009 10:58 PM (GMT -8)
There are a total of 393,737 posts in 55,521 threads.
In the last 3 days there were 82 new threads and 702 reply posts. View Active Threads
Who's Online
This forum has 17687 registered members. Please welcome our newest member, mark09.
54 Guest(s), 6 Registered Member(s) are currently online.  Details
Peter Verkaik, BradC, Harley, Chris Savage (Parallax), Rich_W8VK, potatohead