Tindankan Data Logging Shield di atas Uno, panggil SD.begin(10) dan tulis baris berpisah koma ke dalam satu fail — tetapi bait-bait itu cuma sampai ke kad bila blok 512-bait library itu penuh atau bila anda panggil flush(). Shield ini membawa soket SD saiz penuh dan jam DS1307 untuk mengecop masa. Kad dan sel CR1220 pula anda yang sediakan.
DC voltan rendah sahaja: USB atau barrel jack Uno. Jangan sesekali masukkan atau cabut kad semasa board masih berkuasa, dan pastikan hujung wayar probe yang terpotong itu kering — hanya tiub stainless sahaja yang kalis air.
Apa yang ada pada Data Logging Shield, dan apa yang tiada?
Data Logging Shield sampai dalam keadaan siap pasang, jadi ia terus duduk di atas Uno sebaik keluar dari beg. Soket kad SD saiz penuh berserta spring eject mengambil separuh kiri board biru gelap itu; di bawahnya, pemegang lutsinar warna maroon menyokong jam masa nyata DS1307. Satu pertiga sebelah kanan pula ialah grid prototaip, tempat anda solder pendawaian secara kekal nanti. Setiap pin Uno diulang semula pada female header shield ini sendiri, jadi tiada satu pun yang tertimbus. Chip 14-pin di sebelah soket kad itu ialah quad buffer yang membuat level shifting: kad SD ialah komponen 3.3 V semata-mata sedangkan Uno memacu logik 5 V, jadi shield inilah yang membuat penterjemahan yang soket kad kosong akan serahkan kepada anda.
Dua benda yang projek ini perlukan tiada di dalam beg, dan kedua-duanya bukan barang yang kami jual:
- Kad SD saiz penuh, bukan microSD. Library SD Arduino yang dihantar bersama IDE menyifatkan dirinya sebagai mengakses “FAT16 and FAT32 files on SD and SDHC cards” (
SdFat.h), dan SDHC berhenti pada 32 GB mengikut spesifikasi, jadi kad exFAT 64 GB tidak akan mount. microSD di dalam adapter saiz penuh memang boleh, cuma adapter itu menambah satu lagi set sentuhan spring — tukar adapter dahulu sebelum menyalahkan shield. - Satu sel syiling CR1220. Pemegangnya dihantar kosong, board biru terdedah kelihatan menerusi tengahnya. Shield ini mengikut reka bentuk rujukan Adafruit dan mengambil sel 12 mm yang sama. Ia tetap boleh digunakan sepenuhnya tanpa sel — bahagian 01/01/2000 di bawah menerangkan apa yang anda hilang.
Lubang CS, L1 dan L2 di atas grid itu, dan dua LED halus di sebelah butang reset, ialah pad solder yang tidak bersambung — bukan penunjuk aktiviti. Tinjauan hands-on board V1.0 yang sama persis:
Senarai komponen — board, shield, probe dan pendawaian yang menyambungkannya
Parts list
| Item | Price | Qty | |
|---|---|---|---|
XL830L Digital Multimeter with backlight Portable Multimeter Electronics ProjectMULTIME | RM25.95 |
Dua kerja khusus untuk projek ini: sahkan pada julat ohm nilai mana sebenarnya yang anda cabut daripada pek perintang dua puluh nilai itu, dan ukur pad 5V shield bila kad enggan mount — rel USB yang jatuh voltan di bawah kad yang lahap kuasa nampak sama macam pepijat kod.
Pin Arduino mana yang sudah digunakan oleh shield ini?
Data Logging Shield menuntut enam pin Uno merentas dua bas: SPI ke kad, I2C ke jam. Jadi probe pula mendarat di D2.
| Pin | Dituntut oleh | Bebas untuk anda? |
|---|---|---|
| D10 | SD chip select (dan pin SS perkakasan ATmega328P) | Tidak |
| D11, D12, D13 | Data dan clock SPI ke kad | Tidak |
| A4, A5 | I2C ke jam DS1307 | Tidak |
| D0, D1 | Dikongsi dengan serial USB | Elakkan |
| D2–D9, A0–A3 | Tiada apa-apa | Ya |
Pada ATmega328P, D10 ialah chip select shield ini dan juga pin SS perkakasan, dan periferal SPI sentiasa memerhati SS — biarkan ia sebagai input, biar sesuatu menariknya ke rendah, maka perkakasan itu jatuh ke mod slave dan master pun berhenti bercakap. SD.begin() menguruskan hal itu untuk anda — ia memanggil SPI.begin(), dan SPI.cpp dalam core AVR menetapkan pinMode(SS, OUTPUT) di situ, di bawah amaran “if the SS pin ever becomes a LOW INPUT then SPI automatically switches to Slave, so the data direction of the SS pin MUST be kept as OUTPUT”. Jangan sesekali menuntut semula D10 selepas itu.
Kenapa probe ini perlukan breadboard dan perintang?
DS18B20 kalis air ini berakhir dengan tiga wayar terjuntai bertimah yang terdedah — merah untuk kuasa, hitam untuk ground, kuning untuk data — tanpa sebarang connector padanya, sedangkan satu-satunya antara muka shield yang boleh dicapai pengguna ialah female stacking header. Wayar bertimah yang terdedah tidak akan mencengkam di dalam shell Dupont female. Mini breadboard 170 lubang menyelesaikannya: setiap lajur lima lubang bersambung di bawah, jadi hujung bertimah dan kaki perintang boleh ditolak masuk terus, dan jumper male-to-male membawa net itu naik ke shield. Format mini ini tiada power rail, jadi 5V dan ground duduk dalam lajur biasa — dan oleh sebab satu lajur ialah satu net, tiga wayar itu perlukan tiga lajur berasingan: merah dan hitam berkongsi satu lajur bermakna 5V berwayar terus ke ground.
Perintang itu bukan pilihan, dan sebabnya terletak pada peringkat outputnya. Pin DQ pada DS18B20 ialah open-drain: di dalamnya ada transistor yang boleh menarik talian turun ke ground, dan tiada apa-apa pula yang boleh memacunya naik. Bila dilepaskan, talian itu terapung mengikut cas sesat yang ada berhampiran. Perintang luaran ke 5V itulah yang membekalkan aras tinggi, dan sebab itulah probe tanpa perintang memulangkan -127.00, iaitu nilai “tiada apa-apa menjawab” bagi library itu, atau tersekat pada 85.00, iaitu nilai lalai sensor sebaik dihidupkan yang terbaca sebelum sebarang penukaran sempat selesai.
Datasheet DS18B20 meminta lebih kurang 5 kΩ, dan 4.7 kΩ hingga 10 kΩ semuanya sesuai untuk satu sensor pada wayar sepanjang satu meter probe ini: perintang dan kapasitans bas membentuk pasangan RC, jadi perintang yang lebih besar membuatkan talian naik lebih perlahan, dan hanya bas yang panjang atau beberapa sensor sekali gus yang kehabisan margin. Pek perintang 400 biji kami mencetak setiap nilai dengan dakwat pada pita kertas bandoliernya, jadi tiada jalur warna untuk dinyahkod — jalur 6.8 kΩ elok digunakan di sini.

