查看: 3935|回复: 3

【体验】+机智云ESP8266的SOC方案实现DS18B20温度采集

[复制链接]

该用户从未签到

发表于 2018-3-15 15:04:58 | 显示全部楼层 |阅读模式
分享到:
云端产品和数据点创建不用说了,
移植以下驱动ds18b20.h和ds18b20.c
ds18b20.h
#ifndef __DS18B20_H__
#define __DS18B20_H__
#include "ets_sys.h"
#include "osapi.h"
#include "gpio.h"
#define DS18B20_MUX                PERIPHS_IO_MUX_GPIO5_U
#define DS18B20_FUNC        FUNC_GPIO5
#define DS18B20_PIN                5
#define DS1820_WRITE_SCRATCHPAD         0x4E
#define DS1820_READ_SCRATCHPAD      0xBE
#define DS1820_COPY_SCRATCHPAD                 0x48
#define DS1820_READ_EEPROM                         0xB8
#define DS1820_READ_PWRSUPPLY                 0xB4
#define DS1820_SEARCHROM                         0xF0
#define DS1820_SKIP_ROM             0xCC
#define DS1820_READROM                                 0x33
#define DS1820_MATCHROM                         0x55
#define DS1820_ALARMSEARCH                         0xEC
#define DS1820_CONVERT_T            0x44
static uint16_t oddparity[16] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0};
void ds_init();
int ds_search(uint8_t *addr);
void select(const uint8_t rom[8]);
void skip();
void reset_search();
uint8_t reset(void);
void ds_write(uint8_t v, int power);
void write_bit(int v);
uint8_t ds_read();
int read_bit(void);
uint8_t crc8(const uint8_t *addr, uint8_t len);
uint16_t crc16(const uint16_t *data, const uint16_t  len);
void ds18SensorTest(void);
int ds18Read(void);
#endif

