ESP8266 PWM Pin4

OP #7579690
Lesenswert?

Hi, kann man den Pin4 verwenden um ein PWM Feedback von der Wilo Umwälzpumpe zu bekommen?

frequency = 150 solarpump = PWM(Pin(5), frequency) pwminput = PWM(Pin(4), 75)

Das Senden funktioniert, aber ich bekomme keine Antwort auf Pin4:

PWM(4, freq=75, duty=0) 399 PWM(4, freq=75, duty=0)

OP #7579961
Lesenswert?

Board: Nodemcu 12e http://cms.media.wilo.com/cdndoc/wilo429191/4683951/wilo429191.pdf Micropython Quellcode:

import uos, machine, esp, gc, webrepl, network, socket, ure, time import onewire, ds18x20 from machine import PWM, Pin from umqttsimple import MQTTClient import ubinascii from time import sleep

mqtt_server = '192.168.178.23' client_id = ubinascii.hexlify(machine.unique_id()) topic_sub = b'heatp/solar' topic_sub2 = b'heatp/pump' topic_pub = b'heatp/heizraum' #solartemp = -199 #pumpvalue = 1022 last_message = 0 message_interval = 5 counter = 0 frequency = 150 solarpump = PWM(Pin(5), frequency) pwminput = PWM(Pin(4), 75)

def sub_cb(topic, msg): global solartemp global pumpvalue
print(topic, msg) if topic == topic_sub: solartemp = int(msg.decode('utf-8')) print(solartemp) if topic == b'heatp/pump': pumpvalue = int(msg.decode('utf-8'))

def connect_and_subscribe(): global client_id, mqtt_server, topic_sub client = MQTTClient(client_id, mqtt_server) client.set_callback(sub_cb) client.connect() client.subscribe(topic_sub) client.subscribe("heatp/pump") print('Connected to %s MQTT broker, subscribed to %s topic' % (mqtt_server, topic_sub)) return client

def restart_and_reconnect(): print('Failed to connect to MQTT broker. Reconnecting...') time.sleep(5) machine.reset()

try: client = connect_and_subscribe() except OSError as e: restart_and_reconnect()

while True: try: client.check_msg() if (time.time() - last_message) > message_interval: msg = b'Hello #%d' % counter last_message = time.time() print(last_message) client.publish("heatp/ip169", msg) counter += 1 if 3>4: #4 < stemp < 32: solarpump.duty(0) else: try: pumpvalue except NameError: x = 777 else: print(pumpvalue) print(pwminput) solarpump.duty(pumpvalue) sleep(0.5) except OSError as e: restart_and_reconnect()

OP #7580316
Lesenswert?

Ja, die Antwort sieht auf dem Oszilloskop einwandfrei aus.

Danke für Deine Antwort, das wäre aber schade, wenn ein so mächtiger Chip wie der ESP8266 kein PWM Signal als Input auswerten könnte. Es muss ja nur der Duty_Cycle der am Pin anliegt, erkannt werden. Ich könnte mir aber vorstellen, dass das Board nicht mit zwei verschiedenen Frequenzen umgehen kann. Die Frage warum WILO, beim Feedback 75Hz verwendet, stelle ich mir auch.

#7580319
Lesenswert?

Schorsch Z. schrieb:

das wäre aber schade, wenn ein so mächtiger Chip wie der ESP8266 kein PWM Signal als Input auswerten könnte.

Dafür hat er aber Fähigkeiten, die andere Controller nicht haben, die PWMs vermessen können...

Der erste Blick sollte ins Datenblatt gehen: https://www.espressif.com/sites/default/files/documentation/0a-esp8266ex_datasheet_en.pdf Kapitel 4.:"Peripheral Interface" Da steht nur, dass er vier PWMs erzeugen kann, aber nicht, dass sie auch einlesen kann. Der hat vermutlich schon mit dem WLAN-Gedöns genug um die Ohren.

Man könnte einen AVR (oder ähnliches) nehmen, mit dem die PWN per Input-Capture-Unit messen und dann UART, I²C oder SPI an den ESP übertragen.

Gast #7580337
Lesenswert?

Rahul D. schrieb:

Da steht nur, dass er vier PWMs erzeugen kann, aber nich

