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
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.
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
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.
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.
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.
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.
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?
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.
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.
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?
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.
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.
' 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?
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.
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)
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.
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.
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.
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
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.
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
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
Comments
gets stuck in the loop for this code:
'
or it will only do once as in here when I changed it:
Also, you have an extra old=in7 that should not be there.
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.
I'm going to going to go over the shiftin and shiftout stuff for the clock to switch sensors.
Here are the 2 programs:
PCF8574P:
LCD, it has code for the SHT11 also:
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.
I am using the BS2 sx
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?
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?
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?
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
The thing is that I have my counter currently set up like this:
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,
Is it still possible to get the javilin stamp somewhere despite it being discontinued?
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.
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)
what is the code that I require to display it?
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.
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
Have you tried this at 9600 Baud? To use 19.2K I believe you have to use Flow Control.
Scratch that....see next post.
I use this template for BS2 programing. Helps when you are dealing with serial communications.
Ill let you know how it turns out.
here is the program if u want to look at it.