Forum: Mikrocontroller und Digitale Elektronik ESP8266 mit DHT11 Sensor -> HTTP-GET request


von Pascal S. (pascalsch)


Lesenswert?

Hallo Zusammen,

Habe ein neues Spielzeug bekommen... ;)
Den ESP8266.

Nun will ich mit dem über einen DHT11-Sensor die Temperatur und 
Luftfeuchtigkeit erfassen.
Hierfür habe ich folgende Skripte von jankop 
(http://www.esp8266.com/viewtopic.php?f=19&t=1363) gefunden:

http://esp8266.fancon.cz/common/monDHT11.lua
http://esp8266.fancon.cz/common/dht11.lua


Diese funktionieren einwandfrei, sieht super aus!
Jedoch will ich jetzt bei diesem Code noch ein HTTP-GET request 
einfügen, der die Daten an meinen Webserver sendet.
Das Format sollte folgend sein: 
"http://example.com/upload.php?tempf=69.98&tempc=21.1&humidity=67";.

Habe schon etliche Codes ausprobiert, jedoch will das nicht ganz so... 
:(
Bin noch nicht wirklich vertraut mit dem ESP...

Hat hier jemand Erfahrung mit dem, wäre Froh um eine Hilfe!
Danke!


Gruß,
PascalSch

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Pascal S. schrieb:
> Hat hier jemand Erfahrung mit dem ESP…

Hier? Sicherlich nicht nur einer, sondern viele.
Vielleicht nicht speziell mit LUA.

Wo klemmt es?

: Bearbeitet durch User
von Pascal S. (pascalsch)


Lesenswert?

Hallo Torsten C.

Danke für deine schnelle Antwort!

Habe bereits probiert in den init.lua (monDHT11.lua von oben) folgenden 
Code einzufügen:
1
print('Upload started')
2
3
conn = nil
4
conn=net.createConnection(net.TCP, 0) 
5
6
-- show the retrieved web page
7
8
conn:on("receive", function(conn, payload) 
9
                       success = true
10
                       print(payload) 
11
                       end) 
12
13
-- when connected, request page (send parameters to a script)
14
conn:on("connection", function(conn, payload) 
15
                       print('\nConnected') 
16
                       conn:send("GET /update.php?"
17
                        .."soiltempf="..fare
18
                        .."&soiltempc="..temp
19
            .."&soilhumidity="..humi
20
                        .." HTTP/1.1\r\n" 
21
                        .."Host: example.com\r\n" 
22
                      .."Connection: close\r\n"
23
                        .."Accept: */*\r\n" 
24
                        .."User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n" 
25
                        .."\r\n")
26
                       end) 
27
-- when disconnected, let it be known
28
conn:on("disconnection", function(conn, payload) print('\nDisconnected') end)
29
                                             
30
conn:connect(80,'example.com')

Jedoch ohne Erfolg, muss ich vielleicht ein neues Programm (httpget.lua) 
daraus machen und es im init.lua aufrufen, aber wie?
Wie gesagt ist komplett neues Gebiet für micht ;)


Gruß,
PascalSch

von Dirk K. (dekoepi)


Lesenswert?

Gehört dir die Domain "example.com"? Lauscht da dein Server?

Das ist die einfachste Adaption, die dir da grade nicht gelingt.

von Pascal S. (pascalsch)


Lesenswert?

Hallo Dirk,

Nein, beim ESP8266 habe ich schon meine Homepage angegeben, habe sie 
aber für diesen Post auf example.com getauscht (Geheim :P), ansonsten 
der genau gleiche Code :D

Außerdem startet der Code gar nicht auf dem ESP8266, wenn ich es beim 
init-Code oben unten anfüge...
Muss ich vielleicht ein neues Programm (httpget.lua) daraus machen und 
es im init.lua aufrufen, aber wie?


Trotzdem mal danke!


Gruß,
PascalSch

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Trag doch in den Code des ESP8266 den URL-Aufruf einfach mal als 
vollständige Textkonstante mit Fake-Argumenten ein. Wenn dieser Aufruf 
ankommt, steckt dein Problem im Zusammenbau der Zeile ...

von Honk (Gast)


Lesenswert?

Ich würde das nicht in der init.lua machen.
Du musst sicherstellen, dass die WLAN-Verbindung zum Zeitpunkt von 
createConnection() bereits steht.

von Dirk K. (dekoepi)


Lesenswert?

Ja, mit einem Timer prüfen und das Senden in eine Funktion werfen. (Ich 
mache das in init.lua :P )

Vor dein Print:
1
function loop()
2
  if wifi.sta.status() == 5 then
3
    -- Stop the wifi connection wait-loop
4
    tmr.stop(0)

Nach dem conn:connect:
1
    end)
2
  else
3
    print("Waiting for Wifi ...\n")
4
  end
