Kategorien
Arduino

Arduino – MCP42010 mehrere digitale Potentiometer kaskadiert steuern

Arduino – MCP42010 – Beispiel Ansteuerung mehrerer digitaler Potentiometer

Nach dem Beispiel Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett und der grafischen Variante Node Red – Arduino – digitales Potentiometer MCP42010 steuern habe ich die Ansteuerung von 2 digitalen Potentiometern MCP42010 kaskadiert getestet.

Schaltung

 

Ansteuerung der beiden MCP42010

Die Ansteuerung des primären MCP42010 ist ausführlich in Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett beschrieben.
Schreiben in Potentiometer 1 -> B00010001 und in Potentiometer 2 -> B00010010
Als zweites Byte wird der Wert übertragen, den das ausgewählte Potentiometer annehmen soll.

Um den zweiten MCP42010 zu erreichen müssen 4 Bytes, statt bisher 2 gesendet werden. Beim dritten MCP42010 wären es dann 6, beim vierten 8 und so weiter.
Um ein Potentiometer des 2. MCP42010 direkt anzusteuern ohne die Inhalte des ersten Chips zu verändern, werden zwei weitere Bytes mit dem Wert 0 gesendet.
Siehe auch Bild links aus dem Datenblatt.

Schreiben in Potentiometer 3 -> B00010001 WERT B00000000 B00000000
Schreiben in Potentiometer 4 -> B00010010 WERT B00000000 B00000000

Das ganze ist von rechts nach links zu lesen.
Es werden 4 Bytes geschrieben oder besser hinein geschoben. Die ersten beiden Bytes (von links) werden von den folgenden beiden Bytes in den zweiten MCP42010 geschoben.
Im ersten MCP42010 kommen zwei mal Null an, also keine Änderungen an den Werten im 1. Chip.

Anbei ein Minimal Beispiel, wie in das Potentiometer 1 (Pot0) des zweiten MCP42010 der Wert 127 geladen wird.

Kategorien
Node Red

Arduino – Node Red – MCP42010 – Steuerung des digitalen Potentiometers

Arduino – Node Red – MCP42010 – Beispiel Steuerung des digitalen Potentiometers

Im Beitrag Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett habe ich dargestellt wie der MCP42010 über den seriellen Monitor der Arduino IDE gesteuert werden kann.
Jetzt will ich dieses etwas komfortabler zu tun.
Die Bedienung sollte aus dem Browser heraus erfolgen, optisch sehr ansprechend aussehen und auch mit dem Smartphone möglich sein.

Warum mit Node Red?

Node Red ist in der Standard Installation der Raspberry Pi enthalten, kostenlos und intuitiv bedienbar.
Durch die Möglichkeit den Programm Flow per drag and drop zusammen zu stellen, kommt man sehr schnell zu einem guten Ergebnis.
Für Prototypen und auch IOT Anwendungen eine echt tolle Sache.
Wo Licht ist, ist auch Schatten: Es verbraucht recht viel Ressourcen.
Dennoch kommt die Raspberry Pi 2 spielend damit zurecht und die Pi 3 logischerweise noch viel besser.

benötigte Funktionen des Flows

Der Flow soll die Eingaben, die ich im Experiment Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett per Hand gemacht habe übernehmen.
Der Flow soll die Rückgabe – Werte in einem Gauge Chart darstellen.

Eingabe:
1:Wert von 0-255 -> setzt Potentiometer1 auf den Wert und gibt die Spannung an A0 zurück
2:Wert von 0-255 -> setzt Potentiometer2 auf den Wert und gibt die Spannung an A1 zurück

Der Flow

  • einfach den folgenden Flow kopieren und unter Menü (rechts oben) -> Import – Clipboard einfügen
