Своя первая Библиотека...

Otto
Offline
Зарегистрирован: 26.06.2016

Здраствуйте. Помогите с созданием своей первой библиотеки из рабочего кода.

Есть код:

#include <EEPROM.h>         // Библиотека для  энергонезависимой памяти 

#define EEPROM_SIZE 1024     // Размер EEPROM равный 1024 байтам (для Atmega328)
#define EEPROM_EMPTY 0xFF   // Начальный адрес в EEPROM (0xFF - В шестнадцатеричной системе == 255)
#define EEPROM_MARKER 0xFE  // Маркер для EEPROM (0xFE - В шестнадцатеричной системе == 254)

int addr = 0;   //первая ячейка памяти EEPROM (счёт начинается с нуля)
int L;          //переменная, через которую будут сохраняться нужные нам данные в EEPROM

void setup()
{
// тут другой код...

  bool init = true;   //создаём булево значение и делаем её ИСТИНА
  for (int i = 0; i < EEPROM_SIZE; i++)   //запускаем счётчик, если i < объёма EEPROM, тогда +1
  {
    if (EEPROM.read(i) == EEPROM_MARKER)  //считаем переменную i и сравниваем с Маркером, если ровна...
    {
      addr = (i - 1 + EEPROM_SIZE) % EEPROM_SIZE;  //отнимаем от i единицу и прибавляем EEPROM_SIZE(512) и остаток деления от EEPROM_SIZE
      init = false;   //меняем значение на ЛОЖ
      break;          //принудительно выходим из цикла for
    }
  }
  if (init) L = 0;    //если init ИСТИНА, присваиваем L ноль
  else L = EEPROM.read(addr);  //иначе, читаем addr-значение из ячейки памяти
}

void TransitionWrite()    //Функция записывает данные в 2 ячейки памяти, одна ячейка для Маркера, вторая для наших данных.
{
// тут другой код...
  int maddr = (addr + 1) % EEPROM_SIZE; //записываем в переменную maddr(МаркерАдрес) прибавленый addr с остатком деления от размера EEPROM
  EEPROM.write(maddr, EEPROM_MARKER);   //Записываем в maddr значения из Маркера
  EEPROM.update(addr, L);               //записываем обновлённые значения в через переменную L в ячейку addr (если они изменялись)
  addr++;                     //переходим на следующую ячейку памяти для записи
  if (addr >= EEPROM_SIZE)    //если addr >= размеру EEPROM
  {
    addr = 0;                 //переходим обратно в первую ячейку и опять по кругу...
  }
}

void loop() {
// какие то действия и другой код...

}

попытался перенести его в библиотеку и понимаю, что что то сделал не совсем так. Библиотека компилируется, но подставить в функции переменные в скетче для сохранения чЁто не получается.

заголовочный файл EEPROM_Transition.h

 // проверка, что библиотека еще не подключена
#ifndef EEPROM_Transition_h  // если библиотека EEPROM_Transition не подключена...
#define EEPROM_Transition_h  // тогда подключаем ее

#include "Arduino.h"		 // подключаем стандартные функции Arduino
#include "EEPROM.h"			 // подключаем библиотеку EEPROM (по умолчанию установлена в Arduino IDE)

#define EEPROM_SIZE 1024     // Размер EEPROM равный 1024 байтам (для Atmega328)
#define EEPROM_EMPTY 0xFF    // Начальный адрес в EEPROM (0xFF - В шестнадцатеричной системе == 255)
#define EEPROM_MARKER 0xFE   // Маркер для EEPROM (0xFE - В шестнадцатеричной системе == 254)


class EEPROM_Transition   	 // создаём класс под названием - EEPROM_Transition
{
	public:			// объявляем функции и переменные - общедоступными
	//EEPROM_Transition();
	void TransitionWrite();		// Функция запист размещается в любом месте кода, через неё будет происходить запись
	void TransitionRead();		// эта Функция должна выполняться 1 раз (отвечает за чтение данных из EEPROM при Вкл.), её надо поместить в void setup()
	