5
end
6
7
tmr.alarm(0, 100, 1, function() loop() end)

: Bearbeitet durch User
von Florian T. (florian_t)


Lesenswert?

Ich habe auch den ESP8266 und LUA war mir für meine Zwecke nicht mehr 
ausreichend. Ich habe darauf hin ESPEasy gefunden welche schon die 
Bibliothek für die meisten Sensoren dabei hat und schon mit diversen 
Heimautomatisierungslösungen reden kann.

Ich habe die Firmware dann für mich modifiziert dass sie auch per HTTP 
GET mit einer beliebigen Domain richtig kommunizieren kann.

Ich bin gerade dabei einen Dienst aufzubauen an den man seine Daten 
schicken und visualisieren kann. Bei Interesse kannst Dich gerne mal 
melden. :-)

von Pascal S. (pascalsch)


Lesenswert?

Hallo Zusammen,

Danke für euer Antworten!

Also die WLAN-Verbindung besteht immer, da ja der ESP über die IP 
abrufbar ist (Webserver), was ja tadellos geht...

Hier mal meine Codes:

init.lua
1
wifi.setmode(wifi.STATION)
2
wifi.sta.config("SSID","PASSWORD")
3
tmr.delay(1000000)
4
humi="XX"
5
temp="XX"
6
fare="XX"
7
bimb=1
8
PIN = 4 --  data pin, GPIO2
9
--load DHT11 module and read sensor
10
function ReadDHT11()
11
  dht11 = require("dht11")
12
  dht11.read(PIN)
13
  t = dht11.getTemperature()
14
  h = dht11.getHumidity()
15
  humi=(h)
16
  temp=(t)
17
  fare=((t*9/5)+32)
18
  print("Humidity:    "..humi.."%")
19
  print("Temperature: "..temp.." deg C")
20
  print("Temperature: "..fare.." deg F")
21
  -- release module
22
  dht11 = nil
23
  package.loaded["dht11"]=nil
24
end
25
26
ReadDHT11()
27
tmr.alarm(1,60000, 1, function() ReadDHT11() bimb=bimb+1 if bimb==5 then bimb=0 wifi.sta.connect() print("Reconnect")end end)
28
29
srv=net.createServer(net.TCP) srv:listen(80,function(conn)
30
    conn:on("receive",function(conn,payload)
31
  --print(payload) -- for debugging only
32
  --generates HTML web site
33
    conn:send('HTTP/1.1 200 OK\r\nConnection: keep-alive\r\nCache-Control: private, no-store\r\n\r\n\
34
  <!DOCTYPE HTML>\
35
    <html><head><meta content="text/html;charset=utf-8"><title>ESP8266</title></head>\
36
  <body bgcolor="#ffe4c4"><h2>Hygrometer with<br>DHT11 sensor</h2>\
37
  <h3><font color="green">\
38
  <IMG SRC="http://esp8266.fancon.cz/common/hyg.gif"WIDTH="64"HEIGHT="64"><br>\
39
  <input style="text-align: center"type="text"size=4 name="j"value="'..humi..'"> % of relative humidity<br><br>\
40
  <IMG SRC="http://esp8266.fancon.cz/common/tmp.gif"WIDTH="64"HEIGHT="64"><br>\
41
  <input style="text-align: center"type="text"size=4 name="p"value="'..temp..'"> Temperature grade C<br>\
42
  <input style="text-align: center"type="text"size=4 name="p"value="'..fare..'"> Temperature grade F</font></h3>\
43
  <IMG SRC="http://esp8266.fancon.cz/common/dht11.gif"WIDTH="200"HEIGHT="230"BORDER="2"></body></html>')
44
    conn:on("sent",function(conn) conn:close() end)
45
    end)
46
end)


dht11.lua
1
local moduleName = ...
2
local M = {}
3
_G[moduleName] = M
4
5
local humidity
6
local temperature
7
local checksum
8
local checksumTest
9
local checko1
10
local checko2
11
12
function M.read(pin)
13
  humidity = 0
14
  temperature = 0
15
  checksum = 0
16
  checko1=0
17
  checko2=0
18
  -- Use Markus Gritsch trick to speed up read/write on GPIO
19
  gpio_read = gpio.read
20
  gpio_write = gpio.write
21
22
  bitStream = {}
23
  for j = 1, 40, 1 do
24
    bitStream[j] = 0
25
  end
26
  bitlength = 0
27
28
  -- Step 1:  send out start signal to DHT11
29
  gpio.mode(pin, gpio.OUTPUT)
30
  gpio.write(pin, gpio.HIGH)
31
  tmr.delay(100)
32
  gpio.write(pin, gpio.LOW)
33
  tmr.delay(20000)
34
  gpio.write(pin, gpio.HIGH)
35
  gpio.mode(pin, gpio.INPUT)
36
37
  -- Step 2:  DHT11 send response signal
38
  -- bus will always let up eventually, don't bother with timeout
39
  while (gpio_read(pin) == 0 ) do end
40
  c=0
41
  while (gpio_read(pin) == 1 and c < 100) do c = c + 1 end
42
  -- bus will always let up eventually, don't bother with timeout
43
  while (gpio_read(pin) == 0 ) do end
44
  c=0
45
  while (gpio_read(pin) == 1 and c < 100) do c = c + 1 end
46
47
  -- Step 3: DHT11 send data
48
  for j = 1, 40, 1 do
49
    while (gpio_read(pin) == 1 and bitlength < 10 ) do
50
      bitlength = bitlength + 1
51
    end
52
    bitStream[j] = bitlength
53
    bitlength = 0
54
    -- bus will always let up eventually, don't bother with timeout
55
    while (gpio_read(pin) == 0) do end
56
  end
57
58
  --DHT data acquired, process.
59
  for i = 1, 8, 1 do
60
    if(bitStream[i+0]>2)then
61
      humidity=humidity+2^(8-i)
62
    end
63
  if(bitStream[i+8]>2)then
64
      checko1=checko1+2^(8-i)
65
    end
66
    if(bitStream[i+16]>2)then
67
      temperature=temperature+2^(8-i)
68
    end
69
    if(bitStream[i+24]>2)then
70
      checko2=checko2+2^(8-i)
71
  end
72
    if (bitStream[i+32]>2)then
73
      checksum=checksum+2^(8-i)
74
    end
75
  end
76
77
  checksumTest=(humidity+checko1+temperature+checko2)%256
78
79
 -- convert to negative format
80
 --if temperature > 0x8000 then temperature = -(temperature - 0x8000)
81
 --end
82
83
  if checksum ~= checksumTest then
84
    humidity = -1
85
  end
86
end
87
88
function M.getTemperature()
89
  return temperature
90
end
91
92
function M.getHumidity()
93
  return humidity
94
end
95
96
return M

Wie füge ich jetzt hier ein HTTP-Get request ein?
Funktion?

Wie gesagt, bin kompletter Neuling, daher sorry für die Umstände... ;)


