Код ArduinoCode для 1-wire

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

Модератор: immortal

sochkasov
Сообщения: 21
Зарегистрирован: Ср июл 25, 2012 4:15 pm
Благодарил (а): 0
Поблагодарили: 0

Код ArduinoCode для 1-wire

Сообщение sochkasov » Пт сен 07, 2012 11:37 am

Немного переделал код разработанный автором: http://smartliving.ru/Main/ArduinoCode
Дописал код для использования 1-wire (для подключения нескольких датчиков температуры на 1 ногу контроллера).
Некоторые мелкие изменения.
Т.к. планирую дальше развивать код, то решил выложить на http://github.com/sochkasov/majordomo-arduino/

Вообще есть идеи как развить код дальше, если все получится, буду делиться наработками :)

Вот начальный код:

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

/**
* Platform: Arduino UNO R3 + EthernetShield W5100
* Подключение датчиков температуры DS18x20 по схеме с нормальным питанием (пример http://sourceforge.net/apps/trac/arduios/wiki/owmon)
* данные (зеленый провод со схемы по ссылке указанной выше) подключаем на D2
* ВНИМАНИЕ! Для того чтобы у Вас заработало получение данных с детчиков температуры, нужно прописать адреса ваших датчиков (ниже по коду)
*
* Остальные датчики:
* Digital 4 - Датчик гаражной двери
* Digital 5 - Датчик въездных ворот
* Digital 6 - Датчик движения 1
* Digital 7 - Датчик движения 2
* Digital 8 - Датчик света
*  
*
*
**/
#include <Ethernet.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <math.h>

// MAC-адрес нашего устройства
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 8, 120 };
byte subnet[] = { 255, 255, 255, 0 };
byte gateway[] = { 192, 168, 8, 1 };
byte dns_server[] = { 192, 168, 8, 1 };
// ip-адрес удалённого сервера
byte server[] = { 192, 168, 10, 130 };

EthernetClient rclient;

// Pin controller for connection data pin DS18S20
#define ONE_WIRE_BUS 2 // D2 pin Arduino (куда подключен выход с шины датчиков DS18X20
#define TEMPERATURE_PRECISION 9

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// Настройка датчиков температуры (адреса удобно определять программой из примера DallasTemperature/Mulriple)
//Device 0 Address: 1060CF59010800E3
//Device 1 Address: 109ABE59010800FE
// Датчик температуры на 3-й пин (зал)
DeviceAddress Termometer1 =  { 0x10, 0x60, 0xCF, 0x59, 0x1, 0x8, 0x0, 0xE3 };
// Датчик температуры на 2-й пин (котёл)
DeviceAddress Termometer2 = { 0x10, 0x9A, 0xBE, 0x59, 0x1, 0x8, 0x0, 0xFE };

// Инициализация начальных значений
float tempC;
int old_temperature1=0;
int old_temperature2=0;
int old_garage=0;
int old_entry=0;
int old_movement_1=0;
int old_movement_2=0;
int old_light=0;
char buf[80];
char ipbuff[16];

// ------------------------------------------------------------------------------------------------

