-->
Page 1 of 1

Loops and memory, OH MY!

PostPosted: Wed Dec 28, 2016 7:32 am
by culinandy
Really hitting my head against a wall here. Trying to set up a nodemcu to send a temp to my phant server every 60 seconds.

I can successfully get it to boot up, get on wifi, and run my script to send the temp on the first try. That works, phant receives the temp, all is well.

HOWEVER, if I throw all of that code into any type of a loop or try and put any delay in there, either a) the connection won't get created and the data won't send, and/or b) I end up running out of memory.

Help?

init.lua
Code: Select allfunction startup()
    print('in startup')
    dofile('sendtemp.lua')
end

wifi.setmode(wifi.STATION)
wifi.sta.config("mywifi","mypassword")
wifi.sta.connect()
tmr.delay(1000000)   -- wait 1,000,000 us = 1 second
tmr.alarm(1,1000, 1, function() if wifi.sta.getip()==nil then print("Waiting for IP address!") else print(wifi.sta.status()) print(wifi.sta.getip()) tmr.alarm(0,5000,0,startup) tmr.stop(1) end end)


sentemp.lua
Code: Select allrequire("phant")

hostName = "192.168.0.108"
port = 8087
publicKey = "key"
privateKey = "key"

phant.init(hostName .. ":" .. port, publicKey, privateKey)

print("Reading Temp")

voltage = adc.read(0)
mV = voltage * (3300/1024)
tempC = (mV - 500) / 10
tempF = (tempC * 9 / 5) + 32

phant.add("temp", tempF)

conn = net.createConnection(net.TCP, 0)

conn:on("connection", function(conn, payload)
    print("Connected")
    conn:send(phant.post())
end)

conn:on("sent", function()
    print("Sent")
end)

conn:connect(port, hostName)



On the first run, I will get this result:
Code: Select allReading Temp
> Connected
Sent


If I change my init.lua to this, though:
Code: Select allfunction startup()
    print('in startup')
    while ( true)
    do
        dofile('sendtemp.lua')
        tmr.delay(1000000)
    end
end

wifi.setmode(wifi.STATION)
wifi.sta.config("mywifi","mypassword")
wifi.sta.connect()
tmr.delay(1000000)   -- wait 1,000,000 us = 1 second
tmr.alarm(1,1000, 1, function() if wifi.sta.getip()==nil then print("Waiting for IP address!") else print(wifi.sta.status()) print(wifi.sta.getip()) tmr.alarm(0,5000,0,startup) tmr.stop(1) end end)


I just get this result:
Code: Select allReading Temp
Reading Temp
Reading Temp
Reading Temp
Reading Temp
Reading Temp
PANIC: unprotected error in call to Lua API (not enough memory)
PANIC: unprotected error in call to Lua API (attempt to call a string value)

and my temps are never sent to phant. Similarly if I try and put the temp read/send code in my sendtemp.lua in any kind of a loop, I get the same issue.

Any help is appreciated.

Thanks,
Andy

Re: Loops and memory, OH MY!

PostPosted: Wed Dec 28, 2016 3:25 pm
by culinandy
THANK YOU, SPARKFUN!

For those interested, I switched from LUA to straight up arduino, and found a nice chunk of example code: https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/example-sketch-posting-to-phant. Here's what I wound up with:

Code: Select all// Include the ESP8266 WiFi library. (Works a lot like the
// Arduino WiFi library.)
#include <ESP8266WiFi.h>
// Include the SparkFun Phant library.
#include <Phant.h>

//////////////////////
// WiFi Definitions //
//////////////////////
const char WiFiSSID[] = "wifisid";
const char WiFiPSK[] = "wifipass";

/////////////////////
// Pin Definitions //
/////////////////////
const int LED_PIN = 5; // Thing's onboard, green LED
const int ANALOG_PIN = 0; // The only analog pin on the Thing
const int DIGITAL_PIN = 12; // Digital pin to be read

////////////////
// Phant Keys //
////////////////
const char PhantHost[] = "192.168.0.108";
const int PhantPort = 8087;
const char PhantHostPort[] = "192.168.0.108:8087";
const char PublicKey[] = "pubkey";
const char PrivateKey[] = "privkey";

/////////////////
// Post Timing //
/////////////////
const unsigned long postRate = 3000;
unsigned long lastPost = 0;

void setup()
{
  initHardware();
  connectWiFi();
  digitalWrite(LED_PIN, HIGH);
}

void loop()
{
  if (lastPost + postRate <= millis())
  {
    if (postToPhant())
      lastPost = millis();
    else
      delay(100);   
  }
}

void connectWiFi()
{
  byte ledStatus = LOW;

  // Set WiFi mode to station (as opposed to AP or AP_STA)
  WiFi.mode(WIFI_STA);

  // WiFI.begin([ssid], [passkey]) initiates a WiFI connection
  // to the stated [ssid], using the [passkey] as a WPA, WPA2,
  // or WEP passphrase.
  WiFi.begin(WiFiSSID, WiFiPSK);

  // Use the WiFi.status() function to check if the ESP8266
  // is connected to a WiFi network.
  while (WiFi.status() != WL_CONNECTED)
  {
    // Blink the LED
    digitalWrite(LED_PIN, ledStatus); // Write LED high/low
    ledStatus = (ledStatus == HIGH) ? LOW : HIGH;

    // Delays allow the ESP8266 to perform critical tasks
    // defined outside of the sketch. These tasks include
    // setting up, and maintaining, a WiFi connection.
    delay(100);
    // Potentially infinite loops are generally dangerous.
    // Add delays -- allowing the processor to perform other
    // tasks -- wherever possible.
  }
}

void initHardware()
{
  Serial.begin(9600);
  pinMode(DIGITAL_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  // Don't need to set ANALOG_PIN as input,
  // that's all it can be.
}

int postToPhant()
{
  // LED turns on when we enter, it'll go off when we
  // successfully post.
  digitalWrite(LED_PIN, HIGH);

  // Declare an object from the Phant library - phant
  Phant phant(PhantHostPort, PublicKey, PrivateKey);

  // Add the four field/value pairs defined by our stream:

   int reading = analogRead(ANALOG_PIN); 
 
 // converting that reading to voltage, for 3.3v arduino use 3.3
 float voltage = reading * 3.3;
 voltage /= 1024.0;
 
 // print out the voltage
 // now print out the temperature
 float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
                                               //to degrees ((voltage - 500mV) times 100)

 // now convert to Fahrenheit
 float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
 Serial.print(temperatureF); Serial.println(" degrees F");
  phant.add("temp", temperatureF );

  // Now connect to data.sparkfun.com, and post our data:
  WiFiClient client;
  if (!client.connect(PhantHost, PhantPort))
  {
    // If we fail to connect, return 0.
    return 0;
  }
  // If we successfully connected, print our Phant post:
  client.print(phant.post());

  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
    //Serial.print(line); // Trying to avoid using serial
  }

  // Before we exit, turn the LED off.
  digitalWrite(LED_PIN, LOW);

  return 1; // Return success
}