Хранение даннх датчиков, структуры, списки...

AlexMann
Offline
Зарегистрирован: 13.05.2014

Если добавить начало в конце этой темы

http://arduino.ru/forum/programmirovanie/vyzov-attachinterrupt-iz-obekta...

 

Суть проблемы.  Есть некие датчики, в частности температурные далласы. Всем известные DS 1820.

Их примерно 22-25,  выполняемый код должен знать адрес далласа, его описание (где установлен), мин/макс значения, значения по умолчанию, и текущее значение.  Логично предположить, что удобно для этого использваться struct , где все описать. Затем структуры включить в линкедлист, и перемещаять по нему, запрашивать данные, обнослять структуру , описывающею каждый датчик, получть от туда значения мин/мак и сравнивать их с актуальным значением в функции обработчике.

struct DS{int index;DeviceAddress deviceAddress;String desc;float result;float preres;float low;float high; boolean trend;};

 Но! проблема в том, что это все занимает много места. 

Уважемый kisoft, предложил инициировать эти структуры как конситанты и во флеше. Использовать массив структур, что вполне удобно.

Вот что в итоге навскигу у меня получилось

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 12
#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))
OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

//DeviceAddress _deviceAddress; // временное место для адвера, нужно для перебора адресов в printAdress

struct DS{int index;DeviceAddress deviceAddress;String desc;float result;float preres;float low;float high; boolean trend;};


const DS dallas[]  =
{     
{0, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},"Температура воздуха на улице",0,0,25,100,NULL},
{1, {0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},"Температура воздуха в доме",0,0,25,100,NULL},
{2, {0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},"Температура на всасе",0,0,25,100,NULL},
{3, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},"Температура на разгрузке",0,0,25,100,NULL},
{4, {0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},"Температура перед испарителем",0,0,25,100,NULL},
{5, {0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},"Температура фреона перед ППТО",0,0,25,100,NULL},
{6, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},"Температура фреона после ППТО",0,0,25,100,NULL},
{7, {0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},"Температура воды перед ППТО",0,0,25,100,NULL},
{8, {0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},"Температура воды перед ППТО",0,0,25,100,NULL},
{9,{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},"Температура подачи в ТП",0,0,25,100,NULL},
{10,{0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},"Температура обратки ТП",0,0,25,100,NULL},
{11,{0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},"Температура поверхности пола",0,9,25,100,NULL},
{12,{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},"Температура подачи ДК",0,0,25,100,NULL},
{13,{0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},"Температура обратки ДК",0,0,25,100,NULL},
{14,{0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},"Температура гидрострелки",0,0,25,100,NULL},
{15,{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},"Температура подачи СО",0,0,25,100,NULL},
{16,{0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},"Температура обратки СО",0,0,25,100,NULL},
{17,{0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},"Температура воздуха после предпрогрева",0,25,100,NULL},
{18,{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},"Температура воздуха после фэнкоила",0,25,100,NULL},
{19,{0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},"Температура воздуха после рекуператора",0,25,100,NULL},
{20,{0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},"Температура эвакуируваемого воздуха",0,25,100,NULL},
{21,{0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},"Температура поступающего воздуха",0,25,100,NULL}
	};


void setup(void)
{
 
  Serial.begin(38400);
 
  Serial.println("setup");
  test();

}//setup
 
 void loop(void)
{
  
   Serial.println("loop");
   delay(2000);
  
}//loop

void test(){

  for(int i=0; i< NUMITEMS(dallas); i++){
  
    const DS &temp = dallas[i];
     Serial.print(i);
     Serial.print(" ");
     Serial.println(temp.desc);
    
  }

}
 

Имеем вот такой вывод (что то еще с кирилицей случилось, до кучи)

