Подключение железа к AMS

Модератор: Alex

serghei
Сообщения: 2575
Зарегистрирован: Пт ноя 06, 2015 10:22 am
Откуда: Кишинёв
Благодарил (а): 303 раза
Поблагодарили: 282 раза

Re: Подключение железа к AMS

Сообщение serghei » Сб фев 02, 2019 11:27 pm

Сильно получилось! Особенно интересует реализация 485 протокола. Скетч отработан для этого ? Можно его увидеть ?
AMS : ESP32 + NRF24 + 1Wire-I2C мост DS2482 + счетчик DS2423 + сеть MySensors + редактирование страниц в браузере + Upload по воздуху + SPIFFS
Аватара пользователя
shemnik69
Сообщения: 590
Зарегистрирован: Пн дек 24, 2012 3:01 pm
Откуда: Саратов Saratov
Благодарил (а): 67 раз
Поблагодарили: 63 раза

Re: Подключение железа к AMS

Сообщение shemnik69 » Вс фев 03, 2019 12:56 am

Приветствую Сергей. Из всего чем могу поделится пока это. лут печатных плат и пока сырым начальным скетчем обработки кнопок, контактов и вывода информации на индикатор (время дата состояние и пр. также температурные датчики.
Скетч сильно сложный. Уже столько переделок. Пока пишу один вариант приходит мысль что то добавить или изменить ... короче творческие муки.
1. Опираюсь в основном на тот сайт который тебе посылал. mypractic.ru его изучал два месяца на вахте. много почерпнул.
из результата, это работа всех основных модулей на прерываниях от таймера.
Также таймеры, у меня не на милисах (milis) а от генератора прерываний 2 мс. На него ориентируется опрос кнопок датчиков. Библиотека с того сайта да и основные идеи. Ну а время от РТС модуля.
Модбус пока еще только в основных набросках.
Скетч могу скинуть но наверное он будет не совсем понятен без основного железа.
также на сайте Ардуино.ru есть интересная статья про частный дом и систему на мега 256. там есть скетч и схема и главное уже отработано само ядро т.е. костяк скетча.
Поскольку все решения моего "АМС" типовые то скетч перерабатывается легко.
485 интерфейс уже заложен конечно. Это порт Serial2 и D2 на управление прием передача микросхемой MAX485/ Сама микросхема стоит разведена и размещены основные ее компоненты.
Пробные тесты с библиотекой типа модбус или modbusino показали что работает.
теперь идея и реализация в том чтобы встроить этот комплекс в уже работающую сетку причем как мастер сети. Почему так.
я сейчас приготовил кучу разных датчиков и ардуино мини, а также хорошие корпуса для них и постепенно буду их собирать уже под готовые задачи т.е есть датчик под него маленький процессор либо с NRF24l01 либо 485 который мне ближе. НО хочу сделать так чтобы работало все просто а вот тут как раз и сложность...
Если конечно интересна наработка то поделюсь.
serghei
Сообщения: 2575
Зарегистрирован: Пт ноя 06, 2015 10:22 am
Откуда: Кишинёв
Благодарил (а): 303 раза
Поблагодарили: 282 раза

Re: Подключение железа к AMS

Сообщение serghei » Вт фев 05, 2019 11:28 am

Чтобы реализовать термостат , надо определиться каким образом управлять реле и их количеством. Самый простой способ - в скетче задать пороги включения по датчику. У меня это работает на ESP32, но думаю точно так же будет и на остальных платформах. Для начала добавить вкладку " Реле" ( у меня названа "test")

Код: Выделить всё

#define relePin 04 // Назначаем пины реле . На Меге будут другие.
#define rele1Pin 26
#define rele2Pin 25
#define rele3Pin 32


void testInit(){
  pinMode(relePin, OUTPUT);
  digitalWrite(relePin, LOW);

  pinMode(rele1Pin, OUTPUT);
  digitalWrite(relePin, LOW);

  pinMode(rele2Pin, OUTPUT);
  digitalWrite(relePin, LOW);

  pinMode(rele3Pin, OUTPUT);
  digitalWrite(relePin, LOW);
}
//==============
void testRele(){ // рабочая функция 
  if(!releSt && current_temp[3] > 40.0){ // Привязываем к показаниям DS18B20 из вкладки температуры
   // if(!releSt && analogRead(35) > 2000.0){ // Можно привязать к величине с аналогового входа
      
  digitalWrite(relePin, HIGH);

  timeStamp();
  Serial.println(" Rele \"ON\"");
  releSt = 1;

    MessText = "Реле 1 включено";
    MessLoger(String (MessText), String(Info)); // если нет логирования событий , то закомментировать

  }
  if(releSt && current_temp[3] < 35.0){ //  Условия для первого реле. Привязано к четвертому гладуснику.

  //  if(releSt && analogRead(35) < 1500.0){
  digitalWrite(relePin, LOW);
 timeStamp();
  Serial.println(" Rele \"OFF\"");
  releSt = 0;

    MessText = "Реле 1 выключено";
    MessLoger(String (MessText), String(Info));

  }
}
//========================================

void testRele1(){ // рабочая функция 
  if(!rele1St && current_temp[3] > 30.0){
   // if(!releSt && analogRead(35) > 2000.0){
      
  digitalWrite(rele1Pin, HIGH);

  timeStamp();
  Serial.println(" Rele_1 \"ON\"");
  rele1St = 1;

    MessText = "Реле 2 включено";
    MessLoger(String (MessText), String(Info));  
  }
  if(rele1St && current_temp[3] < 28.0){

  //  if(releSt && analogRead(35) < 1500.0){
  digitalWrite(rele1Pin, LOW);
 timeStamp();
  Serial.println(" Rele_1 \"OFF\"");
  rele1St = 0;

    MessText = "Реле 2 выключено";
    MessLoger(String (MessText), String(Info));
      
  }
}

void testRele2(){ // рабочая функция 
  if(!rele2St && current_temp[3] > 25.0){
   // if(!releSt && analogRead(35) > 2000.0){
      
  digitalWrite(rele2Pin, HIGH);

  timeStamp();
  Serial.println(" Rele_2 \"ON\"");
  rele2St = 1;

    MessText = "Реле 3 включено";
    MessLoger(String (MessText), String(Info));   
  }
  if(rele2St && current_temp[3] < 22.0){

  //  if(releSt && analogRead(35) < 1500.0){
  digitalWrite(rele2Pin, LOW);
 timeStamp();
  Serial.println(" Rele_2 \"OFF\"");
  rele2St = 0;

    MessText = "Реле 3 выключено";
    MessLoger(String (MessText), String(Info));  
  }
}

void testRele3(){ // рабочая функция 
  if(!rele3St && current_temp[3] > 20.0){
   // if(!releSt && analogRead(35) > 2000.0){
      
  digitalWrite(rele3Pin, HIGH);

  timeStamp();
  Serial.println(" Rele_3 \"ON\"");
  rele3St = 1;

    MessText = "Реле 4 включено";
    MessLoger(String (MessText), String(Info));  
  }
  if(rele3St && current_temp[3] < 17.0){ // Четвертое реле к четвертому градуснику.

  //  if(releSt && analogRead(35) < 1500.0){
  digitalWrite(rele3Pin, LOW);
 timeStamp();
  Serial.println(" Rele_3 \"OFF\"");
  rele3St = 0;

    MessText = "Реле 4 выключено";
    MessLoger(String (MessText), String(Info));    
  }
}
Чтобы код работал , в самом начале определяем статусы реле перед описанием модулей

Код: Выделить всё

bool releSt = 0; // вот на это может ругаться, что переменная не объявлена
bool rele1St = 0; 
bool rele2St = 0;
bool rele3St = 0; 

// modules
#define FEATURE_UPLOAD
#define FEATURE_SD
#define FEATURE_TIME
#define FEATURE_NTP
Далее в конце Сетапа

Код: Выделить всё

  testInit();
  
} // setup
И в Лупе