// Функция отправки HTTP-запроса на сервер
void sendHTTPRequest() {
  Serial.println(buf); 
  if (rclient.connect(server, 80)) { 
   Serial.println("OK"); 
   rclient.print(buf);
   rclient.println(" HTTP/1.0");
   rclient.print("Host: ");
   sprintf(ipbuff, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
   rclient.println(ipbuff); // ip адрес нашего контроллера в текстовом виде
   rclient.print("Content-Type: text/html\n");
   rclient.println("Connection: close\n");
   delay(2000);
   rclient.stop();
  } else {
   Serial.println("FAILED");     
  }
}

// ------------------------------------------------------------------------------------------------
void setup()
{
  // Для дебага будем выводить отладочные сообщения в консоль
  Serial.begin(9600);
  Serial.println("Start");

// Настройки 1-wire 
  sensors.begin(); // Инициализация шины 1-wire (для датчиков температуры)

// Определим сколько датчиков на шине
  Serial.print("1-wire: found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.print(" devices.");
  Serial.print(" Parasite power is: "); 
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

/*  
if (sensors.validAddress(Termometer1) == true) {
  Serial.println("Address is VALID");
  if (sensors.isConnected(Termometer1) == true) {
    Serial.println("Termometer1 isConnected");
    sensors.setResolution(Termometer1, TEMPERATURE_PRECISION);
    sensors.setResolution(Termometer2, TEMPERATURE_PRECISION);
  } else {
    Serial.println("Termometer1 isConnected=false");
  }
}
*/

 Ethernet.begin(mac, ip, dns_server, gateway, subnet); // Инициализируем Ethernet Shield

 pinMode(4, INPUT); // Датчик гаражной двери
 old_garage=digitalRead(4);

 pinMode(5, INPUT); // Датчик въездных ворот
 old_entry=digitalRead(5);

 pinMode(6, INPUT); // Датчик движения 1
 old_movement_1=digitalRead(6);

 pinMode(7, INPUT); // Датчик движения 2
 old_movement_2=digitalRead(7);

 pinMode(8, INPUT); // Датчик света
 old_light=digitalRead(8);

}

// ------------------------------------------------------------------------------------------------
void loop()
{

  // Перед каждым получением температуры надо ее запросить
  sensors.requestTemperatures();
  
  int valid_sensor=0;

  delay(1000); // задержка в 1 сек.  


  // TEMP SENSOR 1 --------------------------------------
  float current_temp1=0;
  tempC = sensors.getTempC(Termometer1); // Получим температуру от датчика (или ошибку)
  if (tempC == DEVICE_DISCONNECTED) { 
    // Устройство отсоеденнено
    Serial.println("Termometer1 is DEVICE_DISCONNECTED");
    // TODO Послать бы на сервер сигнал о том, что датчит не отвечает
    
  } else {
    // Устройство отдало реальное значение температуры (или осталось старое)
    Serial.print("T1: ");
    current_temp1 = tempC; // получаем температуру
    Serial.println(current_temp1);
    if ((old_temperature1!=(int)current_temp1) && (current_temp1<79) && (current_temp1>5)) {
      int temp1 = (current_temp1 - (int)current_temp1) * 100; // выделяем дробную часть
      sprintf(buf, "GET /objects/?object=sensorKotel&op=m&m=tempChanged&t=%0d.%d", (int)current_temp1, abs(temp1));   
      sendHTTPRequest();
    }
  old_temperature1=(int)current_temp1;
  }


  // TEMP SENSOR 2 --------------------------------------
  float current_temp2=0;
  tempC = sensors.getTempC(Termometer2); // Получим температуру от датчика (или ошибку)
  if (tempC == DEVICE_DISCONNECTED) { 
    // Устройство отсоеденнено
    Serial.println("Termometer2 is DEVICE_DISCONNECTED");
    // TODO Послать бы на сервер сигнал о том, что датчит не отвечает
    
  } else {
    // Устройство отдало реальное значение температуры (или осталось старое)
    Serial.print("T2: ");
    current_temp2 = tempC; // получаем температуру
    Serial.println(current_temp2);
    if ((old_temperature2!=(int)current_temp2) && (current_temp2<50) && (current_temp2>5)) {
      int temp1 = (current_temp2 - (int)current_temp2) * 100; // выделяем дробную часть
      sprintf(buf, "GET /objects/?object=sensorZal&op=m&m=tempChanged&t=%0d.%d", (int)current_temp2, abs(temp1));   
      sendHTTPRequest();
    }
  old_temperature2=(int)current_temp2;
  }
  

  //GARAGE GATES SENSOR
  Serial.println("G");
  int current_garage=digitalRead(4);
  //Serial.println(current_garage);
  if (current_garage!=(int)old_garage) {
    old_garage=(int)current_garage;
    sprintf(buf, "GET /objects/?object=sensorGarage&op=m&m=statusChanged&status=%i", (int)current_garage);
    sendHTTPRequest();
  }

 //ENTRY GATES SENSOR

  Serial.println("E");
  int current_entry=digitalRead(5);
  //Serial.println(current_entry);
  if (current_entry!=(int)old_entry) {
    old_entry=(int)current_entry;
    sprintf(buf, "GET /objects/?object=sensorEntry&op=m&m=statusChanged&status=%i", (int)current_entry);
    sendHTTPRequest();
  }

 //MOVEMENT 1 SENSOR
  Serial.println("M1");
  int current_movement_1=digitalRead(6);
  //Serial.println(current_movement_1);
  if (current_movement_1!=(int)old_movement_1) {
    old_movement_1=(int)current_movement_1;
    sprintf(buf, "GET /objects/?object=sensorMovement1&op=m&m=statusChanged&status=%i", (int)current_movement_1);
    sendHTTPRequest();
  }

 //MOVEMENT 2 SENSOR
  Serial.println("M2");
  int current_movement_2=digitalRead(7);
  //Serial.println(current_movement_2);
  if (current_movement_2!=(int)old_movement_2) {
    old_movement_2=(int)current_movement_2;
    sprintf(buf, "GET /objects/?object=sensorMovement2&op=m&m=statusChanged&status=%i", (int)current_movement_2);
    sendHTTPRequest();
  }


 //LIGHT SENSOR

  Serial.println("L");
  int current_light=digitalRead(8);
  //Serial.println(current_light);
  if (current_light!=(int)old_light) {
    old_light=(int)current_light;
    sprintf(buf, "GET /objects/?object=sensorLight&op=m&m=statusChanged&status=%i", (int)current_light);
    sendHTTPRequest();
  }  
}
Jager
Сообщения: 708
Зарегистрирован: Сб авг 18, 2012 10:21 am
Благодарил (а): 26 раз
Поблагодарили: 183 раза

Re: Код ArduinoCode для 1-wire

Сообщение Jager » Пт сен 07, 2012 6:46 pm

sochkasov писал(а): // Датчик температуры на 3-й пин (зал)
DeviceAddress Termometer1 = { 0x10, 0x60, 0xCF, 0x59, 0x1, 0x8, 0x0, 0xE3 };
// Датчик температуры на 2-й пин (котёл)
DeviceAddress Termometer2 = { 0x10, 0x9A, 0xBE, 0x59, 0x1, 0x8, 0x0, 0xFE };
[/code]
А почему на разные пины? а если у меня 20 термометров, логичнее все DS18B20 повесить на один вход, благо библиотека позволяет.
sochkasov
Сообщения: 21
Зарегистрирован: Ср июл 25, 2012 4:15 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Код ArduinoCode для 1-wire

Сообщение sochkasov » Вс сен 09, 2012 2:07 pm

Jager писал(а):
sochkasov писал(а): // Датчик температуры на 3-й пин (зал)
DeviceAddress Termometer1 = { 0x10, 0x60, 0xCF, 0x59, 0x1, 0x8, 0x0, 0xE3 };
// Датчик температуры на 2-й пин (котёл)
DeviceAddress Termometer2 = { 0x10, 0x9A, 0xBE, 0x59, 0x1, 0x8, 0x0, 0xFE };
[/code]
А почему на разные пины? а если у меня 20 термометров, логичнее все DS18B20 повесить на один вход, благо библиотека позволяет.
Прошу прощения комментарии не все поправил. На самом деле код правильный. Датчики сажать надо на 1 ногу.
А указанный Вами кусок код будет выглядеть так:

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

// Датчик температуры (зал)
DeviceAddress Termometer1 =  { 0x10, 0x60, 0xCF, 0x59, 0x1, 0x8, 0x0, 0xE3 };
// Датчик температуры (котёл)
DeviceAddress Termometer2 = { 0x10, 0x9A, 0xBE, 0x59, 0x1, 0x8, 0x0, 0xFE };
Кстати, забыл добавить. Писалось и компилировалось все на Arduino 1.0.1
Аватара пользователя
ser009
Сообщения: 595
Зарегистрирован: Сб окт 13, 2012 9:55 am
Благодарил (а): 4 раза
Поблагодарили: 43 раза

Re: Код ArduinoCode для 1-wire

Сообщение ser009 » Пн ноя 19, 2012 7:36 pm

Доброго времени суток.
Приехала Arduino Mega2560 :D

Сидел перебирал написанные проекты под Arduino.

Остановился на прошивке Исполнительный контроллер на Arduino от sochkasov

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

Анализировал прошивки и каждый называет дискретные выхода кто как умеет :roll:

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

float tempC;
int old_temperature1=0;
int old_temperature2=0;
int old_garage=0;
int old_entry=0;
int old_movement_1=0;
int old_movement_2=0;
int old_light=0;
char buf[80];
char ipbuff[16];
Проект мне очень нравится и хочу предложить определится с концами и входами/выходами, тем боле что на плате они пронумерованы (Я говорю о ARDUINO)

Допустим:
2 - порт для 1-wire
3 - что-то ещё
4 - и так далее
5 - 13 - порты Output (дискретный выход, управляющие элементы, реле, пускатели, привода)
14 - 20 - порты Input (дискретный вход: кнопки, концевые выключатели)
и т.д. аналоговые входы обозначить.

Просто на моей плате выходов свыше 50 выходов на всё хватит :)

Ещё раз оговорюсь что речь идёт для "Стандартной прошивки" допустим для Mega2560, Mega1280, Uno и т.д.

И при оформлении в свойствах проще перечисляй Out`ы и Inp`уты, а в дополнении (описании) уже добавить Гараж Двор Подвал и т.д.
Vit
Сообщения: 867
Зарегистрирован: Вт янв 17, 2012 12:31 pm
Благодарил (а): 121 раз
Поблагодарили: 78 раз

Re: Код ArduinoCode для 1-wire

Сообщение Vit » Вт ноя 20, 2012 12:04 pm

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

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

Может данные ветки по программированию и все что каcается arduino собрать в оду ветку по железу с разделом arduino а там можно подразделы сделать...отдельно код и все что с ним связано , отдельно описание и т.д. думаю так правильней будет, тоже самое сделать по 1-wire сети...

предлагайте свои варианты если с чем то не согласны
Аватара пользователя
ser009
Сообщения: 595
Зарегистрирован: Сб окт 13, 2012 9:55 am
Благодарил (а): 4 раза
Поблагодарили: 43 раза

Re: Код ArduinoCode для 1-wire

Сообщение ser009 » Вт ноя 20, 2012 2:36 pm

давайте начну описывать в общем Типы сигналов далее скорректируем

Вход - I
Выход - O

Дискретные D
DI - дискретные входа (тут просто)
DO - дискретные выхода (здесь тоже понятно)

Аналоговые A
AI - аналоговые входа (пример с измерением напряжения)
AO - аналоговые выхода (допустим для регулирования освещения в помещении)

Счётчики F
FI - счетные входа (допустим для замера параметра с счётчика воды)

1-Wire
Вот тут нужно подумать :roll:
Протокол может работать в режиме опроса прописанных датчиков (допустим температуры, исполнительных датчиков и т.д.).
И в режиме ожидания допустим если протокол используется в системе контроля доступа (например датчик DS1990)

Вот допустим 8 порт назначить выходом будет DO8

Ну как-то так...
Жду ваших предложений :)
Sergey
Сообщения: 12
Зарегистрирован: Чт ноя 15, 2012 12:27 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Код ArduinoCode для 1-wire

