A/D mcp3424 I2C

Fragen zu Raspberry, FritzBox, Microcontroller, UART, etc...
Antworten
tgreif
Foriker
Beiträge: 14
Registriert: Sa 12. Mär 2016, 14:59
Kontaktdaten:

A/D mcp3424 I2C

Beitrag von tgreif » Do 31. Mär 2016, 17:39

Hallo an alle , ich bin ein weiterer neuer, mit einem hoffentlich kleinem problem .
ich wuerde gerne ein A/D ueber di I2C Schnittstelle ansteuern. di Kommunikation selbst funktioniert schon . das mcp3424 wird mit dem befehl "i2cdetect -y 1" mit der Adresse 0x68 erkannt.
leider habe ich absolut keine Ahnung wie ich jetzt mit Gambas die werte auslesen.
hat einer von euch schon ein kleines Programm ??? gibt es eine Beispielanwendung unter Gambas??

danke im voraus

tgreif
Foriker
Beiträge: 14
Registriert: Sa 12. Mär 2016, 14:59
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tgreif » Mo 4. Apr 2016, 21:35

hallo an alle .

ich habe mitlerweile die werte mit pyton auslesen koennen .

soweit so gut .
leider habe ich aber immer noch keine loesung in gambas gefunden .

Frigo2010
Foriker
Beiträge: 12
Registriert: Sa 13. Feb 2016, 08:30
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von Frigo2010 » Di 5. Apr 2016, 10:59

Hallo

Ich weiß zwar nicht was du genau machen möchtest, aber eventuell hilft dir das hier weiter

http://www.strippenstrolch.de/5-5-2-RS2 ... ambas.html


Gruß

Frigo

PS: https://www.google.de/search?q=i2c+gambas&oq=i2c+gambas

tgreif
Foriker
Beiträge: 14
Registriert: Sa 12. Mär 2016, 14:59
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tgreif » Mi 6. Apr 2016, 18:21

hallo Frigo2010

danke fuer den tip . werd mal durchschauen ob es mir hilft.
im prinzip moecte ich an den i2c bus ein ad wandler mit 4 kanaelen haengen , und dann die ausgelesenen werte im programm weiterverarbeiten.
im moment benutze ich python und kann mitlerweile die kanaele auslesen . das python program starte ich in gambas mit dem exec befehl und uebergebe dann die werte der 4 kanaele an 4 verschiedene textboxen. dafuer benutze ich di python files von ABelectronics
[url]git clone https://github.com/abelectronicsuk/ABEl ... raries.git[/url]
:

Code: Alles auswählen

Dim ttx As String
TextBox6.text = TextBox6.text + Str(1)
   
Exec ["python", "/home/pi/Scaricati/ABElectronics_Python3_Libraries-master/ADCPi/demo-readvoltage.py", "-p"] To ttx

''auslesen der werte und in text box anzeigen
TextBox1.text = Mid(ttx, 1, 8)  'chanel 1
TextBox2.text = Mid(ttx, 10, 9) 'chanel 2
TextBox3.text = Mid(ttx, 19, 9) 'chanel 3
TextBox4.text = Mid(ttx, 28, 9) 'chanel 4

End


allerdings waere es schoen wenn ich mit gambas die werte der analogeingange direkt auslesen koente , damit ich nicht ein externes programm starten muss.

tux_
Moderator
Beiträge: 942
Registriert: Di 11. Nov 2008, 20:05
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tux_ » Mi 6. Apr 2016, 18:51

Wenn du dafuer schon eine Extra-Bibliothek in Python hast, dann bist du doch in der gluecklichen Situation, sie nur noch auf Gambas umschreiben zu muessen. Ich kann zwar kein Python, aber es sieht so aus, als muesstest du nur die Klasse ADCPi[1] portieren. Nach kurzem Druebersehen scheint der Code recht geradlinig zu sein. Fuer i2c kannst du vielleicht einfach Dateien in /dev verwenden[2]. In Gambas sind hierbei die Instruktionen Open, Read, Write und Seek[3] relevant.

[1] https://github.com/abelectronicsuk/ABElectronics_Python3_Libraries/blob/master/ADCPi/ABE_ADCPi.py
[2] https://www.kernel.org/doc/Documentation/i2c/dev-interface
[3] http://gambaswiki.org/wiki/cat/stream
Achtung: Es passiert, dass ich einen frisch geschrieben Beitrag innerhalb von 10 Minuten noch 3-4 Mal aendere!

