Thursday, January 23, 2014

Adding Analog Pins to Arduino pt.1

EDIT: I suggest reading this post instead:
It is easier and more straightforward to program for.

All of the commonly used Arduino boards have Analog pins for use in converting analog data to digital data that can be manipulated via code. Arduino Pro Mini, Nano, Mega, Duemilanove, are all examples of boards that have 8 or more ADC pins and in some cases, they're not even all broken out!

In any case, 8 pins may not be enough for your needs, I know this fact first hand. The reasons why you may need so many ADC connections is not important, but figuring out a way around the problem is!

First, lets talk about know about the ADC pins before using them.
1. They may be used as Digital I/O.
2. They convert the analog voltages to digital data with a 10-bit resolution.
3. You don't want to waste them. ;)

The 10 bit resolution means that the data returned when using them as Analog inputs is within the range of 2^10, or 0 - 1023. I like to work with data in binary, but the data may be dealt with in decimal, binary or hex if you wish. Like:
B0000000000 - B1111111111
0x000 - 0x3FF
0 - 1023

Aside from the main point of this post, my needs are to use the values from potentiometers in an 8-bit resolution. I just found out that instead of shifting the data to the right twice (or divided by 2 twice) that the data range itself may be mapped to other values, both higher or lower. One way to read an analog input and mapping the value is as follows:

Stupid simple code to read a pot value and map it to another range.
By Jazzmarazz

map(value, fromLow, fromHigh, toLow, toHigh)

int A0pin = A0;

int potVal = 0;

void setup() {
pinMode(A0pin, INPUT);
void loop() {
map(analogRead(A0pin), 0, 1023, 0, 255);

The map function could allow for you to map it to most any value:
map(analogRead(A0pin), 0, 1023, 0, 9);
map(analogRead(A0pin), 0, 1023, 0, 4095);
map(analogRead(A0pin), 0, 1023, 10, 100);
Whatever you like, for whatever purposes.

In addition, it is a good idea to read the constrain function:

Now to the point. To add many more ADC pins to the arduino, I suggest adding an external ADC via an SPI connection. Alternatively, you may use an I2C connection, but it seems like SPI devices come equipped with more analog channels. The MCP3008 for example, is an 8-channel, 10-bit ADC. This means that there are 8 analog inputs which all read back in the above mentioned 10-bit resolution.

To wire one such device to our Arduino, we must follow one of the Communication methods:

UART, I2C, SPI 2 wire, SPI 3 wire and lastly, 4 wire (full) SPI. An example of all four connections are shown below. In all of these cases, you need at least two things, a master device and a slave device. In our case, the master is our Arduino and the slave will be the MCP3008 ADC. Below also shows how you can daisy chain more slave devices to the same master bus. This is incredibly helpful because all of the devices are going to share up to three of the connections, and only have one connection that is unique to itself.

The shared connections are SCK, MOSI, and MISO while the unique connection is SS, but what do these connections mean?

MISO (Master In Slave Out) - The Slave line for sending data to the master,
MOSI (Master Out Slave In) - The Master line for sending data to the peripherals,
SCK (Serial Clock) - The clock pulses which synchronize data transmission generated by the master and one line specific for every device:
SS (Slave Select) - the pin on each device that the master can use to enable and disable specific devices.

Pretty simple, taken straight from the Arduino reference guide. You're probably wondering where the pins are. Now, you can write your own functions if you wanted to drop the external SPI slave anywhere, but a custom code is going to be much slower and it would be more easy to move your other connections somewhere else so that these pins are free for SPI:

Digital pin 13 is the Serial clock, 12 is Master Input, 11 is Master output and lastly, SS or Chip enable is 10, but I believe this can be moved where ever since it just requires a digitalWrite high or low. Low to enable of course.

That is about as complicated as it gets, honestly. Now, back to my needs. To iterate, I need to read the analog values of many potentiometers to assign to other devices, not on the SPI bus. We can do this two ways. Wire up all four connections, or wire up three connections and tie SS to ground on the slave only. If we keep SS connected to the Arduino, then we can expand the SPI bus to have more devices, more analog inputs, sensors, outputs, etc. IF we tie SS to ground, then the slave will always be active but can be the only SPI device on our bus.

Looking at the datasheet, there are two package types, the 3004 and the 3008. Both will take up all of the same connections, so lets focus on the 3008.

Pins 1 - 8 are the Analog input pins where we will connect the wiper of our pots. Pin 10 is the 1CS pin, which we will connect to !SS on the arduino. Pin 11 is the Din or Data input pin which will be connected to the Dout pin of the Arduino, MOSI. Pin 12 is the Dout which will be connected to the MISO pin. and lastly, the clock pin on 13 will be connected to Digital pin 13 on the Arduino.

Pins 16 and 15 will be bridged and connected to VCC or +5v. VDD is the supply and Vref is the reference voltage that the analog inputs are referencing. If we had a lower vref like 3v3, then our pots would have to be connected between Ground and 3v3, while the IC runs on +5v.

Pins 14 and 9 are the two grounds, Analog ground and digital ground, respectively. This may be one of the more confusing parts to hook up if you over think it. Copied stright from the datasheet:

"Utilizing the Digital and Analog Ground Pins The MCP3004/3008 devices provide both digital and analog ground connections to provide additional means of noise reduction. As is shown in Figure 6-5, the analog and digital circuitry is separated internal to the device. This reduces noise from the digital portion of the device being coupled into the analog portion of the device. The two grounds are connected internally through the substrate which has a resistance of 5 -10Ω. If no ground plane is utilized, both grounds must be connected to VSS on the board. If a ground plane is available, both digital and analog ground pins should be connected to the analog ground plane. If both an analog and a digital ground plane are available, both the digital and the analog ground pins should be connected to the analog ground plane. Following these steps will reduce the amount of digital noise from the rest of the board being coupled into the A/D converter."

What this basically means is that having analog ground and digital ground connected together may cause interference in the form of noise on the data traces. Since most of our Arduino board have only a single GND pin, we will have to take separating the two into our own hands. Some suggest dividing the two ground planes by a gap and then connecting them together via a small bridge like so:

They also suggest that you use separate power supplies. You should also remember to route any traces crossing the ground planes trough the bridge and not over the gaps. Being so strict will help you to reduce noise, but how much noise do you think that you actually have in your circuit? Are you running it on an unregulated series of AA batteries? A potato (joke)? Could you not afford filter capacitors? In most cases, the on board Arduino regulator is going to do its job in regulating the power supply, reducing noise and with capacitors between VCC and GND, yet more noise reduction.

Unless you plan on wiring up many different crystal oscillators, high speed devices, and wireless communications all on the same board, then your noise should not be readily noticeable.

Now enough of my tangents. I made up a quick MSpaint drawing of the connections:

That is the wiring diagram we will use, but for the time being, the MCP3008's are still in the mail. Once they arrive, I will write part 2 where we actually wire up the circuit and write some code to read from each pot. You may notice that the pinout is exactly 13 -> 13, 12 -> 12, 11 -> 11 and 10 -> 10. It would seem that the SPI functions were written to accommodate common SPI pinouts. You may see this on other SPI devices as well.

Thanks for reading!
Part 2:

No comments:

Post a Comment