素子:デジタルポテンショメータ

Microchip社のデジタルポテンショメータです。型番MCP4151、MCP4152

・簡単に言うと「簡易D-Aコンバータ」
・入力がSPIで出力が抵抗
・半固定抵抗の代用品として使用するのが一般的(らしい)
・抵抗値を目一杯下げても100Ω程度
・抵抗値のばらつきが大きく、温度特性も良くない
・抵抗値は購入するときに選択する、1個の素子で抵抗値が切り替えられるわけではない
・1個約$1と安価
・英語ではdigital-POT、DPOTと略されていることもある
・購入時に選択しないといけない項目
  -レオスタットモードで使用するのかポテンショメータモード(分圧)で使用するのか
  -抵抗値をEEPROMに記憶できるか否か
  -抵抗値 5k、10k、50k、100k が選択可能
  -入力インターフェースの種類 SPI,I2C,独自 がある
  -パッケージ
    -2個入り、1個入り
    -サイズ DIP、MSOP、DFN
  -分解能 129段階、257段階


2009-11-15

I2Cインターフェースの物にはDIPパッケージが有りませんが、SPIインターフェースの物にはDIPパッケージが用意されている

PICT0937.jpg

MCP4151とMCP4152

PICT0953.jpg

ピン配置。左がポテンショメータモードのMCP4151で分圧に使う、右がMCP4152で可変抵抗として使う

EEPROMに抵抗値を記憶できる物があるが、MPUを後で取り外してしまう物ではないかと思う。MPUと接続したままならMPUのEEPROMに記憶しておけば済むはず。

PICT0954.jpg

この表を見て購入する物を検討する。50kΩのものはMCP4151-503の様に抵抗値を表す番号が付いている。

ワイパーレジスタンスというのが目一杯抵抗値を下げたときの抵抗値。75Ωとかなり大きい。それ以外にも温度特性が良くないことや、あまり電流を流せない(MAX2.5mA)というのが見て取れる。

PICT0961.jpg

特性

PICT0962.jpg

抵抗値もばらつきがある。5kΩの物を購入しても4~6kΩにばらつく。このばらつきは分圧の時には気にならなくなります。

ブレッドボードで回路を組む

PICT0952.jpg

実験風景

