изменение регистра конфигурации датчика ds18b20

evgenmatrix
Offline
Зарегистрирован: 25.06.2017

Здравствуйте, подскажите как понизить точночть разрешения измерения температуры ds18b20 c 0.00625С до 0.5С в библиотеке DallasTemperature? Спасибо.

Файл DallasTemperature.cpp

/*
DallasTemperature.CPP -  Dallas Temperature Control Library 1.0.0
Author: Miles Burton, miles@mnetcs.com
Copyright (c) 2009 Miles Burton All Rights Reserved
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
  This code has been derived from: http://www.arduino.cc/playground/Learning/OneWire. Unknown author, unknown date
 
*/
 
#include "DallasTemperature.h"
 
#include "Arduino.h"
extern "C" {
#include <string.h>
#include <stdlib.h>
 
}
 
#define DS18S20MODEL 0x10       // Model ID
#define DS18B20MODEL 0x28       // Model ID
#define DS1822MODEL 0x22       // Model ID
 
#define STARTCONVO 0x44         // Initalises slaves
#define COPYSCRATCH 0x48 // Copy EEPROM
#define READSCRATCH 0xBE // Read EEPROM
#define WRITESCRATCH 0x4E // Write to EEPROM
#define TEMPCOMMAND 0xBE // Request temperature
#define RECALLSCRATCH 0xB8 // Reload from last known
 
// Slave validation
#define INVALIDCRC 1
#define INVALIDMODEL 2
#define SLAVEGOOD 0
 
DallasTemperature::DallasTemperature(StratBase* pTBase)
{
  // Allow user to pass in a strategy if required
  if(pStratBase != 0) pStratBase = pTBase;
 
    // Warning: Nothing will be defined
}
 
 
// Start the interface with a new instance of NewOneWire
void DallasTemperature::begin(uint8_t wirePin)
{
 pDataWire = new NewOneWire(wirePin); // Instance object
 reset();
 
}
 
 
// Initalise with a reference to one wire
void DallasTemperature::begin(NewOneWire& NewOneWireRef)
{
  pDataWire = &NewOneWireRef;
  reset();
}
 
 
// Search the 1-wire interface for sign of our little device
void DallasTemperature::searchWire(void)
{
  initArr();
 
  if (!pDataWire->search(arSlaveAddr)){
    pDataWire->reset_search();
    return;
  } // Note: this is enumerating
}
 
// Return one wire instance if required
NewOneWire DallasTemperature::getNewOneWireInstance(void)
{
    return *pDataWire;
}
 
 
// Initalise arrays
void DallasTemperature::initArr(void)
{
  // init array
  for(int i=0;i<8;i++)     arSlaveAddr[i] = 0xFF;
}
 
// Send command
void DallasTemperature::beginCommunication(void)
{
  pDataWire->reset();
  pDataWire->select(arSlaveAddr);
  pDataWire->write(STARTCONVO,1);   // start conversion, with parasite power on at the end
  delay(1000);
}
 
// Send command
void DallasTemperature::requestTemperature(void)
{
  pDataWire->reset();
  pDataWire->select(arSlaveAddr);
  pDataWire->write(READSCRATCH);   // Read Scratchpad
}
 
float DallasTemperature::getTemperature() // ~ Double word, expensive
{
    // If we're ready to rock, begin communication channel
    if(isValid()==SLAVEGOOD){
        beginCommunication();
    }else{
        return 0;
    }
 
    requestTemperature(); // Send appropriate command
 
 
  // Originally you would read all n bytes (12~). We only need the first two
  byte lowByte = pDataWire->read();
  byte highByte = pDataWire->read();
 
 
    // TODO: Doesn't consider negative.
  int reading = (highByte<<8) + lowByte; // Concat word
 
  //TODO fix me, should negate
  if (reading & 0x8000) reading = (reading ^ 0xffff) + 1; // 2's comp
  float temp = (6 * reading) + reading / 4;    // multiply by (100 * 0.0625) or 6.25
 
 
  return temp/100;    // Divide by 100 to gain decimal.
 
}
 
// Validate whether the current address is correct
int DallasTemperature::isValid(void)
{
  // Calculate Cycle-Redudancy-Check (ie: check the data is not invalid
  if ( NewOneWire::crc8( arSlaveAddr, 7) != arSlaveAddr[7]) {
    return INVALIDCRC;
  }
 
    if(!(arSlaveAddr[0] ==    DS18B20MODEL
    || arSlaveAddr[0] ==    DS18S20MODEL
    || arSlaveAddr[0] ==    DS1822MODEL
    )){
        return INVALIDMODEL;
    }
 
  // Return all good
  return SLAVEGOOD;
 
}
 