setup
0 ТемпеÑаÑÑÑа воздÑÑа на ÑлиÑе
1 ТемпеÑаÑÑÑа воздÑÑа в доме
2 ТемпеÑаÑÑÑа на вÑаÑе
3 ТемпеÑаÑÑÑа на ÑазгÑÑзке
4 ТемпеÑаÑÑÑа пеÑед иÑпаÑиÑелем
5 ТемпеÑаÑÑÑа ÑÑеона пеÑед ÐÐТÐ
6 ТемпеÑаÑÑÑа ÑÑеона поÑле ÐÐТÐ
7 ТемпеÑаÑÑÑа Ð²Ð¾Ð´Ñ Ð¿ÐµÑед ÐÐТÐ
8 ТемпеÑаÑÑÑа Ð²Ð¾Ð´Ñ Ð¿ÐµÑед ÐÐТÐ
9 ТемпеÑаÑÑÑа подаÑи в ТÐ
10 ТемпеÑаÑÑÑа обÑаÑки ТÐ
11 ТемпеÑаÑÑÑа повеÑÑноÑÑи пола
12 ТемпеÑаÑÑÑа подаÑи ÐÐ
13 ТемпеÑаÑÑÑа обÑаÑки ÐÐ
14 ТемпеÑаÑÑÑа гидÑоÑÑÑелки
15 ТемпеÑаÑÑÑа подаÑи СÐ
16 ТемпеÑаÑÑÑа обÑаÑки СÐ
17 ТемпеÑаÑÑÑа воздÑÑа поÑле пÑедпÑогÑева
18 ТемпеÑаÑÑÑа воздÑÑа поÑле ÑÑнкоила
19 ТемпеÑаÑÑÑа воздÑÑа поÑле ÑекÑпеÑаÑоÑа
20 ТемпеÑаÑÑÑа ÑвакÑиÑÑваемого воздÑÑа
21 ТемпеÑаÑÑÑа поÑÑÑпаÑÑего воздÑÑа
loop
loop
loop

Если добавить директиву PROGMEM


const DS dallas[] PROGMEM =
{   

То все гордо перестает работать.

Но в любом случае, привеленный док компилится в 10К, и работает на 2560, а на 328 (нане) это уже не работает... на Нане работает токка если урезать массив в половину. А тут еще нет собситвенно самого мегакода, который должен получать данные от датчиков и соотведственно отправлять комманты на исполнительные устройства.

В общем, как быть ?  Какой подход применить к описанию датчиков и работе с их данными, что бы осталось место для основного кода :) ??

Спасибо.

 

 

AlexMann
Offline
Зарегистрирован: 13.05.2014

Может, в частности отказаться от использования DallasTemperature, и описать свой класс ? будет 25 поименованных экземпларов, и структуры тогда не нужны ? Я так понимаю, в массиве можно хранить указатели на экземпляры и так же в цикле их получать...

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Если мы храним данные во Flash, то их нужно читать особым способом. Если Вам интересны шаблоны и прочее, то можете почитать статью http://we.easyelectronics.ru/Soft/avr-s-i-umnye-ukazateli.html либо начать с главного http://arduino.cc/en/Reference/PROGMEM а также http://arduiniana.org/libraries/flash/ эти ссылки давал maksim в одной из тем (искать по слову PROGMEM в верхнем правом углу форума).

Русский язык. Поскольку среда по умолчанию читает данные в UTF-8, то и русские символы - двухбайтные. Здесь на форуме кто то исправлял это, путем корректировки среды, тогда файлы будут в кодировке 1251, поищите на форуме.

Еще, само значение (result) во Flash хранить не получится, поскольку программе во флеш писать можно, но это достаточно сложно, плюс ни к чему убивать камень ради этого. Скорее всего нужно хранить результат в самом классе. Т.е. константы во Flash, переменные в самом объекте.

PS Первая ссылка - я и сам хочу попробовать (как будет время), довольно таки хороший метод читать из Flash/EEPROM, тем более автор хорошо разбирается в вопросе программирования на С++, так что рекомендую и статью и автора :)

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

AlexMann пишет:

Может, в частности отказаться от использования DallasTemperature, и описать свой класс ? будет 25 поименованных экземпларов, и структуры тогда не нужны ? Я так понимаю, в массиве можно хранить указатели на экземпляры и так же в цикле их получать...