tgreif
Foriker
Beiträge: 14
Registriert: Sa 12. Mär 2016, 14:59
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tgreif » Mi 6. Apr 2016, 20:20

hallo tux danke fuer die antwort.
das script [url]
[1] https://github.com/abelectronicsuk/ABEl ... E_ADCPi.py[/url] soll( so glaube ich) nur die konfiguration uebernehmen.
das eigentliche auslesen der werte wird mit diesen code gestartet.
python3 code
#!/usr/bin/python3
from ABE_ADCPi import ADCPi
from ABE_helpers import ABEHelpers
import time
import os
"""================================================
ABElectronics ADC Pi 8-Channel ADC demo
Version 1.0 Created 29/02/2015
Requires python 3 smbus to be installed
run with: python3 demo-read_voltage.py
================================================
Initialise the ADC device using the default addresses and sample rate,
change this value if you have changed the address selection jumpers
Sample rate can be 12,14, 16 or 18
"""
i2c_helper = ABEHelpers()
bus = i2c_helper.get_smbus()
adc = ADCPi(bus, 0x68, 18)
#while (True):
# clear the console
#os.system('clear')

# read from adc channels and print to screen
print ("%02f" % adc.read_voltage(1))
print ("%02f" % adc.read_voltage(2))
print ("%02f" % adc.read_voltage(3))
print ("%02f" % adc.read_voltage(4))
#print ("Channel 5: %02f" % adc.read_voltage(5))
#print ("Channel 6: %02f" % adc.read_voltage(6))
#print ("Channel 7: %02f" % adc.read_voltage(7))
#print ("Channel 8: %02f" % adc.read_voltage(8))

# wait 0.5 seconds before reading the pins again
# time.sleep(0.8)

in dem ich sowohl die schleife als auch das lesen der eingaenge 5-8 kommentiert habe .
ich wuerde es auch gerne umschreiben , ich weis leider nicht wie das geht .... :?: :?: :?:
Zuletzt geändert von tux_ am Mi 6. Apr 2016, 20:57, insgesamt 1-mal geändert.
Grund: Bitte die hicode-Tags fuer Programm-Code verwenden.

tux_
Moderator
Beiträge: 942
Registriert: Di 11. Nov 2008, 20:05
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tux_ » Mi 6. Apr 2016, 20:59

Das ADCPi uebernimmt nicht nur die Konfiguration. Mit adc.read_voltage() werden in deinem Schnipsel die gewuenschten Werte gelesen und adc ist vom Typ ADCPi. Also steht in der Klasse ADCPi auch drin, wie man Werte aus dem Geraet ausliest.
Achtung: Es passiert, dass ich einen frisch geschrieben Beitrag innerhalb von 10 Minuten noch 3-4 Mal aendere!

tgreif
Foriker
Beiträge: 14
Registriert: Sa 12. Mär 2016, 14:59
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tgreif » Mi 6. Apr 2016, 22:34

hallo tux danke .
wenn ich das dann richtig verstanden habe , macht folgender code python3 code
print ("%02f" % adc.read_voltage(1))

dass die werte ausgelesenwerden und dann im terminal ausgegeben werden mit der formatierung wi angegeben. richtig?
und der folgende code ist nicht nur konfiguratio , sondern notwendig zum auslesen! richtig? (entschuldige meine unwissenheit , bin neu sowohl bei linux, gambas, und python)
versuche aber mein bestes.. versprochen
python3 code
#!/usr/bin/python3

"""
================================================
ABElectronics ADC Pi V2 8-Channel ADC
Version 1.0 Created 29/02/2015
Requires python 3 smbus to be installed
================================================
"""


class ADCPi:
# internal variables

__address = 0x68 # default address for adc 1 on adc pi and delta-sigma pi
__address2 = 0x69 # default address for adc 2 on adc pi and delta-sigma pi
__config1 = 0x9C # PGAx1, 18 bit, continuous conversion, channel 1
__currentchannel1 = 1 # channel variable for adc 1
__config2 = 0x9C # PGAx1, 18 bit, continuous-shot conversion, channel 1
__currentchannel2 = 1 # channel variable for adc2
__bitrate = 18 # current bitrate
__conversionmode = 1 # Conversion Mode
__pga = float(0.5) # current pga setting
__lsb = float(0.0000078125) # default lsb value for 18 bit

