ちょっと脱線して、USB接続パワーコントローラ

昔いろいろ検討して作りかけだったUSBパワーコントローラを完成させました。


もともとはUSB接続式のファンのスピードを可変させたいと思って、5V入力、PWMの5V出力となるものを作成。
元の回路や考え方は以前作ったLEDアレイと同じ。
http://d.hatena.ne.jp/youhei1981/20090427/1240842582

5V入力をもらって、FETとPICでPWM制御、出力側に5Vパルス出力を供給する。
ダイオードを並列に入れて、DCモーターからの回生電力を吸収する。

  • 使用した機器
    • PIC12F675
    • パワーMOSFET 2SK2232
    • 可変抵抗(10kΩ)
    • フライホイールダイオード 普通の信号用のもの
    • USBケーブルオス、ジャンク品
    • USBコネクタA メス
    • 抵抗各種  10kΩ、470Ω、120Ω
    • LED 動作確認用

詳細は気が向いたら記録に残します。
参考URL
http://www.marutsu.co.jp/pc/static/large_order/fet_3

FETのゲート-ソース間抵抗は10kΩ、ゲート抵抗は470Ωを採用。
なぜなら、手持ちにあったから。
最初は両方とも1kΩを使っていて見事に動作しませんでした。

フライホイールダイオードも手持ちのもの。会社のごみ捨て場から拾ったジャンクダイオード
FETも手持ちのごみ捨て場からのジャンク品。USBケーブルも同じく。
PICはLEDアレイで使用したものをそのまま流用。つまり、PIC周りの回路、ピンアサインはそのまま流用した。



これでファイバークリスマスツリーの点滅速度を変えることができる。
あと、モーター音を下げることもできそう。よかったよかった。

思い通りの動作完了?