Структуры нужно только для того, чтобы поместить их во Flash. Эти данные постоянные и не меняются. А если их засадить в класс, то они попадут в ОЗУ, которого кот наплакал. Главная идея именно в этом.

Структуры в виде массива структур - каждая запись имеет индекс (лучше оформить  виде enum, чтобы имена были конкретные), который будет знать каждый экземпляр и читать из Flash нужную информацию по этому индексу. Чтобы сказать точнее нужно знать, как будут использоваться все эти данные, которые есть в структуре.

 

AlexMann
Offline
Зарегистрирован: 13.05.2014

FLASH_TABLE я пробовал, оно не поддерживает сложные типы, как я понял.  

я не могу понять, как получить структуру из масссива в прогмем...



const DS dallas[] PROGMEM  =
{     
{0, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},"Температура воздуха на улице",0,0,25,100,NULL},
...
}

void test(){

  for(int i=0; i< NUMITEMS(dallas); i++){
  
  //  const DS &temp = dallas[i];
    
    Serial.println(pgm_read_dword_near(&dallas[i].result));
  //   Serial.print(i);
  //   Serial.print(" ");
  //   Serial.println(temp.desc);
    
  }

}

Выводит жуткую ахинею и вооще, сбивает настройки Сериала...

 

AlexMann
Offline
Зарегистрирован: 13.05.2014

В общем, что то ниче у меня  не выходит...

даже совсем упрощенный вариант

#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))

struct DS {int index; String deviceAddress; String desc;int result;};

 const DS dallas[] PROGMEM =
{     
{0, "1111","Temp",0},
{1, "2222","Temp",0}
};

void setup(void)
{
 
  Serial.begin(38400);
 
  Serial.println("setup");
  test();

}//setup
 
 void loop(void)
{
  
   Serial.println("loop");
   delay(2000);
  
}//loop

void test(){

  for(int i=0; i< NUMITEMS(dallas); i++){
  
  
     Serial.print(pgm_read_word(&dallas[i].index));
     Serial.print(" ");
     Serial.print(pgm_read_word(&dallas[i].deviceAddress));
       Serial.print(" ");
     Serial.print(pgm_read_word(&dallas[i].desc));
       Serial.print(" ");
     Serial.print(pgm_read_word(&dallas[i].result));
       Serial.println(" ");
       
  }

}
 

Выводит что то не то...

setup
0 0 0 0
0 0 0 0
loop

 

 

AlexMann
Offline
Зарегистрирован: 13.05.2014

такая конструкция 

 Serial.print(pgm_read_word_near(&dallas[i].index));
     Serial.print(" ");
     strcpy_P(buff, (char*)pgm_read_word(&dallas[i].deviceAddress));
     Serial.print(buff);
     Serial.print(" ");
     strcpy_P(buff, (char*)pgm_read_word(&dallas[i].desc));
     Serial.print(buff);
     Serial.print(" ");
     Serial.print(pgm_read_word_near(&dallas[i].result));
     Serial.println(" ");

Выводит вот это

setup
0 À À 0
0 À À 0
loop

AlexMann
Offline
Зарегистрирован: 13.05.2014

оно, наверно и понятно, я пытаюсь обратиться к полям элемента массива. Нужно получить элемент цилеком, или ссылку на элеимент, а потом получить как то его поля... как то страшно все это после C# :)

Так то kisoft об этом и писал :)

kisoft пишет:

Структуры в виде массива структур - каждая запись имеет индекс (лучше оформить  виде enum, чтобы имена были конкретные), который будет знать каждый экземпляр и читать из Flash нужную информацию по этому индексу.

kisoft пишет:

 Чтобы сказать точнее нужно знать, как будут использоваться все эти данные, которые есть в структуре.

Предпологалось хранить в структуре данные о датчике, передавать эту структуру в функцию, в цикле, там уже по адресу запрашивать данные,  одновлять значение result, сравнивать это поле с полями мин и макс, записывать обновленную структуру ( видимо опять во флеш) и переходить к структуре следующей в массиве...

 

 