# create byte array and fill with initial values to define size
__adcreading = bytearray()
__adcreading.append(0x00)
__adcreading.append(0x00)
__adcreading.append(0x00)
__adcreading.append(0x00)

global _bus

# local methods

def __updatebyte(self, byte, bit, value):
# internal method for setting the value of a single bit within a
# byte
if value == 0:
return byte & ~(1 << bit)
elif value == 1:
return byte | (1 << bit)

def __checkbit(self, byte, bit):
# internal method for reading the value of a single bit within a
# byte
bitval = ((byte & (1 << bit)) != 0)
if (bitval == 1):
return True
else:
return False

def __twos_comp(self, val, bits):
if((val & (1 << (bits - 1))) != 0):
val = val - (1 << bits)
return val

def __setchannel(self, channel):
# internal method for updating the config to the selected channel
if channel < 5:
if channel != self.__currentchannel1:
if channel == 1:
self.__config1 = self.__updatebyte(self.__config1, 5, 0)
self.__config1 = self.__updatebyte(self.__config1, 6, 0)
self.__currentchannel1 = 1
if channel == 2:
self.__config1 = self.__updatebyte(self.__config1, 5, 1)
self.__config1 = self.__updatebyte(self.__config1, 6, 0)
self.__currentchannel1 = 2
if channel == 3:
self.__config1 = self.__updatebyte(self.__config1, 5, 0)
self.__config1 = self.__updatebyte(self.__config1, 6, 1)
self.__currentchannel1 = 3
if channel == 4:
self.__config1 = self.__updatebyte(self.__config1, 5, 1)
self.__config1 = self.__updatebyte(self.__config1, 6, 1)
self.__currentchannel1 = 4
else:
if channel != self.__currentchannel2:
if channel == 5:
self.__config2 = self.__updatebyte(self.__config2, 5, 0)
self.__config2 = self.__updatebyte(self.__config2, 6, 0)
self.__currentchannel2 = 5
if channel == 6:
self.__config2 = self.__updatebyte(self.__config2, 5, 1)
self.__config2 = self.__updatebyte(self.__config2, 6, 0)
self.__currentchannel2 = 6
if channel == 7:
self.__config2 = self.__updatebyte(self.__config2, 5, 0)
self.__config2 = self.__updatebyte(self.__config2, 6, 1)
self.__currentchannel2 = 7
if channel == 8:
self.__config2 = self.__updatebyte(self.__config2, 5, 1)
self.__config2 = self.__updatebyte(self.__config2, 6, 1)
self.__currentchannel2 = 8
return

# init object with i2caddress, default is 0x68, 0x69 for ADCoPi board
def __init__(self, bus, address=0x68, address2=0x69, rate=18):
self._bus = bus
self.__address = address
self.__address2 = address2
self.set_bit_rate(rate)

def read_voltage(self, channel):
# returns the voltage from the selected adc channel - channels 1 to
# 8
raw = self.read_raw(channel)
if (self.__signbit):
return float(0.0) # returned a negative voltage so return 0
else:
voltage = float(
(raw * (self.__lsb / self.__pga)) * 2.471)
return float(voltage)

def read_raw(self, channel):
# reads the raw value from the selected adc channel - channels 1 to 8
h = 0
l = 0
m = 0
s = 0

# get the config and i2c address for the selected channel
self.__setchannel(channel)
if (channel < 5):
config = self.__config1
address = self.__address
else:
config = self.__config2
address = self.__address2

# if the conversion mode is set to one-shot update the ready bit to 1
if (self.__conversionmode == 0):
config = self.__updatebyte(config, 7, 1)
self._bus.write_byte(address, config)
config = self.__updatebyte(config, 7, 0)
# keep reading the adc data until the conversion result is ready
while True:

__adcreading = self._bus.read_i2c_block_data(address, config, 4)
if self.__bitrate == 18:
h = __adcreading[0]
m = __adcreading[1]
l = __adcreading[2]
s = __adcreading[3]
else:
h = __adcreading[0]
m = __adcreading[1]
s = __adcreading[2]
if self.__checkbit(s, 7) == 0:
break

self.__signbit = False
t = 0.0
# extract the returned bytes and combine in the correct order
if self.__bitrate == 18:
t = ((h & 0b00000011) << 16) | (m << 8) | l
self.__signbit = bool(self.__checkbit(t, 17))
if self.__signbit:
t = self.__updatebyte(t, 17, 0)

