Anfänger fragt: Mittelwert aus Sensorwerten (Gewicht)

Hi Leute,
ich habe mir jetzt mal diesen M5Stack Core2 zugelegt. Ist ein schickes kleines Teil mit tollen Einsatzmöglichkeiten. Jetzt also mein erstes Projekt damit...

Ich möchte das Gewicht von Futter in einer Futterschale ermitteln. Für den M5Stack Core2 habe ich ein "Scales-Kit" mit 4 Gewichtssensoren (HX711). Programmieren wollte ich eigentlich über UIFlow 2, wirkt optisch sehr ansprechend und einfach. Als Neuling ist das aber doch etwas überfordernd. Also bin ich doch zu Python gewechselt...

Also, alles angesteckt (absolut simple) ich habe auch schon mal Messwerte im Display. Die schwanken aber noch zu sehr. Pro Sekunde kommen unzählige Messwerte rein. Die Idee ist also die Messwerte eine für eine halbe Sekunde zu sammeln und dann nur den Mittelwert im Display anzuzeigen. Leider bin ich schon wieder so lange aus der Python-Programmierung raus, dass ich es nicht hinbekomme ohne eure Hilfe.

import os, sys, io
import M5
from M5 import *
from hardware import *
from unit import WEIGHTUnit

label0 = None
title0 = None
label1 = None
label2 = None
weight_0 = None

import math

gewicht = None
gewicht1 = None

def btnA_wasClicked_event(state):
  global label0, title0, label1, label2, weight_0, gewicht, gewicht1
  weight_0.set_tare()

def setup():
  global label0, title0, label1, label2, weight_0, gewicht, gewicht1

  weight_0 = WEIGHTUnit((33,32))
  M5.begin()
  Widgets.fillScreen(0x222222)
  label0 = Widgets.Label("label0", 45, 87, 1.0, 0xffffff, 0x222222, Widgets.FONTS.DejaVu72)
  title0 = Widgets.Title("Futter/Feed", 3, 0xffffff, 0x0000FF, Widgets.FONTS.DejaVu40)
  label1 = Widgets.Label("Kg", 47, 163, 1.0, 0xffffff, 0x222222, Widgets.FONTS.DejaVu24)
  label2 = Widgets.Label(">0<", 49, 224, 1.0, 0xffffff, 0x222222, Widgets.FONTS.DejaVu12)

  BtnA.setCallback(type=BtnA.CB_TYPE.WAS_CLICKED, cb=btnA_wasClicked_event)

def loop():
  global label0, title0, label1, label2, weight_0, gewicht, gewicht1
  M5.update()
  gewicht = (weight_0.get_scale_weight) / 52000
  gewicht1 = round(gewicht, 2)
  if gewicht1 <= 0.00:
    gewicht1 = 0.00
  label0.setText(str(gewicht1))

if __name__ == '__main__':
  try:
    setup()
    while True:
      loop()
  except (Exception, KeyboardInterrupt) as e:
    try:
      from utility import print_error_msg
      print_error_msg(e)
    except ImportError:
      print("please update to latest firmware")

Ich bin für jede Hilfe sehr dankbar :slight_smile:

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

1 Like

Lies Dir mal das Datenblatt des HX711 durch mit Augenmerk auf die Output data rate.
Für hardwarespezifische Probleme und für Software scheint mir daß dies das falsche Forum ist.
Grüße Uwe

1 Like

Der Arduino wird mit Python programmiert - genau wie der M5Stack Core2. Es geht ja nur um Python-Funktionen die ich noch nicht drauf habe. Wie gesagt, der Sensor wird ja bereits ausgelesen. Nur mus die Ausgabe noch etwas konvertiert werden um auf dem Display eine ordentlich Anzeige zubekommen.

Bin ich raus.
In C++ ist das einfach.
Lege Dir ein Array mit einer Handvoll Elementen an und bilde über alle hinweg den Durchschnitt nach der Messung.
Zur Ausgabe lege Dir einen Wert an, den Du mit deinem errechneten Wert vergleichts.
Sind die ungleich, neuen Wert in die Merkvariable und auf den Displayy.

Ich gehe sogar noch einen Schritt weiter bei solchen Berechnungen und rechne den/einen höchsten udn den/einen tiefsten Wert nciht mit.

2 Likes

Arduinos benutzen C/C++ als Programmiersprache.

Kontrolliere mal ob Du die Sensordaten nicht zu oft abrufst, noch bevor die Konvertierung zu Ende ist.

1 Like

Dan gehört die Frage in Python Forum.

1 Like

Ich würde erst mal das lesen der Sensordaten auf ein vernünftiges Maß ausbremsen:

from time import sleep;
....

    while True:
      loop()
      sleep(1) # je nachdem wie schnell sich deine Daten ändern

[/quote]

1 Like

Danke schon mal für die Antworten.
Ich habe das Gewicht schon im Display stehen, aber es springt eben immer wieder hin und her. Ich habe das mal in einem Video festgehalten.