[{"id":"ebf0e947.110038","type":"ui_slider","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Slider","topic":"","group":"Pot1","order":1,"min":0,"max":"255","x":225.5,"y":125,"wires":[["25bd2695.9acaf2"]]},{"id":"b755b484.2bd75","type":"ui_text","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Wert","group":"Pot1","order":1,"format":"{{msg.payload}}","x":636.5,"y":102,"wires":[]},{"id":"ed9f01b2.dfae38","type":"ui_gauge","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Spannung in V an A0","group":"Pot1","order":1,"format":"{{value}}","min":0,"max":"5","x":681.5,"y":322,"wires":[]},{"id":"25bd2695.9acaf2","type":"function","z":"8ec3bd3.cce4dc","name":"Value to Command","func":"var msg1 = { payload:\"1:\" + msg.payload +\"\\n\"};\nreturn [msg, msg1];","outputs":"2","noerr":0,"x":440.5,"y":125,"wires":[["b755b484.2bd75"],["134514.6c0042ed"]]},{"id":"134514.6c0042ed","type":"serial out","z":"8ec3bd3.cce4dc","name":"/dev/ttyUSB0","serial":"d535ccdc.123838","x":658.5,"y":148,"wires":[]},{"id":"13db30d1.da3c67","type":"serial in","z":"8ec3bd3.cce4dc","name":"/dev/ttyUSB0","serial":"43aa993f.185738","x":186.5,"y":345,"wires":[["f39416bc.0495"]]},{"id":"f39416bc.0495","type":"function","z":"8ec3bd3.cce4dc","name":"Response to value","func":"//find A0 or A1\nvar value;\nif (msg.payload.indexOf(\"A0\") != -1) {\n    value = msg.payload.split(\"A0: \");\n    value = value[1].replace(\" Volt\", \"\");\n    msg.payload = value;\n    return [msg, null];\n} else {\n    value = msg.payload.split(\"A1: \");\n    value = value[1].replace(\" Volt\", \"\");\n    msg.payload = value;\n    return [null , msg];\n}","outputs":"2","noerr":0,"x":431.5,"y":345,"wires":[["ed9f01b2.dfae38"],["ddbfff6.2bdb3"]]},{"id":"8a48ef7d.33ba9","type":"ui_slider","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Slider","topic":"","group":"Pot2","order":1,"min":0,"max":"255","x":224,"y":227,"wires":[["127d632d.c0419d"]]},{"id":"5a58be54.e6b8d8","type":"ui_text","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Wert","group":"Pot2","order":1,"format":"{{msg.payload}}","x":635,"y":204,"wires":[]},{"id":"127d632d.c0419d","type":"function","z":"8ec3bd3.cce4dc","name":"Value to Command","func":"var msg1 = { payload:\"2:\" + msg.payload +\"\\n\"};\nreturn [msg, msg1];","outputs":"2","noerr":0,"x":439,"y":227,"wires":[["5a58be54.e6b8d8"],["ee1b0407.9fbca"]]},{"id":"ee1b0407.9fbca","type":"serial out","z":"8ec3bd3.cce4dc","name":"/dev/ttyUSB0","serial":"43aa993f.185738","x":657,"y":250,"wires":[]},{"id":"ddbfff6.2bdb3","type":"ui_gauge","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Spannung in V an A1","group":"Pot2","order":1,"format":"{{value}}","min":0,"max":"5","x":681,"y":370,"wires":[]},{"id":"147200e2.b8e19f","type":"ui_tab","z":"","name":"Test MCP42010","icon":"dashboard","order":"1"},{"id":"d535ccdc.123838","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","newline":"\\n","bin":"false","out":"char","addchar":false},{"id":"43aa993f.185738","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","newline":"\\n","bin":"false","out":"char","addchar":false}]

Video Ansteuerung MCP42010 mit Node Red

Kategorien
Arduino

Arduino MCP42010 – Steuerung und Test des Digital Potentiometers

Arduino MCP42010 – auf einem Steckbrett austesten

Es gibt viele Anleitungen digitale Potentiometer mit einer Arduino anzusteuern.
Meine Suche im Internet nach dem MCP42010 in Verbindung mit Arduino war sehr vielversprechend, führte aber erst nach einigen Versuchen zum Erfolg.
Viele Seiten und Foreneinträge diskutieren das Thema, beschreiben aber keine funktionierende Lösung.

Die Idee ist die beiden digitalen 10 Kiloohm Potentiometer an den Enden zwischen 5 Volt und Masse zu schalten und die Mitte des Potis auf jeweils einen analogen Eingang zu legen.
Je nach dem was jetzt für ein Widerstand (angesteuert) wird, wird die Spannung an den analogen Eingängen steigen oder fallen. Und das lässt sich auswerten.

Ich beschreibe, wie ich vorgegangen bin.

Zum Einsatz kam ein Arduino Nano Nachbau, der schon für etwas über 3,50 Euro zu haben ist und ein digitales Potentiometer MCP42010 (Datenblatt), was ich für ca. 2 Euro bei www.reichelt.de bestellt habe. Ich habe den Aufbau auch mit einer Arduino Uno getestet mit den selben IO Pins. Erfolgreich :-)

Wie in der folgenden Fritzing Grafik und dem Eagle Schaltplan zu erkennen, habe ich folgendermaßen verdrahtet.
Pin Belegung MCP42010MCP42010:
Pin 1 -> D10 Arduino, Pin2 -> D13 Arduino, Pin3 -> D11 Arduino, Pin4 -> Masse, Pin5 -> Masse, Pin6 -> A1 -> Arduino, Pin7 -> +5V, Pin8 -> + 5V, Pin9 -> A0 Arduino, Pin10 -> Masse, Pin11 -> +5V, Pin12 -> 5V, Pin13 – frei, Pin14 -> 5V

