Posts with «analog» label

Hack an Old DC Motor to Provide Rotary Input

Watch a Redditor share how he hacked a DC motor and hooked it up to an Arduino to use as an encoder.

Read more on MAKE

The post Hack an Old DC Motor to Provide Rotary Input appeared first on Make: DIY Projects, How-Tos, Electronics, Crafts and Ideas for Makers.

Printing Text with a Chart Recorder

Chart recorders are vintage devices that were used to plot analog values on paper. They’re similar to old seismometers which plot seismic waves from earthquakes. The device has a heated pen which moves across a piece of thermally sensitive paper. This paper is fed through the machine at a specified rate, which gives two dimensions of plotting.

[Marv] ended up getting a couple of discontinued chart recorders and figured out the interface. Five parallel signals control the feed rate of the paper, and an analog voltage controls the pen location. The next logical step was to hook up an Arduino to control the plotter.

However, once the device could plot analog values, [Marv] quickly looked for a new challenge. He wanted to write characters and bitmaps using the device, but this would require non-continuous lines. By adding a solenoid to lift the pen, he built a chart recorder printer.

After the break, check out a video of the chart recorder doing something it was never intended to do. If you happen to have one of these chart recorders, [Marv] included all of the code in his writeup to help you build your own.


Filed under: classic hacks

Arduino Tutorials – Chapter 22 – the AREF pin

Learn how to measure smaller voltages with greater accuracy using your Arduino.

This is chapter twenty-two of our huge Arduino tutorial seriesUpdated 12/12/2013

In this chapter we’ll look at how you can measure smaller voltages with greater accuracy using the analogue input pins on your Arduino or compatible board in conjunction with the AREF pin. However first we’ll do some revision to get you up to speed. Please read this post entirely before working with AREF the first time.

Revision

You may recall from the first few chapters in our tutorial series that we used the analogRead() function to measure the voltage of an electrical current from sensors and so on using one of the analogue input pins. The value returned from analogRead() would be between zero an 1023, with zero representing zero volts and 1023 representing the operating voltage of the Arduino board in use.

And when we say the operating voltage – this is the voltage available to the Arduino after the power supply circuitry. For example, if you have a typical Arduino Uno board and run it from the USB socket – sure, there is 5V available to the board from the USB socket on your computer or hub – but the voltage is reduced slightly as the current winds around the circuit to the microcontroller – or the USB source just isn’t up to scratch.

This can easily be demonstrated by connecting an Arduino Uno to USB and putting a multimeter set to measure voltage across the 5V and GND pins. Some boards will return as low as 4.8 V, some higher but still below 5V. So if you’re gunning for accuracy, power your board from an external power supply via the DC socket or Vin pin – such as 9V DC. Then after that goes through the power regulator circuit you’ll have a nice 5V, for example:

This is important as the accuracy of any analogRead() values will be affected by not having a true 5 V. If you don’t have any option, you can use some maths in your sketch to compensate for the drop in voltage. For example, if your voltage is 4.8V – the analogRead() range of 0~1023 will relate to 0~4.8V and not 0~5V. This may sound trivial, however if you’re using a sensor that returns a value as a voltage (e.g. the TMP36 temperature sensor) – the calculated value will be wrong. So in the interests of accuracy, use an external power supply.

Why does analogRead() return a value between 0 and 1023?

This is due to the resolution of the ADC. The resolution (for this article) is the degree to which something can be represented numerically. The higher the resolution, the greater accuracy with which something can be represented. We measure resolution in the terms of the number of bits of resolution.

For example, a 1-bit resolution would only allow two (two to the power of one) values – zero and one. A 2-bit resolution would allow four (two to the power of two) values – zero, one, two and three. If we tried to measure  a five volt range with a two-bit resolution, and the measured voltage was four volts, our ADC would return a numerical value of 3 – as four volts falls between 3.75 and 5V. It is easier to imagine this with the following image:

 So with our example ADC with 2-bit resolution, it can only represent the voltage with four possible resulting values. If the input voltage falls between 0 and 1.25, the ADC returns numerical 0; if the voltage falls between 1.25 and 2.5, the ADC returns a numerical value of 1. And so on. With our Arduino’s ADC range of 0~1023 – we have 1024 possible values – or 2 to the power of 10. So our Arduinos have an ADC with a 10-bit resolution.

