Как исправить нажатия кнопок, которые больше не записываются после 10-15 нажатий кнопок?
У меня есть Arduino Uno с 5 кнопками (со светодиодами), включенными параллельно друг другу. Моя цель состоит в том, чтобы они загорались при нажатии, а также записывали и отмечали время, какая кнопка нажата как таковая:
Blue,2023/2/28,18:29:5
Это отображается на последовательном мониторе и сохраняется в файле CSV на SD-карте (32 ГБ без свободного места на нем, так что это не проблема хранения). Моя проблема в том, что когда я запускаю это, он работает отлично, пока я не нажму примерно 10-12 кнопок. В этот момент кнопки все еще будут светиться, но нажатия кнопок не записываются на последовательный монитор Arduino или на SD-карту. Я понятия не имею, почему это так.
Есть ли что-то в моем коде, что вызывает это? Как это исправить? Будем признательны за любую помощь!
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>
RTC_DS3231 rtc; // Модуль часов реального времени
File dataFile;
// Значения светодиодов
int LEDValuesL[] = {LOW, LOW, LOW, LOW, LOW}; //
int LEDValues[] = {0,0,0,0,0}; //
// Состояние светодиодов и кнопок
int LEDStates[] = {LOW,LOW,LOW,LOW,LOW}; //
int ButtonStates[] = {0, 0, 0, 0, 0}; //
int lastButtonStates[] = {LOW, LOW, LOW, LOW, LOW}; //
// Контакты светодиода и кнопки
int buttonPins[] = {4, 2, A2, 8, 6}; // Кнопки чтения: Зеленая, Синяя, Белая, Желтая, Красная
int LEDPins[] = {5, 3, A3, 9, 7}; // Светодиоды управления: зеленый, синий, белый, желтый, красный
char *Colors_Array[] = {"Green,", "Blue,", "White,", "Yellow,", "Red,"} ;
int CS = 10; // Контакт модуля карты MicroSD
unsigned long lastDebounceTime = 0; // последний раз, когда выходной пин был переключен
unsigned long debounceDelay = 20; // время устранения дребезга; увеличить, если выход мерцает
void setup() {
Serial.begin(9600); // 9600 бит в секунду
Wire.begin();
rtc.begin();
SD.begin(CS);
if(!SD.begin(CS)){ // Инициализация SD-карты
Serial.print ("Could Not Initialize SD Card ");
// если возвращаемое значение ложно, что-то пошло не так
}
if (SD.exists("datafile.csv")) { // Если этот файл существует на SD-карте, удалите его
Serial.println("File exists.");
if (SD.remove("datafile.csv") == true ) {
Serial.println("Successfully removed file.");
} else{
Serial.println("Could not remove file");
}}
for (int i = 0; i<5 ; i++) {
pinMode(buttonPins[i], INPUT); // кнопки - это входы
pinMode(LEDPins[i], OUTPUT); // светодиоды - это выходы
}
dataFile.close();
for (int i = 0; i<5 ; i++) {
digitalWrite(LEDPins[i], LEDStates[i]); // Все светодиоды установлены на НИЗКИЙ уровень
}
dataFile = SD.open("datafile.csv", FILE_WRITE);
if (dataFile){
dataFile.println("Stress,Date,Time");
dataFile.close();
}
}
void loop() {
for (int i = 0; i<5 ; i++) {
int reading = digitalRead(buttonPins[i]); // чтение пинов
if (reading != lastButtonStates[i]) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != ButtonStates[i]) {
ButtonStates[i] = reading;
LEDStates[i] = reading;
}
}
digitalWrite(LEDPins[i], LEDStates[i]);
lastButtonStates[i] = reading;
String dataString = ""; // Инициализируем строку, которая будет использоваться в качестве вывода
DateTime now = rtc.now(); LEDValues[i] = digitalRead(LEDPins[i]);
if (LEDValues[i] != LEDValuesL[i]) {
if (LEDValues[i] == HIGH) {
String year = String(now.year(), DEC);
String month = String(now.month(), DEC);
String day = String(now.day(), DEC);
String hour = String(now.hour(), DEC);
String min = String(now.minute(), DEC);
String sec = String(now.second(), DEC);
// Помещаем все строки даты и времени в одну строку
dataFile = SD.open("datafile.csv", FILE_WRITE);
if ((millis() - lastDebounceTime) > debounceDelay) {
if (dataFile){
String data = String(Colors_Array[i] + year + "/" + month +
"/" + day + "," + hour + ":" + min + ":" + sec);
Serial.println(data);
dataFile.println(data);
dataFile.close();
}}}}
delay(20);
}}
@IWahab7, 👍0
Обсуждение1 ответ
С чего начать?
Начнем с самого "оскорбительного" строки кода. Все они начинаются с одного и того же ключевого слова: String
.
Когда я удаляю код Модуля часов реального времени из вашего скетча и вставляю жестко закодированные значения для отсутствующих данных RTC, например, String year = String(2023, DEC);
, в окне сообщений Arduino IDE, использующем версию IDE 1.8.9 на OSX, говорится:
Глобальные переменные используют 1278 байт (62%) динамической памяти, оставляя 770 байт для локальных переменных. Максимум 2048 байт.
Когда UNO достигает 75% использования динамической памяти, вы можете получить следующее сообщение:
Недостаточно доступной памяти, могут возникнуть проблемы со стабильностью.
После того как вы добавите свой код RTC, я могу представить, что ваше использование динамической памяти превысит отметку 75%.
Вам не нужно создавать новую
строку
для записи данных на SD-карту. Вы можете просто писать/печатать данные, как хотите, затем не забудьте закрыть файл. Например:
dataFile.print(F("Writing millis()="));
dataFile.println(millis());
dataFile.close();
У вас есть дополнительный dataFile.close();
в настройках.
Вот 2 скетча, которые выводят одно и то же сообщение на последовательный монитор, но их место для хранения программ и динамическая память меньше, используя char< массив /code> против объекта
String
.
// Использование объекта String.
// Sketch использует 2844 байта (8%) пространства для хранения программ.
// Глобальные переменные используют 214 байт (10%) динамической памяти
String TestStringString = "TestString";
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.println(TestStringString);
}
VS
// Использование символьной строки.
// Sketch использует 1504 байта (4%) места для хранения программы.
// Глобальные переменные используют 198 байт (9%) динамической памяти
char TestCharString[10 + 1] = "TestString";
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.println(TestCharString);
}
Обратите внимание, что вы можете написать `char TestCharString[] = "TestString"; и позволить компилятору считать байты., @Edgar Bonet
- Определение того, была ли нажата и отпущена кнопка
- Хорошая кнопка debouncing/Библиотека StateChange
- Остановить мигание светодиодов
- Интеграция 2 кнопок для включения и выключения светодиода.
- Код Arduino для управления 4 светодиодами с 4 кнопок
- Нужен ли подтягивающий/понижающий резистор для цепи светодиода кнопки?
- Как прервать функцию цикла и перезапустить ее?
- Как перезапустить счетчик в программе с помощью кнопки в настройке LDR Tripwire
отлаживать код... тестировать каждый участок кода отдельно, @jsotola
}}}}
выделяется как больной палец... этого не должно быть видно ни в одном коде C++, особенно в коде, написанном новичком... это указывает на то, что код неправильно отформатирован, и в результате , склонный к ошибкам программирования... на самом деле ваш код беспорядочный, @jsotolaсделайте себе большое одолжение и избавьте себя от множества проблем, постоянно поддерживая правильный формат кода... это значительно облегчит отслеживание хода программы и снизит вероятность добавления строк кода не в том месте место, @jsotola
Используете ли вы внешние подтягивающие/подтягивающие резисторы на контактах кнопок? Вы также интенсивно используете класс String, что может привести к нестабильности., @6v6gt
вы делаете
SD.begin(CS);
два раза подряд... может это на что-то влияет... у меня нет возможности проверить, @jsotolaНа скольких форумах вы это публиковали?, @Gil