Ви не увійшли.
Сторінки 1
Имею такой вот блок управления Твердотопливным котлом.
В его состав входят Arduino Mega 2560 + Ethernet Shield W5100 +microSD
в общем все "что доктор прописал"
Кроме этого есть
Графический дисплей QC12864B
Усилитель термопары MAX31855
Датчик температуры DS18B20
4-канальный реле модуль
Как в данный момент функционирует блок можно почитать тут.
Данные с датчиков температуры блок отправляет сейчас на сторонний сервер
Требуется:
разобраться, как функционирует этот могучий инструмент (Ардуино Мега Сервер) и вывести показания с этих датчиков на AMS в виде аналогичных графиков с сохранением функционала блока, то есть не отправлять данные на xively.com, а формировать графики на SD карточке и просматривать их через браузер.
Я сам с этим справится не смог.
Скетч в виде кода прикрепить не могу, так как он слишком длинный, поэтому креплю его библиотеки в виде .zip
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>
#include <OneWire.h>
#include "U8glib.h"
//+vasko 150224
#include "Adafruit_MAX31855.h"
// назначаем выходы Ардуино для взаимодействия с MAX31855
#define thermoDO 34
#define thermoCS 38
#define thermoCLK 36
Adafruit_MAX31855 thermocouple(thermoCLK, thermoCS, thermoDO);
//-vasko 150224
// закрепляем за оборудованием цифровые выходы ардуино
#define nasosKranKotel 47 // Реле 1 - верхнее - НЦ1, КЭ1 47
#define nasosPotrebiteli 48 // Реле не присвоено - НЦ2, НЦ3, НЦ4 48
#define dymosos 44 // Реле 2 - второе сверху - Дымосос 44
#define kranTA 45 // Реле 3 - третье сверху - КЭ2 45
#define zaslonkaVozduha 46 // Реле 4 - нижнее - МЗ 46
//#define txa 8 // Аналоговый вход A8 ТХА (Датчик термопары дыма).
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//-----
IPAddress ip(192,168,0,20);
char xivelyKey[] = "yxLIRTV1LH6WAR52rvLSsXDidl7sGgN0efvah8hr0461";// Идентификатор на
unsigned long feedId = 192768;// xively
//---------------------------------------------
//IPAddress ip(192,168,0,21);
//char xivelyKey[] = "8kSv3fJUP6SrrlEbCZvKZWI6NNCdbWAZj3PTTuiof9i";
//unsigned long feedId = 556923;
//----------------------------------------------------
// присваеваем типы значений числовым переменным
// присваеваем тип значения переменной для темп. сенсоров - char
char sensor1Id[] = "1_Dymovaya_Truba"; // ТХА
char sensor2Id[] = "2_Kotel_Vyhod"; // ДТ2
char sensor3Id[] = "3_Kotel_Obratka"; // ДТ3
char sensor4Id[] = "4_Verh_TA"; // ДТ4
char sensor5Id[] = "5_Niz_TA"; // ДТ5
char sensor0Id[] = "6_Test_Sensor";
XivelyDatastream datastreams[] = {
XivelyDatastream(sensor0Id, strlen(sensor0Id), DATASTREAM_FLOAT),
XivelyDatastream(sensor1Id, strlen(sensor1Id), DATASTREAM_FLOAT),
XivelyDatastream(sensor2Id, strlen(sensor2Id), DATASTREAM_FLOAT),
XivelyDatastream(sensor3Id, strlen(sensor3Id), DATASTREAM_FLOAT),
XivelyDatastream(sensor4Id, strlen(sensor4Id), DATASTREAM_FLOAT),
XivelyDatastream(sensor5Id, strlen(sensor5Id), DATASTREAM_FLOAT),
};
// Finally, wrap the datastreams into a feed
XivelyFeed feed(feedId, datastreams, 6/* number of datastreams */);// назначаем выходы Ардуино для взаимодействия с дисплеем
EthernetClient client;
XivelyClient xivelyclient(client);
// назначаем выходы Ардуино для взаимодействия с дисплеем
U8GLIB_ST7920_128X64_1X u8g(24, 22, 23); // SPI Com: SCK = en = 24, MOSI = rw = 22, CS = di = 23
// Кроме этого GND на (VSS, K(BLK) и PSB), +5В на (VDD и А(BLA))
//int tempCelsVal[6], tempCelsPre[6], txaCode;
// присваеваем тип значения переменной для термопары - int
int txaCode;
// присваеваем тип значения переменной для термопары - float
float tempCels[6], txaTemp;
// присваеваем тип значения переменной для описывающей состояние Отопительной системы - boolean
boolean reactorActive=0, accumulatorWarm=0, systemCRIHot=0, systemVeryHot=0, dymVeryCold=0, postplenieGar=0, sensorOnline[5];
// закрепляем входы Ардуино за датчиками температуры в СО
OneWire ds1(28); // Неиспользуемый датчик
OneWire ds2(29); // Температура воды Котел подача ДТ2
OneWire ds3(30); // Температура воды Котел обратка ДТ3
OneWire ds4(27); // Температура воды ТА Верхняя часть ДТ4
OneWire ds5(31); // Температура воды ТА Нижняя часть ДТ5
//----------------------------------------
// Графика дисплея
void draw(void)
{
u8g.setFont(u8g_font_freedoomr10r);
//-------------------Котел Подача--------------
u8g.drawFrame(0,15,33,48); // прямоугольник корпуса котла
tempOutGraph(2,3,32); // Определяет положение индикации ds2 "Температура воды Котел подача ДТ2"
u8g.drawVLine(25,0,15); // труба дымовая левая часть
u8g.drawVLine(29,0,15); // труба дымовая правая часть
if (!digitalRead(zaslonkaVozduha))
{
u8g.drawLine(24,9,30,3);
} // вывод изображения заслонки, если она включена (закрыта)
//-------------------Аккумулятор Верх--------
u8g.drawEllipse(67,32,4,10,U8G_DRAW_UPPER_LEFT|U8G_DRAW_LOWER_LEFT);
u8g.drawEllipse(110,32,4,10);
u8g.drawHLine(69,21,41); // верхняя линия
u8g.drawHLine(69,42,41); // нижняя линия
tempOutGraph(4,85,20); // Определяет положение индикации ds4 "Температура воды ТА Верхняя часть ДТ4"
// (№ датчика темп.,x,y)
//----------------Аккумулятор Низ----------
tempOutGraph(5,85,59); // Определяет положение индикации ds5 "Температура воды ТА Нижняя часть ДТ5"
//--------------------Трубы-------------
u8g.drawHLine(33,17,16); // выход котла
u8g.drawHLine(33,48,16); // вход котла
u8g.drawFrame(49,0,79,64); // рамка СО
u8g.drawVLine(78,42,22); // выход аккумулятора
u8g.drawVLine(78,2,20); // вход аккумулятора
u8g.drawDisc(126,26,3); // насос система
u8g.drawDisc(49,48,3); // насос обратка
//-------------
tempOutGraph(3,3,62); // Определяет положение индикации ds3 "Температура воды Котел обратка ДТ3"
//--------------------------------------
if (!digitalRead(nasosPotrebiteli)) // Если включен насос СО
{ // оператор (!) перд digitalRead обеспечивает правильное положенеи контактов рере соответствующее работе светодиода
u8g.drawVLine(120,25,12); // стрелка после насоса системы (x,y,длина лин.)(119,37,12)
u8g.drawLine(120,39,118,34);// наконечник стрелки (Х,У,х-коца линии наконечника,у-конец лин. нак.) (119,49,117,47)
u8g.drawLine(120,39,122,34);
}
//---------------------------
if (!digitalRead(nasosKranKotel)) // Если включены кран и насос Котла
{ // оператор (!) перд digitalRead обеспечивает правильное положенеи котактов рере соответствующее работе светодиода
u8g.drawHLine(39,21,6);
u8g.drawVLine(44,21,10); // обратка
u8g.drawHLine(39,31,6);
u8g.drawLine(39,31,41,29);
u8g.drawLine(39,31,41,33);
u8g.drawVLine(46,3,12); // выход в систему
u8g.drawLine(46,3,44,5);
u8g.drawLine(46,3,48,5);
//------------
u8g.drawHLine(54,5,11); // стрелка перед краном ТА
u8g.drawLine(68,5,63,3);
u8g.drawLine(68,5,63,7);
//------------
u8g.drawHLine(54,58,12); // стрелка на вход в котел (x,y,длина линии) drawHLine-горизонтальная
u8g.drawLine(51,58,55,56); // перед краном котла линия по 2-м точкам (х,у,х,у)
u8g.drawLine(51,58,55,60);
}
//-------------
if (digitalRead(nasosKranKotel))// Kран котла закрыт (Рисуем крестик на трубе)
{
u8g.drawLine(40,46,36,50);// кран котла 1-я линия (Х,У,х-коца линии,у-конца линии)
u8g.drawLine(40,50,36,46);// кран котла 2-я линия (Х,У,х-коца линии,у-конца линии)
}
//-------------
if (!digitalRead(kranTA) && !digitalRead(nasosKranKotel)) // Если открыт кран ТА и включены кран и насос Котла
{ // рисуем Стрелку в ТА
u8g.drawVLine(73,6,10); // стрелка ТА drawVLine-вертикальная
u8g.drawLine(75,13,73,18);
u8g.drawLine(71,13,73,18);// (Х,У,х-коца линии наконечника,у-конец лин. нак.)
}
if (!digitalRead(kranTA) && digitalRead(nasosKranKotel))// Если открыт кран ТА и вЫключены кран и насос Котл
{ // рисуем Стрелку выход из ТА
u8g.drawVLine(73,6,10); // стрелка ТА drawVLine-вертикальная
u8g.drawLine(73,3,71,8);
u8g.drawLine(73,3,75,8);// (Х,У,х-коца линии наконечника,у-конец лин. нак.)
}
if (digitalRead(kranTA))// Если закрыт кран ТА
{
u8g.drawLine(80,7,76,11);// кран ТА 1-я линия (Х,У,х-коца линии,у-конца линии)
u8g.drawLine(76,7,80,11);// кран ТА 2-я линия (Х,У,х-коца линии,у-конца линии)
}
//--------------------------------------
u8g.setPrintPos(0, 12); // Вывод показаний датчика
u8g.print((int)txaTemp); // температуры дыма
//--------------------------------------
}
//----------------------------------------
// Определение первоначальных состояний цифровым выходам
void setup()
{
pinMode(zaslonkaVozduha, OUTPUT); // Назначаем порт "Выходом"
pinMode(kranTA, OUTPUT); // Назначаем порт "Выходом"
//pinMode(nasosPotrebiteli, OUTPUT); // Назначаем порт "Выходом"
pinMode(dymosos, OUTPUT); // Назначаем порт "Выходом"
pinMode(nasosKranKotel, OUTPUT); // Назначаем порт "Выходом"
digitalWrite(zaslonkaVozduha, HIGH); // Назначаем первичное состояние ячейки Воздушой заслонки "HIGH" - подача воздуха закрыта
digitalWrite(kranTA, LOW); // Назначаем первичное состояние ячейки Крана ТА "HIGH"
//digitalWrite(nasosPotrebiteli, HIGH); // Назначаем первичное состояние ячейки Насос потребители "HIGH"
digitalWrite(dymosos, HIGH); // Назначаем первичное состояние ячейки Дымососа "HIGH"
digitalWrite(nasosKranKotel, LOW); // Назначаем первичное состояние ячейки Насоса и крана котла "HIGH"
u8g.setRot180();
u8g.setColorIndex(1); // pixel on
Serial.begin(9600);
Serial.println("Starting single datastream upload to Xively...");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// Ошибка DHCP, установка стандартного IP-адреса
Ethernet.begin(mac, ip);
}
Serial.print("IP address: ");
for (byte thisByte = 0; thisByte < 4; thisByte++)
{
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
Serial.println();
Serial.println();
}
//----------------------------------------
//Циклически исполняемая программа
//----------------------------------------
void loop()
{
//+vasko 150224
//txaCode=analogRead(8); // считывание показаний ТХА (код от 0 до 1023, 4.9 мВ/ед)
//txaTemp=txaCode*1.0+1; // вычисление температуры дыма и добавление примерной температуры холодного спая 1 гр.С
txaTemp= thermocouple.readCelsius()+0.5; // 0.5 поправочное значение
//-vasko 150224
tempCels[1] = txaTemp;
sendToXively(1);
secondSensorInquiry(2);// Считывает показания с sensor2Id[]
temperaturePrint(2);// Пишет на дисплее показания sensor2Id[]
sendToXively(2);// Отправляет на Xively показания sensor2Id[]
thirdSensorInquiry(3);// Считывает показания с sensor3Id[]
temperaturePrint(3);//// Пишет на дисплее показания sensor3Id[
sendToXively(3);//Отправляет на Xively показания sensor3Id[]
fourthSensorInquiry(4);// Считывает показания с sensor4Id[]
temperaturePrint(4); // Пишет на дисплее показания sensor4Id[]
sendToXively(4);//Отправляет на Xively показания sensor4Id[]
fifthSensorInquiry(5);// Считывает показания с sensor5Id[]
temperaturePrint(5);// Пишет на дисплее показания sensor5Id[]
sendToXively(5);//Отправляет на Xively показания sensor5Id[]
Serial.print("Smoke temp:");
Serial.println(txaTemp);
//-----------------------------
// Условия определяющие состояние Котла -reactorActive-
//--------------------------------------
if (tempCels[2] > 95 || txaTemp > 109){ // если температура воды
reactorActive=1;//на выходе из котла более 95 градусов или дыма более 109 (105) градусов
}
if (tempCels[2] < 94 && txaTemp < 108){ // если температура воды менее 94 и
reactorActive=0;// температура дыма менее 108 (100) град. С
}
//-----------------------------
// Условия определяющие состояние ТА при разборе с него тепла
//-----------------------------------
if (tempCels[4] > 28){ // есть ли в аккумуляторе тепло (больше чем 27С)
accumulatorWarm=1;
}
if (tempCels[4] <28){ // есть ли в аккумуляторе холодно (мньше чем 27С)
accumulatorWarm=0;
}
//-----------------------------
// Условие определяющее состояние Заслонки Дыма при перегреве котла
//-----------------------------
if (tempCels[2] > 96){ // если котел нагрет, более 96 градусов
systemCRIHot=1;
}
if (tempCels[2] < 95){ // если котел нагрет, менее 95 градусов
systemCRIHot=0;
}
//-----------------------------
// Условие определяющее подпитку Котла водой из ТА
//-----------------------------
if (tempCels[2] > 85){ // если температура котла более 85 градусов
systemVeryHot=1;
}
if (tempCels[2] < 85){ // если температура котла меньше 84 градусов
systemVeryHot=0;
}
//---------------------
// Порядок работы СО в период работы котла (reactorActive)
//----------------------
if (reactorActive)
{
on(nasosKranKotel);
// Условие открытия кран ТА по перегреву
if (systemVeryHot)
{
on(kranTA); // в случае нагрева котла до 85 градусов открыть кран подачи в ТА
}
else
{
off(kranTA);
}
// Условия работы дымососа
if (txaTemp < 112) // Температура дыма меньше 112 градусов
{
//on(zaslonkaVozduha);// Закроет заслонку дым трубы,
on(dymosos);// включит мотор дымососа;
}
if (txaTemp > 125) // Температура дыма больше 125 градусов
{
off(dymosos);// остановит мотор дымососа
//off(zaslonkaVozduha);// Откроет заслонку дым. трубы
}
// Условие работы звслонки дыма и дымососа при перегреве котла выше 95 гр.
if (systemCRIHot) // Если котел перегрет более 95 градусов
{
on(zaslonkaVozduha);// Закроет заслонку дым трубы, остановить подачу воздуха в котел
off(dymosos);// остановит мотор дымососа;
}
else
{
off (zaslonkaVozduha);// откроет подачу воздуха в котел
}
}
else
{
off(nasosKranKotel); // Остановлен насос котла, закрыт кран котла
on(zaslonkaVozduha); // остановить подачу воздуха в котел
off(dymosos);
if (accumulatorWarm)
{ // если в аккумуляторе есть тепло
on(kranTA); // обогрев
delay (1000); // от
on(nasosPotrebiteli); // ТА
}
else
{
off(nasosPotrebiteli);
delay (1000);
off(kranTA);
}
}
//-----------------------------
u8g.firstPage();
do {
draw();
}
while( u8g.nextPage() );
delay(100);// 300
//-----------------------------
}
//-----------------------------
void sendToXively(byte sensorNumber)
{
datastreams[sensorNumber].setFloat(tempCels[sensorNumber]);
Serial.print("Sensor ");
Serial.print(sensorNumber);
Serial.print(" value is: ");
Serial.print(datastreams[sensorNumber].getFloat());
Serial.print(" Sending... ");
int ret = xivelyclient.put(feed, xivelyKey);
Serial.print("xivelyclient.put returned ");
Serial.println(ret);
}
//-----------------------------
/*void firstSensorInquiry(byte sensorNumber)
{
byte i;
byte ram[12];
byte rom[8];
float temp;
int divider;
ds1.reset_search();
if ( !ds1.search(rom)) {
sensorOnline[sensorNumber] = 0;
tempCels[sensorNumber]=0;}// если не включен- задает значение ноль
else {
sensorOnline[sensorNumber] = 1;
ds1.reset();
ds1.select(rom);
ds1.write(0x44, 1);
delay(900);
ds1.reset();
ds1.select(rom);
ds1.write(0xBE);
for ( i = 0; i < 9; i++) {
ram[i] = ds1.read();}
crcTest(rom, ram, sensorNumber);
divider = sensorType(rom[0]);
temp=(ram[1]<<8)+ram[0];
tempCels[sensorNumber] = temp/divider;
}
return;
} */
//-----------------------------
void secondSensorInquiry(byte sensorNumber)
{
byte i;
byte ram[12];
byte rom[8];
float temp;
int divider;
ds2.reset_search();
if ( !ds2.search(rom)) {
sensorOnline[sensorNumber] = 0;
tempCels[sensorNumber]=0;
}// если не включен- задает значение ноль
else {
sensorOnline[sensorNumber] = 1;
ds2.reset();
ds2.select(rom);
ds2.write(0x44, 1);
delay(800);// 900
ds2.reset();
ds2.select(rom);
ds2.write(0xBE);
for ( i = 0; i < 9; i++) {
ram[i] = ds2.read();
}
crcTest(rom, ram, sensorNumber);
divider = sensorType(rom[0]);
temp=(ram[1]<<8)+ram[0];
tempCels[sensorNumber] = temp/divider;
}
return;
}
//-----------------------------
void thirdSensorInquiry(byte sensorNumber)
{
byte i;
byte ram[12];
byte rom[8];
float temp;
int divider;
ds3.reset_search();
if ( !ds3.search(rom)) {
sensorOnline[sensorNumber] = 0;
tempCels[sensorNumber]=0;
}// если не включен- задает значение ноль
else {
sensorOnline[sensorNumber] = 1;
ds3.reset();
ds3.select(rom);
ds3.write(0x44, 1);
delay(800); // 900
ds3.reset();
ds3.select(rom);
ds3.write(0xBE);
for ( i = 0; i < 9; i++) {
ram[i] = ds3.read();
}
crcTest(rom, ram, sensorNumber);
divider = sensorType(rom[0]);
temp=(ram[1]<<8)+ram[0];
tempCels[sensorNumber] = temp/divider;
}
return;
}
//-----------------------------
void fourthSensorInquiry(byte sensorNumber)
{
byte i;
byte ram[12];
byte rom[8];
float temp;
int divider;
ds4.reset_search();
if ( !ds4.search(rom)) {
sensorOnline[sensorNumber] = 0;
tempCels[sensorNumber]=0;
}// если не включен- задает значение ноль
else {
sensorOnline[sensorNumber] = 1;
ds4.reset();
ds4.select(rom);
ds4.write(0x44, 1);
delay(800); // 900
ds4.reset();
ds4.select(rom);
ds4.write(0xBE);
for ( i = 0; i < 9; i++) {
ram[i] = ds4.read();
}
crcTest(rom, ram, sensorNumber);
divider = sensorType(rom[0]);
temp=(ram[1]<<8)+ram[0];
tempCels[sensorNumber] = temp/divider;
}
return;
}
//-----------------------------
void fifthSensorInquiry(byte sensorNumber)
{
byte i;
byte ram[12];
byte rom[8];
float temp;
int divider;
ds5.reset_search();
if ( !ds5.search(rom)) {
sensorOnline[sensorNumber] = 0;
tempCels[sensorNumber]=0;
} // если не включен- задает значение ноль
else {
sensorOnline[sensorNumber] = 1;
ds5.reset();
ds5.select(rom);
ds5.write(0x44, 1);
delay(800); //900
ds5.reset();
ds5.select(rom);
ds5.write(0xBE);
for ( i = 0; i < 9; i++) {
ram[i] = ds5.read();
}
crcTest(rom, ram, sensorNumber);
divider = sensorType(rom[0]);
temp=(ram[1]<<8)+ram[0];
tempCels[sensorNumber] = temp/divider;
}
return;
}
//-----------------------------
void crcTest(byte romCode[8], byte ramCode[12], byte sensorNumber)
{
if ( OneWire::crc8(romCode, 7) == romCode[7] && OneWire::crc8(ramCode, 8)== ramCode[8] ){
Serial.print("CRC-");
Serial.print(sensorNumber);
Serial.print(" OK.");
return;
}
else {
Serial.print("CRC-");
Serial.print(sensorNumber);
Serial.print(" ERROR!");
sensorOnline[sensorNumber] = 0;
return;
}
}
//-----------------------------
int sensorType(byte serCode)
{
if ( serCode == 0x10) {
Serial.print("Sensor is 18S20.");
return 2;
}
if ( serCode == 0x28) {
Serial.print("Sensor is 18B20.");
return 16;
}
}
//-----------------------------
void temperaturePrint(int sensorNumber)
{
if (sensorOnline[sensorNumber]) {
Serial.print("Temp ");
Serial.print(sensorNumber);
Serial.print(" is ");
Serial.print(tempCels[sensorNumber],2);
Serial.print("C.\n");
}
else {
Serial.print("Sensor ");
Serial.print(sensorNumber);
Serial.print(" not connected\n");
delay (200); // 200
}
return;
}
//-----------------------------
void on (int relay)
{
digitalWrite(relay, LOW);
}
//-----------------------------
void off (int relay)
{
digitalWrite(relay, HIGH);
}
//-----------------------------
void tempOutGraph(int sensor, int x, int y)
{
if (sensorOnline[sensor]){
u8g.setPrintPos(x, y);
u8g.print(tempCels[sensor],1);
}
else {
u8g.drawStr(x+7, y, "NC");
}
}
Остання редакція glory24 (2017-03-11 16:01:50)
Неактивний
Я могу вам помочь, разобраться с этим "Мега" сервером. Не даром, конечно.
Сторінки 1