ユーザ用ツール

サイト用ツール


softdev:tempmeter3

LM61で外気温計

今回は、5個ほど買ってあったPIC12F683を使いました。8pinのDip品です。塩尻のあたりは-10ぐらいまでは下がるので温度検出はLM61を使います。これを使えば理論上、-30℃~50℃ぐらいは計測可能なので日常生活には困らないはずです。

温度はデジタル表示で、視認性の良いセグメントLEDとしました。

回路

pic12f683_ondo-meter-sch.pdf

  • 8pinだとポートが少ないので、セグメントLED点灯のシフトレジスタにHC164を使いました。HC164への接続はCLKとDataだけで良いので2本で良い。ただラッチやEN端子がないので、送信中も表示してしまう。速く送信すればわかんないのでは?ってことですが、わかりますね。
  • Pickit3のdata,clkを動作と共用できると思ったのだけど、うまくないね。ターゲットの動作が変になる。PUするな、って書いてあったのでPDしているのだが、、なぜだろ。
  • LM61の出力は4倍に増幅して、Voltage followerでADC(AN2)に入れる。
  • LEDの消費が大きいから、P-MOSで切れるようにした。
  • 当初、電池で動かそうと思ってて、単3を6セルと3端子で5Vを作って動作させていたのだが、屋外だと厳しいですね。氷点下になると電池性能が著しく低下して、1週間持たなかった。なので、古いACダプタを流用してACで動作するようにしています。
  • ACアダプタの無効損失を含みますが、、LED常時動作で約0.6W。もったいないですね。SWで起動するようにSleepをいれても、待機時0.3W程度しか下がらないので、もったいないですね。

ソース

恥ずかしいので抜粋

ポート初期化他

#include <pic.h>
#define _XTAL_FREQ		4000000
#define SPDAT		GP0
#define SPCLK		GP1
#define LED1		GP5
#define SW1		GP4
#define LED_ON	0
#define LED_OFF	1
#define KURIKAESHI	20
#define HEIKIN	10
 
//点灯は0、消灯は1
//DPは点灯しない、LSBに1付けとく
#define data0	0b00000011
#define data1	0b10011111
#define data2	0b00100101
#define data3	0b00001101
#define data4	0b10011001
#define data5	0b01001001
#define data6	0b01000001
#define data7	0b00011011
#define data8	0b00000001
#define data9	0b00001001
 
#define MINUS	0b11111110	// MINUS is - display.
#define PLUS	0b00000001	// PLUS is no display.
 
__CONFIG(CP_OFF & BOREN_ON  & PWRTE_ON & WDTE_OFF & FOSC_INTOSCIO) ;
 
main()
{	
/* Note: The ANSEL and CMCON0 registers must be initialized to configure an analog
 * channel as a digital input. Pins configured as analog inputs will read ‘0’.
 */
	GPIO   = 0x00;	/* IO initialize */
	CMCON0 = 0x07;	/* Comparator function CM210=111(disable)*/
	ANSEL  = 0x54;	// ADCS=101;4us  GP2だけAN2として使う。
	OSCCON = 0x60;	/* 4MHz */
	TRISIO = 0x1C;	/* IO direction 543210=011100 0=Out,1=In */
	ADCON0 = 0x89;	// 10001001
	IOC    = 0x10;	// IOC4 is enable
	INTCON = 0x88;	// GIE , GPIE
 
	ADFM=1; 
	ADON = 1;

ADC計算部(ごめん、long使ってる)

char	avg,fugo,d3,d2,d1,loop;
int	andata,temp;
long	temp10;	// AD変換値の10倍で途中まで計算(long型とする)
 
andata = 0;
for(avg=0;avg<HEIKIN;avg++){
  __delay_ms(5);
  GO = 1;
  while(GO);
  andata += (ADRESH<<8) | ADRESL ;
}
andata = andata / HEIKIN ;
temp10 = (long)andata * 5000 - 2457600;
temp10 =  temp10 / 4096;
temp   = (int)temp10;
softdev/tempmeter3.txt · 最終更新: 2013/07/15 20:25 by 127.0.0.1