今回は、全く家の話と全く関係のない、趣味の工作の話です。
作ったのはこんなのです。
夏休み中にパワコンと宅内電圧の監視モニターの工作をして、勢いが余ってしまいました。
最近は、面白そうな部品が安く出回っているので、なおさら拍車がかかります。
メインになる部品は、TOCOSという会社のTWE-Liteという製品です。
TWE-Liteは、ZigBeeという無線規格を利用した、超小型の無線ユニットです。
きっと、HEMSに関心のある方なら、ZigBeeについて聞いたことがあるのではないでしょうか?
いわゆるスマートメーター向けの技術として、長距離省電力超小型の無線システムがいろいろと開発されていますが、ZigBeeはそういったもののうちの一つです。
TWE-Liteは、ZigBeeモジュールなのですが、他の製品と比べて、特徴的なのは、その簡単さです。
どれくらい簡単か?
なんと、とりあえず二つ買ってくれば、電源と信号線をつなぐだけで無線通信できちゃいます!
最低限の電子工作の知識は必要ですが、モジュールの設定とか、プログラミングとか何もしなくても良いのは素晴らしいことです。
その簡単さのアピールなのか、製品にはこんなカードも同梱されています。
これを見れば、TWE-Liteの使いこなしはばっちりです。
このカードから、TWE-Liteで何ができるのかを読み取ることもできます。
・デジタル接点 入出力各4点
・アナログ接点 入出力各4点
・UART シリアル通信
・I2C シリアル通信
TWE-Liteを2個そろえるだけで、こんなにいろんな情報のやり取り(双方向!)をすることができます。
プログラムを書き換えることで、入出力の種類や点数もある程度は自由に変えることもできます。
通信可能な距離は、屋外で1kmに達するそうです。
今回は屋内だし、アンテナも小さいので、実際はそれほどではなさそうですが、家の中なら十分に電波は届きそうです。
電子工作による無線通信というと、赤外線が定番なのですが、赤外線だと、目で見える範囲での操作しかできません。可視光線と同じですから、壁の影に隠れたらアウトです。
その点、ZigBeeは無線LANと同じ2.4GHzの電波を使うので、心強いです。
さて、TWE-Liteの説明はこれくらいにして、工作本体の説明です。
操作用リモコンは、有線用のタミヤのリモコンキットを改造しました。
本来、単一乾電池2本が収まる場所に、TWE-Lite DIP(工作しやすいように大き目の基板に載せたTWE-Lite)と、単四乾電池2本、電源用スイッチを収めています。
リモコンキットの配線そのものは何もいじっていません。
通常、このタイプのリモコンを使うときは、2つのスティックがそれぞれ2つのモーターの動きに合うように、結線します。つまり、前進するのに、2つのスティックの両方を前に倒す必要があります。
今回は、それでは面白くないので、スティック一本の操作で、前後進、右折、左折、回転の全操作ができるようにしました。
戦車本体は、タミヤのキットをそのまま組んでいます。右折、左折、回転ができるように、ギアボックスは2モーター独立タイプのものを使っています。
電子基板には、秋月のB基板というちょっと大き目のものを使ったので、戦車からはみ出ています。もう一回り小さいC基盤に組めないこともないかと思いましたが、ちょっと自信がありませんでした。σ(^_^;)
電池とギアボックスは下面に実装しています。
理想としては、もう少し小さい基盤に組んで、タッパーウェアかなんかで保護できると、子供らに安心して預けられるのですが、こんな部品丸見えのも、これはこれで良いかなあと思います。
うちの子らは「せんちゃん」と呼んで遊んでいるようです。
最後に、作ってみたい方のために回路図、PICのプログラムを掲載します。
部品は、電子部品はすべて秋月電子通商、戦車関係はすべてアマゾンで手に入ります。
プログラムはがんばるPICさんと趣味のブログさんを参考にさせてもらいました。
この場を借りて、感謝を申し上げます。
最後に、もし、作ってみた、あるいは参考にしてみたという方がいれば、一言でいいので、コメントしてもらえるととってもうれしいです。
にほんブログ村 にほんブログ村 にほんブログ村
エコ住宅 ブログランキングへ
回路図:
/*
* File: newmain.c
* Author:
*
* Created on 2014/08/17, 18:00
*/
#pragma config WDTE = OFF
#include <stdio.h>
#include <stdlib.h>
#include <pic.h> //delayを使うのに必要
#include <pic16lf1827.h> //レジスタの定義に必要
#define _XTAL_FREQ 16000000 // delay用に必要(クロック16MHzを指定)
#define SDA RB5
#define SCL RB4
#define TRISSDA TRISB5
#define TRISSCL TRISB4
#define DRV1ADR 0xc8
#define DRV2ADR 0xc6
#define I2C_ADR 0x7c //Display Address
#define DUS 1 //I2C Clock( usec)
#define DelayMS 100 //Delay for LED
#define DO1 RA2
#define DO2 RA3
#define DO3 RA4
#define LED1 RA2
#define LED2 RA3
#define LED3 RA4
#define DI1 RB0
#define DI2 RB1
#define DI3 RB2
#define DI4 RB3
void LEDrepeat(unsigned char number);
void I2CStart(void);
void I2CStop(void);
unsigned char I2COut(unsigned char data);
void DRV1STOP(void);
void DRV1FWD(unsigned char SpeedOut);
void DRV1RVS(unsigned char SpeedOut);
void DRV1CLR(void);
void DRV2STOP(void);
void DRV2FWD(unsigned char SpeedOut);
void DRV2RVS(unsigned char SpeedOut);
void DRV2CLR(void);
int main(int argc, char** argv) {
unsigned char Forward;
unsigned char Reverse;
unsigned char Left;
unsigned char Right;
unsigned char ForwardPrev;
unsigned char ReversePrev;
unsigned char LeftPrev;
unsigned char RightPrev;
unsigned char Speed;
OSCCON = 0b01111011; // 16MHz Internal Clock
PORTA = 0x00; // All PORT Clear
PORTB = 0x00;
ANSELA = 0x00;
ANSELB = 0x00;
TRISA=0b00000000; //RA all pin output
TRISB=0b00001111; //RB 0,1,2,3 input SDA,SCL > output
C1ON = 0; // Comparator disable
C2ON = 0;
Speed = 0x80; //Speed
SDA=1;SCL=1;
//TRIP test if trip , LED sign repeated
__delay_ms(500);
LED1=1;
LEDrepeat(5);
//DRV8830 Error Reset
DRV1CLR();
DRV2CLR();
while(1){
Forward = (DI1==0);
Reverse = (DI2==0);
Left = (DI3==0);
Right = (DI4==0);
if (Forward == 1 & ForwardPrev == 0){
LEDrepeat(2);
}else{
if (Reverse == 1 & ReversePrev == 0){
LEDrepeat(2);
}else{
if (Left == 1 & LeftPrev == 0){
LEDrepeat(2);
}else{
if (Right ==1 & RightPrev == 0){
LEDrepeat(2);
}
}
}
}
if (Forward != ForwardPrev | Reverse != ReversePrev | Left != LeftPrev | Right != RightPrev){
if(Forward == 1){
if(Left == 1){
DRV1STOP();
DRV2FWD(Speed);
LEDrepeat(2);
}else{
if(Right == 1){
DRV1FWD(Speed);
DRV2STOP();
LEDrepeat(2);
}else{
DRV1FWD(Speed);
DRV2FWD(Speed);
LEDrepeat(2);
}
}
}
if(Reverse ==1){
if(Left == 1){
DRV1STOP();
DRV2RVS(Speed);
LEDrepeat(2);
}else{
if(Right == 1){
DRV1RVS(Speed);
DRV2STOP();
LEDrepeat(2);
}else{
DRV1RVS(Speed);
DRV2RVS(Speed);
LEDrepeat(2);
}
}
}
if(Left == 1 & Forward == 0 & Reverse == 0){
DRV1RVS(Speed);
DRV2FWD(Speed);
LEDrepeat(2);
}
if(Right == 1 & Forward == 0 & Reverse == 0){
DRV1FWD(Speed);
DRV2RVS(Speed);
LEDrepeat(2);
}
if(Right == 0 & Left == 0 & Forward == 0 & Reverse == 0){
DRV1STOP();
DRV2STOP();
LEDrepeat(1);
}
ForwardPrev=Forward;
ReversePrev=Reverse;
LeftPrev=Left;
RightPrev=Right;
LEDrepeat(1);
}
}
return (EXIT_SUCCESS);
}
void LEDrepeat(unsigned char number)
{
unsigned char i;
for(i=0;i<number;i++)
{
LED1 = 0;
__delay_ms(DelayMS);
LED1 = 1;
__delay_ms(DelayMS);
}
}
void DRV1CLR(void)
{
I2CStart();
I2COut(DRV1ADR);
I2COut(0x01);
I2COut(0b10000000);
I2CStop();
}
void DRV1FWD(unsigned char SpeedOut)
{
I2CStart();
I2COut(DRV1ADR);
I2COut(0x00);
I2COut(SpeedOut+1);
I2CStop();
}
void DRV1RVS(unsigned char SpeedOut)
{
I2CStart();
I2COut(DRV1ADR);
I2COut(0x00);
I2COut(SpeedOut+2);
I2CStop();
}
void DRV1STOP(void)
{
I2CStart();
I2COut(DRV1ADR);
I2COut(0x00);
I2COut(0x00);
I2CStop();
}
void DRV2CLR(void)
{
I2CStart();
I2COut(DRV2ADR);
I2COut(0x01);
I2COut(0b10000000);
I2CStop();
}
void DRV2FWD(unsigned char SpeedOut)
{
I2CStart();
I2COut(DRV2ADR);
I2COut(0x00);
I2COut(SpeedOut+1);
I2CStop();
}
void DRV2RVS(unsigned char SpeedOut)
{
I2CStart();
I2COut(DRV2ADR);
I2COut(0x00);
I2COut(SpeedOut+2);
I2CStop();
}
void DRV2STOP(void)
{
I2CStart();
I2COut(DRV2ADR);
I2COut(0x00);
I2COut(0x00);
I2CStop();
}
void I2CStart(void)
{
SDA = 1;
__delay_us(DUS);
SCL = 1;
__delay_us(DUS);
SDA = 0;
__delay_us(DUS);
SCL = 0;
__delay_us(DUS);
}
void I2CStop(void)
{
SCL = 0;
__delay_us(DUS);
SDA = 0;
__delay_us(DUS);
SCL = 1;
__delay_us(DUS);
SDA = 1;
__delay_us(DUS);
}
unsigned char I2COut(unsigned char data)
{
int i;
unsigned char BitPos;
unsigned char ACK;
TRISSDA = 0;
BitPos = 0x80;
for(i=0;i<8;i++)
{
SCL = 0;
if((data & BitPos)!= 0)
{
SDA = 1;
}
else
{
SDA = 0;
}
BitPos = BitPos >> 1;
__delay_us(DUS);
SCL = 1;
__delay_us(DUS);
SCL = 0;
__delay_us(DUS);
}
TRISSDA = 1;
SCL = 1;
__delay_us(DUS);
ACK = SDA;
__delay_us(DUS);
SCL = 0;
__delay_us(DUS);
SDA = 1;
TRISSDA = 0;
__delay_us(DUS);
return(ACK);
}





