阿杜伊诺。将文本文件从SD卡发送到web服务器
我有一个Arduino草图,每10分钟,将温度数据写入SD文本文件,并将数据发布到web服务器 如果internet连接丢失,草图将继续将数据保存到SD文本文件(但不会将其发布到web)。 当互联网连接恢复时,我需要 从SD卡读取整个文本文件并将其发布到web服务器(php脚本接收发布的内容) 使用以下代码,我可以发布到php脚本。但是现在我需要postdata变量包含文本文件阿杜伊诺。将文本文件从SD卡发送到web服务器,web,post,arduino,text-files,Web,Post,Arduino,Text Files,我有一个Arduino草图,每10分钟,将温度数据写入SD文本文件,并将数据发布到web服务器 如果internet连接丢失,草图将继续将数据保存到SD文本文件(但不会将其发布到web)。 当互联网连接恢复时,我需要 从SD卡读取整个文本文件并将其发布到web服务器(php脚本接收发布的内容) 使用以下代码,我可以发布到php脚本。但是现在我需要postdata变量包含文本文件 if (client.connect("192.168.1.100", 80))
if (client.connect("192.168.1.100", 80))
{
client.println("POST /readfile.php HTTP/1.1");
client.println("Host: 192.168.1.100");
client.println("User-Agent: Arduino/1.0");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(postdata.length());
client.println("");
client.println(postdata);
delay(1);
client.stop();
所以我需要一种方法来读取字符串(或任何)变量中的文本文件
我可以使用Arduino UNO、MEGA或ESP32
提前谢谢 这是一个完整的代码,可在ArduineIDE 1.8.12上使用ESP8266(核心1.6.3)或ESP32(核心1.0.4),并使用内置SD卡。
由于您没有提供数据文件结构的详细信息,因此假设是
- 每个数据项都在一行中
- 行内的数据结构在服务器上处理
- 服务器期望并处理每个传输的一个数据条目(=行)
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#ifdef ESP32
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
// function declaration
void postFileContent(const char * path );
#define FILE_LINE_LENGTH 81 // a line has 80 chars
char txtLine[FILE_LINE_LENGTH];
char postdata [FILE_LINE_LENGTH];
bool readCondition = true; // Has to be defined somewhere to trigger SD read
#ifdef ESP8266
const uint8_t chipSelect = 4; //CS pin of the sd card reader
#endif
WiFiClient client;
void setup() {
Serial.begin(115200);
#ifdef ESP32
if (!SD.begin()) {
#elif defined(ESP8266)
if (!SD.begin(chipSelect)) {
#endif
Serial.println("Card reader mount failed");
return;
}
#ifdef ESP32
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}
#endif
}
void loop() {
//...... Your program structure
if (client.connect("192.168.1.100", 80)) {
if (readCondition == true) {
postFileContent("/data_log.txt"); // Read file data_log.txt in Root directory
readCondition = false; // reset condition
}
else {
client.println("POST /readfile.php HTTP/1.1");
client.println("Host: 192.168.1.100");
client.println("User-Agent: Arduino/1.0");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(strlen(postdata));
client.println("");
client.println(postdata);
}
delay(1);
client.stop();
}
//...... Your program structure
}
void postFileContent(const char* path) {
Serial.print(F(" -- Reading entries from file = "));
Serial.print(path);
if (!SD.exists(path)) {
Serial.println("ERROR: The required file does not exist.");
return;
}
#ifdef ESP32
File file = SD.open(path);
#elif defined(ESP8266)
File file = SD.open(path, FILE_READ); // FILE_READ is default so not realy needed but if you like to use this technique for e.g. write you need FILE_WRITE
#endif
if (!file) {
Serial.println("Failed to open file for reading");
return;
}
char c;
uint8_t i = 0;
while (file.available()) {
c = file.read();
if (c == '\n') { //Checks forline break
txtLine[i] = '\0';
Serial.print(F(" * "));
Serial.println(txtLine); //This is where you get one line of file at a time.
client.println("POST /readfile.php HTTP/1.1");
client.println("Host: 192.168.1.100");
client.println("User-Agent: Arduino/1.0");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(strlen(txtLine));
client.println("");
client.println(txtLine);
}
else if (c >= 32) {
txtLine[i] = c;
i++;
}
}
file.close();
Serial.println(F("DONE Reading"));
}
#包括“FS.h”
#包括“SD.h”
#包括“SPI.h”
#ifdef ESP32
#包括
#定义的elif(ESP8266)
#包括
#恩迪夫
//函数声明
void postFileContent(const char*path);
#定义文件行长度81//一行有80个字符
char txtLine[文件行长度];
char postdata[文件行长度];
bool readCondition=true;//必须在某个地方定义以触发SD读取
#ifdef ESP8266
const uint8\u t chipSelect=4//sd卡读卡器的CS pin码
#恩迪夫
无线客户端;
无效设置(){
序列号开始(115200);
#ifdef ESP32
如果(!SD.begin()){
#定义的elif(ESP8266)
如果(!SD.begin(芯片选择)){
#恩迪夫
Serial.println(“读卡器安装失败”);
返回;
}
#ifdef ESP32
uint8_t cardType=SD.cardType();
如果(cardType==卡\u无){
Serial.println(“未附SD卡”);
返回;
}
#恩迪夫
}
void循环(){
//……您的课程结构
if(客户端连接(“192.168.1.100”,80)){
if(readCondition==true){
postFileContent(“/data_log.txt”);//读取根目录中的文件数据_log.txt
readCondition=false;//重置条件
}
否则{
println(“POST/readfile.php HTTP/1.1”);
client.println(“主机:192.168.1.100”);
client.println(“用户代理:Arduino/1.0”);
client.println(“连接:关闭”);
client.println(“内容类型:application/x-www-form-urlencoded”);
client.print(“内容长度:”);
client.println(strlen(postdata));
客户。println(“”);
client.println(postdata);
}
延迟(1);
client.stop();
}
//……您的课程结构
}
无效postFileContent(常量字符*路径){
Serial.print(F(“--readingentriefromfile=”);
串行打印(路径);
如果(!SD.存在(路径)){
Serial.println(“错误:所需文件不存在。”);
返回;
}
#ifdef ESP32
File File=SD.open(路径);
#定义的elif(ESP8266)
File File=SD.open(path,File_READ);//File_READ是默认值,因此不需要,但如果您想使用此技术进行写入,则需要使用File_write
#恩迪夫
如果(!文件){
Serial.println(“打开文件读取失败”);
返回;
}
字符c;
uint8_t i=0;
while(file.available()){
c=file.read();
如果(c=='\n'){//检查换行符
txtLine[i]='\0';
连续打印(F(“*”);
Serial.println(txtLine);//这是一次获取一行文件的地方。
println(“POST/readfile.php HTTP/1.1”);
client.println(“主机:192.168.1.100”);
client.println(“用户代理:Arduino/1.0”);
client.println(“连接:关闭”);
client.println(“内容类型:application/x-www-form-urlencoded”);
client.print(“内容长度:”);
client.println(strlen(txtLine));
客户。println(“”);
client.println(txtLine);
}
如果(c>=32),则为else{
txtLine[i]=c;
i++;
}
}
file.close();
序列号。打印号(F(“完成读取”);
}
希望这能帮助您入门这里有一个完整的代码,可以在ArduineIDE 1.8.12上使用ESP8266(core 1.6.3)或ESP32(core 1.0.4),并使用内置SD卡。
由于您没有提供数据文件结构的详细信息,因此假设是
- 每个数据项都在一行中
- 行内的数据结构在服务器上处理
- 服务器期望并处理每个传输的一个数据条目(=行)
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#ifdef ESP32
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
// function declaration
void postFileContent(const char * path );
#define FILE_LINE_LENGTH 81 // a line has 80 chars
char txtLine[FILE_LINE_LENGTH];
char postdata [FILE_LINE_LENGTH];
bool readCondition = true; // Has to be defined somewhere to trigger SD read
#ifdef ESP8266
const uint8_t chipSelect = 4; //CS pin of the sd card reader
#endif
WiFiClient client;
void setup() {
Serial.begin(115200);
#ifdef ESP32
if (!SD.begin()) {
#elif defined(ESP8266)
if (!SD.begin(chipSelect)) {
#endif
Serial.println("Card reader mount failed");
return;
}
#ifdef ESP32
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}
#endif
}
void loop() {
//...... Your program structure
if (client.connect("192.168.1.100", 80)) {
if (readCondition == true) {
postFileContent("/data_log.txt"); // Read file data_log.txt in Root directory
readCondition = false; // reset condition
}
else {
client.println("POST /readfile.php HTTP/1.1");
client.println("Host: 192.168.1.100");
client.println("User-Agent: Arduino/1.0");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(strlen(postdata));
client.println("");
client.println(postdata);
}
delay(1);
client.stop();
}
//...... Your program structure
}
void postFileContent(const char* path) {
Serial.print(F(" -- Reading entries from file = "));
Serial.print(path);
if (!SD.exists(path)) {
Serial.println("ERROR: The required file does not exist.");
return;
}
#ifdef ESP32
File file = SD.open(path);
#elif defined(ESP8266)
File file = SD.open(path, FILE_READ); // FILE_READ is default so not realy needed but if you like to use this technique for e.g. write you need FILE_WRITE
#endif
if (!file) {
Serial.println("Failed to open file for reading");
return;
}
char c;
uint8_t i = 0;
while (file.available()) {
c = file.read();
if (c == '\n') { //Checks forline break
txtLine[i] = '\0';
Serial.print(F(" * "));
Serial.println(txtLine); //This is where you get one line of file at a time.
client.println("POST /readfile.php HTTP/1.1");
client.println("Host: 192.168.1.100");
client.println("User-Agent: Arduino/1.0");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(strlen(txtLine));
client.println("");
client.println(txtLine);
}
else if (c >= 32) {
txtLine[i] = c;
i++;
}
}
file.close();
Serial.println(F("DONE Reading"));
}
#包括“FS.h”
#包括“SD.h”
#包括“SPI.h”
#ifdef ESP32
#包括
#定义的elif(ESP8266)
#包括
#恩迪夫
//函数声明
void postFileContent(const char*path);
#定义文件行长度81//一行有80个字符
char txtLine[文件行长度];
char postdata[文件行长度];
bool readCondition=true;//必须在某个地方定义以触发SD读取
#ifdef ESP8266
const uint8\u t chipSelect=4;//sd卡读卡器的CS pin
#恩迪夫
无线客户端;
无效设置(){
序列号开始(115200);
#ifdef ESP32
如果(!SD.begin()){
#定义的elif(ESP8266)
如果(!SD.begin(芯片选择)){
#恩迪夫
Serial.println(“读卡器安装失败”);
返回;
}
#ifdef ESP32
uint8_t cardType=SD.cardType();
如果(cardType==卡\u无){
Serial.println(“未附SD卡”);
返回;
}
#恩迪夫
}
void循环(){
//……您的课程结构
if(客户端连接(“192.168.1.100”,80)){
if(readCondition==true){
postFileContent(“/data_log.txt”);//读取根目录中的文件数据_log.txt
readCondition=false;//重置条件
}
否则{
println(“POST/readfile.php HTTP/1.1”);
client.println(“主机:192.168.1.100”);
client.println(“用户代理:Arduino/1.0”);
client.println(“连接:关闭”);
client.println(“内容类型:application/x-www-form-urle