Werte aus Tabelle / Matrix / Array, oder Liste?

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

__deets__ hat geschrieben:Das ist noch mal eine ganz andere Baustelle. Ich weiss jetzt nicht was dieses Powermeter-Zeugs ist, aber um etwas an einen Browser zu schicken reicht es nicht nur JSON zu erzeugen, sondern das muss ueber eine geeignete Verbindung an den Browser geschickt werden.

Du kannst zB mal hier http://www.forum-raspberrypi.de/Thread- ... schen-ajax schauen ob dir das nachvollziehbar ist.
Das macht das JSON Programm, das sendet hier im Beispiel:
https://github.com/olympum/ant-cycling- ... er/test.js

kontinuierlich power und cadence an den ANT+ Stick im Raspberry PI

Wie soll ich das erklären? Ich versuchs:
der Raspberry PI is der Slave mit einem ANT+ Stick, der bekommt geliefert vom Cross trainer die RPM. Die Level kann ich auch schalten mit den Tastern die am Raspberry angeschlossen sind. Somit habe ich meine POWER Werte und RPM Werte. (Der jetzige Code halt)

Der ANT+ Stick ist als "Sender" konfiguriert und sendet an meine Windows Maschine wo ebenfalls ein ANT+ Stick als Master eingesteckt ist (Empfänger)
Dieser empfängt also die POWER und RPM Daten. Somit kann ich in Zwift radeln:
Bild

Die Zwift Software erwartet Power (auf dem Bild als Beispiel 170) und RPM, daraus ergibt sich die Geschwindigkeit.

Hab ich das einigermaßen Verständnisvoll erklärt?

100€ stehen immer noch im Raum *wink :)
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

Ich frag mich grad, ob ich das alles auch hätte in Javascript machen sollen/müssen?

Da das Programm was ant ANT+ sendet ja JSON ist. JSON ist Javascript?

:shock:
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@Landixus: JSON ist ein allgemein bekanntes, standardisiertes Format, das gewisse Ähnlichkeit mit Javascript-Strukturen wie Listen und Wörterbüchern hat. Es ist kein Javascript. Es gibt für so gut wie jede Programmiersprache Parser dafür.
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

Sirius3 hat geschrieben:@Landixus: JSON ist ein allgemein bekanntes, standardisiertes Format, das gewisse Ähnlichkeit mit Javascript-Strukturen wie Listen und Wörterbüchern hat. Es ist kein Javascript. Es gibt für so gut wie jede Programmiersprache Parser dafür.
Beruhigt mich das jetzt? :)

Und vor allem bekomme ich das Output in mein python file überhaupt eingebaut?:

Code: Alles auswählen

var power_meter = require('./power-meter');
var pm = new power_meter.PowerMeter();

function a() {
  var power_instant = calculate_power(LEVEL, RPM);
  var cadence = RPM={}".format(int(RPM+1));
  pm.broadcast(power_instant, cadence);
  setTimeout(a, 249);
}

a();
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du kannst nicht einfach zwei Programmiersprachen zusammenmanschen. Und mit json hat das auch nix zu tun. Das ist JavaScript, ganz normal.

Was du brauchst ist eine ANT+ Protokoll Bibliothek. Sowas gibts auch für Python, zB hier: http://python-evdev.readthedocs.io/en/latest/index.html

Ob die den Zweck erfüllt oder nicht weiß ich nicht. Ich habe keine ant+-fähigen Geräte.
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

__deets__ hat geschrieben:Du kannst nicht einfach zwei Programmiersprachen zusammenmanschen. Und mit json hat das auch nix zu tun. Das ist JavaScript, ganz normal.

Was du brauchst ist eine ANT+ Protokoll Bibliothek. Sowas gibts auch für Python, zB hier: http://python-evdev.readthedocs.io/en/latest/index.html

