ویژگی های ماژول شیلد دیتالاگر آردوینو
از ماژول شیلد دیتالاگر آردوینو میتوان برای برقراری ارتباط بین آردوینو و یک SD کارت استفاده کرد. در واقع میتوان از این ماژول برای ذخیرهسازی اطلاعات آردوینو استفاده نمود. یکی از کاربردهای شیلد دیتالاگر، حفظ اطلاعات موقع قطع شدن ناگهانی منبع تغذیه برد آردینو مثلا هنگام قطع برق است. این ماژول علاوه بر توانایی ذخیره اطلاعات بر روی SD کارت، یک ماژول DS1307 به عنوان RTC نیز برای شمارش ساعت و تاریخ دقیق در اختیار میگذارد. پروتکل ارتباطی ماژول ساعت I2C و پروتکل ارتباطی SD کارت SPI میباشد.
معرفی پایه ها (Pinout) ماژول شیلد دیتالاگر آردوینو
این ماژول دقیقا بر روی یک برد آردوینو قرار میگیرد و پایههای آن همان پایههای برد آردوینو میشود.
لوازمی که به آن احتیاج دارید
قطعات مورد نیاز
نرم افزارهای مورد نیاز
راه اندازی ماژول شیلد دیتالاگر آردوینو
گام اول: سیم بندی
مطابق زیر، ماژول را بر روی آردوینو قرار دهید.
گام دوم: نصب کتابخانه
به Library manager رفته و کتابخانه DS1307RTC را نصب کنید.
سپس کتابخانه SD را نصب کنید.
گام سوم: کد
کد زیر را روی برد آردوینو آپلود کنید. پس از آپلود کد، پنجره ی Serial Monitor را باز کنید.
/*
Modified on Nov 24, 2020
Modified by MehranMaleki from Arduino Examples
Home
*/
#include "SD.h"
#include <Wire.h>
#include <DS1307RTC.h>
const char *monthName[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
tmElements_t tm;
// A simple data logger for the Arduino analog pins
#define LOG_INTERVAL 1000 // mills between entries
// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()
// The analog pins that connect to the sensors
#define voltPin A0 // analog A0
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void setup(void)
{
Serial.begin(9600);
while (!Serial) ; // wait for serial
delay(2000);
bool parse=false;
bool config=false;
// get the date and time the compiler was run
if (getDate(__DATE__) && getTime(__TIME__)) {
parse = true;
// and configure the RTC with this info
if (RTC.write(tm)) {
config = true;
}
}
if (parse && config) {
Serial.print("DS1307 configured Time=");
Serial.print(__TIME__);
Serial.print(", Date=");
Serial.println(__DATE__);
} else if (parse) {
Serial.println("DS1307 Communication Error :-{");
Serial.println("Please check your circuitry");
} else {
Serial.print("Could not parse info from the compiler, Time=\"");
Serial.print(__TIME__);
Serial.print("\", Date=\"");
Serial.print(__DATE__);
Serial.println("\"");
}
#if WAIT_TO_START
Serial.println("Type any character to start");
while (!Serial.available());
#endif //WAIT_TO_START
// initialize the SD card
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
// If you want to set the aref to something other than 5v
//analogReference(EXTERNAL);
}
void loop(void)
{
// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
// log milliseconds since starting
uint32_t m = millis();
logfile.print("Miliseconds Since Start: "); // milliseconds since start
logfile.println(m);
#if ECHO_TO_SERIAL
Serial.print("Miliseconds Since Start: ");
Serial.println(m); // milliseconds since start
#endif
delay(2000);
if (RTC.read(tm)) {
Serial.print("Ok, Time = ");
print2digits(tm.Hour);
Serial.write(':');
print2digits(tm.Minute);
Serial.write(':');
print2digits(tm.Second);
Serial.print(", Date (D/M/Y) = ");
Serial.print(tm.Day);
Serial.write('/');
Serial.print(tm.Month);
Serial.write('/');
Serial.print(tmYearToCalendar(tm.Year));
Serial.println();
} else {
if (RTC.chipPresent()) {
Serial.println("The DS1307 is stopped. Please run the SetTime");
Serial.println("example to initialize the time and begin running.");
Serial.println();
} else {
Serial.println("DS1307 read error! Please check the circuitry.");
Serial.println();
}
delay(9000);
}
delay(2000);
int voltReading = analogRead(voltPin);
delay(10);
// converting that reading to voltage, for 3.3v arduino use 3.3
float voltage = (voltReading * 5.0) / 1024.0;
logfile.print("Data We Read from Analog Pin: ");
logfile.print(voltReading);
logfile.print(", ");
logfile.print("Calculated Voltage: ");
logfile.println(voltage);
#if ECHO_TO_SERIAL
Serial.print("Data We Read from Analog Pin: ");
Serial.print(voltReading);
Serial.print(", ");
Serial.print("Calculated Voltage: ");
Serial.println(voltage);
#endif //ECHO_TO_SERIAL
delay(1000);
// Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
// which uses a bunch of power and takes time
if ((millis() - syncTime) < SYNC_INTERVAL) return;
syncTime = millis();
logfile.flush();
}
void error(char *str)
{
Serial.print("error: ");
Serial.println(str);
while(1);
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write('0');
}
Serial.print(number);
}
bool getTime(const char *str)
{
int Hour, Min, Sec;
if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
tm.Hour = Hour;
tm.Minute = Min;
tm.Second = Sec;
return true;
}
bool getDate(const char *str)
{
char Month[12];
int Day, Year;
uint8_t monthIndex;
if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
for (monthIndex = 0; monthIndex < 12; monthIndex++) {
if (strcmp(Month, monthName[monthIndex]) == 0) break;
}
if (monthIndex >= 12) return false;
tm.Day = Day;
tm.Month = monthIndex + 1;
tm.Year = CalendarYrToTm(Year);
return true;
}
در کد بالا ابتدا RTC و سپس کارت SD را فعال کرده و یک فایل با پسوند .CSV میسازیم. در ادامه ولتاژ آنالوگ مربوط به پین A0 آردوینو را خوانده و آن را در فایل ساخته شده در کارت SD ذخیره میکنیم. همچنین هر بار، تاریخ دقیق و مدت زمان شروع ماژول بر حسب میلیثانیه را هم در فایل ذخیره میکنیم. در ادامه هر بار اطلاعات ذخیره شده در کارت SD را بر روی Serial Monitor نمایش میدهیم.
خروجی کد به شکل زیر است.
Comments (11)
سلام. ارتباط سریال کاملا درست کار میکنه ولی داخل فایل CSV ایجاد شده هیچ چیزی ذخیره نمیشه و حجمش صفره. مشکل از کجاست؟
سلام.
بله یه قسمتی از کد مشکل داشت. الان بر طرف شده و میتونید ازش استفاده کنید.
سلام این کد من نمی تونم توی آردیونو verify کنم،فکر کنم کد مشکل داره
سلام.
احتمالا کتابخونه Time رو روی برنامه آردوینوتون نصب ندارید. در قسمت Manage Libraries، کتابخونه DS1307RTC رو جستوجو کنید و کتابخونه Time رو هم که در نتایج جستوجو میاره نصب کنید.
با سلام و احترام در خط انتهای کامپایل برنامه چنین خطایی می ده
Low memory available, stability problems may occur
سلام.
این مسالهای که میگید خطا نیست و صرفا یک هشداره. به این معنی که کد شما در نهایت روی برد آردوینو آپلود میشه و کار هم میکنه اما نرمافزار با توجه به نزدیک بودن حافظه مورد نیاز برای این کد به حافظه کلی برد آردوینو Uno این هشدار رو میده که ممکنه بعدا در حین کار کردن برد ریست بشه.
این موضوع در حالت کلی مساله خاصی نیست اما برای حلش میتونید از برد آردوینو مگا به جای Uno استفاده کنید.
سلام… من میخوام یه جدول که دارای سه ستون هستش رو در اکسل ایجاد کنم و تو کارت sd ذخیره کنم.. ستون اول طول جغرافیایی و ستون دوم عرض جغرافیایی و ستون سوم عددی بین 0 تا 10… سپس ورودی GPS را دریافت می کنیم و اگر طول و عرض جغرافیایی با هر یک از اعدادی که در ستون اول و ستون دوم نوشتیم برابر بود، یکی از اعداد متناظر با طول و عرض جرافیایی دریافت شده از gps (0 تا 10) را روی نمایشگر سریال نمایش می دهد … کمک شما برای من بسیار مهم است
سلام از این ماژول میشه برای ارتباط با stm32 استفاده کرد؟
با سلام
این ماژول یک شیلد برای برد آردوینو می باشد. شما می توانید از همین مدل را به stm32 وصل کنید یا ماژول SD کارت را به صورت جدا تهیه کنید و آن را به میکرو خود وصل کنید. یک ماژول RTC هم بر روی این شیلد می باشد که آن را نیز هم می توانید به صورت جدا تهیه کنید و استفاده کنید و هم می توانید از RTC داخلی خود میکرو STM استفاده کنید
سلام و خسته نباشید.
امکانش هست کدی که قبلا با یه ماژول sd card و RTC نوشته شده و کار کرده رو با این شیلد، پروگرم کرد؟
با سلام
بله میتوانید استفاده کنید در صورتی که کد RTC شما با این مدل یکی باشد.
همچنین ترتیب پایه های خود را با این مدل بررسی کنید و در صورت لزوم تغییر بدهید.