Digitales Potentiometer



Verwendete Pin-Nummern findet man unter hardware/arduino/variants

z.B: für das Board Duemilanove: SS = 10 (Chip-Select), MOSI = 11 (Master Out/Slave In),MISO=12, SCK = 13

MCP 4151-104E/P

http://pdf1.alldatasheet.com/datasheet-pdf/view/305851/MICROCHIP/MCP4151T.html





Wahl des R1: 1kOhm (10kOhm war zu hochhohmig, konnte den internen Pullup im MCP41X1 nicht überschreiben; je niederohmiger desto schneller wird der Bus

Fritzing-Verdrahtungsplan; Achtung: Pin A vom MCP4151 sollte auf VCC und Pin B auf GND verdrahtet werden, hier sinkt bei steigendem Digital-Wert die Spannung am Wiper Ausgang. Der Widerstandswert mit 10k ist zu hoch: es gelingt damit nicht, gegen den inneren Pullup den Pegel auf Null zu ziehen.



/*
  kner 2013 MCP4151 Digital Poti
  Pin 5(A) - Full Scale End -  connect this to VDD
  Pin 6(W) - wiper - connet to Analog In A0
  Pin 7(B) - GND
  Pin 1(CS) - arduino pin 10  (SS pin)
  Pin 3(SDI/SDO) - arduino pin 11 (MOSI pin) via resistor for writing to poti
  Pin 3(SDI/SDO) - arduino pin 12 (MISO pin) direct for reading from poti
  Pin 2(SCK) - arduino pin 13 (SCK pin)
 
 data frame 
 increment: 1 byte    0000 0100
 decrement: 1 byte    0000 1000
 
 write value: 2byte 0000 00dd dddd dddd  values from 0x00 to 0x100
 read status register (address 5): 2 byte 0101 1100 xxxx xxdx        - bit 1 = hardware shutdown bit; 
                                                                   a shutdown disconnects pin A and sets the wiper to B
 tcon register (address 4): can connect/disconnect terminals(A,B,W) and hardware-shutdown(HW) the device
 9 bits: 1 1111 R0HW-R0A-R0W-R0B   bit 8 - bit 4 not used/ 
 to shutdown:  0000 0001 1111 0111    (bit 9 is not used) 
 to disconnect A: 111111011
*/


// inslude the SPI library:
#include <SPI.h>
#include <avr/io.h>


// set pin 10 as the slave select for the digital pot:
const int slaveSelectPin = 10;

void setup() {
  Serial.begin(9600); 
  pinMode (slaveSelectPin, OUTPUT);
  SPI.begin(); 
  SPI.setClockDivider(SPI_CLOCK_DIV128); //depends on resistors
}

void loop() {
   Serial.print("Max: ");
   //after POR: wiper is in the middle
   digitalPotWrite(0x100);  //Maximum
   Serial.println(analogRead(A0)); 
   delay(3000); 

    //Shutdown output should be 0
    Serial.print("Shutdown:"); 
    digitalPotWrite16Bit(0x40F7);
    Serial.println(analogRead(A0)); 
    Serial.print("Status:"); 
    Serial.println(digitalPotReadControlregister(),HEX); // did it work?
    // i am not successful in reading register 5 (Status Register) 
    
    
    //reactivate after Shutdown 
    Serial.print("Finish shutdown:"); 
    digitalPotWrite16Bit(0x40FF);
    Serial.println(digitalPotReadControlregister(),HEX); 
   Serial.print("Min: ");
   digitalPotWrite(0x0);  //Minimum
   Serial.println(analogRead(A0)); 
   delay(3000);  
   Serial.println("inc: ");
   for (int level = 0; level < 257; level++) {
      digitalPotInc();
      Serial.println(analogRead(A0)); 
      delay(10);  
    }
    Serial.println("dec: ");
   //decrement
   for (int level = 0; level < 257; level++) {
      digitalPotDec();
      Serial.println(analogRead(A0)); 
      delay(10);  
    }
    Serial.println("inc level: ");
    for (int level = 0; level < 257; level++) {
      digitalPotWrite(level);
      Serial.println(analogRead(A0)); 
      delay(10);  
    }
    Serial.println("dec level: ");
    for (int level = 257; level >0; level--) {
      digitalPotWrite(level);
      Serial.println(analogRead(A0)); 
      delay(1);
    } 
    while(1); 
}

void digitalPotInc() {
  digitalWrite(slaveSelectPin,LOW);
  SPI.transfer(4);
  digitalWrite(slaveSelectPin,HIGH); 
}
void digitalPotDec() {
  digitalWrite(slaveSelectPin,LOW);
  SPI.transfer(8);
  digitalWrite(slaveSelectPin,HIGH); 
}

void digitalPotWrite(int value) {
  digitalWrite(slaveSelectPin,LOW);
  SPI.transfer((value>>8)&0b00000001);  //high byte least significant bit
  SPI.transfer(value & 0xff);
  digitalWrite(slaveSelectPin,HIGH); 
}

void digitalPotWrite16Bit(int value) {
  digitalWrite(slaveSelectPin,LOW);
  SPI.transfer(value>>8);  //the short way also works
  SPI.transfer(value);
  digitalWrite(slaveSelectPin,HIGH); 
}

uint16_t digitalPotReadControlregister() {
  digitalWrite(slaveSelectPin,LOW);
  int highbyte = SPI.transfer(0x4F);
  int lowbyte =   SPI.transfer(0xFF);
  digitalWrite(slaveSelectPin,HIGH); 
  return highbyte*256+lowbyte;
}