勝手な電子工作・・

勝手なオリジナル電子工作に関する記事を書きます

鳥除け器(ひょっとすると画期的!?)

f:id:a-tomi:20210727113541j:plain

毎朝欠かさずベランダに来てたくさんのフンをしていくスズメ達。前回の記事で書いた鳥除け用ブリンカーを3つ設置後は、なんと全く来なくなりました!ピタッとやんで1週間・・・これが続けばビックリだし拍子抜けですね。

な~んだ、こんなので良かったのか!

世に出回る鳥除けテープや、様々な道具もそのうち併設が必要になるかな?と考えてはいたのですが、今のところはたったのこれだけで済んでいます。

ちなみに、これにまつわる前回の記事は次です。

省エネ用のSleep + Watch Dog Timer(Arduinoでもできる!) - 勝手な電子工作・・

ただ、前の装置は夜中にもピカリと強烈な光を出すため、近所に迷惑そう。暗い時は、鳥が来ないわけなので光らないようにしたい。この際きちんと作り直すことにしました。

明るさ検知用にI2C照度センサーをと考えましたが、何よりもしかけが単純ですむCdSセルを使うことにします。CdSは最近は敬遠され気味ですが、明るさで抵抗値が大きく変わる硫化カドミウム半導体です。 しかも暗い環境でも変化をよく検出します。

f:id:a-tomi:20210727114218j:plain

CdSの精度は大抵の人が考えるよりも高く、照度と抵抗変化の直線性、ヒステリシスの少なさ、温度補正が通常ほぼ不要な点、などの利点があります。価格は今Aliでみる限りは、1例として次のように20個で72円。送料をいれても1個10円しません。

f:id:a-tomi:20210727120414j:plain

こういうCdSセンサーの典型的な仕様の例を示します。 本来ずいぶん暗い状態までを測れるのが分かります。

f:id:a-tomi:20210727114410j:plain

通常の使用範囲(0~30℃)だと、あまり変化せず次のとおり、温度係数は僅か±0.002/℃です。

f:id:a-tomi:20210727114624j:plain

ただし測定回路には少し工夫を要します

単に固定Rと直列にして間の分圧をADCに入力する形では、暗い領域内での変化の検知はできません。なぜなら、暗いと1MΩオーダーにも変化するわけなのに、入力抵抗が低い10~20kΩのADCで分圧測定をすることはできないからです(ADCがCdSと並列にはいってしまうためです)。

そこで、測定回路をチョットだけ工夫すれば、暗闇の中でも変化を正確に測定できます。次は筆者のやり方ですが、エミッタフォロワー回路をつなぐもの。これによって測定の入力インピーダンスを100倍以上高めることができます。そして、測定値は正確な分圧-0.65V(Vbe)となり、温度の影響も受けないごく単純な回路でできます。

f:id:a-tomi:20210727115234j:plain

R1には高抵抗(例:51kΩとか100kΩとか)を安心して使うことができます。R2を3kΩ程度にすればADC入力インピーダンスの影響が防げます。トランジスタはNPN型ならこの型に限りませんが、要するにインピーダンス変換をするわけです。

そして次の回路にしてArduinoで実験しました。

f:id:a-tomi:20210727115832j:plain

D2ピンから先ほどの回路へ電力供給をオンオフしますが、2mA未満なので問題ないです。そしてエミッタフォロワーの出力(上図でDarkness)をA3ピンで読みます。値が高いほど暗いわけです。

f:id:a-tomi:20210727120240j:plain

Arduinoのテストプログラムは次のものです。

/*******************************************************
   Bird-Guard-Blinker for Arduino-Uno (ATmega328P)
      Initial version V00 7/24, 2021 (c) Akira Tominaga
      Function:
        Blink bright LED to expel birds away
         -Stop blinks if in enough dark environment.
         -Save battery energy by deep-sleep
 *******************************************************/