	private:		// объявляем переменные - внутренними
	int _L;			// через эту переменную будут записываться данные для сохранения в EEPROM
	int _addr = 0;	// начальный адрес ячейки EEPROM
};

#endif

файл с исходным кодом EEPROM_Transition.cpp

#include "Arduino.h"			//подключаем стандартные функции Arduino
#include "EEPROM_Transition.h"  //подключаем заголовочный файл
#include "EEPROM.h"			 	// подключаем библиотеку EEPROM (по умолчанию установлена в Arduino IDE)



void EEPROM_Transition :: TransitionWrite()  // Функция запист размещается в любом месте кода, через неё будет происходить запись
{
	  int maddr = (_addr + 1) % EEPROM_SIZE; //записываем в переменную maddr(МаркерАдрес) прибавленый _addr с остатком деления от размера EEPROM
  EEPROM.write(maddr, EEPROM_MARKER);   	 //Записываем в maddr значения из Маркера
  EEPROM.update(_addr, _L);                  //записываем обновлённые значения в через переменную _L в ячейку _addr (если они изменялись)
  _addr++;                     //переходим на следующую ячейку памяти для записи
  if (_addr >= EEPROM_SIZE)    //если _addr >= размеру EEPROM
  {
    _addr = 0;                 //переходим обратно в первую ячейку и опять по кругу...
  }
}


void EEPROM_Transition :: TransitionRead()	// эта Функция должна выполняться 1раз (отвечает за чтение данных из EEPROM при Вкл.), её надо поместить в void setup()
{
	  bool init = true;   //создаём булево значение и делаем её ИСТИНА
  for (int i = 0; i < EEPROM_SIZE; i++)   //запускаем счётчик, если i < объёма EEPROM, тогда +1
  {
    if (EEPROM.read(i) == EEPROM_MARKER)  //считаем переменную i и сравниваем с Маркером, если ровна...
    {
      _addr = (i - 1 + EEPROM_SIZE) % EEPROM_SIZE;  //отнимаем от i единицу и прибавляем EEPROM_SIZE и остаток деления от EEPROM_SIZE
      init = false;   //меняем значение на ЛОЖ
      break;          //принудительно выходим из цикла for
    }
  }
  if (init) _L = 0;    //если init ИСТИНА, присваиваем _L ноль
  else _L = EEPROM.read(_addr);  //иначе, читаем _addr-значение из ячейки памяти
}

где я сделал не так?

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Классу нужен конструктор.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Otto пишет:

 но подставить в функции переменные в скетче для сохранения чЁто не получается.

Так параметры функциям добавьте.

Otto
Offline
Зарегистрирован: 26.06.2016

Конструктор создал, а параметры функциям добаветь не понимаю как.

EEPROM_Transition.h

// проверка, что библиотека еще не подключена
#ifndef EEPROM_Transition_h  // если библиотека EEPROM_Transition не подключена...
#define EEPROM_Transition_h  // тогда подключаем ее

#include "Arduino.h"		 // подключаем стандартные функции Arduino
#include "EEPROM.h"			 // подключаем библиотеку EEPROM (по умолчанию установлена в Arduino IDE)

#define EEPROM_SIZE 1024     // Размер EEPROM равный 1024 байтам (для Atmega328)
#define EEPROM_EMPTY 0xFF    // Начальный адрес в EEPROM (0xFF - В шестнадцатеричной системе == 255)
#define EEPROM_MARKER 0xFE   // Маркер для EEPROM (0xFE - В шестнадцатеричной системе == 254)


class EEPROM_Transition   	 // создаём класс под названием - EEPROM_Transition
{
	public:			// объявляем функции и переменные - общедоступными
	EEPROM_Transition(int dannye, int yaceika); 	// Конструктор класса
	void TransitionWrite();		// Функция запист размещается в любом месте кода, через неё будет происходить запись
	void TransitionRead();		// эта Функция должна выполняться 1 раз (отвечает за чтение данных из EEPROM при Вкл.), её надо поместить в void setup()

