L リチウムイオン電池の回収 〜ゴミとして出すには
by fjk
ゴミとして捨てられたリチウム電池による火災事故が増えてきています。そこで、富山市では「リチウムイオン電池やカセットボンベ等の出し方には注意が必要です」と注意を呼びかけています。
基本は、「小型廃家電製品から取り外し、販売店に引き取ってもらうか、家電量販店等のリサイクル協力店に設置してある回収ボックスに持ち込む」ことになっていますが、
- (1)小型廃家電製品からリチウムイオン電池などを取り外せない場合や
- (2)膨張などにより販売店やリサイクル協力店に回収を断られた場合は、
- ・月2回の「燃やせないごみ」の日に町内の集積場へ、
( 他の「燃やせないごみ」とは混ぜずに、それだけを透明な袋に入れて、「 リチウムイオン電池有り!」の貼り紙をして、収集員が分かるように)
町内の集積場のほかに、富山市内で土日祝日に開設している資源物ステーションへも持ち込みできます
※ 富山県の対応
P PIC16F13145 (3) 〜CLBによるデバウンス回路
by fjk
前報(abc945)では、ソフトウェアでスイッチ入力のデバウンス処理(チャタリング対策)を行ったが、今回はCLBを使ってデバウンスを試みた。
なお、ハードはabc945をそのまま使用した(abc944の回路図、abc945の写真を参照)。
- 【CLBを使用したスイッチ入力のデバウンス】
- @ 新しいプロジェクトを作製し、MCCを起動
- A ProjectResources の Libraries から CLBSynthesizerlibrary をクリック
- B CLBのClockSelection を LFINTOSC に設定
- C 回路設計画面(canvas)にデバウンス回路を作る(使い方は CLB Synthesizer[PDF] 等参照)
・左の COMPONENTS のパーツを canvas にドラッグ&ドロップ
・パーツ端子にマウスを合わせ、入力−出力間を、接続線をドラッグして接続
・入力は CLBIN0PPS、出力は PPS_OUT0、クロックは LFINTOSC
・なお、design は CLBSynthesize メニューの右クリックより clb ファイルの保存・読出しが可能
- D 作図が終わったなら、「syntheize」をクリック(正常に結線完了なら STATUSアイコンが緑色に)
- E PinGridView で CLBPPSOUT0 に RC7、CLBIN0PPS に RC3、RC2 を output
- F Pins で RC2 を LED0、RC3 を SW0、RC7 を SW0DB と名付ける
- G MCC で Generate する
- ※参考:
CLB (Microchip) 、
CLB Synthesizer User Guide (Microchip) 、
わらしもり
-
- Gmain.c に以下を記述
#include "mcc_generated_files/system/system.h"
int main(void){
SYSTEM_Initialize();
while(1){
if(SW0DB_GetValue())
LED0_SetHigh();
else
LED0_SetLow();
}
} |

Pins設定
|
- Hコンパイル後、PICに書き込む
- <結 果>
- ボードのスイッチを押している間だけLEDが点灯し、CLBバウンス回路がチャンと働いているようだ。
しかし、出力ポートのラッチを介してCLB出力を得ているので、ポートが少ないPICではもったいない。
(※CLBSWOUTレジスタを利用できそうだが、PIC16F13145シリーズには実装されていない)
- そこで、CLB割込によるスイッチ入力の取得を試みた。
【CLB割込によるスイッチ入力のデバウンス】
@ 前記のCLB出力を「CLB_IRQ0」に変更
(出力にインバータも追加、赤枠参照)
A 「synthesize」を実行
B PinGridViewでRC7の使用を削除
C MCCをgenerateする
D CLB割り込み処理Handlerを記述
E main()でHandler登録、grobal割込を有効
F コンパイル後、PICに書き込む
|
|
/******** main.c *************/
#include "mcc_generated_files/system/system.h"
void CLB_IRQ0_Handler(void){
LED0_Toggle();
}
int main(void) {
SYSTEM_Initialize();
InterRUPT_GlobalInterruptEnable();
CLB_CLB1I0_SetInturruptHandler(CLB_IRQ0_Handler);
while(1){
}
}
|
-
- <トラブル>
- これで、割込が働き、スイッチを押すたびにLEDがON/OFFを繰り返す(ハズ)。
ところが、LEDは点灯のまま変化しない。どうも割込が認識(実行)されていないようだ。
さらに、原因を調べて見ると、CLB割込処理の記述がMCCで作られていない!。
本来は、右のCLB_Synthesizer画面で、CLB割込の設定ができるはずだが、何故かこのCLB割込設定画面がToolberに表示されない。
Generate_ISRの設定(赤枠)ができないので、MCCのGenerateでCLB割込関係のコードが作られないようだ。
|

toolbarのCLB設定画面
|
|
また、割込全体をマネージするために必要な INTERRUPT_InturruptManager()関数も作られていない。
|
- ★ ApplicationBuilderタブでPanelを表示し、CLB1アイコンをクリックすると、toolbarにCLB割込設定画面を表示することができました。
これで、CLB割込の設定がMCCで可能だが、勉強のため、CLB割込処理を自分で記述してみました。
- @ EUSART(割込み有り)を追加し、MCCでGenerateする(abc945を参照)
−>これで、 INTERRUPT_InturruptManager()関数が MCC で作られる。
- ※ abc945プロジェクトをコピーし、それにCLBを追加して、修正する方法もある。
(projectのコピーは、左のproject画面で、コピーしたいprojectを選んで右クリック後 project/copy)
- A mcc_generate_files/system/src/interrupt.c の INTERRUPT_InturruptManager() に以下の記述(赤字)を追加
void __interrupt() INTERRUPT_InterruptManager (void) {
// interrupt handler
if(INTCONbits.PEIE == 1) {
if(PIE4bits.TX1IE == 1 && PIR4bits.TX1IF == 1) {
EUSART1_TxInterruptHandler();
}
else if(PIE4bits.RC1IE == 1 && PIR4bits.RC1IF == 1) {
EUSART1_RxInterruptHandler();
}
// CLB interrupt handler
else if(PIE7bits.CLB1IE0 == 1 && PIR7bits.CLB1IF0 == 1) {
CLB1_CLB1I0_Task(); // '0'はゼロです
// CLB1_CLB1I0_ISR(): // MCCでgenerateした場合
}
else {
//Unhandled Interrupt
}
}
else {
//Unhandled Interrupt
}
}
|
- B main.cを以下に置き換える
| ▼abc946-13146i.c(zip)
|
/*****************************************
* Switch Debounce (use CLB interrupt)
*****************************************/
#include "mcc_generated_files/system/system.h"
uint8_t SW0_Flg = 0; // SW0割込フラグ
void CLB_IRQ0_Handler(void){ // IRQ0(SW0)割込ハンドラー
SW0_Flg = 1;
}
/*=======================================
* Main application
*---------------------------------------*/
int main(void) {
SYSTEM_Initialize();
CLB1_CLB1I0_SetInterruptHandler(CLB_IRQ0_Handler);
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
while(1) {
if(SW0_Flg){ // SW0割込があれば
SW0_Flg = 0;
LED0_Toggle() ;
}
}
|
- 【結 果】
- 無事、CLB割込でスイッチ入力デバウンスを実現できました。
なお、当初の CLBClockDevider = 1 でデバウンスできないケースがあったので「4」にしました。
- 【おまけ】
- 「デバウンス」は、CLBを使わずに、CLCだけでも実現できます。
−>CLC応用の詳細は、後述の「CLCデバウンス回路」を参考
★★ CLBの割込 ★★ −> Melody の Application Builder Panelを正しく使っていませんでした。 m(_ _)m
- ここまで、MCCでCLB割込設定ができないと述べてきましたが、以下の手順でCLB割込設定ができました。
- 「CLBSynthezerLibrary」タブを選択後、CLB Clockを設定。
- 「ApplicationBuilder」タブを選択する。
- 「CLB1」アイコンをクリックすると、toolbarにInterrupt設定できるメニューが表示される。
- InterruptSettingでGenerateISRをOnにする。
|
|
★ 【おまけ】 CLCデバウンス回路
ハードはPIC16F1813145のCLBを使った回路をそのまま利用(ただし、CLBは使用しない)。
CLCによるデバウンスは Switch Debouncing with the PIC18F16Q40 (github) を参考にした。
- <CLCデバウンス回路>
-
- <MCC>

TMR0およびCLC1の設定
|
-

CLC3の設定
|

PIN設定
|
- <トラブル>
- 参考にした回路では、TMR2を使っているが、16F13145でTMR2を使ってGenerate後、コンパイルするとエラーとなり、TMR2を使用できなかった。
(→対策はabc947で紹介)
TMR0では、コンパイルでこのような問題が発生しなかったので、今回はTMR0を使用することにした。
また、入出力ピンは今までの配線に合わせるため、RC2およびRC3を使用した。
- 新しいプロジェクトを作製し、MCCを起動
- TMR0 (period = 2mS)、CLC1とCLC3追加し、パラメータ等を設定
- CLC3のCLCIN0inputにRC3、CLC1のCLC1outputにRC2にピン設定
- MCCでGenerate (Clock等はデフォルトのまま)
- main()に何も記述しなくても、これだけで、SW0入力にデバウンスが働き、SW0を押している間にLEDがOffとなる。
#include "mcc_generated_files/system/system.h"
int main(void){
SYSTEM_Initialize();
while(1){
}
} |
- ※CLC1のInterruptを設定すると割込が使え、下記関数でハンドラーを設定
CLC1_SetInterruptHandler(*InterruptHandler)
※プログラムのリストをハイライト付きのスタイルで見る場合はここをクリック
※ 本レポートの参考・利用は、あくまでも自己責任でお願いします。