Помогите срочно. зависает плата и запись на sd
- Войдите на сайт для отправки комментариев
Сб, 28/11/2020 - 12:27
Добрый день.
Плата должна включать/отключать нагреватель в зависимости от температуры. А также параллельно записывать ЛОГ файл на СД карту.
Проблема - спустя 1,5-2 часа работы плата полностью встает, либо начинает записывать какую то ерунду на СД карту. В чем может быть проблема.
Код прикладываю.
И господа, заранее спасибо.
Arduino mega
BME-280
Sd card logger - модель не помню. Сейчас не под рукой
#include "pin_map.h"
#include "settings.h"
// библиотека для работы I²C
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <TimerOne.h>
// библиотека для работы с метеосенсором
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// создаём объект для работы с датчиком в камере
Adafruit_BME280 bme;
// Переменные для хранения метеоданных
volatile float pressure = 0;
volatile float temperature = 0;
volatile float humidity = 0;
unsigned long timestampTelemetryWrite = 0;
//переменные для диода
boolean InitSD;
boolean InitMeteo;
void writeSD(String str)
{
File logFile = SD.open("log1.txt", FILE_WRITE);
// if the file is available, write to it:
if (logFile)
{
logFile.println(String(millis()) + ":::" + " "+ str);
logFile.close();
Serial.println("Write to log1.txt---OK");
InitSD = true;
}
// if the file isn't open, pop up an error:
else
{
Serial.println("error opening log1.txt");
InitSD = false;
}
}
void initMeteoSensor()
{
// печатаем сообщение об успешной инициализации Serial-порта
Serial.println("Meteo begin init...");
writeSD("Meteo begin init...");
// начало работы с датчиком
unsigned status;
status = bme.begin(0x76);
if (!status)
{
Serial.println("Meteo Sensor init FAIL");
writeSD("Meteo Sensor init FAIL");
InitMeteo = false;
}
else
{
Serial.println("Meteo Sensor init OK");
writeSD("Meteo Sensor init OK");
InitMeteo = true;
}
}
void updateSensorData()
{
pressure = bme.readPressure() / 100.0f;
temperature = bme.readTemperature();
humidity = bme.readHumidity();
}
void warmControl()
{
Serial.println("Temperature in camera:" + String(temperature));
writeSD("Temperature in camera:" + String(temperature));
// Если температура ниже минимальной
if (temperature < TEMPERATURE_IN_CAMERA_MIN)
{
// то включаем подогрев
digitalWrite(WARM_CONTROL_PIN, ON);
Serial.println("Warm is ON");
Serial.println("Write WARM_CONTROL_PIN = " + String(ON));
writeSD("Warm is ON");
}
// Если больше максимальной
else if (temperature > TEMPERATURE_IN_CAMERA_MAX)
{
// То выключаем подогрев
digitalWrite(WARM_CONTROL_PIN, OFF);
Serial.println("Warm is OFF");
Serial.println("Write WARM_CONTROL_PIN = " + String(OFF));
writeSD("Warm is OFF");
}
else
{
/* code */
}
if (millis() - timestampTelemetryWrite > TELEMETRY_DELAY_MS)
{
Serial.println("Telemetry Write Start");
writeSD("Telemetry Write Start");
String result = "";
result += String(millis()/60000);
result += ":min";
result += ":::";
result += " TemperatureInCamera = " + String(temperature) + " ";
result += " PressureInCamera = " + String(pressure) + " ";
result += " HumidityInCamera = " + String(humidity) + " ";
result += "\n";
Serial.println(result);
File dataFile = SD.open("datalog1.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile)
{
dataFile.println(result);
dataFile.close();
Serial.println("Write to datalog1.txt---OK");
}
// if the file isn't open, pop up an error:
else
{
Serial.println("error opening datalog1.txt");
}
timestampTelemetryWrite = millis();
Serial.println("Telemetry Write End");
writeSD("Telemetry Write End");
}
}
void setup()
{
Serial.begin(115200);
// Init Sensor
initMeteoSensor();
if (!SD.begin(SD_CARD_ENABLE_PIN))
{
Serial.println("Card failed, or not present");
// don't do anything more:
}
Serial.println("card initialized.");
// Настройка пина управления подогревателем
pinMode(WARM_CONTROL_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
}
void loop()
{
static unsigned long timestampSensorUpdate = 0;
static unsigned long warmControlTimestamp = 0;
if (millis() - warmControlTimestamp > 1000)
{
// контроль температуры в барокамере
//Serial.println("warmControl");
//writeSD("warmControl");
warmControl();
warmControlTimestamp = millis();
}
if (millis() - timestampSensorUpdate > 1000)
{
updateSensorData();
timestampSensorUpdate = millis();
}
if (InitSD and InitMeteo)
{
digitalWrite(LED_PIN, HIGH);
}
else
{
digitalWrite(LED_PIN, LOW);
}
}
Код вроде норм, так что скорее всего некачественная сборка.
Я бы воткнул промер по RAM. Не доверяю этим стрингам ))
Можете поподробнее пожалуйста)
А что пишет в Serial, когда "начинает записывать какую то ерунду на СД карту."
Должно быть так:
"127:min::: TemperatureInCamera = 20.37 PressureInCamera = 1002.37 HumidityInCamera = 14.93 "
Прошлые записи за работу все такие.
А последняя (извините за объем):
Например, https://github.com/maniacbug/MemoryFree/tree/master/examples/FreeMemory
Если будет видно, что Free memory монотонно уменьшается, то искать где течет.
Готов поспорить, что это выход за пределы какого нибудь массива.
Вот почему переменные в строках 20-22 volatile ? Так было в каком то примере ?
До какого размера у вас "раздувается" логфайл ? Как часто вы в него пишете ?
Ранее использовалось прерывание. Потом убрал его. Признак volatile остался.
Пишу в файл раз в секунду
Какого размера получается файл на момент ошибки ?
А 172 строка у вас си превратился в паскаль ? :)
Должно быть так:
"127:min::: TemperatureInCamera = 20.37 PressureInCamera = 1002.37 HumidityInCamera = 14.93 "
Прошлые записи за работу все такие.
А последняя (извините за объем):
Я спрашивал, что пишет в Serial. А вы отвеnили - что пишет на SD.
В монитор порта записи не идут.Т к предполагаю, что плата зависает
Примерно 2кб.
А что не так со строкой?
Сами не видите ?!
if(InitSD and InitMeteo)and - 'это у вас ЧТО ?
brokly, так тоже можно писать. And, not, or задефайнены, сам иногда пользуюсь, для читабельности.
Но там, где нужны именно логические операции, не битовые. В паскале оне, с.ка, не отличаюца. Вирту кол в ж.пу за это. :-)
А где они задефайнены ? И самое главное НАКУА !?
От жеж блин, не знал !
Виима, тот, кто задефайнил, вырос из Turbo Pascal.
А где, я нинаю. Работает искаропки, спицально ничо подключать не надо. :-)
c:\Program Files (x86)\Arduino\hardware\tools\avr\lib\gcc\avr\7.3.0\include\iso646.h
Собственно, этот файл только это и содержит ))
Фига себе, это еще и стандарт ! Совсем я старый стал :(
Посмотрел что это такое - принят 25 лет назад - заголовочный файл, являющийся частью стандартной библиотеки языка Си. Вон оно чё! А мужики то и не знают :-(
Ну дык я и говорю... Теперь даже и не знаю, если на собеседовании спросят есть ли в си оператор "and" чего отвечать то ?
Отвечай "иногда".
Теперь придется :)
UPD: Это сделали для тех у кого нет символов & | ^ и других в раскладке. Для китайцев что ли :) ?
Господа, всем огромное спасибо за ответы. Помогли!
Дело было в volatile переменных. За подсказку огромное спасибо brokly
Господа, всем огромное спасибо за ответы. Помогли!
Дело было в volatile переменных. За подсказку огромное спасибо brokly
Если честно, то странно :(
Как только убрал данный тип из кода - все стало стабильно)