#include "avr/sleep.h"
#include "avr/wdt.h"
#define LED 9             // super bright LED
#define CdSval A3         // darkness val. w/ CdS circuit
#define CdSpwr 2          // Power supply for CdS circuit

void setup() { // ***** Arduino setup() *****
  // sleep time definitions for Watch-dog-timer
#define sT1 B00000110     // 1 second
#define sT2 B00000111     // 2 seconds
#define sT4 B00100000     // 4 seconds
#define sTQ B00000100     // 1/4 second
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  pinMode(CdSpwr, OUTPUT);
  digitalWrite(CdSpwr, LOW);
  Serial.begin(9600);
  // for Sleep and Watch-dog-timer
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}

void loop() { // ***** Arduino loop() *****
  #define cdsPon 40	   // CdS power-on time before ADC
  #define LEDoT 25         // LED-on time = 25mS
  digitalWrite(CdSpwr, HIGH);
  delay(cdsPon); 	   // wait for stability
  uint16_t Darkness = analogRead(CdSval);
  digitalWrite(CdSpwr, LOW);
  //Serial.print("Darkness=");
  //Serial.println(Darkness);
  if (Darkness <= 767) {    // if not dark (<= 75% Vref)
    // *** Step1: LED-on once and wait 1 sec
    digitalWrite(LED, HIGH);// LED on
    delay(LEDoT);           // 
    digitalWrite(LED, LOW); // and off
    deepSleep(sT1);         // sleep + ADCpower-off
    // ** Step2: LED-on once again and wait 1 sec
    digitalWrite(LED, HIGH);// LED on
    delay(LEDoT);           // 
    digitalWrite(LED, LOW); // and off
    deepSleep(sT1);         // sleep + ADCpower-off
    // ** Step: LED-on twice with short sleep, & 2 sec
    digitalWrite(LED, HIGH);// LED on
    delay(LEDoT);           // 
    digitalWrite(LED, LOW); // and off
    deepSleep(sTQ);         // sleep + ADCpower-off
    digitalWrite(LED, HIGH);// LED on
    delay(LEDoT);           // 
    digitalWrite(LED, LOW); // and off
    deepSleep(sT2);         // sleep + ADCpower-off
  } else { // if dark enough, sleep for a minute
    for (uint8_t n=0;n<15;n++){
      deepSleep(sT4);
    }
  }
}

ISR(WDT_vect) { // *** Intrpt svc rtn for WDT ISR(vect) *****
}                    // do nothing here

/**********************************
   User defined functions
 **********************************/
// ***** Setting Watch dog timer *** setWDT(seconds) *****
void setWDT(byte sleepT) {
  sleepT += B00010000;    // sleepTime + Enalbe WD-change bit-on
  MCUSR &=  B11110111;    // Prepare WDT-reset-flag in MCU-status-Reg
  WDTCSR |= B00011000;    // Enable WD-system-reset + WD-change
  WDTCSR  = sleepT;       // Set sleepTime + Enable WD-change
  WDTCSR |= B01000000;    // Finally, enable WDT-interrrupt
}
// ***** Sleep + Stop ADC pwr *** deepSleep(WDtime) *****
void deepSleep(byte WDtime) {
  setWDT(WDtime);
  ADCSRA &= B01111111;    // disable ADC to save power
  sleep_enable();
  sleep_cpu();            // sleep until WDT-interrup
  sleep_disable();
  ADCSRA |= B10000000;    // enable ADC again
}
// *** End of program

 色々実験してOK!

月夜など明るい夜もあるため、回路を消灯する暗さは真っ暗闇よりは少し明るく設定しています。使う場所にもよるでしょう。場合によってはR1を200kΩの可変抵抗にするなどして、いちいちプログラムで調整しない手もあるでしょうね。

よし、これならPICで作ればさらに小さくてすむなと、8ピンPICで次のようにしてみます。

f:id:a-tomi:20210727122525j:plain

 

