EDIT: The Maple Leaf has two ADCs which can be simultaniously used. As far as I can tell this is the closest thing to an Arduino board with multiple ADCs.
OLD MESSAGE:
Hi Everyone
Can anyone recomend a arduino-clone or other microcontroller which has several A/D converters? I have seen that some of the netduinos have multiple AD converters, but I would love to use a board which I can program using the regular Arduino Language.
Any recomandations?
Thanks
P.
edit: the netduinos have a "One 8-channel 10-bit Analog-to-Digital Converter, Four Channels Multiplexed with Digital I/Os" I misinterpreted that. It actually simply multiplexes one a/d converter as well... http://www.atmel.com/dyn/resources/prod_documents/doc6120.pdf
edit2: The chip used in the Maple by LeafLab (STM32 F103RB) has 2 Analog to Digital Converters. I am not sure if both are brought out to the board though.
I was hover wondering, if I could save myself some extra work by simply using a different board. But I have been reading up on data-sheets and I guess that is unlikely...
edit: @coding badly. Is there any external converter you can recommend? I need at least 4 channels
fkeel:
Is there any external converter you can recommend? I need at least 4 channels
Unfortunately, my only experience is vicarious. I can say that the forum discussions about external converters seem to be primarily positive (easy to get working; good results) but that does not help you very much.
I vaguely recall that CrossRoads has posted links to Analog Devices training sessions. I believe Anachrocomputer has posted often about digital-to-analog conversion (wrong direction but he seems to have an interest in the general topic). You may have luck focusing a search on those two.
Here is an external pretty nice I2C 16 bit A/D converter, it's based on the TI ADS1115 chip. It can be run as either two differential channels or four single ended analog input. Can be run at 5vdc and is breadboard friendly. So far my check out of the device is very favorable, I can detect a 1 microvolt change at the highest gain setting of +/- .256 vdc full range, but can still read 0-5vdc at it's lowest gain setting, but still getting .000187 volts per step resolution. Seems very stable and the large number of programmable range options can save needing to use external op-amps for interfacing things like strain gages and other Wheatstone bridge type sensors.
Here is a sketch I wrote this weekend to check out the device:
/* Basic testing and check out sketch for a TI ADS1115 4 channel,16 bit, I2C, analog to digital converter chip
Leftyretro 08/06/11
*/
#include <Wire.h>
int topofScale; // made global to use adc range value to display millivolt reading conversion
void setup()
{
Wire.begin(); // join I2C bus
Serial.begin(38400); // initialize serial communication
setConfiguration(); // configure ADS1115 chip for range and channel desired
}
void loop() {
int rawValue; // holds 16 bit result read from A/D device
int scaledValue; // to convert to millivolts
byte userKeys;
Serial.print("Analog input #1 counts = ");
rawValue = getadcReading(); // read current A/D value
Serial.print(rawValue);
Serial.print(" Millvolts = ");
scaledValue = map(rawValue, 0, 32767, 0, topofScale);
Serial.print(scaledValue);
Serial.println(" Hit any key to continue");
while(Serial.available() < 1) {} // wait for user keystroke
while(Serial.available() > 0) {userKeys = Serial.read();} //read keystrokes then back to loop
}
int getadcReading()
{
int data;
int deviceAdd = 0x48; //ADS1115 address with address pin grounded
Wire.beginTransmission(deviceAdd); // transmit to I2c device address
Wire.send(0x00); // point to device register 0
Wire.endTransmission(); // stop transmitting
Wire.requestFrom(deviceAdd, 2); // request 2 bytes from slave device #2
while(Wire.available()) // need two bytes, MSB and LSB of converstion value
{
data = Wire.receive(); //get MSB of reading
data = data << 8; // shift it to high byte of data
data = data + Wire.receive(); // add LSB to data
}
return data;
}
void setConfiguration()
{
int deviceAdd = 0x48; //ADS1115 address with address pin grounded
//uncomment desired voltage input range
int confWord= 0x0000; topofScale = 6144; // 0- 0-6.144 vdc range
//int confWord= 0x0200; topofScale = 4096; // 1= 0-4.096 vdc range
//int confWord= 0x0400; topofScale = 2048; // 2= 0-2.048 vdc range
//int confWord= 0x0600; topofScale = 1024; // 3= 0-1.024 vdc range
//int confWord= 0x0800; topofScale = 512; // 4= 0-.512 vdc range
//int confWord= 0x0A00; topofScale = 256; // 5= 0-.256 vdc range
//uncomment desired channel input
// Also this sets sample rate to 860 SPS, disables comparitor,
// and turns on continous conversion mode.
confWord = confWord | 0x00E3; // 0= input wired to + AIN0 - AIN1, diff
//confWord = confWord | 0x30E3; // 3= input wired to + AIN2 - AIN3, diff
//confWord = confWord | 0x40E3; // 4= input wired to + AIN0 - gnd, single ended
//confWord = confWord | 0x50E3; // 5= input wired to + AIN1 - gnd, single ended
//confWord = confWord | 0x60E3; // 6= input wired to + AIN2 - gnd, single ended
//confWord = confWord | 0x70E3 ; // 7= input wired to + AIN3 - gnd, single ended
Wire.beginTransmission(deviceAdd); // transmit to ADS1115 device
Wire.send(0x01); // point to configuration register
Wire.send(highByte(confWord)); // sends MSB of configuration word
Wire.send(lowByte(confWord)); // sends LSB of configuration word
Wire.endTransmission(); // stop transmitting
}
I updated my check sketch for the device to include enabling and testing the comparitor function. This lets you set a high limit and low limit and if the voltage is between them it sets a output pin low in one comparitor mode, or will go low if the voltage exceeds the high set limit or falls below the low limit, in the other comparitor mode.
/* Basic testing and check out sketch for a TI ADS1115 4 channel 16 bit I2C analog to digital converter chip.
Reads voltage at desired range on desired channel and displays it on serial monitor. Also allows comparitor
to output a active low signal pin if enabled.
Leftyretro 08/10/11
*/
#include <Wire.h>
int topofScale; // global to use adc range value to display millivolt reading conversion
int hiCompair = 17000; // high setting for comparitor threshold value, must be higher then loCompair 32767
int loCompair = 11000; // low setting for comparitor threshold value, must be lower then hiCompair -32768
void setup()
{
Wire.begin(); // join I2C bus
Serial.begin(38400); // initialize serial communication
setadcConfiguration(); // configure ADS1115 chip for range, channel input, and comparitor options desired
}
void loop() {
int rawValue; // holds 16 bit result read from A/D device
int scaledValue; // to convert to millivolts
Serial.print("Analog input #1 counts = ");
rawValue = getadcReading(); // read current A/D value
Serial.print(rawValue);
Serial.print(" Millvolts = ");
scaledValue = map(rawValue, 0, 32767, 0, topofScale); //convert raw adc counts to millivolts
Serial.print(scaledValue);
Serial.println(" Hit any key to continue");
while(Serial.available() < 1) {} // wait for user keystroke
while(Serial.available() > 0) {byte userKeys = Serial.read();} //read keystrokes
}
int getadcReading() // read 16 bit analog voltage reading
{
int data;
int deviceAdd = 0x48; // ADS1115 address with address pin grounded
Wire.beginTransmission(deviceAdd); // transmit to I2c device address
Wire.send(0x00); // point to device register 0
Wire.endTransmission(); // stop transmitting
Wire.requestFrom(deviceAdd, 2); // request 2 bytes from slave device
while(Wire.available()) // need two bytes, MSB and LSB of converstion value
{
data = Wire.receive(); // get MSB of reading
data = data << 8; // shift it to high byte of data
data = data + Wire.receive(); // add LSB to data
}
return data;
}
void setadcConfiguration()
{
int deviceAdd = 0x48; // ADS1115 address with address pin grounded
/* uncomment one desired voltage input range */
int confWord= 0x0000; topofScale = 6144; // +/-6.144 vdc range
//int confWord= 0x0200; topofScale = 4096; // +/-4.096 vdc range
//int confWord= 0x0400; topofScale = 2048; // +/-2.048 vdc range
//int confWord= 0x0600; topofScale = 1024; // +/-1.024 vdc range
//int confWord= 0x0800; topofScale = 512; // +/-.512 vdc range
//int confWord= 0x0A00; topofScale = 256; // +/-.256 vdc range
/* uncomment one desired channel input
This also sets sample rate to 860 SPS and turns on continous conversion mode. */
confWord = confWord | 0x00E0; //input wired to + AIN0 - AIN1, diff +/- max range
//confWord = confWord | 0x30E0; //input wired to + AIN2 - AIN3, diff +/- max range
//confWord = confWord | 0x40E0; //input wired to + AIN0 - gnd, single ended, 0 to +max range
//confWord = confWord | 0x50E0; //input wired to + AIN1 - gnd, single ended, 0 to +max range
//confWord = confWord | 0x60E0; //input wired to + AIN2 - gnd, single ended, 0 to +max range
//confWord = confWord | 0x70E0; //input wired to + AIN3 - gnd, single ended, 0 to +max range
/* uncomment one desired comparator options
active low ready pin, window mode = input voltage is inside window values
active low ready pin, traditional = voltage raised above or fell below set values */
//confWord = confWord | 0x0003; //disable comparitor
//confWord = confWord | 0x0008; //enable comparitor in traditional comparator mode
confWord = confWord | 0x0018; //enable comparitor in window comparator mode
//send configuration word to device
Wire.beginTransmission(deviceAdd); // transmit to ADS1115 device
Wire.send(0x01); // point to configuration register
Wire.send(highByte(confWord)); // sends MSB of configuration word
Wire.send(lowByte(confWord)); // sends LSB of configuration word
Wire.endTransmission(); // stop transmitting
//send low threshold value word to device
Wire.beginTransmission(deviceAdd); // transmit to ADS1115 device
Wire.send(0x02); // point to low threshold register
Wire.send(highByte(loCompair)); // sends MSB of low threshold word
Wire.send(lowByte(loCompair)); // sends LSB of low threshold word
Wire.endTransmission(); // stop transmitting
//send high threshold value word to device
Wire.beginTransmission(deviceAdd); // transmit to ADS1115 device
Wire.send(0x03); // point to high threshold register
Wire.send(highByte(hiCompair)); // sends MSB of high threshold word
Wire.send(lowByte(hiCompair)); // sends LSB of high threshold word
Wire.endTransmission(); // stop transmitting
}
seriously... I am a psych guy who randomly got thrown into HCI and hardware development ... and people like you (and many others in this forum) are teaching me so much ...