Raspberry Pi MCP3208

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Consti9_9
User
Beiträge: 24
Registriert: Dienstag 4. Dezember 2018, 09:09

Da ichjetzt die einzelnen Channel auslesen will benötigte ich einen Code der die Werte einzeln ausgeben kann und ich sie einzeln abfragen kann, mit den Wert muss ich in dem Programm weiter rechnen können. Somit muss ich diese zum Beispiel als Variable in eine Rechnung einfügen können.

Ich arbeite im Moment mit dem Beispielcode:

Code: Alles auswählen

from mcp3208 import MCP3208
import time
adc = MCP3208()
while True:
        for i in range(8):
                print('ADC[{}]: {:.2f}'.format(i, adc.read(i)))
        time.sleep(0.5)
Gibt es einen Code mit dem ich das besser Programmieren könnte?

Mit dem folgenden Code funktioniert es jedoch nicht -> Werte sind alle immer 0

Code: Alles auswählen

from MCP3208 import MCP3208
from spidev import SpiDev
import time
 
class MCP3208:
    def __init__(self, bus = 0, device = 0):    # Hier wird der SPI Bus aktiviert
        self.bus, self.device = bus, device
        self.spi = SpiDev()
        self.open()
 
    def open(self):
        self.spi.open(self.bus, self.device)
    
    def read(self, channel = 0):        # Hier werden die Channels abgefragt
        adc = self.spi.xfer2([1, (8 + channel) << 4, 0])
        data = ((adc[1] & 3) << 8) + adc[2]
        return data
            
    def close(self):
        self.spi.close()
adc = MCP3208()
value0 = adc.read( channel = 0 ) # Channel 0
value1 = adc.read( channel = 1 ) # Channel 1
value2 = adc.read( channel = 2 ) # Channel 2
value3 = adc.read( channel = 3 ) # Channel 3
value4 = adc.read( channel = 4 ) # Channel 4
print("Anliegende Spannung: %.2f" % (value0 / 4096.0 * 3.3) )   # Ausgabe der Spannung
print("Anliegende Spannung: %.2f" % (value1 / 4096.0 * 3.3) )    # Ausgabe der Spannung
print("Anliegende Spannung: %.2f" % (value2 / 4096.0 * 3.3) )    # Ausgabe der Spannung
print("Anliegende Spannung: %.2f" % (value3 / 4096.0 * 3.3) )    # Ausgabe der Spannung
print("Anliegende Spannung: %.2f" % (value4 / 4096.0 * 3.3) )    # Ausgabe der Spannung
Mein Ziel ist es die Werte der einzelnen Channels in Variablen zu schreiben also 8 Channels 8 Variablen.

Mit diesen Variablen möchte ich dann weitere Rechnungen durchführen, da mir ja ein Wert von 0-4096 ausgegeben wird und ich ja aber den Stromwert wissen möchte. Diese Umrechnung habe ich mir schon aufgeschrieben, nur schaffe ich es nicht die Channel-werte als Variable

zu definieren.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wieso hast du die Klasse in den Code kopiert? Wieso hast du sie dann davor immer noch importiert?

Wenn du Variablen durchnummerierst, ist das ein Zeichen dafür, dass du eine Datenstruktur willst. In diesem Fall eine Liste. Du solltest die Grundlagen aus dem Python Tutorial dafür durcharbeiten.

Folgender Code sollte (wenn dein eigenes Beispiel stimmt) alle Werte zur Weiterverarbeitung in eine Liste einlesen:

Code: Alles auswählen

from mcp3208 import MCP3208
import time
adc = MCP3208()
while True:
        werte = []
        for i in range(8):
                werte.append(adc.read(i))
        print(werte)
        time.sleep(0.5)
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Die beiden Codes unterscheiden sich in ihrer Ausführung nicht, außer dass die Hardware anders angesprochen wird. Im ersten Fall in einer Schleife, im zweiten nur einmal. Kann es sein, dass die Initialisierung ein Weile braucht, bis richtige Spannungen geliefert werden.
Consti9_9
User
Beiträge: 24
Registriert: Dienstag 4. Dezember 2018, 09:09

@_deets_ Danke für dein Antwort
Jedoch weis ich auch nach reichlicher Recherche nicht wie ist jetzt zum Beispiel den 3 Wert als Variable C definieren kann.
Gibt es hier eine Internetseite oder einen Code an dem ich mir das Anlernen kann?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Consti9_9: die Antwort ist, man kann über einen Index zugreifen, die andere Antwort ist, warum willst Du das überhaupt?
Consti9_9
User
Beiträge: 24
Registriert: Dienstag 4. Dezember 2018, 09:09

Folgendes: Meine Werte sind die Werte der AD Wandlung der Signale von einem Stromsensor dieser soll verschiedene Stromwerte messen und da ich jedoch nach der AD Wandlung noch keinen Stromwert hab muss ich auf diesen zurückrechnen. Dies muss ich dann mit einer Variablen machen oder gibt es einen leichteren Weg. Anschließend soll dieser Wert als Label am Display angezeigt werden.
Consti9_9
User
Beiträge: 24
Registriert: Dienstag 4. Dezember 2018, 09:09

Habe es jetzt mit dem Befehl global a um eine Variable zu definieren und in der Schleife mit dem Befehl a = adc.read(1) als Beispiel probiert. Er zeigt mir jetzt alle 8 Werte und den a Wert danach an eigentlich weis ich somit das die Variable funktioniert nur weicht diese immer ein wenig ab. Liegt das daran das sich der Wert in der Zwischenzeit geändert haben kann?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Consti9_9: Vergiss ``global`` am besten gleich wieder.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Consti9_9
User
Beiträge: 24
Registriert: Dienstag 4. Dezember 2018, 09:09

Wieso das?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Globale Variablen zu benutzen ist verpoent, weil es leicht subtile Fehler einfuehrt, denen man dann schwer auf die Schliche kommt.

Zu deinem Berechnungsproblem: natuerlich musst du mit Variablen rechnen. Das kannst du aber auch genauso gut mit Listen:

Code: Alles auswählen

rohe_werte = [1, 2, 3, 4]
verfeinerte_werte = [wert / 10.0 for wert in rohe_werte]
Insofern hat das erstmal ueberhaupt nichts mit der Frage "listen oder nicht" zu tun. Wenn du keine SINNVOLLEN Namen fuer deine Variablen hast, als zB "rohwert_erdgeschoss", sondern sie stattdessen nur durchnummerierst, dann solltest du auch bei einer Liste bleiben.

Wenn du stattdessen mit konkreten Namen arbeiten willst, muss der Code

Code: Alles auswählen

rohwert_erdgeschoss = adc.read(0)
rohwert_datsche = adc.read(1)
rohwert_atombunker = adc.read(2)
funktionieren. Da gibt es keinen prinzipiellen Unterschied, und auch das Timing des MCP3208 sollte da eigentlich keine Rolle spielen.
Antworten