Forum: Mikrocontroller und Digitale Elektronik Vor und Nachteile von MicroPython auf dem ESP8266


von Kolja L. (kolja82)


Lesenswert?

Nabend

Nachdem ich jetzt auf dem ESP ein Python laufen habe,
frage ich mich gerade, ob das denn wohl zielführend war.

Der ausschlaggebende Grund für den Versuch ist,
dass der ESP mit µPython relativ einfach ein MeshNetzwerk aufbauen kann.

So langsam dämmert mir aber der Unterschied zwischen kompilieren und 
interpretieren.
Nämlich die Zeit.

Eine fast leere while true Schleife soll nur drei mal pro Sekunde 
durchlaufen.
Damit wäre es ja unmöglich ein Poti auszulesen,
welches sich in einer Sekunde um 180° dreht.
Also, möglich ist es schon,
nur bekomme ich dann ja nur die Werte 0,90,180 ausgegeben.

Oder gibt es eine Möglichkeit den ADC zu beschleunigen?

Danke und Gruß

Kolja

von (prx) A. K. (prx)


Lesenswert?

Kolja L. schrieb:
> Eine fast leere while true Schleife soll nur drei mal pro Sekunde
> durchlaufen.

Ein "while(1) { delayMS(333); }" ist auch fast leer und trotz Compiler 
nicht schneller. ;-)

So krass langsam kann ein Interpreter eigentlich kaum sein, um auf einem 
80 MHz Prozessor eine simple Totschleife derart langsam zu machen. 
Klingt nach anderer Ursache.

von Timmo H. (masterfx)


Lesenswert?

Also ich habe anfangs auch mit LUA auf dem ESP rumgespielt. Ist zwar 
ganz nett, aber wenn es um Perfomance geht fand ich dann doch die 
Arduino-Lösung (auch wenn ich Arduino eigentlich nicht so mag) besser... 
insb. was die Perfomance angeht ist natives C/C++ auf dem ESP eine ganze 
Ecke schneller, und da alles in der inzwischen sehr gut in Arduino 
implementiert ist, wüsste ich nicht warum ich zu einem Interpreter 
greifen sollte, wenn es doch fast genauso einfach mit C geht bzw. den 
von Arduino bereitgestellten Libs geht.

Ich hatte mit LUA versucht in einem festen Zeitraster eine BMP-Datei von 
dem Dateisystem zu lesen und dieses Spaltenweise an einen WS2812 
LED-Strip zu senden (64 Pixel). Mit LUA war das alles andere als 
berechenbar (mal brauchte eine Spalte 10ms, mal 100ms). Mit Arduino und 
fs.h habe ich meine konstante  50 Hz problemlos geschafft.

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

https://github.com/micropython/micropython/wiki/Performance

Also so schlimm wie du tust dürft die Performance nicht sein...
Du kannst ja mal versuchen den ADC via DMA auszulesen und via Timer 
triggern zu lassen. Dann braucht ausschließlich das verarbeiten der 
Werte CPU Zeit.

Sonst bietet Micropython mit Sicherheit irgendein C-Interface an?

von Joachim S. (oyo)


Lesenswert?

Timmo H. schrieb:
> Ich hatte mit LUA versucht in einem festen Zeitraster eine BMP-Datei von
> dem Dateisystem zu lesen und dieses Spaltenweise an einen WS2812
> LED-Strip zu senden (64 Pixel). Mit LUA war das alles andere als
> berechenbar (mal brauchte eine Spalte 10ms, mal 100ms).

Das verstehe ich jetzt auch nicht ganz, denn das senden einer 
WS2812-Spalte ist in LUA ja nur ein einziger Funktionsaufruf, 
`ws2812.write()` - und diese Funktion ist auch bei NodeMCU ja gar nicht 
in LUA, sondern in C implementiert.
Könnte mir das höchstens so erklären, dass Du die zu sendenden Daten 
jedes Mal neu erzeugt hast, statt einen Buffer (wieder) zu benutzen, und 
der ESP daher ständig im Hintergrund eine garbage collection 
durchgeführt hat oder irgend sowas...

Ansonsten @Threadstarter: Es ist klar, dass interpretierter Code niemals 
die Geschwindigkeit von gutem kompiliertem C/C++-Code erreicht. Dennoch 
glaube auch ich nicht, dass das beschriebene Problem nur mit kompiliert 
vs. interpretiert zu tun hat. Ich programmiere den ESP8266 in LUA, also 
ebenfalls interpretiert, und da laufen Schleifen völlig problemlos viele 
tausend Mal pro Sekunde durch.