Selbst dass ist eigentlich gelogen. Der Chip hat keinerlei PWM Hardware. Deswegen heißt es im Datenblatt: "The functionality of PWM interfaces can be implemented via software programming".

Und "via software programming" ist insofern problematisch, dass die Software unregelmäßig oft und unterschiedlich lange unterbrochen wird, um die WLAN Schnittstelle zu bedienen. Die Ergebnisse werden dementsprechend ungenau. Sieht man bei PWM Dimmern schön daran, dass die Lichter flackern. Mal mehr, mal weniger.

Gast #7580347
Lesenswert?

Die Aufgabe des Programmierers ist, Wünsche mit der verfügbaren Hardware und Software in Einklang zu bringen. Einfach irgendwas hin zu schrieben und auf Glück hoffen, ist keine funktionierende Arbeitsmethode.

Von PWM Eingabe steht nirgendwo etwas. Nicht im Datenblatt, nicht der Anleitung von Micropython, nicht in der Anleitung vom großen Python und auch in keinem Diskussionsforum.

Schorsch, wo hast du das her?:

1
pwminput = PWM(Pin(4), 75)
2
print(pwminput)

Ich könnte mir aber vorstellen, dass das Board nicht mit zwei verschiedenen Frequenzen umgehen kann

Beim Arduino Framework gibt es diese Einschränkung tatsächlich. Sie kommt daher, dass dort das PWM Signal in einem Interrupt-Handler per Software erzeugt wird (geht ja nicht anders) und es nur einen Timer gibt, der dazu taugt.

So viel zum Thema "mächtig". Was den Funktionsumfang angeht, ist der Chip alles andere als mächtig. Der kann ja nicht nicht einmal aus dem Ruhezustand aufwachen, ohne neu zu booten. Sorry, aber ich glaube zu vertraust da zu sehr den wohlwollenden Superlativen von Espressifs Marketing.

Damit du in Zukunft nicht noch öfter auf falsche Erwartungen herein fällst empfehle ich dir, diese Seite zu lesen: http://stefanfrings.de/esp8266/index.html

Und lass dir nicht einreden, dass die zahlreichen ESP32 Varianten als Nachfolger ohne Mängel seien. Da ist auch nicht alles Gold, was glänzt.

#7580348
Lesenswert?

Schorsch Z. schrieb:

OK, ich werde jetzt versuchen die 75Hz mit dem AD Pin zu analysieren, bei 10-bit Auflösung, sollte das ja keinerlei Problem sein, oder.

Was hat die ADC-Auflösung mit einem genauen Timing (was für eine PWM-Vermessung reelvant sein sollte) zu tun?

Würde man den ESP-ADC kontinuierlich messen lassen ("adc_read_fast()"), könte man kein WiFi mehr benutzen (Punkt 4 im von die geposteten Dokuments).

Edit: Vielle geht das damit: https://esphome.io/components/sensor/pulse_width.html

pwminput = PWM(Pin(4), 75)

Erscheint mir nicht wirklich zielführend zu sein. Ich kann mich aber auch irren, da ich eine Aversion gegen Python habe (und da schimpfen andere über Arduino...)

Gast #7580355
Lesenswert?

Schorsch Z. schrieb:

ich werde jetzt versuchen die 75Hz mit dem AD Pin zu analysieren, bei 10-bit Auflösung, sollte das ja keinerlei Problem sein,

Wenn du mit bis zu 20% Abweichung vom richtigen Wert leben kannst, dann kann das klappen. Du musst dabei aber das WLAN aus schalten (was einen Neustart erfordert), sonst ist er noch ungenauer.

#7580361
Lesenswert?

Steve van de Grens schrieb:

Ich denke, er will das PWM Signal mit einem Tiefpass in eine analoge Spannung umwandeln, und diese dann messen.

kommt mir bekannt vor... Also ein digitales Signal analogisieren um es dann in ein digitales zu wandeln. Das hat ein Kollege auch mal gemacht, weil ihm Modbus zu kompliziert war. Man kann natürlich vor der Auswahl der Hardware schon mal auflisten, was man am Ende alles haben will.

OP #7580375
Lesenswert?