So what is AREF? 

To cut a long story short, when your Arduino takes an analogue reading, it compares the voltage measured at the analogue pin being used against what is known as the reference voltage. In normal analogRead use, the reference voltage is the operating voltage of the board. For the more popular Arduino boards such as the Uno, Mega, Duemilanove and Leonardo/Yún boards, the operating voltage of 5V. If you have an Arduino Due board, the operating voltage is 3.3V. If you have something else – check the Arduino product page or ask your board supplier.

So if you have a reference voltage of 5V, each unit returned by analogRead() is valued at 0.00488 V. (This is calculated by dividing 1024 into 5V). What if we want to measure voltages between 0 and 2, or 0 and 4.6? How would the ADC know what is 100% of our voltage range?

And therein lies the reason for the AREF pin. AREF means Analogue REFerence. It allows us to feed the Arduino a reference voltage from an external power supply. For example, if we want to measure voltages with a maximum range of 3.3V, we would feed a nice smooth 3.3V into the AREF pin – perhaps from a voltage regulator IC. Then the each step of the ADC would represent around 3.22 millivolts (divide 1024 into 3.3).

Note that the lowest reference voltage you can have is 1.1V. There are two forms of AREF – internal and external, so let’s check them out.

External AREF

An external AREF is where you supply an external reference voltage to the Arduino board. This can come from a regulated power supply, or if you need 3.3V you can get it from the Arduino’s 3.3V pin. If you are using an external power supply, be sure to connect the GND to the Arduino’s GND pin. Or if you’re using the Arduno’s 3.3V source – just run a jumper from the 3.3V pin to the AREF pin.

To activate the external AREF, use the following in void setup():

analogReference(EXTERNAL); // use AREF for reference voltage

This sets the reference voltage to whatever you have connected to the AREF pin – which of course will have a voltage between 1.1V and the board’s operation voltage.

Very important note – when using an external voltage reference, you must set the analogue reference to EXTERNAL before using analogRead(). This will prevent you from shorting the active internal reference voltage and the AREF pin, which can damage the microcontroller on the board.

If necessary for your application, you can revert back to the board’s operating voltage for AREF (that is – back to normal) with the following:

analogReference(DEFAULT);

Now to demonstrate external AREF at work. Using a 3.3V AREF, the following sketch measures the voltage from A0 and displays the percentage of total AREF and the calculated voltage:

#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);

int analoginput = 0; // our analog pin
int analogamount = 0; // stores incoming value
float percentage = 0; // used to store our percentage value
float voltage =0; // used to store voltage value

void setup()
{
  lcd.begin(16, 2);
  analogReference(EXTERNAL); // use AREF for reference voltage
}

void loop()
{
  lcd.clear();
  analogamount=analogRead(analoginput);
  percentage=(analogamount/1024.00)*100;
  voltage=analogamount*3.222; // in millivolts
  lcd.setCursor(0,0);
  lcd.print("% of AREF: ");
  lcd.print(percentage,2);
  lcd.setCursor(0,1);  
  lcd.print("A0 (mV): ");
  lcd.println(voltage,2);
  delay(250);
}

The results of the sketch above are shown in the following video:

Internal AREF

The microcontrollers on our Arduino boards can also generate an internal reference voltage of 1.1V and we can use this for AREF work. Simply use the line:

analogReference(INTERNAL);

For Arduino Mega boards, use:

analogReference(INTERNAL1V1);

in void setup() and you’re off. If you have an Arduino Mega there is also a 2.56V reference voltage available which is activated with:

analogReference(INTERNAL2V56);