Ob die den Zweck erfüllt oder nicht weiß ich nicht. Ich habe keine ant+-fähigen Geräte.
Also kann ich den Wert von dem Python Programm doch nicht abholen und in dem JavaScript einfügen?
Also muss ich die 2 Wochen frickeln doch auf Javascript umbauen? Wenn es denn überhaupt geht.

Das ant+ Zeug macht alles die software aus dem github. ich wollte nur "etwas" anpassen und so übertragen.

Da habe ich wohl falsch gedacht. Bleibt wohl beim Versuch...
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich weiß nicht genau was du dir da ausgedacht hast. Aber rein konzeptionell sehe ich keinen Grund, warum da javascript sein muss. Die Sensoren reden über funk miteinander, das wars. Ob du deinen ant stick von Python aus treibst oder von JavaScript ist egal. Wenn da natürlich eine signifikante Verarbeitung von Daten *vorher* passiert, dann hast du ein Problem.
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

Ich mach erst mal 2 Tage Pause und überlege wie ich das doch noch lösen kann.

Aufgeben kommt da irgendwie nicht in Frage. Ich WILL das haben.

Außerdem bin ich das dem Forum hier schuldig :)

Ich melde mich mit dem Ergebnis zurück!
Liffi
User
Beiträge: 153
Registriert: Montag 1. Januar 2007, 17:23

Landixus hat geschrieben: JSON ist Javascript?
Ja, JSON steht für "JavaScript Object Notation." Aber letztlich kann, wie die anderen schon gesagt haben, jede Programmiersprache mehr oder weniger einfach JSON Objekte erzeugen und verarbeiten.
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

Eine Idee habe ich noch!

Kann ich nicht meine Werte, oder Wert in eine Datei schreiben und kontinuierlich updaten? mir langt ja der Power Wert.

Dann kann ich doch "diese" Datei mit einem "egal" was für einem Programm öffnen und den Wert auslesen für mein Programm!?
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

ich rede so gerne mit mir selber :)


Code: Alles auswählen

...
    LEVEL = count
    RPM = p.RPM()
    RPM = (int(RPM+1))
    time.sleep(SAMPLE_TIME)
    print('Power',calculate_power(LEVEL, RPM),'Level', count, "RPM={}".format(int(RPM+1)))  
    with open ('power') as output:
        output.write (calculate_power(LEVEL, RPM)
        output.close()
    time.sleep(1)
....
Korrekt? :D
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Landixus hat geschrieben:Korrekt?
Leider nein. Du öffnest die Datei zum Lesen, versuchst hinein zu schreiben und im with-Kontext brauchst Du sie auch nicht zu schließen.

@Liffi: JSON ist kein JavaScript. Da steckt zwar JavaScript im Namen, aber der Eindruck täuscht. Es ist ein Datenformat.
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

Ich hab jetzt ein Programm gefunden was die Shell-Ausgabe lesen kann.
I wesentlichen geht es mir ja um den Power Wert.

https://github.com/extrabacon/python-sh ... and-python

damit sollte ich klar kommen.

Ist zwar eine Bastellösung, aber eine die vielleicht funktioniert.
Ich probiere das nachher mal aus :)
Liffi
User
Beiträge: 153
Registriert: Montag 1. Januar 2007, 17:23

kbr hat geschrieben: @Liffi: JSON ist kein JavaScript. Da steckt zwar JavaScript im Namen, aber der Eindruck täuscht. Es ist ein Datenformat.
Ich hatte in Erinnerung, dass es valides JavaScript ist. Mein Browser enttäuscht mich da aber ein bisschen.

Code: Alles auswählen