Gibt es nicht eine Funktion in Python, die die Messwerte für 250 ms sammelt und den Mittelwert ausspuckt? Dieser ist sicher genauer...

Das ist der Code dazu:

import os, sys, io
import M5
from M5 import *
from hardware import *
from unit import WEIGHTUnit

label0 = None
title0 = None
label1 = None
label2 = None
weight_0 = None

import math

gewicht = None
gewicht1 = None

def btnA_wasClicked_event(state):
  global label0, title0, label1, label2, weight_0, gewicht, gewicht1
  weight_0.set_tare()

def setup():
  global label0, title0, label1, label2, weight_0, gewicht, gewicht1

  weight_0 = WEIGHTUnit((33,32))
  M5.begin()
  Widgets.fillScreen(0x222222)
  label0 = Widgets.Label("label0", 45, 87, 1.0, 0xffffff, 0x222222, Widgets.FONTS.DejaVu72)
  title0 = Widgets.Title("Futter/Feed", 3, 0xffffff, 0x0000FF, Widgets.FONTS.DejaVu40)
  label1 = Widgets.Label("Kg", 47, 163, 1.0, 0xffffff, 0x222222, Widgets.FONTS.DejaVu24)
  label2 = Widgets.Label(">0<", 49, 224, 1.0, 0xffffff, 0x222222, Widgets.FONTS.DejaVu12)

  BtnA.setCallback(type=BtnA.CB_TYPE.WAS_CLICKED, cb=btnA_wasClicked_event)

def loop():
  global label0, title0, label1, label2, weight_0, gewicht, gewicht1
  M5.update()
  gewicht = (weight_0.get_scale_weight) / 52000
  gewicht1 = round(gewicht, 2)
  if gewicht1 <= 0.00:
    gewicht1 = 0.00
  label0.setText(str(gewicht1))
  sleep(1)

if __name__ == '__main__':
  try:
    setup()
    while True:
      loop()
  except (Exception, KeyboardInterrupt) as e:
    try:
      from utility import print_error_msg
      print_error_msg(e)
    except ImportError:
      print("please update to latest firmware")

Die Mittelwertermittlung über ein Fifo-Speicher sollte die Glättung machen

gl_Gewichte=[0,0,0,0,0] # Je mehr Elemente um so mehr Glättung

def loop():
    global gl_Gewichte
    Gewicht=randint(0, 200)  # hier Natürlich deinen Sensor auslesen

    gl_Gewichte.append(Gewicht)   # Neues Gewicht rein in den FIFO
    gl_Gewichte.pop(0) # Das älteste raus aus dem FIFO

   # und den Mittelwert berechnen
    Summe = 0
    Anzahl = 0
    for Gewicht in gl_Gewichte:
        Summe = Summe + Gewicht
        Anzahl += 1
        
    Gewicht = Summe/Anzahl

    print(Gewicht)

geht gewiss auch eleganter... aber so sollte es erst mal funktionieren

2 Likes

Wenn die loop funktioniert so wie bei der IDE wird nix mit Mittelwert, jedoch könne Pascal gar nicht.

1 Like

Nein, genauer wird es durch eine Mittelung nicht... nur das Rauschen kann man reduzieren. Wie genau ist denn dein Sensor ?

Welches Messintervall möchtest du / brauchst du ?

1 Like

wenn du das globale Array gl_Gewichte einbeziehst klappt es..

1 Like

In C, C++, BASIC wurde das nicht funktionieren, wegen
Summe = 0
Anzahl = 0
Es wurde nur funktionieren wen man direkt in die for Schelfe zurück springt.

1 Like

Ich kann dir nicht ganz folgen....

aber die beiden Zuweisungen vor der Schleife sind in allen Sprachen gleich...

In Python kann man direkt über die Array-Werte iteriern ohne diese zu referenzieren ... aber das ist halt Python :slight_smile:

1 Like

Wenn Du eine Programmiersprache nicht verstehst, solltest Du nicht über Programme in dieser Sprache urteilen. Du blamierst Dich dabei nur.
Oder willst Du mit Pucki007 in einen Wettbewerb treten?

Gruß Tommy

Abgesehen davon wie die vor schleife aufgebaut ist, wird das in der IDE mit void loop() nicht Funktionieren den bei jedem durchlauf wird Summe und Anzahl auf null gesetzt da kann man Addieren wie man will, man fängt immer mit 0 an, außer man setzt beide vor die loop, oder springt zurück in die for schleife.

1 Like

Deshalb war ja die Frage ob die loop funktioniert wie bei Arduino IDE.

1 Like

Nö, tut sie nicht. Ist ja, wie im Code zu sehen, eine selbst erstellte Funktion.

Gruß Tommy

1 Like

Danke, hätte @leonardo-zwei so wie Du geantwortet, hätte mein M.. gehalten.

1 Like