Пример использования EEPROM. Хранение настроек в arduino

Пример использования EEPROM в adruino

Не всегда есть возможность полностью отладить устройство и прошить с нужными настройками. Это может быть связано с разными факторами: иногда подстройка производится только после установки девайса, иногда просто со временем нужно внести корректировки в работу и т.д. Для таких случаев можно использовать подстроечные резисторы, но это не всегда удобно, например, если придется менять сразу десяток конфигураций. В таких случаях можно воспользоваться, встроенной в arduino, энергонезависимой памятью – EEPROM. Ей не страшно отсутствие питания или перезагрузки устройства, данные останутся в памяти.
Я как-то писал статью про подстроечный резистор и обещал продолжение. Пришло время сдержать обещание и немного расширить функционал из старой статьи.

Энергонезависимая память EEPROM и arduino

EEPROM – это запоминающее устройство, которое позволяет хранить данные десятки лет с отключенным питанием. Перезаписывать данные можно довольно много раз, но не бесконечно. В одних источниках пишут, что EEPROM позволяет осуществлять до нескольких миллионов циклов перезаписи, а где-то пишут, что не больше ста тысяч. В любом случае, этого количества с лихвой должно хватить, если использовать с умом.
Arduino уже имеет встроенную EEPROM и управлять ею очень просто. В зависимости от версии arduino, объем памяти отличается:
— Платы с микроконтроллерами ATmega8 и ATmega168 используют EEPROM с объемом памяти в 512 байт.
— Платы с ATmega328 используют EEPROM с объемом 1 кб
— Платы на ATmega1280 и ATmega2560 имеют EEPROM с объемом в 4 кб
Для хранения настроек и других не больших массивов данных, даже 512 байт будет достаточно. Но если вы решите хранить какие-то огромные значения, не помещающиеся даже в 4 кб, то всегда можно купить дополнительную микросхему EEPROM и подключить ее к arduino. Такие микросхемы способны хранить, куда больший объем, чем встроенные. Главное при выборе обращать внимание на совместимость с arduino и способность работать с 8-битным микроконтроллером. Например, можно использовать 24LC256.

Подстроечный резистор и EEPROM

Чтобы было понятней, как работает EEPROM и как ее использовать, попробуем реализовать небольшой пример. Подключим к ардуино подстроечный резистор, кнопку и пять светодиодов(не забыв про резисторы, чтобы не сжечь светодиоды). И напишем небольшой скетч: по нажатию на кнопку будем считывать значения с подстроечного резистора и конвертировать их в число от 0 до 4х. По повторному нажатию на кнопку, будем сохранять полученное значение в EEPROM. И уже в зависимости от записанного значения, зажжем соответствующее количество светодиодов. Если после перезагрузки или после отключения питания arduino, будет гореть нужное количество огоньков, значит все работает и эксперимент можно считать успешным.
Чтобы было понятней, ниже приведена схема подключения всех элементов.

Схема подключения

Скетч записи и чтения данных из EEPROM

Для работы EEPROM в arduino IDE уже есть встроенная библиотека EEPROM.h, ее и будем использовать. Вся память разбита на ячейки по 1 байту, соответственно в каждую ячейку можно записать не больше одного байта, если хранить целые числа, то можно записывать значения от 0 до 255 без сложностей. Этим мы и займемся в скетче – используем одну ячейку памяти и сначала сохраним в нее число от 0 до 4, а потом прочитаем содержимое.
Если вам необходимо хранить значения, превышающие размер в 1 байт, то их придется разбивать по байтам и записывать в разные ячейки по частям.
Обратите внимание: по умолчанию в пустой EEPROM в каждой ячейке хранятся значения 255. Но делать проверку на пустоту с помощью сравнения с числом 255 не стоит. Поскольку не всегда можно полагаться на заводские настройки. И перед использованием лучше прогнать все ячейки в цикле и записать в них свои значения для обнуления, чтобы быть полностью уверенным в содержимом.
Далее остается только привести скетч с подробными комментариями:

#include <EEPROM.h> // библиотека для работы с EEPROM

int pin_rezistor = A0;
int value = 0;
int count_leds = 0;

// пин светодиода
int ledPins[5] = {4, 5, 6, 7,8}; 
boolean editOn = false; // состояние светодиода

// пин кнопки
int btn_1 = 2; 
boolean lastBtn_1 = false; // предыдущее состояние кнопки
boolean currentBtn_1 = false; // текущее состояние кнопки

void setup() {  
  // режимы работы пинов
  pinMode(pin_rezistor, INPUT);
  pinMode (btn_1, INPUT);
  for(int i=0; i<=4; i++){
    pinMode (ledPins[i], OUTPUT);  
  }   
}

void loop() {
  if(editOn){
    value = analogRead(pin_rezistor); 
    count_leds = map(value, 0, 1000, 0, 4);
  }else{
    count_leds = EEPROM_int_read(0);
  }
  
  // получение состояния кнопки
  currentBtn_1 = isBtnStatus(lastBtn_1);
  // если кнопка была нажата 5 миллисекунд и более
  if (lastBtn_1 == false && currentBtn_1 == true) { 
    // меняем состояние светодиода
    editOn = !editOn; 
    // если выключился режим настройки
    if(!editOn){
      EEPROM.write(0, count_leds);
    }
  }
  // сохраняем состояние кнопки
  lastBtn_1 = currentBtn_1;

  // все гасим
  for(int i=0; i<=4; i++){
    digitalWrite(ledPins[i], LOW);  
  } 
  // включаем нужное количество
  for(int i=0; i<=count_leds; i++){
    digitalWrite(ledPins[i], HIGH);  
  }
  delay(50);
}

// функция для определения состояния кнопки
boolean isBtnStatus(boolean last) { 
  // считываем состояние кнопки
  boolean current = digitalRead(btn_1);
  // сравниваем текущее состояние кнопки со старым
  if (last != current) { 
    // ждем 5 миллисекунд
    delay(5);
    // считываем состояние кнопки еще раз
    current = digitalRead(btn_1);
  }
  // возвращаем состояние кнопки
  return current; 
}


// чтение
int EEPROM_int_read(int addr) {    
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}

// запись
void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
}
 

Послесловие

Я заказал себе в стране Великого Дракона десяток 24LC256, чтобы можно было поэкспериментировать с внешней EEPROM. Как посылка приедет и я «наиграюсь» с микросхемой, то постараюсь написать статью и поделиться опытом.

Рассказать друзьям:


Оценить:
(8 оценок, среднее: 5,00 из 5)

Пример использования EEPROM. Хранение настроек в arduino: 1 комментарий

  1. Почему всегда в примерах народ указывает нулевую ячейку памяти когда сам производитель рекомендует её использовать в крайних случаях? Примеры смотрят начинающие и надо им указывать на эти моменты.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

code