······················································· ························································· EXAMPLE 19
··················A/D CONVERSION WITH RESULTS DISPLAYED ON A VIDEO MONITOR··
{
ADC0831
/CS •1││8• Vcc +5
Vin+ •2│ │7• CLK
Vin-•3│ │6• DO
GND •4││5• Vref
+5V ADC0831
│ Pin A0 -------→•1││8• -------- +5V
10k ←-------------------→•2│ │7• ←------- Pin A2
│ │---•3│ │6• -----→ Pin A1 ←-- The series resistor is 10k.
Vss Vss│---•4││5• -------- Vref +5 V The purpose of this resistor
' is to limit current.
'
WARNING: DO NOT USE THE +5 VOLTS AS THE PROPELLER'S Vdd.
THE PROPELLER'S Vdd MUST NEVER EXCEED 3.6 VOLTS.
NOTE: The ADC0831 is rated at 4.5 to 6.3 volts. I was
able to get the ADC0831 to function using the
Propeller's 3.3 volts power supply. How well
did it function? Don't know, but quick-and-dirty
testing looked ok.
'
RESISTOR SYMBOL IS NOT DISPLAYING CORRECTLY WHEN POSTED.
'
}
' EXAMPLE 19
'
' A/D CONVERSION WITH RESULTS DISPLAYED ON A VIDEO MONITOR
'***************************************************************************
'IMPORTANT: This example may require an understanding of example 09
'***************************************************************************
'WHAT'S NEW IN THIS EXAMPLE:
' ADC0831 A/D CONVERTER
' 1. This is a serial 8-bit converter.
' 2. Zero to 5 volt range on a single 5 volt power supply.
' 3. Conversion time: 32uS.
' 4. Supply voltage 4.5 to 6.3 volts.
' 5. With an overshoot, the digital output is about 5 volts.
' Since the Propeller is a 3.3 volt device, it is prudent
' to add a 10k resistor between Pin 6 of the ADC0831
' and Pin A1 of the Propeller. This limits the current
' at Pin A1 of the Propeller.
' 6. References: [url=http://www2.ics.hawaii.edu/~chin/331/lab08c.pdf]http://www2.ics.hawaii.edu/~chin/331/lab08c.pdf[/url]
' : [url=http://www.parallax.com/dl/sw/bs2Tutorial.ppt]www.parallax.com/dl/sw/bs2Tutorial.ppt[/url]
' (Slides 223-230)
'
' BS2.SHIFTIN (DataPin, CLK_Pin, Mode, Bits)
' 1. Shifts data in from a synchronous device. In this case,
' the device is the serial A/D converter.
'***************************************************************************
'DIFFICULTY LEVEL: Easy
'
'PURPOSE: The purpose of this Example is to illustrate how to interface
' a popular A/D device to the propeller and to illustrate how to
' display the results on a video monitor.
' WARNING: DO NOT CONNECT THE 5V SOURCE TO Vdd OF THE PROPELLER.
' MAX VOLTAGE TO RUN THE PROPELLER IS 3.6V.
'
'Submitted by Dave Scanlan, May 8, 2006
'File: Example19_A2D_ADC0831_Video.spin
'***************************************************************************
'CORRECT OUTPUT: The video monitor will dispaly the following:
'
' EIGHT-BIT DECIMAL VALUE: XXX
' ANALOG VOLTAGE INPUTTED: XXX cv
'
'
'***************************************************************************
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
OUT = %1
IN = %0
HIGH = 1
LOW = 0
NewLine = 13
ClearScreen = 0
'
ADC_CS = 0 ' /CS Pin on Propeller
ADC_Data = 1 ' Data Pin on Propeller
ADC_CLK = 2 ' Clock Pin on Propeller
'
OBJ
BS2: "BS2_Functions"
VideoDisplay: "TV_Terminal"
'
VAR
Byte ADC_Result 'A/D result (8 bits)
'
PUB START 'Initialize VideoDisplay
VideoDisplay.start
SetScreenWhiteOnDarkBlue
VideoDisplay.out(ClearScreen) 'Clear screen.
Repeat
A2D_Conversion
DisplayOutputOfADC
'
PRI A2D_Conversion
DIRA[noparse][[/noparse]ADC_CS] := OUT
DIRA[noparse][[/noparse]ADC_Data] := IN
DIRA[noparse][[/noparse]ADC_CLK] := OUT
OUTA[noparse][[/noparse]ADC_CS] := LOW ' Select ADC chip
ADC_Result := BS2.SHIFTIN(ADC_Data, ADC_CLK,BS2#MSBPOST,9)
OUTA[noparse][[/noparse]ADC_CS] := HIGH ' Deselect ADC chip when done
'
PRI DisplayOutputOfADC
VideoDisplay.str(string("EIGHT-BIT DECIMAL VALUE: "))'Send text to monitor.
VideoDisplay.dec(ADC_Result) 'Sends a decimal value to a video monitor.
VideoDisplay.out(NewLine)
VideoDisplay.str(string("ANALOG VOLTAGE INPUTTED: "))'Send text to monitor.
VideoDisplay.dec(ADC_Result * 500/255) ' Hundredth of a volt
VideoDisplay.str(string(" cv")) ' cv (centivolt)
VideoDisplay.out(NewLine) ' Send a NewLine to monitor.
WaitCnt(80_000_000 + Cnt) ' One second delay
VideoDisplay.out(NewLine)
VideoDisplay.out(NewLine)
'
'
PRI SetScreenWhiteOnDarkBlue ' Sets the foreground color to
VideoDisplay.out(3) ' white and the background color
VideoDisplay.out(5) ' to dark blue on the monitor.
'***************************************************************************
'ADDITIONAL INFORMATION
' WARNING: DO NOT CONNECT THE 5V POWER SOURCE TO Vdd OF THE PROPELLER.
' MAX VOLTAGE TO RUN THE PROPELLER IS 3.6V.
' I DID NOT DO EXTENSIVE TESTING ON THIS EXAMPLE; THEREFORE, I CANNOT
' RECOMMEND IT FOR COMMERICAL APPLICATIONS. I BELIEVE IN MURPHY'S LAW.
' I did not check for failed initialization of VideoDisplay object.
' MEMORY USAGE:
' Program: 1,735 Longs
' Variables: 3,519 Longs
' Stack/Free: 2,935 Longs
··················································· ······················································FEW COMMENTS (EASIER TO READ)
{
ADC0831
/CS •1││8• Vcc +5
Vin+ •2│ │7• CLK
Vin-•3│ │6• DO
GND •4││5• Vref
+5V ADC0831
│ Pin A0 -------→•1││8• -------- +5V
10k ←-------------------→•2│ │7• ←------- Pin A2
│ │---•3│ │6• -----→ Pin A1 ←-- The series resistor is 10k.
Vss Vss│---•4││5• -------- Vref +5 V The purpose of this resistor
' is to limit current.
'
WARNING: DO NOT USE THE +5 VOLTS AS THE PROPELLER'S Vdd.
THE PROPELLER'S Vdd MUST NEVER EXCEED 3.6 VOLTS.
}
' EXAMPLE 19
'
' A/D CONVERSION WITH RESULTS DISPLAYED ON A VIDEO MONITOR
'***************************************************************************
'IMPORTANT: This example may require an understanding of example 09
'***************************************************************************
'DIFFICULTY LEVEL: Easy
'***************************************************************************
'CORRECT OUTPUT: The video monitor will dispaly the following:
'
' EIGHT-BIT DECIMAL VALUE: XXX
' ANALOG VOLTAGE INPUTTED: XXX cv
'
'Submitted by Dave Scanlan, May 8, 2006
'File: Example19_A2D_ADC0831_Video.spin
'***************************************************************************
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
OUT = %1
IN = %0
HIGH = 1
LOW = 0
NewLine = 13
ClearScreen = 0
'
ADC_CS = 0
ADC_Data = 1
ADC_CLK = 2
'
OBJ
BS2: "BS2_Functions"
VideoDisplay: "TV_Terminal"
'
VAR
Byte ADC_Result 'A/D result (8 bits)
'
PUB START
VideoDisplay.start
SetScreenWhiteOnDarkBlue
VideoDisplay.out(ClearScreen)
Repeat
A2D_Conversion
DisplayOutputOfADC
'
PRI A2D_Conversion
DIRA[noparse][[/noparse]ADC_CS] := OUT
DIRA[noparse][[/noparse]ADC_Data] := IN
DIRA[noparse][[/noparse]ADC_CLK] := OUT
OUTA[noparse][[/noparse]ADC_CS] := LOW ' Select ADC chip
ADC_Result := BS2.SHIFTIN(ADC_Data, ADC_CLK,BS2#MSBPOST,9)
OUTA[noparse][[/noparse]ADC_CS] := HIGH ' Deselect ADC chip when done
'
PRI DisplayOutputOfADC
VideoDisplay.str(string("EIGHT-BIT DECIMAL VALUE: "))
VideoDisplay.dec(ADC_Result)
VideoDisplay.out(NewLine)
VideoDisplay.str(string("ANALOG VOLTAGE INPUTTED: "))
VideoDisplay.dec(ADC_Result * 500/255) ' Hundredth of a volt
VideoDisplay.str(string(" cv")) ' cv (centivolt)
VideoDisplay.out(NewLine)
WaitCnt(80_000_000 + Cnt)
VideoDisplay.out(NewLine)
VideoDisplay.out(NewLine)
'
'
PRI SetScreenWhiteOnDarkBlue
VideoDisplay.out(3)
VideoDisplay.out(5)
'***************************************************************************
'ADDITIONAL INFORMATION
' WARNING: DO NOT CONNECT THE 5V POWER SOURCE TO Vdd OF THE PROPELLER.
' MAX VOLTAGE TO RUN THE PROPELLER IS 3.6V.
' I DID NOT DO EXTENSIVE TESTING ON THIS EXAMPLE; THEREFORE, I CANNOT
' RECOMMEND IT FOR COMMERICAL APPLICATIONS. I BELIEVE IN MURPHY'S LAW.
' I did not check for failed initialization of VideoDisplay object.
' MEMORY USAGE:
' Program: 1,735 Longs
' Variables: 3,519 Longs
' Stack/Free: 2,935 Longs
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ··
Post Edited (Dave Scanlan) : 5/15/2006 2:04:01 AM GMT
Could you explain why the memory usage is so incredibly high??? That does not seem correct. I understand, though, that you state that you have not done extensive testing on this. Also, you may want to point out that this example almost seems like more of an example of using the serial in command, versus the A/D. You just motivated me to get my video out wired up. A/D is going to be my first real project. I'm also curious if you could provide an example using the discreet components version (non-dedicated peripherial ADC)?
The memory usage is high because of all the objects that are being used: (1) TV_Terminal, (2) TV, (3) Graphics, ·and (4) BS2_Functions. Of course, my own code adds to the usage.
SERIN·is for asynchronous communication.· This example uses SHIFTIN (synchronous communication).· As for using a capacitor and resistor for
the A/D process, I will do that if others want to see it too.· How about an example using flash A/D?· Flash is fun stuff, for me at least.
On second thought, I will do the cap/resistor A/D.· It is very easy to do with the objects that
are available.
I personally would not use this example for a commercial application until I had done about 25 measurements with calibrated
equipment to test this circuit.· I also found some noise on the data pin.· Perhaps, one should consider bypass caps and/or a
pullup resistor.
As for today, well, I've got to go to work in a few minutes.· I will try to answer any further question later today.
You are right...video is·fun stuff.· Isn't the Propeller great!!!!
Dave
parsko said...
Dave,
Could you explain why the memory usage is so incredibly high??? That does not seem correct. I understand, though, that you state that you have not done extensive testing on this. Also, you may want to point out that this example almost seems like more of an example of using the serial in command, versus the A/D. You just motivated me to get my video out wired up. A/D is going to be my first real project. I'm also curious if you could provide an example using the discreet components version (non-dedicated peripherial ADC)?
Thanks,
-Parsko
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ··
Post Edited (Dave Scanlan) : 5/9/2006 3:58:07 PM GMT
I was in such a hurry to get to work, that I did not read your words carefully.· Now I see what you meant about serial-in.· Yes, the example
has a lot to do with processing data serially.· I was hoping that people would refer to PBASIC for this serial processing: SHIFTIN
Sorry about the NewLine method. It was in the object I used. Perhaps you are missing one of the supporting objects.
Dave
parsko said...
Dave,
Could you explain why the memory usage is so incredibly high??? That does not seem correct. I understand, though, that you state that you have not done extensive testing on this. Also, you may want to point out that this example almost seems like more of an example of using the serial in command, versus the A/D. You just motivated me to get my video out wired up. A/D is going to be my first real project. I'm also curious if you could provide an example using the discreet components version (non-dedicated peripherial ADC)?
·'······································ EXAMPLE 20
'
'············ THIS EXAMPLE MEASURES THE CHARGE TIME OF A CAPACITOR,
'·················· USES TWO COGS, AND HAS VIDEO OUTPUT·····································
'
' EXAMPLE 20
'
' THIS EXAMPLE MEASURES THE CHARGE TIME OF A CAPACITOR,
' USES TWO COGS, AND HAS VIDEO OUTPUT
'************************************************************************
'IMPORTANT: This example may require an understanding of examples 6 & 9
'************************************************************************
' WHAT'S NEW:
' RCTIME METHOD
' - This method measures in clock pulses (12.5 ns) the time it
' takes to charge a capacitor (0.1uf) in an R/C circuit.
' The resistor in the circuit is a 10k pot.
'
'************************************************************************
'DIFFICULTY LEVEL: Easy
'************************************************************************
'PURPOSE:
' -- The purpose of this example is to illustrate how to program
' an RCTIME method and how to use it. The output from the RCTIME
' method is converted to microseconds before being displayed
' on the video monitor.
'Submitted by Dave Scanlan, May 13, 2006
'File: Example20_RCTimeTwoCogs __.spin
'************************************************************************
'CORRECT OUTPUT: The approximate time in microseconds for the 0.1uf
' capacitor to charge is displayed as below:
' VIDEO DISPLAY UNIT
' _________________________________
' | CAP CHARGE TIME: ~XXX us |
' | |
' | |
' |_________________________________|
'
'************************************************************************
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
NewLine = 13
'
VAR
Long Count
Long stack0[noparse][[/noparse]60] 'Sets up a stack space for a Cog(processor)
Long stack1[noparse][[/noparse]50] 'Sets up a stack space for a second Cog(processor)
'
OBJ
VideoDisplay: "TV_Terminal"
'
PUB Start
VideoDisplay.Start
SetScreenWhiteOnDarkBlue
CogNew(RCTIME, @stack0)
CogNew(DisplayCount, @stack1)
'
PRI RCTIME | ClkStart, ClkStop, Pin, State, Out, In, High
High := 1
Out := %1
In := %0
Pin := 0
State := 1
'
Repeat
DirA[noparse][[/noparse]Pin] := Out
OutA[noparse][[/noparse]Pin] := High ' Discharge the 0.1uf capacitor
WaitCnt(80_000 + Cnt) ' 1ms pause
DirA[noparse][[/noparse]Pin] := In ' Reads high or low.
ClkStart := Cnt ' Counter value at Start
Waitpne(State << Pin, |< Pin, 0) ' Wait for low on Pin 0
ClkStop := Cnt ' Counter value at Stop
Count := (ClkStop - ClkStart) ' 12.5ns units
'
PRI DisplayCount
Repeat
VideoDisplay.Str(String("CAP CHARGE TIME: ~"))
VideoDisplay.Dec(Count * 125/10_000) 'Time in microseconds
VideoDisplay.Str(String("us"))
VideoDisplay.Out(NewLine)
'
PRI SetScreenWhiteOnDarkBlue
VideoDisplay.out(3)
VideoDisplay.out(5)
'
'ADDITIONAL INFORMATION
' The code used in the RCTIME method is a modification
' of Martin Hebel's code in BS2_Functins.spin.
'
' According to my 7904 Tektronics scope, cap charge times
' displayed on the video monitor in this example are
' in close, but not in perfect, agreement with the scope's.
' IT WOULD BE GREAT IF SOMEONE WITH ACCURATE
' EQUIPMENT WOULD CHECK THESE CHARGE TIMES.
'
' Memory Usage:
' - Program: 1,719 Longs
' - Variables: 3,630 Longs
' - Stack/Free: 2,839 Longs
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ··
Post Edited (Dave Scanlan) : 5/13/2006 7:11:27 PM GMT
At the possible risk of seeming to go off topic slightly, I wish Adobe or someone would publish just some simple tools, not unlike what Microsoft has done, to do minimal manipulation of their PDF files. The universality of the format is well respected in most quarters, but once they're "locked in", you need deeper pockets than I have, to get the information back out, unless you're just looking to extract some simple text, or a single graphic or two which is not "protected" <sigh>.
Just to bring this back on topic, nothing would please me more, than if I had access to just such a program so that I could take all of these marvelous Propeller examples (THANKS Dave and others!), Propeller tips, tricks, and hints, and the Parallax prepared Propeller documentation, etc. and build my own personal Propeller Notebook. The REALLY nice thing about something like that is you could make personal notations therein, as to who the "experts" are in all the various application-specific areas which have been mentioned on this Propeller Forum, for possible future reference, without having to re-scan all the messages to find those gurus!
Regards,
Bruce Bates
·Well, this may solve everyones problem!· FREE too It works as a reader!
· The PRO version $39.95 has a library function that may do the trick.
I checked out the PDF software site below.··A person·certainly can't grip about the price.
Thanks,
Dave
cocokiwi said...
Bruce Bates said...
Dave -
At the possible risk of seeming to go off topic slightly, I wish Adobe or someone would publish just some simple tools, not unlike what Microsoft has done, to do minimal manipulation of their PDF files. The universality of the format is well respected in most quarters, but once they're "locked in", you need deeper pockets than I have, to get the information back out, unless you're just looking to extract some simple text, or a single graphic or two which is not "protected" <sigh>.
Just to bring this back on topic, nothing would please me more, than if I had access to just such a program so that I could take all of these marvelous Propeller examples (THANKS Dave and others!), Propeller tips, tricks, and hints, and the Parallax prepared Propeller documentation, etc. and build my own personal Propeller Notebook. The REALLY nice thing about something like that is you could make personal notations therein, as to who the "experts" are in all the various application-specific areas which have been mentioned on this Propeller Forum, for possible future reference, without having to re-scan all the messages to find those gurus!
Regards,
Bruce Bates
·Well, this may solve everyones problem!· FREE too It works as a reader!
· The PRO version $39.95 has a library function that may do the trick.
A/D CONVERSION WITH RESULTS DISPLAYED ON A VIDEO MONITOR
{
ADC0831
/CS •1││8• Vcc +5
Vin+ •2│ │7• CLK
Vin-•3│ │6• DO
GND •4││5• Vref
+5V ADC0831
│ Pin A0 -------→•1││8• -------- +5V
10k ←-------------------→•2│ │7• ←------- Pin A0
│ │---•3│ │6• -----→ Pin A1 ←-- The series resistor is 10k.
Vss Vss│---•4││5• -------- Vref +5 V The purpose of this resistor
' is to limit current.
Dave, a small typo here. You have in the diagram above labele pin 7 of the ADC0831 as "A0" - it should be "A2" according to your actual code. "A0" is the Chip Select "CS". The problem is in both copies of the source code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cheers ... brian riley, n1bq, underhill center, vermont
See the K107 Serial LCD Controller at www.wulfden.org/k107/
Thanks for spotting·the error·and for taking the time to report it.
Did you try out the example?
Dave
Brian Riley said...
Dave Scanlan said...
EXAMPLE 19
A/D CONVERSION WITH RESULTS DISPLAYED ON A VIDEO MONITOR
{
ADC0831
/CS •1││8• Vcc +5
Vin+ •2│ │7• CLK
Vin-•3│ │6• DO
GND •4││5• Vref
+5V ADC0831
│ Pin A0 -------→•1││8• -------- +5V
10k ←-------------------→•2│ │7• ←------- Pin A0 (Change A0 to A2)
│ │---•3│ │6• -----→ Pin A1 ←-- The series resistor is 10k.
Vss Vss│---•4││5• -------- Vref +5 V The purpose of this resistor
' is to limit current.
Dave, a small typo here. You have in the diagram above labele pin 7 of the ADC0831 as "A0" - it should be "A2" according to your actual code. "A0" is the Chip Select "CS". The problem is in both copies of the source code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ··
Post Edited (Dave Scanlan) : 5/18/2006 4:05:45 AM GMT
IF YOU HAVE THE LATEST VERSION OF THE PROPELLER DEMO BOARD, CHANGES HAVE
BEEN MADE SO THAT THE KEYBOARD OBJECTS AND CODE ARE DIFFERENT FROM
THE EARILER VERSION OF THE DEMO BOARD.· THE EXAMPLES I WROTE ARE FOR THE
EARLIER VERSION.
THE EARLIER VERSION USES THIS OBJECT: Keyboard_iso.spin
THE LATEST VERSION USES THIS OBJECT: Keyboard.spin
SORRY ABOUT THE CONFUSION.· I JUST FOUND OUT ABOUT THESE CHANGES TODAY, MAY 19, 2006.
If I had the latest version of the demo board, I would·post Examples 8 and 18 using the·code for this demo board version.·I can't post code unless I can test it.
The code I posted works perfectly with the earlier demo boards.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ··
Post Edited (Dave Scanlan) : 5/19/2006 5:11:55 PM GMT
···W/R TO AN EXTERNAL EEPROM(24LC32A) USING I2C ·AND DISPLAY RESULT ON AN LCD·
·········································
'
'
'
' SERIAL EEPROM SERIAL LCD (4x20)
' _______ _____________________
'Vss ←╋•│1 8|•→Vdd (3.3 VDC) (Pin A2)RX--→ │ │
' ┣•| |•→Vss (Write Enabled) +5←--- │ LCD SCREEN │
' ┣•| |•SCL--------•--R1--→ Pin A1 Gnd---→ │ │
' ┣•|4___5|•SDA---•----|--R2--→ Pin A2 │_____________________│
' | |
' EEPROM R3 R4
' 24LC34A ↓ ↓ R1: 160
' Vdd Vdd (3.3VDC) R2: 160
' R3: 4.7K
' R4: 4.7K
'
' EXAMPLE 21
'
' W/R TO AN EEPROM(24LC32A) USING I2C
' AND DISPLAY RESULT ON AN LCD
'***********************************************************************
'IMPORTANT: This example may require an understanding of other examples
'***********************************************************************
'WHAT'S NEW IN THIS EXAMPLE:
'
' I2C: The name I2C is shorthand for a standard Inter-IC
' (integrated circuit) bus.
' 1. Basically it is a two-wire bus using a bi-directional
' data line (SDA: Seral DAta) and a clock line
' (SCL: Serial CLock).
' 2. Resources: [url=http://www.embedded.com/story/OEG20010718S0073]http://www.embedded.com/story/OEG20010718S0073[/url]
' ww1.microchip.com/downloads/en/DeviceDoc/21713F.pdf
' 3. This is a commonly used serial interface for IC devices.
'
' 24LC32A: This is an 8-pin, serial, 4096 byte (32Kbits) EEPROM. It uses
' an I2C protocol.
' CHARACTERISTICS:
' 1. 1,000,000 Erase/Write cycles
' 2. Max clock: 400 KHz
' 3. 2.5 to 5.5 volts
'
' Control byte for 24LC32A: %1010_000_0
' FUNCTION OF BITS:
' 1. 1010 is the device ID
' 2. 000 These are the bus-address bits for this device.
' -- Eight devices (0-7) are possible on this bus.
' -- This example uses address 000.
' -- 000 was selected by grounding pins 2,3,and 4
' 3. 0 is the R/W bit. 0 = Write; 1 = Read
' -- This "tells" the EEPROM what the operation is
' going to be: Write or Read.
'
'
'***********************************************************************
'DIFFICULTY LEVEL: Intermediate
'*********************************************************************** '
'PURPOSE: This example illustrates:
' 1. How to hookup a serial EEPROM (24LC32) to the Propeller
' 2. How to hookup a Parallax, serial LCD (20x4) to the Propeller
' 3. How to Write to and Read from a 24LC32 using I2C protocol
' 4. EVERY EFFORT WAS MADE TO SIMPLIFY THE I2C ALGORITHM.
'
'Submitted by Dave Scanlan, May 30, 2006
'File: Example21_EEPROM_I2C_LCD.spin
'***********************************************************************
'CORRECT OUTPUT:
' 1. Write:xxx (Shows the values as they are being written to the EEPROM.)
' 2. Read:xxx (Shows the values as they are being read from the EEPROM.)
' 3. W/R Failures:xxx (Shows the number of W/R failures.)
' 4. W/R Passes:xxxxx (Shows the number of successful W/R operations.)
' 5. ALL LOCATIONS OK (Displayed at the end of W/R's if there are
' no W/R failures.)
' 6. All values are displayed in real-time on the LCD.
'
'
' SERIAL LCD (4x20)
' ||
' (Pin A2) RX--→ │Write:xxx Read:xxx │
' +5←--- │W/R Failures:xxx │
' Ground---→ │W/R Passes:xxxxx │
' │ALL LOCATIONS OK │
' 
'***********************************************************************
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
'
SDA = 0 'EEPROM Data pin
SCL = 1 'EEPROM Clock pin
IN = %0 'Pin direction
OUT = %1 'Pin direction
LOW = 0 'Pin state
HIGH = 1 'Pin state
Ack = 0 'Valid data transfer
Nak = 1 'Invalid data transfer
LCD_Pin = 2 'The LCD is connected to pin A2.
LCD_Baud = 19_200 'Baud
LCD_Lines = 4 'The number of lines on this LCD
'
VAR
Byte EEPROM_ID 'Device ID: 1010 MSBits
Word EEPROM_Address 'Holds EEPROM addresses used in
' Write/Read operations.
Byte Data 'Holds Data to be stored in the EEPROM
Byte AddrOrData 'Working byte for TX and RX routines
Byte Ack_I2C 'Ack bit from device
Byte Index 'Used to index LOOKUP
Byte ValueStored 'Holds the value to be written to EEPROM
Byte ValueRead 'Holds the value read from the EEPROM.
Word WriteReadFailures 'Holds the number of W/R failures
Word WR_Passes 'Holds the number of successful W/R passes.
Byte HiByte 'Holds the MSB of the EEPROM address
Byte LoByte 'Holds the LSB of the EEPROM address
'
OBJ
LCD : "Debug_Lcd" 'Code must be able to access Debug_Lcd
BS2 : "BS2_Functions" 'Code must be able to access BS2_Functions
'
'
'
'START
'***********************************************************************
PUB Start
Initialization 'Calls Initialization Method
Repeat EEPROM_Address FROM 0 to 4095 'Used to generate 4096 EEPROM
' addresses for Writing to and
' Reading from the EEPROM.
'
Repeat Index FROM 1 TO 4 'Tests each EEPROM location
' using four values.
ValueStored := LOOKUP(Index: $FF, $AA, $55, $00) 'Four test values
Data := ValueStored 'Data is used in Write_Byte
Write_Byte 'Calls Write_Byte Method.
BS2.PAUSE(10) 'PROGRAM "MUST" PAUSE
Read_Byte 'Calls Read_Byte Method
ValueRead := Data 'Data value comes from Read_Byte
DisplayResultsOnLCD 'Calls DisplayResultsOnLCD
If WriteReadFailures == 0 'If all locations test OK,
LCD.GotoXY(0,3) ' ALL LOCATIONS OK is
LCD.STR(STRING("ALL LOCATIONS OK ")) ' displayed.
'
'INITIALIZATON
'**********************************************************************
PRI Initialization
EEPROM_ID := %1010_000_0 'Device ID: 1010 (MSBits)
LCD.Start(LCD_Pin, LCD_Baud, LCD_Lines) 'Initialize LCD object
BS2.Start(31,30) 'Initialize BS2 object
LCD.Cls 'Clear Screen on LCD
LCD.Backlight(1) 'Turn on LCD backlight
LCD.GotoXY(0,0) 'Go to Home position on LCD
LCD.STR(STRING("Write:")) 'For value written to EEPROM
LCD.GotoXY(10,0)
LCD.STR(STRING("Read:")) 'For value read from EEPROM
LCD.GotoXY(0,1)
LCD.STR(STRING("W/R Failures:")) 'W/R failures
LCD.GotoXY(0,2)
LCD.STR(STRING("W/R Passes:")) 'W/R successes
'
'DISPLAY Results on LCD
'**********************************************************************
PRI DisplayResultsOnLCD
LCD.GotoXY(6,0) 'Puts cursor at Col 5, Line 0
' (Cols and Lines start at 0,0)
LCD.DEC(ValueStored) 'Current value Written
LCD.GotoXY(15,0)
LCD.DEC(ValueRead) 'Current value Read
LCD.GotoXY(13,1)
If ValueStored <> ValueRead 'Tracks W/R failures.
WriteReadFailures := WriteReadFailures + 1
LCD.DEC(WriteReadFailures)
LCD.GotoXY(11,2)
If ValueStored == ValueRead 'Tracks W/R successes
WR_Passes := WR_Passes + 1
LCD.DEC(WR_Passes)
'
'WRITE_Byte
'**********************************************************************
' -- See this URL for a full understanding of the Write algorithm:
' ww1.microchip.com/downloads/en/DeviceDoc/21713F.pdf
'**********************************************************************
PRI Write_Byte
Start_I2C 'Send Start bit to EEPROM
AddrOrData := EEPROM_ID & %1111_111_0 'Set "0" WRITE bit
TX_Byte 'Send Write bit to EEPROM
IF (Ack_I2C == Nak) 'Wait until not busy
Write_Byte
HiByte := EEPROM_Address >> 8 'Get High address byte
AddrOrData := HiByte
TX_Byte 'Send High address byte to EEPROM
LoByte := EEPROM_Address 'Get Low address byte
AddrOrData := LoByte
TX_Byte 'Send Low address byte to EEPROM
AddrOrData := Data
TX_Byte 'Send Data byte to EEPROM
Stop_I2C 'Send Stop bit to EEPROM
'
'READ_Byte
'**********************************************************************
' -- See this URL for a full understanding of the Read algorithm:
' ww1.microchip.com/downloads/en/DeviceDoc/21713F.pdf
'**********************************************************************
PRI Read_Byte
Start_I2C 'Send Start bit to EEPROM
AddrOrData := EEPROM_ID & %1111_111_0 'Set "0" WRITE bit
TX_Byte 'Send Write bit to EEPROM
IF (Ack_I2C == Nak) 'Wait until EEPROM not busy
Write_Byte
HiByte := EEPROM_Address >> 8 'Get High address byte
AddrOrData := HiByte 'HiByte for code clarity
TX_Byte 'Send High address byte to EEPROM
LoByte := EEPROM_Address 'Get Low address byte
AddrOrData := LoByte 'LowByte for code clarity
TX_Byte 'Send LoByte address byte to EEPROM
Start_I2C 'End Write and Prepare to Read EEPROM
AddrOrData := EEPROM_ID | %0000_000_1 'Set READ bit "1".
TX_Byte 'Send READ bit to EEPROM
RX_Byte 'Get Data byte from EEPROM
Stop_I2C 'Send Stop bit to EEPROM
Data := AddrOrData 'Put data from EEPROM in Data
'
'RX_Byte
'**********************************************************************
'-- See PBASIC documentation for a basic understanding of SHIFTIN and
' SHIFTOUT.
'**********************************************************************
PRI RX_Byte
Ack_I2C := Nak 'Nak = High
AddrOrData := BS2.SHIFTIN(SDA,SCL,BS2#MSBPRE,8) 'Get data from EEPROM
BS2.SHIFTOUT (SDA, SCL,Ack_I2C, BS2#LSBFIRST,1) 'Send ACK or NAK
'
'TX_Byte
'**********************************************************************
'-- See PBASIC documentation for a basic understanding of SHIFTIN and
' SHIFTOUT
'**********************************************************************
PRI TX_Byte
BS2.SHIFTOUT (SDA, SCL,AddrOrData, BS2#MSBFIRST,8)
Ack_I2C := BS2.SHIFTIN(SDA,SCL,BS2#MSBPRE,1) '1=NO NAK; 0=ACK
'
'START
'**********************************************************************
' -- See this URL for a full understanding of the Start algorithm:
' ww1.microchip.com/downloads/en/DeviceDoc/21713F.pdf
' -- This code should be easy to follow, because it does not
' depend on pullup resistor conditions; and it follows the
' start algorithm perfectly.
' -- There are more statements than some would deem necessary, but
' these statements produce scope pulses that perfectly match the
' algorithm. Some statements could be eliminated if processing
' time is a major consideration. (See comments below.)
'**********************************************************************
PRI Start_I2C
DIRA[noparse][[/noparse]SCL] := OUT
OUTA[noparse][[/noparse]SCL] := LOW 'Could be eliminated to save processing time
DIRA[noparse][[/noparse]SDA] := OUT
OUTA[noparse][[/noparse]SDA] := HIGH
OUTA[noparse][[/noparse]SCL] := HIGH
OUTA[noparse][[/noparse]SDA] := LOW 'Sets SDA to Low to trigger START in I2C.
' START is triggered by transitioning SDA to a low
' while SCL is high.
'
OUTA[noparse][[/noparse]SCL] := LOW 'Get ready for address and data
' Could be eliminated to save processing time
'
'PULSES GENERATED BY THE START CODE:
' __ ___
' │ │ SDA Pulse
' │__│
' __
' │ │
' ___│ │___ SCL Pulse
'
'
'
'STOP
'**********************************************************************
' -- See this URL for a full understanding of the Stop algorithm:
' ww1.microchip.com/downloads/en/DeviceDoc/21713F.pdf
' -- This code should be easy to follow, because it does not
' depend on pullup resistor conditions; and it follows the
' stop algorithm perfectly.
' -- There are more statements than some would deem necessary, but
' these statements produce scope pulses that perfectly match the
' algorithm. Some statements could be eliminated if processing
' time is a major consideration. (See comments below.)
'***********************************************************************
PRI Stop_I2C
DIRA[noparse][[/noparse]SCL] := OUT
DIRA[noparse][[/noparse]SDA] := OUT
OUTA[noparse][[/noparse]SCL] := LOW 'Could be eliminated to save processing time
OUTA[noparse][[/noparse]SDA] := LOW
OUTA[noparse][[/noparse]SCL] := HIGH
OUTA[noparse][[/noparse]SDA] := HIGH 'Sets SDA High to trigger a STOP in I2C.
' STOP is triggered by transitioning SDA to a high
' while SCL is high.
OUTA[noparse][[/noparse]SCL] := LOW 'Get ready for address and data
' Could be eliminated to save processing time
'
'PULSES GENERATED BY THE STOP CODE:
' __ ___
' │ │ SDA Pulse
' │__│
' __
' │ │
' ___│ │___ SCL Pulse
'
'
'
'ADDITIONAL INFORMATION:
' -- This program is an adaptation of a PBASIC program written by Jon
' Williams.
' -- This code "should" work with other serial, 8-pin EEPROMs such as
' the 24LC64, 24LC128, 24LC256, and 24LC512. These device have
' NOT been tested with this code. Minor modifications may be
' necessary.
' -- The LCD (4x20) is from Parallax: Stock#: 27979
' -- The EEPROM (24LC32A) is from Parallax: Stock#: 604-00020
' -- Over 300,000 W/R operations were used to test this code.
' No failures were detected. Only one EEPROM was used.
' -- The code for Start_I2C and Stop_I2C was carefully checked
' with a 500 MHz Tektronix scope to be sure that the timing is correct.
' -- In my opinion, this program has too many global variables; but in order
' to make the code easy to understand, I did not use arguments and
' parameters to communicate between methods.
' -- CAUTION: DO NOT ALLOW THE +5 VOLTS, USED WITH THE LCD, TO POWER
' -- THE PROPELLER.
' -- This code is intended for educational purposes only.
' -- This code is intended to be used with a single EEPROM with the
' device address set to 000.
' -- I have used "W/R" instead of the standard "R/W" because this is the
' order of operations in this example.
' -- R1 and R2 are not necessary unless you have more than one device
' accessing the I2C bus. These two resistors will compensate for a
' possible bus short when more than one device is accessing the bus.
'
·································· ·······························FEWER COMMENTS (EASIER TO READ)
' EXAMPLE 21
'
' W/R TO AN EEPROM(24LC32A) USING I2C
' AND DISPLAY RESULT ON AN LCD
'***********************************************************************
'DIFFICULTY LEVEL: Intermediate
'*********************************************************************** '
'Submitted by Dave Scanlan, May 30, 2006
'File: Example21_EEPROM_I2C_LCD.spin
'***********************************************************************
'CORRECT OUTPUT:
' 1. Write:xxx (Shows the values as they are being written to the EEPROM.)
' 2. Read:xxx (Shows the values as they are being read from the EEPROM.)
' 3. W/R Failures:xxx (Shows the number of W/R failures.)
' 4. W/R Passes:xxxxx (Shows the number of successful W/R operations.)
' 5. ALL LOCATIONS OK (Displayed at the end of W/R's if there are
' no W/R failures.)
' 6. All values are displayed in real-time on the LCD.
'
'
' SERIAL LCD (4x20)
' ||
' (Pin A2) RX--→ │Write:xxx Read:xxx │
' +5←--- │W/R Failures:xxx │
' Ground---→ │W/R Passes:xxxxx │
' │ALL LOCATIONS OK │
' 
'Submitted by Dave Scanlan, May 30, 2006
'File: Example21_FewerComments.spin
'***********************************************************************
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
'
SDA = 0
SCL = 1
IN = %0
OUT = %1
LOW = 0
HIGH = 1
Ack = 0
Nak = 1
LCD_Pin = 2
LCD_Baud = 19_200
LCD_Lines = 4
'
VAR
Byte EEPROM_ID 'Device ID: 1010 MSBits
Word EEPROM_Address 'Holds EEPROM addresses used in
' Write/Read operations.
Byte Data 'Holds Data to be stored in the EEPROM
Byte AddrOrData 'Working byte for TX and RX routines
Byte Ack_I2C 'Ack bit from device
Byte Index 'Used to index LOOKUP
Byte ValueStored 'Holds the value to be written to EEPROM
Byte ValueRead 'Holds the value read from the EEPROM.
Word WriteReadFailures 'Holds the number of W/R failures
Word WR_Passes 'Holds the number of successful W/R passes.
Byte HiByte 'Holds the MSB of the EEPROM address
Byte LoByte 'Holds the LSB of the EEPROM address
'
OBJ
LCD : "Debug_Lcd"
BS2 : "BS2_Functions"
'
'START
'***********************************************************************
PUB Start
Initialization
Repeat EEPROM_Address FROM 0 to 4095
Repeat Index FROM 1 TO 4
ValueStored := LOOKUP(Index: $FF, $AA, $55, $00)
Data := ValueStored
Write_Byte
BS2.PAUSE(10) 'PROGRAM "MUST" PAUSE
Read_Byte
ValueRead := Data
DisplayResultsOnLCD
If WriteReadFailures == 0
LCD.GotoXY(0,3)
LCD.STR(STRING("ALL LOCATIONS OK "))
'
'INITIALIZATON
'**********************************************************************
PRI Initialization
EEPROM_ID := %1010_000_0 'Device ID: 1010 (MSBits)
LCD.Start(LCD_Pin, LCD_Baud, LCD_Lines)
BS2.Start(31,30)
LCD.Cls
LCD.Backlight(1)
LCD.GotoXY(0,0)
LCD.STR(STRING("Write:"))
LCD.GotoXY(10,0)
LCD.STR(STRING("Read:"))
LCD.GotoXY(0,1)
LCD.STR(STRING("W/R Failures:"))
LCD.GotoXY(0,2)
LCD.STR(STRING("W/R Passes:"))
'
'DISPLAY Results on LCD
'**********************************************************************
PRI DisplayResultsOnLCD
LCD.GotoXY(6,0)
LCD.DEC(ValueStored)
LCD.GotoXY(15,0)
LCD.DEC(ValueRead)
LCD.GotoXY(13,1)
If ValueStored <> ValueRead
WriteReadFailures := WriteReadFailures + 1
LCD.DEC(WriteReadFailures)
LCD.GotoXY(11,2)
If ValueStored == ValueRead
WR_Passes := WR_Passes + 1
LCD.DEC(WR_Passes)
'
'WRITE_Byte
'**********************************************************************
PRI Write_Byte
Start_I2C 'Send Start bit to EEPROM
AddrOrData := EEPROM_ID & %1111_111_0 'Set "0" WRITE bit
TX_Byte 'Send Write bit to EEPROM
IF (Ack_I2C == Nak) 'Wait until not busy
Write_Byte
HiByte := EEPROM_Address >> 8 'Get High address byte
AddrOrData := HiByte
TX_Byte 'Send High address byte to EEPROM
LoByte := EEPROM_Address 'Get Low address byte
AddrOrData := LoByte
TX_Byte 'Send Low address byte to EEPROM
AddrOrData := Data
TX_Byte 'Send Data byte to EEPROM
Stop_I2C 'Send Stop bit to EEPROM
'
'READ_Byte
'**********************************************************************
PRI Read_Byte
Start_I2C 'Send Start bit to EEPROM
AddrOrData := EEPROM_ID & %1111_111_0 'Set "0" WRITE bit
TX_Byte 'Send Write bit to EEPROM
IF (Ack_I2C == Nak) 'Wait until EEPROM not busy
Write_Byte
HiByte := EEPROM_Address >> 8 'Get High address byte
AddrOrData := HiByte
TX_Byte 'Send High address byte to EEPROM
LoByte := EEPROM_Address 'Get Low address byte
AddrOrData := LoByte
TX_Byte 'Send LoByte address byte to EEPROM
Start_I2C 'Prepare to READ EEPROM
AddrOrData := EEPROM_ID | %0000_000_1 'Set "1" READ bit.
TX_Byte 'Send READ bit to EEPROM
RX_Byte 'Get Data byte from EEPROM
Stop_I2C 'Send Stop bit to EEPROM
Data := AddrOrData 'Put data from EEPROM in Data
'
'RX_Byte
'**********************************************************************
PRI RX_Byte
Ack_I2C := Nak 'Nak = High
AddrOrData := BS2.SHIFTIN(SDA,SCL,BS2#MSBPRE,8) 'Get data from EEPROM
BS2.SHIFTOUT (SDA, SCL,Ack_I2C, BS2#LSBFIRST,1) 'Send ACK or NAK
'
'TX_Byte
'**********************************************************************
PRI TX_Byte
BS2.SHIFTOUT (SDA, SCL,AddrOrData, BS2#MSBFIRST,8)
Ack_I2C := BS2.SHIFTIN(SDA,SCL,BS2#MSBPRE,1)
'
'START
'**********************************************************************
PRI Start_I2C
DIRA[noparse][[/noparse]SCL] := OUT
OUTA[noparse][[/noparse]SCL] := LOW
DIRA[noparse][[/noparse]SDA] := OUT
OUTA[noparse][[/noparse]SDA] := HIGH
OUTA[noparse][[/noparse]SCL] := HIGH
OUTA[noparse][[/noparse]SDA] := LOW 'Sets SDA to Low to trigger START in I2C.
' START is triggered by transitioning SDA to a low
' while SCL is high.
OUTA[noparse][[/noparse]SCL] := LOW 'Get ready for address and data
'
'STOP
'**********************************************************************
PRI Stop_I2C
DIRA[noparse][[/noparse]SCL] := OUT
DIRA[noparse][[/noparse]SDA] := OUT
OUTA[noparse][[/noparse]SCL] := LOW
OUTA[noparse][[/noparse]SDA] := LOW
OUTA[noparse][[/noparse]SCL] := HIGH
OUTA[noparse][[/noparse]SDA] := HIGH 'Sets SDA High to trigger a STOP in I2C.
' STOP is triggered by transitioning SDA to a high
' while SCL is high.
OUTA[noparse][[/noparse]SCL] := LOW 'Get ready for address and data
'
'ADDITIONAL INFORMATION:
' -- This program is an adaptation of a PBASIC program written by Jon
' Williams.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ··
Post Edited (Dave Scanlan) : 6/1/2006 5:56:53 PM GMT
Dave: I love these demos, and all the comments. It does a great service to you for coding and answering the questions, as well as me, to see some of the things in actual working program. THanks again. I have some questions, but before I ask, I'll go do some more reading...
Fred
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
You guys should more consistent .
Example 21 connects SDA to pin A0 and SCL to pin 1.
The propkit and demo board uses A29 to SDA and pin 28 to pin A28.
What is going on??
I said:
You guys should more consistent .
Example 21 connects SDA to pin A0 and SCL to pin 1.
The propkit and demo board uses A29 to SDA and pin 28 to pin A28.
What is going on??
I should said
The propkit and demo board uses A29 to SDA and pin 28 to SCL.
Example 21 is showing how to hook up an external I2C memory (24LC32A) on A0, and A1 other than the memory the Propeller uses (24LC256) during power up on A28 and A29.
There is not an issue of inconsistency here.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Beau Schwabe
IC Layout Engineer
Parallax, Inc.
I am wondering if·YOU and·OTHERS would comment on my coding in the Start and Stop routines.
When I was coding these two algorithms using more traditional methods, I would occasionally get
Write/Read errors.·
I looked at the pulses generated and found both·fall and rise transitions of SDA while SLC was
high for a START. I decided to make sure that a START only had a fall transitions while SLC was
high; thus, I coded the algorithm as seen in the example.· I was concerned that the EEPROM
was occasionally not "seeing" the fall transition, but was "seeing" the rise transition.· Both transitions
were occurring close in time.
I have now done about 300,000 W/R combinations without an error.
BTW, your interaction on this forum is as good as it gets.· Thanks!
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ··
Post Edited (Dave Scanlan) : 5/31/2006 1:07:00 AM GMT
Also, thanks to you, El Paisa.· Your comment shows how important it is to
think of all the ways a reader could·interpret things.· I changed the
leading title to·include the words ·"External EEPROM" on Example 21.
Dave
Beau Schwabe (Parallax) said...
El Paisa,
Example 21 is showing how to hook up an external I2C memory (24LC32A) on A0, and A1 other than the memory the Propeller uses (24LC256) during power up on A28 and A29.
Dave:
This is what my questions were about...
I was sure there are timing specs needed for the I2C device between clock transactions.
I know I read someplace the max clock was something, 20 mhz coms to mind, but I could be wrong...
(I havent done the reading I said I was going to do before I posted my questions.)
But... if there's a max speed for the I2C bus, that would, in part, define the pulse width and length, right?
In your examples, you manually creating the clock levels, at the indicated code speed:
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
Here's a link to the pdf with the timings...· Now, please understand, most of this is in the BFZ (Beyond Fred Zone), but I real sure that the speed of the propellrer running at the coded speed is way to fast...
This could be part of the reason why you were getting errors without resulting to code you did.
My new hardware is due today (Yea!), and I'll be reading and doing your code for my stuff...
I have a long way to go on making it work, but I know when it's done, it will be worth it...
I agree with you about all the global vars and stuff, and even for ease or reading, well documented code, suchs as yours, it would stand to reason:
Make high & Low lever routines and pass params back and fourth.
It would make for taking your examples and using them directly.
Anyway, the heart of my questions are in the addressing of these eeproms:
My intent is to hang 4 additional eeproms off the propellers 28/29 I2C bus, and how I would address them vs addressing the root eeprom (the propellers eeprom)...
I can't tell by your example how you would change the address of the eeprom...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
Post Edited (Kaos Kidd) : 5/30/2006 4:34:56 PM GMT
If you noticed, I stated in Example 21 to use one EEPROM with this code.· I am concerned that
a short condition could occur on the bus with several devices.· Perhaps you should use
220 ohm resistors at· SLC and SDA to protect the Propeller from a bus short.
If Beau thinks this could be a problem, I will add these resistors to the schematic in Example 21.
What do you advise, Beau?
Dave
Kaos Kidd said...
Dave:
This is what my questions were about...
I was sure there are timing specs needed for the I2C device between clock transactions.
I know I read someplace the max clock was something, 20 mhz coms to mind, but I could be wrong...
(I havent done the reading I said I was going to do before I posted my questions.)
But... if there's a max speed for the I2C bus, that would, in part, define the pulse width and length, right?
In your examples, you manually creating the clock levels, at the indicated code speed:
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
Here's a link to the pdf with the timings...· Now, please understand, most of this is in the BFZ (Beyond Fred Zone), but I real sure that the speed of the propellrer running at the coded speed is way to fast...
This could be part of the reason why you were getting errors without resulting to code you did.
My new hardware is due today (Yea!), and I'll be reading and doing your code for my stuff...
I have a long way to go on making it work, but I know when it's done, it will be worth it...
I agree with you about all the global vars and stuff, and even for ease or reading, well documented code, suchs as yours, it would stand to reason:
Make high & Low lever routines and pass params back and fourth.
It would make for taking your examples and using them directly.
Anyway, the heart of my questions are in the addressing of these eeproms:
My intent is to hang 4 additional eeproms off the propellers 28/29 I2C bus, and how I would address them vs addressing the root eeprom (the propellers eeprom)...
I can't tell by your example how you would change the address of the eeprom...
You must select the bus addresses on your new EEPROMs through Spin code.
Example 21 hard-wires the address.· You may not use 000 as the bus address
for any of your added EEPROMS because it is being used by the Propeller EEPROM.
You must also use 29/28 for your SDA, and SCL, if you can access them.· If
not, perhaps·Parallax can suggest the best way to get at·them.
If you are building up your system from "scratch" this should not be
a problem: you will be able to access 29/28.
Since I·believe in Murphy's Law and since I have never done this,
please·take·my answer as a likely solution.· I try not to
recommend something unless I·have duplicated the situation.
Dave
Fred asked:
Anyway, the heart of my questions are in the addressing of these eeproms:
My intent is to hang 4 additional eeproms off the propellers 28/29 I2C bus, and how I would address them vs addressing the root eeprom (the propellers eeprom)...
I can't tell by your example how you would change the address of the eeprom...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ··
Post Edited (Dave Scanlan) : 5/31/2006 7:42:18 PM GMT
As a safety precaution that would probably be just fine. Although the 220 Ohm resistors are suggested to keep a 5V I/O minimized to about 20mA
if there is a problem (short). Keeping the same theme with 3.3V this would be equivalent to using a 160 Ohm resistor. Probably doesn't matter, a
220 Ohm resistor would functionally work just the same.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Two resistors R1 and R2 have been added to the schematic in Example21.· These are not necessary if
only one device is using the I2C bus.· These two resistors will compensate for any potential
bus short when using more than one device.
Dave
Beau Schwabe (Parallax) said...
Dave,
As a safety precaution that would probably be just fine. Although the 220 Ohm resistors are suggested to keep a 5V I/O minimized to about 20mA
if there is a problem (short). Keeping the same theme with 3.3V this would be equivalent to using a 160 Ohm resistor. Probably doesn't matter, a
220 Ohm resistor would functionally work just the same.
·······················RFID READER WITH VIDEO OUTPUT
''
'' Parallax RFID Reader
'' ____________________________________
'' | | R1: 1K Ohms
'' | | (Limits current to P1)
'' | ______________ |
'' | | | |
'' | | | |
'' | | | GND |• ------> Ground
'' | | | SOUT |• --R1--> P1-Demo Board Ver. C
'' | | _____________| ENABLE |• ------> P0-Demo Board Ver. C
'' | Vcc |• ------>+5V DC
'' | |
'' |____________________________________|
''
''
'' EXAMPLE 22
''
'' RFID READER WITH VIDEO OUTPUT
''****************************************************************
''IMPORTANT: Do not connect RFID +5 volt supply to the Propeller.
''****************************************************************
''WHAT'S NEW IN THIS EXAMPLE:
'' RFID READER
'' -- This device reads Radio Frequency ID tags.
'' SERIN_CHAR
'' -- SERIN_CHAR is a method used to input serial data from
'' RFID tags.
''****************************************************************
''DIFFICULTY LEVEL: Easy
''****************************************************************
''PURPOSE:
'' 1. Illustrates how to connect an RFID reader to the Propeller.
'' 2. Illustrates how to read and display RFID tag data using
'' the Parallax RFID reader.
''Submitted by Charlie Johnson, June 10, 2006, [noparse][[/noparse](C) C&C, Inc.]
''Modified, elaborated and posted by Dave Scanlan
''File: Example22_RFID_ReaderWithVideoOutput.spin
''****************************************************************
''CORRECT OUTPUT:
''
'' Video Display
'' ____________________________________
'' | RFID TAG VALUES IN HEX AND ASCII |
'' | XXXXXXXXXX |
'' | XXXXXXXXXXXXXXXXXXXXXXXX |
'' | |
'' | XXXXXXXXXX |
'' | XXXXXXXXXXXXXXXXXXXXXXXX |
'' | |
'' | |
'' | |
'' | |
'' | |
'' |____________________________________|
''
''
''****************************************************************
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
'
RX_Pin = 1
Enable_Pin = 0
Out = %1
Low = 0
High = 1
CR = 13
'
VAR
Byte Index
Byte Rx_Data[noparse][[/noparse]12] 'Holds RFID tag's 12-byte record
'
OBJ
VideoDisplay: "TV_Terminal" 'Declare VideoDisplay
BS2: "BS2_Functions" 'Declare BS2
'
PUB Start
DirA[noparse][[/noparse]Enable_Pin] := Out
VideoDisplay.Start(12) 'Instantiates VideoDisplay
SetScreenWhiteOnDarkBlue
BS2.Start(31, 30) 'Instantiates BS2
VideoDisplay.Str(String("RFID TAG VALUES IN HEX AND ASCII"))
VideoDisplay.Out(Cr)
'
Repeat
OutA[noparse][[/noparse]Enable_Pin] := Low 'Enables RFID
Index := 0
Repeat 12 'Gets 12 bytes from RFID reader
Rx_Data[noparse][[/noparse]index++] := BS2.SERIN_CHAR(RX_Pin, 2400, BS2#NInv, 8)
VideoDisplay.Str(@RX_data) 'Displays 10 RFID hex digits.
Index := 0
Repeat 12
VideoDisplay.dec(RX_Data[noparse][[/noparse]Index++]) 'Displays full RFID in ASCII
VideoDisplay.Out(Cr)
VideoDisplay.Out(Cr)
OutA[noparse][[/noparse]Enable_Pin] := High 'Disables RFID
BS2.PAUSE(1_000) 'Pause for 1 second
'
PRI SetScreenWhiteOnDarkBlue
VideoDisplay.Out(3)
VideoDisplay.Out(5)
''
'' ADDITIONAL INFORMATION
'' -- Be careful to not connect the RFID +5 volt supply to the Propeller
'' -- Thanks for the contributions of Marty Hebel to BS2_Functions.
'' -- Dave Scanlan does not support implanting RFID chips into humans.
'' -- This example is intended for educational use only.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ ··
Post Edited (Dave Scanlan) : 6/17/2006 8:23:43 PM GMT
Comments
·······················································
························································· EXAMPLE 19
·················· A/D CONVERSION WITH RESULTS DISPLAYED ON A VIDEO MONITOR··
···················································
······················································ FEW COMMENTS (EASIER TO READ)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Post Edited (Dave Scanlan) : 5/15/2006 2:04:01 AM GMT
Could you explain why the memory usage is so incredibly high??? That does not seem correct. I understand, though, that you state that you have not done extensive testing on this. Also, you may want to point out that this example almost seems like more of an example of using the serial in command, versus the A/D. You just motivated me to get my video out wired up. A/D is going to be my first real project. I'm also curious if you could provide an example using the discreet components version (non-dedicated peripherial ADC)?
Thanks,
-Parsko
The memory usage is high because of all the objects that are being used: (1) TV_Terminal, (2) TV, (3) Graphics,
·and (4) BS2_Functions. Of course, my own code adds to the usage.
SERIN·is for asynchronous communication.· This example uses SHIFTIN (synchronous communication).· As for using a capacitor and resistor for
the A/D process, I will do that if others want to see it too.· How about an example using flash A/D?· Flash is fun stuff, for me at least.
On second thought, I will do the cap/resistor A/D.· It is very easy to do with the objects that
are available.
I personally would not use this example for a commercial application until I had done about 25 measurements with calibrated
equipment to test this circuit.· I also found some noise on the data pin.· Perhaps, one should consider bypass caps and/or a
pullup resistor.
As for today, well, I've got to go to work in a few minutes.· I will try to answer any further question later today.
You are right...video is·fun stuff.· Isn't the Propeller great!!!!
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Post Edited (Dave Scanlan) : 5/9/2006 3:58:07 PM GMT
the line lcd.newline
in my library and examples (prop .95)
there isnt a lcd.newline procedure in my debug_lcd (updated 29 apr)
where can i get the latest and greatest ? the library still show ver 1.0
thanks
dan
· lcd.putc(13)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
I was in such a hurry to get to work, that I did not read your words carefully.· Now I see what you meant about serial-in.· Yes, the example
has a lot to do with processing data serially.· I was hoping that people would refer to PBASIC for this serial processing: SHIFTIN
Sorry about the NewLine method. It was in the object I used. Perhaps you are missing one of the supporting objects.
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
·'······································ EXAMPLE 20
'
'············ THIS EXAMPLE MEASURES THE CHARGE TIME OF A CAPACITOR,
'·················· USES TWO COGS, AND HAS VIDEO OUTPUT·····································
'
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Post Edited (Dave Scanlan) : 5/13/2006 7:11:27 PM GMT
· The PRO version $39.95 has a library function that may do the trick.
·http://www.foxitsoftware.com/
·Cheers Dennis
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
http://people.delphiforums.com/cocokiwi/Image/picture.jpg
Post Edited (cocokiwi) : 5/14/2006 8:25:24 AM GMT
I checked out the PDF software site below.··A person·certainly can't grip about the price.
Thanks,
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Dave, a small typo here. You have in the diagram above labele pin 7 of the ADC0831 as "A0" - it should be "A2" according to your actual code. "A0" is the Chip Select "CS". The problem is in both copies of the source code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
cheers ... brian riley, n1bq, underhill center, vermont
See the K107 Serial LCD Controller at
www.wulfden.org/k107/
The typing error has been fixed.
Thanks for spotting·the error·and for taking the time to report it.
Did you try out the example?
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Post Edited (Dave Scanlan) : 5/18/2006 4:05:45 AM GMT
IF YOU HAVE THE LATEST VERSION OF THE PROPELLER DEMO BOARD, CHANGES HAVE
BEEN MADE SO THAT THE KEYBOARD OBJECTS AND CODE ARE DIFFERENT FROM
THE EARILER VERSION OF THE DEMO BOARD.· THE EXAMPLES I WROTE ARE FOR THE
EARLIER VERSION.
THE EARLIER VERSION USES THIS OBJECT: Keyboard_iso.spin
THE LATEST VERSION USES THIS OBJECT: Keyboard.spin
See·this thread for changes and modifications: "keyboard_iso"
http://forums.parallax.com/showthread.php?p=587529
SORRY ABOUT THE CONFUSION.· I JUST FOUND OUT ABOUT THESE CHANGES TODAY, MAY 19, 2006.
If I had the latest version of the demo board, I would·post Examples 8 and 18 using the·code for this demo board version.·I can't post code unless I can test it.
The code I posted works perfectly with the earlier demo boards.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Post Edited (Dave Scanlan) : 5/19/2006 5:11:55 PM GMT
···········EXAMPLE 21
···W/R TO AN EXTERNAL EEPROM(24LC32A) USING I2C
·AND DISPLAY RESULT ON AN LCD·
·········································
··································
······························· FEWER COMMENTS (EASIER TO READ)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Post Edited (Dave Scanlan) : 6/1/2006 5:56:53 PM GMT
Fred
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
·
Example 21 connects SDA to pin A0 and SCL to pin 1.
The propkit and demo board uses A29 to SDA and pin 28 to pin A28.
What is going on??
You guys should more consistent .
Example 21 connects SDA to pin A0 and SCL to pin 1.
The propkit and demo board uses A29 to SDA and pin 28 to pin A28.
What is going on??
I should said
The propkit and demo board uses A29 to SDA and pin 28 to SCL.
Example 21 is showing how to hook up an external I2C memory (24LC32A) on A0, and A1 other than the memory the Propeller uses (24LC256) during power up on A28 and A29.
There is not an issue of inconsistency here.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
I understand now.
Thanks for your words of support.
I am wondering if·YOU and·OTHERS would comment on my coding in the Start and Stop routines.
When I was coding these two algorithms using more traditional methods, I would occasionally get
Write/Read errors.·
I looked at the pulses generated and found both·fall and rise transitions of SDA while SLC was
high for a START. I decided to make sure that a START only had a fall transitions while SLC was
high; thus, I coded the algorithm as seen in the example.· I was concerned that the EEPROM
was occasionally not "seeing" the fall transition, but was "seeing" the rise transition.· Both transitions
were occurring close in time.
I have now done about 300,000 W/R combinations without an error.
BTW, your interaction on this forum is as good as it gets.· Thanks!
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Post Edited (Dave Scanlan) : 5/31/2006 1:07:00 AM GMT
Also, thanks to you, El Paisa.· Your comment shows how important it is to
think of all the ways a reader could·interpret things.· I changed the
leading title to·include the words ·"External EEPROM" on Example 21.
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
This is what my questions were about...
I was sure there are timing specs needed for the I2C device between clock transactions.
I know I read someplace the max clock was something, 20 mhz coms to mind, but I could be wrong...
(I havent done the reading I said I was going to do before I posted my questions.)
But... if there's a max speed for the I2C bus, that would, in part, define the pulse width and length, right?
In your examples, you manually creating the clock levels, at the indicated code speed:
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
Here's a link to the pdf with the timings...· Now, please understand, most of this is in the BFZ (Beyond Fred Zone), but I real sure that the speed of the propellrer running at the coded speed is way to fast...
http://www.sparkfun.com/datasheets/IC/24LC256.pdf
(BTW: I ordered 4 of these exact chips... )
This could be part of the reason why you were getting errors without resulting to code you did.
My new hardware is due today (Yea!), and I'll be reading and doing your code for my stuff...
I have a long way to go on making it work, but I know when it's done, it will be worth it...
I agree with you about all the global vars and stuff, and even for ease or reading, well documented code, suchs as yours, it would stand to reason:
Make high & Low lever routines and pass params back and fourth.
It would make for taking your examples and using them directly.
Anyway, the heart of my questions are in the addressing of these eeproms:
My intent is to hang 4 additional eeproms off the propellers 28/29 I2C bus, and how I would address them vs addressing the root eeprom (the propellers eeprom)...
I can't tell by your example how you would change the address of the eeprom...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Just tossing my two bits worth into the bit bucket
KK
Post Edited (Kaos Kidd) : 5/30/2006 4:34:56 PM GMT
Thanks for your input.
If you noticed, I stated in Example 21 to use one EEPROM with this code.· I am concerned that
a short condition could occur on the bus with several devices.· Perhaps you should use
220 ohm resistors at· SLC and SDA to protect the Propeller from a bus short.
If Beau thinks this could be a problem, I will add these resistors to the schematic in Example 21.
What do you advise, Beau?
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
You must select the bus addresses on your new EEPROMs through Spin code.
Example 21 hard-wires the address.· You may not use 000 as the bus address
for any of your added EEPROMS because it is being used by the Propeller EEPROM.
You must also use 29/28 for your SDA, and SCL, if you can access them.· If
not, perhaps·Parallax can suggest the best way to get at·them.
If you are building up your system from "scratch" this should not be
a problem: you will be able to access 29/28.
Since I·believe in Murphy's Law and since I have never done this,
please·take·my answer as a likely solution.· I try not to
recommend something unless I·have duplicated the situation.
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Post Edited (Dave Scanlan) : 5/31/2006 7:42:18 PM GMT
As a safety precaution that would probably be just fine. Although the 220 Ohm resistors are suggested to keep a 5V I/O minimized to about 20mA
if there is a problem (short). Keeping the same theme with 3.3V this would be equivalent to using a 160 Ohm resistor. Probably doesn't matter, a
220 Ohm resistor would functionally work just the same.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Two resistors R1 and R2 have been added to the schematic in Example21.· These are not necessary if
only one device is using the I2C bus.· These two resistors will compensate for any potential
bus short when using more than one device.
Dave
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
······································
··································· EXAMPLE 22
······················· RFID READER WITH VIDEO OUTPUT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
Post Edited (Dave Scanlan) : 6/17/2006 8:23:43 PM GMT
0415146F24
10485249534952347050
Sid
If you ran the exact same code as in Example 22, your output "should" have displayed the tag values correctly.
I have tested this code repeatedly using 15 different RFID tags.· I used both the new and old versions of the demo boards.
QUESTION: IF OTHERS HAVE RUN THIS CODE, DID·CODE RUN CORRECTLY OR INCORRECTLY?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
··
have a blue background!
I ran about 10 tags and they all displayed the numbers correctly with both
programs.·
Sid
VideoDisplay.dec(RX_Data[noparse][[/noparse]Index++])
to read
VideoDisplay.bin(RX_Data,8)
All I got was·twelve 0000 1010 binaries.· What am I not doing?
Sid