Schöne Grüße,
PascalSch

von Dirk K. (dekoepi)


Lesenswert?

Das ist doch Kraut und Rüben.

Mach mal richtig. Fange von vorne an. Und dann Stück für Stück:
- DHT11 auslesen und mittels Print das Ergebnis auf der Konsole ausgeben
- Wenn das klappt, gerne mal mit dem http-Zeugs spielen. Aber nicht 
Server und irgendwelche GET-Requests durcheinander werfen. Alles mal 
einzeln angehen.

Du musst dein Problem in so kleine Teile zerlegen, dass du diese 
Einzelteile angehen und lösen kannst. Hier hast du mal einen großen Wust 
Chaos hingeworfen. Kein Wunder, dass da nichts geht.

von Florian T. (florian_t)


Lesenswert?

Pascal S. schrieb:
> Wie füge ich jetzt hier ein HTTP-Get request ein?
> Funktion?

http://benlo.com/esp8266/esp8266QuickStart.html
Abschnitt "How do I send data to a server?"

von Pascal S. (pascalsch)


Lesenswert?

Hallo Dirk,

Wie schon geschrieben habe ich die verwendeten Skripte von jankop 
(http://www.esp8266.com/viewtopic.php?f=19&t=1363).

http://esp8266.fancon.cz/common/monDHT11.lua
http://esp8266.fancon.cz/common/dht11.lua

Sie gehen ja auch soweit, jedoch will ich jetzt nur noch das HTTP-GET 
request einfügen...
Das sollte ja möglich sein, oder?

Ich will den ESP einfach so programmieren, dass die Werte des DHT11 
Sensors per Interface über die IP abrufbar sind und die Werte per 
HTTP-GET request an meinen Webserver gesendet werden.

Danke!


Schöne Grüße,
PascalSch

von Pascal S. (pascalsch)


Lesenswert?

Hallo Florian,

Der oben gepostete HTTP-GET-Code entspricht diesem, der leider nicht 
wirklich geht... :(
Bzw. weiß ich nicht genau wo ich ihn bei meinem Code einfügen soll bzw. 
aufrufen.

Wäre Froh um eine Hilfe...
Danke mal! :)


Schöne Grüße,
PascalSch

von Dirk K. (dekoepi)


Lesenswert?

Ich wiederhole mich.

Wirf' mal deinen Server auf dem ESP raus und packe deinen 
http-get-Request rein.

Und wundere dich ...

von Pascal S. (pascalsch)


Lesenswert?

Hallo Dirk,

Ging leider auch nicht... :(

Habe aber einen anderen HTTP-GET request-Code gefunden mit dem funzts 
super!

In dem Fall lass ich das mit dem Server... ;)


Ich sage nochmals vielen Dank an alle!


Schöne Grüße,
PascalSch

von Pascal S. (pascalsch)


Lesenswert?

Hallo Zusammen,

Habe jetzt mal ein bisschen getüffel :P und stehe leider nun komplett 
mit LUA an.

Also, ich habe folgendes gemeistert (abgeleitet von: 
http://projectproto.blogspot.co.at/2016/05/esp8266-and-sht1x-web-interface.html):

init.lua
1
wifi.setmode(wifi.STATION)
2
wifi.sta.config("WIFI_SSID","WIFI_PASSWORD")
3
4
local DAT = 4
5
local CLK = 3
6
7
function DL()
8
  gpio.write(DAT, gpio.LOW)
9
  gpio.mode(DAT, gpio.OUTPUT)
10
end
11
12
function DH()
13
  gpio.mode(DAT, gpio.INPUT)
14
  gpio.write(DAT, gpio.HIGH)
15
end
16
17
function CL()
18
  gpio.write(CLK, gpio.LOW)
19
end
20
21
function CH()
22
  gpio.write(CLK, gpio.HIGH)
23
end
24
25
function DR()
26
  gpio.mode(DAT, gpio.INPUT)
27
  return gpio.read(DAT)
28
end
29
30
function W8()
31
  for i = 1, 100 do
32
    tmr.delay(10000)
33
    if DR() == gpio.LOW then
34
      return true
35
    end
36
  end
37
  return false
38
end
39
40
function RB()
41
  local val = 0
42
  for i = 0, 7 do
43
    CH()
44
    val = val*2 + DR()
45
    CL()
46
  end
47
  return val
48
end
49
50
function shtread(cmd)
51
  DH() CH() DL() CL() CH() DH() CL()
52
  for i = 0, 7 do
53
    if bit.band(cmd, 2^(7-i))==0 then
54
      DL()
55
    else
56
      DH()
57
    end
58
    CH() CL()
59
  end
60
  CH() CL()
61
  if not W8() then
62
    return nil
63
  end
64
  DH()
65
  local val = RB()
66
  DH() DL() CH() CL() DH()
67
  val = val*256 + RB()
68
  DH() CH() CL()
69
  return val
70
end
71
72
temperature = shtread(3)
73
humidity = shtread(5)
74
75
76
--- Get temp and send data to homepage.com
77
function sendData()
78
shtread()
79
print ("Temperature: "..temperature)
80
print ("Humidity: "..humidity)
81
-- conection to homepage.com
82
print("Sending data to homepage.com")
83
conn=net.createConnection(net.TCP, 0) 
84
conn:on("receive", function(conn, payload) print(payload) end)
85
-- homepage.com 81.11.160.21
86
conn:connect(80,'81.11.160.21') 
87
conn:send("GET /update.php?soiltempc="..temperature.."&soilhumidity="..humidity.." HTTP/1.1\r\n") 
88
conn:send("Host: homepage.com\r\n") 
89
conn:send("Accept: */*\r\n") 
90
conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n")
91
conn:send("\r\n")
92
conn:on("sent",function(conn)
93
                      print("Closing connection")
94
                      conn:close()
95
                  end)
96
conn:on("disconnection", function(conn)
97
                      print("Got disconnection...")
98
  end)
99
end
100
-- send data every X ms to homepage.com
101
tmr.alarm(2, 16000, 1, function() sendData() end )

Jedoch funktioniert das leider nicht ganz, ich vermute, dass ich die 
Variablen "temperature" und "humidity" falsch abrufe für das HTTP-GET...


Wie schon geschrieben, bin totaler Neuling in diesem Gebiet, also sorry 
für die Umstände ;)

Bitte um Hilfe!
Ich will einfach, das die Daten vom SHT10 Sensor alle 16 Sekunden 
abgefragt und an meine Hompage per HTTP-GET weitergeleitet wird.


Schöne Grüße,
PascalSch

: Bearbeitet durch User
von Dirk K. (dekoepi)


Lesenswert?

Vor deiner Schleife steht es doch richtig:

temperature = shtread(3)
humidity = shtread(5)


Deine Transferleistung war, davon in der Schleife zu machen:
shtread()


Wo die Funktion definiert ist als:
function shtread(cmd)


Das hat mit Neuling oder nicht nichts zu tun, sondern mit mangelnder 
Konzentration und komplettem Unverständnis der Materie. Fang' doch mal 
an, eine LED zu blinken. So richtig alles von Pieke auf lernen.

: Bearbeitet durch User
von Pascal S. (pascalsch)


Lesenswert?

Hallo Dirk,

Vielen Dank für deine Antwort!

Das verstehe ich jetzt leider aber nicht ganz...

Meinst du so?
1
--- Get temp and send data to homepage.com
2
function sendData()
3
temperature = shtread(3)
4
humidity = shtread(5)
5
print ("Temperature: "..temperature)
6
print ("Humidity: "..humidity)
7
-- conection to homepage.com
8
print("Sending data to homepage.com")
9
conn=net.createConnection(net.TCP, 0) 
10
conn:on("receive", function(conn, payload) print(payload) end)
11
-- homepage.com 81.11.160.21
12
conn:connect(80,'81.11.160.21') 
13
conn:send("GET /update.php?soiltempc="..temperature.."&soilhumidity="..humidity.." HTTP/1.1\r\n") 
14
conn:send("Host: homepage.com\r\n") 
15
conn:send("Accept: */*\r\n") 
16
conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n")
17
conn:send("\r\n")
18
conn:on("sent",function(conn)
19
                      print("Closing connection")
20
                      conn:close()
21
                  end)
22
conn:on("disconnection", function(conn)
23
                      print("Got disconnection...")
24
  end)
25
end
26
-- send data every X ms to homepage.com
27
tmr.alarm(2, 16000, 1, function() sendData() end )

Habe eben noch ein komplettes Unverständnis mit dem Zeugs, kennst du 
vielleicht eine gute Quelle für den Einstieg?

Danke!

Schöne Grüße,
PascalS

von Dirk K. (dekoepi)


Lesenswert?

So sollte es eher klappen.

Edit: Die ganzen einzelnen conn:send gehen schief. Mach einen großen 
String daraus, indem du immer mit ".." anhängst. Also ein großes 
conn:send.
1
conn:send("GET /update.php?soiltempc="..temperature.."&soilhumidity="..humidity.." HTTP/1.1\r\n"
2
.."Host: homepage.com\r\n"
3
.."Accept: */*\r\n" 
4
.."User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n"
5
.."\r\n")



Wo hakt es jetzt? Er druckt die Temperatur und Feuchte im Terminal? Er 
überträgt nur einmal?
Die Werte schwanken nicht so schnell; statt alle 16s einmal alle 5 
Minuten, vielleicht auch minütlich, messen sollte durchaus ausreichen 
für ein ordentlichen Graphen.

: Bearbeitet durch User
von Pascal S. (pascalsch)


Angehängte Dateien:

Lesenswert?

Hallo Dirk,

Danke!

Ja, es funktioniert, jedoch werden falsche Daten ermittelt...

Wie oben im Anhang zu sehen ist, sind die Werte falsch.
Beim Programm mit dem Interface 
(http://projectproto.blogspot.co.at/2016/05/esp8266-and-sht1x-web-interface.html) 
hat es jedoch super funktioniert, die Werte stimmten, warum jetzt nicht 
mehr?
Habe ich etwas vergessen?


Schöne Grüße,
PascalS

von Dirk K. (dekoepi)


Lesenswert?

Jetzt guckst du ins Datenblatt deines Sensors.

Die Werte, die du jetzt ausgibst, sind 1:1 die vom Sensor geschickten. 
Die muss man aber noch umrechnen.
Datenblatt: https://akizukidenshi.com/download/ds/aosong/DHT11.pdf

Vielleicht solltest du einfach die in der NodeMCU-Firmware integrierte 
Funktion dafür nutzen, anstatt dieser komischen read-Routine.
1
PIN = 4 -- GPIO2, also hier anpassen an den richtigen Pin (GPIO ist nicht dieselbe Nummer wie die Pin-Nummer!
2
DHT.read11(PIN)
3
 
4
t = DHT.getTemperature()
5
h = DHT.getHumidity()


https://nodemcu.readthedocs.io/en/master/en/modules/dht/

: Bearbeitet durch User
von Pascal S. (pascalsch)


Lesenswert?

Hallo Dirk,

Erst mal muss ich beichten, dass der Titel dieses Beitrags falsch ist, 
es handelt sich um den SHT10 Sensor, k.A. was da bei mir abging ;)

Zum berechnen:
Habe gerade gesehen, dass es im Programm mit dem Web-Inferface ebenfalls 
berechnet wird, sorry, bin glaube ein bisschen daneben...

Also, so wird es berechnet:
1
temperature=(temperaturesht*0.01)-39.7;
2
humidityl=(0.0367*humiditysht)+(-0.0000015955*humiditysht*humiditysht)-2.0468;
3
humidity=(temperature-25.0)*(0.01+(0.00008*humiditysht))+humidityl;

Nun die Frage, wie kann man in LUA rechnen?
Wie füge ich das in mein Programm ein? Endergebnis sollte 1 Kommastelle 
haben.

Bitte nochmals um Hilfe, vielen Dank! :)

Schöne Grüße,
PascalS

: Bearbeitet durch User
von Dirk K. (dekoepi)


Lesenswert?

Du trägst es genau so in dein Programm ein, passe aber die 
Variablennamen an. Das sollte direkt so klappen in LUA. Ich sehe da grad 
nur die simplen Grundrechenarten.

von Pascal S. (pascalsch)


Lesenswert?

Hallo Dirk,

Ok, danke, werde es versuchen...


Schöne Grüße,
PascalS

von Dirk K. (dekoepi)


Lesenswert?

Und, hats geklappt?

von Pascal S. (pascalsch)


Lesenswert?

Hallo Dirk,

Ja, funktioniert, voll cool... :)

