Seite 1 von 1

Matlab funktion in python funktion umschreiben (bitshift)

Verfasst: Mittwoch 15. April 2015, 13:15
von python48
Hallo,

ich bräuchte mal wieder eure Hilfe.
Eine Funktion, die in Matlab funktioniert und die ich in Python umgeschrieben habe,
funktioniert leider nicht so wie sie soll in python.
Ich habe schon einiges ausprobiert aber komme einfach nicht weiter.
Im Folgenden habe ich die funktionierende Matlab funktion eingefügt und die nicht
funktionierende python funktion.
Womöglich könnt ihr mir gleich einen Hinweis geben woran es liegen könnte.
Mit dieser Funktion werden sensoren ausgelesen (analogwerte). Normalerweise
sollten im ruhezustand immer werte im Bereich 20-80 angezeigt werden, was in der
Matlab funktion auch klappt. In der python funktion scheinen die ersten beiden werte
korrekt und die 2 nachfolgenden sind im bereich von 3000-40000.
Den bitshift habe ich ja genau wie in der Matlabfunktion übernommen also kann es
daran eigentlich nicht liegen aber trozdem sieht es nach eine shift oder konvertierungsfehler aus.
Kann es was mit der integerinterpretation von python zu tun haben?
Muss ich die werte zuerst in ein anderes format casten? (unsigned integer wie in der matlab funktion?)
Komme hier einfach nicht weiter und hoffe dass mir der ein oder andere einen hinweis geben kann! :)

Code: Alles auswählen

function [ data ] = analogreaddistancel()
%Die Bodensensoren werden ausgelesen
       a = [234,4,6,1];
       x = serialwriteread(a);

       b = uint16(x(2));
       c = uint16(x(3));
       g = uint16(x(4));
       e = uint16(x(5));
       f = uint16(x(6));
       
       d(2) = bitshift(b,2) + bitshift(c,-6);
       d(3) = bitshift(bitshift(c,10),-6) + bitshift(g,-4);
       d(4) = bitshift(bitshift(g,12),-6) + bitshift(e,-2);
       d(5) = bitshift(bitshift(e,14),-6) + f;
      
       data = [d(2),d(3),d(4),d(5),];
       
   end
end

Code: Alles auswählen

def analogreaddistanceleft():  
            order = [234, 4, 6, 1]
            data_response = []
            response = serial_write_read(order)

            response_2 = int(response[2])
            response_3 = int(response[3])
            response_4 = int(response[4])
            response_5 = int(response[5])
            response_6 = int(response[6])

            shift_tmp_1 = (response_2 << 2) + (response_3 >> 6)
            shift_tmp_2 = ((response_3 << 10) >> 6) + (response_4 >> 4)
            shift_tmp_3 = ((response_4 << 12) >> 6) + (response_5 >> 2)
            shift_tmp_4 = ((response_5 << 14) >> 6) + response_6

            data_response.append(shift_tmp_1)
            data_response.append(shift_tmp_2)
            data_response.append(shift_tmp_3)
            data_response.append(shift_tmp_4)

            return data_response
Vielen Dank schon mal! :)

Re: Matlab funktion in python funktion umschreiben (bitshift

Verfasst: Mittwoch 15. April 2015, 13:38
von Sirius3
@python48: für mich sieht das so aus, als ob Du 5 Bytes in 4 10bit-Werte konvertieren willst:

Code: Alles auswählen

def analogreaddistanceleft():  
    order = [234, 4, 6, 1]
    _, b, c, g, e, f = serial_write_read(order)
    a = (((b * 256 + c) * 256 + g) * 256 + e) * 256 + f
    a, a4 = divmod(a, 1024)
    a, a3 = divmod(a, 1024)
    a1, a2 = divmod(a, 1024)
    return a1, a2, a3, a4

Re: Matlab funktion in python funktion umschreiben (bitshift

Verfasst: Mittwoch 15. April 2015, 13:41
von BlackJack
@python48: Also der Fehler dürfte sein das in Matlab anscheinend 16-Bit-Zahlen benutzt werden wo Bits die man ”links raus schiebt” einfach verschwinden, während die in Python erhalten bleiben weil `int` in Python keine Grössenbeschränkung haben. Da müsste man dann das Ergebnis vom jeweiligen links-schieben mit ``& 0xffff`` auf 16 Bit beschränken. Oder den schöneren Weg von Sirius3 nehmen. :-)

Re: Matlab funktion in python funktion umschreiben (bitshift

Verfasst: Mittwoch 15. April 2015, 13:46
von python48
vielen lieben dank für deine schnelle hilfe! :)

Wenn ich deinen code ausprobiere bekomme ich jedoch eine fehlermeldung:

Code: Alles auswählen

_, b, c, g, e, f = serial_write_read(order)
ValueError: too many values to unpack
Also der Fehler dürfte sein das in Matlab anscheinend 16-Bit-Zahlen benutzt werden wo Bits die man ”links raus schiebt” einfach verschwinden, während die in Python erhalten bleiben weil `int` in Python keine Grössenbeschränkung haben.
Ah, das erscheint logisch... Vielen Dank, daran habe ich jetzt nicht gedacht :P

Re: Matlab funktion in python funktion umschreiben (bitshift

Verfasst: Mittwoch 15. April 2015, 13:52
von BlackJack
@python48: Dann liefert `serial_write_read()` mehr als die 6 Bytes. Da könnte man mit Slicing arbeiten: ``a, b, c, d, e = map(int, serial_write_read(order)[1:6])``

Re: Matlab funktion in python funktion umschreiben (bitshift

Verfasst: Mittwoch 15. April 2015, 14:07
von python48
@BlackJack: Ich habe den Wertebereich jetzt noch mit der entsprechenden Bitmask verundet/begrenzt
und es funktioniert jetzt einwandfrei! Vielen Dank für den Hinweis mit der Größenbeschränkung! :)

@Sirius: Danke dir, ich hätte jedoch noch 2 Fragen zu deinem code:
1. Wieso nimmst du immer mal 256? Da stehe ich bei mir grad aufm Schlauch...

Code: Alles auswählen

a = (((b * 256 + c) * 256 + g) * 256 + e) * 256 + f

2. Hat der Unterstrich am Anfang der Zeile eine besondere Bedeutung in python oder wird das
einfach als eine normale variable interpretiert?

Code: Alles auswählen

_, b, c, g, e, f = serial_write_read(order)
Danke euch! :)

Re: Matlab funktion in python funktion umschreiben (bitshift

Verfasst: Mittwoch 15. April 2015, 15:03
von BlackJack
@python48: ``n << e`` ist äquivalent zu ``n * 2**e``, also ist ``n << 8`` das gleiche wie ``n * 256``. Der Unterstrich ist ein an sich normaler Name, wird in Quelltext aber per Konvention für Stellen verwendet wo man syntaktisch einen Namen schreiben muss, wo einem der Wert aber egal ist.

Re: Matlab funktion in python funktion umschreiben (bitshift

Verfasst: Mittwoch 15. April 2015, 15:06
von python48
Vielen Dank für die Hilfe, hat mich ein ganzes stück weitergebracht! :)

Gruß, python48.