I2C-Analog Output 4 Kanäle 0-10V 10 Bit

Wir haben unser Produktspektrum um zwei neue I2C-Baugruppen zum aufschnappen auf die Norm-Hutschiene erweitert. Die Abmessungen der Leiterplatten sind 45,5 mm x 65,5 mm und passen in die WAGO Montagesockel für Kleinplatinen, die auf Standard-DIN-Schienen montiert werden können. Die Karten wird es ab Mitte Februar im Onlineshop zu kaufen geben.

Analoge Ausgabekarte mit 4 Kanälen und 10 Bit Auflösung

I2C-DAC 4 CH 10 Bit

I2C-Analog Output card 4 Chanel 0-10V 10 Bit

 

Allgemeines

Die Analog-Out Karte verfügt über insgesamt 4 D/A Wandler mit einer Auflösung von 10 Bit. Die Analog-Out Karte ist komplett Register gesteuert. Dies bedeutet es gibt keine Befehle! Einzig der Inhalt der Register steuert das Verhalten der Karte. Alle Daten werden in les- und schreibbaren Registern gespeichert.

Hardware

Gesteuert werden alle Vorgänge auf der Karte von einem Mikrokontroller (PIC 18F13K22). Dieser stellt die Verbindung zwischen dem I2C-Bus und den D/A-Wandlern her. Er sorgt dafür dass die Daten aus den Registern an die DA-Wandler MCP4812 gesendet werden. Die Ausgangsspannung lässt sich mit einer Breite von 10 Bit gegen eine interne Referenzspannung von 2,048 Volt einstellen. Die nachgeschalteten Operationsverstärker sorgen für eine Ausgangsspannung im Bereich von 0 – 10 Volt. Der minimale Wert liegt bei 0x0000 (dec. 0) der Maximale  0x03FF (dec. 1023). Der maximale Wert entspricht einer Spannung von 2,048 Volt am Ausgang des MCP4812 bzw. 10,24 Volt am Ausgang der Operationsverstärker.

I2C-Adresse

Wie bei allen Karten kann man die I2C-Adresse innerhalb eines gewissen Rahmens wählen. I2C-Adressen sind immer als 7+1 Bit Adressen aufgebaut. Das letzte Bit entscheidet darüber ob der Master lesen oder schreiben will. Auf gerade I2C-Adressen wird immer geschrieben – von ungeraden Adressen wird immer gelesen. Somit ergibt sich das auf der Adresse 0xB0 (176 dec.) Daten auf die Karte geschrieben und auf der Adresse 0xB1 (177 dec.) Daten von der Karte gelesen werden Mittels Jumper 3 lässt sich die Basisadresse der Karte einstellen.

Wird der Jumper in die Position OFF gestellt, so ist die Basisadresse 0xB0. Daraus ergeben sich folgende Adressen:

176 dez = B0 hex
178 dez = B2 hex
180 dez = B4 hex
182 dez = B6 hex
184 dez = B8 hex
186 dez = BA hex
188 dez = BC hex
190 dez = BE hex

In der Position ON ist die Basisadresse 0xD0. Daraus ergeben sich folgende Adressen:

208 dez = B0 hex
210 dez = D2 hex
212 dez = D4 hex
214 dez = D6 hex
216 dez = D8 hex
218 dez = DA hex
220 dez = DC hex
222 dez = DE hex

 

Datenübertragung

Bei der Datenübertragung können beliebig viele Bytes gesendet oder empfangen werden. Dabei gelten vier Regeln.

  • die Anzahl der Bytes muss immer ungerade sein (1, 3, 5 usw.)
  • es muss mindestens ein Byte übertragen werden
  • alle Registerwerte werden mit dem LSB voran gesendet
  • alle überflüssigen Schreib- oder Leseoperationen werden ignoriert.

Im einfachsten Fall schreibt man immer 3 Bytes zur Analogkarte.

Byte 1    Zeiger = 0
Byte 2    Analogwert 0 Low Byte
Byte 3    Analogwert 0 High Byte

 

Würde man weiter 2 Bytes übertragen landen diese im Analog-Kanal 1

Byte 1    Zeiger = 0
Byte 2    Analogwert 0 Low Byte
Byte 3    Analogwert 0 High Byte
Byte 4    Analogwert 1 Low Byte
Byte 5    Analogwert 1 High Byte

 

oder direkt nur auf Kanal 3

Byte 1     Zeiger = 3
Byte 2    Analogwert 3 Low Byte
Byte 3    Analogwert 3 High Byte

 

Beispiel für I2C-RS232-Modem 2 oder I2C-USB-Modem

Im Beispiel wird mit dem Befehl 51 das Übertragen der 3 Bytes zur Analogausgabekarte angest0ßen. Die Fehlerbehandlung soll nur einen Programmabsturz verhindern wenn in den feldern keine Zahlen eingegeben wurden..