Nochmals vielen Dank!!


Schöne Grüße,
PascalS

: Bearbeitet durch User
von Pascal S. (pascalsch)


Lesenswert?

Hallo,

Habe jetzt aber noch ein Problem...
Und zwar, wenn ich den ESP8266 einschalte, dann startet er irgendwie das 
Programm nicht?

Der ESP bootet so alle 16 Sekunden (mein Intervall?) neu.
Da kommen dann immer so Hieroglyphen, darauf der Starttext mit 
...powered by Lua...

Erst wenn ich "dofile(init.lua)" eingebe, gehts...
Habe den ESP auch schon neu geflasht, ohne Erfolg.

Manchmal kommt auch "no enough memory", obwohl nur dieses Programm drauf 
ist und der größte Teil leer ist?


An was kann das liegen?

Bitte um Hilfe, danke!

Schöne Grüße,
PascalS

von Dirk K. (dekoepi)


Lesenswert?

- Welches ESP-Modul genau setzt du ein?
- Welche NodeMCU-Firmware?
- Falls mit Buildbot erstellt: Einfach zuviele Module einkompiliert? Wie 
groß ist die Firmware-Datei?
- Wie sieht die Stromversorgung aus? Welche Kondensatoren hast du an 
Vcc/GND deines ESP-Moduls gelötet?