USBシリアル変換ケーブルを交換しました。
家にUSBシリアルが2本もある状態ってどうなのよ、と思いながらも、仕事で使うんだからしょうがない、つか最初の一本は会社で買ったやつだし(ぉぃ


さて
実機デバッグでは効率が悪い。
プログラム書き換えて、コンパイルして、書き込んで、PIC挿しなおして、電源入れて確認、という作業なので単純に手間と時間がかかる。
せっかくMPLABX IDEにシミュレータとデバッガがついているので活用することにした。
参考にしたのは下記
http://www.geocities.jp/zattouka/GarageHouse/micon/MPLABX/Simulator1.htm

通常のIDEと同じく、

  1. ブレークポイント設定
  2. デバッグモードでコンパイル
  3. デバッグモードRUN実行

止まったところで変数を見る。

デバッガ上で見る限りは変数まともに動いてるようなんだけど。。
わからん。。。

いろいろ直してみて結果、想定どおりに動くようになりました。
でも、どれが効いたのかよくわからず。
やったこと

  • 関数に入れる変数で、関数側ではchar型で宣言してるのに、渡す値はint型になっていたので両方をint型で統一。
  • init_pic関数内で、ポートAの入出力設定のため、TRISA=0xFFとしてたのに、main関数内でTRISA=0としていた。明らかにおかしいのでmain関数内のほうを削除。
  • PORTBに入力する値はunsigned charらしい。char型で渡してたのでunsigned charに変更。


一応下記にソースコードを記載します。

  • メインファイルのみ
  • 使ってるのはPIC18F2550-I/SP
  • includeファイルはUSBを使うために入れているがまだUSBは使ってない
  • コンフィグレーションビット設定ファイルもあるが、面倒なので載せない。

設定はポートAは全入力、ポートBは全出力、ポートCはUSBに割り当て

  • 使用するときは自己責任で。なんせまだデバッグ中なんで。
  • なんかインデントがIDEで見たときとはてなにコピペしたときで位置が違う。。。
/******************************************************************************/
/* Files to Include                                                           */
/******************************************************************************/
#include <xc.h>             /* XC8 General Include File */
#include <stdint.h>         /* For uint8_t definition */
#include <stdbool.h>        /* For true/false definition */
#include "system.h"         /* System funct/params, like osc/peripheral config */
#include "usb.h"
#include "usb_device.h"
#include "usb_device_generic.h"

// グローバル変数定義
char USB_In_Buffer[64];
char USB_Out_Buffer[64];

/* Refer to the device datasheet for information about available
oscillator configurations. */
void ConfigureOscillator(void)
{
    /* TODO Add clock switching code if appropriate.  */

    /* Typical actions in this function are to tweak the oscillator tuning
    register, select new clock sources, and to wait until new clock sources
    are stable before resuming execution of the main project. */
}

/******************************************************************************/
/* User Functions                                                             */
/******************************************************************************/

/* <Initialize variables in user.h and insert code for user algorithms.> */

void InitApp(void)
{
    /* TODO Initialize User Ports/Peripherals/Project here */
	ADCON1 = 0x07;             	// ポートA全アナログに設定
	ADCON2 = 0x16;				// Left,Tad=Tcy/64 Taq=4Tad 
	ADCON0 = 0x1D;				// AD On	
	CMCON = 0x07;					// コンパレータオフ
	/// ポート初期化	
	LATB = 0xFF;					// LEDオフ
	TRISA = 0xFF;					// アナログ入力
	TRISB = 0x00;					// LED出力
	TRISC = 0xB0;					// USB
	// タイマ1初期化
	T1CON = 0xB0;					// 内部クロック プリスケール1/8
	TMR1H = 0;					// 基準 = 48MHz/4/8=1.5MHz
	TMR1L = 0;
	T3CON = 0;					// CCP1一致でタイマ1リセット
	// CCP1初期化

    /* Enable interrupts */
}

/***********************
関数名 Ctrl7seg
役割  7seg点灯制御でIO出力させる
入力 int num:表示させたい数字(0&#12316;16まで)
   int dp :ドットを表示させる場合1、させない場合は0
出力 int型 正常完了=0, エラー時は1
*************************/
int Ctrl7seg(int num, int dp){
	
	unsigned char portnum = 0x00;
	
	//渡された数字に合わせて条件分岐させる
	//出力数字の詳細は別途エクセル参照
	switch (num){
		case 0:
			portnum = 0x77;
			break;
		case 1:
			portnum = 0x14;
			break;
		case 2:
			portnum = 0xB3;
			break;
		case 3:
			portnum = 0xB5;
			break;
		case 4:
			portnum = 0xD4;
			break;
		case 5:
			portnum = 0xE5;
			break;
		case 6:
			portnum = 0xE7;
			break;
		case 7:
			portnum = 0x74;
			break;
		case 8:
			portnum = 0xF7;
			break;
		case 9:
			portnum = 0xF5;
			break;
		case 10://16進数でA
			portnum = 0xF6;
			break;
		case 11://16進数でB
			portnum = 0xC7;
			break;
		case 12://16進数でC
			portnum = 0x83;
			break;
		case 13://16進数でD
			portnum = 0x97;
			break;
		case 14://16進数でE
			portnum = 0xE3;
			break;
		case 15://16進数でF
			portnum = 0xE2;
			break;
		default:
			//数字以外、16以上の数字が送られて来たら
			//7セグはドットのみ点灯、 1(エラーコード)を返す
			PORTB = 0x08;
			return 1;
			//break;
	}
	
	if (1==dp){ portnum += 0x08; }//ドットを表示させるために足し算

	PORTB = portnum;
	return 0;
}

void MyDelayUs(unsigned short usec){
	
	while(usec--){
		NOP();
	}
}
void MyDelayMs(unsigned short usec){
	int i;
	while(usec--){
            for (i=0; i<1000; i++){
    		NOP();
            }
	}
}




/******************************************************************************/
/* Main Program                                                               */
/******************************************************************************/

void main(void)
{
    int i=0;
    
    /* Configure the oscillator for the device */
    ConfigureOscillator();

    USBDeviceInit();
    
    /* Initialize I/O and Peripherals for application */
    InitApp();


    /* TODO <INSERT USER APPLICATION CODE HERE> */

    while(1)
    {
            //USBDeviceTasks();
		MyDelayMs(500); 
		Ctrl7seg(i, 0);

        if (i > 15){
            i=0;
        } else {
            i++;
        }
    }

}
/*******************************************************************
 * Function:        bool USER_USB_CALLBACK_EVENT_HANDLER(
 *                        USB_EVENT event, void *pdata, uint16_t size)
 *
 * PreCondition:    None
 *
 * Input:           USB_EVENT event - the type of event
 *                  void *pdata - pointer to the event data
 *                  uint16_t size - size of the event data
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is called from the USB stack to
 *                  notify a user application that a USB event
 *                  occured.  This callback is in interrupt context
 *                  when the USB_INTERRUPT option is selected.
 *
 * Note:            None
 *******************************************************************/
bool USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, uint16_t size)
{
    switch((int)event)
    {
        case EVENT_EP0_REQUEST:
            /* We have received a non-standard USB request.  The vendor driver
             * needs to check to see if the request was for it. */
            USBCheckVendorRequest();
            break;
        case EVENT_SUSPEND:
        case EVENT_RESUME:
        case EVENT_CONFIGURED:
        case EVENT_SET_DESCRIPTOR:
        case EVENT_BUS_ERROR:
        case EVENT_TRANSFER_TERMINATED:
        case EVENT_TRANSFER:
        case EVENT_SOF:
        default:
            break;
    }
    return true;
}