Private Sub Command_AOUT1_SCHREIBEN_Click()
'Der Befehl I2C-Data 33 hex = 51 dez.
'liest oder schreibt bis zu 128 Bytes vom I2C-Slave

Dim Adr, HBy, LBy
Adr = Combo_AOUT_Adresse   'Adresse aus Cobo-Box

On Error GoTo ErrorHandler  'Für falsche Eingaben im Feld

If TextBox_AOUT1.Text > 1023 Then
    MsgBox ("Im Feld WERT nur Zahlen <= 1023 erlaubt")
    TextBox_AOUT1.Text = 1023
Else
    'HIGH-Byte berechnen
    HBy = Fix(TextBox_AOUT1.Text / 256)
    'LOW-Byte berechnen
    LBy = TextBox_AOUT1.Text - HBy * 256

    SENDBYTE (51)  'Befehl 51 = Daten senden
    SENDBYTE (5)   'Frame Anzahl = 5
    SENDBYTE (Adr) 'Bus-Adresse des PCF 8574
    SENDBYTE (0)   'Adresse MSB
    SENDBYTE (0)   'Kanal 0
    SENDBYTE (LBy) 'LOW-Byte schreiben
    SENDBYTE (HBy) 'HIGH-Byte schreiben
    SENDBYTE (4)   'Endekennung
End If

If Modem_Antwort = False Then
    MsgBox ("Fehler bei I2C-DATA")
End If

ErrorHandler:
Select Case ERR.Number              'Fehlernummer auswerten.
    Case 0 'ok
    Case 13
         MsgBox ("Im Feld WERT nur Zahlen erlaubt")
         TextBox_AOUT1.Text = "0"
    Case Else
        MsgBox ("Fehler " & ERR.Number)
    End Select

End Sub

 