: Bearbeitet durch User
von Pascal S. (pascalsch)


Angehängte Dateien:

Lesenswert?

Hallo Dirk,

Ich verwende den NodeMCU V3 
(https://www.amazon.de/NodeMCU-Wifi-Entwicklungsboard-CP2102-inkl-Geh%C3%A4use/dp/B01GUXS9D0/ref=sr_1_6?ie=UTF8&qid=1472633321&sr=8-6&keywords=nodemcu) 
mit dem ESP8266 12-E Serie.

Ursprünglich war das NodeMCU 0.9.5 build 20150127 drauf.
Beim Flashen habe ich dann eine aktuellerer Firmware (NodeMCU 0.9.6 
build 20150704 (float)), dessen 452 KB hat, raufgespielt.
Bei beiden Firmewares das gleiche...

Die Lua-Version ist 5.1.4.

Die Stromversorgung geht derzeit über den im NodeMCU integrierten 
Micro-USB.

Oben im Anhang ist zu sehen, was genau passiert, zuerst startet er mit 
dem Starttest, nach ca. 16 Sekunden kommen so Hieroglyphen, danach 
wieder der Starttext und so weiter...
Will ich nun mit "dofile(init.lua)" starten, passiert das selbe...
Erst wenn ich die Daten per "Reload" im ESPlorer abfrage und daraufhin 
mit "dofile(init.lua)" starte, gehts...

Schöne Grüße,
PascalS

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

@Pascal

Dann wird Mist in der init.lua sein, der das Teil zum Absturz bringt. 
Nenn den file mal um, damit er nicht automatisch gestartet wird, z.B. 
test.lua.

Dann sollte der ESP anlaufen und melden, daß er kein init.lua findet. 
Und dann test.lua mit dofile("test.lua") starten (die Anführungszeichen 
gehören in die Klammer, das ist ein String).

Jetzt kannst du in Ruhe die Fehlermeldungen auswerten und die Bugs raus 
machen. Erst ganz zum Schluß wieder in init.lua umbenennen.

Das hab ich gefühlte tausend mal mit einem dutzen Firmwaren, gebaut mit

https://nodemcu-build.com/

gemacht.

MfG Klaus

PS
Pascal S. schrieb:
> nach ca. 16 Sekunden kommen so Hieroglyphen,
Das sind Meldungen des Bootloaders mit seiner eigenen Baudrate, hab ich 
mit meinem saleae aufgezeichnet und dekodiert.

von Pascal S. (pascalsch)


Angehängte Dateien:

Lesenswert?

Hallo Klaus,

Danke für deine Antwort!

Habe ich in "test.lua" umgenannt.
Es kommt beim starten, wie erwartet, "lua: cannot open init.lua
", jedoch, wie im Anhang test oben zu sehen ist, leider keine 
Fehlermeldung, wieder die Hieroglyphen :P und reboot...
Sobald ich auf "Reload" im ESPlorer klicke und dann dofile, gehts 
komischerweise?

Außerdem, wie es auf dem Bild zu sehen ist, sagt er bei jedem 
Einschalten "Can't autodetect firmware, because proper answer not 
received (may be unknown firmware).", wobei ich reseten muss, liegt hier 
was?
Diese Meldung kommt jedoch bei beiden probierten Firmewares...

Außerdem, wie im Anhang esplorer2 zu sehen ist, habe ich den ESP mal mit 
file.format komplett gelöscht (es wird ja 0 bytes bei verwendet 
angezeigt), jedoch arbeitet er immer noch weiter, hier passt doch auch 
was nicht, oder?


Danke für eure Hilfe!

Schöne Grüße,
PascalS

: Bearbeitet durch User
von Dirk K. (dekoepi)


Lesenswert?

Was war anders, als es lief?

Du hast etwas geändert, und das macht es jetzt kaputt. Was hast du denn 
geändert, dass es dann nicht klappte?

Falscher Funktionsname im Timer-Aufruf vielleicht?

Stell' die Baudrate mal um. Dann siehst du mehr Hieroglyphen, aber bei 
der richtigen EInstellung die Fehlermeldung, die jetzt kryptisch 
aussieht. 78400 zB, oder mal 9600 probieren.

: Bearbeitet durch User
von Pascal S. (pascalsch)


Angehängte Dateien:

Lesenswert?

Hallo Dirk,

Habe es jetzt mal mit "Reload" und "dofile" gestartet.

Nach einiger Zeit kam jedoch "PANIC: unprotected error in call to Lua 
API (not enough memory)" und er bootete wieder, liegt hier was?

Mein Programm sieht derzeit so aus, vielleicht sieht jemand den Fehler 
;):