if self.__bitrate == 16:
t = (h << 8) | m
self.__signbit = bool(self.__checkbit(t, 15))
if self.__signbit:
t = self.__updatebyte(t, 15, 0)

if self.__bitrate == 14:
t = ((h & 0b00111111) << 8) | m
self.__signbit = self.__checkbit(t, 13)
if self.__signbit:
t = self.__updatebyte(t, 13, 0)

if self.__bitrate == 12:
t = ((h & 0b00001111) << 8) | m
self.__signbit = self.__checkbit(t, 11)
if self.__signbit:
t = self.__updatebyte(t, 11, 0)

return t

def set_pga(self, gain):
"""
PGA gain selection
1 = 1x
2 = 2x
4 = 4x
8 = 8x
"""

if gain == 1:
self.__config1 = self.__updatebyte(self.__config1, 0, 0)
self.__config1 = self.__updatebyte(self.__config1, 1, 0)
self.__config2 = self.__updatebyte(self.__config2, 0, 0)
self.__config2 = self.__updatebyte(self.__config2, 1, 0)
self.__pga = 0.5
if gain == 2:
self.__config1 = self.__updatebyte(self.__config1, 0, 1)
self.__config1 = self.__updatebyte(self.__config1, 1, 0)
self.__config2 = self.__updatebyte(self.__config2, 0, 1)
self.__config2 = self.__updatebyte(self.__config2, 1, 0)
self.__pga = 1
if gain == 4:
self.__config1 = self.__updatebyte(self.__config1, 0, 0)
self.__config1 = self.__updatebyte(self.__config1, 1, 1)
self.__config2 = self.__updatebyte(self.__config2, 0, 0)
self.__config2 = self.__updatebyte(self.__config2, 1, 1)
self.__pga = 2
if gain == 8:
self.__config1 = self.__updatebyte(self.__config1, 0, 1)
self.__config1 = self.__updatebyte(self.__config1, 1, 1)
self.__config2 = self.__updatebyte(self.__config2, 0, 1)
self.__config2 = self.__updatebyte(self.__config2, 1, 1)
self.__pga = 4

self._bus.write_byte(self.__address, self.__config1)
self._bus.write_byte(self.__address2, self.__config2)
return

def set_bit_rate(self, rate):
"""
sample rate and resolution
12 = 12 bit (240SPS max)
14 = 14 bit (60SPS max)
16 = 16 bit (15SPS max)
18 = 18 bit (3.75SPS max)
"""

if rate == 12:
self.__config1 = self.__updatebyte(self.__config1, 2, 0)
self.__config1 = self.__updatebyte(self.__config1, 3, 0)
self.__config2 = self.__updatebyte(self.__config2, 2, 0)
self.__config2 = self.__updatebyte(self.__config2, 3, 0)
self.__bitrate = 12
self.__lsb = 0.0005
if rate == 14:
self.__config1 = self.__updatebyte(self.__config1, 2, 1)
self.__config1 = self.__updatebyte(self.__config1, 3, 0)
self.__config2 = self.__updatebyte(self.__config2, 2, 1)
self.__config2 = self.__updatebyte(self.__config2, 3, 0)
self.__bitrate = 14
self.__lsb = 0.000125
if rate == 16:
self.__config1 = self.__updatebyte(self.__config1, 2, 0)
self.__config1 = self.__updatebyte(self.__config1, 3, 1)
self.__config2 = self.__updatebyte(self.__config2, 2, 0)
self.__config2 = self.__updatebyte(self.__config2, 3, 1)
self.__bitrate = 16
self.__lsb = 0.00003125
if rate == 18:
self.__config1 = self.__updatebyte(self.__config1, 2, 1)
self.__config1 = self.__updatebyte(self.__config1, 3, 1)
self.__config2 = self.__updatebyte(self.__config2, 2, 1)
self.__config2 = self.__updatebyte(self.__config2, 3, 1)
self.__bitrate = 18
self.__lsb = 0.0000078125

self._bus.write_byte(self.__address, self.__config1)
self._bus.write_byte(self.__address2, self.__config2)
return