34 Kommentare

  1. Hallo,
    kann diese Karte verwendet werden um Osram Quicktronic DIM EVG zu steuern?
    Die EVG haben eine 0-10V Schnittstelle, die jedoch schon selbst 10V (nachgemessen knapp 12) liefert, davon 0,6mA pro EVG. Ich hätte 6 EVG zu steuern wobei immer zwei über einen Ausgang gesteuert werden könnten. Macht dieser „gegenstrom“ dem Modul etwas aus oder kann dieses den Strom übersteuern?

    Viele Grüße

      • Hallo,
        das funktioniert optimal, ich habe sogar je zwei EVG pro Ausgang angehängt und auch dann ist dies kein Problem. Die einfache Ansteuerung und der übersichtliche aufbau machen es einem wirklich leicht.
        Im Prinzip würden her 1-10V reichen da das EVG unabhängig der Steuerspannung nur bis auf ca. 10% herunter regelt. Darunter wird es aber sowieso schwierig Leuchtstoffröhren zu betreiben, ist aber auch vollkommen ausreichend.
        Vielen Dank und viele Grüße

  2. Dear.

    I have bought this module a week ago and trying to get it up and running with a Py script.

    Is it mandatory to feed 12V (or max 30V) before the module is visible on the I2C network?
    I have (only) connected to lower connections of the module (5V+, GND, SDA and SCL), but the module is not visible (with i2cdetect) on my Raspberry Pi Zero W. I Don’t make use of a repeater, it’s directly linked to my RPi0W.

    Thank you in advance for your answer.

    Kindest regards.

    • Hello,
      it is not necessary to connect the 12V.
      The PIC is detected when it hangs on the bus with 5V.
      If you do not use a repeater you may need to install 10kOhm resistors between
      SCL and + 5V and
      SDA and + 5V

      But a Repeater is much better!
      Best wishes

  3. Hallo zusammen,
    in einer aufgebauten Anlage wird dieses Analogmodul verwendet um Umrichter anzusteuern.
    Nun wurde der Großteil bereits mit Matlab programmiert, nur hängt es noch an der Kommunikation mit dem Analogmodul. Es sind 3 Umrichter angeschlossen.

    Kann mir jemand helfen? Zumindest wie es vielleicht grundsätzlich mit der Kommunikation aussehen muss? Was muss gesendet werden?

    Bin ein bisschen Ratlos, da ich schon viel ausprobiert habe.

    Vielen Dank

    Chris

    • Hallo Chris,
      um den Analogwert für den ersten FU zu ändern müssen 3 Bytes zum Slave geschickt werden.
      Byte 1 0 (Zeiger)
      Byte 2 Analogwert 0 Low Byte
      Byte 3 Analogwert 0 High Byte

      Sollen alle drei Analogwerte gesendet werden müssen sieben Bytes geschickt werden.
      Byte 1 0 (Zeiger)
      Byte 2 Analogwert 0 Low Byte
      Byte 3 Analogwert 0 High Byte
      Byte 4 Analogwert 1 Low Byte
      Byte 5 Analogwert 1 High Byte
      Byte 6 Analogwert 2 Low Byte
      Byte 7 Analogwert 2 High Byte

      Wichtig!!
      Die Bytes müssen nacheinander, also ohne Pause gesendet werden.

  4. Hallo,
    ich nutze das Modul mit einem Controllino MEGA über i²c.
    Funktioniert einwandfrei!
    Hier der Code… bei Fragen einfach melden.
    Grüße

    #include // Bibliothek einbinden
    #include // I2C Schnittstelle einbinden

    int Analog_1 = 100; // Kanal 1: 1V
    int Analog_2 = 500; // Kanal 2: 5V
    int Analog_3 = 1000; // Kanal 3: 10V
    int Analog_4 = 800; // Kanal 4: 8V

    // Aufteilen des dezimalen zahlenwertes auf 2 Bytes:
    byte by_1_1 = Analog_1 & 0xFF; // Byte 1, Kanal 1
    byte by_2_1 = (Analog_1-by_1_1)/256; // Byte 2, Kanal 1
    byte by_1_2 = Analog_2 & 0xFF; // Byte 1, Kanal 2
    byte by_2_2 = (Analog_2-by_1_2)/256; // Byte 2, Kanal 2
    byte by_1_3 = Analog_3 & 0xFF; // Byte 1, Kanal 3
    byte by_2_3 = (Analog_3-by_1_3)/256; // Byte 2, Kanal 3
    byte by_1_4 = Analog_3 & 0xFF; // Byte 1, Kanal 4
    byte by_2_4 = (Analog_3-by_1_3)/256; // Byte 2, Kanal 4
    byte Kanal = 0; // Kanalauswahl

    void setup() {
    Wire.begin();
    }

    void loop() {
    Wire.beginTransmission(0xB0>>1); // Beginn der Übertragung
    // an Adresse 0xB0 (Hex) = 176 (Dez)
    // „>>1“ –> Bitmanipulation: verschiebt Moduladresse um eine Stelle (Bit) nach rechts
    // da nur 7 Bits gesendet werden können, Moduladresse aber aus 8 Bits besteht
    Wire.write(Kanal); // sende Kanal 0 –> auswählen/aktivieren
    // Werte werden gespiegelt mit LSB voran gesendet
    // daher zuerst by_1x, dann by_2_x senden
    Wire.write(by_1_1); // sende Byte 1 Kanal 1
    Wire.write(by_2_1); // sende Byte 2 Kanal 1
    Wire.write(by_1_2); // sende Byte 1 Kanal 2
    Wire.write(by_2_2); // sende Byte 2 Kanal 2
    Wire.write(by_1_3); // sende Byte 1 Kanal 3
    Wire.write(by_2_3); // sende Byte 2 Kanal 3
    Wire.write(by_1_4); // sende Byte 1 Kanal 4
    Wire.write(by_2_4); // sende Byte 2 Kanal 4
    Wire.endTransmission(); // Ende der Übertragung
    }

    • Hallo,
      eine I2C-PT100 RDC oder I2C-PT1000 RDC ist derzeit nicht geplant.
      Besorgen Sie sich „PT100 Temperatur Messumformer 0-100C Ausgang 0-10V DC“ und schließen Sie diese an die Analoge Eingangskarte an.
      Messumformer „PT100 4-20mA 24VDC“ können Sie über einen 500 Ohm Widerstand auch anschließen.
      20mA Sensor an I2C-Analogkarte
      Wir planen aber eine I2C-Karte für max. 5 Thermoelemente mit dem MAX31855.

    • Hallo,
      mit I2Cset kann man meines Wissens nur ein Byte übertragen

      i2cset -y 1 0x20 0xFF       überträgt FF an einen Slave an Adresse 20

      oder in ein Byte in ein definiertes Register schreiben

      i2cset -y 1 0x50 0x00 0x10      Schreibt in ein EEprom an Adresse 50 an die Speicherzelle 0 den Wert 10

      Unsere Analog-Karte braucht aber mindestens 3 Byte hintereinander ohne ACK damit ein Kanal angesprochen werden kann.

      Byte 1 Zeiger = 0
      Byte 2 Analogwert 0 Low Byte
      Byte 3 Analogwert 0 High Byte

      Der Analogwert z.B. vom Kanal 0 bleibt bestehen, wenn ein neuer Wert zum Kanal 2 geschrieben wird

      Byte 1 Zeiger = 2
      Byte 2 Analogwert 2 Low Byte
      Byte 3 Analogwert 2 High Byte

      Gruß, JH

  5. Hallo,

    ich nutze den RPI 3 Model B mit dem I2C Repeater und der Analogkarte. 12V sind eingespeist.
    Ich erhalte jedoch keine Spannungsänderung am A1 GND mit folgendem Phython Code:

    import smbus

    bus = smbus.SMBus(1)
    aout = 1023

    Hby = int (aout / 256)
    LBY = int (aout – Hby * 256)
    field = [LBY, Hby]
    bus.write_i2c_block_data (0x58, 0x00, field)

    Bitte um Hilfe 🙂

  6. Hallo,

    ich teste die analog out karte mit einem raspberrypi mit repeater. 12 V sind am Eingang. I2C Ansteuerung von LED’s war o.k.
    Leider war keine Spannungsaenderung an A1 GND messbar.
    Für einen Hinweis wäre ich dankbar.

    Der Code:

    # test I2C-Analog Output am raspberrypi

    import time
    import pigpio # ’sudo service –status-all‘
    # deamon ‚piogpiod‘
    import sys

    BUS = 1

    PIC_I2C_ADDR = 0x58 # with ’sudo i2cdetect -y 1′

    pi = pigpio.pi() # open local Pi
    h = pi.i2c_open(BUS, PIC_I2C_ADDR) # open device at address 0x58 on bus 1
    if h >= 0: # Connected OK?
    print(h)
    pi.i2c_write_byte(h,0) # send byte 0 chanal 0
    pi.i2c_write_byte(h,0x03) # send high byte
    pi.i2c_write_byte(h,0xFF) # send low byte

    pi.i2c_close(h)

    pi.stop()

    • Hallo Ulf,

      Entschuldigung für nicht Deutsch…

      I have successfully used this product with a Raspberry Pi. I have a small Python test script that sets the A1 output to 0V and then increases to 10V over a few seconds.

      On the Pi header, I connected the Pi 3.3V to +5 on the board, GND – GND, SDA – SDA, SCL – SCL.

      The script needs smbus for Python3 to be installed:
      sudo apt-get install python3-smbus

      Here is the script:

      #!/usr/bin/env python

      import smbus
      import time

      # Horter.de 4 channel analogue output 10V 10bit module
      # value range 0 – 1023 for 0 – 10V on the analog outputs

      bus = smbus.SMBus(1)
      aout = 0

      try:

      while True:

      aout = aout + 1
      Hby = int (aout / 256)
      LBY = int (aout – Hby * 256)
      field = [LBY, Hby]
      print (field)
      bus.write_i2c_block_data (0x58, 0x00, field)

      time.sleep(0.01)
      print (aout)

      if aout > 1023:
      aout = 0
      break

      except:
      pass

  7. Hallo,

    es sollte doch problemlos möglich sein, eine Versorgungsspannung von 24 V statt 12 V zu wählen. Der verwendete LM324 ist schließlich bis 32 V spezifiziert. Oder sehe ich das falsch?
    Für 12 V müsste ich nämlich einen eigenen Spannungsregler vorsehen, und den Aufwand möchte ich mir gerne sparen.
    Der gewünschte Ausgangsspannungsbereich soll dabei unverändert 0 V … 10 V sein.

    Über eine Antwort freue ich mich. Danke

  8. thank you . since i am using i2c on smbus (beaglebone black with ubuntu ) i tried to write the three bytes as you instructed . i defined a new method in the Adafruit_I2C to expose the smbus write_byte method. i then called it three times to send each individual byte . the bytes are formatted correctly as seen through print command , however the channels are not outputting values . i checked both on the DAC output and the card 0~10V output . i’m new to i2c so am working as closely as possible with existant code . the code which i’m emulating expect register values . is there a dummy register value i can include ? i tried using the channel number as the register , to no effect . thanks again .

  9. can you include an example of the I2C Analog Output 0-10V 4 channel 10 bit instead of the modem . can you explain “ The analog output card is completely controlled register. This means there are no instructions! Only the contents of registers controls the behavior of the map.“ (google translation). my co-workers purchased these and handed them off to me without realizing they are more complicated than single output units. do we have to contact the PIC to program it , or is there a register map to write values to the four outputs ?

    • Hello John,

      to an analog value output on channel 0 they simply send 3 bytes to the slave.

      Byte 1 = 0 (Channel 0)
      Byte 2 = HBy (High Byte from analog value)
      Byte 2 = LBy (Low Byte from analog value)

      ‚Calculate HIGH Byte
      HBy = Fix(Ananlog_Value / 256)
      ‚Calculate HIGH Byte
      LBy = Ananlog_Value – HBy * 256

      The analog value must be between 0 and 1023 (0=0V 1000=10V)

      To 5V output at output 3 will send the following 3 Bytes

      Byte 1 = 3
      Byte 2 = 1
      Byte 2 = 244

      I hope I could help

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.