kisoft пишет:

Еще, само значение (result) во Flash хранить не получится, поскольку программе во флеш писать можно, но это достаточно сложно, плюс ни к чему убивать камень ради этого. Скорее всего нужно хранить результат в самом классе. Т.е. константы во Flash, переменные в самом объекте.

Да.. тогда моэжно уже и в EEPROM в принцире хранить...

kisoft пишет:

PS Первая ссылка - я и сам хочу попробовать (как будет время), довольно таки хороший метод читать из Flash/EEPROM, тем более автор хорошо разбирается в вопросе программирования на С++, так что рекомендую и статью и автора :)

Да, почитал... но вроде его там разгромили в коментах, за уныло не эффективный код и сам подход... 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

На счёт разгромили можно поспорить, но не буду, другое дело, что статья про хранение простых данных.
Ещё, использование в массиве String, приводит к тому, что структура перестаёт быть плоской.
Поиграюсь, по возможности. Всё это можно реализовать так или иначе.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Вот этот скетч работает нормально. Отлаживался и проверялся в симуляторе AtmelStudo 6.1, там с кодировкой всё нормально, так что проблемы utf8 мне решать ну совсем не интересно. Прогнал по шагам, читаются корректные данные:

/*
 * Flash_Tester.cpp
 *
 * Created: 08.09.2013 18:08:26
 *  Author: kisoft
 */ 

#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 12
#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))
OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

struct DS
{
	uint8_t index;
	DeviceAddress deviceAddress;
	float result;
	float preres;
	float low;
	float high;
	uint8_t trend;
};

const char g_text_0[] PROGMEM = "Температура воздуха на улице";
const char g_text_1[] PROGMEM = "Температура воздуха в доме";
const char g_text_2[] PROGMEM = "Температура на всасе";
const char g_text_3[] PROGMEM = "Температура на разгрузке";
const char g_text_4[] PROGMEM = "Температура перед испарителем";
const char g_text_5[] PROGMEM = "Температура фреона перед ППТО";
const char g_text_6[] PROGMEM = "Температура фреона после ППТО";
const char g_text_7[] PROGMEM = "Температура воды перед ППТО";
const char g_text_8[] PROGMEM = "Температура воды перед ППТО";
const char g_text_9[] PROGMEM = "Температура подачи в ТП";

PROGMEM const char* const g_messages[] =
{
	g_text_0,
	g_text_1,
	g_text_2,
	g_text_3,
	g_text_4,
	g_text_5,
	g_text_6,
	g_text_7,
	g_text_8,
	g_text_9
};

PROGMEM const DS dallas[] =
{
	{0, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},0,0,25,100,false},
	{1, {0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},0,0,25,100,false},
	{2, {0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},0,0,25,100,false},
	{3, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},0,0,25,100,false},
	{4, {0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},0,0,25,100,false},
	{5, {0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},0,0,25,100,false},
	{6, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},0,0,25,100,false},
	{7, {0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},0,0,25,100,false},
	{8, {0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},0,0,25,100,false},
	{9,{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},0,0,25,100,false}
};

class Sensors
{
public:
	Sensors();
	
	static void loadDatas( uint8_t p_Index, DS *pp_Data, char* pp_Desc );
	
	void solveProblem( DS *pp_datas );
private:
	float		m_Result;
};

Sensors::Sensors() : m_Result( 0 )
{
}

// static 
void Sensors::loadDatas( uint8_t p_Index, DS *pp_Data, char *pp_Desc )
{
	if( pp_Data )
	{
		/* Читаем всю структуру в pp_Data */
		uint8_t *lp_Ptr = (uint8_t *)pp_Data;
		for( uint8_t i = 0; i < sizeof( DS ); ++i, lp_Ptr++ )
		{
			(*lp_Ptr) = pgm_read_byte( ((uint8_t *)&(dallas[ p_Index ])) + i );
		}
	}
	if( pp_Desc )
	{
		strcpy_P( pp_Desc, (char*)pgm_read_word(&(g_messages[ p_Index ])) );
	}
}

