Shop OBEX P1 Docs P2 Docs Learn Events
Returning more than one value from method — Parallax Forums

Returning more than one value from method

stevoveestevovee Posts: 18
edited 2013-10-11 15:32 in Propeller 1
To give a little background on my project. I already have a PCB made so I can't really go change the schematic much and I'm pretty much out of IO pins. I'm interfacing with two max6675 thermocouple chips. In my schematic to save pins I have the CS and SCK pins connected together and then each chip has a separate IO pin for the SO pin. Individually they both work fine, i'm using this object http://obex.parallax.com/object/566

But I want to get to where I can pull out temp information from both thermocouples. I'm using the shiftin command from that object.
PUB SHIFTIN(Dpin, Cpin, Mode, Bits)|Value 

    dira[Dpin]~                                           ' make dpin input
    outa[Cpin] := ClockState                              ' set initial clock state
    dira[Cpin]~~                                          ' make cpin output


    
    Value~                                               ' clear output 




    if Mode == 0                'MSBPRE
       repeat Bits
         value := (Value << 1) | ina[Dpin]
         PostClock(Cpin)
          
    if Mode == 1                'LSBPRE
       repeat Bits +1
         Value := (Value >> 1) | (ina[Dpin] << 31)
         PostClock(Cpin)
       value >>= (32 - Bits)


    if Mode == 2                'MSBPOST
       repeat Bits
         PreClock(Cpin)
         Value := (Value << 1) | ina[Dpin]
 
    if Mode == 3                'LSBPOST
      repeat Bits + 1
        PreClock(Cpin)
        Value := (Value >> 1) | (ina[Dpin] << 31) 
      Value >>= (32 - Bits)




    return Value



the CS and SCK pins should stay the same. I can add a Dpin2 to the inputs for this function and write in a value2 into the function but I can't figure out how to pass 2 values out of this function. Anyone have any ideas?