def set_conversion_mode(self, mode):
"""
conversion mode for adc
0 = One shot conversion mode
1 = Continuous conversion mode
"""
if (mode == 0):
self.__config1 = self.__updatebyte(self.__config1, 4, 0)
self.__config2 = self.__updatebyte(self.__config2, 4, 0)
self.__conversionmode = 0
if (mode == 1):
self.__config1 = self.__updatebyte(self.__config1, 4, 1)
self.__config2 = self.__updatebyte(self.__config2, 4, 1)
self.__conversionmode = 1
#self._bus.write_byte(self.__address, self.__config1)
#self._bus.write_byte(self.__address2, self.__config2)
return
Zuletzt geändert von tux_ am Do 7. Apr 2016, 08:04, insgesamt 1-mal geändert.
Grund: Bitte hicode- statt code-Tags verwenden

tux_
Moderator
Beiträge: 942
Registriert: Di 11. Nov 2008, 20:05
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tux_ » Do 7. Apr 2016, 08:19

und der folgende code ist nicht nur konfiguratio , sondern notwendig zum auslesen! richtig?

Ja, die Funktionen read_voltage() und read_raw() tun das.

(entschuldige meine unwissenheit , bin neu sowohl bei linux, gambas, und python)
versuche aber mein bestes.. versprochen

Das wusste ich nicht. An sich passiert dort auf der Python-Seite nicht viel auszer Bit-Operationen und Arithmetik. Beides gibt es in Gambas auch. Es koennte aber ein Problem sein, als Linux-Neuling an die I2C-Daten zu kommen. Wie du vielleicht siehst, besteht die Hauptarbeit von read_voltage() daraus, read_raw() aufzurufen. read_raw() wiederum ruft im wesentlichen nur self._bus.read_i2c_block_data(address, config, 4) auf (der Rest des Codes in der Funktion sind Rechnungen). Wenn ich mich nicht irre ist self._bus vom Typ SMBus, der wiederum hier[1] in C implementiert ist. Dort sieht man, dass die Python-Bibliothek auch nur mit Wasser kocht und das /dev-Interface verwendet, dessen Beschreibung ich dir gestern verlinkt habe.

Vielleicht finde ich heute abend auch etwas Zeit, zumindest den C-Code in Gambas zu uebersetzen.

[1] https://github.com/abelectronicsuk/ABEl ... usmodule.c
Achtung: Es passiert, dass ich einen frisch geschrieben Beitrag innerhalb von 10 Minuten noch 3-4 Mal aendere!

tux_
Moderator
Beiträge: 942
Registriert: Di 11. Nov 2008, 20:05
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tux_ » Do 7. Apr 2016, 18:11

Im Anhang ist ein Versuch, die SMBus-Klasse in Gambas zu schreiben. Beachte aber, dass ich den Code nicht getestet habe. Gar nicht. Ich habe nicht einmal ein RPi. Der Code koennte einfach funktionieren, er koennte abstuerzen, die CPU aufheizen oder sonstwas. Du arbeitest hier auszerdem an der haesslichsten Seite von Gambas: der Schnittstelle zu C-Bibliotheken bzw. zum Kernel. Die Alternative zu solchen Hacks wie im Anhang ist eine ordentliche I2C-Komponente fuer Gambas. Bisher hat sich dafuer wohl aber noch niemand ernsthaft interessiert. Deshalb gibt es sie nicht.

i2c-0.0.1.tar.gz
(12.21 KiB) 92-mal heruntergeladen
Achtung: Es passiert, dass ich einen frisch geschrieben Beitrag innerhalb von 10 Minuten noch 3-4 Mal aendere!

tgreif
Foriker
Beiträge: 14
Registriert: Sa 12. Mär 2016, 14:59
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tgreif » Do 7. Apr 2016, 20:42

hi tux
vielen dank .
ich werde sie gleichmal probieren und dir dann bescheid geben .

bis dann :)

tgreif
Foriker
Beiträge: 14
Registriert: Sa 12. Mär 2016, 14:59
Kontaktdaten:

Re: A/D mcp3424 I2C

Beitrag von tgreif » Fr 8. Apr 2016, 17:29

Hallo Tux .
habe das gestern ausprobiert. beim starten gibt es keine fehlermeldung.
werde diese tage mal sehen wie ich da weiter komme .
besten dank .
vielleicht erbamt sich ja mal einer daer das kann eine komponente fuer den i2c zu programmiere. ( nicht ein newbe wie ich)

bis dann

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast