· 

17.温度センサープロジェクト(7)DS18B20ーRaspberry Pi Pico WindowsC言語入門

13.7.DS18B20による温度計測

プロジェクト名:TempDS18B20

プロジェクトの概要

=Vcc

=GND

=SIG

DS18B20を使用した防水ケーブル構造の温度センサーを使用した温度計測プロジェクトです。このため、液体、屋外等での温度計測が可能です。仕様は以下です。

電源                   3.05.5V

温度範囲          -55°C+125°C

精度                   -10°C+85°C±0.5°C

Picoとの通信は専用の1 ワイヤ インターフェイスです。プローブは直径7mm、長さ約26mm。全長は 約183cmです。温度計の分解能は、912 ビットでプログラム可能です。

 

部品リスト

DS18B20搭載 温度センサ(高温、防水)

 

GROVE16 x 2 LCD                                                                     スイッチサイエンス

配線図

ソースリスト

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "pico/stdlib.h"

#include "hardware/i2c.h"

#include "hardware/rtc.h"

#include "hardware/adc.h"

 

//#define PICO_DEFAULT_LED_PIN 25

#define LED_PIN PICO_DEFAULT_LED_PIN

#define I2C_PORT i2c0

#define I2C_SDA 8

#define I2C_SCL 9

#define BS18_PIN 10

 

//setup ----------------------

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

//adc-------------

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

//rtc --------------

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

//DS18B20 ------------

bool presence() {

    gpio_set_dir(BS18_PIN, GPIO_OUT);

    gpio_put(BS18_PIN, 0);

    sleep_us(500);  //Min 480

    gpio_set_dir(BS18_PIN, GPIO_IN);

    sleep_us(70);   //MIN 15 + 60

    int b = gpio_get(BS18_PIN);

    sleep_us(420); //Max 480 - 70 

    if(b == 1){

        return false;

    }

    return true;

}

void writeBit(int b){

    int delay1, delay2;

    if(b == 1){

        delay1 = 7;      //6;

        delay2 = 100 -7; //64;

    }else{

        delay1 = 90; //80;

        delay2 = 100 - 90; //10;

    }

    gpio_set_dir(BS18_PIN, GPIO_OUT);

    gpio_put(BS18_PIN, 0);

    sleep_us(delay1);

    gpio_set_dir(BS18_PIN, GPIO_IN);

    sleep_us(delay2);

}

void writeByte(int byte){

    for(int i = 0; i < 8; i++){

        if(byte & 1){

            writeBit(1);

        }else{

            writeBit(0);

        }

        byte = byte >> 1;

    }

}

uint8_t readBit(){

    gpio_set_dir(BS18_PIN, GPIO_OUT);

    gpio_put(BS18_PIN,0);

    sleep_us(2);// sleep_us(8);

    gpio_set_dir(BS18_PIN, GPIO_IN);

    sleep_us(15); //sleep_us(2);

    uint8_t b = gpio_get(BS18_PIN);

    sleep_us(50);//sleep_us(60)

    return b;   

}

 

uint8_t readByte(){

    uint8_t byte = 0;

    for(int i = 0; i < 8; i++) {

        byte = byte | (readBit() << i);

    }

    return byte;

}

int convert(){

    int     i;

 

    writeByte(0x44);

    for(i = 0; i < 500; i++)

    {

        gpio_set_dir(BS18_PIN, GPIO_OUT);

        gpio_put(BS18_PIN,0);

        sleep_us(2);// sleep_us(8);

        gpio_set_dir(BS18_PIN, GPIO_IN);

        sleep_us(15); //sleep_us(2);

        uint8_t b = gpio_get(BS18_PIN);

        sleep_us(50);//sleep_us(60)

        if(b == 1) {

            break;

        }

        sleep_ms(10);

    }   

    return i;

}

 

uint8_t crc8(uint8_t *data, uint8_t len){

    uint8_t i;

    uint8_t j;

    uint8_t temp;

    uint8_t databyte;

    uint8_t crc = 0;

    for(i = 0; i < len; i++){

        databyte = data[i];

        for (j = 0; j < 8; j++) {

            temp = (crc ^ databyte) & 0x01;

            crc >>= 1;

            if(temp){

                crc ^= 0x8c;

            }

            databyte >>= 1;

        }

    }

    return crc;

}

bool InitDs()

{

    gpio_init(BS18_PIN);

    gpio_set_dir(BS18_PIN, GPIO_IN);

    gpio_pull_up(BS18_PIN);

   

    if(!presence()){

        return false;

    }

    return true;

}

 

bool getDsTemperature(float *temperature){

    int ret;

    int i, j;

    

    if(!presence()){

        return false;

    }

    writeByte(0xCC); //skip rom  command

    ret = convert();

 

    presence();

    writeByte(0xCC);

    writeByte(0xBE);

 

    uint8_t data[9];

    for(i = 0; i < 9; i++){

        data[i] = readByte();

    }

    uint8_t crc = crc8(data, 9);

    if(crc != 0){

        return false;

    }

    int t1 = data[0];

    int t2 = data[1];

    int16_t temp1 = (t2 << 8) | t1;

    float temp = ((float)temp1)/16.0;

    *temperature = temp;

    return true;

}

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

//lcd -------------------

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

 

int main()

{

    stdio_init_all();

 

    gpio_init(LED_PIN);

    gpio_set_dir(LED_PIN, GPIO_OUT);

    gpio_put(LED_PIN, 0);

   

    i2c_init(I2C_PORT, 400*1000);

    gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);

    gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);

    gpio_pull_up(I2C_SDA);

    gpio_pull_up(I2C_SCL);

 

    WaitTerminalStartup(30*1000);

    printf("\nTerminal connected\n");

    ScanI2CBus();   

    printf("I2C Scan completed\n");

 

    lcd_init();

    InitAdc();

    InitRtc();

    if(!InitDs()){

        printf("No device\n");

        return 0;

    }

    printf("Detect device\n");

   

    char buf[128];

    datetime_t nowdt;

    int presec = -1;

    float dsTemp;

    while (1) {

        rtc_get_datetime(&nowdt);

        if(presec != nowdt.sec)

        {

            float bTemp = ReadOnBoardTemperature();

            getDsTemperature(&dsTemp);

 

            sprintf(buf, "%02d/%02d %02d:%02d:%02d",

                    nowdt.month, nowdt.day, nowdt.hour,nowdt.min, nowdt.sec);

            lcd_set_cursor(0, 0);

            lcd_string(buf);

 

            sprintf(buf, " DS:%4.1f AD:%4.1f", dsTemp, bTemp);

            printf("%4d/%02d/%02d %02d:%02d:%02d DsTemp:%4.1fC AdTemp:%4.1fC\n", 

                        nowdt.year, nowdt.month, nowdt.day,

                        nowdt.hour,nowdt.min, nowdt.sec, dsTemp, bTemp);

            lcd_set_cursor(1, 0);

            lcd_string(buf);

        }

        presec = nowdt.sec;

        sleep_ms(200);

    }

    return 0;

 

}