Finally – before settling on the results from your AREF pin, always calibrate the readings against a known good multimeter.

Conclusion

The AREF function gives you more flexibility with measuring analogue signals. If you are interested in using specific ADC components, we have tutorials on the ADS1110 16-bit ADC and the NXP PCF 8591 8-bit A/D and D/A IC.

Stay tuned for upcoming Arduino tutorials by subscribing to the blog, RSS feed (top-right), twitter or joining our Google Group. And if you enjoyed the tutorial, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop” from No Starch Press.

 

The post Arduino Tutorials – Chapter 22 – the AREF pin appeared first on tronixstuff.

Arduino Tutorials – Chapter 22 – the AREF pin

Learn how to measure smaller voltages with greater accuracy using your Arduino.

This is chapter twenty-two of our huge Arduino tutorial seriesUpdated 12/12/2013

In this chapter we’ll look at how you can measure smaller voltages with greater accuracy using the analogue input pins on your Arduino or compatible board in conjunction with the AREF pin. However first we’ll do some revision to get you up to speed. Please read this post entirely before working with AREF the first time.

Revision

You may recall from the first few chapters in our tutorial series that we used the analogRead() function to measure the voltage of an electrical current from sensors and so on using one of the analogue input pins. The value returned from analogRead() would be between zero an 1023, with zero representing zero volts and 1023 representing the operating voltage of the Arduino board in use.

And when we say the operating voltage – this is the voltage available to the Arduino after the power supply circuitry. For example, if you have a typical Arduino Uno board and run it from the USB socket – sure, there is 5V available to the board from the USB socket on your computer or hub – but the voltage is reduced slightly as the current winds around the circuit to the microcontroller – or the USB source just isn’t up to scratch.

This can easily be demonstrated by connecting an Arduino Uno to USB and putting a multimeter set to measure voltage across the 5V and GND pins. Some boards will return as low as 4.8 V, some higher but still below 5V. So if you’re gunning for accuracy, power your board from an external power supply via the DC socket or Vin pin – such as 9V DC. Then after that goes through the power regulator circuit you’ll have a nice 5V, for example:

This is important as the accuracy of any analogRead() values will be affected by not having a true 5 V. If you don’t have any option, you can use some maths in your sketch to compensate for the drop in voltage. For example, if your voltage is 4.8V – the analogRead() range of 0~1023 will relate to 0~4.8V and not 0~5V. This may sound trivial, however if you’re using a sensor that returns a value as a voltage (e.g. the TMP36 temperature sensor) – the calculated value will be wrong. So in the interests of accuracy, use an external power supply.

Why does analogRead() return a value between 0 and 1023?

This is due to the resolution of the ADC. The resolution (for this article) is the degree to which something can be represented numerically. The higher the resolution, the greater accuracy with which something can be represented. We measure resolution in the terms of the number of bits of resolution.

For example, a 1-bit resolution would only allow two (two to the power of one) values – zero and one. A 2-bit resolution would allow four (two to the power of two) values – zero, one, two and three. If we tried to measure  a five volt range with a two-bit resolution, and the measured voltage was four volts, our ADC would return a numerical value of 3 – as four volts falls between 3.75 and 5V. It is easier to imagine this with the following image:

 So with our example ADC with 2-bit resolution, it can only represent the voltage with four possible resulting values. If the input voltage falls between 0 and 1.25, the ADC returns numerical 0; if the voltage falls between 1.25 and 2.5, the ADC returns a numerical value of 1. And so on. With our Arduino’s ADC range of 0~1023 – we have 1024 possible values – or 2 to the power of 10. So our Arduinos have an ADC with a 10-bit resolution.

So what is AREF? 

To cut a long story short, when your Arduino takes an analogue reading, it compares the voltage measured at the analogue pin being used against what is known as the reference voltage. In normal analogRead use, the reference voltage is the operating voltage of the board. For the more popular Arduino boards such as the Uno, Mega, Duemilanove and Leonardo/Yún boards, the operating voltage of 5V. If you have an Arduino Due board, the operating voltage is 3.3V. If you have something else – check the Arduino product page or ask your board supplier.

