Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Micromite MK2:MCP342x i2c ADCs
Author | Message | ||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9122 |
Another favorite range of chips. The MCP3424 is a 4 channel 18 bit ADC with programmable gain (1,2,4,8) and 4 possible i2c addresses allowing up to 16 channels of high resolution conversion (1 LSB=0.015625 millivolts at a gain of 8). The MCP3423 has 2 channels and 4 possible i2c addresses. The MCP3422 is 2 channel on a single fixed i2c address and the MCP3421 is single channel single address. The base address conflicts with DS1307 beware! The MCP3424 is available as a breakout from Jeelabs if you ignore their strange labeling of the i2c signals, 3424 and 3422 are available as SOIC so easy to solder to a PDIP adapter. The thing I really like about these chips is the programmable gain which allows them to be used for things like strain gauges and thermocouples with no addition signal conditioning. I'll post full thermocouple conversion for K-type thermocouples including cold junction compensation using a DS18B20 in a subsequent thread. In the example code I use a DAC to generate a test voltage and then convert it at various gains and number of bits. Output on my test rig as follows: 12 bit conversion, Gain = 1 Voltage = 0.174 14 bit conversion, Gain = 1 Voltage = 0.17375 16 bit conversion, Gain = 1 Voltage = 0.173813 18 bit conversion, Gain = 1 Voltage = 0.173813 12 bit conversion, Gain = 2 Voltage = 0.174 14 bit conversion, Gain = 2 Voltage = 0.173875 16 bit conversion, Gain = 2 Voltage = 0.173906 18 bit conversion, Gain = 2 Voltage = 0.173898 12 bit conversion, Gain = 4 Voltage = 0.17375 14 bit conversion, Gain = 4 Voltage = 0.173813 16 bit conversion, Gain = 4 Voltage = 0.0434531 18 bit conversion, Gain = 4 Voltage = 0.173824 12 bit conversion, Gain = 8 Voltage = 0.173625 14 bit conversion, Gain = 8 Voltage = 0.173625 16 bit conversion, Gain = 8 Voltage = 0.173625 18 bit conversion, Gain = 8 Voltage = 0.173621 ' MCP 342x 18bit Multi-channel ADC with I2C interface demo program ' cpu 48 option explicit option default FLOAT const ADCi2c = &B1101000 ' set to match your hardware const ADCBits12=&B10000000 const ADCBits14=&B10000100 const ADCBits16=&B10001000 const ADCBits18=&B10001100 const ADCbits12timeout= 2 'number of 5 msec loops to wait for ADC conversion before giving up const ADCbits14timeout= 5 const ADCbits16timeout= 15 const ADCbits18timeout= 60 const ADCBits12size= 0.001 const ADCBits14size= 0.00025 const ADCBits16size= 0.0000625 const ADCBits18size= 0.000015625 'max voltages ' gain 1 = +/- 2.048V ' gain 2 = +/- 1.024V ' gain 4 = +/- 0.512V ' gain 8 = +/- 0.256V const signed=1 const unsigned=0 ' Pin assignments ' ' DAC pin 1 = VDD const cs=23 'DAC pin 2 connected to digital output on micromite ' Pin 25 = SCK : DAC Pin 3 ' Pin 3 = SDI : DAC Pin 4 const ldac=24 ' DAC Pin 5 connected to digital output on micromite const voutb=7 ' DAC Pin 6 connected to analogue input on micromite ' DAC Pin 7 = GND const vouta=6 ' DAC Pin 8 connected to analogue input on micromite ' 'Pin use ' setpin cs, dout setpin ldac, dout setpin vouta,ain setpin voutb,ain ' dim voltage dim i as integer,gain as integer ' INIT: pin(cs)=1 'set chip select inactive pin(ldac)=1 'set ldac inactive spi open 5000000,0,16 '5 MEG, 16 bit transfer, CLK active high, data on leading edge i2c open 400,1000 ' MAIN: voltage=setdac(0,1,0.173) for i=0 to 3 gain=1<<i print "12 bit conversion, Gain = ",gain," Voltage = ",readadc(0,gain,12) print "14 bit conversion, Gain = ",gain," Voltage = ",readadc(0,gain,14) print "16 bit conversion, Gain = ",gain," Voltage = ",readadc(0,gain,16) print "18 bit conversion, Gain = ",gain," Voltage = ",readadc(0,gain,18) next i end ' function readadc(channel as integer, adcgain as integer, bits as integer) ' config byte for chip is: ' bits 0 and 1 - Gain 1,2,4,8 ' bits 2 and 3 - # of bits 12,14,16,18; 240,60,15,3.75 samples per second respectively ' bit 4 - 0=one-shot conversion ; 1=continous; we will always use 0 to allow changes to config e.g. which channel ' bits 5 and 6 - channel number 0-3 ' bit 7 - set to start conversion, wait for clear to indicate conversion end ' max voltages ' gain 1 = +/- 2.048V with both vin- and vin+ between VSS and VDD ' gain 2 = +/- 1.024V ' gain 4 = +/- 0.512V ' gain 8 = +/- 0.256V local channelmask as integer,gainmask as integer, scratch as integer, timeout as integer local configbyte as integer, ADCreading as integer local ADCret$ length 4 local bitsize as float scratch=adcgain gainmask=0 do while not(scratch and 1) scratch=scratch>>1 gainmask=gainmask+1 loop scratch=((bits-12)\2) + 1 if channel<0 or channel>3 or gainmask<0 or gainmask>3 or scratch<1 or scratch>4 then readadc=100 'impossible value exit function endif on scratch goto bit12,bit14,bit16,bit18 bit12: timeout=ADCbits12timeout configbyte=ADCbits12 bitsize=ADCbits12size goto addgainbits bit14: timeout=ADCbits14timeout configbyte=ADCbits14 bitsize=ADCbits14size goto addgainbits bit16: timeout=ADCbits16timeout configbyte=ADCbits16 bitsize=ADCbits16size goto addgainbits bit18: timeout=ADCbits18timeout configbyte=ADCbits18 bitsize=ADCbits18size addgainbits: configbyte=configbyte or gainmask channelmask=channel << 5 configbyte=configbyte or channelmask i2c write ADCi2c, 0,1,configbyte do pause 5 i2c read ADCi2c, 0,4,ADCret$ scratch =asc(right$(ADCret$,1)) AND &B10000000 timeout=timeout-1 loop until (scratch=0) or (timeout=0) if timeout <>0 then if bits=18 then adcreading=intconv(left$(ADCret$,3),signed) else adcreading=intconv(left$(ADCret$,2),signed) endif readadc=adcreading*bitsize/adcgain else readadc=0 endif' end function ' ' Function to set output on one of the DAC channels ' function setdac (DAC as integer, dacgain as integer, volts) local dacdata as integer,FuncRet as integer dacdata=cint(volts * 2000 / dacgain) if dacdata>4095 or dacdata<0 or DAC<0 or DAC>1 or dacgain<1 or dacgain>2 then setDAC=0 exit function endif setdac= dacdata /2000 * dacgain if DAC=0 then dacdata=dacdata or &B0011000000000000 else dacdata=dacdata OR &B1011000000000000 endif if dacgain=2 then dacdata=dacdata and &B1101111111111111 'clear bit 13 to set gain of 2 pin(cs)=0 'enable data reception FuncRet=spi(dacdata) 'output the control bits and the data pin(cs)=1 'disable data reception pulse ldac,0.005 end function ' CFunction intconv 00000000 27bdfff8 00001021 00001821 afa20000 afa30004 90880000 1900000b 01003821 2503ffff 03a31821 24020001 00823021 90c60000 a0660000 24420001 00e2302a 10c0fffa 2463ffff 8ca20000 1040000d 03a81021 9042ffff 30420080 10400009 29020008 10400007 03a81021 27a40008 2403ffff a0430000 24420001 5444fffe a0430000 8fa20000 8fa30004 03e00008 27bd0008 End CFunction |
||||
twofingers Guru Joined: 02/06/2014 Location: GermanyPosts: 1243 |
Hi very impressive and useful! Thanks! Regards Michael causality ≠ correlation ≠ coincidence |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9122 |
Got the resolution wrong in my note above, 1 LSB @ 18 bits and gain 8 = 1.953125 MICRO volts |
||||
Plasmamac Guru Joined: 31/01/2019 Location: GermanyPosts: 554 |
Will this work on picomite ? I like to use Picomite wlan to share the values over udp . Thx Plasma |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3194 |
No, it uses a CFunction. CFunctions contain binary code compiled for a specific CPU. Geoff Graham - http://geoffg.net |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6099 |
The CFunction only converts the input data so it would be easy enough to do that in Basic. The pico doesn't have the DAC so you would have to organize a test voltage differently. The chip is I2C so that part is OK. Jim VK7JH MMedit MMBasic Help |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3802 |
The logic would convert to Basic and the pico is fast so maybe no CSUB (equivalent of the CFunction) would be needed. John |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9122 |
Intconv can be replaced by the inbuilt function str2bin |
||||
Plasmamac Guru Joined: 31/01/2019 Location: GermanyPosts: 554 |
What DAC are you using here ? Only for interest? Thx Plasma |
||||
Print this page |