だいぶ小さくできそうですね。もっとも8pinのAVRでもなんでも良いわけですが手持ちがないだけなのです^^;

  ブレッドボードでの比較は次です。下がPICの配線ですが右上RA5からの小LEDはデバッグ用で、完成したら外します。そうすると消灯用以外の回路はほぼ何もないのは同様です。

f:id:a-tomi:20210727123325j:plain

 PICのプログラム(アセンブラー)は次のとおり。デバッグ用のルーチンは使ってないですがつけたままです。外してかまいませんが。

;U210724-Bird-Guard-Blinker-CdS-WDT-12F1822-V00.asm		As of 7/24, 2021
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;										;
;    Bird-Guard Blinker for PIC12F1822 V00 					;
;	        (C)2021 Akira Tominaga, All rights reserved.			;
;		Initial Version 00 on July 24, 2021				;
;	  Function								;
;		1. Blink bright LED to expel birds away				;
;		  stop blinking in very dark environment			;
;		  Save battery energy using sleep+Watch-dog-Timer		;
;	  Input/output       							;
;		RA0 LED output to super bright LED				;
;		AN2(Ra2) AD input from CdS-circuit (Dark >= half Vdd)		;
;		RA4 Power supply to CdS-circuit					;
;	  Remarks								;
;		1. Clock = HFINTOSC (	16MHz)					;
;			Hence 1 step = 0.25 micro seconds			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
	list		p=12F1822      ; list directive to define processor
	#include	"p12F1822.inc" ; device specific variable definitions
    __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_SWDTEN & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
    __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_LO & _LVP_OFF
;	page
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Macro definitions					;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Device dependent Macros			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
DEVset	macro	
	BANKSEL	OSCCON		; Bank=1
	movlw	B'01111010'	; 16MHz and internal oscillator
	movwf	OSCCON
;
;	BANKSEL	INTCON		; Interrupt Con (in all banks hence comment)
	clrf	INTCON		; Disable all interrupts
;
; PORTA initialization
	BANKSEL	PORTA		; Bank=0
	clrf	PORTA
	BANKSEL	LATA		; Bank=2
	clrf	LATA
;
	BANKSEL	TRISA		; Bank=1
	movlw	B'11001110'	; RA0, RA4-5 are output
	movwf	TRISA
;
	BANKSEL	ANSELA		; Bank=3
	movlw	B'00000100'	; AN2(RA2) is analog input
	movwf	ANSELA		; set it to ANSELA
	BANKSEL	FVRCON		; Bank=2
	clrf	FVRCON		; Not use Fixed Voltage Reference
;
	BANKSEL	ADCON0		; Bank=1
	movlw	B'00001000'	; Analog channel AN2 and ADON 0(disabled)
	movwf	ADCON0		;
;	BANKSEL	ADCON1		; ADCONs in Bank1, hence comment
	movlw	B'00100000' 	; Leftjustified, Fosc/32, Reference Vdd
	movwf	ADCON1		;
;	BANKSEL	ADRESH		; ADC Registeres in Bank1, hence comment
	clrf	ADRESH		;
;	BANKSEL ADRESL		; ADC Registeres are in Bank1, hence commen
	clrf	ADRESL		;

	BANKSEL	OPTION_REG	; Bank=1
	bcf	OPTION_REG,7	; Enable weak pull-up
	BANKSEL	WPUA		; Bank=4
	movlw	B'00001010'	; Weak Pull-up  RA1and RA3
	movwf	WPUA		;  
;
	BANKSEL WDTCON		; Bank=1
	clrf	WDTCON		; WDT is set by program
;
	clrf	BSR		; Bank=0
	InitP			; Initialize ports
	endm
;
InitP	macro			; Initialize ports
	movlw	B'11001010'	; All inputs pulled-up and outputs & ADC L
	movwf	PORTA
	endm
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Macros			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	General purpose macros	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LEDon	macro			; LED on
	goto	$+1
	bsf	PORTA,LED
	goto	$+1
	endm
