Shop OBEX P1 Docs P2 Docs Learn Events
MAX 31855 trying to read with Propeller? — Parallax Forums

MAX 31855 trying to read with Propeller?

NeutronNeutron Posts: 21
edited 2014-01-30 22:15 in Propeller 1
Hello,

I know there must be some simple mistake I'm making here. I'm trying to read one of these http://www.adafruit.com/products/269 using Jonny Mac's object jm_max31855.spin

I'm just trying to read and display a temp value on an lcd... but not getting anything but zero on screen.

This is my program:
''TC testing


CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

  CR = 13
  
  cspin = 17
  sckpin = 16
  misopin = 19
  lock = -1


  LCD_PIN   = 8                 
  LCD_BAUD  = 19_200
  LCD_LINES = 4    
 

OBJ
  TC : "jm_max31855"
  lcd : "debug_lcd" 

VAR
  long tcone          ' 

  long count
    
       
PUB Initialize

  tcone~          ' 
  count~
  
  if lcd.init(LCD_PIN, LCD_BAUD, LCD_LINES)             'Start lcd
    lcd.cursor(0)                                       'Cursor off
    lcd.backLight(true)                                 'Backlight on (if available)
    lcd.cls                                             'Clear LCD 
    waitcnt(clkfreq/10+cnt)                             'Pause for lcd clearing
    lcd.gotoxy(0,3)                                     'Position cursor  
    lcd.str(string("TEMP VALUE",CR))                    'Print text label
                                                                                   
  TC.start(cspin, sckpin, misopin, lock)               

  Main


PUB Main

  repeat
    tcone := TC.read_tc(1)
    updateLcd(tcone)
    waitcnt(clkfreq+cnt)
  

PRI updateLcd(val1)                           
'Display recieved value
  lcd.gotoxy(0,0)                                'Position cursor
  lcd.decf(val1,10)                              'Print right-justified decimal value


Can somebody spot what I'm doing wrong here?

Comments

  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-01-29 16:04
    I don't think it's a good idea to chain methods the way you're doing -- a method call is like a GOSUB, not a GOTO, that is, information is left on the stack that never gets popped off.

    I'm very particular about program formatting -- here's how I would re-format your code.
    '' TC testing
    
    
    con
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    
    con
    
      MISOPIN = 19      
      CSPIN   = 17
      SCKPIN  = 16
    
      LCD_PIN =  8  
    
      
    con
                     
      LCD_BAUD  = 19_200
      LCD_LINES = 4    
     
    
    obj
    
      tc  : "jm_max31855"
      lcd : "debug_lcd" 
    
      
    var
    
    
    pub main | t, tcone
    
      ifnot (setup)                                                 ' if problem
        repeat                                                      ' low-power shutdown
          waitcnt(0)
    
      t := cnt                                                      ' sync loop
      repeat
        tcone := tc.read_tc(true)                                   ' get temperature               
        lcd.gotoxy(0, 1)                                            ' move to start of 2nd line
        lcd.decf(tcone, 10)                                         ' display; right-justified
        waitcnt(t += clkfreq)                                       ' update every second
        
    
    pub setup
    
      ifnot (tc.start(CSPIN, SCKPIN, MISOPIN, -1))
        return false
    
      ifnot (lcd.init(LCD_PIN, LCD_BAUD, LCD_LINES))
        tc.stop
        return false
    
      ' both objects initialized; configure LCD
    
      lcd.cursor(0)
      lcd.backlight(true)
      lcd.cls
      waitcnt(cnt + clkfreq/10)
      lcd.str(string("TEMP VALUE"))
    


    Make sure that you have the correct kind of thermocouple and that it's connected properly. I used my tc object in a commercial application so it has been vetted.
  • NeutronNeutron Posts: 21
    edited 2014-01-30 10:20
    It turns out I had made a simple wiring error, my original program now works. The main goal of this project (exhaust gas temp display) is to better my programming skills. I welcome any input!

    So by chaining methods like I was, I'm leaving data on the stack from the first method that never gets revisited... correct? With enough of this, I would presumably end up with a stack full of "garbage" and open myself up to some strange behavior from the Prop. I just want to make sure I'm understanding correctly.

    Thank you!
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-01-30 10:28
    You could and that happened to a friend who was treating method calls like GOTO instead of GOSUB. He though his program would run in a loop like this

    Method_A calls Method_B
    Method_B calls Method_C
    Method_C calls Method_A

    It worked -- for a minute or so, then the stack crashed and the program stopped. The correct structure for him was:
    pub main
    
      repeat
        method_a
        method_b
        method_c
    


    Remember that when you call a method, the return address of that method (plus any parameters that get passed) are pushed onto the stack. Those values are popped from the stack when then called method is complete.

    When you get a little more advanced you'll want to look into abort trapping. Some programs will have nested calls and an error should take us all the way back up to the origin -- this is where abort comes in handy.
  • NeutronNeutron Posts: 21
    edited 2014-01-30 15:21
    That makes sense. Thanks a bunch!
  • garyggaryg Posts: 420
    edited 2014-01-30 20:57
    JonnyMac wrote: »
    You could and that happened to a friend who was treating method calls like GOTO instead of GOSUB. He though his program would run in a loop like this

    Method_A calls Method_B
    Method_B calls Method_C
    Method_C calls Method_A

    It worked -- for a minute or so, then the stack crashed and the program stopped. The correct structure for him was:
    pub main
    
      repeat
        method_a
        method_b
        method_c
    


    Remember that when you call a method, the return address of that method (plus any parameters that get passed) are pushed onto the stack. Those values are popped from the stack when then called method is complete.

    When you get a little more advanced you'll want to look into abort trapping. Some programs will have nested calls and an error should take us all the way back up to the origin -- this is where abort comes in handy.


    Jonnymac
    This GOTO,GOSUB thing Is something that I've been trying to deal with for the past several months.
    It is an important subject that, for some reason, I was not able to understand until very much lately.
    I'm really trying to understand this.
    In OLD BASIC like GW basic and Qbasic GOTO statements leave no return address.
    GOSUB does leave a return address.
    It appears that in spin, there is really no GOTO statement that does not leave a trace of where it's been.

    Thanks for your comments.
    I realize that I'm reveiling that I'm basic lly an old guy.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-01-30 22:15
    It appears that in spin, there is really no GOTO statement that does not leave a trace of where it's been.

    You got it; there is no explicit equivalent of GOTO in Spin. This bothers some that migrate from BASIC, but I always encourage those learning any new language for what it is, not what we wish it was.

    Indecently, there is a PASM instruction called JMP, which is the Assembly version of GOTO. While this may seem like a contradition, it's really not. For example, we might do this in BASIC:
    Main:
      GOSUB Routine_A
      GOSUB Routine_B
      GOSUB Routine_C
      GOTO Main
    


    In Spin, we do this:
    pub main
    
      repeat
        routine_a
        routine_b
        routine_c
    


    Note how there's an implicit GOTO at the end of the repeat loop.
Sign In or Register to comment.