Ja, es geht leider nur über den Tiefpass Umweg, da nur das pyboard die elegante Methode "ADC.read.timed()" zur Verfügung stellt und das ADC sample in einen Buffer liest, der dann ausgewertet werden kann. Ich habe jetzt nur die Möglichkeit mit 25% Ungenauigkeit zu leben, oder für einen DI Pin einen buffer zu implementieren um über das timing die Pulsweite zu analysieren. Aber wer weiss wie ungenau das dann wieder sein wird? NUr gut dass das Board nur 6 Euro gekostet hat. Eventuell steige ich noch auf einen teurere Hardware um...

#7580387
Lesenswert?

Schorsch Z. schrieb:

Ja, es geht leider nur über den Tiefpass Umweg, da nur das pyboard die elegante Methode "ADC.read.timed()" zur Verfügung stellt und das ADC sample in einen Buffer liest, der dann ausgewertet werden kann.

Zitat aus der micropython-Doku: "ADC.read_timed(buf, timer)

1
Read analog values into buf at a rate set by the timer object.
2

3
buf can be bytearray or array.array for example. The ADC values have 12-bit resolution and are stored directly into buf if its element size is 16 bits or greater. If buf has only 8-bit elements (eg a bytearray) then the sample resolution will be reduced to 8 bits.
4

5
*timer* should be a Timer object, and a sample is read each time the timer triggers. The timer must already be initialised and running at the desired sampling frequency.
6

7
To support previous behaviour of this function, timer can also be an integer which specifies the frequency (in Hz) to sample at. In this case Timer(6) will be automatically configured to run at the given frequency."

Woher kommt das Timer-Objekt, wenn der Controller nur den Watchdog als Timer besitzt?

#7580739
Lesenswert?

Schorsch Z. schrieb:

Hast Du einen Sourcecode Deiner Lösung?

Machbar ist das auf dem ESP8266 mit MicroPython schon, denke ich. Vielleicht so:

1
import micropython
2
micropython.alloc_emergency_exception_buf(100)
3
import time
4
from machine import Pin
5
ti = tr = tf = ton = ttot = 0
6
def pirq(p):
7
     global tc, tr,tf,ton,ttot
8
     t = time.ticks_us()
9
     if p.value():
10
         if ti:
11
             ton = (tf-tr)%0x100000000
12
             ttot = (t-tr)%0x100000000
13
         tr = t
14
         ti = 1
15
     else:
16
         tf = t
17
p4 = Pin(4,Pin.IN)
18
cb = p4.irq(pirq,Pin.IRQ_FALLING|Pin.IRQ_RISING)

Während der Berechnung von duty als ton/ttot außerhalb von pirq solltest du die Interrupts kurz sperren.

Dieser Code fängt allerdings noch nicht den Fall 0% Duty Cycle ab.

LG, Sebastian

OP #7580761
Lesenswert?

Wow, Sebastian, Du bist ja ganz schön fit mit dem Zeug! Da ich für die Wilo Pumpen eine einfache Lösung suche habe ich mir jetzt aber 10 Stück Pi Pico W bei Kaufland bestellt, da die nur 5,15 Euro kosten und alles von der Stange können was ich brauche: https://datasheets.raspberrypi.com/picow/pico-w-datasheet.pdf

Ich frage mich, warum ich für meine bisherigen Projekte jemals ein anderes Board benutzt habe.

Das Pico W ist günstiger und wesentlich leistungsfähiger als esp8266.

Viele Grüße Schorsch

#7580834
Lesenswert?

Schorsch Z. schrieb:

Ich frage mich, warum ich für meine bisherigen Projekte jemals ein anderes Board benutzt habe.

du hast eine tolle Tischkreissäge, aber jetzt eine große Platte die du da nicht durchschieben kannst. Da ist eine Handkreissäge mit Schiene auf einmal viel besser. Jetzt möchtest du einen Stamm aufsägen, aber der ist zu dick für beide Sägen. Also muss eine Bandsäge her. Passt nicht für die Kurvenschnitte in der Arbeitsplatte, also noch ne Stichsäge. usw....

Gast #7580951
Lesenswert?

Python auf einem Mikrocontroller fühlt sich für mich an wie