{"JSON":"ro
cks!"}
Da stolpert mein Firefox drüber, über folgendes aber nicht:

Code: Alles auswählen

{JSON:"ro
cks!"}
Hätte eigentlich erwartet, dass das erste super gehen müsste.
BlackJack

@Liffi: Das erste geht auch wenn da nicht irgendwas komisches in der zweiten Zeichenkette wäre. Wenn ich das markiere und in meine Shell mit IPython kopiere passieren komische Dinge. Da sind irgendwelche unsichtbare Steuerzeichen nach dem o von rocks.

Es ging glaube ich auch mehr darum dem OP zu vermitteln das JSON kein JavaScript ist, weil der mehrfach von JSON-Programmen gesprochen hat und *dann* die Frage aufkam ob JSON einfach JavaScript ist. JSON ist halt keine Programmiersprache und auch unabhängig von einer Programmiersprache verwendbar, beziehungsweise mit allen möglichen Programmiersprachen verwendbar.

Edit: Zwischen o und c von rocks ist ein U+2028 LINE SEPARATOR Zeichen was von JavaScript (und auch Python) als Zeilenende interpretiert wird und damit hat man mit der zweiten Zeichenkette eine die nicht syntaxkonform beendet wird, weil das Ende erst in der nächsten Zeile steht.
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

Hab ich verstanden mit JSON und Javascript.

Was ich aber schade finden würde wenn das Stücken Code von @__deets__ nicht bei mir verarbeitet wird:

Code: Alles auswählen

from __future__ import print_function
 
import math
 
LEVEL_TO_POWER = {
    1: [6,12,20,29,40,53,69,79,92,106,121],
    2: [8,16,26,38,53,68,88,103,120,138,152],
    3: [9,20,32,47,66,84,107,125,148,172,186],
    4: [11,23,39,56,79,101,126,150,173,206,219],
    5: [13,27,45,65,92,117,145,175,202,238,254],
    6: [15,31,52,75,105,135,166,202,231,275,289],
    7: [16,35,58,85,118,152,185,226,260,305,332],
    8: [18,39,65,96,131,169,208,249,289,333,375],
    9: [19,42,71,104,144,184,227,272,318,361,408],
    10:[21,46,77,113,157,199,245,295,345,386,442],
    11:[23,50,84,123,170,216,262,318,372,413,480],
    12:[24,53,89,131,183,230,279,342,398,441,512],
    13:[26,56,94,139,196,245,296,365,424,468,548],
    14:[28,60,101,148,209,261,318,389,449,494,585],
    15:[30,64,108,158,222,277,337,415,476,518,620],
    16:[32,68,115,168,235,296,355,439,503,548,658],
    17:[33,72,122,177,248,312,373,463,530,576,694],
    18:[35,76,129,187,261,328,390,484,556,606,727],
    19:[37,79,134,195,274,342,407,507,572,632,763],
    20:[39,83,140,204,287,354,424,528,598,659,790],
    21:[40,87,146,213,300,368,442,551,616,689,812],
    22:[42,91,153,223,313,385,461,574,645,720,840],
    23:[44,95,160,234,326,401,479,598,673,752,872],
    24:[47,101,171,246,340,418,501,625,706,788,908],
    }
 
UPPER_LIMIT = len(LEVEL_TO_POWER.values()[0]) - 2
 
def clamp(v, lower, upper):
    return max(min(v, upper), lower)
 
 
def rpm2index(rpm):
    # clamping downto a range that never exceeds
    # the power level size - 2 so we can interpolate
    i = clamp((rpm - 20) // 10, 0, UPPER_LIMIT)
    f = (rpm - (i * 10 + 20)) / 10.0
    return i, f
 
 
def rpm2power(rpm):
    i, f = rpm2index(rpm)
    a = LEVEL_TO_POWER[1][i]
    b = LEVEL_TO_POWER[1][i + 1]
    return a + (b - a) * f
 
 
def main():
    for rpm in xrange(20, 131):
        print("RPM:", rpm, "POWER:", rpm2power(rpm))
 
 
if __name__ == '__main__':
    main()
Das muss ich noch irgendwie mit meinem verbaut bekommen. *verdammt :)
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

Ich hab noch einmal alles gegeben :)

Kann das jetzt mit @__deets__ seinem code so richtig sein wie ich das eingebaut habe?
Ich habe alle Zeilenfehler entfernt und meinen code von der Syntax auch geprüft.
Ab Zeile 115 gehts los *schwitz

Code: Alles auswählen

#!/usr/bin/env python
import time
import pigpio


class reader:

    def __init__(self, pi, gpio, pulses_per_rev=1.0, weighting=0, min_RPM=5):

        self.pi = pi
        self.gpio = gpio
        self.pulses_per_rev = pulses_per_rev

        if min_RPM > 1000:
            min_RPM = 1000
            elif min_RPM < 1:
                min_RPM = 1

        self.min_RPM = min_RPM

        self._watchdog = 200  # Milliseconds.

        if weighting < 0:
            weighting = 0
        elif weighting > 0:
            weighting = 0

        self._new = 1 - weighting   # Weighting for new reading.
        self._old = weighting       # Weighting for old reading.

        self._high_tick = None
        self._period = None

        pi.set_mode(gpio, pigpio.INPUT)

        self._cb = pi.callback(gpio, pigpio.RISING_EDGE, self._cbf)
        pi.set_watchdog(gpio, self._watchdog)

    def _cbf(self, gpio, level, tick):

        if level == 1:  # Rising edge.

            if self._high_tick is not None:
                t = pigpio.tickDiff(self._high_tick, tick)

            if self._period is not None:
                self._period = (self._old * self._period) + (self._new * t)
            else:
                self._period = t

            self._high_tick = tick

            elif level == 2:  # Watchdog timeout.

                if self._period is not None:
                    if self._period < 2000000000:
                        self._period += (self._watchdog * 1000)

    def RPM(self):

        RPM = 0
        if self._period is not None:
            RPM = 60000000 / (self._period * self.pulses_per_rev)
            if RPM < self.min_RPM:
                RPM = 0

        return RPM

    def cancel(self):

        self.pi.set_watchdog(self.gpio, 0)  # cancel watchdog
        self._cb.cancel()
if __name__ == "__main__":
    from __future__ import print_function
    import math
    import time
    import pigpio
    import readRPM
    import RPi.GPIO as GPIO
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    count = 5
    RPM_GPIO = 4
    RUN_TIME = 9600.0
    SAMPLE_TIME = 1.0


LEVEL_TO_POWER = {
    1: [6, 12, 20, 29, 40, 53, 69, 79, 92, 106, 121],
    2: [8, 16, 26, 38, 53, 68, 88, 103, 120, 138, 152],
    3: [9, 20, 32, 47, 66, 84, 107, 125, 148, 172, 186],
    4: [11, 23, 39, 56, 79, 101, 126, 150, 173, 206, 219],
    5: [13, 27, 45, 65, 92, 117, 145, 175, 202, 238, 254],
    6: [15, 31, 52, 75, 105, 135, 166, 202, 231, 275, 289],
    7: [16, 35, 58, 85, 118, 152, 185, 226, 260, 305, 332],
    8: [18, 39, 65, 96, 131, 169, 208, 249, 289, 333, 375],
    9: [19, 42, 71, 104, 144, 184, 227, 272, 318, 361, 408],
    10: [21, 46, 77, 113, 157, 199, 245, 295, 345, 386, 442],
    11: [23, 50, 84, 123, 170, 216, 262, 318, 372, 413, 480],
    12: [24, 53, 89, 131, 183, 230, 279, 342, 398, 441, 512],
    13: [26, 56, 94, 139, 196, 245, 296, 365, 424, 468, 548],
    14: [28, 60, 101, 148, 209, 261, 318, 389, 449, 494, 585],
    15: [30, 64, 108, 158, 222, 277, 337, 415, 476, 518, 620],
    16: [32, 68, 115, 168, 235, 296, 355, 439, 503, 548, 658],
    17: [33, 72, 122, 177, 248, 312, 373, 463, 530, 576, 694],
    18: [35, 76, 129, 187, 261, 328, 390, 484, 556, 606, 727],
    19: [37, 79, 134, 195, 274, 342, 407, 507, 572, 632, 763],
    20: [39, 83, 140, 204, 287, 354, 424, 528, 598, 659, 790],
    21: [40, 87, 146, 213, 300, 368, 442, 551, 616, 689, 812],
    22: [42, 91, 153, 223, 313, 385, 461, 574, 645, 720, 840],
    23: [44, 95, 160, 234, 326, 401, 479, 598, 673, 752, 872],
    24: [47, 101, 171, 246, 340, 418, 501, 625, 706, 788, 908],
    }
pi = pigpio.pi()
p = readRPM.reader(pi, RPM_GPIO)
input_state = false

UPPER_LIMIT = len(LEVEL_TO_POWER.values()[0]) - 2


def clamp(v, lower, upper):
    return max(min(v, upper), lower)


def rpm2index(rpm):
    # clamping downto a range that never exceeds
    # the power level size - 2 so we can interpolate
    i = clamp((rpm - 20) // 10, 0, UPPER_LIMIT)
    f = (rpm - (i * 10 + 20)) / 10.0
    return i, f


def rpm2power(rpm):
    i, f = rpm2index(rpm)
    a = LEVEL_TO_POWER[1][i]
    b = LEVEL_TO_POWER[1][i + 1]
    return a + (b - a) * f


def main():
    for rpm in xrange(20, 131):
        start = time.time()
        while (time.time() - start) < RUN_TIME:
            input_state = GPIO.input(20)
            if input_state:
                if count < 24:
                    count = count + 1
                    LEVEL = count
                    print("LEVEL", count"RPM:", rpm, "POWER:", rpm2power(rpm))
                    time.sleep(SAMPLE_TIME)
            input_state = GPIO.input(20)
            if input_state:
                if count > 1:
                    count = count - 1
                    LEVEL = count
                    print("LEVEL", count"RPM:", rpm, "POWER:", rpm2power(rpm))
                    time.sleep(SAMPLE_TIME)
p.cancel()
pi.stop()
if __name__ == '__main__':
    main()
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du hast immer noch die hart-kodierte Stufe eins in rpm2power.

Das muss einen weiteren Parameter bekommen, level, und der muss statt der 1 benutzt werden.
Benutzeravatar
Landixus
User
Beiträge: 49
Registriert: Mittwoch 26. April 2017, 09:38

__deets__ hat geschrieben:Du hast immer noch die hart-kodierte Stufe eins in rpm2power.

Das muss einen weiteren Parameter bekommen, level, und der muss statt der 1 benutzt werden.
Also:

Code: Alles auswählen

LEVEL = 5  # We start at LEVEL 5


def rpm2power(rpm):

    i, f = rpm2index(rpm)
    a = LEVEL_TO_POWER[LEVEL][i]
    b = LEVEL_TO_POWER[LEVEL][i + LEVEL]
    return a + (b - a) * f


def main():
    for rpm in xrange(20, 131):
        start = time.time()
        while (time.time() - start) < RUN_TIME:
            input_state = GPIO.input(20)
            if input_state:
                if LEVEL < 24:
                    LEVEL = count + 1
                    print("LEVEL", LEVEL"RPM:", rpm, "POWER:", rpm2power(rpm))
                    time.sleep(SAMPLE_TIME)
das

Code: Alles auswählen

 LEVEL = count
brauch ich dann ja nicht mehr? Ich glaub so ganz langsam komme ich dahinter.
__deets__
User
Beiträge: 14480
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein. Du sollst es als PARAMETER uebergeben. Das arbeiten mit globalem Zustand ist ueblicherweise ungesund und Ursache fuer schwer zu ermittelnde Fehler.

Code: Alles auswählen

def rpm2power(rpm, level):
      ...
Antworten