;
LEDoff	macro			; LED off
	goto	$+1
	bcf	PORTA,LED
	goto	$+1
	endm
;
WDTt	macro tLen		; Set WDT 1, 2, 4 or 0(1/4) Sec
  if tLen==1
	movlw  	B'00010101' 	; Set 1-sec WDT
  endif
  if tLen==2
	movlw 	B'00010111' 	; Set 2-sec WDT
  endif
  if tLen==4
	movlw 	B'00011001' 	; Set 4-sec WDT
  endif
  if tLen==0
	movlw 	B'00010001' 	; Set a-quarter-sec WDT
  endif
  	call	WDTtr
	endm
;
WDToff	macro			; Off the WDT
	call	WDoffr
	endm
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Comparison macro		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Compare A w/ literal and branch to Large, or Others
CalLO	macro	Aadr,Blit,Ladr
	movlw	Blit		; W=B
	subwf	Aadr,W		; W=A-B
	btfss	STATUS,C	; A≧B? Yes, skip next
	goto	$+3		; 	If A<B goto Others
	btfss	STATUS,Z	; A=B? Yes skip next
	goto	Ladr		;	If A>B goto Laddr
;				; 	If A≦B then next (here)
	endm
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Time cosuming macros			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mic	macro			;Consume 1 μS only
	goto	$+1
	goto	$+1
	endm
;
Mic2	macro	mic2p		;Consume 2 μS x n
	movlw	mic2p
	call	Mic2r
	endm
;
Mic2p5	macro 	mic25p		; Consume 2.5μS x n
	movlw	mic25p
	call	Mic25r
	endm
;
Mic5	macro	mic5p		; Consume 5μS x n
	movlw	mic5p
	call	Mic25r
	movlw	mic5p
	call	Mic25r
	endm
;
Mic50	macro	mic50p		; Consume 50μS x n
	movlw	mic50p
	call	Mic50r
	endm
;
Milli	macro	millip		; Consume mS x n
	movlw	millip
	call 	Millir
	endm
;
Mil100	macro	mil100p		; Consume 100 mS x n
	movlw	mil100p
	call 	Mil100r
	endm
; 
Secs	macro	secsp		; Consume Second x n
	movlw	secsp
	call	Secsr
	endm
;
Mins	macro	minsp		; Consume Minute x n
	movlw	minsp
	call	Minsr
	endm
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Debug and Abend macros			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dLEDon	macro			; dLED on
	goto	$+1
	bsf	PORTdbg,dLED
	goto	$+1
	endm
;
dLEDoff	macro			; dLED off
	goto	$+1
	bcf	PORTdbg,dLED
	goto	$+1
	endm
;
Udebug	macro 	Area
	movf	Area,W
	call	Udbgr
	endm
;
Ustop	macro				; Stop until Sw2 on (=L)
	call	Udstopr			; 
	endm
;
Trigger	macro				; DSO external trigger
	goto	$+1
	bsf	PORTtrg,Trig
	Mic2
	bcf	PORTtrg,Trig
	goto	$+1
	endm
;
Uabend	macro	abn			; User Abnormal-end number
	movlw	abn
	goto	Uabendr
	endm
;
Ublink	macro	bno			; Blink LED for specified times
	movlw	bno
	call	Ublinkr
	endm
;
Ucp	macro	CPNo 		; Check point literal chr to display to LCD
	movlw	CPNo
	movwf	Ucpc
	Udebug	Ucpc
	endm
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Files and Equations					;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Files				;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	cblock	H'20'
;
; For Application support
	MeasH			; Measured high byte
	MeasL			; Measured low byte
	SkipC			; Counter for bypassing blinks
;
; Areas for time consuming subroutines
	Mic25c
	Mic50c
	Millic
	Mil100c
	Secsc
	Minsc
;
; Areas for debugging routine
	DmpA 		; Display byte area 
	Dmp8C 		; Bit counter for loop (Initial Dmp8V =8)
	BlinkC 		; Counter for blinking (set for Debugb or Abendb)
	Abendn		; Abend number
	Ucpc		; User Check point chr to trace 
;
	endc
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Equations			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LedOnT	equ	D'25'		; LED-on Time(25mS)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	For PORTA		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LED	equ	0		; LED @ PORTdbg
Dkns	equ	2		; Darkness value
CdSpwr	equ	4		; Power for CdS circuit
;dLED	equ	5		; for debug

;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ***	Logical PORTdbg		; Change this when port changed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PORTdbg	equ	PORTA		;
dLED	equ	5		; LED for debugging
Trig	equ	5		; DSO trigger pulse port for test use
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Values			;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Dark 	equ	D'191'		; Min. threshold of darkness (>=2.5V)
SkipS	equ	D'15'		; Skipping 15x4 seconds when dark enough
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	For Debug		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Dmp8V	equ	D'8'		; Debug display bit counter initial value
Debugb	equ	D'8'		; number of blinkings to show Debugging
Abendb	equ	D'30'		; number of blinkings to notify Abend
;
	page
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Initializing						;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	org	0
	goto	Startp		; Go to start entry
	org	4		; This is Interrupt entry
	retfie			; 
;
Startp	DEVset			; Define ports
	call	CdSpOn		; Prepare CdS circuit power
	dLEDon
	Mil100	5		;
	dLEDoff
	Mil100	5
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Main program loop					;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mainp	nop
;Step0  Measure darkness and skip if dark enough
	call	CdSpOn		; Power on the CdS circuit
	call	Measr		; Measure the darkness level
	call	CdSpOff		; Power off the CdS circuit
	CalLO 	MeasH,Dark,Skipr ; If not dark go on, else stop blinks
;
;Step1	Blink LED once and wait a second
	WDToff			; Off watch-dog-timer
	LEDon			; Blink LED once
	Milli	LedOnT		; for LedOnT (25mS)
	LEDoff
	WDTt	1		; On watch-dog-timer 1 Sec
	sleep			; This includes clrwdt
	WDToff			; Restart without WDT
;
;Step2	Blink LED once again and wait a second
	LEDon			; Blink LED once
	Milli	LedOnT		; for LedOnT (25mS)
	LEDoff
	WDTt	1		; On watch-dog-timer 1Sec
	sleep			; This includes clrwdt
	WDToff			; Restart without WDT
;
;Step3	Blink twice with 0.25 sec sleep and wait a few seconds
	LEDon			; Blink LED 1st time
	Milli	LedOnT		; for LedOnT (25mS)
	LEDoff
	WDTt	0		; On watch-dog-timer 1/4 Sec
	sleep			; This includes clrwdt
	WDToff			; Restart without WDT
	LEDon			; Blink LED 2ndt time
	Milli	LedOnT		; for LedOnT (25mS)
	LEDoff
	WDTt	2		; On watch-dog-timer 2 Sec long
	sleep			; This includes clrwdt
	WDToff			; Restart without WDT
	goto	Mainp		; Contilue infinite loop
