Работа с устройствами хранения данных МК.
Практическое занятие №7
Цель работы
Целью практического занятия является получение практических навыков работы со средой моделирования и разработки микроконтроллерных модулей цифровых платформ.
Теоретическая часть
Хранение данных на карте памяти в среде Arduino
В данном задании будет использоваться модуль с интерфейсом подключения карты памяти SD (microSD). Это один из наиболее удобных и доступных способов записывать данные с микроконтроллера и затем считывать их компьютером.
Интерфейс SPI
Для подключения карты памяти используется интерфейс SPI - Serial Peripherial Interface. Интерфейс содержит тактовый сигнал SCL (Serial Clock), сигналы MOSI (Master Output Slave Input) и MISO (Master Input Slave Output), используемые соответственно для тактирования шины SPI и передачи данных с головного на ведомое устройство и обратно. Для установления роли в интерфейсе применяется сигнал SS (Slave Select, иногда CS - Chip Select).

Рисунок 1 – Подключение карты памяти к пинам SPI Arduino
Файловая система
При запуске симуляции Wokwi эмулирует карту памяти с файловой системой FAT16 и добавляет туда все файлы, имеющиеся в проекте. Wokwi. К примеру, Wokwi добавляет файл wokwi.txt с текстом
Hello, SD Card!
Этот файл мы и будем использовать для прототипирования.
Пример работы с библиотекой SD
Инициализация карты памяти микроконтроллером осуществляется через подключение библиотеки SD.h и команду SD.begin(int CS_PIN).
#include <SD.h> //подключение библиотеки
#define CS_PIN 10 //задание пина CS
void setup() {
if (!SD.begin(CS_PIN)) {
Serial.println("Card initialization failed!");
}
else {
Serial.println("Card initialization OK");
}
}
Далее используем встроенный в библиотеку обработчик File, через который происходит обращение к файлам на карте памяти. С его помощью открываются и закрываются файлы, а также меняется их содержимое. Подробнее в примерах ниже.
File wokwi_txt;
void loop() {
wokwi_txt = SD.open("wokwi.txt");
while (wokwi_txt.available()) {
Serial.write(wokwi_txt.read());
}
wokwi_txt.close();
...
}
Отметим, что в указанных примерах приведена лишь часть кода, отвечающая за определенные функции.
Чтение с карты памяти осуществляется с помощью команды File.read() в цикле.
File wokwi_txt;
void loop() {
wokwi_txt = SD.open("wokwi.txt", FILE_WRITE);
wokwi_txt.println("Line 1");
wokwi_txt.println("Line 2");
wokwi_txt.println("Line 3");
wokwi_txt.println("Line 4");
wokwi_txt.close();
...
}
Для записи в файл используются функции print и println. В целом эти функции сопоставимы с функциями работы с последовательным портом.
Пример проекта устройства измерения параметров с картой памяти
В проекте используется карта памяти и модуль RTC. Каждую секунду на карту памяти производится запись текущего времени и порядкового номера записи counter.
Каждые 10 секунд отображается текущее содержание файла wokwi.txt, чтобы в процессе отладки наблюдать корректность выполнения программы.

