ARDUINO Кто работал в wokwi?

Bird_Intern

✩✩✩✩✩✩✩
12 Июн 2023
1
0
Хочу реализовать систему логирования , когда человек пришел, а когда ушёл, с помощью часов реального времени DS1307, SD карты и кейпада. Если аутентификация прошла успешно - на флешку записывается Вася Пупкин пришёл в 9.00. Когда пользователь уходит, запись на флешку Вася Пупкин ушел в 9.10. Написал код с костылями начитавшись и накопировав с оф. сайта wokwi, так как не могу разобраться с флешкой в этом симуляторе. На ардуино мега все работает как мне надо, но нужно на ардуино уно.
Код для мега:
C++:
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
#include <Keypad.h>

// Пользователи и пароли
const int numUsers = 2;
const String users[numUsers] = {"Вася Пупкин", "Иван Иванов"};
const String passwords[numUsers] = {"1234", "5678"};

// Настройка кейпада
const byte numRows = 4;
const byte numCols = 4;
char keymap[numRows][numCols] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[numRows] = {13, 12, 11, 10};
byte colPins[numCols] = {9, 8, 7, 6};
Keypad keypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

// Настройка часов DS1307 и SD карты
RTC_DS1307 rtc;
const int chipSelect = 53;
File root;
#define CS_PIN 53

void setup() {
  Serial.begin(115200);

  Serial.print("Initializing SD card... ");

  if (!SD.begin(CS_PIN)) {
    Serial.println("Card initialization failed!");
    while (true);
  }

  Serial.println("initialization done.");

  Serial.println("Files in the card:");
  root = SD.open("/");
  printDirectory(root, 0);
  Serial.println("");

  // Example of reading file from the card:
  File textFile = SD.open("log.txt");
  if (textFile) {
    Serial.print("log.txt: ");
    while (textFile.available()) {
      Serial.write(textFile.read());
    }
    textFile.close();
  } else {
    Serial.println("error opening log.txt!");
  }

  // Инициализация часов DS1307
  if (!rtc.begin()) {
    Serial.println("Ошибка инициализации DS1307");
    while (1) {} // Останавливаем выполнение программы
  }

  if (!rtc.isrunning()) {
    Serial.println("Часы DS1307 не работают!");
  }
}

void loop() {
  String inputPassword = "";
  Serial.println("Введите пароль:");
  while (inputPassword.length() < 4) {
    char customKey = keypad.getKey();
    if (customKey) {
      inputPassword += customKey;
      Serial.print("*");
    }
  }

  int userIndex = -1;
  for (int i = 0; i < numUsers; i++) {
    if (inputPassword.equals(passwords[i])) {
      userIndex = i;
      break;
    }
  }

  if (userIndex >= 0) {
    DateTime now = rtc.now() + TimeSpan(0, 0, 0, 1); // Добавляем одну секунду
    String logMessage = users[userIndex] + " пришел в " + formatTime(now.hour()) + ":" + formatTime(now.minute()) + ":" + formatTime(now.second()); // Добавляем секунды
    logToFile(logMessage);
    Serial.println(logMessage);

    delay(10000); // Задержка для имитации времени работы (10 секунд)

    now = rtc.now() + TimeSpan(0, 0, 0, 1); // Добавляем одну секунду
    logMessage = users[userIndex] + " ушел в " + formatTime(now.hour()) + ":" + formatTime(now.minute()) + ":" + formatTime(now.second()); // Добавляем секунды
    logToFile(logMessage);
    Serial.println(logMessage);
  } else {
    Serial.println("Неверный пароль!");
  }

  delay(1000);
}

void logToFile(String logMessage) {
  File logFile = SD.open("log.txt", FILE_WRITE);
  if (logFile) {
    logFile.println(logMessage);
    logFile.close();
    Serial.println("Сообщение записано в файл");
  } else
{
Serial.println("Ошибка открытия файла");
}
}

String formatTime(int timeValue) {
if (timeValue < 10) {
return "0" + String(timeValue);
}
return String(timeValue);
}
void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}
При нажатии кнопки ресет выводит лог в сериал, например,
log.txt:
Вася Пупкин пришел в 22:46:00
Вася Пупкин ушел в 22:54:26
Иван Иванов пришел в 22:55:34
Иван Иванов ушел в 22:55:44