	//private:		// объявляем переменные - внутренними
	int _L;			// через эту переменную будут записываться данные для сохранения в EEPROM
	int _addr = 0;	// начальный адрес ячейки EEPROM
};

#endif

EEPROM_Transition.cpp

#include "Arduino.h"			//подключаем стандартные функции Arduino
#include "EEPROM_Transition.h"  //подключаем заголовочный файл
#include "EEPROM.h"			 	// подключаем библиотеку EEPROM (по умолчанию установлена в Arduino IDE)

EEPROM_Transition :: EEPROM_Transition(int dannye, int yaceika)
{
	
	_L = dannye; 
	_addr = yaceika;
}


void EEPROM_Transition :: TransitionWrite()  // Функция запист размещается в любом месте кода, через неё будет происходить запись
{
	  int maddr = (_addr + 1) % EEPROM_SIZE; //записываем в переменную maddr(МаркерАдрес) прибавленый _addr с остатком деления от размера EEPROM
  EEPROM.write(maddr, EEPROM_MARKER);   	 //Записываем в maddr значения из Маркера
  EEPROM.update(_addr, _L);                  //записываем обновлённые значения в через переменную _L в ячейку _addr (если они изменялись)
  _addr++;                     //переходим на следующую ячейку памяти для записи
  if (_addr >= EEPROM_SIZE)    //если _addr >= размеру EEPROM
  {
    _addr = 0;                 //переходим обратно в первую ячейку и опять по кругу...
  }
}


