Arduino hangs using ethernet and I2C in one project

Hi.
I am using my Arduino for remote measurements via ethernet. I send an HTTP request to the Arduino and get a response with the specified measurement value. This works for standard measurements that the Arduino can do by itself, like Voltage. I am however experiencing a weird problem when using the Adafruit INA219 I2C chip to measure current.

When a request for current measurement is made, the Arduino communicates with the INA219 as it should and responds via http, but it hangs in the first new cycle of the main loop after the completed response. The system no longer listens for http requests and requires a physical restart before it stars functioning again.

I am running an Arduino Meag2560 R3 with the Arduino Ethernet shield 2. Communicating with the Adafruit INA219 by I2C.
for specs on the INA219 see INA219 High Side DC Current Sensor Breakout - 26V ±3.2A Max [STEMMA QT] : ID 904 : $9.95 : Adafruit Industries, Unique & fun DIY electronics and kits

#include <Adafruit_INA219.h> 
#include <CommandList.h>
#include <Ethernet.h>


int count=0;
byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0xA9, 0xB9 };
EthernetServer server(80);
boolean httpActive=false;

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(100);

  digitalWrite(4, HIGH); //deselect SD card mode
  Ethernet.init(10);    //init ethernet
  Ethernet.begin(mac);  //Initiate connection using DHCP
  server.begin( );
  Serial.println(Ethernet.localIP());
 
}
void loop() {
  count++;
  if(count==2000){
    Serial.println("Still running"); //For debugging
    count=0;
  }
  int res;
  readCommand();
  if(httpActive){
    Serial.println("currentMeasurement");
    res=intCurrent();
    Serial.println(res);
    sendResponse(res);
  }
  Serial.println(F("Returned to loop"));
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Measure current. Private function.
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int currentMeasure(Adafruit_INA219 *ina219){
  return (ina219)->getCurrent_mA();
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Function for current measurement. 
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int intCurrent(){
  int moduleAdr=0x40; //I2C address current sensor
  Adafruit_INA219 ina219(moduleAdr);

  if(!ina219.begin()){  //if not connected, send error
    Serial.println(F("Failed to find INA219 chip"));
    return 0;
  }

  int reading=currentMeasure(&ina219); //Single reading
  
  //Terminate connection, reset settings.
  ina219.~Adafruit_INA219();
  if(ina219.success())Serial.println("destructed INA219");
  return reading;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Send a response via http
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void sendResponse(int value){
  Serial.println(F("Send response function"));
  EthernetClient client = server.available();
  if (client) {
    Serial.println(F("client found"));
    while (client.connected()){
      Serial.println(F("client connected"));
      if (client.available()){
        Serial.println(F("client available"));
        client.println ("HTTP/1.1 200 OK");
        client.println ("Content-Type: text/html");
        client.println ("Connection: close");
        client.println ( );
        client.println ("Brewing Coffe :)");
        client.print(value);
        client.flush();
        Serial.println(F("actually sent"));
        break;                  
      }
    }
  delay(1);
  client.stop();
  Serial.println(F("client stopped"));
  }
  Serial.println(F("Function end"));
  httpActive=false;
  return;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Read http command from ethernet shield
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void readCommand(){
  Serial.println(F("Read command func"));
  String commandStr="";
  EthernetClient client = server.available();
  if(client){
    if(client.available()){
      boolean currentLineIsBlank = true;
      char character = client.read ( );
      while(!(character == '\n' && currentLineIsBlank)){
        Serial.write(character);
        commandStr+=character;
        character = client.read ( );
        
        if ( character == '\n') {
          currentLineIsBlank = true;
        }else if (character != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
  }
  Serial.println(F("client finished"));
  if(commandStr.indexOf("favicon")!=-1){
    Serial.println(F("Favicon stopped"));
    client.stop();
    return;
  }else if(commandStr!=""){
    Serial.println(F("Non empty command"));
    httpActive=true;
    return;
  }
  Serial.println(F("empty command"));//<------------- crashes here
  return;
}

As mentioned this issue only happens after a call to the INA219 chip, so I believe the problem is connected to I2C communication. Is there possibly a memory overlap in the Adafruit library and the Ethernet library?
When running the freeRam() function ( Solved: Use of freeRAM() ) in my main code during debugging I have found that there are approximately 6000 bytes still available, so I don't believe that I am running out of memory.
I am grateful for any help and insight you are able to give.

PS: This is my first post on the forum. If I have made any mistakes when posting, i.e. incorrect use of code tags or links, please let me know so I can fix my mistakes.

you have no guarantee that the second call to server.available returns the same client. it could return the next favicon request

I am aware of the Favicon request. My program handles(ignores) the favicon request and this works fine as long as I am not calling the INA chip, so I don't see how the favicon request stops the entire loop from running.
If this is the case however, could you please explain how the favicon request stops the main loop from running so I can understand what is wrong?

you get the client again in sendResponse. that is wrong.
server.available() will only return a client which has data to read

Thank you for clarifying. I have attempted to use the same client as well, with the exact same result.
I do get the response to my browser however, so the sendResponse() does find its client and sends a result with the correct measurement. The issue arrives at the next iteration of the main loop.

I have attached a picture of my debug printouts. As you can see it crashes after completing the next readCommand() .

you have client.read() without checking if anything is available

Thank you for pointing that out to me. I have fixed it in the code, but the issue persists unfortunately.
if(client.available()>0)character = client.read ( );

so you now abort reading the request?

Yes.
I moved the client.available() call to the while loop, so that it will abort the reading request if no data is available. See code below. The same problem persists, as it freezes after the completion of reading function. In my browser I receive an ECONNREFUSED error, I don't know if that will help make the problem clearer.

      while(!(character == '\n' && currentLineIsBlank) && client.available()>0){
        Serial.write(character);
        commandStr+=character;
        character = client.read ( );
        
        if ( character == '\n') {
          currentLineIsBlank = true;
        }else if (character != '\r') {
          currentLineIsBlank = false;
        }
      }

there can be a gap between bytes from the client

Yes, there might be a gap, however that wouldn’t explain why the Arduino only crashes after using the Adafruit_ina219 library. As I mentioned in my original post, the readCommand() and sendResponse() function work perfectly fine when measureCurrent() is replaced with a voltage measurement.

timing

in the function intCurrent() look at the lines:

Is'nt it that you call the destructor and after that you use a function of this object just killed?

The call to ina219.success was added as a means of debugging. The problem was there before it was added unfortunately.

I solved the issue for my system.
Didn't actually solve the problem, as I suspect that there may be some sort of memory collision between the ina219 library and ethernet use.
However I was able to make the system run again by reading and writing the directly to ina219 chips registers using the Wire.h library.
Thanks for all replies and help I recieved.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.