void setup()
{
}

/* Хранилище данных, считанных из Flash */
static DS g_datas;
/* Описание, считанное из Flash */
static char g_Desc[ 50 ];

void loop()
{
	for( uint8_t i = 0; i < NUMITEMS(dallas); i++ )
	{
		Sensors::loadDatas( i, &g_datas, g_Desc );
	}
}

Главный смысл в том, что в ОЗУ всегда находится только одна (!) структура DS (а не все 25), которую можно считать статическим методом Sensors::loadDatas. Если нужно описание, то он считает и его, если не нужно, ставите NULL последним параметром и описание читаться не будет. Считываются данные по индексу (не по полю index в DS, а по индексу расположения структуры в массиве dallas).

Разумеется это только рыба, остальное писать Вам. Для примера оставил в классе Sensors метод void solveProblem( DS *pp_datas ); который может делать рассчеты или еще что то с данными структуры DS.

На счет оптимальности - возможно не всё оптимально, сделано тупо в лоб, для проверки и обкатки этого способа хранения константных данных во Flash.

 

AlexMann
Offline
Зарегистрирован: 13.05.2014

Спасиб, счас разребусь с работой и вернуть в нирвану :)

да... парвильно конечно все разобрать на разные массивы, для разных данных...

AlexMann
Offline
Зарегистрирован: 13.05.2014

Поставив АтмелСтудию и приручив к ней ардуинку, 

попробовал приведенный выше код

Вот что имеем..

