Shop OBEX P1 Docs P2 Docs Learn Events
Basic stamp & Linux: how to read data on serial port? — Parallax Forums

Basic stamp & Linux: how to read data on serial port?

fromfrom Posts: 2
edited 2009-06-18 16:18 in BASIC Stamp
Dear forum,

I know this question has been raised several times but I haven't found the answer.

I have a quite extensive experience with Linux/POSIX C API for serial communication (tio, read, write and so on) but I'm a newbie to Basic Stamp. Despite my efforts I have not succeeded in communicating with my BS2e in C under Linux.
I would like to read data from a CMP03 device (connected via I2C) on the PC .

The PBASIC program seems OK (it runs under windows with Parallax soft). By the way it doesn't work with Hyper Terminal under windows so I guess it's a matter of serial port configuration.
The program waits for a 'j' and then outputs the bearing followed by CR ('\r' in C).

'{$STAMP BS2}

'***********************************************************
'**                                                       **
'**            I2C Routines for the Basic Stamp           **
'**            using the CMPS01 Compass Module            **
'**                                                       **
'**             Copyright 2002 - Devantech Ltd            **
'**     Commercial use of this software is prohibited     **
'**     Private and educational use only is permitted     **
'**                                                       **
'**        Written by Gerald Coe - January 2002           **
'**                                                       **
'**      This Code has been Tested on BS2 and BS2p        **
'**  It should work equally well on the BS2e and BS2sx    **
'**                                         **
'** E.T.I.S Neurocybernetic 10/2004                    **
'** Modified by N.Cuperlier for the Blue Robot           **
'**                                                       **
'***********************************************************


SDA        con    8            ' I2C data
SCL          con    9            ' I2C clock
SDAin        var    in8
SDAout    var    out8
SDAdir    var    dir8

loop        var    byte            ' just a looping counter
I2cBuf    var    byte            ' I2c read/write buffer
I2cAddr    var    byte            ' Address of I2C device
I2cReg    var    byte            ' Register number within I2C device
I2cData    var    word            ' Data to read/write
I2cAck    var    bit            ' Acknowledge bit

Main:
    '** wait for an serial input "J" to send back the value of the compass
     ' debug    1,0,0, "Entrez J pour lire la valeur de la boussole"
    serin 16,16468,[noparse][[/noparse]WAIT("j")] '
    I2cAddr = $c0            ' CMPS01 Compass module address
    I2cReg = 1                ' Bearing as 0-255 (BRAD)
    gosub    I2cByteRead
    '**debug    2,0,0, "Compass Bearing (0-255 BRAD)   ", dec3 I2cData
    I2cReg = 2                ' Bearing as 0-359.9 degrees
    gosub    I2cWordRead
    '**debug    2,0,1, "Compass Bearing (0-359 Degrees ", dec3 I2cData/10
      serout 16,16468,[noparse][[/noparse]DEC I2cData/10, CR]
    goto    Main

Baddata:
'debug    1,0,0, "wait:",CR
sleep 2
    goto Main

I2cByteWrite:                ' writes I2cData.lowbyte to I2cReg at I2cAddr
    gosub    I2cStart
    I2cBuf = I2cAddr    
    gosub    I2cOutByte            ' send device address
    I2cBuf = I2cReg    
    gosub    I2cOutByte            ' send register number
    I2cBuf = I2cData.lowbyte    
    gosub    I2cOutByte            ' send the data
    gosub    I2cStop
    return


I2cWordWrite:                ' writes I2cData to I2cReg at I2cAddr
    gosub    I2cStart
    I2cBuf = I2cAddr    
    gosub    I2cOutByte            ' send device address
    I2cBuf = I2cReg    
    gosub    I2cOutByte            ' send register number
    I2cBuf = I2cData.highbyte
    gosub    I2cOutByte            ' send the data - high byte
    I2cBuf = I2cData.lowbyte
    gosub    I2cOutByte            ' send the data - low byte
    gosub    I2cStop
    return
    

I2CByteRead:
    gosub    I2cStart
    I2cBuf = I2cAddr    
    gosub    I2cOutByte            ' send device address
    I2cBuf = I2cReg    
    gosub    I2cOutByte            ' send register number
    gosub    I2cStart            ' repeated start
    I2cBuf = I2cAddr | 1    
    gosub    I2cOutByte            ' send device address (with read set)
    I2cAck = 0                ' send Nak
    gosub    I2cInByte
    I2cData.lowbyte = I2cBuf    ' read the data
    I2cData.highbyte = 0
    gosub    I2cStop
    return


I2CWordRead:
    gosub    I2cStart
    I2cBuf = I2cAddr    
    gosub    I2cOutByte            ' send device address
    I2cBuf = I2cReg    
    gosub    I2cOutByte            ' send register number
    gosub    I2cStart            ' repeated start
    I2cBuf = I2cAddr | 1    
    I2cAck = 1                ' send Ack
    gosub    I2cOutByte            ' send device address (with read set)
    gosub    I2cInByte
    I2cData.highbyte = I2cBuf    ' read the data
    I2cAck = 0                ' send Nak
    gosub    I2cInByte
    I2cData.lowbyte = I2cBuf
    gosub    I2cStop
    return


I2cOutByte:
    shiftout SDA, SCL, MSBFIRST, [noparse][[/noparse]I2cBuf]
    input    SDA
    high    SCL                    ' clock in the ack' bit
    low    SCL
    return

 
I2cInByte:
    shiftin SDA, SCL, MSBPRE, [noparse][[/noparse]I2cBuf]
    SDAout = 0
    SDAdir = I2cAck
    high    SCL                    ' clock out the ack' bit
    low     SCL
    input    SDA
    return


I2cStart                        ' I2C start bit sequence
    high    SDA
    high    SCL
    low    SDA
    low    SCL
    return


I2cStop:                        ' I2C stop bit sequence
    low    SDA
    high    SCL
    high    SDA
    return




The basic stamp is plugged under /dev/ttyUSB0 (permissions are OK).
I have configured the tio to use baudrate 9600 and 8N1.

Writing 'j' on the port seems ok but I can't read data. My best trials returned 'j' (the very same things that I have input).

Questions:
1) Do I need to do disable/enable the DTR and RTS bits? Those seems to be disabled by Stamp Editor.
2) Can I use the canonical mode?
3) The documentation of SERIN and SEROUT talks about INVERTED polarity. What's this?

I must confess I'm a bit lost. Any help would be appreciated. Thanks in advance.
Mathieu

Comments

  • fromfrom Posts: 2
    edited 2009-06-18 16:18
    OK I have found some workarounds.

    First I have used C code to reset the basic stamp (thanks to open source) by playing with ioctl().

    Second I have slightly modified the code to insert a pause after the SEROUT command and an explicit message after initialization.

    All in all this seems to work. If somebody have a better way to do I'm still opened...

    Mathieu
Sign In or Register to comment.