String... Переполнение строки?
- Войдите на сайт для отправки комментариев
Доброго вечера! Итак, есть arduino uno v3 и ethernet shild. В него вставлена SD карта. Задача следующая: с аналоговых датчиков A1 (temperature), A2 (humidity) читать данные и преобразовав их в строку dataString, записать в текстовый файл на SD карте.... Результат вывести в serial monitor. В начале всё происходит хорошо: arduino читает значения с аналоговых пинов, записывает в txt, выводит в монитор... Но через некоторое время вместо значений и текста начинает выводится "кракозябра"... В файл также пишутся иероглифы... Скорее всего это происходит изза переполнения буфера строки... Но как очистить строку от мусора, возобновив нормальную работу скетча, не могу понять... Ребята, помогите пожалуйста разобраться. Заранее спасибо огромное за помощь.
#include <Ethernet.h>
#include <SPI.h>
#include <SD.h>
const int chipSelect = 4;
#define SWITCH_TO_W5100 digitalWrite(4,HIGH); digitalWrite(10,LOW)
#define SWITCH_TO_SD digitalWrite(10,HIGH); digitalWrite(4,LOW)
#define ALL_OFF digitalWrite(10,HIGH); digitalWrite(4,HIGH)
File root;
EthernetClient client;
byte server[] = { 10,10,20,1 };
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip ( 10,10,20,1 );
void setup()
{
SWITCH_TO_W5100;
pinMode(4, OUTPUT);
pinMode(10, OUTPUT);
Serial.begin(9600);
Ethernet.begin(mac,ip);
Serial.println("Ethernet start");
Serial.print("Initializing SD card...");
SWITCH_TO_SD;
pinMode(10, OUTPUT);
if (!SD.begin(4)) Serial.println("initialization failed!");
else Serial.println("initialization done.");
ALL_OFF;
}
void loop()
{
delay(3000);
readPage();
}
void readPage()
{
Serial.println("connecting..."); //конектимся к серверу по 80 порту
if (client.connect(server, 80)) Serial.println("connected");
client.stop();
Serial.println("Disconnected");
root = SD.open("/");
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
return;
}
// создать строку для сборки данных в лог:
String dataString = "";
// прочитать два датчика и добавить данные к строке:
{
int sensor1 = analogRead(A1);
int sensor2 = analogRead(A2);
dataString += String("temperature") + ":" + String(sensor1) + "\n" + String ("humidity") + ":" + String(sensor2) + "\r"; // ключи переноса строки \r файл \n сериал порт
}
// открыть файл. обратите внимание, что за раз может быть открыт только один файл,
// поэтому вы должны закрыть его перед открытием другого.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// если файл доступен, то записать в него:
if (dataFile)
{
dataFile.println(dataString);
dataFile.close();
// вывести строку и в последовательный порт:
Serial.println(dataString);
Serial.flush();
}
// если файл не открыт, вывести сообщение об ошибке:
else
{
Serial.println("error opening datalog.txt");
}
Serial.println("done!");
}

Скетч-то опубликуйте, посмотрим.
вверху в шапке прикреплённый скетч :)
Ой, прошу прощения, не заметил за картинкой.
Ничего страшного, я прям удивился, как это... вроде бы вставлял код и скрин... :) Вообщем, надеюсь кто нибудь поможет справиться с этими "кракозябрами" :)
Локалиуйте проблему. У вас в скетче и Ethernet, и SD. Закомментируйте пока всё лишнее, чтобы скетч просто опрашивал датчики и выводил их показания в Serial. После этого постепенно возвращайте функционал.
45 строчка лишняя. Тем более вы читаете SD задолго до ее инициализации.
Со строками такое бувает, чо...
убрал 45 строчку... и на всякий случай отформатировал флешку в обычный FAT (не FAT32)... Сбоев нет... Странно. Но действует. Спасибо! :)
Зачем в строке 60 складывать в одну строку подстроки? Не проще ли просто последовательно писать в файл? Т.е. вместо:
// создать строку для сборки данных в лог: String dataString = ""; // прочитать два датчика и добавить данные к строке: { int sensor1 = analogRead(A1); int sensor2 = analogRead(A2); dataString += String("temperature") + ":" + String(sensor1) + "\n" + String ("humidity") + ":" + String(sensor2) + "\r"; // ключи переноса строки \r файл \n сериал порт } // открыть файл. обратите внимание, что за раз может быть открыт только один файл, // поэтому вы должны закрыть его перед открытием другого. File dataFile = SD.open("datalog.txt", FILE_WRITE); // если файл доступен, то записать в него: if (dataFile) { dataFile.println(dataString); dataFile.close(); // вывести строку и в последовательный порт: Serial.println(dataString); Serial.flush(); }сделать нечто вроде этого:
void printInt(Stream& s, const char* message, int val) { s.print(message); s.println(val); } int sensor1 = analogRead(A1); int sensor2 = analogRead(A2); File dataFile = SD.open("datalog.txt", FILE_WRITE); if(dataTile) { const char* message = "temperature:"; printInt(dataFile,message,sensor1); printInt(Serial,message,sensor1); message = "humidity:"; printInt(dataFile,message,sensor2); printInt(Serial,message,sensor2); dataFile.close(); }И в файл выведется, и в Serial, работы с оперативкой - минимум.
в документации не нашёл описание функции
printInt() - побайтовый вывод? А как реализуется форматирование текста?Ее и нет в документации. Смотри внимательнее код выше)
Ее и нет в документации. Смотри внимательнее код выше)
смотрел, не понял, то и спрашиваю
Вот же она
void printInt(Stream& s, const char* message, int val) { s.print(message); s.println(val); }е понял, то и спрашиваю
Ещё раз посмотрите. Строки с №1 по №5
е понял, то и спрашиваю
Ещё раз посмотрите. Строки с №1 по №5
слона то я и не приметил )))
сбило с толку название ...я бы написал myPrint()
DIYMan: После записи данных с аналоговых пинов в текстовый файл, необходимо будет передавать этот файл с SD карты на компьютер через ethernet по GET запросу. И уже обработав txt через C#, нарисовать график... Пока что подумываю, как это можно будет реализовать, гуглю возможные варианты.
Удивляют меня такие прожекты. В планах - создать супернужный девайс и покорить весь мир, но вот в первом же скетче String подставу делает.
Я бы сначала у ТС уточнил что важнее корректно данные отправить или на карту записывать, потом бы уже в скетче приоритеты расставлять, типа если данные не ушли, а на том конце сервер ну очень нужен, то отправлять до успеха, а на карту потом уже записывать.