Рисунок 2 – Схема соединений в проекте
#include <SD.h> //подключение библиотеки карты памяти
#include "RTClib.h" //подключение библиотеки RTC
#define CS_PIN 10
File wokwi_txt; //обработчик для файловой системы
RTC_DS1307 rtc; //обработчик для модуля RTC
void setup() {
Serial.begin(115200);
Serial.println("Initializing SD card... ");
if (!SD.begin(CS_PIN)) { //проверяем, что подключена карта памяти
Serial.println("Card initialization failed!");
}
else {
Serial.println("Card initialization OK;");
}
if (!rtc.begin()) { //проверяем, что подключен RTC
Serial.println("RTC initialization failed!");
}
else {
Serial.println("RTC initialization OK");
}
}
int last_second = 0; //последняя секунда, в которую была произведена запись
int counter = 0; //счетчик прошедших записей в файл
void loop() {
DateTime now = rtc.now();
if (now.second() != last_second) { //прошло больше секунды
last_second = now.second();
counter++;
//производим запись в файл
wokwi_txt = SD.open("wokwi.txt", FILE_WRITE);
wokwi_txt.print(now.timestamp(DateTime::TIMESTAMP_FULL));
wokwi_txt.print("\t");
wokwi_txt.println(counter);
wokwi_txt.close();
//запись в формате "2023-12-31T23:59:59 21\n"
//для проверки результата каждую десятую запись выводим содержание файла wokwi_txt
if (counter % 10 == 0) {
Serial.println("!!! wokwi.txt file:");
wokwi_txt = SD.open("wokwi.txt");
while (wokwi_txt.available()) {
Serial.write(wokwi_txt.read());
}
wokwi_txt.close();
}
}
}
Содержание файла libraries.txt:
# Automatically added based on includes:
SD
RTClib
# ---
Содержание файла diagram.json:
{
"version": 1,
"author": "Uri Shaked",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-arduino-uno", "id": "uno", "top": 71.32, "left": -100.01, "attrs": {} },
{
"type": "wokwi-microsd-card",
"id": "sd1",
"top": -55.03,
"left": -12.53,
"rotate": 90,
"attrs": {}
},
{ "type": "wokwi-ds1307", "id": "rtc1", "top": 301.8, "left": 182.5, "attrs": {} }
],
"connections": [
[ "sd1:SCK", "uno:13", "green", [ "v18", "h-31" ] ],
[ "sd1:GND", "uno:GND.1", "black", [ "v21", "h-48" ] ],
[ "sd1:DO", "uno:12", "green", [ "v24", "h-42" ] ],
[ "sd1:DI", "uno:11", "green", [ "v14", "h6" ] ],
[ "sd1:CS", "uno:10", "green", [ "v7", "h21" ] ],
[ "uno:5V", "sd1:VCC", "red", [ "v11", "h-89", "v-220", "h79" ] ],
[ "rtc1:5V", "uno:5V", "red", [ "h0" ] ],
[ "rtc1:GND", "uno:GND.2", "black", [ "h0" ] ],
[ "rtc1:SDA", "uno:A4", "green", [ "h0" ] ],
[ "rtc1:SCL", "uno:A5", "green", [ "h0" ] ]
],
"dependencies": {}
}
Индивидуальное задание
Используя полученную информацию, создайте проект, в котором каждую секунду производится запись в файл показаний датчика по варианту.
Вариант выполнения задания определяется остатком от деления номера студента внутри списка группы на 3.
| Вариант | 0 | 1 | 2 |
|---|---|---|---|
| Датчик | NTC | DS18B20 | DHT22 |
Требования к оформлению отчёта
Отчет оформляется в виде файла в формате Microsoft Word. Скриншоты добавляются в файл отчета с необходимыми пояснениями.
Требования к оформлению отчета в формате Microsoft Word: * пользуйтесь правилами оформления лабораторных работ; * при написании кода используйте стили программирования (делайте код удобным для прочтения).
Требования к наименованию файлов отчета: * файл отчета именуется «ЛабХХФамилияИООтчет.doc», где ХХ – двухзначный номер лабораторной работы, например, 02; ФамилияИО – фамилия и инициалы студента, например, ИвановИИ. Пример наименования файла отчета для третьей лабораторной работы выполненной Ивановым И.И. – «Лаб03ИвановИИ.doc»; * дополнительные файлы именуются аналогичным образом, но с указанием, что это на отчет, приложение к нему с добавлением номера приложения «ЛабХХФамилияИОПриложениеYY.doc», где YY – двухзначный номер приложения. Например, для второго приложения наименование, будет следующее «Лаб03ИвановИИПриложение02.doc»; Все отчетные материалы загружаются в домашние работы ОРИОКС.
Список рекомендуемой литературы
- https://docs.wokwi.com/parts/wokwi-arduino-uno - Общие сведения о плате Arduino Uno
- https://docs.arduino.cc/learn/programming/sd-guide#examples - Примеры кода для взаимодействия с картой памяти с библиотекой
SD - https://wokwi.com/projects/310692660849410626 - пример wokwi с другой библиотекой
SdFat, который позволяет посмотреть содержание файловой системы FAT16 на карте памяти в симуляторе - https://docs.wokwi.com/parts/wokwi-ds1307 - Работа модуля RTC в среде Wokwi