Posts written by Juan-Manuel Fluxà

Controlling a 10-bit Digital Potentiometer via SPI with Arduino

1. A brief introduction to the Serial Peripheral Interface (SPI)

The Serial Peripheral Interface a.k.a SPI or four-wire serial interface is a full-duplex serial data protocol used by microcontrollers for communicating with one or more peripheral devices. Devices communicate in master/slave mode and there are four logic signals:

  • - MOSI: Master Out Slave In, is the master line to send data to the peripheral.
  • - MISO: Master In Slave Out, is the slave line to send data to the master.
  • - SCK: Serial Clock, the clock pulses which synchronize data transmission generated by the master.
  • - SS: Slave Select, the pin on each device that the master can use to enable and disable specific devices.

For more on this topic, visit Wikipedia's page on SPI.

2. Wiring the Master - Slave

For this tutorial we will use the Non-volatile memory, 1024 Position (10-bit) Digital Potentiometer AD5131 from Analog Devices. Wiring the IC to Arduino should be pretty straight-forward by looking at the pin configuration from the Data Sheet.

You might encounter different naming conventions for the lines on the SPI interface; the most commonly used are:

  • - The Motorola terms: MOSI and MISO for 'Master Out Slave In' and 'Master In Slave Out'.
  • - The PIC terms: SDI and SDO for 'SPI Data In' and 'SPI Data Out'.

MOSI always connects to MOSI or SDI (slave) and MISO always connects MISO or SDO (slave). CLK or SCK both refer to the serial clock and SS (slave select) or CS (chip select) are the same line.

On the Arduino Uno or Duemilanove the SPI lines are available from the digital pins 11 (MOSI), 12 (MISO) and 13 (SCK). Also, MOSI, MISO and SCK are available in a consistent physical location on the ICSP header.

If you are using a different Arduino board, the SPI lines might be located on different pins numbers. To find this information, please go to the SPI Library reference on the Arduino website.  Please note that when using the SPI feature on the Arduino, the digital pins 11, 12 and 13 can't be used as digital I/O.

Now, let's take a look at our wiring schematic.

Note that, as in this example we are not using all the features from the AD5231.  We left some of the pins unconnected (O1, O2 and RDY). Also, the pins marked with the optional features Write Protect (WP) and Hardware Override (PR) should be connected to VDD if they are not used.

3. Basic Operation

The AD5231 Digital Potentiometer is designed to operate as a true variable resistor replacement device for analog signals. The digital potentiometer wiper position is determined by the RDAC register contents (Address 0x0). The RDAC register acts as a scratchpad register, allowing as many values changes as necessary to place the potentiometer wiper in the correct position.

The basic mode of setting the variable resistor wiper position (programming the scratchpad register) is accomplished by loading the serial data input register with the instruction: 0xB, Address 0x0, and the desired wiper position data.

4. Serial Data Interface

The AD5231 uses a 24-bit serial data-word loaded Most Significant Bit first (MSBFIRST). The CS (chip select) pin must be held LOW until the complete data-word is loaded into the SDI pin. When CS returns to HIGH, the serial data-word is decoded. The command bits (Cx) control the operation of the digital potentiometer. The address bits (Ax) determine which register is activated. The data bits (Dx) are the values that are loaded into the decoded register.

 

MSB | Command Byte 0
Data Byte 1
Data Byte 0 | LSB
C3 C2 C1 C0 Ax Ax Ax Ax
X X X X X X D9 D8
D7 D6 D5 D4 D3 D2 D1 D0

5. Programing the Interface with Arduino

The Arduino SPI library allows us to transfer [SPI.transfer(byte)] only 8-bits (1 byte) at a time. In order to transfer a complete instruction (24-bits) to the digital potentiometer we will have to send the instruction in 3 parts of 8-bits each.

The first byte or 'Command Byte' is composed by the Command + Address which allows us to write data into the RDAC register:

Command = 0xB = 1011
Address = 0x0 = 0000
then:
Command + Address = 10110000

The following 2 bytes, the Data Bytes, contain the 10-bits (from 0 to 1023) wiper position. The Data Byte 1 only contains 2 bits from this value and 6 bits that are not used (X). In order to achieve this operation we will use the bitwise operands Logical Right Shift '>>' and AND '&'.

If you are not familiar with bitwise operations, I suggest reading  the 'Absolute Beginner's Guide to Bit Shifting' post from StackOverflow.

For this example, we will assume that we want to send the value 620 to the digital potentiometer to move the Wiper W to approximately 60%  full-scale position, then:

620 = 0000001001101100
620 >> 8 = 00000010 //Shifting 8 bits to the right
620 & 11111111 = 01101100  //Truncate to 8-bits on the LSB side

And finally, the Arduino code.

#include <SPI.h> 

const int csPin = 10;

