I like TR-52D modules, but I was disappointed of their DAC capabilities inherited from used MCU. Fortunately we have several ways, how to fix this issue. One of them is AS1500 digital potentiometer usage. It is very simple (from programming view) device and not so expensive. Following example is only draft. For fully functional circuit, some additional hardware is required.
About Hardware
The AS1500 is a digital potentiometer with 256 programmable steps. The values of the resistor can be controlled via 3 wire serial interface capable to handle programming rates up to 10MHz.
The AS1500 is available in four different resistor values. The AS1500 incorporates a 10kΩ, the AS1501 a 20kΩ, the AS1502 a 50kΩ and the AS1503 a 100kΩ fixed resistor. The wiper contact taps the fixed resistor at points determined by the 8-bit digital code word. The resistance between the wiper and the endpoint of the resistor is linear. The switching action is performed in a way that no glitches occur. (from datasheet)
The AS150x is available in an 8-pin SOIC package:
- B terminal of resistor divider.
- GND.
- CSN – Chip Select Input.
- SDI – Serial Data Input.
- CK – Serial Clock Input.
- VCC.
- W – Wiper.
- A terminal of resistor divider.
Following picture shows wiring of test circuit
About software
Software follows servo example from last week. TR module inserted into DK-EVAL-04 expects two incoming bytes. “S” and “data” bytes. Data byte is written to AS1500. You can use ADC control module from Wireless servo controller II article. Do not forget to delete value limitation.
AS150x is controled via one 8bit register. But you have to send 10bits. The first two bits are address bits, but for wiper position changes, zeros has to be in address positions.
// Port initialisation and setup
void AS1500_Init()
{
TRISC.6 = 0; // Pin 5 = CLK (output)
TRISB.4 = 1; // parallel pin (input)
TRISA.5 = 1; // parallel pin (input)
TRISC.3 = 0; // Pin 6 = STROBE (output)
TRISC.5 = 0; // Pin 8 = DATA (output)
TRISC.7 = 1; // parallel pin (input)
// initial state
CLK_CLR; // data at zero
DATA_CLR; // clk at zero
STROBE_SET; // strobe at zero
}
// fill AS1500 and strobe it out
void AS1500_SendData(uns8 data)
{
uns8 i;
uns8 mask = 128;
STROBE_CLR;
waitDelay(1);
DATA_CLR;
waitDelay(1);
// first address zero bit
CLK_SET;
waitDelay(1);
// first address zero bit
CLK_CLR;
waitDelay(1);
for (i=0; i<8; i++)
{
if (data & mask) // set data against the mask
DATA_SET;
else
DATA_CLR;
waitDelay(1); // shift it
CLK_SET;
waitDelay(1);
CLK_CLR;
waitDelay(1);
mask = mask >> 1;
}
STROBE_SET; // strobe it out
waitDelay(1);
}
Full source code is attached.
Enjoy.