So if you have a reference voltage of 5V, each unit returned by analogRead() is valued at 0.00488 V. (This is calculated by dividing 1024 into 5V). What if we want to measure voltages between 0 and 2, or 0 and 4.6? How would the ADC know what is 100% of our voltage range?

And therein lies the reason for the AREF pin. AREF means Analogue REFerence. It allows us to feed the Arduino a reference voltage from an external power supply. For example, if we want to measure voltages with a maximum range of 3.3V, we would feed a nice smooth 3.3V into the AREF pin – perhaps from a voltage regulator IC. Then the each step of the ADC would represent around 3.22 millivolts (divide 1024 into 3.3).

Note that the lowest reference voltage you can have is 1.1V. There are two forms of AREF – internal and external, so let’s check them out.

External AREF

An external AREF is where you supply an external reference voltage to the Arduino board. This can come from a regulated power supply, or if you need 3.3V you can get it from the Arduino’s 3.3V pin. If you are using an external power supply, be sure to connect the GND to the Arduino’s GND pin. Or if you’re using the Arduno’s 3.3V source – just run a jumper from the 3.3V pin to the AREF pin.

To activate the external AREF, use the following in void setup():

analogReference(EXTERNAL); // use AREF for reference voltage

This sets the reference voltage to whatever you have connected to the AREF pin – which of course will have a voltage between 1.1V and the board’s operation voltage.

Very important note – when using an external voltage reference, you must set the analogue reference to EXTERNAL before using analogRead(). This will prevent you from shorting the active internal reference voltage and the AREF pin, which can damage the microcontroller on the board.

If necessary for your application, you can revert back to the board’s operating voltage for AREF (that is – back to normal) with the following:

analogReference(DEFAULT);

Now to demonstrate external AREF at work. Using a 3.3V AREF, the following sketch measures the voltage from A0 and displays the percentage of total AREF and the calculated voltage:

#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);

int analoginput = 0; // our analog pin
int analogamount = 0; // stores incoming value
float percentage = 0; // used to store our percentage value
float voltage =0; // used to store voltage value

void setup()
{
  lcd.begin(16, 2);
  analogReference(EXTERNAL); // use AREF for reference voltage
}

void loop()
{
  lcd.clear();
  analogamount=analogRead(analoginput);
  percentage=(analogamount/1024.00)*100;
  voltage=analogamount*3.222; // in millivolts
  lcd.setCursor(0,0);
  lcd.print("% of AREF: ");
  lcd.print(percentage,2);
  lcd.setCursor(0,1);  
  lcd.print("A0 (mV): ");
  lcd.println(voltage,2);
  delay(250);
}

The results of the sketch above are shown in the following video:

Internal AREF

The microcontrollers on our Arduino boards can also generate an internal reference voltage of 1.1V and we can use this for AREF work. Simply use the line:

analogReference(INTERNAL);

For Arduino Mega boards, use:

analogReference(INTERNAL1V1);

in void setup() and you’re off. If you have an Arduino Mega there is also a 2.56V reference voltage available which is activated with:

analogReference(INTERNAL2V56);

Finally – before settling on the results from your AREF pin, always calibrate the readings against a known good multimeter.

Conclusion

The AREF function gives you more flexibility with measuring analogue signals. If you are interested in using specific ADC components, we have tutorials on the ADS1110 16-bit ADC and the NXP PCF 8591 8-bit A/D and D/A IC.

Stay tuned for upcoming Arduino tutorials by subscribing to the blog, RSS feed (top-right), twitter or joining our Google Group. And if you enjoyed the tutorial, or want to introduce someone else to the interesting world of Arduino – check out my book (now in a third printing!) “Arduino Workshop” from No Starch Press.

 

Tutorial – Arduino and PCF8591 ADC DAC IC