Сообщение Sergey » Пт ноя 23, 2012 1:39 pm

По поводу 1-wire и arduino хочу сказать несколько слов. Датчики на этой шине очень медленые и вешать их целую кучу на arduino не очень хорошо, можно столкнуться с одной проблемой не очень приятной...Во время чтния информации с датчиков контроллер останавливается и ждет определенное время и все внешнии сигналы он не воспринимает, вот здесь и есть засада, любое нажатие кнопки , внешний управляющий сигнал, счетчик импульсов и т.д. не будет принято arduino, событие пройдет незамеченным.
Если делается устройство которое например делает только одну задачу - управляет клапаном отопления, то это неважно .
Как только понадобится обрабатывать внешнии сигналы об этом надо помнить.
Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: Код ArduinoCode для 1-wire

Сообщение sergejey » Пт ноя 23, 2012 2:58 pm

Абсолютно согласен с последним комментарием. Вместе с датчиками температуры можно вешать только то, что не требует мгновенной реакции. Например, у меня висят концевики ворот -- всё ок, там задержка в пару секунд не критична. Но повесил туда же кнопку и зачастую система на неё не реагирует, т.к. контроллер может быть занят опросом датчиков температуры. В общем, такие вещи лучше разносить на разные контроллеры.

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
electric
Сообщения: 309
Зарегистрирован: Вт сен 17, 2013 10:11 pm
Благодарил (а): 3 раза
Поблагодарили: 56 раз