/*******************************************************************************
 End of File
*/

結局シリアル変換ケーブルの不具合

ネットでいろいろ調べながら書き込み実施。
いろいろやってると、動作中にUSBシリアル変換ケーブルを触るとエラーが出る様子。
ケーブルが断線しかけ?

ということで、書き込み中はできる限り息を潜めて待っていると無事書き込みができました。

書けたはいいけどまったく思い通りに動いてないので、今一度やり直しの予定。
なんでやろうな。

コンパイル完了

なにをどうやったか記憶があいまいです。
参考としたアドレスは下記です。
http://picmidi.seesaa.net/article/148816608.html

ひとまず、新規でプロジェクトをつくり、PIC18F2550にあわせて作りました。
それ以外のPICの設定はすべて削除Removeしました。
フレームワークのUSB Genericのサンプルファイルをのぞいて、Includeしてあるヘッダファイルを上記で作ったプロジェクトフォルダにコピー。

main.cファイル内でIncludeしてビルド
もちろんエラーが出るので、同名のusb_device_generic.cだったかのファイルもコピー。
エラーで怒られたら調べてコピペを繰り返した。

ひとまずメイン関数内は空欄ですが、ビルド成功の表示までは確認しました。

次に、秋月のPIC programmer v4.0を引っ張り出してきて、PCに接続。。。。したいところだけどRS-232c接続なのでそこから。。。。

シリアル変換ケーブルを引っ張り出してきて、ドライバをネットからDL、インストール。
USB挿して認識したところで PIC programmerに接続。
ソフトを立ち上げてプログラマを認識したことを確認。

ただ、18F2550がリストにない・・・・
秋月のHPに行き、サポートページを探す。
ベータバージョンは無視して、リリースバージョンの最新をダウンロード。
数字を確認すると、インストールしているものよりも新しい様子。
今あるものをアンインストールして、最新を再インストール。
無事2550がリストに現れました。

書き込めることを確認するため上記でビルド成功したHEXファイルを読み込み、書き込み実施。
なにやらエラーが出て書き込めない。困った。

8021
BCD書き込み中にエラーが発生しました。

今日はもう遅いので、明日確認予定。

コンパイルが通らない

先ほどやっとincludeのところの修正ができた。
MPLAB X IDEだとHeader Filesのところにヘッダファイルを置いても認識しないのね。
プロジェクトプロパティから選んだフォルダ内を優先的に検索して、中にあるものを使うようです。
なので、Firmwareのincludeディレクトリを設定していたもんで、その中を探し回ってて「ヘッダファイルがないよーおかしいよー」ってエラーを吐いてた。

やっとusb.hをincludeするようになったので、usb独特の関数を書こうと思います
サンプルコードのこぴぺからかな。

PIC電子工作再開しました

すっかり忘れていましたが、電子工作熱が出てきたので、途中で止まっていたUSB接続データロガーの製作を再開しました。

もうブランクあきすぎで、PCも変わってるし、IDEやら秋月の書き込みソフトもなくて、環境構築から時間食ってしまった。

ハードウエアはやっと完成したので、PICソフトを製作中です。
ハードの構成

  • PIC18F2550
  • セラロック20MHz
  • 表示器は7セグを使用
  • USBバスパワーで動作
  • 測定電圧はPICの足に直結


オペアンプ経由しようかとか、LCDを使おうかとか悩んでいましたが、まずはUSB通信ができるようになることが必要と思い、簡単な回路にしました。
まあ、昔の自分が途中まで組んでいたから、という話なんだけど。
(ブレッドボードで試作もせず、すぐに半田付けしだすところが悪いところ。)

  • 方針・目標
    • USB通信ができるようになる(今ここ)
    • オペアンプ回路を組めるようになる
    • LCD表示器を使用する、LCD制御する
    • SDカードにデータを記録する

という順番で動かしていこうかと思います。


ログ見てると5年前くらいなのよね。
PIC記事の更新が2009年4月、初めてPIC触りだしたのが2009年の2月とか書いてある。
今が2015年の11月なので、おおよそ5年半のブランク。
まあ、また完成せずに放置するんだろうな、と気楽に。。。