Forum: Mikrocontroller und Digitale Elektronik MCP3001 per Python auslesen


von Jay M. (blubb33)


Lesenswert?

Ich möchte gerne einen MCP3001 (ADC) auslesen.
Ich gehe nach Figure 6-1 (Seite 16): 
http://ww1.microchip.com/downloads/en/DeviceDoc/21293C.pdf

Entsprechend CLK auf Low gesetzt, CS von High auf Low.
Jetzt lese ich 16 bits ein.

Allerdings kommt so nur Murks raus. Was mache ich grundsätzlich falsch?
1
import time
2
import RPi.GPIO as GPIO
3
4
GPIO.setmode(GPIO.BCM)
5
6
HIGH = True  # HIGH-Pegel
7
LOW  = False # LOW-Pegel
8
9
# Funktionsdefinition
10
def readAnalogData(SCLKPin, MOSIPin, MISOPin, CSPin):
11
    # Pegel vorbereiten
12
    GPIO.output(CSPin,   HIGH)    
13
    GPIO.output(CSPin,   LOW)
14
    GPIO.output(SCLKPin, LOW)
15
16
    # Empfangen der Daten des ADC
17
    adcvalue = 0 # Ruecksetzen des gelesenen Wertes
18
    for i in range(15): # 16 bits lesen
19
        GPIO.output(SCLKPin, HIGH)
20
        GPIO.output(SCLKPin, LOW)
21
        adcvalue <<= 1 # 1 Postition nach links schieben
22
        if(GPIO.input(MISOPin)):
23
            adcvalue |= 0x01
24
    time.sleep(0.5)
25
26
    return adcvalue
27
28
# Variablendefinition
29
SCLK        = 11 # Serial-Clock
30
MOSI        = 10 # Master-Out-Slave-In
31
MISO        = 9 # Master-In-Slave-Out
32
CS          = 17 # Chip-Select
33
34
# Pin-Programmierung
35
GPIO.setup(SCLK, GPIO.OUT)
36
GPIO.setup(MOSI, GPIO.OUT)
37
GPIO.setup(MISO, GPIO.IN)
38
GPIO.setup(CS,   GPIO.OUT)
39
40
while True:
41
    print readAnalogData(SCLK, MOSI, MISO, CS)

Edit: Ich habe gesehen, dass die Informationen, die ich bekomme in 
diesem Format sind:
1
XXX0123456789XXX

Wie kann ich nun genau diesen Teil aus meiner Variable auslesen?

: Bearbeitet durch User
von Kaj (Gast)


Lesenswert?

Jay Myon schrieb:
> Edit: Ich habe gesehen, dass die Informationen, die ich bekomme in
> diesem Format sind:
> XXX0123456789XXX
> Wie kann ich nun genau diesen Teil aus meiner Variable auslesen?
1
all_data = "XXX0123456789XXX"
2
3
needed_data = all_data[3:12]

Damit sollte needed_data "0123456789" enthalten. Ggf. die Indices 
anpassen

Gruesse

von Kaj (Gast)


Lesenswert?

der zweite index muss 13 sein
1
all_data = "XXX0123456789XXX"
2
3
needed_data = all_data[3:13]

gruesse

von Jay M. (blubb33)


Lesenswert?

Dann erhalte ich den Fehler:
"TypeError: 'int' object has no attribute '__getitem__'"
1
def readAnalogData(SCLKPin, MOSIPin, MISOPin, CSPin):
2
    # Pegel vorbereiten
3
    GPIO.output(CSPin,   HIGH)    
4
    GPIO.output(CSPin,   LOW)
5
    GPIO.output(SCLKPin, LOW)
6
7
    # Empfangen der Daten des ADC
8
    adcvalue = 0 # Ruecksetzen des gelesenen Wertes
9
    for i in range(15): # 16 bits lesen
10
        GPIO.output(SCLKPin, HIGH)
11
        GPIO.output(SCLKPin, LOW)
12
        adcvalue <<= 1 # 1 Postition nach links schieben
13
        if(GPIO.input(MISOPin)):
14
            adcvalue |= 0x01
15
    adcvalue = adcvalue[3:13]
16
    time.sleep(0.5)
17
18
    return adcvalue

: Bearbeitet durch User
von Kaj (Gast)


Lesenswert?

Jay Myon schrieb:
> Dann erhalte ich den Fehler:
> "TypeError: 'int' object has no attribute '__getitem__'"
1
adcvalue = str(adcvalue) # in string wandeln
2
adcvalue = adcvalue[3:13]
3
adcvalue = int(adcvalue) # zurueck in int wandeln

von Jay M. (blubb33)


Angehängte Dateien:

Lesenswert?

Leider ergibt sich hieraus immer noch vollkommenes Chaos:
1
def readAnalogData(SCLKPin, MOSIPin, MISOPin, CSPin):
2
    # Pegel vorbereiten
3
    GPIO.output(CSPin,   HIGH)    
4
    GPIO.output(CSPin,   LOW)
5
    GPIO.output(SCLKPin, LOW)
6
7
    # Empfangen der Daten des ADC
8
    adcvalue = 0 # Ruecksetzen des gelesenen Wertes
9
    for i in range(15): # 16 bits lesen
10
        GPIO.output(SCLKPin, HIGH)
11
        GPIO.output(SCLKPin, LOW)
12
        adcvalue <<= 1 # 1 Postition nach links schieben
13
        if(GPIO.input(MISOPin)):
14
            adcvalue |= 0x01
15
    adcvalue = str(adcvalue) # in string wandeln
16
    adcvalue = adcvalue[3:13]
17
    adcvalue = int(adcvalue) # zurueck in int wandeln
18
    time.sleep(0.5)
19
20
    return adcvalue

Stimmt was an dem Bitmuster nicht? Ich finde da keine Ungereimtheiten.
Es liegt eine Spannung von etwa 1,4V an. Also erwarte ich etwa Werte von 
500... Außerdem einigermaßen stabil.
Ich erhalte so etwas: 0,2,50,88,3,70,4,86...

: Bearbeitet durch User
von Jay M. (blubb33)


Lesenswert?

Ein paar Fehler sind mir noch aufgefallen:

1) Ich muss 16bits einlesen, also 2 bytes (nicht 15 bits)
2) Davon will ich nun 10bit daten extrahieren

Für mich ergibt sich dann dieses:
1
def readAnalogData(SCLKPin, MOSIPin, MISOPin, CSPin):
2
    GPIO.output(CSPin,   HIGH)    
3
    GPIO.output(CSPin,   LOW)
4
    GPIO.output(SCLKPin, LOW)
5
6
    adcvalue = 0
7
    for i in range(16):
8
        GPIO.output(SCLKPin, HIGH)
9
        GPIO.output(SCLKPin, LOW)
10
        adcvalue <<= 1
11
        if(GPIO.input(MISOPin)):
12
            adcvalue |= 0x01
13
    adcvalue >>= 3
14
    adcvalue &= 0x3ff
15
    time.sleep(0.5)
16
17
    return adcvalue

Leider sind die resultierenden Werte außerhalb des erwarteten Bereichs 
und zudem immer noch zu sehr schwankend.

Wo habe ich noch einen gedanklichen Fehler?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.