Comments

  • stevoveestevovee Posts: 18
    edited 2013-10-11 11:24
    It would probably easiest for the rest of my code if I could just have it save to a public variable that was updated in my main loop. Could I just setup another public variable that it saves the second value to once it runs all repeats of the shifting in of bits?
  • ratronicratronic Posts: 1,451
    edited 2013-10-11 11:38
    What code do you have so far?
  • Mike GreenMike Green Posts: 23,101
    edited 2013-10-11 11:43
    Have another method that reads and processes a single thermocouple given a set of I/O pins like this:
    VAR long value1, value2
    PUB readThermocouple( CS, SCK, DO)
      dira[ CS ]~~
      outa[ CS ]~
      result := shiftin( DO, SCK, 2, 8)  ' whatever you need for a single thermocouple
      outa[ CS ]~~
    
    PUB partOfMain
      value1 := readThermocouple( CS, SCK, DO1)
      value2 := readThermocouple( CS, SCK, DO2)
    
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2013-10-11 11:43
    You can set it up with 2 return values, or even 10 values if you want.
    PUB SHIFTIN(Dpin, Cpin, Mode, Bits)|Value1, value2
        Your code
        return Value1, value2
    
    Duane J
  • Mike GreenMike Green Posts: 23,101
    edited 2013-10-11 11:49
    No, no, no. RETURN allows only one 32-bit return value. Look at the description in the Propeller Manual.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-11 11:49
    Normally you'd share the MISO pin and use separate CS pins. You'd then read the chips one at a time using the CS pins to indicate which chip you're interested in.

    You could do it the way you've wired it but then you need to come up with your own driver. Doing it the way you've wired it wouldn't be too hard but I'm not sure if you have the experience to do it that way yet.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-10-11 11:51
    You can set it up with 2 return values, or even 10 values if you want.
    PUB SHIFTIN(Dpin, Cpin, Mode, Bits)|Value1, value2
        Your code
        return Value1, value2
    
    Duane J

    As Mike said, it doesn't work that way. Only one value is returned.
  • stevoveestevovee Posts: 18
    edited 2013-10-11 12:25
    since I'm only bringing in a 16 bit number and I can pass in a 32bit
    what If i shift both into one 32bit number and then split it up in my code?
  • Mike GreenMike Green Posts: 23,101
    edited 2013-10-11 12:31
    Yes, you can pack several values into a single 32-bit return value and unpack them later. If the values are signed, be sure to extend the sign. There's a built-in operator to do that for 16-bit words and 8-bit bytes.
  • stevoveestevovee Posts: 18
    edited 2013-10-11 12:31
    uta[reset]:=0                                              '' Request to read the temperature
            Celsius := SPI.SHIFTIN(DQ,CLK, SPI#MSBPRE, 16)  '' read the temperature
            outa[reset]:=1                                      
    
    
            Celsius := Celsius >> 3
    

    this is basically the code I'm calling to bring in the temperature now using the spi object mentioned above

    and then i'm in mode zero so this is the section of the object that i'm referring to
    PUB SHIFTIN(Dpin, Cpin, Mode, Bits)|Value 
    
        dira[Dpin]~                                           ' make dpin input
        outa[Cpin] := ClockState                              ' set initial clock state
        dira[Cpin]~~                                          ' make cpin output
    
    
        
        Value~                                               ' clear output 
    
    
    
    
        if Mode == 0                'MSBPRE
           repeat Bits
             value := (Value << 1) | ina[Dpin]
             PostClock(Cpin)
    

    what if i made it so I shift in both 16 bit values, then change the object to combine them and output onen 32bit number which I can split up in code
  • stevoveestevovee Posts: 18
    edited 2013-10-11 12:32
    Mike Green wrote: »
    Yes, you can pack several values into a single 32-bit return value and unpack them later. If the values are signed, be sure to extend the sign. There's a built-in operator to do that for 16-bit words and 8-bit bytes.

    What is the operator for doing this? I was just going to shift one of them 16 bits one direction and then the other 16 bits the other direction
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-10-11 12:49
    You can do it this way:
    pub temperatures : rvalue
      ...
      word[@rvalue][0] := temp0
      word[@rvalue][1] := temp1
    

    -Phil
  • stevoveestevovee Posts: 18
    edited 2013-10-11 13:34
    Once again thanks everyone for the help. What i did was modify the object to the following.
    PUB SHIFTIN(Dpin,Dpin2, Cpin, Mode, Bits)|Value, Value2, Value3
    
        dira[Dpin]~                                           ' make dpin input
        outa[Cpin] := ClockState                              ' set initial clock state
        dira[Cpin]~~                                          ' make cpin output
    
    
        
        Value~                                               ' clear output 
    
    
    
    
        if Mode == 0              
           repeat Bits
             value := (Value << 1) | ina[Dpin]
             value2:= (Value2 << 1) | ina[Dpin2]
             PostClock(Cpin)
    
    
        word[@value3][0] := value
        word[@value3][1] := value2
        
    
    
    
    
        return Value3
    

    and then in my main code I did this to get two separate temps which are othertemp and celsius
    outa[reset]:=0                                              '' Request to read the temperature
            Celsius := SPI.SHIFTIN(DQ,DQ2,CLK, SPI#MSBPRE, 16)  '' read the temperature
            outa[reset]:=1                                      
            othertemp:=Celsius<-16
            othertemp := othertemp >>19                  
            Celsius:=Celsius>>19
    
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-10-11 14:17
    When I want to affect more than one variable I tend to pass pointers as parameters. For example:
    pub some_method(param1, param2, param3, p_result1, p_result2)
    
      ' do something
    
      long[p_result1] := something_cooked_up_by_method
      long[p_result2] := something_cooked_up_by_method
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-10-11 14:51
    JonnyMac wrote: »
    When I want to affect more than one variable I tend to pass pointers as parameters.
    That's the technique that I generally also. If you have a large number of variables you could group them together in memory, and pass a single pointer that points to the beginning of the group.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-10-11 15:17
    That's the technique that I generally also. If you have a large number of variables you could group them together in memory, and pass a single pointer that points to the beginning of the group.


    Great minds think alike! :) -- I do that, too!
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-10-11 15:32
    stevovee,

    If your temperatures are in twos complement form you will want to do an arithmetic right shift (~> instead of >>) on your results to propagate the sign for negative values.

    -Phil
Sign In or Register to comment.