Код: Выделить всё

   testRele(); 
   testRele1();
   testRele2();
   testRele3();             

    workAbstract();
    workLoopEnd();      
  } // MODE_SERVER
Далее в зависимости от того , куда и на какую страницу выводить состояние реле ( включено - выключено ) Проще всего в сервере-ажакс в разделе void responseDash ( У Меги может по другому вызываться ) добавляем

Код: Выделить всё

void responseDash(WiFiClient cl) {
  String s = tagXmlVersion();
  s += "\n<inputs>\n";
  s += makeModules();
  s += makeTag("auth",    "", String(authMode));
  s += makeTag("uptime",  "", uptimeString());
  ----------
  s += makeTag("rele1",    "", String(releSt));// Пишем любое понятное название и статус
  s += makeTag("rele2",    "", String(rele1St));
  s += makeTag("rele3",    "", String(rele2St));
  s += makeTag("rele4",    "", String(rele3St));   
Чтобы увидеть это на странице в скрипте добавляем

Код: Выделить всё

            // Rele_1
			
            try {var releRele1 = this.responseXML.getElementsByTagName('rele1')[0].childNodes[0].nodeValue;} catch (err) {releRele1 = "-1";}
            switch (releRele1) {
              case "0":
                releRele1_ = 'Выключено';
                break;
              case "1":
                releRele1_ = 'Включено';
                break;
              default:
                releRele1_ = 'состояние неизвестно';
              break;
            }            
            try {document.getElementById("dash-rele-rele1").innerHTML = releRele1_;} catch (err) { }
            try {document.getElementById("dash-rele-rele1-hide").innerHTML = releRele1_;} catch (err) { }		
            
            
            // Rele_2
			
            try {var releRele2 = this.responseXML.getElementsByTagName('rele2')[0].childNodes[0].nodeValue;} catch (err) {releRele2 = "-1";}
            switch (releRele2) {
              case "0":
                releRele2_ = 'Выключено';
                break;
              case "1":
                releRele2_ = 'Включено';
                break;
              default:
                releRele2_ = 'состояние неизвестно';
              break;
            }            
            try {document.getElementById("dash-rele-rele2").innerHTML = releRele2_;} catch (err) { }
            try {document.getElementById("dash-rele-rele2-hide").innerHTML = releRele2_;} catch (err) { }	
            
            // Rele_3
			
            try {var releRele3 = this.responseXML.getElementsByTagName('rele3')[0].childNodes[0].nodeValue;} catch (err) {releRele3 = "-1";}
            switch (releRele3) {
              case "0":
                releRele3_ = 'Выключено';
                break;
              case "1":
                releRele3_ = 'Включено';
                break;
              default:
                releRele3_ = 'состояние неизвестно';
              break;
            }            
            try {document.getElementById("dash-rele-rele3").innerHTML = releRele3_;} catch (err) { }
            try {document.getElementById("dash-rele-rele3-hide").innerHTML = releRele3_;} catch (err) { }	
            
            // Rele_4
			
            try {var releRele4 = this.responseXML.getElementsByTagName('rele4')[0].childNodes[0].nodeValue;} catch (err) {releRele4 = "-1";}
            switch (releRele4) {
              case "0":
                releRele4_ = 'Выключено';
                break;
              case "1":
                releRele4_ = 'Включено';
                break;
              default:
                releRele4_ = 'состояние неизвестно';
              break;
            }            
            try {document.getElementById("dash-rele-rele4").innerHTML = releRele4_;} catch (err) { }
            try {document.getElementById("dash-rele-rele4-hide").innerHTML = releRele4_;} catch (err) { }	   
Ну и уже по желанию выводить на любую страницу. Например в даш-панель так

Код: Выделить всё

  <div class="dash">   

    <div class="block spaces-10">
      <div class="lev-hide show">
        <div class="cell-2-fixed">
          <div class="box-dash" title="Важные параметры">
		  

			<p>Реле 1 : <span class="value" id="dash-rele-rele1">...</span></p>
			<p>Реле 2 : <span class="value" id="dash-rele-rele2">...</span></p>
			<p>Реле 3 : <span class="value" id="dash-rele-rele3">...</span></p>
			<p>Реле 4 : <span class="value" id="dash-rele-rele4">...</span></p>
По смыслу в зависимости от платформы. На выходе получится такая картинка
СпойлерПоказать
Форум.jpg
Форум.jpg (69.04 КБ) 5190 просмотров
PS/ Это самый простой , но очень надежный способ. По правильному можно и нужно пороги задавать со страницы. Но тут есть очень много вопросов.
За это сообщение автора serghei поблагодарил:
noname_npc (Вт фев 05, 2019 11:47 am)
Рейтинг: 1.16%
AMS : ESP32 + NRF24 + 1Wire-I2C мост DS2482 + счетчик DS2423 + сеть MySensors + редактирование страниц в браузере + Upload по воздуху + SPIFFS
serghei
Сообщения: 2575
Зарегистрирован: Пт ноя 06, 2015 10:22 am
Откуда: Кишинёв
Благодарил (а): 303 раза
Поблагодарили: 282 раза

Re: Подключение железа к AMS

Сообщение serghei » Вт фев 05, 2019 12:18 pm

Что бы вывести уровень сигнала WiFi , надо его померить )). В примерах для ESP32 это есть. Будет работать на 8266 я не знаю ( не проверял). Для этого добавляем в код во вкладке " WiFi" следующее