Brötchen kaufen mit einer schweren Transportkiste. Man braucht ein Auto, um die schwere Kiste zu transportieren. Und eine Garage, um das Auto zu laden. Und eine Werkstatt, um das Auto zu pflegen.

Unterm Strich ist mir "zu Fuß gehen mit Einkaufstüte" lieber.

OP #7581062
Lesenswert?

Da geht es Dir wie mir. Ich bin auch am liebsten auf steinigen Pfaden unterwegs, wo man nie genau weis, was als nächstes passiert und man viel ausprobieren kann: https://www.youtube.com/watch?v=_JM-e_cl4Wc&t=544s

Nur beim Programmieren halte ich es wie Walter Röhrl und möchte in meinen von den Maintainern bis aufs letzte optimierten "Opel Ascona 400" einsteigen und in Rekordzeit zum Erfolg kommen :-)

https://www.youtube.com/watch?v=Ke5PaNYKlNE

#7581215
Lesenswert?

Steve van de Grens schrieb:

Python auf einem Mikrocontroller fühlt sich für mich an wie Brötchen kaufen mit einer schweren Transportkiste.

Hab gerade https://github.com/micropython/micropython/pull/5962 gefunden. Die MicroPython machine.Pin change interrupts auf dem ESP8266 können nicht "hard=True" sein, sind also sehr flatterhaft. Damit lässt sich die Austastung eines 75Hz-Rechtecks nicht vernünftig messen, ich habs probiert. Die schwere Transportkiste ist also so grob gezimmert dass die meisten Brötchen auf die Straße fallen :(

LG, Sebastian

#7581244
Lesenswert?

Eine PWM lässt sich sehr einfach per Software einlesen, wenn der Eingangsport Interrupts für fallende und steigende Flanken auslösen kann und ein Timer vorhanden ist. Ob das der ESP8266 kann, hab ich nicht nachgeschaut, aber ich nehme es an.

  1. Man konfiguriert den Interrupt des Ports für steigende Flanke
  2. Sobald die steigende Flanke auftritt, startet man einen Timer und konfiguriert den Interrupt um auf fallende Flanke
  3. Sobald die fallende Flanke auftritt, speichert man den Timerwert, startet den Timer neu und konfiguriert den Interrupt auf steigende Flanke
  4. Anschließend wertet man den Timer aus und hat nun die Pulsdauer des positiven Pulses
  5. Sobald die steigende Flanke auftritt, speichert man wieder den Timerwert, startet den Timer neu und konfiguriert den Interrupt auf fallende Flanke
  6. Anschließend wertet man den Timer aus und hat nun die Pulsdauer des negativen Pulses. Aus der Pulsdauer des positiven und negativen Pulses, lässt sich leicht die PWM ausrechnen.

Wenn man den Interrupt mit höchster Priorität laufen lässt, dann bekommt man eine sehr genaue Messung, die nur von der Genauigkeit des Timers abhängt.

Die Flanken der PWM dürfen nicht schneller auftreten, als die ISR dauert.

Falls der Eingang prellt, muss man eine Entprellung vornehmen. Entweder in Hardware oder in Software.

vG Sven

Gast #7581286
Lesenswert?

Sven L. schrieb:

Ob das der ESP8266 kann, hab ich nicht nachgeschaut, aber ich nehme es an.

Interrupts und Timer sind vorhanden

Wenn man den Interrupt mit höchster Priorität laufen lässt, dann bekommt man eine sehr genaue Messung

Daramn scheitert es. Das Programm wird zur Bedienung der WLAN Schnittstelle zu unregelmäßigen Zeitpunkten für unregelmäßige Dauer unterbrochen. Das hat leider höhere Prio, als die Pin Changes.

OP #7582561
Lesenswert?

Mit dem Pi Pico W, funktioniert die Vermessung bei 40% Drehzahl perfekt! Connected to 192.168.178.23 MQTT Broker New message on topic heatp/pump duty = 32000 High-Flanke: 72 Low-Flanke : 39556 High-Flanke:77 Low-Flanke :39734 und so weitere... New message on topic heatp/pump 32000 103 39537 106 39695

Nochmals Vielen Dank Sebastian!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren