oneWire поиск присутствия DS18b20, DS2401 по MAC-адресу

denis999
Offline
Зарегистрирован: 16.04.2013

Здравствуйте,

помогите, пожалуйста, написать(дописать) строчку кода, которая возвращает 1, если устройство с МАС-адресом присутствует(найдено, подключено и т.д.) в сеть 1-wire.

#if defined(ARDUINO) && ARDUINO >= 100 
#include "Arduino.h"                   
#else                                  
#include "WProgram.h"                  
#endif                                 

#include <SPI.h>                      
#include <Ethernet.h>                 
#include <Wire.h>                     
#include <DS1307.h>                   

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 
byte ip[] = {192, 168, 0, 147}; 
byte subnet[] = {255, 255, 255, 0}; 
byte gateway[] = {192, 168, 0, 100};         
byte mydns[] = {192, 168, 0, 100};
byte smtp[] = {94, 100, 177, 1};
//EthernetServer server(80);
EthernetClient client;

#include <OneWire.h>                                //1-WIRE
byte i;                                             //1-WIRE
byte present = 0;                                   //1-WIRE
byte type_s;                                        //1-WIRE
byte data[12];                                      //1-WIRE
byte addr[8];                                       //1-WIRE
float celsius;                                      //1-WIRE
const int relePin =  4;
const int relePin2 =  5;
const int dat220 = 3;
int dat220State = 0;         // variable for reading the gerkon status
int fignya = 0;
byte  address_1[] = {0x28, 0xBA, 0x81, 0x9A, 0x04, 0x00, 0x00, 0xB4}; //1-WIRE термометр №1 28:BA:81:9A:4:0:0:B4:
byte  address_2[] = {0x01, 0x5D, 0x30, 0x45, 0x16, 0x00, 0x00, 0x27}; //1-WIRE геркон мет дверь 1:5D:30:45:16:0:0:27:
                    
OneWire ds (2); // все 1-WIRE устройства на pin 2
byte done[8];                                       //1-WIRE



void setup() 
{
Ethernet.begin(mac, ip, mydns, gateway, subnet);
Serial.begin(9600); 
delay(1000);   
pinMode(relePin, OUTPUT);
pinMode(relePin2, OUTPUT);
pinMode(dat220, INPUT);
}

