You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino Mega发送URL至服务器不完整问题排查求助

Fixing Partial URL Sends & Crashes with Arduino Mega + Ethernet Shield

Hey there! Let's tackle your frustrating issue with partial URL transmissions and random multi-minute device crashes. Since your serial monitor shows the full URL, we know the string generation works fine—so the problem lies in how you're communicating with your Apache server, plus some connection and memory management gaps in your code. Here's how to fix it:

1. Send a Complete HTTP Request (Critical!)

Right now you're only sending the raw URL string, but Apache expects a fully formatted HTTP GET request. Missing headers can cause the server to misinterpret or discard partial data, leading to the truncated logs you're seeing. Update your send logic to include standard HTTP headers:

// Replace your client.println(url) block with this:
client.print("GET ");
client.print(url);
client.println(" HTTP/1.1");
client.println("Host: 192.168.x.x"); // Replace with your server's IP/domain
client.println("Connection: close");
client.println(); // Empty line signals end of request headers

This tells Apache exactly what to expect, so it won't chop off parts of your request.

2. Fix Connection Management to Avoid Blocking

Your current conn() function has two big issues that cause crashes:

  • It re-initializes the Ethernet module (Ethernet.begin()) in an infinite loop if it fails, which blocks your code entirely for minutes.
  • It doesn't properly check existing connections before retrying.

Here's an optimized version that prevents blocking and manages connections smarter:

bool conn() {
  Serial.println("Checking connection status...");
  
  // Skip reconnection if already connected
  if (client.connected()) {
    return true;
  }

  // Only re-initialize Ethernet if it's not already set up
  if (Ethernet.localIP() == IPAddress(0,0,0,0)) {
    Serial.println("Initializing Ethernet module...");
    int attempts = 0;
    // Limit retries to avoid infinite blocking
    while (Ethernet.begin(mac) == 0 && attempts < 5) {
      Serial.print("Ethernet init retry #");
      Serial.println(attempts + 1);
      attempts++;
      delay(1000); // Wait 1 second between retries
    }
    // If Ethernet still fails, return false
    if (Ethernet.localIP() == IPAddress(0,0,0,0)) {
      Serial.println("Ethernet initialization failed!");
      return false;
    }
  }

  // Try connecting to the server
  Serial.println("Connecting to Apache server...");
  if (client.connect(server_ip, 80)) {
    Serial.println("Server connection successful!");
    return true;
  } else {
    Serial.println("Failed to connect to server");
    client.stop(); // Clean up failed connection attempts
    return false;
  }
}

Then update your sendDatatoServer() function to use this improved connection check:

int sendDatatoServer(uint8_t deviceID) {
  // Keep your URL string logic (we'll optimize memory next)
  String url = "GET /Supervisorio_Energia_FPBR/insert_dados.php?";
  url += "ID=";
  url += String(deviceID);
  url += "&amp;F=";
  url += String(vetor_resultado[6]);
  url += "&amp;V1=";
  url += String(vetor_resultado[7]);

  // Only proceed if connection is successful
  if (!conn()) {
    Serial.println("No active connection to server!");
    return -1; // Return error code for debugging
  }

  // Send the full formatted HTTP request
  client.print("GET ");
  client.print(url);
  client.println(" HTTP/1.1");
  client.println("Host: 192.168.x.x"); // Match your server's IP
  client.println("Connection: close");
  client.println();

  // Read server response to clear the buffer (prevents leftover data issues)
  unsigned long timeout = millis();
  while (client.connected() && millis() - timeout < 5000) {
    if (client.available()) {
      char c = client.read();
      // Uncomment below to debug server responses
      // Serial.print(c);
    }
  }

  // Clean up the connection properly
  client.stop();
  Serial.println("Data sent successfully!");
  Serial.println(url);
  return 0;
}

3. Reduce Memory Fragmentation (Prevent Long-Term Crashes)

Using String concatenation repeatedly can cause memory fragmentation on Arduino Mega over time, which leads to random crashes. Swap String for a static char array with snprintf() to avoid dynamic memory issues:

// Replace your String url logic with this:
char url[256]; // Adjust size if you add more parameters later
snprintf(url, sizeof(url), 
         "/Supervisorio_Energia_FPBR/insert_dados.php?ID=%u&amp;F=%f&amp;V1=%f",
         deviceID, vetor_resultado[6], vetor_resultado[7]);

This allocates a fixed-size buffer and formats your URL directly into it, eliminating memory fragmentation risks.

4. Add Small Delays (Optional but Helpful)

If you're still seeing occasional truncation, add a short delay after client.println() to ensure all data is sent before closing the connection:

client.println(); // End of request headers
delay(100); // Give Ethernet shield time to send all data

These changes should eliminate the partial URL sends by giving Apache a properly formatted request, and the connection/memory fixes will stop those multi-minute crashes. Test it out and let me know how it goes!

内容的提问来源于stack exchange,提问作者Matheus Antonio da Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 17:27:50