Help with ATtiny85 current monitor with esp8266

I’ve been playing around with this for a while and I can’t seem to understand why it won’t work on an ATtiny85. My goal is to build a 2 phase current meter using an ATtiny85, an esp8266 and a pair of SCT-013-000 current transformers where you connect to the esp on port 80 and when it receives any input (such as GET /) it will respond with the current readings. I’m using IDE 1.6.1, HLT/damellis core, the built in softwareserial lib in IDE 1.6.1 and Emonlib. ATtiny85 is running with 8mhz internal clock and i have done “burn bootloader” to set the fuses. The whole thing is powered by a 3.3v 500ma regulator (LM2937ET-3.3) with the proper filtering caps as per the datasheet for the regulator. The esp8266 firmware defaults to 9600 baud. I based my code off of this for the esp.

With the below code written to the tiny, it doesn’t even perform the setup routine as the esp will not be listening on port 80 for incoming connections. If I comment out lines in the setup where it sets up emon pins (emon1.current and emon2.current) then it will setup the esp correctly and be listening on port 80 for incoming connections. This confirms to me that I am using the correct pins in the tiny for the serial communication.

If I write the same code to an Uno (modifying the software serial pins) and run the Uno at 3.3v feeding power in the 3.3v pin from the LM2937ET-3.3 it works as expected.

Any suggestions as to why its not working on the tiny?

#include <SoftwareSerial.h>
#include "EmonLib.h"  // Include Emon Library
EnergyMonitor emon1;
EnergyMonitor emon2;

SoftwareSerial esp8266(1,2); //for tiny
//SoftwareSerial esp8266(2,3); //for Uno



void setup()
{
  esp8266.begin(9600); 
  sendData("AT+RST\r\n",2000); 
  sendData("AT+CIPMUX=1\r\n",1000); 
  sendData("AT+CIPSERVER=1,80\r\n",1000);  
  emon1.current(A2, 111.1);
  emon2.current(A3, 111.1);

}
 
void loop()
{
  if(esp8266.available()) // check if the esp is sending a message 
  {
    if(esp8266.find("+IPD,"))
    {
     delay(1000);
     int connectionId = esp8266.read()-48; // subtract 48 because the read() function returns 
                                           // the ASCII decimal value and 0 (the first decimal number) starts at 48
     int Irms1 = emon1.calcIrms(1480);
     int Irms2 = emon2.calcIrms(1480);
     String webpage = "Phase1= ";
     webpage += Irms1;
     webpage += "A
";
     webpage += "Phase2= ";
     webpage += Irms2;
     webpage += "A";

     String cipSend = "AT+CIPSEND=";
     cipSend += connectionId;
     cipSend += ",";
     cipSend +=webpage.length();
     cipSend +="\r\n";
     
     sendData(cipSend,1000);
     sendData(webpage,1000);
     
     String closeCommand = "AT+CIPCLOSE="; 
     closeCommand+=connectionId; // append connection id
     closeCommand+="\r\n";
     
     sendData(closeCommand,3000);
    }
  }
}
 
 
String sendData(String command, const int timeout)
{
    String response = "";
    esp8266.print(command); // send the read character to the esp8266
    long int time = millis();
    while( (time+timeout) > millis())
    {
      while(esp8266.available())
      {
        // The esp has data so display its output to the serial window 
        char c = esp8266.read(); // read the next character.
        response+=c;
      }   
    }
    return response;
}

I'm really wondering if it has something to do with using both analogue and digital PINs on the tiny? Anyone have any experience with that?

Well I've made a bit of progress. It seems that its the "SendData" routine that is causing me problems, though I don't understand why? If i change the setup to this:

void setup()
{
  emon1.current(A2, 111.1);
  emon2.current(A3, 111.1);
  delay(5000);
  esp8266.begin(9600); 
  esp8266.print("AT+RST\r\n");
  delay(1000);
  esp8266.print("AT+CIPMUX=1\r\n");
  delay(1000);
  esp8266.print("AT+CIPSERVER=1,80\r\n");
  delay(1000);
  /*
  sendData("AT+RST\r\n",2000); 
  sendData("AT+CIPMUX=1\r\n",1000); 
  sendData("AT+CIPSERVER=1,80\r\n",1000);  
  */
}

Then it will actually send the 3 commands to the esp for the setup. I just don't understand why it works fine on an Uno but doesn't on a ATtiny85.

How much delay() is needed to make it work?

is the key the delay() at the start, or a delay() between the commands?

If it needs a short delay between the commands, you could be running into the limits of software seria, and were getting away with it before just because it was running faster; you could try running the 85 at 16mhz (pll clock - don't need a crystal with the 85)

I don't think the 5 second delay is needed. I had to put the delay in between the commands otherwise it wouldn't "wait" for the response from the esp first. When I was using the SendData routine it would wait for the response (or the timeout value) before proceeding.

Keep in mind that if i comment out the two lines that setup the emon:
emon1.current(A2, 111.1);
emon2.current(A3, 111.1);

Then it works as expected. If it was timing issue I would expect it to not work even with those lines commented out.

Wait - in OP you had the emon.current() lines at the bottom, and said it didn't work. And now you have them at the top. And either way, it doesn't work?

That seems to throw the idea that it's related to using the ADC out the window, because then you'd expect it not to break anything until you called the functions... that implies that just compiling in those calls is enough to break it, which points to a subtle library conflict, or running out of SRAM or something like that.

Ya, I've trying putting emon.current() before and after and it doesn't make a difference. I've also tried disabling the emon lib completely and just putting some analogRead() in the setup instead and that doesn't break things.... so i think i can throw out the ADC theory.

Now I'm wondering if I should switch form HLT core to arduino-tiny instead and give that a shot? HLT seemed nice because the software serial seemed to work right out of the box with IDE 1.6.1. I did a quick test with switching to arduino-tiny and it looks like I'll need to mess around to get swserial working.

The idea of it running out of RAM sounds like a good theory too. Any idea how I can dig deeper into that?

Sketch uses 5,498 bytes (67%) of program storage space. Maximum is 8,192 bytes.
Global variables use 412 bytes of dynamic memory.

Only leaving 100 bytes of dynamic memory left..... this could very well could be a SRAM issue.

You can use the F() macro to move all those string literals you're sending to the ESP into flash. That should get you a some more sram - probably enough.

ahh didn't know about F()..... and SRAM seems to be my issue because once I moved all of the setup commands to flash it seems to work a bit more, but it looks like I need to optimize this a bunch more still... :frowning: