Shop OBEX P1 Docs P2 Docs Learn Events
Question on using a spin object, but also a custom function... — Parallax Forums

Question on using a spin object, but also a custom function...

clcorbinclcorbin Posts: 14
edited 2008-09-20 09:00 in Propeller 1
Let's see if I can explain what I want to do clearly... I have built a small interface board for testing/playing with my Propeller proto board. It has four SMD switches, four green SMD LEDs wired to the switches (so you get a green LED turning on every time you press a switch) and four red SMD LEDs that I can use for assorted output.

And yes, I was also playing with building SMD PCBs at the time I built this thing...

The whole thing is wired up to a cable that is wired to a 10 pin header so I can get power and ground in, the four switch signals out, and the four LEDs in. I have pin headers installed on each side of the proto board, so it is trivial to plug it into one side when I need some input/output for my testing/playing.

Yesterday, I decided that because I have a standard bit of hardware that I use for testing, I should go ahead and write and object to configure it and operate it so I didn't have to keep duplicating the same code over and over again in different projects. The object works perfectly for what it is, I can use the "Configure" method and pass it the pin number of button1 and it will then setup the four switches and four leds. It has functions that are used for turning the LEDs on and off and it also starts a cog that monitors the four inputs, debounces them, and then figures out what to do when you press the button.

And THAT is the rub. 90% of this object is the same for every single project. But there is usually quit a bit of variation in what is supposed to happen once it figures out which button is pressed, depending on what the particular application it is in. As it is written, all of this variation is wrapped up in a single function "FindButton".

Is there anyway I can write the FindButton function in the main application but have the monitor object use that function? Or, will I have to edit a FindButton function inside the monitor object with every project? That is still MUCH faster than writing the whole thing from scratch every time, but I would really like to have an object that is written and DONE.

Any better ideas on how to persue this?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Clint

