Below is a sample sketch that demonstrates the issue I'm having with a simple arduino web server using the SdFat library. If I use the Arduino IDE (1.8.5) both the standard and SdFat library work as expected. However, if I use Visual Micro the SdFat version fails while the standard SD version works.
The hardware is a teensy 3.2, micro SD card adaptor, and WIZ850io. We discovered the issue when upgrading from a WIZ820io -- with that hardware everything works, but with the new hardware it does not. Just to be clear with either hardware or library code created with the Arduino IDE works.
I've tried adjusting the compiler optimization level but that has had no effect. I'm at a loss as to what else to try to get this sorted out.
#define SD_PIN 4
#define RESPONSE_BUF_SIZE 512
#define LINE_MAX 128
#include <SPI.h>
#include <Ethernet.h>
// Modify this for testing.
//#define USE_SDFAT
#ifdef USE_SDFAT
#include <SdFat.h>
#else
#include <SD.h>
#endif
char response_buf[RESPONSE_BUF_SIZE + 1];
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(10, 2, 1, 33);
EthernetServer http(80);
#ifdef USE_SDFAT
SdFat SD;
#endif
bool hasSD = false;
String method;
String url;
void setup() {
pinMode(9, OUTPUT);
digitalWrite(9, LOW); // begin reset the WIZ820io
pinMode(10, OUTPUT);
digitalWrite(10, HIGH); // de-select WIZ820io
pinMode(4, OUTPUT);
digitalWrite(4, HIGH); // de-select the SD Card
digitalWrite(9, HIGH); // end reset pulse
hasSD = SD.begin(SD_PIN);
Ethernet.begin(mac, ip);
http.begin();
Serial.print("Server is at ");
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = http.available();
if (client) {
String method = "";
String url = "";
int numRead = 0;
// First line is request method, url and version
int readVal;
while (numRead++ < LINE_MAX) {
readVal = client.read();
if (readVal < 0) return; // end of stream
if (readVal == ' ') break;
method.append((char)readVal);
}
while (numRead++ < LINE_MAX) {
readVal = client.read();
if (readVal < 0) return; // end of stream
if (readVal == ' ') break;
url.append((char)readVal);
}
// Request ends with empty line, so just read until blank line
char prev = '\0';
while (true) {
readVal = client.read();
if (readVal < 0) return; // end of stream
if (prev == '\n' && readVal == '\n') break; // emtpy line
if (readVal != '\r') prev = readVal;
}
Serial.print("method = ");
Serial.println(method);
Serial.print("url = ");
Serial.println(url);
if (method == "GET") {
String filename = "www" + url;
if (hasSD && SD.exists(filename.c_str())) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/plain");
client.println("Connection: close");
client.println();
#ifdef USE_SDFAT
SdFile file;
if (file.open(filename.c_str(), FILE_READ)) {
#else
File file = SD.open(filename.c_str());
if (file) {
#endif
int numRead;
while ((numRead = file.read(response_buf, RESPONSE_BUF_SIZE)) > 0)
{
client.write(response_buf, numRead);
}
file.close();
}
else {
client.println("HTTP/1.1 404 NOT FOUND");
client.println("Content-Type: text/plain");
client.println("Connection: close");
client.println();
Serial.print("Unable to open file: ");
Serial.println(filename);
}
}
else {
client.println("HTTP/1.1 404 NOT FOUND");
client.println("Content-Type: text/plain");
client.println("Connection: close");
client.println();
Serial.print("Unable to access SD or file does not exist: ");
Serial.println(filename);
}
delay(1);
client.stop();
Serial.println("Done");
}
}
}