Код: Выделить всё

  WiFi.begin(ssid, pass);
  WiFi.config(ip, gateway, subnet);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(F("."));
  }
  Serial.println();
  Serial.println(F(" WiFi:       connected"));
  Serial.print(F(" IP address: "));
  Serial.println(WiFi.localIP());

            Serial.println(" (");
            Serial.print(WiFi.RSSI()); // стандартная функция в библиотеке
            Serial.print(")");
            
  initDone(false);
}
 void workWifi() {
  
    if(cycle1m) { 
            timeStamp();
            Serial.print("WiFi : ");
            Serial.print(WiFi.SSID());
            Serial.print(" (");
            Serial.print(WiFi.RSSI());
            Serial.print(")");
     }
     
 } 
Ну а дальше опять же в сервере ажакс придумывает название и выводим на страницу ))

Код: Выделить всё

void responseDash(WiFiClient cl) {
  String s = tagXmlVersion();
  s += "\n<inputs>\n";
  s += makeModules();
  s += makeTag("auth",    "", String(authMode));
  s += makeTag("uptime",  "", uptimeString());
  ------------------------
   s += makeTag("wifi",     "", String(WiFi.RSSI()));// придумали имя и вывели переменную
    
И опять же в скрипте в то же месте ,где и реле

Код: Выделить всё

                    // WiFi RSSI
          try {
            var WiFi = this.responseXML.getElementsByTagName('wifi')[0].childNodes[0].nodeValue;
          } catch (err) {
              WiFi = '+';
            }
          try {
            
            document.getElementById("dash-wifi").innerHTML = WiFi;
             document.getElementById("dash-wifi-hide").innerHTML = WiFi;
          } catch (err) { }
Ну и на страницу ниже реле

Код: Выделить всё

			<p>Сигнал WiFi: <span class="value" id="dash-wifi">...</span> dbf</p>
			-------------
			  <p>Сигнал WiFi: <span class="value" id="dash-wifi-hide">...</span> dbf</p>
PS/ Как видно , это базовые понятия как вывести любую переменную на страницу ))
За это сообщение автора serghei поблагодарил:
noname_npc (Вт фев 05, 2019 12:52 pm)
Рейтинг: 1.16%
AMS : ESP32 + NRF24 + 1Wire-I2C мост DS2482 + счетчик DS2423 + сеть MySensors + редактирование страниц в браузере + Upload по воздуху + SPIFFS
noname_npc
Сообщения: 48
Зарегистрирован: Сб июл 21, 2018 9:08 pm
Откуда: Калининград
Благодарил (а): 10 раз
Поблагодарили: 5 раз