Arduino: Außer den Anschlüssen unter MCP42010 nur noch 5 Volt und Masse, um die Arduino mit Strom zu versorgen.

Ansteuerung des MCP42010

Auszug Datenblatt MCP42010Wie im Datenblatt auf Seite 18 zu sehen, muss CS (PIN 10) für die Dauer der Übertragung auf Low gesetzt werden.
Für die Übertragung werden 2 Bytes gesendet.
Als erstes ein Steuerbyte, in dem die Operation (Schreiben) und der Pot (das gewünschte der beiden Potentiometer) angegeben wird.
Schreiben in Potentiometer 1 -> B00010001 und in Potentiometer 2 -> B00010010
Als zweites Byte wird der Wert übertragen, den das ausgewählte Potentiometer annehmen soll.
Anbei ein Minimal Beispiel, wie in das Potentiometer 1 (Pot0) der Wert 127, also ca. Mittelstellung geladen wird.

//minimal Example to set the Pot0 of a MCP42010 to the value 127 
#include 
void setup() {
  // take the CS pin low to select the chip:
  digitalWrite(10,LOW);
  //  send in the address and value via SPI:
  SPI.transfer(B00010001);
  // write out the value 127
  SPI.transfer(127);
  // take the CS pin high to de-select the chip:
  digitalWrite(10,HIGH);
}
 
void loop() {
 
}

Das Programm zur ‘komfortablen’ Ansteuerung der 2 Potentiometer des MCP42010

Die Bedienung ist sehr einfach gehalten, wie auch schon im Video oben zu sehen war. Ich übergebe Werte an das digitale Potentiometer und werte die resultierende Spannung an den analogen Eingängen A0 und A1 aus.
Für die Dateneingabe und -Ausgabe nutze ich den Seriellen Monitor der Arduino IDE.

Eingabe:
1:Wert von 0-255 -> setzt Potentiometer1 auf den Wert und gibt die Spannung an A0 zurück
2:Wert von 0-255 -> setzt Potentiometer2 auf den Wert und gibt die Spannung an A1 zurück
s -> gibt Werte beide Potentiometer und die Spannungen an A0 und A1 zurück

// inslude the SPI library:
#include 
 
// set pin 10 as the slave select for the digital pot:
const int slave_Select_Pin  = 10;
const int analogInPin0      = A0; 
const int analogInPin1      = A1; 
String    inputString       = "";         // a string to hold incoming data
boolean   stringComplete    = false;      // whether the string is complete
int       level1            = 0;
int       level2            = 0;
 
void setup() {
     inputString.reserve(100);
     // set the slaveSelectPin as an output:
     pinMode (slave_Select_Pin, OUTPUT);
     Serial.begin(9600);
 
     // initialize SPI:
     SPI.begin();
     MSP42010PotWrite(slave_Select_Pin, B00010001, level1);
     MSP42010PotWrite(slave_Select_Pin, B00010010, level2);
}
 
void loop() {
  if (stringComplete) {
    //check ob R1:
    if (inputString.substring(0, 2) == "1:") {
      level1 = inputString.substring(2).toInt();
      MSP42010PotWrite(slave_Select_Pin, B00010001, level1);     
      printValues(level1, analogInPin0);
    }
    //check ob R2:
    if (inputString.substring(0, 2) == "2:") {
      level2 = inputString.substring(2).toInt();
      MSP42010PotWrite(slave_Select_Pin, B00010010, level2); //Datasheet Page 18
      printValues(level2, analogInPin1);
    }
    //check ob s
    if (inputString.substring(0, 1) == "s") {
      printValues(level1, analogInPin0);
      printValues(level2, analogInPin1);
    }
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}
 
void MSP42010PotWrite(int slaveSelectPin, byte address, int value) {
     // take the SS pin low to select the chip:
     digitalWrite(slaveSelectPin,LOW);
     //  send in the address and value via SPI:
     SPI.transfer(address);
     SPI.transfer(value);
     // take the SS pin high to de-select the chip:
     digitalWrite(slaveSelectPin,HIGH);
}
void printValues(int level, int aPin) {
      delay(5);
      int pot = 0;
      if (aPin == 15) {
        pot = 1;
      }
      Serial.print("level Pot");
      Serial.print(pot);
      Serial.print(": ");
      Serial.print(level);
      Serial.print(" Spannung an A");
      Serial.print(pot);
      Serial.print(": ");
      double sl = analogRead(aPin);
      sl = sl * 5 / 1024; 
      Serial.print(sl);
      Serial.println(" Volt");  
}
/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    } else {
      inputString += inChar;
    }
  }
}