;
Skipr	movlw	SkipS		; Get skip-time (# of 4 seconds)
	movwf	SkipC		; Set it to counter
Skiprl	WDTt	4		; Set 4 sec WDT
	sleep			; Sleep for 4 sec
	WDToff			; Restart without WDT
	decfsz	SkipC,F		; Done ?
	goto	Skiprl		;  No, loop WD4 x n (SkipS number)
	goto	Mainp		;  Yes, return to main loop
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Measuring with CdS + Tr (emitter follower) circuit	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Power on/off routine	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CdSpOn	bsf	PORTA,CdSpwr	; Cds circuit power on
	Milli	D'40'		; Stabilize power
	return
;	
CdSpOff bcf	PORTA,CdSpwr	; CdS circuit power off
	return
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Measuring routine	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Measr	equ	$
	BANKSEL ADCON0		; Bank=ADCON0(Bank1)
	bsf	ADCON0,ADON	; ADON (bit0)
	clrf	BSR		; Bank=0
	Mic5	D'4'		; Wait for more than 15 micro secs
;
	BANKSEL	ADCON0
	bsf	ADCON0,ADGO	; Start AD conversion	
	btfsc	ADCON0,ADGO	; Check if ADGO on
	goto	$-1		; If still on, then continue to inquire it
;
	BANKSEL	ADRESH
	movf	ADRESH,W	; Get ADRESH content
	clrf	BSR		; Point Bank 0
	movwf	MeasH		; Move it to MeasH
;
	BANKSEL	ADRESL
	movf	ADRESL,W	; Get ADRESL content
	clrf	BSR		; Point Bank 0
	movwf	MeasL		; Move it to MeasL
;
	BANKSEL	ADCON0	
	bcf	ADCON0,ADON	; Cut analog connection
	clrf	BSR		; Bank=0
	return
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Watch-dog-timer subrooutines				;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WDT bit0=0 : WDToff  bit0=1 : WDTon
; WDT bit5-1: Time value
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Set specified length of WDT	;
;		Called by WDTt macro	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WDTtr	equ	$
	BANKSEL	WDTCON
	movwf	WDTCON
	clrf	BSR		; Set Bank=0
	return
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Set WDT off 			;
;		Called by WDToff macro	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WDoffr	equ	$
	BANKSEL	WDTCON
	bcf	WDTCON,SWDTEN	; Disable SW Watch Dog Timer
	clrf	BSR		; Bank = 0
	return
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Timing subrooutines for general purposes		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Make 2.0 micro S x n	(Mic2)	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mic2r	movwf	Mic25c		; + Wset + call = 1 micro sec 
;
Mic2l	decfsz	Mic25c,F	; If exhausted, 1 micro S hereafter
	goto	Mic2li		; else go out (2nd time 1.75 mic sec)
	return		
;
Mic2li	goto	$+1		;            (2nd time 2.25 mic sec)
	nop			;	     (2nd time 2.5 mic sec)
	goto	Mic2l		; go back    (2nd time 3 micro sec)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Make 2.5 micro S x n (Mic2p5)	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mic25r	movwf	Mic25c		; + Wset + call = 1 micro sec 
	nop			; 1.25 micro sec
;
Mic25l	nop			; 1.5 micro sec (2nd time 4 mic sec)
	decfsz	Mic25c,F	; If exhausted, 1 micro S hereafter
	goto	Mic25li		; else go out (2nd time 2.25 mic sec)
	return		
;
Mic25li	Mic			;	      (2nd time 3.25 mic sec)
	goto	Mic25l		; go back    (2nd time 3.75 micro sec)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	50 Microseconds	x n	Mic50  	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
Mic50r	movwf	Mic50c	 	; set how many 50 microsec (1 micro sec to here)
	nop			; 1.25 micro sec up to here
;
Mic50l	Mic2p5	D'19'		; + 47.5 = 48.75 mic sec (2nd time 98.75 mic sec)
	nop			; + 0.25 = 49 micro sec (2nd time 99 mic sec)
; 
	decfsz	Mic50c,F	; If exhausted then 1 mic S hereafter
	goto	Mic50li		; else go out (2nd time 49.75 mic sec)
	return
;
;
Mic50li	Mic			; 	  (2nd time 50.75 mic sec)
	goto	Mic50l		; go back (2nd time 51.25 mic sec)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Milliseconds x n	(Milli)	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
Millir	movwf	Millic 		; set how many 1 mil sec (1 mic S up to here)
	nop			; 1.25 micro sec
;
Millil	Mic50	D'19'		; + 50 mic x 19 = 951.25 mic S (2nd, 1951.25) 
	Mic2p5	D'19'		; + 47.5 mic = 998.75 micro S  (2nd, 1998.75)
	nop			; +0.25 mic = 999 micro sec    (2nd, 1999)
;
	decfsz	Millic,F	; If  exhausted then 1 micro sec hereafter
	goto	Millili		; else go out (2nd, 999.75 mic S)
	return
;
Millili	Mic			; 		(2nd time 1000.75 mic S)
	goto	Millil		; go back (2nd time 1001.25 mic S)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	100 Milliseconds x n	(Mil100);
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Mil100r	movwf	Mil100c		;set how many 100 ms(1 micr sec up to here)
	nop			; 1.25 micro sec
;
Milhl	Milli	D'99'		;+1ms x 99 = 99001.25 micS (2nd,199001.25mic)
	Mic50	D'19'		; + 950 mic = 99951.25 micS(2nd.199951.25mic)
	Mic2p5	D'19'		; + 47.5 mic = 99998.75micS(2nd,199998.75mic)
	nop			; + 0.25 mic = 99999 mic S (2nd,199999 micS)
;
	decfsz	Mil100c,F	; If exhausted then 1 micro sec hereafter
	goto	Milhli		; else go out (2nd time, 99999.75 mic S)
	return
;
Milhli	Mic			;  	    	(2nd time, 100000.75 mic S)
	goto	Milhl		; 		(2nd time, 100001.25 mic S)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Seconds x n	 (Secs)		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
Secsr	movwf	Secsc 		; set how many sec ( 1 mic sec up to here)
	nop			; 1.25 micro sec
;
Secsl	Mil100	D'9'		; 
	Milli	D'99'		; + 999 milli sec = 999001.25 micro sec
;
	Mic50	D'19'		; + 950 mic = 999951.25 micro sec
	Mic2p5	D'19'		; + 47.5 mic = 999998.75 micro sec
	nop			; + 0.25 mic = 999999 micro sec
;
	decfsz	Secsc,F		; If exhausted then 1 micro sec hereafter
	goto	Secsli		; else, go out 
	return
;
Secsli	Mic
	goto	Secsl		; (Second time, Sec + 1.25 micro sec)
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Minutes	x n	 (Mins)		;
;	 Overhead ignored, that is only	;
;	 751.25 Mic S even when 100 Min	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Minsr	movwf	Minsc		;set how many minutes from parameter
;
Minsl	Secs	D'60'		; 1 Seconds x 60
	decfsz	Minsc,F
	goto	Minsl
	return
;
	space
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	Followings are for debugging purpose only	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; User debug to show a specified byte	;
;	on dLED for debuggng purpose	;
;	shown from bit 7 to 0 		;
;	called by Udebug macro		;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Udbgr	clrf	BSR		; Set Bank=0
	movwf	DmpA		; move data to Dmpa
	movlw	Dmp8V		; set counter 8
	movwf	Dmp8C		; to Dmp8C
;
Udblp	Ublink	Debugb		; Blink for Debugging = 8 times
	btfsc	DmpA,7		; check top bit 7
	goto	UdbOn		; if on then to UdbOn
	dLEDoff			;  Show 0
	Mil100	D'10'		;
	goto	Udbeck
;
UdbOn	dLEDon
	Mil100	D'10'		;
	dLEDoff
Udbeck	decfsz	Dmp8C,F
	goto	Udbnext		;if not end, next
	Ublink	4		;if end, blink 4 times and 
	Mil100	D'30'		; blank for 3 seconds to take memo
	return
;
Udbnext	rlf	DmpA,F		; shift for next bit
	goto	Udblp		; loop for next bit
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Blinking to indicate debugging mode	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Ublinkr	movwf	BlinkC
Ublinkl	dLEDon			; dLED on
	Milli	D'15'		; for 15ms
	dLEDoff			; dLED off
	Milli	D'60'		; for 60ms
	decfsz	BlinkC,F	; check blinking counter
	goto	Ublinkl		; if not exhausted, loop
	return			; exhausted, return
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 	Abend (abnormal end) routine	;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Uabendr	clrf	BSR
	movwf	Abendn			; Set Uabend number
	Ublink	Abendb			; Blinking 30 times
	Udebug	Abendn			; Show Abend number
	goto	$
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	End of program						;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	end

 

テストの結果は特に問題なく完成。これで基板を4つ作ることにしました。といってもそれぞれ25mm x 16mmのごく小さな基板です。 

f:id:a-tomi:20210727132636j:plain

 例によって卓上CNCルーターで生基板から削り出します。

 

f:id:a-tomi:20210727132819j:plain

そして20分もかからずに削り終えたのが次。

f:id:a-tomi:20210727132930j:plain

 カットして急いではんだ付けし4つを完成。

f:id:a-tomi:20210727133046j:plain

電池ボックス(単3 x 3 = 4.5V)に貼り付けたものを、防水用にチャック袋に入れてできあがり。徹底的に省エネなので電池は半年以上は持つ計算です。

f:id:a-tomi:20210727133241j:plain

今回は試しにチャック袋を二重にかぶせてみました。前の場所(2Fベランダ)の両端から長手方向に中を向けて2つずつで照らすようにしました。

本日まで+2日もスズメは全く来ませんでした^^

余談ですが、調べてみると暗いと見えないトリメとは、本当は鶏目の意味のようで、ニワトリなどキジ科の鳥だけのことなのだそうです。そしてスズメやムクドリなどは人間と同じくらいに見えているそうな。

よって、明け方や夕方のうす暗い時でも来ないようにするには、各プログラム中に定義したDarknessの値をもう少し大きくするほうが良いのかもしれません。

それにしても、こんなので鳥除けができるとは・・・。

カカシみたいに慣れると来るようなことがないか、しばらくさらに様子をみるとします。今回はスズメを寄せ付けていないのに気をよくしています。もちろん、他の鳥でどうなのかは不明ですよ^^;

皆様、必要に応じてお試しあれ。非常に明るいLEDが要りますが、最近はLEDテープも結構明るいですよね。もし試されたら結果などをコメントで教えてもらえると嬉しいです。

 

では今回はこのへんで。皆様のなんらかのお役に立てば幸い。

 

以下 2021.7.30追記:

その後も鳥を全く寄せ付けず、これだけで問題なさそうです\(^_^)/。

よって、きちんと防水ケースにセットしました。回路基板の貼り付け位置は都合の良い位置にずらしました。

ついでにDarkの限界値もVref(=Vcc)の75%ほどに上げて設定しました。これでうす暗い状態まではちゃんと働き、さらに暗いとSleepします。上に掲げたプログラム両方の該当箇所の値を更新しておきます。

f:id:a-tomi:20210730115048j:plain

防水ケースは百均タッパウェアの一番小さなもの(数年前、たしかセリアで4つで百円^^; これだと大きさがぴったり、しかも側面が透明なので目的に合うしなかなか良いですね)。

これを2Fバルコニーの両端に設置。

f:id:a-tomi:20210730115522j:plain

上の写真ではわかりにくいですが、次の写真のようにエアコン室外機の下に2つずつです。晴れた日は日照が強いため、 少しでも陰になるように。前と横のパンチホールを通る日差しも結構きついので。

f:id:a-tomi:20210730115731j:plain

そしてバルコニーの反対方向にも同じように設置。

f:id:a-tomi:20210730115901j:plain

これだけで、約 6m x 1m のバルコニーのスズメ除けになるとは思いもよりませんでした!

そして照度計測時と超高輝度LED照射時以外はSleepしているし、夜もSleepしているので、単3アルカリ電池は1年以上もつ計算になると思います。

とりあえずメデタシ メデタシ! 

今後もし鳥がきたりしたらここに書き足そうと思います^^。

 

©2021 Akira Tominaga, All rights reserved.