Re: Подключение железа к AMS

Сообщение noname_npc » Чт фев 14, 2019 12:19 pm

Получилось сегодня управлять с мобильного через MODBUS TCP IP выходами железки MOXA E2210. Записывать и считывать регистры. Попробую на Esp32 прикрутить MODBUS. На E2210 есть rs485, буду и 485 и TCP/IP пробовать

На мобильном использую приложение Virtuino
schel4ok
Сообщения: 136
Зарегистрирован: Вс сен 02, 2018 8:03 am
Благодарил (а): 2 раза
Поблагодарили: 0

Re: Подключение железа к AMS

Сообщение schel4ok » Вс мар 03, 2019 12:09 am

Я решил вренуться к вопросу вывода температуры с датчика DHT22.
Показания в монитор порта он уже выводит.
Подключен к пину D40.

Я добавил вывод показаний пина 40 в ответ сервера

server_ajax.ino

Код: Выделить всё

String makeDigitalPorts() {
  String s = "";
  byte pins[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 34, 40};
  for (byte i = 0; i < sizeof(pins); i++) {
    s += makeTag("D", String(pins[i]), String(digitalRead(pins[i])));
  }
  return s;
}
dash.js

Код: Выделить всё

var digitalPins = ['D2','D3','D4','D5','D6','D7','D8','D9','D10', 'D22','D23','D24','D25','D26','D27','D28','D29','D30','D31','D34','D40'];
Но у меня на страницу прилетает всё время 1.
serghei
Сообщения: 2575
Зарегистрирован: Пт ноя 06, 2015 10:22 am
Откуда: Кишинёв
Благодарил (а): 303 раза
Поблагодарили: 282 раза

Re: Подключение железа к AMS

Сообщение serghei » Вс мар 03, 2019 12:33 am

Покажи полный код для датчика. И почему ты думаешь ,что

Код: Выделить всё

s += makeTag("D", String(pins[i]), String(digitalRead(pins[i])));
покажет тебе значение влажности ?
Посмотри как это надо делать примерно Так
А в сервере ажакс прописывать

Код: Выделить всё

    #ifdef TEMPVL_FEATURE
        for (byte i = 0; i < MAX_TEMPVL_SENSORS; i++) {
        s += makeTag(objSensvl[i], "",      String(current_tempvl[i]));
       }
    #endif
AMS : ESP32 + NRF24 + 1Wire-I2C мост DS2482 + счетчик DS2423 + сеть MySensors + редактирование страниц в браузере + Upload по воздуху + SPIFFS
eGorka
Сообщения: 182
Зарегистрирован: Чт ноя 24, 2016 10:47 am
Благодарил (а): 5 раз
Поблагодарили: 25 раз

Re: Подключение железа к AMS

Сообщение eGorka » Вс мар 03, 2019 6:58 am

schel4ok писал(а):
Вс мар 03, 2019 12:09 am
Я решил вренуться к вопросу вывода температуры с датчика DHT22.

Код: Выделить всё

...
    s += makeTag("D", String(pins[i]), String(digitalRead(pins[i])));
 ...
Но у меня на страницу прилетает всё время 1.
Считать уровень состояния и данные с DHT не одно и тоже.
И должна прилетать единица, т.к. в DHT.cpp

Код: Выделить всё

pinMode(_pin, INPUT_PULLUP);
schel4ok
Сообщения: 136
Зарегистрирован: Вс сен 02, 2018 8:03 am
Благодарил (а): 2 раза
Поблагодарили: 0

Re: Подключение железа к AMS

Сообщение schel4ok » Вс мар 03, 2019 9:59 am

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

кстати если датчиков несколько, то каждый надо к отдельному пину подключать или как DS18B20 к одному?

Код: Выделить всё

#ifdef DHT_FEATURE
#include "DHT.h"

#define MAX_TEMP_SENSORS  1
#define DHTTYPE DHT22     // DHT 22  (AM2302), AM2321
const int DHTPin = 40;
DHT dht(DHTPin, DHTTYPE);

static char celsiusTemp[7];
static char fahrenheitTemp[7];
static char humidityTemp[7];

void initDHT() {
  moduleDHT = MODULE_ENABLE;
  started("DHT");
}
void workDHT() {
  if (cycle5s) {
            float h = dht.readHumidity();
            float t = dht.readTemperature();
            float f = dht.readTemperature(true);
            if (isnan(h) || isnan(t) || isnan(f)) {
              Serial.println("Failed to read from DHT sensor!");
              strcpy(celsiusTemp,"Failed");
              strcpy(fahrenheitTemp, "Failed");
              strcpy(humidityTemp, "Failed");         
            }
            else{
              float hic = dht.computeHeatIndex(t, h, false);       
              dtostrf(hic, 6, 2, celsiusTemp);             
              float hif = dht.computeHeatIndex(f, h);
              dtostrf(hif, 6, 2, fahrenheitTemp);         
              dtostrf(h, 6, 2, humidityTemp);

              Serial.print("Humidity: ");
              Serial.print(h);
              Serial.print(" %\t Temperature: ");
              Serial.print(t);
              Serial.println(" *C ");

          }
      }
   }

#endif
eGorka
Сообщения: 182
Зарегистрирован: Чт ноя 24, 2016 10:47 am
Благодарил (а): 5 раз
Поблагодарили: 25 раз

Re: Подключение железа к AMS

Сообщение eGorka » Вс мар 03, 2019 2:39 pm

schel4ok писал(а):
Вс мар 03, 2019 9:59 am
кстати если датчиков несколько, то каждый надо к отдельному пину подключать или как DS18B20 к одному?
ссылка
Ответить