При повторном вставлении 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? Определяется ли у вас карта при повторном вставлении? М.б. какую-то другую библиотеку надо подключить?