0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

STM32L010と内部ADCと温度センサーMCP9701で液晶表示

Last updated at Posted at 2021-05-01

x MCP9701-E/TO 販売コード 103199

温度を表示

目的
STM32L010(STM32L010F4P6)には、内部温度センサーがついていないので
秋月で売っている安価なMCP9701(約25円)を使って温度を液晶に表示する。

構成
MCP9701-E/TO I-03199
STM32L010F4P6 I-15689
AQM0802A-RN-GBW P-06669

説明
MCP9701は、
0℃の時、400mV
1℃あたり19.5mV
精度は、±4℃
電線が引き出しやすい位置のP_4をアナログ入力にする
計算には、容量削減の為に浮動小数点と割り算は、使わない
電圧表示との違いは、メインの式
MCP9700は、ファミリー、オフセット500mV、10mV/1℃ 今回は、使わない

メインの式 すべては、だいたい
496は、400mV(0℃)をADCの値に変更した値
ex 20℃の場合
(20065536)/65536=200
(200
65536)=13,107,200
13,107,200/27081=483
483+496=979

adcの値が979の時
483=979-496
13,080,123=483*27081
13,080,123/65536=199

ADCの電圧が3.3Vで分解度4096の時

3,300,000uV/4096=811uV
400mVの時
400,000uV/811uV=493
20℃の時のADCの値
19,500uV*20=392,000
392,000/811=483
483+493=976


s=((s-496)*27081)>>16;


参考
STM32L010と内蔵ADCで電圧を測る

忙しい人よう

いろいろ改良後


#include "mbed.h"

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

//アナログ入力の設定
AnalogIn adc_vbat(A3); //PA_4
//AnalogIn adc_vbat(A0); //767

#define ADDR_LCD    (0x7C)   //  address

//I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010

char    data_read[8];   //i2cバッファー

char INIT_com[]={0x0,0x38,
0x0,0x39,
0x0,0x4,
0x0,0x14,
0x0,0x70,
0x0,0x56,
0x0,0x6C,
0x0,0x38,
0x0,0xC,
0x0,0x1,
0x40,0x41};

char INIT_cls[]={0x0,0x1};

char ch_hex_a_b[5];
char *ch_hex_a(int l_num)
{
    int a,b,c;

    b=DVI10(l_num);
    c=l_num-(b*10);
    l_num=b;
    a=DVI10(l_num);
    b=l_num-(a*10);

    ch_hex_a_b[0] = '@';
    ch_hex_a_b[1] = '0' + a;
    ch_hex_a_b[2] = '0' + b;
    ch_hex_a_b[3] = '0' + c;
    ch_hex_a_b[4] = 0;

    return(ch_hex_a_b);
} //ch_hex_a

int ii;  //ループカウンタ
int s;   //アナログ読み取り値

int main()
{
    //printf("767\r\n"); //767
    //液晶の初期化
    for(ii=0;ii<11;ii++){
        i2c.write(ADDR_LCD, &INIT_com[ii*2], 2);wait_ms(2);
    } //for
    
    //無限ループ
    while (1) {
        //液晶のクリア
        i2c.write(ADDR_LCD,INIT_cls,2);wait_ms(2);

        //adcの読み込み 0から4096
        s = (adc_vbat.read_u16()>>4);
        
        //電圧を温度に変換 ex 20.0 -> 200 温度の十倍を出力
        s=((s-496)*27081)>>16;

        //小数点以上と小数点以下を分ける
        ii=DVI10(s);  // 10の桁
        s =(s-(ii*10))*10; //  1の桁
        
        //温度の小数点以上の表示
        i2c.write(ADDR_LCD, ch_hex_a( ii ) ,4);

       //温度の小数点以下の表示
        ch_hex_a( s );
        ch_hex_a_b[1] = '.';
      //ch_hex_a_b[2] = '0' + s;
        ch_hex_a_b[3] = 'C';
        i2c.write(ADDR_LCD, ch_hex_a_b ,4);

        //1秒待つ
        wait_ms(1000);

    }//while

}//main

//容量削減
void error(const char* format, ...){}


改良前


#include "mbed.h"

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

//16ビットadcの4ビットの変換テーブル
#define ADC4BIT { 0   , 62 ,125 ,187 ,250 ,312 ,375 ,437 ,500 ,562 ,625 ,687 ,750 ,812 ,875 ,937 }

AnalogIn adc_vbat(A3); //PA_4
//AnalogIn adc_vbat(A0); //767

#define ADDR        (0xD0)   //  address
#define ADDR_LCD    (0x7C)   //  address

//I2C i2c(I2C_SDA, I2C_SCL); //767
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010

char    data_read[8];   //i2cバッファー

char INIT_com[]={0x0,0x38,
0x0,0x39,
0x0,0x4,
0x0,0x14,
0x0,0x70,
0x0,0x56,
0x0,0x6C,
0x0,0x38,
0x0,0xC,
0x0,0x1,
0x40,0x41};

char INIT_cls[]={0x0,0x1};

char ch_hex_a_b[5];
char *ch_hex_a(int l_num)
{
    int a,b,c;

    b=DVI10(l_num);
    c=l_num-(b*10);
    l_num=b;
    a=DVI10(l_num);
    b=l_num-(a*10);

    ch_hex_a_b[0] = '@';
    ch_hex_a_b[1] = '0' + a;
    ch_hex_a_b[2] = '0' + b;
    ch_hex_a_b[3] = '0' + c;
    ch_hex_a_b[4] = 0;

    return(ch_hex_a_b);
}

int ii;     //ループカウンタ

int main()
{
    //printf("767\r\n"); //767
    //液晶の初期化
    for(ii=0;ii<11;ii++){
        i2c.write(ADDR_LCD, &INIT_com[ii*2], 2);wait_ms(2);
    } //for

//16bit init
//e    i2c.write(ADDR, "\230", 1); //16bit 15sps PGA x1

//    int p,s; //767
    int s;   //101
    
//    float Volts;
//    float Vref = 2.048 ;
    
///e    short bit4[]=ADC4BIT;
    
    while (1) {
        //液晶のクリア
        i2c.write(ADDR_LCD,INIT_cls,2);wait_ms(2);

        //adcの読み込み
        s = (adc_vbat.read_u16()>>4);
        
//        printf("-\n\r"); //767
//        printf(" A=%d\r\n",s); //767
//        //s=s-496;
//        //printf(" a=%d\r\n",s); //767

        //電圧を温度に変換 ex 20.0 -> 200 温度の十倍を出力
        s=((s-496)*27081)>>16;

//        printf(" c=%d\r\n",s); //767

        ii=DVI10(s);  // 10の桁
        s =(s-(ii*10))*10; //  1の桁

//        printf(" t=%d %d\r\n",ii,s); //767
        
        //温度の小数点以上の表示
        i2c.write(ADDR_LCD, ch_hex_a( ii ) ,4);

////        ch_hex_a( s );
////
////    ch_hex_a_b[1] = '.';
//////  ch_hex_a_b[2] = '0' + b;
////    ch_hex_a_b[3] = 'C';

////        i2c.write(ADDR_LCD, ch_hex_a_b ,4);

    //  (4096*165)/2048=330 電圧の100倍に変換
//    //s = 13;
//    p = (s*165) >> 11; 

//e        //データの読み込み
//e        i2c.read(ADDR | 1, data_read, 2);
//e        
//e        s = (data_read[0] * 256 ) + data_read[1];
//e        //s = 32767;
//e        printf("-s=%d %d %d\r\n",s,s>>4,(((s>>4)-400)*10)/195); //767
//e        printf(" h=%d\r\n",data_read[0]); //767
//e        printf(" l=%d\r\n",data_read[1]); //767

//        Volts = s * Vref / 32767.0f ;
//        printf(" f=%f\r\n",Volts );

//e        ii = ( (s >> 4) * 1000 )  + (bit4[ s & 0xf ]) ; //767
//e        printf(" q= %d\r\n",ii); //767
//e
//e //s=(65536/2/2/2)+1;
//e
//e ii=(s >> 4);
//e if     ( ii >= 2000 ) { ii = ii - 2000; /*printf("2.\n\r");*/   i2c.write(ADDR_LCD,"@2.",3); }
//e else if( ii >= 1000 ) { ii = ii - 1000; /*printf("1.\n\r");*/   i2c.write(ADDR_LCD,"@1.",3); }
//e else                  {                 /*printf("0.\n\r");*/   i2c.write(ADDR_LCD,"@0.",3); }
//e
//e //printf(" o=%s\r\n",ch_hex_a( ii )                );
//e i2c.write(ADDR_LCD, ch_hex_a( ii ) ,4);
//e 
//e //printf(" o=%s\r\n",ch_hex_a( (bit4[ s & 0xf ]) ) );
//e i2c.write(ADDR_LCD,ch_hex_a( ( (int)bit4[ s & 0xf ]))  ,4);

//        // 32768/(163.84/2)=400 luxに変換
//        p=( ((s>>5)*6)  + (s>>7)  ) >> 4;
//        //printf(" p=%d\r\n",p); //767
//        
//        i2c.write(ADDR_LCD, ch_hex_a( p ) ,4);

        wait_ms(1000);
    }//while

}//main

void error(const char* format, ...){}


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?