eeprom and a basic stamp 2
chris jones
Posts: 391
Hello
i have a EEPROm chip on my basic stamp board and i need to know how can i write a value to that chip and read that value from the chip.
EXAMPLE VALUE "1234A"
i need to write that data to the eeprom and never write over it so i need to pick a location on my eeprom chip.
TEST EXMAPLE
start the bs2
write the value "1234A"
do some code
disconnect the bs2
reconnect the bs2
do some code
Read the value from the eeprom
Thanks in advance
Post Edited By Moderator (Joshua Donelson (Parallax)) : 10/15/2009 5:07:25 PM GMT
i have a EEPROm chip on my basic stamp board and i need to know how can i write a value to that chip and read that value from the chip.
EXAMPLE VALUE "1234A"
i need to write that data to the eeprom and never write over it so i need to pick a location on my eeprom chip.
TEST EXMAPLE
start the bs2
write the value "1234A"
do some code
disconnect the bs2
reconnect the bs2
do some code
Read the value from the eeprom
Thanks in advance
Post Edited By Moderator (Joshua Donelson (Parallax)) : 10/15/2009 5:07:25 PM GMT
Comments
Which one Chris?
Go to the main Parallax webpage, click on the Resources tab, and select Nuts and Volts Columns. That'll get you to the index. There are several columns on I2C devices. One column provides subroutines for the BS2 to use instead of the I2C statements available in the BS2p Stamp models.
http://www.parallax.com/Portals/0/Downloads/docs/prod/oem/24LC128-SourceCode-v2.0.zip
·
EXMAPLE
TEMP VAR Word
TEMP = "1234A"
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Engineering
50 72 6F 6A 65 63 74 20 53 69 74 65
·
This won't work because "1234A" is a string and there are no string variables in Stamp Basic. If you want the 5 characters "1234A" to be written to EEPROM, you'll have to write them one character at a time to successive locations in the EEPROM. If you have a subroutine writeEEPROM that takes the 8-bit value in TEMP and writes it to location ADDR in the EEPROM, you do
ADDR = 0
TEMP = "1"
GOSUB writeEEPROM
ADDR = 1
TEMP = "2"
GOSUB writeEEPROM
ADDR = 2
TEMP = "3"
GOSUB writeEEPROM
ADDR = 3
TEMP = "4"
GOSUB writeEEPROM
ADDR = 4
TEMP = "A"
GOSUB writeEEPROM
here is my code i ned to know if i am doing this right
========================================================================
' {$STAMP BS2}
' {$PBASIC 2.5}
'
[noparse][[/noparse] Revision History ]
'
[noparse][[/noparse] I/O Definitions ]
Rx PIN 7 ' Receiver(27981)DATA pin
TxEnable PIN 9 ' Transmitter(27980)PDN pin
Tx PIN 8 ' Transmitter(27980)DATA pin
SDA PIN 3 ' I2C serial data line
SCL PIN 4 ' I2C serial clock line
'
[noparse][[/noparse] Constants ]
EOM CON 255 ' Value to signal end-of-message
Address CON $A0 ' Address Of 24LC128
Ack CON 0 ' Acknowledge Bit
#SELECT $STAMP ' Select Baud constants
#CASE BS2, BS2E, BS2PE
T1200 CON 813
T2400 CON 396
T4800 CON 188
T9600 CON 84
T19K2 CON 32
#CASE BS2SX, BS2P
T1200 CON 2063
T2400 CON 1021
T4800 CON 500
T9600 CON 240
T19K2 CON 110
#CASE BS2PX
T1200 CON 3313
T2400 CON 1646
T4800 CON 813
T9600 CON 396
T19K2 CON 188
#ENDSELECT
Inverted CON $4000 'Value for inverted serial format
Baud CON T9600+Inverted '9600 baud, 8,N,1 inverted
Nak CON 1 ' no ack bit
EE24LC32 CON %1010 << 4
'
[noparse][[/noparse] Variables ]
string VAR Byte(3) 'Array to hold received data
strLen VAR Byte 'Length of string received
temp VAR Byte 'Temporary variable
packet VAR Byte 'Current packet number
lastPacket VAR Byte 'Last good packet number
cValue VAR Byte 'Value to add to CRC value
crc VAR Word 'Calculate CRC value
rcvdCrc VAR Word 'Received CRC value
idx VAR Word 'Index into message data
char VAR Byte 'Current character from message
temp2 VAR Byte ' Variable Used For Work
i2cWork VAR Word ' Work Byte For I2C I/O
i2cAck VAR Bit ' Ack Bit From Device
eeprom_add VAR Word ' EEPROM Address
cnt VAR Byte
test VAR Nib
ADDR VAR Byte
'
[noparse][[/noparse] Initialization ]
Message DATA "Test My Transmit"
DATA EOM
Check_Module:
#IF ($STAMP >= BS2P) #THEN
#ERROR "Use I2COUT and I2CIN!"
#ENDIF
Setup:
BoardID DATA "1234A"
DEBUG CLS
DEBUG "WSN ", CR,
"
", CR,
"Address... ", CR,
"Output.... ", CR,
"Input..... ", CR,
"Status.... ", CR,
"Errors.... ", CR,
"Light..... ", CR,
"Battery.... ", CR,
"Sensors.... ", CR,
"TPacket.... ", CR,
"RPacket... "
GOTO main
'
[noparse][[/noparse] Program Code ]
Main:
Send_ID:
ADDR = 0
TEMP = "1"
GOSUB Control_Byte_Write:
ADDR = 1
TEMP = "2"
GOSUB Control_Byte_Write:
ADDR = 2
TEMP = "3"
GOSUB Control_Byte_Write:
ADDR = 3
TEMP = "4"
GOSUB Control_Byte_Write:
ADDR = 4
TEMP = "A"
GOSUB Control_Byte_Write:
'
[noparse][[/noparse] Subroutines ]
Transmit:
' Send the test data to another node
LOW Tx 'Initialize transceiver interface
LOW TxEnable 'Disable transmitter
packet = 1 'Initialize packet number
DO
idx = message 'Point idx to start of message data
DO
strLen = 0 'Set string length to zero
crc = 0 'Start Crc at zero
DO
strLen = strLen + 1
READ idx, char 'Read a character from message data
idx = idx + 1 'Point to next character in message
string(strLen-1) = char 'Put character into string array
temp = char 'Prepare to add char to Crc value
GOSUB CalcCRC2 'Add cValue to Crc value
IF (strLen = 2) OR (char = EOM) THEN EXIT ' Exit if done
LOOP 'Keep reading message characters
DO
RecvTimeOut:
PAUSE 100 'Give receiver time to process
DEBUG "Sending packet ", DEC packet, CRSRXY, 15, 10
HIGH TxEnable 'Enable transmitter
' Send packet
PULSOUT Tx,1200 'Send sync pulse to radio
' Send preample "UUUU!", packet #, string length, string data, crc
SEROUT Tx, Baud, [noparse][[/noparse]"UUUU!", packet, strLen, STR string\strLen,
crc.LOWBYTE, crc.HIGHBYTE]
LOW TxEnable 'Disable transmitter
' Wait for response from receiver
GetResponse:
' Receive up to 100 characters looking for a "!"
' Use rcvdCrc as temporary variables
FOR rcvdCrc.LOWBYTE = 1 TO 10
SERIN Rx,Baud,600,RecvTimeOut,[noparse][[/noparse]rcvdCrc.HIGHBYTE]
IF rcvdCrc.HIGHBYTE = "!" THEN EXIT
NEXT
' If we didn't receive a "!" then timeout
IF rcvdCrc.HIGHBYTE <> "!" THEN RecvTimeOut
' Receive the Crc value
SERIN Rx,Baud,600,RecvTimeOut,[noparse][[/noparse]rcvdCrc.LOWBYTE,rcvdCrc.HIGHBYTE]
LOOP UNTIL crc = rcvdCrc 'Repeat packet until crc match
packet = packet + 1 'Advance packet value
packet = packet MIN 1 'Don't use packet value zero
LOOP WHILE char <> EOM 'Keep sending until EOM
LOOP 'Start all over at the beginning
Recive:
' recive data from another node
LOW Tx
LOW TxEnable
DO
' Wait for preamble, then receive data and crc value
SERIN Rx,Baud,[noparse][[/noparse]WAIT ("U!"), packet, strLen, STR string\strLen,
rcvdCrc.LOWBYTE,rcvdCrc.HIGHBYTE]
' Calculate crc of received data
crc = 0
FOR temp = 0 TO strLen-1
cValue = string(temp)
GOSUB CalcCRC
NEXT
' See if received crc value matches calculated crc value
IF rcvdCrc = crc THEN
' Check if this is a repeated packet
IF packet <> lastPacket THEN
' Is last character the "end-of-message" marker ?
IF string(strLen-1) <> EOM THEN
DEBUG STR string\strLen ' Display string on debug screen
ELSE
strLen = strLen -1 ' Don't display EOM
DEBUG STR string\strLen, CRSRXY, 15, 11
ENDIF
ENDIF
lastPacket = packet
' Send acknoledgement back to transmitter
HIGH TxEnable
PULSOUT Tx,1200
SEROUT Tx, Baud, [noparse][[/noparse]"UUUU"]
PAUSE 3 ' Give transmitter time to process
SEROUT Tx,Baud, [noparse][[/noparse]"!"]
PAUSE 3 ' Give transmitter time to process
SEROUT Tx, Baud, [noparse][[/noparse]crc.LOWBYTE, crc.HIGHBYTE]
LOW TxEnable
ELSE
' Received crc did NOT match calculated crc
DEBUG " ** RECEIVE ERROR ** ", BELL
ENDIF
LOOP
' CRC Checksum Calculation Routine
CalcCRC:
CValue= crc.HIGHBYTE ^ cValue >> 4 ^ (crc.HIGHBYTE ^ cValue)
crc = cValue ^ (cValue << 5) ^ (cValue << 12) ^ (crc << 8)
RETURN
' CRC Checksum Calculation Routine
CalcCRC2:
temp= crc.HIGHBYTE ^ temp >> 4 ^ (crc.HIGHBYTE ^ temp)
crc = temp ^ (temp << 5) ^ (temp << 12) ^ (crc << 8)
RETURN
I2C_Stop: ' I2C Stop Bit Sequence
LOW SDA
INPUT SCL
INPUT SDA ' SDA --> High While SCL High
RETURN
I2C_Start: ' I2C Start Bit Sequence
INPUT SDA
INPUT SCL
LOW SDA ' SDA --> Low While SCL High
RETURN
Addrs: ' I2C Address Byte Sequence
i2cWork = eeprom_add
SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork.HIGHBYTE\8] ' Send Byte To Device
SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork.LOWBYTE\8] ' Send Byte To Device
SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
RETURN
Control_Byte_Write: ' I2C Control Write Byte Sequence
i2cWork = Address
i2cWork.BIT0 = 0 ' Sets Unit To Write
SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] ' Send Byte To Device
SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
RETURN
Control_Byte_Read: ' I2C Control Read Byte Sequence
i2cWork = Address
i2cWork.BIT0 = 1 ' Sets Device To Read
SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] ' Send Byte To Device
SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
RETURN
Write_Data: ' I2C Write Byte Sequence
i2cWork = temp
SHIFTOUT SDA, SCL, MSBFIRST, [noparse][[/noparse]i2cWork\8] 'Send Byte To Device
SHIFTIN SDA, SCL, MSBPRE, [noparse][[/noparse]i2cAck\1] ' Get Acknowledge Bit
RETURN
========================================================================
You need to put out a start bit sequence, then two bytes of address information (MSB first - Addrs), then the data byte (Write_Data), then a stop bit sequence. You need to pass the address and data information to the subroutines in the proper variables. There should be a complete example in the Nuts and Volts Columns. You also need a 5ms PAUSE after writing each character.
Wait, what? Can't you just do this with strings?
There are string constants for use in various I/O statements and in DATA statements, but you can't store them or compare them or anything other than use them in certain I/O statements and the DATA statement. The BS2 doesn't have the built-in I2C statements. Only the BS2p/pe/px has them.
It's possible to store a string in EEPROM using a DATA statement, then copy that string a byte at a time to an EEPROM given the starting address of the string, but that's not what chris was asking.
This isn't considered a string?