init.lua
1
wifi.setmode(wifi.STATION)
2
wifi.sta.config("WIFI_SSID","WIFI_PASSWORD")
3
4
local DAT = 4
5
local CLK = 3
6
7
function DL()
8
  gpio.write(DAT, gpio.LOW)
9
  gpio.mode(DAT, gpio.OUTPUT)
10
end
11
12
function DH()
13
  gpio.mode(DAT, gpio.INPUT)
14
  gpio.write(DAT, gpio.HIGH)
15
end
16
17
function CL()
18
  gpio.write(CLK, gpio.LOW)
19
end
20
21
function CH()
22
  gpio.write(CLK, gpio.HIGH)
23
end
24
25
function DR()
26
  gpio.mode(DAT, gpio.INPUT)
27
  return gpio.read(DAT)
28
end
29
30
function W8()
31
  for i = 1, 100 do
32
    tmr.delay(10000)
33
    if DR() == gpio.LOW then
34
      return true
35
    end
36
  end
37
  return false
38
end
39
40
function RB()
41
  local val = 0
42
  for i = 0, 7 do
43
    CH()
44
    val = val*2 + DR()
45
    CL()
46
  end
47
  return val
48
end
49
50
function shtread(cmd)
51
  DH() CH() DL() CL() CH() DH() CL()