void EEPROM_Transition :: TransitionRead()	// эта Функция должна выполняться 1раз (отвечает за чтение данных из EEPROM при Вкл.), её надо поместить в void setup()
{
	  bool init = true;   //создаём булево значение и делаем её ИСТИНА
  for (int i = 0; i < EEPROM_SIZE; i++)   //запускаем счётчик, если i < объёма EEPROM, тогда +1
  {
    if (EEPROM.read(i) == EEPROM_MARKER)  //считаем переменную i и сравниваем с Маркером, если ровна...
    {
      _addr = (i - 1 + EEPROM_SIZE) % EEPROM_SIZE;  //отнимаем от i единицу и прибавляем EEPROM_SIZE и остаток деления от EEPROM_SIZE
      init = false;   //меняем значение на ЛОЖ
      break;          //принудительно выходим из цикла for
    }
  }
  if (init) _L = 0;    //если init ИСТИНА, присваиваем _L ноль
  else _L = EEPROM.read(_addr);  //иначе, читаем _addr-значение из ячейки памяти
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, если Ва нужен класс для одной ячейки и неизменных данных, то всё у Вас нормально. 

А про параметры, ну конструктору же Вы их передаёте, так почему не можете методам передавать?

Otto
Offline
Зарегистрирован: 26.06.2016

Этот код позволяет сохранять в EEPROM данные и после сброса питания продолжает сохранять и дальше в следующие ячейки и читать данные с последней сохранённой ячейки. Это то, о чём писал в предыдущей теме (Ссылка: http://arduino.ru/forum/obshchii/chtenie-s-poslednei-zapolnennoi-yacheiki-eeprom).... Только теперь нужно оформить в библиотеку для дальнейших проектов, что бы примерно вот так выглядело:

#include <EEPROM_Transition.h>

int L;        //переменная которая будет сохраняться
int addr = 0; //начальный адрес EEPROM
EEPROM_Transition transition; 

void setup() {
transition.TransitionRead(addr, L); //читаем данные с последней ячейки и продолжаем писать дальше
}

void loop() {
    //какой то код
transition.TransitionWrite(addr, L); //записываем новые значения 

//.....
}

Попробовал так сделать, работает не стабильно....

EEPROM_Transition.h

 // проверка, что библиотека еще не подключена
#ifndef EEPROM_Transition_h  // если библиотека EEPROM_Transition не подключена...
#define EEPROM_Transition_h  // тогда подключаем ее

#include "Arduino.h"		 // подключаем стандартные функции Arduino
#include "EEPROM.h"			 // подключаем библиотеку EEPROM (по умолчанию установлена в Arduino IDE)

#define EEPROM_SIZE 1024     // Размер EEPROM равный 1024 байтам (для Atmega328)
#define EEPROM_EMPTY 0xFF    // Начальный адрес в EEPROM (0xFF - В шестнадцатеричной системе == 255)
#define EEPROM_MARKER 0xFE   // Маркер для EEPROM (0xFE - В шестнадцатеричной системе == 254)


class EEPROM_Transition   	 // создаём класс под названием - EEPROM_Transition
{
	public:			// объявляем функции и переменные - общедоступными
	EEPROM_Transition(int _addr, int _L); 	// Конструктор класса
	void TransitionWrite(int _addr, int _L);		// Функция запист размещается в любом месте кода, через неё будет происходить запись
	void TransitionRead(int _addr, int _L);		// эта Функция должна выполняться 1 раз (отвечает за чтение данных из EEPROM при Вкл.), её надо поместить в void setup()

	private:		// объявляем переменные - внутренними
	int _L;			// через эту переменную будут записываться данные для сохранения в EEPROM
	int _addr;	// начальный адрес ячейки EEPROM
};

#endif

EEPROM_Transition.cpp

#include "Arduino.h"			//подключаем стандартные функции Arduino
#include "EEPROM_Transition.h"  //подключаем заголовочный файл
#include "EEPROM.h"			 	// подключаем библиотеку EEPROM (по умолчанию установлена в Arduino IDE)


EEPROM_Transition :: EEPROM_Transition(int _addr, int _L) // данные для сохранения
{
	_L = _L;
	_addr = 0;
}


void EEPROM_Transition :: TransitionWrite(int _addr, int _L)  // Функция запист размещается в любом месте кода, через неё будет происходить запись
{
	  int maddr = (_addr + 1) % EEPROM_SIZE; //записываем в переменную maddr(МаркерАдрес) прибавленый _addr с остатком деления от размера EEPROM
  EEPROM.write(maddr, EEPROM_MARKER);   	 //Записываем в maddr значения из Маркера
  EEPROM.update(_addr, _L);                  //записываем обновлённые значения в через переменную _L в ячейку _addr (если они изменялись)
  _addr++;                     //переходим на следующую ячейку памяти для записи
  if ( _addr >= EEPROM_SIZE)    //если _addr >= размеру EEPROM
  {
    _addr = 0;                 //переходим обратно в первую ячейку и опять по кругу...
  }
}


void EEPROM_Transition :: TransitionRead(int _addr, int _L)	// эта Функция должна выполняться 1раз (отвечает за чтение данных из EEPROM при Вкл.), её надо поместить в void setup()
{
	  bool init = true;   //создаём булево значение и делаем её ИСТИНА
  for (int i = 0; i < EEPROM_SIZE; i++)   //запускаем счётчик, если i < объёма EEPROM, тогда +1
  {
    if (EEPROM.read(i) == EEPROM_MARKER)  //считаем переменную i и сравниваем с Маркером, если ровна...
    {
      _addr = (i - 1 + EEPROM_SIZE) % EEPROM_SIZE;  //отнимаем от i единицу и прибавляем EEPROM_SIZE и остаток деления от EEPROM_SIZE
      init = false;   //меняем значение на ЛОЖ
      break;          //принудительно выходим из цикла for
    }
  }
  if (init) _L = 0;    //если init ИСТИНА, присваиваем _L ноль
  else _L = EEPROM.read(_addr);  //иначе, читаем _addr-значение из ячейки памяти
}

Вот какую то мелочь нужно исправить, но недогоняю