ADS1115 Analog Eingang Problem

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
unique24
User
Beiträge: 69
Registriert: Donnerstag 5. Juli 2018, 14:51

Hallo,

ich habe auf de i2c Bus einen Multiplexer und an Kanal 5 einen ADS1115 4-Kanal Analogeingang angeschlossen.

Am Eingang 1 des Analog Eingangs habe ich einen Fotowiderstand zum Helligkeitsmessen.

Angeschlossen über einen 10KOhm Widerstand wie hier beschrieben:
https://tutorials-raspberrypi.de/raspbe ... iderstand/

der code:

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
import Adafruit_ADS1x15

adc = Adafruit_ADS1x15.ADS1115(address=0x48, busnum=5)
GAIN = 1

print('Reading ADS1x15 values, press Ctrl-C to quit...')
# Print nice channel column headers.
print('| {0:>6} | {1:>6} | {2:>6} | {3:>6} |'.format(*range(4)))
print('-' * 37)
# Main loop.
while True:
    # Read all the ADC channel values in a list.
    values = [0]*4
    for i in range(4):
        # Read the specified ADC channel using the previously set gain value.
        values[i] = adc.read_adc(i, gain=GAIN)
        #values[i] = adc.read_adc(i, gain=GAIN, data_rate=128)
    # Print the ADC values.
    print('| {0:>6} | {1:>6} | {2:>6} | {3:>6} |'.format(*values))
    # Pause for half a second.
    time.sleep(0.5)
Jetzt zum skurrilen Problem:
Starte ich das Programm, erhalte ich den Fehler:

Code: Alles auswählen

Reading ADS1x15 values, press Ctrl-C to quit...
|      0 |      1 |      2 |      3 |
-------------------------------------
Traceback (most recent call last):
  File "simpletest.py", line 20, in <module>
    values[i] = adc.read_adc(i, gain=GAIN, data_rate=860)
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_ADS1x15/ADS1x15.py", line 192, in read_adc
    return self._read(channel + 0x04, gain, data_rate, ADS1x15_CONFIG_MODE_SINGLE)
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_ADS1x15/ADS1x15.py", line 128, in _read
    self._device.writeList(ADS1x15_POINTER_CONFIG, [(config >> 8) & 0xFF, config & 0xFF])
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_GPIO/I2C.py", line 127, in writeList
    self._bus.write_i2c_block_data(self._address, register, data)
  File "/usr/local/lib/python3.7/dist-packages/Adafruit_PureIO/smbus.py", line 364, in write_i2c_block_data
    self._device.write(data)
OSError: [Errno 121] Remote I/O error
Wenn ich aber beim starten den Sensor mit einem Finger abdecke, startet er und läuft dann auch ohne Problem. Selbst wenn ich ihn mit einer Taschenlampe anleuchte.

Schaut so aus, als müsste der Sensor im negativen Bereich sein?

Ausgabe(zuerst war er abgedeckt, dann offen im Raum):

Code: Alles auswählen

Reading ADS1x15 values, press Ctrl-C to quit...
|      0 |      1 |      2 |      3 |
-------------------------------------
|  -2336 |  -1952 |  -1968 |  -1952 |
|  -2304 |  -1952 |  -1968 |  -1952 |
|  -2320 |  -1952 |  -1936 |  -1936 |
|  -2336 |  -1952 |  -1936 |  -1952 |
|  -2320 |  -1920 |  -1952 |  -1952 |
|   6992 |   4128 |   4656 |   6784 |
|   7008 |   6752 |   5920 |   3696 |
|   6752 |   5456 |   7520 |   8544 |
|   7056 |   4208 |   4000 |   5792 |
|   7264 |   7056 |   6800 |   4944 |
|   7024 |   4592 |   5872 |   9088 |
|   6832 |   5552 |   3936 |   4192 |
Weiß da jemand woran das liegt?
Benutzeravatar
__blackjack__
User
Beiträge: 13938
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@unique24: Anmerkungen zum Quelltext: Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.

So magische Zahlen wie die 37 sollte man besser im Programm berechnen, dann muss man die bei Änderungen nicht suchen und manuell neu berechnen.

Eine Liste mit Dummywerten zu erstellen die gleich danach in einer Schleife nach und nach per Zuweisung mit Index durch die tatsächlichen Werte ersetzt werden ist kein idiomatisches Python. In Python fängt man mit einer leeren Liste an, an die dann die Werte angehängt werden. Und in einfachen Fällen wie hier bietet sich eine „list comprehension“ an, um die Liste zu erstellen.

4 ist auch so eine magische Zahl die nicht direkt im Programm stehen sollte, weil sie mehrfach dort steht. Sollte man die mal ändern wollen, müsste man das gesamte Programm nach 4en absuchen, und bei jeder entscheiden ob die angepasst werden muss oder nicht. Für solche Werte definiert man besser eine Konstante.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import time

import Adafruit_ADS1x15

CHANNEL_COUNT = 4
GAIN = 1


def print_line(values):
    line = "|{}|".format(" | ".join(format(value, ">6") for value in values))
    print(line)
    return len(line)


def main():
    print("Reading ADS1x15 values, press Ctrl-C to quit...")
    adc = Adafruit_ADS1x15.ADS1115(address=0x48, busnum=5)
    line_length = print_line(range(CHANNEL_COUNT))
    print("-" * line_length)
    while True:
        values = [adc.read_adc(i, gain=GAIN) for i in range(CHANNEL_COUNT)]
        print_line(values)
        time.sleep(0.5)


if __name__ == "__main__":
    main()
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das der Sensor abgedeckt sein muss ist nicht möglich. Der Fehler deutet auf ein Verdrahtungsproblem hin, und wenn du den berührst, ist der I2C Bus glücklich. IOErrors sind immer sowas.
Antworten