Shop OBEX P1 Docs P2 Docs Learn Events
Is I2C & 2 wire communication for sensirion temperature/humidity sensor - Page 2 — Parallax Forums

Is I2C & 2 wire communication for sensirion temperature/humidity sensor

2

Comments

  • CreeCree Posts: 132
    edited 2013-06-13 12:23
    when I tried to apply the both to my program as a sub routine they would get stuck in their loops, can you suggest a way of to avoid this.
    gets stuck in the loop for this code:
    '
    sensor select
    sensor_select:
     ' starts at 0
     old = IN7  'pb
     DO
       DEBUG "loop test" ' gets stuck here****************************************************************************
    old = IN7
      new = IN7
      IF new ^ old & old THEN
        senscnt = senscnt + 1 // 6 ' will not go higher to the value after: (//)
    
      ENDIF
      old = new
      LOOP
    
    RETURN
    

    or it will only do once as in here when I changed it:
    ' sensor select
    sensor_select:
     ' starts at 0
     old = IN7  'pb
     DO
       DEBUG "loop test" 
    old = IN7
      new = IN7
      IF new ^ old & old THEN
        senscnt = senscnt + 1 // 6 ' will not go higher to the value after: (//)
    
    
      ENDIF
      old = new
    
    
      EXIT
       LOOP
    RETURN
    
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2013-06-13 12:48
    The key scan has to be part of the larger loop that includes the query of your sensors. You can write the key test as a subroutine if you want, but in that case the it won't have a loop in it.

    Also, you have an extra old=in7 that should not be there.
    [SIZE=1][FONT=courier new]sensor_select: 
      new = IN7   
      IF new ^ old & old THEN     senscnt = senscnt + 1 // 6 ' will not go higher to the value after: (//) 
     old = new
     RETURN[/FONT][/SIZE]
    

    This code should be part of a larger loop. The statement old=in7 is not inside the loop, nor is it in the sensor_select subroutine. It is only in the initialization. The subroutine has only the update, old = new.

    Also in the large main loop there should be a call to the sensor_select subroutine and calls to the subroutines that measure temperature and humidity and probably also calls that put the data on your LCD. You can make it so that it measures the temperature and humidity only once when the selection changes, or you can make it measure repeatedly so long as a selection applies. It is going around that big loop several times, indeed, many times each second and each time around it will test the button and also acquire sensor data and show the display in some order of your choosing.
  • CreeCree Posts: 132
    edited 2013-06-13 13:48
    thx got the counter work in my program.

    I'm going to going to go over the shiftin and shiftout stuff for the clock to switch sensors.
  • CreeCree Posts: 132
    edited 2013-06-14 08:35
    Sweet I got it working :P
  • CreeCree Posts: 132
    edited 2013-06-14 11:30
    Is it possible to send data to a parallel LCD through the pcf8574p ?
  • CreeCree Posts: 132
    edited 2013-06-14 12:08
    found some examples, but none of them are basic stamp. So at least I know its possible now.
  • CreeCree Posts: 132
    edited 2013-06-17 08:27
    I have been studying an example of the PCF8574P in order to create a program for an lcd, but I am not sure how to start changing the program in order to display messages. I have found examples of people using the PCF8574P with LCDs but they are not in basic stamp. I have gotten the LCD to work with another set up and I got the PCF8574P example to work. Can anyone give me a hin on where to begin. I am doing this in order to save space on my controller, so that I can add more other components for my project.

    Here are the 2 programs:


    PCF8574P:
    ' ==============================================================================' {$PBASIC 2.5}
    '
    ' Program Listing 85.1
    ' File...... PCF8574.BS2
    ' Purpose... PCF8574 control via I2C
    ' Author.... Jon Williams
    ' E-mail.... jonwms@aol.com
    ' Started... 20 MAR 2002
    ' Updated... 29 MAR 2002
    '
    ' {$STAMP BS2sx}
    '
    ' ==============================================================================
    ' ------------------------------------------------------------------------------
    ' Program Description
    ' ------------------------------------------------------------------------------
    '
    ' This program demonstrates essential I2C routines and communication with the
    ' Philips PCF8574 port expander. The expander is a quasi-bidirectional device;
    ' you can write to outputs or read from inputs no data direction register.
    '
    ' Inputs and outputs are active low. When writing to the device, a "1"
    ' should be written to any pin that is used an input.
    ' ------------------------------------------------------------------------------
    ' Revision History
    ' ------------------------------------------------------------------------------
    ' ------------------------------------------------------------------------------
    ' I/O Definitions
    ' ------------------------------------------------------------------------------
    '
    SDA CON 0 ' I2C serial data line
    SCL CON 1 ' I2C serial clock line
    ' ------------------------------------------------------------------------------
    ' Constants
    ' ------------------------------------------------------------------------------
    DevType CON %0100 << 4 ' device type
    DevAddr CON %000 << 1 ' address = %000 -> %111
    Wr8574 CON DevType | DevAddr | 0 ' write to PCF8574
    Rd8574 CON DevType | DevAddr | 1 ' read from PCF8574
    PCFACK CON 0 ' acknowledge bit
    NAK CON 1 ' no ack bit
    MixDDR CON %11110000 ' 1 = input for mixed I/O
    YesPCF CON 0
    NoPCF CON 1
    
    
    'CRSRXY CON 2 ' DEBUG Position Control
    ' ------------------------------------------------------------------------------
    ' Variables
    ' ------------------------------------------------------------------------------
    i2cSDA VAR Nib ' I2C serial data pin
    i2cData VAR Byte ' data to/from I2C device
    i2cWork VAR Byte ' work byte for I2C TX code
    i2cAck VAR Bit ' ACK bit from device
    counter VAR Nib
    switches VAR i2cData.HIGHNIB ' from PCF8574
    ' ------------------------------------------------------------------------------
    ' EEPROM Data
    ' ------------------------------------------------------------------------------
    ' ------------------------------------------------------------------------------
    ' Initialization
    ' ------------------------------------------------------------------------------
    Initialize:
     PAUSE 250 ' let DEBUG open
     DEBUG CLS, "LCD PCF8574 Demo"
     DEBUG CRSRXY, 0, 2, "Counter: ", BIN4 counter
     DEBUG CRSRXY, 0, 3, "Switches: ", BIN4 switches
     i2cSDA = SDA ' define SDA pin
     i2cData = %11111111 ' clear outputs
     GOSUB Write_PCF8574
     IF (i2cAck = PCFACK) THEN Main ' device is present
     DEBUG CLS, "Error: No ACK from PCF8574"
     END
    ' ------------------------------------------------------------------------------
    ' Program Code
    ' ------------------------------------------------------------------------------
    Main:
     FOR counter = 0 TO 15     ' counter thats what it ouputs 0 to 15 different ouput for LEDs
     DEBUG CRSRXY, 10, 2, BIN4 counter ' display counter on screen
     i2cData = MixDDR | ~counter ' mask inputs
     GOSUB Write_PCF8574 ' display counter on LEDs  (check subroutine to understand output)
     GOSUB Read_PCF8574 ' get data from PCF8574
     DEBUG CRSRXY, 10, 3, BIN4 switches ' display switch inputs
     PAUSE 100
     NEXT
     GOTO Main
     END
     ' ------------------------------------------------------------------------------
    ' Subroutines
    ' ------------------------------------------------------------------------------
    ' Data to be sent is passed in i2cData
    Write_PCF8574:
     GOSUB I2C_Start ' send Start
     i2cWork = Wr8574 ' send address
     GOSUB I2C_TX_Byte
     i2cWork = i2cData
     GOSUB I2C_TX_Byte ' send i2cData to device ***********************************data
     GOSUB I2C_TX_Byte ' force to pins
     GOSUB I2C_Stop ' send Stop
     RETURN
    ' Data received is returned in i2cData
    Read_PCF8574:
     GOSUB I2C_Start ' send Start
     i2cWork = Rd8574 ' send address
     GOSUB I2C_TX_Byte
     GOSUB I2C_RX_Byte_Nak ' get byte from device
     i2cData = i2cWork
     GOSUB I2C_Stop ' send Stop
     RETURN
    ' ------------------------------------------------------------------------------
    ' Low Level I2C Subroutines
    ' ------------------------------------------------------------------------------
    ' --- Start ---
    I2C_Start: ' I2C start bit sequence
     INPUT i2cSDA
     INPUT SCL
     LOW i2cSDA ' SDA -> low while SCL high
    Clock_Hold:
     IF (INS.LOWBIT(SCL) = 0) THEN Clock_Hold ' device ready?
     RETURN
    ' --- Transmit ---
    I2C_TX_Byte:
     SHIFTOUT i2cSDA,SCL,MSBFIRST,[i2cWork\8] ' send byte to device
     SHIFTIN i2cSDA,SCL,MSBPRE,[i2cAck\1] ' get acknowledge bit
     RETURN
    ' --- Receive ---
    I2C_RX_Byte_Nak:
     i2cAck = NAK ' no ACK = high
     GOTO I2C_RX
    I2C_RX_Byte:
     i2cAck = PCFACK ' ACK = low
    I2C_RX:
     SHIFTIN i2cSDA,SCL,MSBPRE,[i2cWork\8] ' get byte from device
     SHIFTOUT i2cSDA,SCL,LSBFIRST,[i2cAck\1] ' send ack or nak
     RETURN
    ' --- Stop ---
    I2C_Stop: ' I2C stop bit sequence
     LOW i2cSDA
     INPUT SCL
     INPUT i2cSDA ' SDA --> high while SCL high
     RETURN
    

    LCD, it has code for the SHT11 also:
    ' {$STAMP BS2sx}' {$PBASIC 2.5}
    ' -----[ Program Description ]---------------------------------------------
    '
    ' This program demonstrates how to read data from the LCD's display RAM
    ' (DDRAM) or character RAM (CGRAM).
    '
    ' The connections for this program conform to the BS2p-family LCDCMD,
    ' LCDIN, and LCDOUT instructions. Use this program for the BS2, BS2e,
    ' or BS2sx. There is a separate program for the BS2p, BS2pe, and BS2px.
    ' -----[ I/O Definitions ]-------------------------------------------------
    'LCD
    E PIN 0 ' Enable pin
    RW PIN 2 ' Read/Write
    RS CON 3 ' Register Select
    LcdDirs VAR DIRB ' bus DDR
    LcdBusOut VAR OUTB ' 4-bit LCD data bus
    LcdBusIn VAR INB
    'sensor
    ShtData PIN 8 ' bi-directional data
    Clock PIN 9
    
    
    ' -----[ Constants ]-------------------------------------------------------
    'LCD
    LcdCls CON $01 ' clear the LCD
    LcdHome CON $02 ' move cursor home
    LcdCrsrL CON $10 ' move cursor left
    LcdCrsrR CON $14 ' move cursor right
    LcdDispL CON $18 ' shift chars left
    LcdDispR CON $1C ' shift chars right
    LcdDDRam CON $80 ' Display Data RAM control
    LcdCGRam CON $40 ' Character Generator RAM
    LcdLine1 CON $80 ' DDRAM address of line 1
    LcdLine2 CON $C0 ' DDRAM address of line 2
    #DEFINE _LcdReady = ($STAMP >= BS2P)
    'Sensor
     ShtTemp CON %00011 ' read temperature
    ShtHumi CON %00101 ' read humidity
    ShtStatW CON %00110 ' status register write
    ShtStatR CON %00111 ' status register read
    ShtReset CON %11110 ' soft reset
    Ack CON 0
    NoAck CON 1
    No CON 0
    Yes CON 1
    DegSym CON 186 ' degrees symbol for DEBUG
    ' -----[ Variables ]-------------------------------------------------------
    'LCD
    char VAR Byte ' character sent to LCD
    idx VAR Byte ' loop counter
    rndVal VAR Word ' random value
    addr VAR Byte ' address to write/read
    tOut VAR Byte ' test value - out to LCD
    tIn VAR Byte ' test value - in from LCD
    temp VAR Word ' use for formatting
    width VAR Nib ' width of value to display
    'Sensor
    senscnt VAR Nib    ' counts button presses
     ioByte VAR Byte ' data from/to SHT11
    ackBit VAR Bit ' ack/nak from/to SHT11
    toDelay VAR Byte ' timeout delay timer
    timeOut VAR Bit ' timeout status
    soT VAR Word ' temp counts from SHT11
    tC VAR Word ' temp - Celcius
    tF VAR Word ' temp - Fahrenheit
    soRH VAR Word ' humidity counts
    rhLin VAR Word ' humidity; linearized
    rhTrue VAR Word ' humidity; compensated
    status VAR Byte ' status byte
    ' -----[ Initialization ]--------------------------------------------------
    'Sensor
    GOSUB SHT_Connection_Reset ' reset device connection
    PAUSE 250 ' let DEBUG window open
    DEBUG CLS,
    "SHT11 Sensor Demo", CR,
    "-----------------", CR
    'LCD
    Reset:
     #IF _LcdReady #THEN
     #ERROR "Please use BS2p version: SW21-EX13-LCD_Read.BSP"
     #ENDIF
     DIRL = %11111110 ' setup pins for LCD
     PAUSE 100 ' let the LCD settle
    Lcd_Setup:
     LcdBusOut = %0011 ' 8-bit mode
     PULSOUT E, 3
     PAUSE 5
     PULSOUT E, 3
     PULSOUT E, 3
     LcdBusOut = %0010 ' 4-bit mode
     PULSOUT E, 1
     char = %00101000 ' multi-line mode
     GOSUB LCD_Cmd
     char = %00001100 ' disp on, no crsr or blink
     GOSUB LCD_Cmd
     char = %00000110 ' inc crsr, no disp shift
     GOSUB LCD_Cmd
    Display:
     char = LcdHome
     GOSUB LCD_Cmd
     PAUSE 2
     FOR idx = 0 TO 15
     LOOKUP idx, ["#:      T:     C "], char
     GOSUB LCD_Out
     NEXT
     char = LcdLine2
     GOSUB LCD_Cmd
     PAUSE 2
     FOR idx = 0 TO 15
     LOOKUP idx, ["Humidity:     % "], char
     GOSUB LCD_Out
     NEXT
    ' -----[ Program Code ]----------------------------------------------------
    Main:
    
    
    GOSUB SHT_Measure_Temp
    DEBUG CRSRXY, 0, 3,
    "soT...... ", DEC soT, CR,
    "tC....... ", DEC (tC / 10), ".", DEC1 tC, DegSym, " ", CR,
    "tF....... ", DEC (tF / 10), ".", DEC1 tF, DegSym, " "
    GOSUB SHT_Measure_Humidity
    DEBUG CRSRXY, 0, 7,
    "soRH..... ", DEC soRH, CR,
     "rhLin.... ", DEC (rhLin / 10), ".", DEC1 rhLin, "% ", CR,
    "rhTrue... ", DEC (rhTrue / 10), ".", DEC1 rhTrue, "% "
     'Sensor
    GOSUB sensor_select
    DEBUG CRSRXY, CR, "Sensor # ",senscnt
    
    
    'LCd
     'RANDOM rndVal ' generate random number      \\ not using random generator
     addr = 1 ' adress
    ' tOut = tC ' create test temp value
     char = LcdCGRam  ' set CGRAM pointer
     GOSUB LCD_Cmd
     char = tOut
     GOSUB LCD_Out ' move the value to CGRAM
     PAUSE 100
     char = LcdCGRam + addr ' reset CGRAM pointer
     GOSUB LCD_Cmd
     GOSUB LCD_In ' read value from LCD
     tIn = char
     ' display results
     char = LcdLine1 + 2 ' show address @ L1/C5
     GOSUB LCD_Cmd
     temp = addr   'adress to LCD     **********
     width = 2
     GOSUB Put_Val
     char = LcdLine1 + 10 ' show output @ L1/C13
     GOSUB LCD_cmd
     temp = tC     'temperature to LCD *********
     width = 3
     GOSUB Put_Val
     char = LcdLine2 + 9 ' show output @ L2/C13
     GOSUB LCD_Cmd
     temp = rhTrue 'humidity to LCD  ***********
     width = 3
     GOSUB Put_Val
     PAUSE 1000
     GOTO Main ' do it again
    ' -----[ Subroutines ]-----------------------------------------------------
    'sensor
     ' connection reset: 9 clock cyles with ShtData high, then start sequence
    
    
    SHT_Connection_Reset:
    SHIFTOUT ShtData, Clock, LSBFIRST, [$FFF\9]
    ' generates SHT11 "start" sequence
    ' _____ _____
    ' ShtData |_______|
    ' ___ ___
    ' Clock ___| |___| |___
    '
    SHT_Start:
    INPUT ShtData ' let pull-up take high
    LOW Clock
    HIGH Clock
    LOW ShtData
    LOW Clock
    HIGH Clock
    INPUT ShtData
    LOW Clock
    RETURN
    ' measure temperature
    ' -- celcius = raw * 0.01 - 40
    ' -- fahrenheit = raw * 0.018 - 40
    '
    SHT_Measure_Temp:
    GOSUB SHT_Start ' alert device
    ioByte = ShtTemp ' temperature command
    GOSUB SHT_Write_Byte ' send command
    GOSUB SHT_Wait ' wait for measurement
    ackBit = Ack ' another read follows
    GOSUB SHT_Read_Byte ' get MSB
    soT.HIGHBYTE = ioByte
    ackBit = NoAck ' last read
    GOSUB SHT_Read_Byte ' get LSB
     soT.LOWBYTE = ioByte
    ' Note: Conversion factors are multiplied by 10 to return the
    ' temperature values in tenths of degrees
    tC = soT ** $1999 - 400 ' convert to tenths C
    tF = soT ** $2E14 - 400 ' convert to tenths F
    RETURN
    ' measure humidity
    '
    SHT_Measure_Humidity:
    GOSUB SHT_Start ' alert device
    ioByte = ShtHumi ' humidity command
    GOSUB SHT_Write_Byte ' send command
    GOSUB SHT_Wait ' wait for measurement
    ackBit = Ack ' another read follows
    GOSUB SHT_Read_Byte ' get MSB
    soRH.HIGHBYTE = ioByte
    ackBit = NoAck ' last read
    GOSUB SHT_Read_Byte ' get LSB
    soRH.LOWBYTE = ioByte
    ' linearize humidity
    ' rhLin = (soRH * 0.0405) - (soRH^2 * 0.0000028) - 4
    '
    ' for the BASIC Stamp:
    ' rhLin = (soRH * 0.0405) - (soRH * 0.002 * soRH * 0.0014) - 4
    '
    ' Conversion factors are multiplied by 10 to return tenths
    '
    rhLin = (soRH ** $67AE) - (soRH ** $83 * soRH ** $5B) - 40
    ' temperature compensated humidity
    ' rhTrue = (tc - 25) * (soRH * 0.00008 + 0.01) + rhLin
    '
    ' Conversion factors are multiplied by 10 to return tenths
    ' -- simplified
    '
    rhTrue = (tC - 250) * (soRH ** $34) + rhLin
    RETURN
    ' sends "status"
    '
    SHT_Write_Status:
    GOSUB SHT_Start ' alert device
    ioByte = ShtStatW ' write to status reg cmd
      GOSUB SHT_Write_Byte ' send command
    ioByte = status
    GOSUB SHT_Write_Byte
    RETURN
    ' returns "status"
    '
    SHT_Read_Status:
    GOSUB SHT_Start ' alert device
    ioByte = ShtStatW ' write to status reg cmd
    GOSUB SHT_Read_Byte ' send command
    ackBit = NoAck ' only one byte to read
    GOSUB SHT_Read_Byte
    RETURN
    ' sends "ioByte"
    ' returns "ackBit"
    '
    SHT_Write_Byte:
    SHIFTOUT ShtData, Clock, MSBFIRST, [ioByte] ' send byte
    SHIFTIN ShtData, Clock, LSBPRE, [ackBit\1] ' get ack bit
    RETURN
    ' returns "ioByte"
    ' sends "ackBit"
    '
    SHT_Read_Byte:
    SHIFTIN ShtData, Clock, MSBPRE, [ioByte] ' get byte
    SHIFTOUT ShtData, Clock, LSBFIRST, [ackBit\1] ' send ack bit
    INPUT ShtData ' release data line
    RETURN
    ' wait for device to finish measurement (pulls data line low)
    ' -- timeout after ~1/4 second
    '
    SHT_Wait:
    INPUT ShtData ' data line is input
    timeOut = No ' assume no timeout
    FOR toDelay = 1 TO 250 ' wait ~1/4 second
    IF (ShtData = 0) THEN EXIT
    PAUSE 1
    NEXT
    IF (toDelay = 250) THEN timeOut = Yes ' loop completed = timeout
    RETURN
    ' reset SHT11/15 with soft reset
    '
    SHT_Soft_Reset:
    GOSUB SHT_Connection_Reset ' reset the connection
    ioByte = ShtReset ' reset command
    ackBit = NoAck ' only one byte to send
    GOSUB SHT_Write_Byte ' send it
    PAUSE 11 ' wait at least 11 ms
    RETURN
    
    
     ' sensor select
    sensor_select:
     DO
      DO : LOOP WHILE IN7   ' stay here while pin is high
        senscnt = senscnt + 1  // 6  ' pin has gone low, count
    
    
      DO : LOOP UNTIL IN7   ' stay here until pin returns high
       'make sure 0 is the last sensor
    LOOP
    RETURN
    
    
    'LCD
    LCD_Cmd:
     LOW RS ' enter command mode
    LCD_Out:
     LcdBusOut = char.HIGHNIB ' output high nibble
     PULSOUT E, 3 ' strobe the Enable line
     LcdBusOut = char.LOWNIB ' output low nibble
     PULSOUT E, 3
     HIGH RS ' return to character mode
     RETURN
    LCD_In:
     HIGH RS ' data command
     HIGH RW ' read
     LcdDirs = %0000 ' make data lines inputs
     HIGH E
     char.HIGHNIB = LcdBusIn ' get high nibble
     LOW E
     HIGH E
     char.LOWNIB = LcdBusIn ' get low nibble
     LOW E
     LcdDirs = %1111 ' make buss lines outputs
     LOW RW ' return to write mode
     RETURN
    Put_Val:
     IF temp = addr THEN
          FOR idx = (width - 1)TO 0  ' display digits l-to-r
          char = (temp DIG idx) + "0" ' convert digit to ASCII
         GOSUB LCD_Out ' write to LCD
          NEXT
          RETURN
         ENDIF
     FOR idx = 3 TO 0 STEP 1
       IF idx = 0 THEN   ' Display a decimal point before the tenth's digit
          Char = "."
          GOSUB LCD_OUT
       ENDIF
       Char = (temp DIG idx) + "0"
       GOSUB LCD_OUT
    NEXT
    RETURN
    
    
    '         FOR idx = (width - 1)TO 0  ' display digits l-to-r
     'char = (temp DIG idx) + "0" ' convert digit to ASCII
    ' GOSUB LCD_Out ' write to LCD
    ' NEXT
    ' RETURN
    
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2013-06-17 08:51
    I'm not sure what you are expecting the PCA8574A to do. It is a port expander that allows two pins on your Stamp to control 8 i/os, and those extra i/os could be bit banged to write data to the 4-bit + controls data bus of the LCD. Is that what you want to do? It looks like the program you just posted already has the LCD working directly with the Stamp.

    Doing it with the PCA8574 will be much slower, especially since the BS2sx does not have the built-in i2c commands that came along with the BS2p series.

    By the way, it seems to me your call to Sensor_Select should be placed right after main:, before reading the temperature and humidity values. Otherwise the values displayed come from the previous selection.
  • Mike GreenMike Green Posts: 23,101
    edited 2013-06-17 08:57
    As you have noticed, the BS2 doesn't support either parallel LCDs or I2C devices very well. There are subroutines available for both, but they take up a bit of room in the limited program memory. The BS2p/pe/px Stamps have built-in statements for both parallel LCDs and I2C devices that would save you a lot of code. Note that you can also get the BS2p with another bank of I/O pins (BS2p40) that can save you from having to use an external I/O expander like the PCF8574. If you have to continue with the BS2, I'd recommend substituting a serial LCD for the parallel LCD you're using. A serial LCD would use fewer I/O pins and it's driven directly using the SEROUT statement. If you still want an I/O expander, consider using a 74HC595 for outputs and a 74HC165 for inputs. They're much simpler to use with the BS2 than the PCF8574 since they use the SHIFTIN and SHIFTOUT statements rather than the large hunk of subroutines needed for I2C.
  • CreeCree Posts: 132
    edited 2013-06-17 12:22
    Mike Green wrote: »
    As you have noticed, the BS2 doesn't support either parallel LCDs or I2C devices very well. There are subroutines available for both, but they take up a bit of room in the limited program memory. The BS2p/pe/px Stamps have built-in statements for both parallel LCDs and I2C devices that would save you a lot of code. Note that you can also get the BS2p with another bank of I/O pins (BS2p40) that can save you from having to use an external I/O expander like the PCF8574. If you have to continue with the BS2, I'd recommend substituting a serial LCD for the parallel LCD you're using. A serial LCD would use fewer I/O pins and it's driven directly using the SEROUT statement. If you still want an I/O expander, consider using a 74HC595 for outputs and a 74HC165 for inputs. They're much simpler to use with the BS2 than the PCF8574 since they use the SHIFTIN and SHIFTOUT statements rather than the large hunk of subroutines needed for I2C.

    I am using the BS2 sx
  • Mike GreenMike Green Posts: 23,101
    edited 2013-06-17 12:33
    The BS2sx doesn't support the built-in parallel LCD or built-in I2C statements. Compared to the BS2, the BS2sx is faster and has more memory available, but these other built-in statements are only in the BS2p/pe/px models.
  • CreeCree Posts: 132
    edited 2013-06-21 06:42
    I was wondering is there any way of writing more efficient code to save on Ram has 32 bytes.


    I saw there was a javiline stamp module that has 32 kb of ram, but was discontinued :blank:.

    I also saw the BS2p series has 6 more bytes, but I don't know if that would be enough for what I need to do.

    What should I do if need more ram for variables?
  • CreeCree Posts: 132
    edited 2013-06-21 07:27
    For example right now I am trying to save data that I am getting from my sensors so that the data can update automatically instead of what I have currently which I am using a push button to switch sensors, it only displays and refreshes one sensor at a time which is not convenient for monitoring temperature from a distance.

    Can I use scratchpad ram to save on space because I need to save 6 words, 1 for each sensor. If I can do this, I will be able to cycle through the data without interrupting the sensor data being refreshed. That is what I am working towards. (I am not currently using an LCD right now, but I'm going to get a serial lcd eventually).

    But even if I can save in scratchpad, I would still need 6 individual word variables for the sensors?
  • Mike GreenMike Green Posts: 23,101
    edited 2013-06-21 07:50
    You can use scratchpad RAM to hold information that you might not need for a short time. The variable space on the Stamps is very limited and you often have to re-think how you're doing your program so data can be moved out to the scratchpad RAM or sometimes stored in EEPROM (keeping in mind the limits on rewriting EEPROM). You make use of alias declarations (see the Manual) to use the same variable space for several different variables when that makes sense for your program logic. Sometimes it's easier to just switch to a different microcontroller with more memory available. With careful attention to variable use, you'd be surprised what can be done with a Stamp though.
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2013-06-21 08:10
    Your BS2sx has 64 bytes of scratchpad ram, and you should certainly take advantage of it.
    ' store in scratchpad
    FOR sensorNumber=0 TO 5
      GOSUB readSensor  ' returns value from sensor
      PUT sensorNumber*2, WORD value
    NEXT
    
    ' retrieve...
    FOR sensorNumber=0 TO 5
      GET sensorNumber*2, WORD value  ' from scratchpad
      DEBUG SDEC value, CR
    NEXT
    

    Note the times 2 is necessary to step two bytes for each word value.

    The BS2p series has 128 bytes of scratchpad. The ram both regular and scratchpad is shared across all of the program slots.
  • CreeCree Posts: 132
    edited 2013-06-21 08:35
    Your BS2sx has 64 bytes of scratchpad ram, and you should certainly take advantage of it.
    ' store in scratchpad
    FOR sensorNumber=0 TO 5
      GOSUB readSensor  ' returns value from sensor
      PUT sensorNumber*2, WORD value
    NEXT
    
    ' retrieve...
    FOR sensorNumber=0 TO 5
      GET sensorNumber*2, WORD value  ' from scratchpad
      DEBUG SDEC value, CR
    NEXT
    

    Note the times 2 is necessary to step two bytes for each word value.

    The BS2p series has 128 bytes of scratchpad. The ram both regular and scratchpad is shared across all of the program slots.


    So this way I can save the data in the ScratchPad ram without creating variables that will take up space in ram?
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2013-06-21 10:05
    yes! You need ram variables, but once the value is stored in scratchpad, you use the same regular ram variable for the next sensor or any other purpose.
  • CreeCree Posts: 132
    edited 2013-06-21 10:53
    yes! You need ram variables, but once the value is stored in scratchpad, you use the same regular ram variable for the next sensor or any other purpose.

    good, that help solve part of my automatic data collector part of my program, I just need to figure out how to implement it with the sht11 code.
    I'm going to give it a try and see what I get.

    thx
  • CreeCree Posts: 132
    edited 2013-06-21 12:03
    ' store in scratchpad
    FOR sensorNumber=0 TO 5
      GOSUB readSensor  ' returns value from sensor
      PUT sensorNumber*2, WORD value
    NEXT
    
    ' retrieve...
    FOR sensorNumber=0 TO 5
      GET sensorNumber*2, WORD value  ' from scratchpad
      DEBUG SDEC value, CR
    NEXT
    

    The thing is that I have my counter currently set up like this:
    sensor_number:IF senscnt = 0 THEN    'sensor 1
      Clock = 2
      ENDIF
      IF senscnt =1 THEN
      Clock = 3
      ENDIF
       IF senscnt =2 THEN
      Clock = 4
      ENDIF
       IF senscnt =3 THEN
      Clock = 5
      ENDIF
      IF senscnt =4 THEN
      Clock = 6
      ENDIF
       IF senscnt =5 THEN
      Clock = 7
      ENDIF
      RETURN
    

    it would seem that I need to us my clk for the for loop like this because I used my clock to switch between sensors and i want to make it automatic update of data. then when i want to display on a screen i can use the button to select the data that i want:
    I would need to do something of the sort,
    [COLOR=#3E3E3E][FONT=Parallax][I]'save data
    FOR clock=2 TO 7
    [/I][/FONT][/COLOR][COLOR=#3E3E3E][FONT=Parallax][I]GOSUB sht_connection_reset  ' returns value from sensor                                                               [/I][/FONT][/COLOR][COLOR=#3E3E3E][FONT=Parallax][I] 
    PUT shtdata*2, WORD value
    [/I][/FONT][/COLOR][COLOR=#3E3E3E][FONT=Parallax][I]NEXT[/I][/FONT][/COLOR]
    
    

    Is it still possible to get the javilin stamp somewhere despite it being discontinued?
  • CreeCree Posts: 132
    edited 2013-06-25 08:36
    Just an update, I'm figuring out the scratchpad code slowly slowly, but its coming along. I think I figured it out now, so I am writing the code for my program and going to test it when its done.
  • CreeCree Posts: 132
    edited 2013-06-26 10:26
    I got it working, but now the push button to switch data is not responsive, but ill find something.

    Thx for all the help you guys gave me. It wasn't too hard to learn how to use the basic stamp in a few weeks.
  • PublisonPublison Posts: 12,366
    edited 2013-06-26 10:57
    Cree wrote: »

    Is it still possible to get the javilin stamp somewhere despite it being discontinued?

    Mouser still have 18 in stock, at the full retail price though. Wish I had bought them from Parallax at $19.99. :(

    http://www.mouser.com/ProductDetail/Parallax/JS1-IC/?qs=Re%2bcz0%2FMYCL%2Ff40NXbtrcA%3D%3D&gclid=CJOS5J2lgrgCFcqe4AodeVwAtg


  • CreeCree Posts: 132
    edited 2013-06-26 13:24
    Publison wrote: »
    Mouser still have 18 in stock, at the full retail price though. Wish I had bought them from Parallax at $19.99. :(

    http://www.mouser.com/ProductDetail/Parallax/JS1-IC/?qs=Re%2bcz0%2FMYCL%2Ff40NXbtrcA%3D%3D&gclid=CJOS5J2lgrgCFcqe4AodeVwAtg



    Cool thanks,

    I might be able to buy it here in montreal at abra electronics, but I'd have to check.

    and plus I kind of solved my RAM issue for now by using the scratchpad ram and also separate tasks between 2 BS2sx controllers (the 2 would be far apart using Radio frequency to transmit the data from one end and then displaying it on the other end)
  • CreeCree Posts: 132
    edited 2013-06-27 10:11
    I am trying to use the serial LCD (27977) now and I have a small issue. I have been trying to get the degree symbol to display on my LCD. I have tried different examples that I have found on the parallax website and I have gotten different results from nothing showing to the piezo speaker beeping. I have been able to display data and word on it, so its just the symbol that is an issue.

    what is the code that I require to display it?
  • SapphireSapphire Posts: 496
    edited 2013-06-27 14:23
    Have you tried this?
    SEROUT LCD_PIN,LCD_BAUD,["45",223,"F"]
    

    The 223 above is the character code for a symbol that looks like a degree. So you should see 45° F on your display. But some serial LCDs don't recognize characters above 127, so you might have to compose your own symbol and use that instead.
  • CreeCree Posts: 132
    edited 2013-07-02 06:34
    Sapphire wrote: »
    Have you tried this?
    SEROUT LCD_PIN,LCD_BAUD,["45",223,"F"]
    

    The 223 above is the character code for a symbol that looks like a degree. So you should see 45° F on your display. But some serial LCDs don't recognize characters above 127, so you might have to compose your own symbol and use that instead.


    Ya, the serial lcd has a piezo speaker on it, so it doesn't recognize it. It just beeps instead. I'll have to make a custom symbol.
  • CreeCree Posts: 132
    edited 2013-07-02 07:33
    Its weird I tried the examples for the parallax serial LCD (27977). The example is supposed to be a diamond, but I get: ">/9" with this code

    I have the baud rate at 19200
    power and ground is good, pin 0 is good. And I have used it to display regular text easily.
    I am having trouble with custom character

    ' {$STAMP BS2sx}' {$PBASIC 2.5}
    TxPin CON 0
    Baud19200 CON 32
     HIGH TxPin ' Set pin high to be a serial port
     PAUSE 100 ' Pause for Serial LCD to initialize
     SEROUT TxPin, Baud19200, [250] ' Define custom character 2
     ' Now send the eight data bytes
     SEROUT TxPin, Baud19200, [000] ' 000 =
     SEROUT TxPin, Baud19200, [100] ' 100 = *
     SEROUT TxPin, Baud19200, [110] ' 110 = * * *
     SEROUT TxPin, Baud19200, [111] ' 111 = * * * * *
     SEROUT TxPin, Baud19200, [110] ' 110 = * * *
     SEROUT TxPin, Baud19200, [100] ' 100 = *
     SEROUT TxPin, Baud19200, [000] ' 000 =
     SEROUT TxPin, Baud19200, [000] ' 000 =
     SEROUT TxPin, Baud19200, [2] ' Display the new custom character 2
    
  • PublisonPublison Posts: 12,366
    edited 2013-07-02 08:44
    Cree wrote: »
    Its weird I tried the examples for the parallax serial LCD (27977). The example is supposed to be a diamond, but I get: ">/9" with this code

    I have the baud rate at 19200
    power and ground is good, pin 0 is good. And I have used it to display regular text easily.
    I am having trouble with custom character

    ' {$STAMP BS2sx}' {$PBASIC 2.5}
    TxPin CON 0
    Baud19200 CON 32
     HIGH TxPin ' Set pin high to be a serial port
     PAUSE 100 ' Pause for Serial LCD to initialize
     SEROUT TxPin, Baud19200, [250] ' Define custom character 2
     ' Now send the eight data bytes
     SEROUT TxPin, Baud19200, [000] ' 000 =
     SEROUT TxPin, Baud19200, [100] ' 100 = *
     SEROUT TxPin, Baud19200, [110] ' 110 = * * *
     SEROUT TxPin, Baud19200, [111] ' 111 = * * * * *
     SEROUT TxPin, Baud19200, [110] ' 110 = * * *
     SEROUT TxPin, Baud19200, [100] ' 100 = *
     SEROUT TxPin, Baud19200, [000] ' 000 =
     SEROUT TxPin, Baud19200, [000] ' 000 =
     SEROUT TxPin, Baud19200, [2] ' Display the new custom character 2
    

    Have you tried this at 9600 Baud? To use 19.2K I believe you have to use Flow Control.

    Scratch that....see next post.
  • PublisonPublison Posts: 12,366
    edited 2013-07-02 09:44
    You are using the buadrate for the BS2 (CON 32). For the BS2SX you need to use Baud19200 CON 110 for 19.2Kbaud.

    I use this template for BS2 programing. Helps when you are dealing with serial communications.

    ' {$STAMP BS2}' {$PBASIC 2.5}
    
    
    
    
    #SELECT $STAMP
      #CASE BS2, BS2E, BS2PE
        T1200       CON     813
        T2400       CON     396
        T9600       CON     84
        T19K2       CON     32
        T38K4       CON     6
      #CASE BS2SX, BS2P
        T1200       CON     2063
        T2400       CON     1021
        T9600       CON     240
        T19K2       CON     110
        T38K4       CON     45
      #CASE BS2PX
        T1200       CON     3313
        T2400       CON     1646
        T9600       CON     396
        T19K2       CON     188
        T38K4       CON     84
    #ENDSELECT
    
    
    Inverted        CON     $4000
    Open            CON     $8000
    Baud            CON     T38K4 + Inverted
    
    
    
  • CreeCree Posts: 132
    edited 2013-07-02 10:16
    I went back to the original example programming for serial lcd program that I had modified for my program, and I am going to play around with it since it is the only program that has worked for my LCD.

    Ill let you know how it turns out.

    here is the program if u want to look at it.
    ' ========================================================================='
    '   File...... Serial_LCD_Demo.BS2
    '   Purpose... Basic Serial LCD use, including customer characters
    '   Author.... (c) Parallax, Inc. -- All Rights Reserved
    '   E-mail.... support@parallax.com
    '   Started...
    '   Updated... 11 FEB 2005
    '
    '   {$STAMP BS2sx}
    '   {$PBASIC 2.5}
    '
    ' =========================================================================
    
    
    
    
    ' -----[ Program Description ]---------------------------------------------
    
    
    
    
    ' -----[ Revision History ]------------------------------------------------
    
    
    
    
    ' -----[ I/O Definitions ]-------------------------------------------------
    
    
    TX              PIN     0               ' serial output to LCD
    
    
    
    
    ' -----[ Constants ]-------------------------------------------------------
    
    
    #SELECT $STAMP
      #CASE BS2, BS2E, BS2PE
        T2400       CON     396
        T9600       CON     84
        T19K2       CON     32
      #CASE BS2SX, BS2P
        T2400       CON     1021
        T9600       CON     240
        T19K2       CON     110
    #ENDSELECT
      ' Commands/constants
    LcdBaud         CON     T9600
    
    
    LcdBkSpc        CON     $08             ' move cursor left
    LcdRt           CON     $09             ' move cursor right
    LcdLF           CON     $0A             ' move cursor down 1 line
    LcdCls          CON     $0C             ' clear LCD (use PAUSE 5 after)
    LcdCR           CON     $0D             ' move pos 0 of next line
    LcdBLon         CON     $11             ' backlight on
    LcdBLoff        CON     $12             ' backlight off
    LcdOff          CON     $15             ' LCD off
    LcdOn1          CON     $16             ' LCD on; cursor off, blink off
    LcdOn2          CON     $17             ' LCD on; cursor off, blink on
    LcdOn3          CON     $18             ' LCD on; cursor on, blink off
    LcdOn4          CON     $19             ' LCD on; cursor on, blink on
    LcdLine1        CON     $80             ' move to line 1, column 0
    LcdLine2        CON     $94             ' move to line 2, column 0
     'Do not need custom character, only degree celcius and %
    LcdCC0          CON     $F8             ' define custom char 0
    LcdCC1          CON     $F9             ' define custom char 1
    LcdCC2          CON     $FA             ' define custom char 2
    LcdCC3          CON     $FB             ' define custom char 3
    LcdCC4          CON     $FC             ' define custom char 4
    LcdCC5          CON     $FD             ' define custom char 5
    LcdCC6          CON     $FE             ' define custom char 6
    LcdCC7          CON     $FF             ' define custom char 7
    
    
    
    
    ' -----[ Variables ]-------------------------------------------------------
    
    
    idx1            VAR     Byte
    idx2            VAR     Byte
    char            VAR     Byte
    newChar         VAR     Byte
    
    
    
    
    ' -----[ EEPROM Data ]-----------------------------------------------------
    
    
    '                       C#----  Data----------------------------------
    CC0             DATA    LcdCC0, $0E, $1F, $1C, $18, $1C, $1F, $0E, $00
    CC1             DATA    LcdCC1, $0E, $1F, $1F, $18, $1F, $1F, $0E, $00
    CC2             DATA    LcdCC2, $0E, $1F, $1F, $1F, $1F, $1F, $0E, $00
    Smiley          DATA    LcdCC3, $00, $0A, $0A, $00, $11, $0E, $06, $00
    
    
    'Msg2            DATA    "IS VERY COOL!  ", 3
    
    
    
    
    ' -----[ Initialization ]--------------------------------------------------
     DEBUG "LCD custom character test"
    Reset:
      HIGH TX                               ' setup serial output pin
      PAUSE 100                             ' allow LCD to initialize
    
    
    DnLoad_Custom_Chars:
      FOR idx1 = 0 TO 35                    ' download 4 characters
        READ CC0 + idx1, char               ' get data from table
        SEROUT TX, LcdBaud, [char]          ' send to LCD
      NEXT
    
    
    
    
    ' -----[ Program Code ]----------------------------------------------------
    
    
    ' Clear the display and remove cursor and blinking attributes.
    
    
    Main:
      SEROUT TX, LcdBaud, [LcdBLoff, LcdOn1, LcdCls]
      PAUSE 250
      SEROUT TX, LcdBaud, [CC0]
    
    
    
    
    ' Scroll "chomper" animation across LCD line 2
    
    
    'Animation:
     ' FOR idx1 = 0 TO 15                    ' scroll across line
       ' READ (Msg2 + idx1), newChar         ' read new character
       ' FOR idx2 = 0 TO 4                   ' animate a current position
         ' LOOKUP idx2, [0, 1, 2, 1, newChar], char
          'SEROUT TX, LcdBaud, [(LcdLine2 + idx1), char]
          'PAUSE 75
       ' NEXT
      'NEXT
    
    
    
    
    ' Flash LCD backlight (works only with backlit model)
    
    
    'Flash:
     ' FOR idx1 = 1 TO 4
      '  SEROUT TX, LcdBaud, [LcdBLon]
       ' PAUSE 750
       ' SEROUT TX, LcdBaud, [LcdBLoff]
      '  PAUSE 250
     ' NEXT
    
    
    
    
      END
    
    
    
    
    
Sign In or Register to comment.