Рассчитать статистику в EEPROM

Я искал, как выполнять статистические вычисления в EEPROM, но не по теме. Данные, которые я сохранил в EEPROM, — это температура тела. В настоящее время я сохранил данные, используя float.

Ниже мой код для хранилища данных в eeprom. Я застрял в функции void с именем «printTemp». Я знаю, как вычислить среднее значение в массиве, используя оператор цикла for, но не EEPROM. Из среднего/среднего я могу найти стандартное отклонение.

Есть ли у кого-нибудь идеи о том, как мы можем сделать расчет, используя данные из EEPROM?

#define LM35 A1
#define READSAMPLES 100

float bt;
int buttonPin1 = D5;     // номер вывода кнопки 1 MEASURE
int buttonPin2 = D6;     // номер вывода кнопки 2 RESET CYCLE
int buttonState = 0;         // переменная для чтения статуса кнопки
int ButtonState = 0;         // переменная для чтения статуса кнопки
int address = 0;      //счетчик адресов EEPROM
int count, counT;
int sample[READSAMPLES];

void setup() {

    int contCount = EEPROM.get(5, count) / 10;

}

void loop() {

  buttonState = digitalRead(buttonPin1);
  ButtonState = digitalRead(buttonPin2);

  // проверяем, нажата ли кнопка.
  // если да, то состояние кнопки ВЫСОКОЕ:
  if (buttonState == LOW) { 
        Serial.println("Measuring your Body Temperature:");

        count = counting();
        counT = count / 10;
        Serial.print("Data count entering: ");
        Serial.println(counT);

        writeTemp(); 
  }

  if (ButtonState == LOW) {

        Serial.println("Update New Cycle of body temp..."); 
        printTemp();
        clearEEPROM();
        Particle.publish("DONE new Cycle");

  }

}


void printTemp()
{
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    float cel = EEPROM.read(i);                //читаем данные EEPROM по адресу i
    //Как найти СРЕДНЕЕ значение всех данных?
  }
}

void clearEEPROM()
{
  for (int i = 0 ; i < EEPROM.length() ; i++) {
    if(EEPROM.read(i) != 0)                     //пропустить уже "пустые" адреса
    {
      EEPROM.write(i, 0);                       //записываем 0 по адресу i
    }
  }
  Serial.println("EEPROM erased");
  address = 0;                                  //сброс счетчика адресов
}

void writeTemp()
{
  //получаем показания напряжения с датчика температуры
  int j;
  float average;
  for (j = 0; j < READSAMPLES; j++)
  {
    sample[j] = analogRead(LM35);        //читаем значение датчика
    delay(50);
  }

  average = 0;
  for (j = 0; j < READSAMPLES; j++)
  {
    average += sample[j];
  }
  average /= READSAMPLES;

  // float mv = (среднее / 4096,0) * 3300;
  // float cel = ( mv / 10 ) - 55.01;
  float mv = ( average / 1024.0) * 5000;
  float cel = ( mv / 10 );

  EEPROM.write(address, cel);         //записываем значение в адрес счетчика текущего адреса

  Serial.print("Sensor value stored at address ");
  Serial.println(address);

  address++;                      //увеличиваем адресный счетчик
  if(address == EEPROM.length())  //проверить, достиг ли счетчик адресов конца EEPROM
  {
    address = 0;              //если да: сброс счетчика адресов
  }
}

float counting()
{
  count = count + 10;   // плюс 10, чтобы дать место для ввода данных в eeprom для ПОСЛЕДНЕГО КОДА. Просто живи здесь.
    Particle.publish("Start Count =", String(count));
  return count;
}

Что я могу рассказать о своих проблемах, так это вычислить статистику из данных EEPROM;

  1. нам нужно знать, как считывать все данные из EEPROM. Как и в моем коде, я знаю, как читать данные, но данные не могут быть сохранены, потому что в цикле FOR R процесс будет выполняться до конца 'i'.
  2. нам нужно знать, сколько данных было введено в EEPROM. Чтобы решить эту проблему, я использую count; для подсчета вводимых данных.

Мне нужны ссылки для предложений или, может быть, любая идея о том, как делать статистику в EEPROM.

Спасибо.

, 👍1


2 ответа


Лучший ответ:

0

Выполнение этого вычисления из EEPROM точно такое же, как и из любого другого источника. У вас есть счет, чтобы вы знали, где заканчиваются данные EEPROM. Вы знаете, где начинаются данные EEPROM. Вы знаете, как прочитать число из EEPROM. Что мешает вам создать цикл for для чтения i-го адреса из EEPROM и сложения всех этих чисел вместе, как если бы вы делали это для массива?

for (int i = EEPROM_START; i < EEPROM_END; i++){
   sum = sum + EEPROM.read(i);
}
average = sum / count;

где EEPROM_START и EEPROM_END предоставляются вами, зная, с какого адреса вы начали и закончили запись.

,

0

В вашей программе довольно много проблем. Усреднение является лишь одним из их.

Вы писали:

В настоящее время я сохраняю данные с помощью float.

Нет. Вы сохранили 8-битные целые числа без знака (также известные как uint8_t).

int contCount = EEPROM.get(5, count) / 10;

Предполагая, что вы используете 8-битную плату Arduino, она считывает EEPROM. ячеек по адресам 5 и 6, объединяя эти два показания в одно 16-битное число со знаком и сохранение его в count. Учитывая, что эти EEPROM ячейки также используются для хранения показаний температуры, эта операция делает вообще никакого смысла. Кстати, строка выше также хранит копию нового обновил count в новую локальную переменную, которая немедленно получает отброшен. Это тоже не имеет смысла.

Позже вы написали:

for (int i = 0 ; i < EEPROM.length() ; i++) {
  if(EEPROM.read(i) != 0)  //пропустить уже "пустые" адреса
  {
    EEPROM.write(i, 0);    //записываем 0 по адресу i
  }
}

Существует метод EEPROM.update(), предназначенный для более простого выполнения этой задачи:

for (int i = 0 ; i < EEPROM.length() ; i++) {
  EEPROM.update(i, 0);  // записываем 0 по адресу i, если он уже не равен 0
}

Позже:

for (j = 0; j < READSAMPLES; j++)
{
  sample[j] = analogRead(LM35);        //читаем значение датчика
  delay(50);
}

Нет смысла хранить все показания в оперативной памяти только для того, чтобы вычислить средний. Вы можете избавиться от массива sample и вместо этого:

float average = 0;
for (int j = 0; j < READSAMPLES; j++)
{
  average += analogRead(LM35);  //читаем значение датчика
  delay(50);
}
average /= READSAMPLES;

Позже:

float cel = ( mv / 10 );
EEPROM.write(address, cel);
[...]
address++;

Возможно, это ваша самая большая проблема. Вы можете полагать, что храните плавает, но EEPROM.write() может только записывать байты. Таким образом, значение cel, представляющее собой напряжение в сантивольтах, неявно приводится к uint8_t. Это означает, что оно округляется до ближайшего целого числа ниже это, а затем завернуто по модулю 256. Вполне вероятно, что это не то, что вам нужно.

Если вы действительно хотите хранить числа с плавающей запятой, вам следует заменить последние два строки кода выше от

EEPROM.put(address, cel);
address += sizeof cel;

но учтите, что при чтении EEPROM вы также должны увеличить адрес в шагах sizeof(float).

,