von Timmo H. (masterfx)


Angehängte Dateien:

Lesenswert?

Joachim S. schrieb:
> Das verstehe ich jetzt auch nicht ganz, denn das senden einer
> WS2812-Spalte ist in LUA ja nur ein einziger Funktionsaufruf,
> `ws2812.write()` - und diese Funktion ist auch bei NodeMCU ja gar nicht
> in LUA, sondern in C implementiert.
> Könnte mir das höchstens so erklären, dass Du die zu sendenden Daten
> jedes Mal neu erzeugt hast, statt einen Buffer (wieder) zu benutzen, und
> der ESP daher ständig im Hintergrund eine garbage collection
> durchgeführt hat oder irgend sowas...
Ne das eigentliche ws2821 write ist hier nicht das Problem gewesen, 
sondern vielmehr wie LUA mit Dateien umgeht. Alles wird zunächst als 
Strings interpretiert und direkt aus dem BMP-Format zu lesen, Bytes zu 
swappen und in RGB zu konvertieren ist extrem langsam. Etwas besser ging 
es schon als ich das BMP in ein Text-File konvertiert, in der jede Zeile 
jeweils alle Farbwerte für Zeitpunkt x dargestellt werden:
1
ws2812.init()
2
led_buffer = ws2812.newBuffer(60, 3);
3
4
tmr.register(0, 50, tmr.ALARM_AUTO, function() 
5
    mystring = file.readline()
6
    for w in mystring:gmatch("([^;]*);") do 
7
        r,g,b = w:match("([^,]+),([^,]+),([^*]+)")
8
        led_buffer:set(i,tonumber(g),tonumber(r),tonumber(b))
9
        i = i+1
10
    end
11
    ws2812.write(led_buffer)
12
    spalte = spalte + 1
13
end)
Hat er aber nicht immer in 50ms geschafft.
In Arduino konnte ich direkt das BMP nehmen und damit direkt arbeiten.
1
if ((read16(bmpFile) == 1) && (read16(bmpFile) == 24) && (read32(bmpFile) == 0)) { // Must be depth 24 and 0 (uncompressed format)
2
      //goodBmp = true; // Supported BMP format -- proceed!
3
      // BMP rows are padded (if needed) to 4-byte boundary
4
      rowSize = (bmpWidth * 3 + 3) & ~3;
5
      // Crop area to be loaded
6
      w = bmpWidth;
7
      h = bmpHeight;
8
9
      // We might need to alter rotation to avoid tedious pointer manipulation
10
      // Save the current value so we can restore it later4
11
      for (uint32_t pos = bmpImageoffset; pos < bmpImageoffset + h * rowSize ; pos += rowSize) {
12
        if (bmpFile.position() != pos) {
13
          bmpFile.seek(pos,SeekSet);
14
          bmpFile.read(sdbuffer, sizeof(sdbuffer));
15
        }
16
        
17
        uint16_t buffer_pos=0;
18
          for(i = 0; i < w; i++) {
19
            
20
            pixels.setPixelColor(i, gamma8[sdbuffer[buffer_pos+2]], gamma8[sdbuffer[buffer_pos+1]], gamma8[sdbuffer[buffer_pos]]);
21
            buffer_pos +=3;
22
          }
23
           pixels.show();
24
          
25
          delay(20);
26
        }
27
      }
28
      
29
    }
30
  
31
  bmpFile.close();
Damit kann man dann schöne Bilder in die Luft malen :D. Und da ist das 
exakte Timing halt wichtig, da man ja immer eine Konstante 
Geschwindigkeit gehen/fahren möchte

: Bearbeitet durch User
von Joachim S. (oyo)


Lesenswert?

Timmo H. schrieb:
> Damit kann man dann schöne Bilder in die Luft malen :D. Und da ist das
> exakte Timing halt wichtig, da man ja immer eine Konstante
> Geschwindigkeit gehen/fahren möchte

Aaaah, jetzt ergibt das alles Sinn. In der Tat ein gutes Beispiel für 
eine ESP8266-Aufgabe, die so zeitkritisch ist, dass MicroPython oder LUA 
einfach nicht gut geeignet sind.

Sehr geile Idee übrigens!

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.