void reeds1WARE (void) {


  if  (ds.search  (addr)!=1) {
    ds.reset_search  ();
    delay  (250);
    for(byte i = 0; i < 8; i++) addr[i] = 0;
    return;
  }
  ds.reset  ();
  ds.select  (addr);

//***расскоментировать, чтобы показывал MAC-адреса устройств вместе с температурой***
//  Serial.print("Addr:");
//  for(byte i = 0; i < 8; i++)
//{
//  Serial.print("0x");
//  if(addr[i] < 0x10) Serial.print("0");
//  Serial.print(addr[i], HEX);
//  if(i == 7) Serial.println();
//  else Serial.print(", ");
//}

  ds.write  (0x44,1); // start conversion, with parasite power on at the end
  delay  (1000); // maybe 750ms is enough, maybe not
  // we might do a ds.depower  () here, but the reset will take care of it.
  present = ds.reset  ();
  ds.select  (addr);
  ds.write  (0xBE); // Read Scratchpad
  for  (i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read ();
  }
  // convert the data to actual temperature
  unsigned int raw =  (data[1] << 8) | data[0];
  if  (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if  (data[7] == 0x10) {
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  }
  else {
    byte cfg =  (data[4] & 0x60);
    if  (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
    else if  (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if  (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
  }
  

  celsius =  (float)raw / 16.0;   
}

void(* resetFunc) (void) = 0; // Reset MC function

void loop() 
{

  if  ((ds.search  (addr)) == address_2)
{
Serial.println("ok");
}
  else
 {
digitalWrite(relePin, HIGH);
  } 
}

 

denis999
Offline
Зарегистрирован: 16.04.2013

а именно 107 строчку

maksim
Offline
Зарегистрирован: 12.02.2012

Вам же уже давали ссылку на то как это делается.

http://arduino.ru/forum/programmirovanie/3-datchika-ds18b20arduino#comment-40925

void loop() 
{
   if(ds.search(addr) != 1) 
   {
    ds.reset_search();
    delay(1000);
    for(byte i = 0; i < 8; i++) addr[i] = 0;
    return;
  }
  
  if (!memcmp(address_2, addr, 8))
  {   
    Serial.println("ok");
  }
  else
  {
    digitalWrite(relePin, HIGH);
  } 
}

 

denis999
Offline
Зарегистрирован: 16.04.2013

maksim пишет:

Вам же уже давали ссылку на то как это делается.

http://arduino.ru/forum/programmirovanie/3-datchika-ds18b20arduino#comment-40925

void loop() 
{
   if(ds.search(addr) != 1) 
   {
    ds.reset_search();
    delay(1000);
    for(byte i = 0; i < 8; i++) addr[i] = 0;
    return;
  }
  
  if (!memcmp(address_2, addr, 8))
  {   
    Serial.println("ok");
  }
  else
  {
    digitalWrite(relePin, HIGH);
  } 
}

 

 

спасибо, "ok" пишется в serial НО и РЕЛЕ срабатывает ТОЖЕ 8(. странно...

maksim
Offline
Зарегистрирован: 12.02.2012

Ничего странного, каждый неверный адрес включает реле ,а верный выводит "ок". И не НО ,так как что у вас в голове известно только вам.

denis999
Offline
Зарегистрирован: 16.04.2013

ситуация в том, что есть 2 датчика и оба они подключены. Все-таки спрашивал я о возвращении 1 если найден address_2. Точнее - другие адреса он искать вообще не должен. возможно? поиск по шаблону и вывод 1 или 0.

maksim
Offline
Зарегистрирован: 12.02.2012

denis999 пишет:

Все-таки спрашивал я о возвращении 1 если найден address_2.

А что разве 1 вам не возвращается когда адрес найден? Ну проверьте:

void loop() 
{
   if(ds.search(addr) != 1) 
   {
    ds.reset_search();
    delay(1000);
    for(byte i = 0; i < 8; i++) addr[i] = 0;
    return;
  } 
  Serial.println(!memcmp(address_2, addr, 8));
}

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

denis999
Offline
Зарегистрирован: 16.04.2013

maksim пишет:

Ничего странного, каждый неверный адрес включает реле ,а верный выводит "ок". И не НО ,так как что у вас в голове известно только вам.

можно, конечно и так как вы подсказали, но геркон работает на размыкание(про работающие на замыкание не слышал), поэтому я воспользовался "else". Если использовать только if, то все конечно работает. Но где найти геркон на замыкание? 8) ...замкнутый круг. Можно инвертировать логику на "если отсутсвует address_2"?

denis999
Offline
Зарегистрирован: 16.04.2013

спасибо вам. все теперь понятно.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

denis999 пишет:

...но геркон работает на размыкание(про работающие на замыкание не слышал)...

Во первых геркон, лежащий на столе, разомкнут.

А ещё есть трёхконтактные, перекидываюшиеся....

http://www.alibaba.com/trade/search?fsb=y&IndexArea=product_en&CatId=&Se...

denis999
Offline
Зарегистрирован: 16.04.2013

а вот как прикрутить логику из примера работы с кнопками из этого примера:

int flag=0;
 
 void setup()  
 {       
    pinMode(13, OUTPUT);             
 }

 void loop()

 {

     if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата  
     // и перемення flag равна 0 , то ...
     {
       flag=1;
        //это нужно для того что бы с каждым нажатием кнопки
        //происходило только одно действие
        // плюс защита от "дребезга"  100%
     }

      if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата
     //и переменная flag равна - 1 ,то ...
     {
         digitalWrite(13,!digitalRead(13));
        flag=0;//обнуляем переменную flag
     }
 }

 

сделал как ниже - горит постоянно:

 

  if (!memcmp(address_2, addr, 8)&&address_2_flag==0)
  { 
    address_2_flag=1;
  }
  if (!memcmp(address_2, addr, 8)&&address_2_flag==1)
  { 
   digitalWrite(relePin, HIGH);
   address_2_flag=0;
  }
maksim
Offline
Зарегистрирован: 12.02.2012

Поиск датчика никак не связан с кнопками.

void loop() 
{
  static bool finded = 0;
  if(ds.search(addr) != 1) 
  {
    if(finded == 0) digitalWrite(relePin, HIGH);
    finded = 0;
    ds.reset_search();
    for(byte i = 0; i < 8; i++) addr[i] = 0;
    delay(100);
  }

  if(!memcmp(address_2, addr, 8))
  {
    digitalWrite(relePin, LOW);
    finded = 1;
  }
}

 

denis999
Offline
Зарегистрирован: 16.04.2013

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

denis999
Offline
Зарегистрирован: 16.04.2013

с DS2401 все нормально стало, но теперь я не могу "вытащить" температуру с address_1 (ds18b20), т .к. функция void reeds1WARE (void) не хочет в loop работать с вашим кодом. либо то либо другое. как быть?

рабочий код:

void loop()
{
  
  static bool finded = 0;
    if(ds.search(addr) != 1)
  {
    if(finded == 0&&count_mail>2) //если дверь открывалась и закрылась - сброс счетчика
   {                              //если дверь открывалась и закрылась - сброс счетчика
   count_mail = 0;                //если дверь открывалась и закрылась - сброс счетчика
   }                              //если дверь открывалась и закрылась - сброс счетчика
    if(finded == 0) digitalWrite(relePin, LOW);
    finded = 0;
    ds.reset_search();
    for(byte i = 0; i < 8; i++) addr[i] = 0;
    delay(100);
  }
  
  if(!memcmp(address_2, addr, 8))
  {
    digitalWrite(relePin, HIGH);
    finded = 1;
    count_mail++;
    Serial.println(count_mail);
  }
    
  if(!memcmp(address_2, addr, 8)&&count_mail==1) //выполняем отправку email только один раз, пока дверь открыта
   { 
   Serial.print("OK");
   }

не рабочий код:

void loop()
{
  float t1 ;
  reeds1WARE();
  if (!memcmp(address_1, addr, 8))
                          {
                        t1 =(celsius);
                          }    
  
  static bool finded = 0;
    if(ds.search(addr) != 1)
  {
    if(finded == 0&&count_mail>2) //если дверь открывалась и закрылась - сброс счетчика
   {                              //если дверь открывалась и закрылась - сброс счетчика
   count_mail = 0;                //если дверь открывалась и закрылась - сброс счетчика
   }                              //если дверь открывалась и закрылась - сброс счетчика
    if(finded == 0) digitalWrite(relePin, LOW);
    finded = 0;
    ds.reset_search();
    for(byte i = 0; i < 8; i++) addr[i] = 0;
    delay(100);
  }
  
  if(!memcmp(address_2, addr, 8))
  {
    digitalWrite(relePin, HIGH);
    finded = 1;
    count_mail++;
    Serial.println(count_mail);
  }
    
  if(!memcmp(address_2, addr, 8)&&count_mail==1) //выполняем отправку email только один раз, пока дверь открыта
   { 
   Serial.print(t1); }

после запуска не рабочего кода температуту он покажет ЛИШЬ ОДИН раз до перезагрузки контроллера, и count в serial все время увеличивается