Comments

  • TimmooreTimmoore Posts: 1,031
    edited 2008-09-16 23:55
    One way to do this is to pass in an address of a variable into the object during init. The cog in the object writes to it when a button is pressed and writes a value when the button is released e.g. 0 if no button.
    The main cog normally will have a repeat loop processing whatever it needs. As part of the loop call FindButton which checks the variable, if 0 return else do whatever it needs to do.
    This is the basic approach I use a lot for monitoring sensors.
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-09-17 04:36
    hello Clint,

    you made a detailed description of what you would like to to.

    As english is not my native language I'm not sure if I understood everything right.

    It would become much easier if you post two examples showing what stays the same and what changes

    you wrote "...and then figures out what to do when you press the button" does this mean you want to do
    different things like
    Application 1: if button 3 is pressed switch on PIN 19
    Application 2 if button 3 is pressed blink PIN 23 for 2 seconds

    INSIDE the object that should be DONE ???

    Inside your object you could define a method start wich has parameters like pin-number of first button
    And you can define another method that will be called from your mainfile and GIVES BACK a result value
    and then your findbutton method will be inside your mainfile

    best regards

    Stefan
  • clcorbinclcorbin Posts: 14
    edited 2008-09-17 16:28
    Stefan,

    Actually, I think you have a pretty good understanding of what I am trying to do.

    For example, on the project I am playing with right now, I am simulating a temperature controller. This is what the buttons need to do for the application:

    Button1 pressed: temperature := temperature + 5
    Button2 pressed: temperature := temperature - 5
    Button3 pressed: If enabled, disable, else enable
    Button4 pressed: ignore

    The code for this would be written in the "FindButton" function which would be called every time a button is pressed.

    Other applications might do as you suggest and toggle I/O pins when buttons are pressed, or possibly turn on an LED using the object, or who knows what. But pretty much no matter what I am trying to do, the only changes required are in the "FindButton" function. Everything else stays the same.

    So, to sum it up, I already have a basic Monitor object that can configure and monitor buttons and configure and operate the LEDs. But for every different application that I use this object in, I have to edit the "FindButton" function to customize it for that application. I would like to be able to pull the "FindButton" function out of the object so I do not ever edit the working Monitor object.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Clint
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-09-17 17:20
    Hello Clint,
    Clint said...

    So, to sum it up, I already have a basic Monitor object that can configure and monitor buttons and configure and operate the LEDs.
    But for every different application that I use this object in, I have to edit the "FindButton" function to customize it for that application.
    I would like to be able to pull the "FindButton" function out of the object so I do not ever edit the working Monitor object.

    Yes this is quite easy:

    INSIDE your monitorbject you define a method Get_Button_Value

    This method gives back a resultvalue

    and then OUTSIDE your monitorobject

    as a raw drawing this looks like this
    VAR
      long ButtonPressed
      long EnDis
    
    OBJ
      MonBtn : "Monitor_Buttons"
      
    PUB YourCustomized_Method
    
      EnDis := 0
      ButtonPressed := MonBtn.Get_Button_Value
       
    
      if ButtonPressed == 1
        temperature := temperature + 5
    
      if ButtonPressed == 2
         temperature := temperature - 5
    
      if ButtonPressed == 3
         !EnDis
    
    
    'this method Get_Button_Value is INSIDE your monitor-object
     
    PUB Get_Button_Value : BtnVal
    
    'pseudocode
     monitorbuttons
     if button1 is pressed
       BtnVal := 1
    
     if button2 is pressed
       BtnVal := 2
    
     if no Button is pressed
       BtnVal := 0
    
    
    



    This means: INSIDE your monitor-object there is a method that just gives back a different values for different buttons

    The evaluation of the value is coded OUTSIDE your monitor-object

    make a try to code this. And if it does not work post your COMPLETE archived project
    not only code-snippets

    best regards

    Stefan
  • Paul BakerPaul Baker Posts: 6,351
    edited 2008-09-17 18:30
    Hi Clint,
    There are three ways of passing information across the object boundry: by value, by reference or by wire. The first is done by calling a method in the child object and passing the value through an argument to the method and/or the return value. This is the direction Stefan is pointing you. The second is passing a memory address and each object monitors the location(s) and acts accordingly depending on what the contents are. This is the direction Timmore is pointing you. The last is by using a I/O pin as a communication path between the two objects (this option is rarely used).

    For your application I recommend using the first option Stephan is outlining for you.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • clcorbinclcorbin Posts: 14
    edited 2008-09-20 06:34
    Thanks for the info gents. It looks like I might be stuck then, as none of these methods do what I am trying to do. I can see how Stephan's method would work, but now I have TWO cogs working on something that is only taking a fraction of the time of a single cog.

    In a way, what I want to do is pretty much backwards from Stephan's method. Instead of passing information OUT of an object, I want to know if there is anyway I can pass a complete function TO the object. This would allow me to use the fully built Monitor object, then write the FindButton function in the main routine and pass that to the Monitor object/cog so it can use it to process the results.

    Either way, it is a lot better as I have it now (Monitor object and having to rewrite the FindButton function for each specific application inside the monitor object) versus rewriting the silly thing ever time I wanted to use my input/output board.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Clint
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-09-20 09:00
    Hello Clint,

    SPIN is not as complex as C or C++ whre you can pass complex things like complete functions or methods
    In SPIN you can only pass 1 to n longs to a method as parameters

    Maybe there could be a solution but therefore I have to know what is the maximum variance of the method FindButton

    There are some threads about similar things like you want to do. But as far as I remember the discussion it is very picky
    to change the SPIN-tokens. I remember a thing called DOL dynamic object-loader. This is more or less your direction
    Take a look at it. But I think it will be the same effort as program it customized

    But maybe I have a big lack in understanding what you would like to do
    Maybe I understand more if you post your monitor-object

    best regards

    Stefan
Sign In or Register to comment.