| Swordfish Tutorial - MCP3001 (External ADC) |
|
|
| Saturday, 04 April 2009 09:07 | |
|
The MCP3001 is a high speed 10 Bit Analogue to Digital converter. It utilizes an SPI interface, and is very easy to interface with. The output of the MCP3001 is the "hard" part to take into account. Well that and the fact that I have made the following program accurate too 3 decimal places without the use of Floats. The output of the MCP3001 Would look something like this; 0011 1110 0100 0010 0111 1100
The first two bits are blank - its the converting time. The following 10 Bits is the ADC result, MSB first. And The next 10 Bits are the ADC result LSB first. The last two are always 00. With that said, lets move on. The hardware SPI could be used, I just wanted to experiment with the Software SPI (SSPI) for this example. There are 3 Bytes of information to receive all up, so I can place that into a couple of buffers to be analysed afterwards. Now the next issue is how to extract the 10 Bit result efficiently. To do this, I simply juggle the buffers bytes around a bit Result.Byte1 = Buffer_1 >> 4 Result.Byte0 = (Buffer_2 >> 4) Or (Buffer_1 << 4)
The above will put the 10 Bit result into the variable "Result". Now that we know what the 10 Bit result is, its time to calculate what the answer is in volts; Result = Result * 5000 / 1023
As I am not using Floats with this example, I'm using a scale of 1000 to ensure I don't "drop" the decimal places from my equation. Another point here is to always multiply before dividing - this will keep you results as accurate as possible. 1023 is the greatest value of a 10 Bit number, and 5 volts is the reference voltage. With that in mind, the math of the equation is fairly straight forward. Now to display the answer on the LCD. LCD.WriteAt(1, 10, DecToStr(Digit(Result,4)),".",DecToStr(Digit(Result,3))) LCD.WriteAt(1, 13, DecToStr(Digit(Result,2)),DecToStr(Digit(Result,1)))
The modifier DecToStr turns the numerical values into ASCII codes to be displayed on the LCD. However the Digit command will extract the numerical value for each place in a number. Eg, Digit(123, 3) will return 1 and Digit(123, 1) will return 3. Remembering that the result had a factor of 1000, now I can build the answer, so that it appears to have 3 decimal places.
Device = 18F452 Clock = 20 #option LCD_DATA = PORTD.4 #option LCD_RS = PORTD.2 #option LCD_EN = PORTD.3 #option SSPI_SCK = PORTC.3 #option SSPI_SDI = PORTC.4 Include "system.bas" Include "SSPI.bas" Include "convert.bas" Include "Utils.bas" Include "LCD.bas" Dim Buffer_1 As Byte Dim Buffer_2 As Byte Dim Buffer_3 As Byte Dim Result As LongInt Dim Last_Result As LongInt Dim CS As PORTC.2 Sub ADC_Convert() CS = 0 Buffer_1 = SSPI.ReadByte Buffer_2 = SSPI.ReadByte Buffer_3 = SSPI.ReadByte Result.Byte1 = Buffer_1 >> 4 Result.Byte0 = (Buffer_2 >> 4) Or (Buffer_1 << 4) CS = 1 End Sub // Start Of Program... SetAllDigital ' Make all pins digital DelayMS(150) ' Allow LCD to start up LCD.Cls ' Clear the screen TRISD.1 = 0 SSPI.Initialize ' Initialize the software SPI SSPI.SetClock(spiIdleLow) ' Set the default clock state High(CS) ' Make CS an output and set it high LCD.WriteAt(1, 1, "Result = ") ' This info only needs to be sent once While True ' Create an infinite loop ADC_Convert ' Get the new ADC sample Result = Result * 5000 / 1023 ' Change the 10 Bit result to Volts If Last_Result Result Then ' See if the data has changed LCD.WriteAt(1, 10, DecToStr(Digit(Result,4)),".",DecToStr(Digit(Result,3))) LCD.WriteAt(1, 13, DecToStr(Digit(Result,2)),DecToStr(Digit(Result,1))) Last_Result = Result ' Display the new info, and update the last result EndIf Wend
|
|
| Last Updated ( Saturday, 18 April 2009 07:12 ) |
Whos Online
- andyo
- MrDEB
Forum Activity
LCD / 18F1320 - mrdeb Saturday, 20 March 2010 06:21 - [3 replies]
A 'throw-away" PIC board - mrdeb Thursday, 18 March 2010 06:19 - [32 replies]
Credit Where Credit's Due - jon chandler Tuesday, 16 March 2010 12:01 - [9 replies]
Marching LEDs - mrdeb Saturday, 13 March 2010 22:54 - [7 replies]
USB 8 Channel Servo Controller - andyo Saturday, 13 March 2010 01:19 - [2 replies]
Dedicated Servo Controller - graham Friday, 12 March 2010 17:58 - [0 replies]
Must have....delta temperature glowies! - graham Friday, 12 March 2010 17:31 - [3 replies]




Nice. The TAP-28 boards are looking good. When I've had a buzzi...
The author (Hop) suggests to "set the target PIC's configuratio...
Graham, Thanks for fixing the spacing on the array. This is how i...
Thanks Graham, It is a problem with Flowcode because the demo wa...
Looks like you've pretty much solved every minor issue that was enc...
The low-cost servo does have one other feature. The origina...
I am not familiar with flowcode, though did you try powering the bo...
Hello there, I am still trying to get the LCD to work but I am pro...