52
  for i = 0, 7 do
53
    if bit.band(cmd, 2^(7-i))==0 then
54
      DL()
55
    else
56
      DH()
57
    end
58
    CH() CL()
59
  end
60
  CH() CL()
61
  if not W8() then
62
    return nil
63
  end
64
  DH()
65
  local val = RB()
66
  DH() DL() CH() CL() DH()
67
  val = val*256 + RB()
68
  DH() CH() CL()
69
  return val
70
end
71
72
function mround(number, decimals, method)
73
    decimals = decimals or 0
74
    local factor = 10 ^ decimals
75
    if (method == "ceil" or method == "floor") then return math[method](number * factor) / factor
76
    else return tonumber(("%."..decimals.."f"):format(number)) end
77
end
78
79
80
--- Get temp and send data to homepage.com
81
function sendData()
82
temperaturesht = shtread(3)
83
humiditysht = shtread(5)
84
temperature = mround((temperaturesht*0.01)-39.7, 1)
85
humidityl = ((0.0367*humiditysht)+(-0.0000015955*humiditysht*humiditysht)-2.0468)
86
humidity = mround((temperature-25.0)*(0.01+(0.00008*humiditysht))+humidityl, 1)
87
print ("Temperature: "..temperature)
88
print ("Humidity: "..humidity)
89
-- conection to homepage.com
90
print("Sending data to homepage.com")
91
conn=net.createConnection(net.TCP, 0) 
92
conn:on("receive", function(conn, payload) print(payload) end)
93
-- homepage.com 81.11.160.21
94
conn:connect(80,'81.11.160.21') 
95
conn:send("GET /update.php?soiltempc="..temperature.."&soilhumidity="..humidity.." HTTP/1.1\r\n") 
96
conn:send("Host: homepage.com\r\n") 
97
conn:send("Accept: */*\r\n") 
98
conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n")
99
conn:send("\r\n")
100
conn:on("sent",function(conn)
101
                      print("Closing connection")
102
                      conn:close()
103
                  end)
