How about Johnny Mac's code for the 320x on the OBEX? the 320x series is a 12 bit A/D but that could be changed to 16 in the code. Rest of the code is probably similar and you might be able to figure out the rest from it.
The parts couldn't be more different. The 320x family is SPI interfaced, the 3428 is I2C. The 320x's engine converts as you read the data. The 3428 requires that you wait until a sample's conversion is ready.
The Propeller Board of Education uses an I2C ADC chip (AD7993 (I think)). An object written for the AD7993 could be used as a starting point for an object to interface with the MCP3428.
From looking at the datasheets of the two chips, it looks like they share a basic communication protocol (I suppose most I2C chips do). I don't think it would be trivial to convert an object written for the AD7993 to work with the MCP3428 but it might be easier than starting from scratch.
I have been trying to figure this out to no avail. I have this bee hive monitor put together but the resolution of the MCP3208 is inadequate for the scale. I need this to work so I don't have to tear open the hive all the time, I can just read the weight and know its collection time. It also lets me track the overall health of the hive ect. I see others are interested in code for this as well, Could someone please write this code.
Thanks
What scale are you using,
what weight range are you measuring,
what is meaningful and relevant resolution in grams or Kg or whatever unit,
at what time span and intervals do you need to acquire this, etc?
Pictures of your hive and existing setup may help as well.
Enquiring minds want to know...
I have been trying to figure this out to no avail. I have this bee hive monitor put together but the resolution of the MCP3208 is inadequate for the scale. I need this to work so I don't have to tear open the hive all the time, I can just read the weight and know its collection time. It also lets me track the overall health of the hive ect. I see others are interested in code for this as well, Could someone please write this code.
Thanks
You say you've been trying to figure this out but if that were so then you would have some code that you could post so others could "help" you in the proper sense. There is nothing magical about the MCP3428 or any other I2C chip, they are just have a bunch of registers and use the standard I2C bus to access those registers. Seeing the OBEX is overflowing with I2C drivers I wonder why you haven't used one of those as a starting point, modified the device address, then had a go at reading the registers at least? The configurations register is there to write to, just waiting to be written to, just as the ADC conversion data is waiting to be read. just do it.
As Peter correctly points out, with an I2C object (I used my own) and a bit of code it's pretty easy to interface with this device. I found a Schmarschmino library for the MCP342x and decided -- for those that might make the switch -- to pattern my object after that.
Again, I don't have a device to test with so this code is, as the MIT license states, provided "as is" with no guarantees. Should you decide to modify, "improve," or "enhance" this object, you must remove all traces of my name before re-posting.
11 MAY 2015 : Code updated per note from Dave Hein (post #14) -- directly accounts for both address pins floating (was indirect before). 11 MAY 2015 : Added sample size constants and ready() method 12 MAY 2015 : Changed adc method names to prevent confusion with generic I2C methods; changed interface to set_channel(); added read_mv() method
Thank you JonnyMac and all.
I'm suspecting the chip is bad as it displays 255 no mater what.
Hence my frustration with this. I will try remounting a chip.
Thank you JonnyMac and all.
I'm suspecting the chip is bad as it displays 255 no mater what.
Hence my frustration with this. I will try remounting a chip.
You want help but at what point do you decide "no matter what"? Is it simply by pushing the button again and again? Load my Explorer (see sig) into your Prop and connect to it via a terminal at 115200k baud.On startup it will list details about the hardware and also the whatever it finds on the I2C bus which should then display device $D1 (reading %1101000), with 12-bits of ADC data by default as the high byte, low byte, configurations byte etc. This is called "troubleshooting" and through the process of elimination you can work what it must be by what it isn't.
CelticLord, if you are receiving 255 from the chip you may not be addressing it correctly. How do you have the Adr0 and Adr1 pins wired? If they are floating, and you are passing (2, 2) to Jon's start routine it will not work. The startx routine is missing the case for (2, 2). Use the parameters (0, 0) instead since this maps to the same address.
Another possible route could be to start with the code for the MCP3202 (available on the ObEx in Spin) and try to alter from there. I'm not familiar with the specific differences between the two chips, but they're in the same family at least so the conversion shouldn't be too awful.
Another possible route could be to start with the code for the MCP3202 (available on the ObEx in Spin) and try to alter from there. I'm not familiar with the specific differences between the two chips, but they're in the same family at least so the conversion shouldn't be too awful.
Take a look at post #3. The 320x is SPI, the sensor in question is I2C.
CelticLord, if you are receiving 255 from the chip you may not be addressing it correctly. How do you have the Adr0 and Adr1 pins wired? If they are floating, and you are passing (2, 2) to Jon's start routine it will not work. The startx routine is missing the case for (2, 2). Use the parameters (0, 0) instead since this maps to the same address.
The original code defaulted to %000 with both inputs floating. In order to prevent confusion, I've added both pins floating to the case statement. New code is posted above.
Yes, you are correct, the original code did handle the floating case by initializing devid to WR_342x. So now I'm curious why it didn't work for CelticLoad. CelticLord, can you post your code?
OK
It was the chip but not that it was bad but the jump wires were to messy (long) probably inducing resistance, cross-talk, ect....
I rewired it and am getting readings, but all three reads are the same value. The photo transistor changes the value as I illuminate it.
**I am using a photo transistor for testing only**
I am grounding the A0 & A1 for an address of 1101000
Here is the code im using with JonnyMac's Driver from this post.
OK
It was the chip but not that it was bad but the jump wires were to messy (long) ect..
I rewired it and am getting readings, but all three reads are the same value. The photo transistor changes the value as I illuminate it.
**I am using a photo transistor for testing only**
Here is the code im using with JonnyMac's Driver from this post.
pub read | raw, cfg
'' Read result from previous conversion
'' -- setup by set_channel or write() to configuration register
'' -- application must correct sign of long value
'' * sign position based on bits used in reading
raw := 0
i2c.start
i2c.write(devid | 1) ' read mode
raw.byte[1] := i2c.read(i2c#ACK) ' high byte of volts
raw.byte[0] := i2c.read(i2c#ACK) ' low byte of volts
cfg := i2c.read(i2c#NAK) ' configuration bits
i2c.stop
return raw
Is returning "raw" which is both the high and low byte
Then look at the procedure raw2mv in the code to convert this reading to millivolts depending on bits and gains settings.
Ok The problem was me thinking I was reading back 3 bytes High byte Low byte and a status byte why, don't ask I feel like an idot lol.
I changed the variable recieving the read to a WORD and it works perfect.
I understand this a little better. Thank you all for the help, I really needed it and can now get this on a pcb and into my hive.
Jon, Peter Jakacki , and Duane Thank you very much for the driver and advice.
Ok The problem was me thinking I was reading back 3 bytes High byte Low byte and a status byte why, don't ask I feel like an idot lol.
Nobody is asking you to feel like an idiot, but for myself (and perhaps others that provide code "on demand" for forum members) I will ask that you do me the courtesy to read the code I've written for you. The comments for that method state that it returns the result of the last conversion, and the method is less than 10 lines of code -- one can easily see three calls to i2c.read().
pub read | raw, cfg
'' Read result from previous conversion
'' -- setup by set_channel or write() to configuration register
'' -- application must correct sign of long value
'' * sign position based on bits used in reading
raw := 0
i2c.start
i2c.write(devid | 1) ' read mode
[COLOR="#FF0000"]raw.byte[1] := i2c.read(i2c#ACK) ' high byte of volts
raw.byte[0] := i2c.read(i2c#ACK) ' low byte of volts
cfgbits := i2c.read(i2c#NAK) ' configuration bits[/color]
i2c.stop
return raw ' return raw reading
I changed the variable recieving the read to a WORD and it works perfect.
You really should use a LONG. It is the native type for the Propeller (hence fastest, and uses the least amount of code), and allows for sign bit correction and straightforward use of signed value. There is a method in the object called raw2mv() that converts the raw reading to millivolts. That method needs to know what the bit size and gain factor settings are. It returns and signed LONG.
I'm glad you got things working. Good luck with your hive project. I have a friend in the movie business (she's a costumer) who keeps bees and supplies me and other friends with raw honey.
I don't tend to post "fresh" code unless requested by another forum member -- my preference is to wring-out and object with a few applications before sharing. As that was not the case here I have made changes based on responses to the object.
That latest is attached to post #11 (where the original code was); it has several changes.
-- interface to set_channel() no longer assumes 16-bit sample size; sample size is now a parameter (use constants SAMP_12, SAMP_14, and SAMP_16)
-- the write() method has been renamed write_cfg() to prevent confusion with generic I2C method
-- the read() method has been renamed read_raw() to prevent confusion with generic I2C method
-- added read_mv() method to simplify use
-- updated comments and added code examples where helpful
Comments
http://obex.parallax.com/object/315
From looking at the datasheets of the two chips, it looks like they share a basic communication protocol (I suppose most I2C chips do). I don't think it would be trivial to convert an object written for the AD7993 to work with the MCP3428 but it might be easier than starting from scratch.
Thanks
what weight range are you measuring,
what is meaningful and relevant resolution in grams or Kg or whatever unit,
at what time span and intervals do you need to acquire this, etc?
Pictures of your hive and existing setup may help as well.
Enquiring minds want to know...
-Mike
"Knowledge Is Good." - Emil Faber
I'll have a crack after "Game of Thrones" -- but I don't have one, so I cannot test it.
You say you've been trying to figure this out but if that were so then you would have some code that you could post so others could "help" you in the proper sense. There is nothing magical about the MCP3428 or any other I2C chip, they are just have a bunch of registers and use the standard I2C bus to access those registers. Seeing the OBEX is overflowing with I2C drivers I wonder why you haven't used one of those as a starting point, modified the device address, then had a go at reading the registers at least? The configurations register is there to write to, just waiting to be written to, just as the ADC conversion data is waiting to be read. just do it.
I2C START
WRITE DEVICE ADDRESS with R/W low (writing)
WRITE CONFIGURATION
I2CSTOP
I2CSTART
WRITE DEVICE ADDRESS with R/W high (reading)
READ 2 BYTES OF DATA + OPT CONFIGURATION
I2CSTOP
Isn't that simple???
Again, I don't have a device to test with so this code is, as the MIT license states, provided "as is" with no guarantees. Should you decide to modify, "improve," or "enhance" this object, you must remove all traces of my name before re-posting.
11 MAY 2015 : Code updated per note from Dave Hein (post #14) -- directly accounts for both address pins floating (was indirect before).
11 MAY 2015 : Added sample size constants and ready() method
12 MAY 2015 : Changed adc method names to prevent confusion with generic I2C methods; changed interface to set_channel(); added read_mv() method
I'm suspecting the chip is bad as it displays 255 no mater what.
Hence my frustration with this. I will try remounting a chip.
You want help but at what point do you decide "no matter what"? Is it simply by pushing the button again and again? Load my Explorer (see sig) into your Prop and connect to it via a terminal at 115200k baud.On startup it will list details about the hardware and also the whatever it finds on the I2C bus which should then display device $D1 (reading %1101000), with 12-bits of ADC data by default as the high byte, low byte, configurations byte etc. This is called "troubleshooting" and through the process of elimination you can work what it must be by what it isn't.
Take a look at post #3. The 320x is SPI, the sensor in question is I2C.
The original code defaulted to %000 with both inputs floating. In order to prevent confusion, I've added both pins floating to the case statement. New code is posted above.
It was the chip but not that it was bad but the jump wires were to messy (long) probably inducing resistance, cross-talk, ect....
I rewired it and am getting readings, but all three reads are the same value. The photo transistor changes the value as I illuminate it.
**I am using a photo transistor for testing only**
I am grounding the A0 & A1 for an address of 1101000
Here is the code im using with JonnyMac's Driver from this post.
What am I doing wrong in the code for all 3 reads to be the same?
Is returning "raw" which is both the high and low byte
Then look at the procedure raw2mv in the code to convert this reading to millivolts depending on bits and gains settings.
I updated the code to add a method called ready() -- this will return true when the ready bit is clear.
FTR: My name is Jon.
I changed the variable recieving the read to a WORD and it works perfect.
I understand this a little better. Thank you all for the help, I really needed it and can now get this on a pcb and into my hive.
Jon, Peter Jakacki , and Duane Thank you very much for the driver and advice.
Nobody is asking you to feel like an idiot, but for myself (and perhaps others that provide code "on demand" for forum members) I will ask that you do me the courtesy to read the code I've written for you. The comments for that method state that it returns the result of the last conversion, and the method is less than 10 lines of code -- one can easily see three calls to i2c.read().
You really should use a LONG. It is the native type for the Propeller (hence fastest, and uses the least amount of code), and allows for sign bit correction and straightforward use of signed value. There is a method in the object called raw2mv() that converts the raw reading to millivolts. That method needs to know what the bit size and gain factor settings are. It returns and signed LONG.
I'm glad you got things working. Good luck with your hive project. I have a friend in the movie business (she's a costumer) who keeps bees and supplies me and other friends with raw honey.
That latest is attached to post #11 (where the original code was); it has several changes.
-- interface to set_channel() no longer assumes 16-bit sample size; sample size is now a parameter (use constants SAMP_12, SAMP_14, and SAMP_16)
-- the write() method has been renamed write_cfg() to prevent confusion with generic I2C method
-- the read() method has been renamed read_raw() to prevent confusion with generic I2C method
-- added read_mv() method to simplify use
-- updated comments and added code examples where helpful