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
(20065536)=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, ...){}