104
conn:on("disconnection", function(conn)
105
                      print("Got disconnection...")
106
  end)
107
end
108
-- send data every X ms to homepage.com
109
tmr.alarm(2, 16000, 1, function() sendData() end )


Danke nochmals!

Schöne Grüße,
PascalS

: Bearbeitet durch User
von Dirk K. (dekoepi)


Lesenswert?

Ah. Du machst keinen DeepSleep mit Aufwachen, sondern normal im Timer.

LUA ist etwas ungnädig, was Variablen angeht.
Die musst du am Ende des Durchlaufes aufräuen. Jede genutzte Variable 
=NIL setzen und am Ende CollectGarbage aufrufen.

Bei DeepSleep starten der ESP komplett neu, da kommt man nicht in 
Speicherprobleme.

von Klaus (Gast)


Lesenswert?

Pascal S. schrieb:
> Es kommt beim starten, wie erwartet, "lua: cannot open init.lua
> ", jedoch, wie im Anhang test oben zu sehen ist, leider keine
> Fehlermeldung, wieder die Hieroglyphen :P und reboot...
> Sobald ich auf "Reload" im ESPlorer klicke und dann dofile, gehts
> komischerweise?

Natürlich kommt keine Meldung, es läuft ja kein Programm. Ich hab keine 
Ahnung, was "Reload" macht, benutze den ESPlorer nicht. Ich hab einfach 
ein serielles Terminal, minicom z.B.

Wenn man den Prompt hat, einfach dofile("test.lua") eintippen.

Du hast ja eine Console, solange du deinen Timer nicht startest, kannst 
du ganz in Ruhe alle Funktionen testen. Die sind nach dem dofile() alle 
da, einfach aufrufen. Ein paar prints helfen da. Du kannst dir auch jede 
Variable ansehen. In der Console kann man auch kurz =xxx statt 
print(xxx) benutzen, tippt sich schneller. Man kann sich auch den Heap 
ansehen, da kann man dann ahnen, wo dir der Speicher ausgeht. Ist ein 
bisschen debuggen wie zu BASIC Zeiten.

MfG Klaus

von Pascal S. (pascalsch)


Lesenswert?

Hallo Dirk, hallo Klaus,

Erstmal nochmals vielen Dank für eure Hilfe! ;)

Habe glaube den Fehler gefunden, ich rufe die Funktion "mround" für 2 
Werte auf, nun habe ich ein weiteres "mround2" erstellt und es 
funktioniert...

@Dirk: Müssen die Werte wirklich bei jedem Durchgang auf =nil gesetzt 
werden? Läuft mir jetzt der Speicher voll?

Kennt einer zufällig eine gute Infomationsseite für LUA? Würde gerne ein 
bisschen herumspielen... Am besten wäre in Deutsch :P

Schöne Grüße,
PascalS

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

Pascal S. schrieb:
> Müssen die Werte wirklich bei jedem Durchgang auf =nil gesetzt
> werden?

Nein, müssen sie nicht, wenn du immer wieder die gleichen Variablen 
benutzt.

und hier

https://www.lua.org/pil/

MfG Klaus

von Pascal S. (pascalsch)


Lesenswert?

Hallo Klaus,

Ok, in dem Fall müsste es ja jetzt funzen, lasse gerade ein Dauertest 
laufen, mal schauen...

Danke für den Link, muss gleich her ;)


Schöne Grüße,
PascalS

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Die deutsche Version ist hoffentlich kein alter Aprilscherz:
> Programmieren in Lua Taschenbuch – 1. April 2013
https://www.amazon.de/Programmieren-Lua-Roberto-Ierusalimschy/dp/3955390209

Sie kostet nur rund die Hälfte. Kann man die kaufen?

Oder bringt die Version
   "fourth edition (Englisch) Taschenbuch – 1. August 2016"
deutliche Vorteile?

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

Hab ich grad erst gesehen

Pascal S. schrieb:
> Außerdem, wie im Anhang esplorer2 zu sehen ist, habe ich den ESP mal mit
> file.format komplett gelöscht (es wird ja 0 bytes bei verwendet
> angezeigt), jedoch arbeitet er immer noch weiter, hier passt doch auch
> was nicht, oder?

Das Programm ist im Speicher, es läuft also weiter, auch wenn es im 
Filesystem gelöscht ist.

@Torsten

Ich lese Fachbücher lieber im Original, daher kann ich zur deutschen 
Version nichts sagen. Ich hab die erste Version im Original, sollte für 
alles, was man auf dem ESP so machen kann, reichen.

MfG Klaus

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.