void setup() {

 SPI.begin();
 SPI.setBitOrder(MSBFIRST); //We know this from the Data Sheet

 pinMode(csPin,OUTPUT);
 digitalWrite(csPin, HIGH);
}

void loop() {
 for(int i=0; i<1023; i++) { 
  digitalPotWrite(0,i);
  delay(10);
 } 
}

void digitalPotWrite(int address, int value) {
 digitalWrite(csPin, LOW); //select slave
 byte command = 0xB0; //0xB0 = 10110000 
 command += address; 
 SPI.transfer(command); 
 byte byte1 = (value >> 8);
 byte byte0 = (value & 0xFF); //0xFF = B11111111
 SPI.transfer(byte1);
 SPI.transfer(byte0);
 digitalWrite(csPin, HIGH); //de-select slave
}

There are much more features available in the AD5231 such as memory storing and restoring, increment/decrement, ±6 dB/step log taper adjustment, wiper setting read-back and extra EEMEM  for user-defined information, that are not covered in this post.

Monday App Recommendation: Sparrow

App: Sparrow (desktop) / (iPhone)
Price:
$10.99 (desktop) / $2.99 (iPhone)
Category: Productivitty
Why we like it: Light email client with a polished and very compact twitter-app-looking interface. It integrates with dropbox allowing you to automatically upload attachments just by drag-&-drop on the email body. The attachment then is replaced with the dropbox download link.

Adding labels and re-assigning Github issues via commit message

A very nice feature that Github added some time ago on Issues 2.0 is the ability to refer to and close issues when doing a "git commit" via commit message:

git commit -m 'just fixed issue #123'

That's nice, but what if we want to keep that issue open, change its state, or assign it to a different person in the team? As an example, what if I'm working on a bunch of issues, and I want QA to test them before they get closed?

Well, we have two ways of doing this:

1. Open your web browser of preference. Go to Github.com and sign in. Find the repository of the project you are working on. Find the issue you want to modify on the issues page of the project. Get amused by that very friendly user interface. Add/change the labels to the issue on the right panel. Assign someone to the issue using the "gears" drop box icon. Easy!

OR

 

2. git commit -m 'updated issue #123 ~QA =steve'

If you are like me and would like to do option 2, keep reading! (If not, do option 1 a few hundred times and maybe we'll see you again soon! :P)

 

Luckily, Github user bluescripts wrote a very simple ruby app using the Sinatra web framework that can be easily hooked up into our project's repository using the Github Service Hook: Post-Receive-URL. This Sinatra app can be deployed and hosted on Heroku which gives you some free monthly Dynos enough for this purpose.

Here are the steps to get this app running on Heroku:

1. Go to Heroku.com and sign up for an account (free)
2. Download and Install the Heroku Toolbelt (Mac / Win)
3. After installing the Toolbelt you will have access to the "heroku" command from your command shell, type in:

$ heroku login

Enter your Heroku credentials (email/password) and upload your SSH public key.
If you have any trouble on this steps please refer to the Heroku quickstart guide.

4. git clone this project @ https://github.com/bluescripts/github-postcommit-shinie and then cd into the project folder

$ git clone https://github.com/bluescripts/github-postcommit-shinies.git
$ cd github-postcommit-shinies

5. install the heroku gem

$ gem install heroku

6. install the bundler gem

$ gem install bundler

7. run bundle install to setup your bundle locally

$ bundle install

8. add and commit the Gemfile.lock file

$ git add Gemfile.lock
$ git commit -m 'Gemfile lock'

9. create the app on the Cedar stack

$ heroku create --stack cedar

After running this command you will see something like this:

Creating falling-moon-8152... done, stack is cedar
http://falling-moon-8152.herokuapp.com/ | git@heroku.com:falling-moon-8152.git
Git remote heroku added

Copy and save the deployment Heroku URL of your app, we will use it later. Also you can check this URL on Heroku/myapps.

10. deploy your code to Heroku

$ git push heroku master

11. check the status of your app

$ heroku ps

If everything goes fine you will see your app up and running.

Process State Command
------- --------- ------------------------------------
web.1 up for 1m bundle exec rackup config.ru -p $PORT

Now go to the Admin page of your Github repository and click on the Service Hooks button on the left menu then click on the Post-Service-URLs button and paste your Heroku URL of your app and click the Update Settings button. Done!

 

Unity Native Plugins: OS X

When developing games in Unity3D it is often (if not always) necessary to access to platform specific features, hardware or anything not available to Unity via the API.

Plugins in Unity are a way to establish a bridge between your code in Unity (C#, Javascript, Boo) and the native platform. It allows us access to any non-supported features by creating a native binary bundle which we can access through an interface in our Unity script. Plugins in Unity work in both directions: we can call native code from Unity as well as call Unity code from the native plugin.

To start of this series of tutorials, I will cover desktop and mobile with a native plugin for Mac OS.
Continue reading...