PIC<-SPI->デジタルポテンショメータ テストプログラム MikroBASIC V7.2
0001  '-------------------------------------------------------------- 2009-11-15 -----
0002 ' Digital Potentiometer Test Program
0003 '
0004 ' MPU:PIC16F677 20pin
0005 '-------------------------------------------------------------------------------
0006 program DPOT
0007
0008 symbol PORT_OUTPUT = 0
0009 symbol PORT_INPUT = 1
0010
0011 symbol DIGITAL_IO = 0
0012
0013 '---- SPI chip select --------------
0014 symbol SPI_CS_TRIS = TRISA
0015 symbol SPI_CS_PORT = PORTA
0016 symbol SPI_CS_BIT = 5
0017
0018
0019 '-------------------------------------------------------------------------------
0020 ' SPI initializes
0021 '-------------------------------------------------------------------------------
0022 sub procedure Spi_initialize()
0023 SSPSTAT.SMP = 0 ' Input data sampled at middle of data output time
0024 SSPSTAT.CKE = 0 ' Transmit occurs on transition from Idle to active clock state
0025 SSPCON.SSPEN = 1 ' Enables serial port and configures SCK, SDO, SDI and SS as serial port pins
0026 SSPCON.CKP = 1 ' Idle state for clock is a high level
0027 SSPCON.SSPM3 = 0 ' SPI Clock FSOC/16
0028 SSPCON.SSPM2 = 0 ' SPI Clock FSOC/16
0029 SSPCON.SSPM1 = 0 ' SPI Clock FSOC/16
0030 SSPCON.SSPM0 = 1 ' SPI Clock FSOC/16
0031
0032 SPI_CS_TRIS.SPI_CS_BIT = PORT_OUTPUT ' SPI chip select
0033 SPI_CS_PORT.SPI_CS_BIT = 1
0034 end sub
0035
0036 '-------------------------------------------------------------------------------
0037 ' SPI write 8bit
0038 '-------------------------------------------------------------------------------
0039 sub procedure Spi_write_data_8bit(dim data as byte )
0040 SPI_CS_PORT.SPI_CS_BIT = 0
0041 SSPBUF = data
0042 while PIR1.SSPIF = 0
0043 wend
0044 PIR1.SSPIF = 0
0045 SPI_CS_PORT.SPI_CS_BIT = 1
0046 end sub
0047
0048 '-------------------------------------------------------------------------------
0049 ' SPI write 16bit
0050 '-------------------------------------------------------------------------------
0051 sub procedure Spi_write_data_16bit(dim data1 as byte, dim data2 as byte )
0052 SPI_CS_PORT.SPI_CS_BIT = 0
0053 SSPBUF = data1
0054 while PIR1.SSPIF = 0
0055 wend
0056 PIR1.SSPIF = 0
0057 SSPBUF = data2
0058 while PIR1.SSPIF = 0
0059 wend
0060 PIR1.SSPIF = 0
0061 SPI_CS_PORT.SPI_CS_BIT = 1
0062 end sub
0063
0064
0065 '===============================================================================
0066 ' main
0067 '===============================================================================
0068 main:
0069 dim i as word
0070
0071 ANSEL = DIGITAL_IO ' port A digital I/O
0072
0073 TRISB.6 = PORT_OUTPUT ' SPI CLOCK
0074 TRISB.4 = PORT_INPUT ' SPI DATA INPUT
0075 TRISC.7 = PORT_OUTPUT ' SPI DATA OUTPUT
0076
0077 OSCCON.IRCF2 = 1 ' CLOCK 8MHz
0078 OSCCON.IRCF1 = 1 ' CLOCK 8MHz
0079 OSCCON.IRCF0 = 1 ' CLOCK 8MHz
0080
0081 Spi_initialize
0082
0083 Delay_ms(2000)
0084
0085 for i = 1 to 128 ' 25k ohm -> 50k ohm
0086 Delay_ms(20)
0087 Spi_write_data_8bit( %00000100 ) ' inclement wiper
0088 next i
0089
0090 Delay_ms(2000)
0091
0092 Spi_write_data_16bit( %00000000, %00000000 ) ' set 0k ohm
0093
0094 Delay_ms(2000)
0095
0096 Spi_write_data_16bit( %00000000, %11111111 ) ' set 50k ohm
0097
0098 Delay_ms(2000)
0099
0100 for i = 0 to 256 ' 50k ohm -> 0k ohm
0101 Delay_ms(20)
0102 Spi_write_data_8bit( %00001000 ) ' declement wiper
0103 next i
0104
0105 while true
0106 wend
0107 end.
0108
0109 '--------- E N D O F P R O G R A M -------------------------------------------
行番号
解説
22行目~
SPIの初期化ルーチン。大体どのPICでも同じ。SSPCONがSSPCON1のPICがある
27行目
SPIのクロック周波数設定。PICは8MHzで動かしている。この設定でSPIのクロックは500kHz程度になる。デジタルポテンショメータは10MHzまでOKなので余裕
36行目~
SPIでデジタルポテンショメータに8ビットデータを送るサブルーチン
48行目~
SPIでデジタルポテンショメータに16ビットデータを送るサブルーチン。デジタルポテンショメータには8ビットコマンドと16ビットコマンドがある。8ビットは1ステップだけ抵抗値を上げ下げする時に使い、16ビットコマンドは一気に目的の抵抗値に設定するときに使う。
71行目
A/Dコンバータを切る。比較的新しいPICは最初にこれをやらないとポートAがデジタル入出力にならない。
73行目~
SPIで使用するポートの入出力設定。デジタルポテンショメータから設定値を読み出すことも出来るが、EEPROM版でなければ読み込む必要性がないのでTRISB.4は削除してもOK
77行目
PICを内部オシレータで動かす。内部オシレータの周波数はプログラムから変更できる。最近のPICの高機能化にはついて行けない
83行目
テスターが高速で反応できないので無駄時間を各所に入れている
85行目~
電源投入直後の初期状態では抵抗値がちょうど中央になっている。50kΩのデジタルポテンショメータなら25kΩだ。テストに使用したものは257段階に抵抗値を設定できる。
87行目
抵抗値を1ステップずつ増加させる
92行目
抵抗値をゼロΩにする。実際は100Ω程度にしかならない
96行目
抵抗値を最大にする
100行目
抵抗値を1ステップずつ下げていく。最終的にはゼロΩにまで下げる。
105行目
プログラムが暴走しないように無限ループ。ここでは何もしていない