Re: Код ArduinoCode для 1-wire

Сообщение electric » Вт янв 28, 2014 7:57 pm

sergejey писал(а):Абсолютно согласен с последним комментарием. Вместе с датчиками температуры можно вешать только то, что не требует мгновенной реакции. Например, у меня висят концевики ворот -- всё ок, там задержка в пару секунд не критична. Но повесил туда же кнопку и зачастую система на неё не реагирует, т.к. контроллер может быть занят опросом датчиков температуры. В общем, такие вещи лучше разносить на разные контроллеры.
Можно воспользоваться прерываниями. На Arduino UNO это ножки pin2, pin3.
Было: Majordomo v.0.6.0.b на Cubietruck. OS Armbian с переносом на HDD
Стало: ioBroker на Cubietruck OS Armbian + ZigBee Xiaomi + OWFS + BLE.
Anton_kulibin
Сообщения: 354
Зарегистрирован: Вт окт 09, 2012 8:05 am
Откуда: Луза Кировская обл. Россия
Благодарил (а): 20 раз
Поблагодарили: 35 раз

Re: Код ArduinoCode для 1-wire

Сообщение Anton_kulibin » Вт янв 28, 2014 8:50 pm

Что то все замерло мне только стало нравиться
Linux версия. Ubuntu Server 16.04+2xArduinoMega+Eth_GW_Mysensors_10node+WeatherStation+Xiaomi
CONNECT
Ответить