// Select and initalise appropriate strategy
int DallasTemperature::loadStrategy(void)
{
  switch(arSlaveAddr[0])
  {
   case DS18B20MODEL:
    pStratBase = new BSeries();
   break;
   // Allow fall through
   case DS18S20MODEL:
   case DS1822MODEL:
    pStratBase = new S20Series();
   break;
   default:
    return INVALIDMODEL;
   break;
  }
 
  return SLAVEGOOD;
}
 
// Fires a total reset (Useful for intermittant connections)
void DallasTemperature::reset(void)
{
    initArr(); // reset arrays
    searchWire();
 
    if(isValid()==SLAVEGOOD)
    {
        loadStrategy();
        beginCommunication();
    }
}
 
// Convert float celcius to fahrenheit
float DallasTemperature::toFahrenheit(float celcius)
{
    return (celcius*1.8)+32;
}
 
// MnetCS - Allocates memory for DallasTemperature. Allows us to instance a new object
void* DallasTemperature::operator new(unsigned int size) // Implicit NSS obj size
{
  void * p; // void pointer
  p = malloc(size); // Allocate memory
  memset((DallasTemperature*)p,0,size); // Initalise memory
 
  //!!! CANT EXPLICITLY CALL CONSTRUCTOR - workaround by using an init() methodR - workaround by using an init() method
  return (DallasTemperature*) p; // Cast blank region to NSS pointer
}
 
// MnetCS 2009 -  Unallocates the memory used by this instance
void DallasTemperature::operator delete(void* p)
{
  DallasTemperature* pNss =  (DallasTemperature*) p; // Cast to NSS pointer
  pNss->~DallasTemperature(); // Destruct the object
 
  free(p); // Free the memory
}
 
 
Файл DallasTemperature.h
#ifndef DallasTemperature_h
#define DallasTemperature_h
 
/*
DallasTemperature.h -  Dallas Temperature Control Library 1.0.0
Author: Miles Burton, miles@mnetcs.com
Copyright (c) 2009 Miles Burton All Rights Reserved
 
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
 
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
 
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
  This code has been derived from: http://www.arduino.cc/playground/Learning/OneWire. Unknown author, unknown date
 
*/
#include <inttypes.h>
 
#include "NewOneWire.h"
 
// Strategies to calculate tempreture for specific device
#include "StratBase.h" // Base Strategy
#include "BSeries.h"   // Concrete Strat for 'b' series
#include "S20Series.h" // Concrete strat for S and '20' series
// The measurement we're taking
 
class DallasTemperature
{
private:
 
NewOneWire* pDataWire;      // One Wire Instance (a copy of)
    uint8_t arSlaveAddr[8];    // 64bit address of device
 
    // I wont justify this
    void searchWire();
 
    // Send request temperature command
    void requestTemperature();
 
    // initalise arrays
    void initArr();
 
    // Initalise 1-wire communication
    void beginCommunication();
 
    // Pointer to temperature strategy
    StratBase* pStratBase;
 
    // Load appropriate strat
    int loadStrategy(); // Returns invalid model or good [-1]
 
public:
    DallasTemperature(StratBase* = 0); // Strategy
 
    // Process temperature in given format (default is C*)
    float getTemperature();
 
    // Initalise to pin
void begin(uint8_t);
 
    // is the slave valid
    int isValid(); // strangely, 0 is "GOOD"
 
    // reset everything. Useful if you knock the power cable etc
    void reset();
 
// Begin with existing instance if 'NewOneWire' - could be useful
void begin(NewOneWire&);
 
    // Allow user to repurpose onewire
NewOneWire getNewOneWireInstance();
 
    // Convert from celcius to farenheit if required
    static float toFahrenheit(float);
 
    void* operator new (unsigned int size); // Initalise memory area
    void operator delete(void* p); // delete memory reference
};
#endif
 

 

Araris
Offline
Зарегистрирован: 09.11.2012

evgenmatrix пишет:

Здравствуйте, подскажите как понизить точночть разрешения измерения температуры ds18b20 c 0.00625С до 0.5С в библиотеке DallasTemperature?

1. Найти версию библиотеки посвежее, не 2009-го года.

Например, https://github.com/milesburton/Arduino-Temperature-Control-Library

2. Найти в файле https://github.com/milesburton/Arduino-Temperature-Control-Library/blob/master/DallasTemperature.h функцию setResolution();.

3. Воспользоваться.

evgenmatrix
Offline
Зарегистрирован: 25.06.2017

сделал как вы сказали, выдает следующую ошибку:

finall:4: error: invalid conversion from 'uint8_t {aka unsigned char}' to 'OneWire*' [-fpermissive]
In file included from finall.ino:2:0:
C:\Program Files (x86)\arduino-1.6.5-r5-windows\arduino-1.6.5-r5\libraries\DallasTemperature/DallasTemperature.h:43:5: error:   initializing argument 1 of 'DallasTemperature::DallasTemperature(OneWire*)' [-fpermissive]
     DallasTemperature(OneWire*);
     ^
invalid conversion from 'uint8_t {aka unsigned char}' to 'OneWire*' [-fpermissive]
мне необходимо подключить датчик на pin A4, я понимаю что в ошибке говориться о не правильном объявлении переменной, но что делать не пойму
evgenmatrix
Offline
Зарегистрирован: 25.06.2017

evgenmatrix пишет:

сделал как вы сказали, выдает следующую ошибку:

finall:4: error: invalid conversion from 'uint8_t {aka unsigned char}' to 'OneWire*' [-fpermissive]
In file included from finall.ino:2:0:
C:\Program Files (x86)\arduino-1.6.5-r5-windows\arduino-1.6.5-r5\libraries\DallasTemperature/DallasTemperature.h:43:5: error:   initializing argument 1 of 'DallasTemperature::DallasTemperature(OneWire*)' [-fpermissive]
     DallasTemperature(OneWire*);
     ^
invalid conversion from 'uint8_t {aka unsigned char}' to 'OneWire*' [-fpermissive]
мне необходимо подключить датчик на pin A4, я понимаю что в ошибке говориться о не правильном объявлении переменной, но что делать не пойму

решил данную проблемму, функцию setResolution использовать в разделе установок или в коде программы? время цикла программы станет меньше само или надо где то уменьшить время ожидания датчика? 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

evgenmatrix пишет:

время цикла программы станет меньше само или надо где то уменьшить время ожидания датчика? 

Не понял, Вы всё эо затеяли, чтобы уменьшить время замера? Так?

Ну, во-первых delay(750) там написано тупо, незаивисмо ни от чего. Посмотрите в тексте библиотеки сами. 

Во вторых:

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

Пример неблокирующего вызова нужен?

evgenmatrix
Offline
Зарегистрирован: 25.06.2017

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

 

inspiritus
Offline
Зарегистрирован: 17.12.2012
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

evgenmatrix пишет:

вот мне и надо что то с временем измерения сделать, снизить.

Ну, надо-то Вам не это, но даже если и так, то возникает законный вопрос: снизить насколько?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

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

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

Когда другим частям программы нужна температура, они просто используют это значение. Иногда оно окажется "старым" на 750 мс.

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

По таймеру, через 750 мс  - снова обновили температуру и снова отправили запрос.

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

Понятно? Основное, что требует понимания, это то, что ждать 750 мс НЕ обязательно. Можно разорвать запрос и чтение ответа. Тогда все ваши прерывания будут нормально работать.

bwn
Offline
Зарегистрирован: 25.08.2014

Выкини наконец Даллас Температуру, запили на OneWire (на сторожевом таймере или на миллисе), получи 2К флэша бонусом и избавься тупого ожидания. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

bwn пишет:

Выкини наконец Даллас Температуру, запили на OneWire (на сторожевом таймере или на миллисе), получи 2К флэша бонусом и избавься тупого ожидания. 

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

А если с головой напряг, так не поможет ни OneWire, ни даже чистый, ламповый Си (кажется, я уже наговорил на "Оскорбление чувств верующих", так что замолкаю от греха :-))))

evgenmatrix
Offline
Зарегистрирован: 25.06.2017

да все верно, мне надо сделать "отдельный процесс" который будет жить сам по себе, актуальность информации в 1-2 секунды мне не важна, мне и точности до целых достаточно, датчик "грубый". скиньте пожалуйста пример не блокирующего вызова.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Пожалуйста

template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }

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

#define SENSOR_PIN 6

OneWire oneWire(SENSOR_PIN);
DallasTemperature sensors(&oneWire);
DeviceAddress deviceAddress;


void setup(void) {
  Serial.begin(115200);
  Serial << "Non blocking Dallas Temperature Demo\n";
  sensors.begin();
  sensors.getAddress(deviceAddress, 0);
  sensors.setWaitForConversion(false);
}

void loop(void) {
	static bool didNotSendYet = true;
	static unsigned long start;
	if (didNotSendYet) {
		 start = millis();
		sensors.requestTemperaturesByAddress(deviceAddress); 
		didNotSendYet = false;
	} else if (sensors.isConversionAvailable(deviceAddress)) {
		const float temp = sensors.getTempC(deviceAddress);
		const unsigned long duration = millis() - start;
		Serial << "Temperature: " << temp << " (" << duration << " ms)\n"; 
		delay(2000);
		didNotSendYet = true;
	}
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

ЕвгенийП пишет:

Пожалуйста

Злобный иезуит.))))