| Wayar DS18B20 | Pergi ke | Pada shield |
|---|---|---|
| Merah (VDD) | 5V | Header kuasa bawah |
| Hitam (GND) | GND | Header kuasa bawah |
| Kuning (DQ) | D2 | Header digital atas |
| Perintang 4.7 kΩ–10 kΩ | Merentasi lajur merah dan lajur kuning pada breadboard — iaitu DQ naik ke 5V | |
Sketch apa yang menulis bacaan itu ke dalam kad?
Pasang SD, RTClib (Adafruit), OneWire dan DallasTemperature (Miles Burton) daripada Library Manager, dan biarkan Serial Monitor terbuka pada 9600 baud — sketch ini berhenti pada mana-mana kegagalan setup dan mencetak sebabnya di situ. Sketch mengambil sampel setiap lima saat, mengecop masa daripada DS1307 dan menambah satu baris CSV bagi setiap bacaan — corak yang sama yang merakam load cell HX711 atau MLX90614. Tambah lajur ke dalam satu fail dan bukan mula fail baharu — satu CSV yang lebar boleh dicarta sekali gus.
// Arduino Uno + Data Logging Shield V1.0 + DS18B20 kalis air.
// Menulis satu baris CSV setiap 5 s ke TEMPLOG.CSV pada kad SD saiz penuh,
// bercop masa daripada jam masa nyata DS1307 pada shield.
//
// Shield guna: D10 (SD chip select), D11/D12/D13 (SPI), A4/A5 (I2C untuk RTC).
// Jadi sensor mendarat di D2, dengan pull-up 4.7k-10k dari D2 naik ke 5V.
// DC voltan rendah sahaja: USB atau barrel jack Uno. Jangan masukkan atau
// cabut kad semasa board masih berkuasa.
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const uint8_t SD_CS = 10; // SD chip select shield ini
const uint8_t ONE_WIRE_PIN = 2; // wayar kuning DS18B20 (DQ)
const uint16_t SAMPLE_MS = 5000; // satu bacaan setiap 5 saat
const uint8_t FLUSH_EVERY = 12; // komit ke kad sekali seminit
RTC_DS1307 rtc;
OneWire oneWire(ONE_WIRE_PIN);
DallasTemperature sensors(&oneWire);
File logFile;
uint8_t samplesSinceFlush = 0;
uint32_t nextSampleAt = 0;
// Berhenti dengan lantang, bukan merakam data karut.
void stopHere(const __FlashStringHelper *why) {
Serial.println(why);
while (1) { }
}
void setup() {
Serial.begin(9600);
// D10 ialah SD chip select DAN pin SS perkakasan ATmega328P. SD.begin()
// memanggil SPI.begin(), yang menetapkan SS kepada OUTPUT ("the data
// direction of the SS pin MUST be kept as OUTPUT"), jadi jangan tuntut
// semula D10 sebagai input selepas titik ini - SPI akan jatuh ke mod slave
// dan kad pun terus senyap.
pinMode(SD_CS, OUTPUT);
if (!SD.begin(SD_CS)) {
stopHere(F("Tiada kad. Pastikan ia FAT16/FAT32, <=32GB, tertolak masuk penuh."));
}
Wire.begin();
if (!rtc.begin()) {
stopHere(F("Tiada DS1307 di A4/A5. Shield duduk penuh pada semua pinnya?"));
}
// isrunning() membaca bit CH pada DS1307. Datasheet kata CH hidup dalam
// keadaan SET pada pemberian kuasa yang pertama, jadi dengan pemegang sel
// yang kosong oscillator hidup semula TERHENTI dan tarikh direset kepada
// 01/01/2000 setiap kali.
if (!rtc.isrunning()) {
Serial.println(F("RTC terhenti - menetapkannya daripada sketch ini."));
Serial.println(F("Pasang CR1220 kalau nak masa kekal selepas kuasa terputus."));
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // masa kompil, bukan masa kini
}
sensors.begin();
sensors.setResolution(12); // langkah 0.0625 C, sehingga 750 ms sebacaan
if (sensors.getDeviceCount() == 0) {
stopHere(F("Tiada DS18B20 menjawab. Periksa pull-up antara D2 dan 5V."));
}
logFile = SD.open("TEMPLOG.CSV", FILE_WRITE); // nama 8.3 sahaja
if (!logFile) {
stopHere(F("Tidak dapat buka TEMPLOG.CSV untuk menulis."));
}
if (logFile.size() == 0) { // fail baharu, tambah header
logFile.println(F("timestamp,celsius"));
logFile.flush();
}
Serial.println(F("Merakam ke TEMPLOG.CSV"));
}
void loop() {
if ((int32_t)(millis() - nextSampleAt) < 0) { // perbandingan selamat rollover
return;
}
nextSampleAt += SAMPLE_MS;
sensors.requestTemperatures(); // tersekat ~750 ms pada 12 bit
float celsius = sensors.getTempCByIndex(0);
if (celsius == DEVICE_DISCONNECTED_C) { // -127.00: tiada yang menjawab
Serial.println(F("Sensor tidak menjawab - sampel ini dilangkau."));
return;
}
DateTime now = rtc.now();
char stamp[20];
snprintf(stamp, sizeof(stamp), "%04u-%02u-%02u %02u:%02u:%02u",
now.year(), now.month(), now.day(),
now.hour(), now.minute(), now.second());
logFile.print(stamp);
logFile.print(',');
logFile.println(celsius, 2);
Serial.print(stamp);
Serial.print(F(","));
Serial.println(celsius, 2);
// Bait-bait itu masih berada di dalam blok RAM 512 bait library SD. flush()
// menolak blok itu berserta entri direktorinya ke dalam kad; membuatnya pada
// setiap sampel memakan masa dan mengasak flash, jadi kita buat sekali
// seminit sahaja.
if (++samplesSinceFlush >= FLUSH_EVERY) {
logFile.flush();
samplesSinceFlush = 0;
}
}
Tiga perincian. TEMPLOG.CSV ialah nama 8.3 — sehingga lapan aksara, satu titik, sehingga tiga lagi — kerana itu sahaja yang library ini faham, dan nama yang lebih panjang gagal dibuka secara senyap. setResolution(12) memberi anda langkah 0.0625 °C dengan kos satu penukaran sehingga 750 ms yang ditunggu oleh requestTemperatures(), jadi gelung tersekat hampir sesaat bagi setiap sampel. Dan ujian masanya ialah (int32_t)(millis() - nextSampleAt) < 0 dan bukan millis() < nextSampleAt, supaya ia selamat bila millis() berpusing semula pada hari ke-49.7 — sempadan yang memang direka untuk dilalui oleh sebuah logger.
Kenapa CSV saya kosong selepas bekalan kuasa terputus?
Sebab menulis ke dalam fail dan menulis ke dalam kad ialah dua peristiwa yang berbeza. Library SD menyimpan satu blok 512 bait di dalam RAM — SdFat.h mengisytiharkan static cache_t cacheBuffer_ di bawah komen “512 byte cache for device blocks” — dan println() anda mendarat di situ. Kad hanya disentuh apabila blok itu penuh, apabila flush() dipanggil, atau apabila close() dipanggil. Cabut plug di antara itu, dan baris-baris tadi memang tidak pernah wujud pada pandangan kad.
Separuh keduanya menjelaskan kenapa fail itu terbaca sebagai kosong dan bukan sekadar pendek. flush() memanggil SdFile::sync(), yang menulis blok cache itu dan menyalin saiz semasa fail kembali ke dalam entri direktorinya. Sebelum itu berlaku, direktori masih merekodkan saiz lama, jadi bait yang secara fizikal sudah sampai ke kad duduk di luar apa yang fail itu akui sebagai kandungannya.
Flush selepas setiap sampel pula ialah kesilapan yang sebaliknya. Setiap flush ialah dua kali tulis — blok data dan entri direktori — ditambah waktu tersekat sementara kad mengesahkannya, sedangkan sel flash cuma ada bilangan kitaran padam yang terhad untuk diagihkan oleh pengawalnya. Pilih satu kadar: sketch ini flush pada setiap sampel ke-12, iaitu sekali seminit pada jarak lima saat, jadi kuasa yang terputus paling banyak merugikan seminit bacaan dan larian sehari suntuk memakan 1,440 flush dan bukan 17,280.
Cabut wayar USB dahulu sebelum mengeluarkan kad — mencabut kad semasa ia masih hidup ialah jalan klasik ke arah sistem fail yang rosak. TEMPLOG.CSV ialah teks biasa, jadi mana-mana spreadsheet boleh mencartakannya, dan FILE_WRITE menambah di hujung: kali seterusnya board dihidupkan ia menyambung fail yang sama, bukan menulis gantinya.

