I2C-Poti ansteuern: MCP45xx

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo Forum,

    ich würde gerne ein digitales I2C-Potentiometer an's Laufen bringen und verfüge leider weder über C++-, noch Python-Kenntnisse. Bash-Skripte kriege ich meist noch irgendwie hin. Doch das Umschreiben vorhandener Codebeispiele bereitet mir arge Probleme.

    Konkret versuche ich es gerade mit C++ nach diesem Beispiel (http://blog.stibrany.com/?p=9). Der Typ betreibt den MCP4561. Ich möchte hingegen den MCP4551 ansteuern. Er besitzt, im Unterschied zum MCP4561, keinen Speicher.
    Leider hat der Blogger eine Closed-Source I2C-library verwendet und empfiehlt zum Nachmachen diese hier. Dafür muss sein Programm lediglich "ein bißchen" umgeschrieben werden.

    OK, ich hab das jetzt versucht, doch weiß ich weder, ob meine Änderungen alle richtig sind, noch wie das Ding überhaupt gestartet wird. Da wird ja kreuz und quer verlinkt und "included", sodass ich nichtmal weiß, wo überhaupt das Testprogramm hinkäme. Der soll einfach nur den Poti rauf- und runterdrehen - und das in einer Endlosschleife. Feinheiten kann ich mir dann ja überlegen.

    Meine bisherigen Codeschnipsel sehen so aus:

    mcp4551.h:

    mcp4551.cpp (erste Zeile aus dem Original muss bestimmt weg, zweite Zeile ist von mir und soll auf die alternative I2C-Bibliothek verweisen):


    main.cpp:


    Die I2C-Bibliothek habe ich nicht verändert, deshalb nur die Header-Datei, wo man die Funktionsnamen sieht (die wichen von den aufgerufenen Funktionen im Original-Programm ab, weil ja eine kommerzielle Bibliothek verwendet wurde). Den Rest der Opnsource-Bibliothek hänge ich als Zip-Datei an, falls jemand daran interessiert ist:

    Da ich im Detail nur Bahnhof verstehe, hoffe ich mir kann jemand beim Zusammenfügen der Teile helfen. Ich will einfach nur diesem Poti Befehle senden können.

  • > [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]ich würde gerne ein digitales I2C-Potentiometer an's Laufen bringen und verfüge[/font]
    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]> leider weder über C++-, noch Python-Kenntnisse. Bash-Skripte kriege ich meist[/font]
    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]> noch irgendwie hin.[/font]
    Mit dieser Ausgangslage wuerde ich ein bash-Script mit i2cset schreiben. Um
    ein Poti zu steuern muesste das auch schnell genug sein.


  • > [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]ich würde gerne ein digitales I2C-Potentiometer an's Laufen bringen und verfüge[/font]
    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]> leider weder über C++-, noch Python-Kenntnisse. Bash-Skripte kriege ich meist[/font]
    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]> noch irgendwie hin.[/font]
    Mit dieser Ausgangslage wuerde ich ein bash-Script mit i2cset schreiben. Um
    ein Poti zu steuern muesste das auch schnell genug sein.

    Das sieht wirklich interessant aus. Vielen Dank schonmal. Muss ich mir Gedanken machen, um Sachen wie Timing, Busfrequenz, Start- und Stopbits etc? Ich frage, weil ich irgendwo gelesen habe, dass man sich mit i2cset auch Chips zerschießen kann. Es klingt also nach einem Low-Level-Tool, wie dd.

  • > Muss ich mir Gedanken machen, um Sachen wie Timing, Busfrequenz, Start- und Stopbits etc?
    Busfrequenz weiss ich nicht, es funktionierte einfach mit dem Chip mit dem ich es probiert habe.

    Die anderen Werte sind gegeben, das hat das Tool im Griff.

    > Ich frage, weil ich irgendwo gelesen habe, dass man sich mit i2cset auch Chips zerschießen kann
    Die Warnung auf der man-Seite?

    Ja, klar, wenn man planlos in beliebige Chips schreibt ist das gefaehrlich.

    ABER garantiert weniger gefaehrlich als mit einem zusammenkopierten C-Programm.

  • Das probier ich aus! Vielen Dank.

    Edit:

    Tja, also das funktioniert bei mir irgendwie nicht.

    Egal was ich da ausprobiere, das Ohmmeter zeigt nichts an:

    Code
    i2cset -y 1 0x2f 0x00 0x14
    i2cset -y 1 0x2f 0x00 0x14 b
    i2cset -y 1 0x2f 0x00 0x04
    i2cset -y 1 0x2f 0x00 0x40

    In dem Datenblatt ist lang und breit erklärt, wie man die Bit-Sequenz aufbaut und wie oft man welche Sequenz wiederholen muss, damit dies und das passiert. Von Bytes, Words und Block-Writes steht da schlichtweg nichts.

    der i2cset-Befehl lautet ja:

    i2cset [-f] [-y] [-m mask] [-r] i2cbus chip-address data-address [value] ... [mode]

    also z.B.:
    i2cset -y 1 0x2f 0x00 0x14 b
    i2cset [y für imm er "yes", also keine Rückfragen] [Busnummer 1 in meinem Fall] [Chip-Adresse (per i2cdetect gefunden)] [Schreib-Adresse 0x00 soll Schreiben bedeuten] [0x14 ist 20 in Dezimal und soll einfach irgendein Wert sein] [b für Byte-Mode, w wäre word]

    Tja...und es passiert halt nichts. Hab ebenfalls einfach mal versucht, die cpp-Dateien zu kompilieren:
    Wie ich mir schon dachte, findet er die Verlinkungen nicht.

    C
    gcc mcp4551.cpp
    mcp4551.cpp:1:28: fatal error: xlib/core/i2c.h: Datei oder Verzeichnis nicht gefunden
    #include <xlib/core/i2c.h>
                               ^
    compilation terminated.


    Weil "Xlib/core/i2c.h" ja (wie zuvor erwähnt) die Closed-Source-Bibliothek war, hab ich die Zeile einfach mal gelöscht. Jetzt kommt das hier:

    C
    gcc mcp4551.cpp
    In file included from mcp4551.cpp:1:0:
    ./i2cmaster/i2cmaster.h:89:20: fatal error: avr/io.h: Datei oder Verzeichnis nicht gefunden
    #include <avr/io.h>
                       ^
    compilation terminated.
    C
    gcc ./main.cpp
    ./main.cpp:1:20: fatal error: avr/io.h: Datei oder Verzeichnis nicht gefunden
    #include <avr/io.h>
                       ^
    compilation terminated.

    Die Opensource i2c-Bibliothek benutzt also irgendwas was bei mir nicht da ist. IRgendeine Ahnung was das sein kann? avr/io.h ?

    Einmal editiert, zuletzt von snoopy123 (2. Mai 2017 um 15:57)

  • [font="monospace"]> i2cset -y 1 0x2f 0x00 0x14[/font]
    [font="monospace"]Stimmt das 0x2F wirklich? Ich haette auf 0x5? getippt.[/font]

    [font="monospace"]Und dann denke ich, dass es noch mindestens ein Byte mehr braucht.[/font]

    [font="monospace"]> avr/io.h ?[/font]
    [font="monospace"]AVR ist ein anderer Prozessor. Der Code ist also NICHT fuer den Raspberry gemacht.[/font]

    [font="monospace"]Das heisst natuerlich nicht, dass man es nicht hinkriegt (wenn man weiss was an macht). Aber einfach durch den Compiler schicken und dann laufen lassen wird hoechst wahrscheinlich nicht funktionieren.[/font]


  • [font="monospace"]> i2cset -y 1 0x2f 0x00 0x14[/font]
    [font="monospace"]Stimmt das 0x2F wirklich? Ich haette auf 0x5? getippt.[/font]


    Warum das denn? Natürlich stimmt das. Die Adresse ist Bauteilspezifisch, da kannst Du gar nichts tippen.

    Zitat

    [font="monospace"]AVR ist ein anderer Prozessor. Der Code ist also NICHT fuer den Raspberry gemacht.[/font]

    Zitat

    [font="monospace"]einfach durch den Compiler schicken und dann laufen lassen wird hoechst wahrscheinlich nicht funktionieren.[/font]

    Doch, höchstwahrscheinlich schon. Der Code ist nämlich für den Poti gemacht. Gerätespezifisch ist da sehr wahrscheinlich nur diese dämliche Bibliothek. Guck doch wenigstens mal rein, in den Code, bevor du Vermutungen äußerst.

    io.h klingt nach input/output, also irgendeine general-purpose-bibliothek, wie sie standardmäßig bei programmiersprachen verwendet wird. Die lässt sich bestimmt ersetzen, wenn die für nen bestimmten prozessor war..

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!