Learn how to use the NXP PCF 8591 8-bit A/D and D/A IC with Arduino in chapter fifty-two of my Arduino Tutorials. The first chapter is here, the complete series is detailed here.

Updated 17/06/2013

Introduction

Have you ever wanted more analogue input pins on your Arduino project, but not wanted to fork out for a Mega? Or would you like to generate analogue signals? Then check out the subject of our tutorial – the NXP PCF8591 IC. It solves both these problems as it has a single DAC (digital to analogue) converter as well as four ADCs (analogue to digital converters) – all accessible via the I2C bus. If the I2C bus is new to you, please familiarise yourself with the readings here before moving forward.

The PCF8591 is available in DIP form, which makes it easy to experiment with:

You can get them from the usual retailers. Before moving on, download the data sheet. The PCF8591 can operate on both 5V and 3.3V so if you’re using an Arduino Due, Raspberry Pi or other 3.3 V development board you’re fine. Now we’ll first explain the DAC, then the ADCs.

Using the DAC (digital-to-analogue converter)

The DAC on the PCF8591 has a resolution of 8-bits – so it can generate a theoretical signal of between zero volts and the reference voltage (Vref) in 255 steps. For demonstration purposes we’ll use a Vref of 5V, and you can use a lower Vref such as 3.3V or whatever you wish the maximum value to be … however it must be less than the supply voltage. Note that when there is a load on the analogue output (a real-world situation), the maximum output voltage will drop – the data sheet (which you downloaded) shows a 10% drop for a 10kΩ load. Now for our demonstration circuit:

Note the use of 10kΩ pull-up resistors on the I2C bus, and the 10μF capacitor between 5V and GND. The I2C bus address is set by a combination of pins A0~A2, and with them all to GND the address is 0x90. The analogue output can be taken from pin 15 (and there’s a seperate analogue GND on pin 13. Also, connect pin 13 to GND, and circuit GND to Arduino GND.

To control the DAC we need to send two bytes of data. The first is the control byte, which simply activates the DAC and is 1000000 (or 0x40) and the next byte is the value between 0 and 255 (the output level). This is demonstrated in the following sketch:

// Example 52.1 PCF8591 DAC demo
// http://tronixstuff.com/tutorials Chapter 52
// John Boxall June 2013
#include "Wire.h"
#define PCF8591 (0x90 >> 1) // I2C bus address
void setup()
{
 Wire.begin();
}
void loop()
{
 for (int i=0; i<256; i++)
 {
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
 Wire.write(i); // value to send to DAC
 Wire.endTransmission(); // end tranmission
 }

 for (int i=255; i>=0; --i)
 {
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
 Wire.write(i); // value to send to DAC
 Wire.endTransmission(); // end tranmission
 }
}

Did you notice the bit shift of the bus address in the #define statement? Arduino sends 7-bit addresses but the PCF8591 wants an 8-bit, so we shift the byte over by one bit. 

The results of the sketch are shown below, we’ve connected the Vref to 5V and the oscilloscope probe and GND to the analogue output and GND respectively:

If you like curves you can generate sine waves with the sketch below. It uses a lookup table in an array which contains the necessary pre-calculated data points:

// Example 52.2 PCF8591 DAC demo - sine wave
// http://tronixstuff.com/tutorials Chapter 52
// John Boxall June 2013

#include "Wire.h"
#define PCF8591 (0x90 >> 1) // I2C bus address

uint8_t sine_wave[256] = {
 0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96,
 0x99, 0x9C, 0x9F, 0xA2, 0xA5, 0xA8, 0xAB, 0xAE,
 0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4,
 0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8,
 0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8,
 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4,
 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC,
 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD,
 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6,
 0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB,
 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC,
 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9,
 0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3,
 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA2, 0x9F, 0x9C,
 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83,
 0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A,
 0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52,
 0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x3C,
 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28,
 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18,
 0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C,
 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04,
 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A,
 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15,
 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24,
 0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37,
 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D,
 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64,
 0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D
};
void setup()
{
 Wire.begin();
}
void loop()
{
 for (int i=0; i<256; i++)
 {
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(0x40); // control byte - turn on DAC (binary 1000000)
 Wire.write(sine_wave[i]); // value to send to DAC
 Wire.endTransmission(); // end tranmission
 }
}

And the results:

For the following DSO image dump, we changed the Vref to 3.3V – note the change in the maxima on the sine wave:

Now you can experiment with the DAC to make sound effects, signals or control other analogue circuits.

Using the ADCs (analogue-to-digital converters)

If you’ve used the analogRead() function on your Arduino (way back in Chapter One) then you’re already familiar with an ADC. With out PCF8591 we can read a voltage between zero and the Vref and it will return a value of between zero and 255 which is directly proportional to zero and the Vref. For example, measuring 3.3V should return 168. The resolution (8-bit) of the ADC is lower than the onboard Arduino (10-bit) however the PCF8591 can do something the Arduino’s ADC cannot. But we’ll get to that in a moment.

First, to simply read the values of each ADC pin we send a control byte to tell the PCF8591 which ADC we want to read. For ADCs zero to three the control byte is 0x00, 0x01, ox02 and 0x03 respectively. Then we ask for two bytes of data back from the ADC, and store the second byte for use. Why two bytes? The PCF8591 returns the previously measured value first – then the current byte. (See Figure 8 in the data sheet). Finally, if you’re not using all the ADC pins, connect the unused ones to GND.

The following example sketch simply retrieves values from each ADC pin one at a time, then displays them in the serial monitor:

// Example 52.3 PCF8591 ADC demo
// http://tronixstuff.com/tutorials Chapter 52
// John Boxall June 2013
#include "Wire.h"
#define PCF8591 (0x90 >> 1) // I2C bus address
#define ADC0 0x00 // control bytes for reading individual ADCs
#define ADC1 0x01
#define ADC2 0x02
#define ADC3 0x03
byte value0, value1, value2, value3;
void setup()
{
 Wire.begin();
 Serial.begin(9600);
}
void loop()
{
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(ADC0); // control byte - read ADC0
 Wire.endTransmission(); // end tranmission
 Wire.requestFrom(PCF8591, 2);
 value0=Wire.read();
 value0=Wire.read();
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(ADC1); // control byte - read ADC1
 Wire.endTransmission(); // end tranmission
 Wire.requestFrom(PCF8591, 2);
 value1=Wire.read();
 value1=Wire.read();
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(ADC2); // control byte - read ADC2
 Wire.endTransmission(); // end tranmission
 Wire.requestFrom(PCF8591, 2);
 value2=Wire.read();
 value2=Wire.read();
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(ADC3); // control byte - read ADC3
 Wire.endTransmission(); // end tranmission
 Wire.requestFrom(PCF8591, 2);
 value3=Wire.read();
 value3=Wire.read();
 Serial.print(value0); Serial.print(" ");
 Serial.print(value1); Serial.print(" ");
 Serial.print(value2); Serial.print(" ");
 Serial.print(value3); Serial.print(" ");
 Serial.println();
}

Upon running the sketch you’ll be presented with the values of each ADC in the serial monitor. Although it was a simple demonstration to show you how to individually read each ADC, it is a cumbersome method of getting more than one byte at a time from a particular ADC.

To do this, change the control byte to request auto-increment, which is done by setting bit 2 of the control byte to 1. So to start from ADC0 we use a new control byte of binary 00000100 or hexadecimal 0x04. Then request five bytes of data (once again we ignore the first byte) which will cause the PCF8591 to return all values in one chain of bytes. This process is demonstrated in the following sketch:

// Example 52.4 PCF8591 ADC demo
// http://tronixstuff.com/tutorials Chapter 52
// John Boxall June 2013
#include "Wire.h"
#define PCF8591 (0x90 >> 1) // I2C bus address
byte value0, value1, value2, value3;
void setup()
{
 Wire.begin();
 Serial.begin(9600);
}
void loop()
{
 Wire.beginTransmission(PCF8591); // wake up PCF8591
 Wire.write(0x04); // control byte - read ADC0 then auto-increment
 Wire.endTransmission(); // end tranmission
 Wire.requestFrom(PCF8591, 5);
 value0=Wire.read();
 value0=Wire.read();
 value1=Wire.read();
 value2=Wire.read();
 value3=Wire.read();
 Serial.print(value0); Serial.print(" ");
 Serial.print(value1); Serial.print(" ");
 Serial.print(value2); Serial.print(" ");
 Serial.print(value3); Serial.print(" ");
 Serial.println();
}

Previously we mentioned that the PCF8591 can do something that the Arduino’s ADC cannot, and this is offer a differential ADC. As opposed to the Arduino’s single-ended (i.e. it returns the difference between the positive signal voltage and GND, the differential ADC accepts two signals (that don’t necessarily have to be referenced to ground), and returns the difference between the two signals. This can be convenient for measuring small changes in voltages for load cells and so on.

Setting up the PCF8591 for differential ADC is a simple matter of changing the control byte. If you turn to page seven of the data sheet, then consider the different types of analogue input programming. Previously we used mode ’00’ for four inputs, however you can select the others which are clearly illustrated, for example:

So to set the control byte for two differential inputs, use binary 00110000 or 0x30. Then it’s a simple matter of requesting the bytes of data and working with them. As you can see there’s also combination single/differential and a complex three-differential input. However we’ll leave them for the time being.

Conclusion

Hopefully you found this of interest, whether adding a DAC to your experiments or learning a bit more about ADCs. We’ll have some more analogue to digital articles coming up soon, so stay tuned. And if you enjoy my tutorials, or want to introduce someone else to the interesting world of Arduino – check out my new book “Arduino Workshop” from No Starch Press.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Tutorial – Arduino and PCF8591 ADC DAC IC appeared first on tronixstuff.

Gertboard extender for Raspberry Pi ships to advanced tinkerers

If a seemingly infinitely programmable mini computer like the Raspberry Pi is just too... limiting, we've got good news: the Gertboard extender has started shipping. The $48 companion board reaching customers' doorsteps converts analog to digital and back for Raspberry Pi fans developing home automation, robotics and just about anything else that needs a translation between the computing world and less intelligent objects. The one catch, as you'd sometimes expect from a homebrew project, is the need for some assembly -- you'll have to solder together Gert van Loo's Arduino-controlled invention on your own. We imagine the DIY crowd won't mind, though, as long as they can find the fast-selling Gertboard in the first place.

[Image credit: Stuart Green, Flickr]

Filed under: Misc

Gertboard extender for Raspberry Pi ships to advanced tinkerers originally appeared on Engadget on Wed, 17 Oct 2012 03:58:00 EST. Please see our terms for use of feeds.

Permalink | Email this | Comments

Tweephone is a rotary phone Twitter client, even your grandma could love

The collectives behind the Tweephone, UP digital Bureau and Unteleported tech agency, claim that it's the first analog Twitter client. We find that hard to believe but, while we've seen rotary phone-based Twitter tools before and analog meters that measure microblogging activity, we couldn't come up with a single example of a client that lets you punch in messages through non-digital means. Even if it's not the first of its kind, the Tweephone is still a pretty neat hack. Inside the old-school chassis is the ubiquitous Arduino, which interprets your pulls of the dial as letters. Like a phone with only a dial pad, you'll have to ring up numbers multiple times to get the right letter (i.e. dial "2" three times to get a "c"). It definitely not the most efficient method for sending out 140-character missives, but certainly one of the more unique. Check out the video after the break to see it in action.

Continue reading Tweephone is a rotary phone Twitter client, even your grandma could love

Tweephone is a rotary phone Twitter client, even your grandma could love originally appeared on Engadget on Tue, 01 Nov 2011 19:04:00 EST. Please see our terms for use of feeds.

Permalink | Email this | Comments