Kenapa setiap baris bercop 01/01/2000?
DS1307 bukan sekadar hidup dengan masa yang salah — ia hidup dalam keadaan terhenti. Datasheetnya menyatakan bahawa pada pemberian kuasa yang pertama, registernya direset kepada 01/01/00 dan bit CH dalam register saat ditetapkan kepada 1 — dan CH yang ditetapkan bermakna oscillator terhenti. Sel sandaran itulah yang menghalang “pemberian kuasa yang pertama” daripada berulang setiap kali board dihidupkan, jadi pemegang yang kosong menghidupkan semula jam itu dalam keadaan terhenti setiap kali dan setiap baris pula membawa tarikh beku yang sama. Datasheet itu turut menyatakan VBAT mesti disambung ke ground di mana tiada bekalan sandaran digunakan, sedangkan pemegang yang kosong membiarkan pin itu terapung — satu lagi sebab untuk memasang sel tersebut.

Sketch ini mendedahkan hal itu. rtc.isrunning() membaca tepat bit CH tadi, dan pada jam yang terhenti sketch akan menghidupkannya dan menetapkannya daripada __DATE__ dan __TIME__ — makro yang memegang saat sketch itu dikompil. Tanpa sel, itulah siling yang jujur: selang masa kekal sempurna, tetapi tarikh mutlak direset kepada masa kompil setiap kali dihidupkan. Memasang sel kemudian pula ialah perangkapnya — jam sudah pun berjalan ketika itu, jadi blok tadi tidak akan berjalan lagi dan setiap baris membawa masa kompil yang basi. Pasang sel sebelum upload pertama, atau alihkan rtc.adjust() ke atas ujian isrunning() untuk satu upload.
Pasang CR1220 dan jam itu terus berjalan menembusi gangguan bekalan kuasa. Ia tetap hanyut, kerana DS1307 mengira kristal 32.768 kHz biasa tanpa pampasan suhu sedangkan frekuensi kristal berubah mengikut suhu — logger di dalam ruang bumbung yang panas hanyut lebih laju daripada yang duduk di atas meja. Kalau cop masa masih perlu betul enam bulan kemudian, DS3231 dalam panduan jam digital kami meletakkan kristal dan termometer di dalam chip itu sendiri.
Kesilapan biasa yang kami nampak
Kad microSD yang tidak muat. Soketnya SD saiz penuh dengan spring eject, bukan microSD. Adapter saiz penuh yang biasa menyelesaikannya — formatkan kad kepada FAT32 dan kekalkan pada 32 GB atau ke bawah.
Fail yang wujud tetapi kosong, atau terhenti di tengah baris. Buffer yang belum di-flush, bukan kerosakan: kuasa terputus semasa satu blok masih di dalam RAM. Flush lebih kerap, atau berikan logger itu satu cara berhenti yang disengajakan — sebuah butang atau satu arahan Serial yang memanggil close() — dan putuskan kuasa hanya selepas itu. Mencabut sensor tidak akan menyelamatkannya: itu cuma menghentikan baris baharu, sedangkan yang sudah tersimpan dalam buffer masih berada di dalam RAM. Selagi cara berhenti itu belum ada, kadar flush yang anda pilih itulah tingkap kerugian anda.
Setiap baris bertarikh 01/01/2000. Pemegangnya kosong dan DS1307 hidup semula dalam keadaan terhenti. Pasang CR1220, atau rekodkan milisaat yang berlalu dalam lajur kedua dan terima asas masa yang direset setiap kali.
-127.00, atau 85.00 yang tersekat. Kedua-duanya menunjuk kepada talian 1-Wire, bukan kepada sensornya. Periksa sama ada perintang itu betul-betul merentasi lajur kuning ke lajur merah.
Soalan Lazim
Adakah Arduino Data Logging Shield menerima kad microSD?
Tidak — soketnya SD saiz penuh dengan spring eject. microSD di dalam adapter berfungsi dengan baik. Formatkan kepada FAT32 dan kekal pada 32 GB atau ke bawah: library SD Arduino membaca FAT16 dan FAT32 pada kad SD dan SDHC sahaja.
Kenapa fail dalam kad SD Arduino saya kosong sedangkan Serial menunjukkan bacaannya?
Library itu menyimpan satu blok 512 bait di dalam RAM dan hanya mengkomitnya bila blok itu penuh, bila flush() dipanggil, atau bila close() dipanggil. Output Serial tidak melalui buffer tersebut, jadi ia nampak sempurna sedangkan kad itu kosong.
Adakah data logging shield Arduino memerlukan bateri CR1220?
Bukan untuk merakam data. Tanpa CR1220, DS1307 hidup semula dalam keadaan terhenti pada 01/01/2000 setiap kali board dihidupkan, jadi sketch terpaksa menetapkan masa pada setiap boot. Bacaan dan selang masanya tidak terjejas.
Kenapa DS18B20 saya membaca -127 pada data logging shield Arduino?
Pin DQ padanya open-drain — ia boleh menarik talian ke rendah tetapi tidak boleh memacunya ke tinggi — jadi ia perlukan perintang 4.7 kΩ hingga 10 kΩ dari wayar kuning naik ke 5V. Tanpanya talian itu terapung dan library melaporkan -127.00, iaitu “tiada peranti menjawab”.
Kemas kini terakhir Ogos 2026. Tersangkut? Chat dengan kami di WhatsApp.



Arduino Uno Compatible SMD UNO R3 with Type B Cable - ATMEGA328P with CH340G-Microcontroller Project
Data Logging Shield Data Logger Module Data Recorder with Built in RTC For Arduino IOT Application
Temperature Sensor DS18B20 Temperature Measurement Probe WaterProof 18B20
MB102 Breadboard 170 400 830 Holes Breadboard Donut Board Arduino Prototype Multi Color - MINI BREADBOARD 170 HOLES (WHITE)
40pcs Dupont Wire 10cm 20cm 30cm for Breadboard DIY Experiment Jumper Wire Breadboard wire - DUPONT WIRE M-M 30CM
400 pcs 1/4W Resistor Pack Resistor Kit 20 Common Value with 20 each
XL830L Digital Multimeter with backlight Portable Multimeter Electronics Project