При повторном вставлении SD карта не определяеться.
- Войдите на сайт для отправки комментариев
Плата MEGA 2560. Подключены дисплей 12862B V2.0, часы DS1302, клавиатура и считыватель SD карт от LC STUDIO.
Программа имеет два файла CSBoiler.ino и CSBoiler.h. Отлаживается на Microsoft Visual Studio 2015.
Файл CSBoiler.ino.
#include "CSBoiler.h"
void setup()
{
/* add setup code here */
u8g.setRot180();
initSD();
Serial.begin(115200);
}
void loop()
{
/* add main program code here */
switch (wait4event())
{
case eDisp:
draw();
break;
case eSDwr:
writeLog();
break;
case eKeyP:
break;
default:
break;
}
}
Файл CSBoiler.h
// CSBoiler.h
#ifndef _CSBOILER_h
#define _CSBOILER_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "arduino.h"
#else
#include "WProgram.h"
#endif
#include <U8glib.h>
#include <DS1302.h>
#include <Keypad.h>
#include <SPI.h>
#include <SD.h>
#define Tic 200
#define RTic 10
#define eNone 0
#define eTerm 1
#define eVent 2
#define eDisp 3
#define eSDwr 8
#define eKeyP 4
void printTime(void);
struct CSData
{
uint16_t yyyy;
uint8_t mm;
uint8_t dd;
uint8_t hh;
uint8_t nn;
uint8_t ss;
char temp1[10];
char temp2[10];
char temp3[10];
char temp4[10];
uint16_t dtBegn;
uint16_t dtTemp;
uint16_t dtDisp;
uint16_t dtKeyp;
uint16_t dtSDwr;
};
struct CSData csd = { 2016,02,04, 23,30,44, "88.0","89.3","84.7", "70.6", 55,120,300 };
/*****************************************************************************/
// Настройка клавиатуры
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{ '9', '#', '3', '6' },
{ 'C', 'D', 'A', 'B' },
{ '7', '*', '1', '4' },
{ '8', '0', '2', '5' }
};
byte rowPins[ROWS] = { 29, 28, 27, 26 }; //connect to the row pinouts of the keypad
byte colPins[COLS] = { 25, 24, 23, 22 }; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
/*****************************************************************************/
const int csLCD = A7;
const int enLCD = A6;
const int rwLCD = A5;
//U8GLIB_ST7920_128X64_4X u8g(18, 16, 17); // SPI Com: SCK = en = 18, MOSI = rw = 16, CS = di = 17
U8GLIB_ST7920_128X64_4X u8g(csLCD);
/*****************************************************************************/
// Часы
const int kCePin = A2; // Chip Enable
const int kIoPin = A1; // Input/Output
const int kSclkPin = A0; // Serial Clock
char inKey;
// Create a DS1302 object.
DS1302 rtc(kCePin, kIoPin, kSclkPin);
Time t(2016, 2, 4, 22, 15, 0, Time::kThursday);
/*****************************************************************************/
// SD Card
const int csSD = 48;
boolean errSD;
void initSD(void) {
Serial.println("Init");
pinMode(SS, OUTPUT);
pinMode(csSD, OUTPUT);
pinMode(csLCD, OUTPUT);
digitalWrite(SS, HIGH);
digitalWrite(csSD, HIGH);
digitalWrite(csLCD, HIGH);
errSD = !SD.begin(csSD);
Serial.print("errSD=");
Serial.println(errSD);
if (errSD)
return;
printTime();
char fname[10];
snprintf(fname, sizeof(fname), "%02d_%02d.txt",
csd.dd, csd.hh);
uint16_t tmp = millis();
File dataFile = SD.open(fname, FILE_WRITE);
if (dataFile) {
dataFile.println("Begin ---------------------------------------------------------------");
dataFile.close();
}
else
{
errSD = true;
}
csd.dtSDwr = (uint16_t)millis() - tmp;
return;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
uint8_t wait4event(void) {
uint32_t numTic = millis();
if ((numTic % Tic) == 0) {
csd.dtBegn = (uint16_t)millis();
return (uint8_t)((numTic / Tic) % RTic);
}
if (numTic % Tic < Tic - 10) {
csd.dtKeyp = -(uint16_t)millis();
customKeypad.getKey();
csd.dtKeyp += (uint16_t)millis();
return eKeyP;
}
return eNone;
}
/*****************************************************************************/
/*****************************************************************************/
void printTime() {
// Get the current time and date from the chip.
t = rtc.time();
csd.yyyy = t.yr; csd.mm = t.mon; csd.dd = t.date;
csd.hh = t.hr; csd.nn = t.min; csd.ss = t.sec;
// Name the day of the week.
// Format the time and date and insert into the temporary buffer.
char buf[50];
snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d",
t.yr, t.mon, t.date,
t.hr, t.min, t.sec);
// Print the formatted string to serial so we can see the time.
u8g.setFont(u8g_font_courB08);
u8g.drawStr(7, 8, buf);
}
/*****************************************************************************/
void printErrors(void) {
if (errSD) {
u8g.setFont(u8g_font_courB08);
u8g.drawStr( 1, 63, "SD!");
}
}
/*****************************************************************************/
void draw(void){
csd.dtDisp = -(uint16_t)millis();
u8g.firstPage();
do {
printTime();
printErrors();
} while (u8g.nextPage());
pinMode(csLCD, OUTPUT);
digitalWrite(csLCD, HIGH);
csd.dtDisp += (uint16_t)millis();
}
/*****************************************************************************/
void writeLog(void) {
uint16_t tmp = millis();
Serial.println("writeLog");
Serial.print("errSD=");
Serial.println(errSD);
if (errSD) {
initSD();
Serial.println("ReInit");
Serial.print("errSD=");
Serial.println(errSD);
}
if(errSD) return;
char fname[10];
snprintf(fname, sizeof(fname), "%02d_%02d.txt",
csd.dd, csd.hh);
File logFile = SD.open(fname, FILE_WRITE);
int num;
// if the file is available, write to it:
if (logFile) {
char dstr[200];
snprintf(dstr, sizeof(dstr), "%02d:%02d:%02d %s %s %s %s %04d %04d %04d %04d %04d",
csd.hh, csd.nn, csd.ss,
csd.temp1, csd.temp2, csd.temp3, csd.temp4,
csd.dtBegn, csd.dtTemp, csd.dtDisp, csd.dtKeyp, csd.dtSDwr);
num = logFile.println(dstr);
Serial.print("NumWrite=");
Serial.println(num);
logFile.close();
}
else
errSD = true;
if(num == 0)
errSD = true;
// logFile = SD.open(fname, FILE_READ);
csd.dtSDwr = (uint16_t)millis() - tmp;
}
Если карта вставлена то при запуске все работает, за исключением «муссора» на экране. По вопросу «муссора» создал тему в Аппаратных вопросах «При работе по SPI SD карта «мусорит» дисплей ST7920_128X64. Как побороть?».
А теперь софтовая проблема №1: Если карту вынуть во время работы то программа это определяет и выводит сообщение на дисплей. Если ее повторно вставить то она не переинициализируется и не работает. Все время стоит флаг ошибки errSD = true.
Отладочная информация:
Opening port Port open writeLog errSD=0 NumWrite=55 writeLog errSD=0 NumWrite=55 /// Вынул карту writeLog errSD=0 /// Дальше сколько раз не вставляй/вынимай карту, она не работает writeLog errSD=1 Init errSD=1 ReInit errSD=1 writeLog errSD=1 Init errSD=1 ReInit errSD=1 writeLog errSD=1 Init errSD=1 ReInit errSD=1 writeLog errSD=1 Init errSD=1 ReInit errSD=1 writeLog errSD=1 Init errSD=1 ReInit errSD=1 writeLog errSD=1 Init errSD=1 ReInit errSD=1 Port closed
Если карта вынута при запуске то при вставлении она инициализируется, но после вынимания и повторного вставления она не переинициализируется.
Opening port Port open writeLog errSD=1 Init errSD=1 ReInit errSD=1 writeLog errSD=1 /// Вставил карту Init errSD=0 ReInit errSD=0 NumWrite=55 writeLog errSD=0 NumWrite=55 writeLog errSD=0 NumWrite=56 /// Вынул карту writeLog errSD=0 writeLog errSD=1 /// Дальше сколько раз не вставляй/вынимай карту, она не работает Init errSD=1 ReInit errSD=1 writeLog errSD=1 Init errSD=1 ReInit errSD=1 writeLog errSD=1 Init errSD=1 ReInit errSD=1 Port closed
Как заставить карту работать нормально? Это ошибка библиотеки SD?
Второй вопрос возник по анализу записываемой в карту информации, а именно времени работы подпрограмм.
Вот фрагмент такого файла:
Из него видно, что вывод на LCD занимает 48-49 мс, опрос клавиатуры меньше 1 мс, а вот с записью в SD карту происходят чудеса.
Как правило строка 55-56 символов пишется 17-18 мс (последняя колонка), но периодически бывает резкое увеличение времени записи - больше 174 мс. Чем это объяснить. Как с этим бороться?
Имел ли кто опыт работы с SD? Определяется ли у вас карта при повторном вставлении? М.б. какую-то другую библиотеку надо подключить?