ds18b20.c
#include "ets_sys.h"
#include "os_type.h"
#include "mem.h"
#include "osapi.h"
#include "user_interface.h"
#include "espconn.h"
#include "gpio.h"
#include "driver/ds18b20.h"
// global search state
static unsigned char address[8];
static uint8_t LastDiscrepancy;
static uint8_t LastFamilyDiscrepancy;
static uint8_t LastDeviceFlag;
void ICACHE_FLASH_ATTR ds_init()
{
        // Set DS18B20_PIN as gpio pin
        PIN_FUNC_SELECT(DS18B20_MUX,  DS18B20_FUNC);
        // Enable pull-up
        PIN_PULLUP_EN(DS18B20_MUX);
        // Set DS18B20_PIN pin as an input
        GPIO_DIS_OUTPUT(DS18B20_PIN);
        reset_search();
}
/* pass array of 8 bytes in */
int ICACHE_FLASH_ATTR ds_search(uint8_t *newAddr)
{
        uint8_t id_bit_number;
        uint8_t last_zero, rom_byte_number;
        uint8_t id_bit, cmp_id_bit;
        int search_result;
        int i;


        unsigned char rom_byte_mask, search_direction;
        // initialize for search
        id_bit_number = 1;
        last_zero = 0;
        rom_byte_number = 0;
        rom_byte_mask = 1;
        search_result = 0;
        // if the last call was not the last one
        if (!LastDeviceFlag)
        {
                // 1-Wire reset
                if (!reset())
                {
                        // reset the search
                        LastDiscrepancy = 0;
                        LastDeviceFlag = FALSE;
                        LastFamilyDiscrepancy = 0;
                        return FALSE;
                }
                // issue the search command
                ds_write(DS1820_SEARCHROM, 0);
                // loop to do the search
                do
                {
                        // read a bit and its complement
                        id_bit = read_bit();
                        cmp_id_bit = read_bit();
                        // check for no devices on 1-wire
                        if ((id_bit == 1) && (cmp_id_bit == 1))
                                break;
                        else
                        {
                                // all devices coupled have 0 or 1
                                if (id_bit != cmp_id_bit)
                                        search_direction = id_bit;  // bit write value for search
                                else
                                {
                                        // if this discrepancy if before the Last Discrepancy
                                        // on a previous next then pick the same as last time
                                        if (id_bit_number < LastDiscrepancy)
                                                search_direction = ((address[rom_byte_number] & rom_byte_mask) > 0);
                                        else
                                                // if equal to last pick 1, if not then pick 0
                                                search_direction = (id_bit_number == LastDiscrepancy);


                                        // if 0 was picked then record its position in LastZero
                                        if (search_direction == 0)
                                        {
                                                last_zero = id_bit_number;


                                                // check for Last discrepancy in family
                                                if (last_zero < 9)
                                                        LastFamilyDiscrepancy = last_zero;
                                        }
                                }


                                // set or clear the bit in the ROM byte rom_byte_number
                                // with mask rom_byte_mask
                                if (search_direction == 1)
                                        address[rom_byte_number] |= rom_byte_mask;
                                else
                                        address[rom_byte_number] &= ~rom_byte_mask;


                                // serial number search direction write bit
                                write_bit(search_direction);


                                // increment the byte counter id_bit_number
                                // and shift the mask rom_byte_mask
                                id_bit_number++;
                                rom_byte_mask <<= 1;


                                // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
                                if (rom_byte_mask == 0)
                                {
                                        rom_byte_number++;
                                        rom_byte_mask = 1;
                                }
                        }
                }
                while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7


                // if the search was successful then
                if (!(id_bit_number < 65))
                {
                        // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
                        LastDiscrepancy = last_zero;


                        // check for last device
                        if (LastDiscrepancy == 0)
                                LastDeviceFlag = TRUE;


                        search_result = TRUE;
                }
        }


        // if no device found then reset counters so next 'search' will be like a first
        if (!search_result || !address[0])
        {
                LastDiscrepancy = 0;
                LastDeviceFlag = FALSE;
                LastFamilyDiscrepancy = 0;
                search_result = FALSE;
        }
        for (i = 0; i < 8; i++) newAddr = address;
        return search_result;
}
void ICACHE_FLASH_ATTR select(const uint8_t *rom)
{
        uint8_t i;
        ds_write(DS1820_MATCHROM, 0); // Choose ROM
        for (i = 0; i < 8; i++) ds_write(rom, 0);
}
void ICACHE_FLASH_ATTR skip()
{
    ds_write(DS1820_SKIP_ROM,0); // Skip ROM
}
void ICACHE_FLASH_ATTR reset_search()
{
        int i;
        // reset the search state
        LastDiscrepancy = 0;
        LastDeviceFlag = FALSE;
        LastFamilyDiscrepancy = 0;
        for(i = 7; ; i--) {
                address = 0;
                if ( i == 0) break;
        }
}
uint8_t ICACHE_FLASH_ATTR reset(void)
{
        int r;
        uint8_t retries = 125;
        GPIO_DIS_OUTPUT(DS18B20_PIN);
        do {
                if (--retries == 0) return 0;
                os_delay_us(2);
        } while ( !GPIO_INPUT_GET(DS18B20_PIN));
        GPIO_OUTPUT_SET(DS18B20_PIN, 0);
        os_delay_us(500);
        GPIO_DIS_OUTPUT(DS18B20_PIN);
        os_delay_us(65);
        r = !GPIO_INPUT_GET(DS18B20_PIN);
        os_delay_us(490);
        return r;
}
void ICACHE_FLASH_ATTR ds_write(uint8_t v, int power)
{
        uint8_t bitMask;
        for (bitMask = 0x01; bitMask; bitMask <<= 1) {
                write_bit((bitMask & v)?1:0);
        }
        if (!power) {
                GPIO_DIS_OUTPUT(DS18B20_PIN);
                GPIO_OUTPUT_SET(DS18B20_PIN, 0);
        }
}
void ICACHE_FLASH_ATTR write_bit(int v)
{
        GPIO_OUTPUT_SET(DS18B20_PIN, 0);
        if(v) {
                os_delay_us(10);
                GPIO_OUTPUT_SET(DS18B20_PIN, 1);
                os_delay_us(55);
        } else {
                os_delay_us(65);
                GPIO_OUTPUT_SET(DS18B20_PIN, 1);
                os_delay_us(5);
        }
}
uint8_t ICACHE_FLASH_ATTR ds_read()
{
        uint8_t bitMask;
        uint8_t r = 0;
        for (bitMask = 0x01; bitMask; bitMask <<= 1) {
                if ( read_bit()) r |= bitMask;
        }
        return r;
}
int ICACHE_FLASH_ATTR read_bit(void)
{
        int r;
        GPIO_OUTPUT_SET(DS18B20_PIN, 0);
        os_delay_us(3);
        GPIO_DIS_OUTPUT(DS18B20_PIN);
        os_delay_us(10);
        r = GPIO_INPUT_GET(DS18B20_PIN);
        os_delay_us(53);
        return r;
}
uint8_t ICACHE_FLASH_ATTR crc8(const uint8_t *addr, uint8_t len)
{
        uint8_t crc = 0;
        uint8_t i;
        while (len--) {
                uint8_t inbyte = *addr++;
                for (i = 8; i; i--) {
                        uint8_t mix = (crc ^ inbyte) & 0x01;
                        crc >>= 1;
                        if (mix) crc ^= 0x8C;
                        inbyte >>= 1;
                }
        }
        return crc;
}
uint16_t ICACHE_FLASH_ATTR crc16(const uint16_t *data, const uint16_t  len)
{
        uint16_t  i;
        uint16_t  crc = 0;
    for ( i = 0; i < len; i++) {
            uint16_t cdata = data[len];
            cdata = (cdata ^ (crc & 0xff)) & 0xff;
            crc >>= 8;
            if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4])
                    crc ^= 0xc001;
            cdata <<= 6;
            crc ^= cdata;
            cdata <<= 1;
            crc ^= cdata;
    }
    return crc;
      return 0;
}
int ICACHE_FLASH_ATTR ds18Read(void)
{
  int r, i,low,high,temp;
  uint8_t addr[8];
  ds_init();
  r = ds_search(addr);
  reset();
  select(addr);
  ds_write(DS1820_CONVERT_T, 1); // perform temperature conversion
  os_delay_us(1000000); // sleep 1s
  reset();
  select(addr);
  ds_write(DS1820_READ_SCRATCHPAD, 0); // read scratchpad
    low = ds_read(); //low
    high = ds_read(); //high
    temp=high;
    temp=temp<<8;
    temp=temp|low;
    temp=((temp*0.0625)+10)*10;
    return temp;
}
void ICACHE_FLASH_ATTR dh11SensorTest(void)
{
  int r, i;
  uint8_t addr[8], data[12];
  ds_init();
  r = ds_search(addr);
  if(r)
  {
    os_printf("Found Device @ %02x %02x %02x %02x %02x %02x %02x %02x\r\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
    if(crc8(addr, 7) != addr[7])
      os_printf( "CRC mismatch, crc=%xd, addr[7]=%xd\r\n", crc8(addr, 7), addr[7]);
    switch(addr[0])
    {
    case 0x10:
      os_printf("Device is DS18S20 family.\r\n");
      break;


    case 0x28:
      os_printf("Device is DS18B20 family.\r\n");
      break;


    default:
      os_printf("Device is unknown family.\r\n");
      break;
    }
  }
  else {
    os_printf("No DS18B20 detected, sorry.\r\n");
  }
   // perform the conversion
  reset();
  select(addr);
  ds_write(DS1820_CONVERT_T, 1); // perform temperature conversion
  os_delay_us(1000000); // sleep 1s
  os_printf("Scratchpad: ");
  reset();
  select(addr);
  ds_write(DS1820_READ_SCRATCHPAD, 0); // read scratchpad
  for(i = 0; i < 9; i++)
  {
    data = ds_read();
    os_printf("%2x ", data);
  }
  os_printf("\r\n");


  int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
  LowByte = data[0];
  os_printf("lowb %d \r\n", LowByte);
  HighByte = data[1];
   os_printf("HighByte %d \r\n", HighByte);
  TReading = (HighByte << 8) + LowByte;
  os_printf("TReading %d \r\n", TReading);
  SignBit = TReading & 0x8000;  // test most sig bit
  os_printf("SignBit %d \r\n", SignBit);
  if (SignBit) // negative
  {
            TReading = (TReading ^ 0xffff) + 1; // 2's comp
          os_printf("TReading %d \r\n", TReading);
  }
  Whole = TReading >> 4;  // separate off the whole and fractional portions
   os_printf("Whole %d \n", Whole);
  Fract = (TReading & 0xf) * 10 / 16;
os_printf("Fract %d \n", Fract);
  os_printf("Temperature: %c%d.%d Celsius\r\n", SignBit ? '-' : '+', Whole, Fract < 10 ? 0 : Fract);
}
函数功能解读:ds_init初始化
ds18Read,温度读取函数
userHandle函数里面加入温度读取,由于数据变化就会上报,可以设置一个时间,来设置采集的周期
    int curTemperature = 0; //临时存放温度
    static uint8_t thCtime = 0;//间隔时间设定
    thCtime++;
    if(50 < thCtime)//一段时间才采集一次,自己调整
    {
        thCtime = 0;
        curTemperature = ds18Read();
        currentDataPoint.valuetemp = curTemperature;//上报
    }




回复

使用道具 举报

  • TA的每日心情
    开心
    2018-3-16 10:47
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2018-3-16 10:48:07 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-3-16 10:47
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2018-3-16 10:48:39 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 07:45 , Processed in 0.141688 second(s), 21 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.