以下のMOVIEの回路図。レオスタットモード用のMCP4152。5,6番ピンの抵抗をテスターで計測している

dpot1.PNG
50kΩのMCP4152の実験
ファイル ファイルタイプ 添付ファイルの解説
mcp4152.wmv MOVIE 1.PICkit2の黄色LEDが点灯してテスト開始
2.電源投入直後は約23kΩ
3.徐々に抵抗値を上げていき最大抵抗値は45kΩ
4.一気に最小抵抗値に設定。抵抗値は102Ω
5.一気に最大抵抗値に設定。抵抗値は45kΩ
6.徐々に抵抗値を下げていき最小抵抗値は102Ω

以下のMOVIEの回路図。分圧モード用のMCP4151。GND,6番ピン間の電圧をテスターで計測している

DPOT2.PNG
50kΩのMCP4151の実験。プログラムは全く同じ物を使用
ファイル ファイルタイプ 添付ファイルの解説
mcp4151.wmv MOVIE 1.PICkit2の黄色LEDが点灯してテスト開始
2.電源投入直後は2.24V
3.徐々に抵抗値を上げていき最小電圧は0.005V(7、5番ピンの接続が逆だった)
4.一気に最小抵抗値に設定。電圧は電源電圧と等しくなる。PICkit2の出力電圧なので4.5V
5.一気に最大抵抗値に設定。電圧は0.0225V
6.徐々に抵抗値を下げていき最大電圧は電源電圧と等しくなる。

Arduinoの例

dpotino.PNG
Arduinoスケッチ
0001  //----------------------------------------------- 2014-12-11 --------
0002 // Digital Potentiometer Test Program MCP4151-502(5k ohm)
0003 //------------------------------ written by iizuka Japan ----------
0004 #include <SPI.h>
0005
0006 #define DPOT_CS 8 // digital 8pin
0007
0008 //------------------------------------------------------------------------------------------
0009 // DPOT に書き込む
0010 //------------------------------------------------------------------------------------------
0011 void spi_dpot_write_16bit( byte data1, byte data2 )
0012 {
0013 digitalWrite( DPOT_CS, LOW ); // MCP4151 chip select enable
0014 SPI.transfer( data1 );
0015 SPI.transfer( data2 );
0016 digitalWrite( DPOT_CS, HIGH ); // MCP4151 chip select disable
0017 }
0018
0019 void spi_dpot_write_8bit( byte data )
0020 {
0021 digitalWrite( DPOT_CS, LOW ); // MCP4151 chip select enable
0022 SPI.transfer( data );
0023 digitalWrite( DPOT_CS, HIGH ); // MCP4151 chip select disable
0024 }
0025
0026 //------------------------------------------------------------------------------------------
0027 // arduino setup
0028 //------------------------------------------------------------------------------------------
0029 void setup()
0030 {
0031 SPI.begin();
0032
0033 pinMode(DPOT_CS, OUTPUT);
0034 digitalWrite( DPOT_CS, HIGH ); // MCP4151 disable
0035 }
0036
0037 //------------------------------------------------------------------------------------------
0038 // arduino loop
0039 //------------------------------------------------------------------------------------------
0040 void loop()
0041 {
0042 spi_dpot_write_16bit( 0b00000000, 0b00000000 ); // P0A <-> P0W set 5k ohm
0043 for( byte i = 1 ; i <= 128 ; i++ ) { // P0A <-> P0W 5.0k ohm -> 2.5k ohm
0044 delay(20);
0045 spi_dpot_write_8bit( 0b00000100 ); // inclement wiper
0046 }
0047 delay(2000);
0048 spi_dpot_write_16bit( 0b00000000, 0b00000000 ); // P0A <-> P0W set 5k ohm
0049 delay(2000);
0050 spi_dpot_write_16bit( 0b00000000, 0b11111111 ); // P0A <-> P0W set 0k ohm
0051 delay(2000);
0052 for( byte i = 0 ; i <= 256 ; i++ ) { // P0A <-> P0W 0k ohm -> 5k ohm
0053 delay(20);
0054 spi_dpot_write_8bit( 0b00001000 ); // declement wiper
0055 }
0056 while( true ) {}
0057 }
0058
0059 //--------- E N D O F P R O G R A M -------------------------------------------
0060
行番号
解説
解説はコメント参照
5kΩのMCP4151-502の実験
ファイル ファイルタイプ 添付ファイルの解説
DPOT.zip arduino サンプルスケッチ