Blink.ino:25: warning: only initialized variables can be placed into program memory area
Blink.ino:26: warning: only initialized variables can be placed into program memory area
Blink.ino:27: warning: only initialized variables can be placed into program memory area
Blink.ino:28: warning: only initialized variables can be placed into program memory area
Blink.ino:29: warning: only initialized variables can be placed into program memory area
Blink.ino:30: warning: only initialized variables can be placed into program memory area
Blink.ino:31: warning: only initialized variables can be placed into program memory area
Blink.ino:32: warning: only initialized variables can be placed into program memory area
Blink.ino:33: warning: only initialized variables can be placed into program memory area
Blink.ino:34: warning: only initialized variables can be placed into program memory area
Blink.ino:36: warning: only initialized variables can be placed into program memory area
Blink.ino:50: warning: only initialized variables can be placed into program memory area
C:\Users\master.OFFICE\Google Диск\spec\Arduino\arduino-1.0.5-r2-windows\arduino-1.0.5-r2\hardware\tools\avr\bin\avr-gcc -Os -Wl,--gc-sections,--relax -mmcu=atmega2560 -L"C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560" -o "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.elf" "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.cpp.o" "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\core.a" -lm
Blink.cpp.o:In function `__static_initialization_and_destruction_0'
Blink.ino:OneWire(unsigned char)'
Blink.ino:DallasTemperature(OneWire*)'
Error creating .elf

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Хорошо бы еще сам скетч приложить, а то номера строк не соответствуют моему тексту.

Во вторых, что то я уже запамятовал, нужен ли тут Micro, скорее всего нет, потому что в нем нет возможности выбрать simulator, потому это собственноручно мной собранная система. Надо было проект приложить. Понятно, но всё равно, нужен скетч, потому что приблизительно понятно, но чтобы говорить на одном языке, нужно работать с одной копией скетча. Сегодня, правда, хоккей.. так что как получится. Мне эта тема и самому интересна, разобраться с Flash хранением, я пока это только в теории пробовал.

 

AlexMann
Offline
Зарегистрирован: 13.05.2014

Код ы точности Ваш

#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>


#define ONE_WIRE_BUS 12
#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

struct DS
{
	uint8_t index;
	DeviceAddress deviceAddress;
	float result;
	float preres;
	float low;
	float high;
	uint8_t trend;
};

const char PROGMEM g_text_0[]  = "test";
const char PROGMEM g_text_1[]  = "Температура воздуха в доме";
const char PROGMEM g_text_2[]  = "Температура на всасе";
const char PROGMEM g_text_3[]  = "Температура на разгрузке";
const char PROGMEM g_text_4[]  = "Температура перед испарителем";
const char PROGMEM g_text_5[]  = "Температура фреона перед ППТО";
const char PROGMEM g_text_6[]  = "Температура фреона после ППТО";
const char PROGMEM g_text_7[]  = "Температура воды перед ППТО";
const char PROGMEM g_text_8[]  = "Температура воды перед ППТО";
const char PROGMEM g_text_9[]  = "Температура подачи в ТП";

 const char* const g_messages[] =
{
	g_text_0,
	g_text_1,
	g_text_2,
	g_text_3,
	g_text_4,
	g_text_5,
	g_text_6,
	g_text_7,
	g_text_8,
	g_text_9
};

 const DS dallas[] PROGMEM =
{
	{0, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},0,0,25,100,false},
	{1, {0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},0,0,25,100,false},
	{2, {0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},0,0,25,100,false},
	{3, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},0,0,25,100,false},
	{4, {0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},0,0,25,100,false},
	{5, {0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},0,0,25,100,false},
	{6, {0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},0,0,25,100,false},
	{7, {0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},0,0,25,100,false},
	{8, {0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},0,0,25,100,false},
	{9,{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},0,0,25,100,false}
};

class Sensors
{
public:
	Sensors();
	
	static void loadDatas( uint8_t p_Index, DS *pp_Data, char* pp_Desc );
	
	void solveProblem( DS *pp_datas );
private:
	float		m_Result;
};

Sensors::Sensors() : m_Result( 0 )
{
}

// static 
void Sensors::loadDatas( uint8_t p_Index, DS *pp_Data, char *pp_Desc )
{
	if( pp_Data )
	{
		/* Читаем всю структуру в pp_Data */
		uint8_t *lp_Ptr = (uint8_t *)pp_Data;
		for( uint8_t i = 0; i < sizeof( DS ); ++i, lp_Ptr++ )
		{
			(*lp_Ptr) = pgm_read_byte( ((uint8_t *)&(dallas[ p_Index ])) + i );
		}
	}
	if( pp_Desc )
	{
		strcpy_P( pp_Desc, (char*)pgm_read_word(&(g_messages[ p_Index ])) );
	}
}

void setup()
{
}

/* Хранилище данных, считанных из Flash */
static DS g_datas;
/* Описание, считанное из Flash */
static char g_Desc[ 50 ];

void loop()
{
	for( uint8_t i = 0; i < NUMITEMS(dallas); i++ )
	{
		Sensors::loadDatas( i, &g_datas, g_Desc );
	}
}

Вот вывод

 

Compiling 'Blink' for 'Arduino Mega 2560 or Mega ADK'
Build folder: file:///C:/Users/master.OFFICE/AppData/Local/VMicro/Arduino/Builds/Blink...
Summary: Header=1 Prototypes=3 Imports=3
Additional Defines: VISUALMICRO_COMPILER_VER=1;
Architecture Tools: C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\tools\avr\bin\
GCC: 4.3.2
Sketchbook: file:///C:/Users/master.OFFICE/Documents/Arduino
Include Path 'C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\arduino\cores\arduino'
Include Path 'C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\arduino\variants\mega'
Include Path 'C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\libraries\OneWire'
Include Path 'C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\libraries\DallasTemperature'
Include Path 'C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\libraries'
Include Path 'C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\arduino\libraries'
Include Path 'C:\Users\master.OFFICE\Documents\Arduino\libraries'
C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\tools\avr\bin\avr-g++ -c -g -Os -fno-exceptions -ffunction-sections -fdata-sections -Wall -mmcu=atmega2560 -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -I"C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\arduino\cores\arduino" -I"C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\arduino\variants\mega" -I"C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\libraries\OneWire" -I"C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\libraries\DallasTemperature" -I"C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\libraries" -I"C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\arduino\libraries" -I"C:\Program Files (x86)\Visual Micro\Visual Micro for Arduino\Micro Platforms\default\debuggers" -I"C:\Users\master.OFFICE\Documents\Arduino\libraries" -o "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.cpp.o" "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.cpp" -DVISUALMICRO_COMPILER_VER=1
Blink.ino:24: warning: only initialized variables can be placed into program memory area
Blink.ino:25: warning: only initialized variables can be placed into program memory area
Blink.ino:26: warning: only initialized variables can be placed into program memory area
Blink.ino:27: warning: only initialized variables can be placed into program memory area
Blink.ino:28: warning: only initialized variables can be placed into program memory area
Blink.ino:29: warning: only initialized variables can be placed into program memory area
Blink.ino:30: warning: only initialized variables can be placed into program memory area
Blink.ino:31: warning: only initialized variables can be placed into program memory area
Blink.ino:32: warning: only initialized variables can be placed into program memory area
Blink.ino:33: warning: only initialized variables can be placed into program memory area
Blink.ino:49: warning: only initialized variables can be placed into program memory area
C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\tools\avr\bin\avr-gcc -Os -Wl,--gc-sections,--relax -mmcu=atmega2560 -L"C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560" -o "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.elf" "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.cpp.o" "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\OneWire\OneWire.cpp.o" "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\DallasTemperature\DallasTemperature.cpp.o" "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\core.a" -lm
C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\tools\avr\bin\avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.elf" "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.eep"
C:\Users\master.OFFICE\Google Диск\spec\Arduino\1.0.5\hardware\tools\avr\bin\avr-objcopy -O ihex -R .eeprom "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.elf" "C:\Users\master.OFFICE\AppData\Local\VMicro\Arduino\Builds\Blink\mega2560\Blink.hex"
Binary sketch size: 2 340 bytes (used 1% of a 258 048 byte maximum) (0,44 secs)

С библиотеками я разобрался, все ок.. (в прошлом выводе были ошибки...)

Код компилится, прошивается на мегу...  Катати, включение оптимизатора, сократило его размер в 2 раза...

 щас попробую его как то приминить , что бы лолучить какую то лабу, с реальными датчиками и опросом... 

Интересно, почему оно ругается на PROGMEM 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Вот теперь вижу по номерам строк, что этот текст соответствует ошибкам. С PROGMEM сам хочу разобраться, вроде бы примеров вагон, но эти варнинги толи можно на них забить, то ли забить в набат. Ну вот скетч есть, я его вечерком помацаю малёк.

AlexMann
Offline
Зарегистрирован: 13.05.2014

что то мне Нану не приручить к студии...

Кто нибудь может дать ключ к микре ?

vlkam
Offline
Зарегистрирован: 17.02.2013

Алекс, а что это такое Вы делаете ? Очень похоже, что я сейчас примерно тоже самое делаю (модуль управления вентиляцией и отоплением).

Было бы интересно пообщаться. Скайп есть ?

AlexMann
Offline
Зарегистрирован: 13.05.2014

пришлите свой на

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Предупреждения легко можно обойти, вставив следующий текст в строку 5:

#ifdef PROGMEM
#undef PROGMEM
#define PROGMEM __attribute__((section(".progmem.data")))
#endif

Решение найдено в интернете, гуглится наура, вот здесь: http://forum.arduino.cc/index.php/topic,85840.0.html

У меня в Atmel Studio 6.1, под vMicro компилируется нормально, без предупреждений.

 

AlexMann
Offline
Зарегистрирован: 13.05.2014
Что ж уменя заработало, примерно в таком виде...
 #include <Arduino.h>

#include <OneWire/OneWire.h>
#include <DallasTemperature/DallasTemperature.h>

#define ONE_WIRE_BUS 12
#define SDEL 300
#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))


OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);
 
 const DS dallas[] PROGMEM =
 {
  {{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},25,100},
  {{0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},25,100},
  {{0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},25,100},
  {{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},25,100},
  {{0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},25,100},
  {{0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},25,100},
  {{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},25,100},
  {{0x28,0x35,0x72,0x80,0x04,0x00,0x00,0xB1},25,100},
  {{0x28,0x57,0x8E,0x7F,0x04,0x00,0x00,0x70},25,100},
  {{0x10,0x3E,0x59,0x9A,0x02,0x08,0x00,0xA0},25,100}
 };

const prog_char PROGMEM g_text_0[]  = "test";   /// пришлось сменить тип  на prog_char иначе писалась охинея
const prog_char PROGMEM g_text_1[]  = "qqqqqq";
const prog_char PROGMEM g_text_2[]  = "wwwwwwww";
const prog_char PROGMEM g_text_3[]  = "eeeeeeee";
const prog_char PROGMEM g_text_4[]  = "rrrrrrrr";
const prog_char PROGMEM g_text_5[]  = "addddddd";
const prog_char PROGMEM g_text_6[]  = "ffffffffffffffffffffff";
const prog_char PROGMEM g_text_7[]  = "yyyyyy";
const prog_char PROGMEM g_text_8[]  = "ggggggg";
const prog_char PROGMEM g_text_9[]  = "rrrrrrrr";

PROGMEM const char *g_messages[] =

{
 g_text_0,
 g_text_1,
 g_text_2,
 g_text_3,
 g_text_4,
 g_text_5,
 g_text_6,
 g_text_7,
 g_text_8,
 g_text_9
};


float g_result[NUMITEMS(dallas)]; // здесь храним результаты измерений


static DS g_datas;

static char g_Desc[50];

void sens_reload_all_result( uint8_t p_Index, DS *pp_Data, char *pp_Desc )
{
 if( pp_Data )
 {
  uint8_t *lp_Ptr = (uint8_t *)pp_Data;
  for( uint8_t i = 0; i < sizeof(DS); ++i, lp_Ptr++ )
  {
   (*lp_Ptr) = pgm_read_byte( ((uint8_t *)&(dallas[ p_Index ])) + i );
   g_result[i] =  sensors.getTempC(g_datas.deviceAddress);
  }
 }
 if( pp_Desc )
 {
  strcpy_P( pp_Desc, (char*)pgm_read_word(&(g_messages[ p_Index ])) );
 }
 
 
}

Правда, есть ощущение, что по дороге потерялась идея, т.к. структуры вроде не очень и нужны. Но в целом все ок. надо будет еще поработать над тем, что правильно вызывать для обработки, по отдельности структуру кадлый раз, когда нужены данные датчика, или один раз за цыкл заполнять массив с данными со всех датчиков.

А потом используя EMUM просто обращаться  по имени датчика к каждому из массивов... с данными, описанием или персетом (структурой) ... ENUM бы поправить с int на uint8_t ... знаю, что как то можно ...

 

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

72 строку нужно вынести из цикла и вставить сразу после 73-ей (!) И вместо i напсать:
 

g_result[ p_Index ] =  sensors.getTempC( pp_Date->deviceAddress);

Если из структуры нужен только deviceAddres, то нужно только его и считывать. Впрочем он может снаружи использоваться, тогда надо всё считать.

По поводу enum:
enum ENUM_NAME : uint8_t {};
Шучу, это в C++11.

А вообще у меня сейчас противоречивая информация, либо enum занимает столько, чтобы влезло любое его значение, либо всегда int, как то не нужно было никогда особо, потому не знаю точно.

enum нужен только если бы был общий класс, а так, может и не нужен. Для читабельности программы точно был бы нужен.

 

AlexMann
Offline
Зарегистрирован: 13.05.2014

kisoft пишет:

72 строку нужно вынести из цикла и вставить сразу после 73-ей (!) И вместо i напсать:
g_result[ p_Index ] = sensors.getTempC( pp_Date->deviceAddress);

ГЫ :) точно... спасибо.

Мне все никак не решить, правшивать все датчики один раз за цикл, или вызывать отдельные по мере надобности...

ENUM да, для читаемости...  много датчиков, можно запутаться при вызовах...  может int не так и накладно...