Код для уно
C++:
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
#include <Keypad.h>

// Пользователи и пароли
const int numUsers = 2;
const String users[numUsers] = {"Вася Пупкин", "Иван Иванов"};
const String passwords[numUsers] = {"1234", "5678"};

// Настройка кейпада
const byte numRows = 4;
const byte numCols = 4;
char keymap[numRows][numCols] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[numRows] = {9, 8, 7, 6};
byte colPins[numCols] = {5, 4, 3, 2};
Keypad keypad = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

// Настройка часов DS1307 и SD карты
RTC_DS1307 rtc;
const int chipSelect = 10;
File root;
#define CS_PIN 10

void setup() {
  Serial.begin(115200);

  Serial.print("Initializing SD card... ");

  if (!SD.begin(CS_PIN)) {
    Serial.println("Card initialization failed!");
    while (true);
  }

  Serial.println("initialization done.");

  Serial.println("Files in the card:");
  root = SD.open("/");
  printDirectory(root, 0);
  Serial.println("");

  // Example of reading file from the card:
  File textFile = SD.open("log.txt");
  if (textFile) {
    Serial.print("log.txt: ");
    while (textFile.available()) {
      Serial.write(textFile.read());
    }
    textFile.close();
  } else {
    Serial.println("error opening log.txt!");
  }

  // Инициализация часов DS1307
  if (!rtc.begin()) {
    Serial.println("Ошибка инициализации DS1307");
    while (1) {} // Останавливаем выполнение программы
  }

  if (!rtc.isrunning()) {
    Serial.println("Часы DS1307 не работают!");
  }
}

void loop() {
  String inputPassword = "";
  Serial.println("Введите пароль:");
  while (inputPassword.length() < 4) {
    char customKey = keypad.getKey();
    if (customKey) {
      inputPassword += customKey;
      Serial.print("*");
    }
  }

  int userIndex = -1;
  for (int i = 0; i < numUsers; i++) {
    if (inputPassword.equals(passwords[i])) {
      userIndex = i;
      break;
    }
  }

  if (userIndex >= 0) {
    DateTime now = rtc.now() + TimeSpan(0, 0, 0, 1); // Добавляем одну секунду
    String logMessage = users[userIndex] + " пришел в " + formatTime(now.hour()) + ":" + formatTime(now.minute()) + ":" + formatTime(now.second()); // Добавляем секунды
    logToFile(logMessage);
    Serial.println(logMessage);

    delay(10000); // Задержка для имитации времени работы

    now = rtc.now() + TimeSpan(0, 0, 0, 1);
    logMessage = users[userIndex] + " ушел в " + formatTime(now.hour()) + ":" + formatTime(now.minute()) + ":" + formatTime(now.second()); // Добавляем секунды
    logToFile(logMessage);
    Serial.println(logMessage);
  } else {
    Serial.println("Неверный пароль!");
  }

  delay(1000);
}

void logToFile(String logMessage) {
  File logFile = SD.open("log.txt", FILE_WRITE);
  if (logFile) {
    logFile.println(logMessage);
    logFile.close();
    Serial.println("Сообщение записано в файл");
  } else
{
Serial.println("Ошибка открытия файла");
}
}

String formatTime(int timeValue) {
if (timeValue < 10) {
return "0" + String(timeValue);
}
return String(timeValue);
}
void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}
Этот же выводит при проверке ошибку в сериал
error opening log.txt!
Так же сейчас почему-то и пароли называет неверными.
Надеюсь на понимание и помощь. Не ругайте сильно, маленький опыт в языках си,.
 

vortigont

★★★★★★✩
24 Апр 2020
1,022
541
Saint-Petersburg, Russia
Разницы в коде между мега и уно нет, только в пинах. Проверяйте разводку. И смотря какой СД модуль у вас, популярные HW203 работают от 3.3 вольт, уно обычно от 5, может капризнячать и глючить.
Попробуйте сначала завести скерч-пример для сд-карты, если заработает, потом уже писать свой код.