SurferTim,
THANK YOU SOOOOO MUCH FOR TAKING THE TIME TO LOOK AT MY CODE AND HELP ME! It was a simple mistake, and you caught it. I spent over 3.5 hrs stuck on this stupid thing, after writing all this code, with that being my only error the whole time. Since this is my first time talking to a device via SPI, from scratch, with no library or anything, I was sure I was doing something wrong there, sending the commands and all, or that my device was broken, since I did the TSSOP-14 surface-mount soldering myself and didn't know what else to think. It turns out, however, that you are spot-on, and my only problem was forgetting the two parentheses () at the end of a function call.
Problem solved!
Sincerely,
Gabriel Staples
http://electricrcaircraftguy.blogspot.com/
My final, working code is here:
/*
write_to_MAX5481
-Code to command this 10-bit digital potentiometer
By Gabriel Staples
http://electricrcaircraftguy.blogspot.com/
23 May 2014
Circuit:
Pin Name Connect to what?
1 VDD +5V (Important: connect a 0.1uF [or larger] ceramic capacitor from VDD to GND, as close to the device as possible) [I'm using a 1uF multi-layer ceramic cap]
2 GND GND/0V
3 CS (SS) Any Arduino pin, let's use D9
4 SCK Arduino pin D13
5 MOSI Arduino pin D11
6 SPI/UD +5V to select SPI mode
7 X
8 X
9 X
10 L GND/0V; this is the LOW side of the voltage divider
11 W Vout; this is the wiper on the potentiometer
12 H +5V; this is the HIGH side of the voltage divider
13 X
14 VSS GND/0V (make sure to tie this to GND)
*/
/*
===================================================================================================
LICENSE & DISCLAIMER
Copyright (C) 2014 Gabriel Staples. All right reserved.
------------------------------------------------------------------------------------------------
License: GNU Lesser General Public License Version 3 (LGPLv3) - https://www.gnu.org/licenses/lgpl.html
------------------------------------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see http://www.gnu.org/licenses/
===================================================================================================
*/
#include <SPI.h>
//Global Variables
const uint8_t slaveSelectPin = 9; //SPI Slave Select pin
float VDD_measured = 4.4; //measured supply voltage to the device
void setup()
{
Serial.begin(115200);
//set the Slave Select pin as an output
pinMode(slaveSelectPin,OUTPUT);
//initialize SPI
SPI.begin();
// SPI.setDataMode(SPI_MODE0); //I think this is the correct mode; I also think this is the default mode, so I'll just comment this out
// SPI.setDataMode(SPI_MODE2); //test mode
// SPI.setBitOrder(MSBFIRST); //this is correct; the LSBFIRST bit order definitely does NOT work--it scrambles the commands (I checked); Note: default mode is
//"MSBFIRST," so I'll just comment this line out
Serial.println(F("Enter your desired command (0-1023) as an int, with end of line char on.\n"
"Type just a \"c\" to copy the EEPROM val to the wiper.\n"
"Type a \"t\" to have future commands also get stored into the pot's EEPROM.\n"
"Type a \"f\" to NOT have future commands also get stored into the pot's EEPROM"));
}
void loop()
{
static boolean writeEEPROM = false;
if (Serial.available()>0)
{
if (Serial.peek()=='c')
{
Serial.println("copying EEPROM value to wiper register");
Serial.read(); //read in the 'c'
Serial.read(); //read in the '\n'
copy_EEPROM_to_wiper();
}
else if (Serial.peek()=='t')
{
Serial.println("writeEEPROM = true");
Serial.read(); //read in the 't'
Serial.read(); //read in the '\n'
writeEEPROM = true;
}
else if (Serial.peek()=='f')
{
Serial.println("writeEEPROM = false");
Serial.read(); //read in the 'f'
Serial.read(); //read in the '\n'
writeEEPROM = false;
}
else //the first char coming in is NOT a 'c', 't', or 'f', so it must be the wiper command
{
unsigned int command = Serial.parseInt();
if (Serial.read()=='\n') //read in the last char & ensure it is an end-of-line char
{
command = constrain(command,0,1023);
float V_out_calculated = command/1023.0*VDD_measured;
//print data
Serial.print("command = "); Serial.println(command);
Serial.print("V_out_calculated = "); Serial.println(V_out_calculated);
digitalPotWrite(command, writeEEPROM);
}
}
} //end of if serial is available
} //end of loop()
void digitalPotWrite(unsigned int command, boolean writeEEPROM)
{
//local constants
const byte WRITE_WIPER = 0x00; //command to write to the wiper register only
const byte WRITE_EEPROM = 0x20; //command to copy the wiper register into the non-volatile memory (EEPROM) of the digital pot
// const byte COPY_EEPROM_TO_WIPER = 0x30; //command to copy the EEPROM value to the wiper register
//command the new wiper setting (requires sending 3 bytes)
digitalWrite(slaveSelectPin,LOW); //set the SS pin low to select the chip
SPI.transfer(WRITE_WIPER); //Byte 1: the command byte
SPI.transfer(highByte(command<<6)); //Byte 2: the upper 8 bits of the 10-bit command: (D9.D8.D7.D6.D5.D4.D3.D2)
SPI.transfer(lowByte(command<<6)); //Byte 3: the lower 2 bits of the 10-bit command, with 6 zeros to the right of them: (D1.D0.x.x.x.x.x.x)
digitalWrite(slaveSelectPin,HIGH); //set the SS pin high to "latch the data into the appropriate control register" (see datasheet pg. 14)
//copy the wiper register into the non-volatile memory (EEPROM) of the digital pot, if commanded (requires sending only 1 byte)
if (writeEEPROM)
{
Serial.println("writing to EEPROM");
delay(10); //wait a short time for the previous command to get properly set
digitalWrite(slaveSelectPin,LOW); //set the SS pin low to select the chip
SPI.transfer(WRITE_EEPROM); //Byte 1: the command byte
digitalWrite(slaveSelectPin,HIGH); //set the SS pin high to "latch the data into the appropriate control register" (see datasheet pg. 14 & 16)
delay(13); //wait 13ms (see datasheet pg. 16 under the paragraph titled "Copy Wiper Register to NV Register"--they require a 12ms wait time, so I'll wait 13ms to be sure)
Serial.println("done writing to EEPROM");
}
}
//copy the value stored in the EEPROM to the wiper register, to command the wiper to go there
void copy_EEPROM_to_wiper()
{
const byte COPY_EEPROM_TO_WIPER = 0x30; //command to copy the EEPROM value to the wiper register
digitalWrite(slaveSelectPin,LOW); //set the SS pin low to select the chip
SPI.transfer(COPY_EEPROM_TO_WIPER); //Byte 1: the command byte
digitalWrite(slaveSelectPin,HIGH); //set the SS pin high to "latch the data into the appropriate control register" (see datasheet pg. 14 & 16)
}