エントリー

タグ「attiny13」の検索結果は以下のとおりです。

DSO138に付けたロータリエンコーダ

DSO138に付けたロータリエンコーダ・・・使えない訳でではないのだが早く回すと今一つの動作なのは感じていた

そこでロータリエンコーダ制御プログラムの修正を行うことにした

//DSO138改造
//ロータリエンコーダを取り付け V1.40
//
// ロータリエンコーダの回転を割込みで処理
// A・B軸割込みを全て受けて前回と今回でインデックス処理し回転カウントを蓄積
// メインループでは蓄積された量によってボタンをエミュレートする回数を決める
// 蓄積が少ない多いでロータリエンコーダの回転速度を判定し
// 初回をある程度の回数をボタン1回とし残りはボタン1回とする数を変動する
// 現在は2段階にしている
//
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

#define EN_A PB0
#define EN_B PB1
#define OUT1 PB2
#define OUT2 PB3

#define BTNON_TIME_US   (20000)   //ボタンON時間
#define BTNOFF_TIME_US  (10000)   //ボタンOFF時間
#define RT_FIRST_COUNT  (3)       //初回回転カウント数(クリック付きでは1クリック4なので4以下が望ましい)
#define RT_NEXT_COUNT   (2)       //初回以降の回転カウント数

//回転方向テーブル
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
// 0 + - 0 - 0 0 + + 0 0 - 0 - + 0
// 0: 静止,無効,+: 右,-: 左
static const int dir[] = { 0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0 };
static int count = 0;
static int prev = 0;

//ロータリー動作割込み:前回値と今回値でインデックスを作り回転方向を蓄積
ISR(PCINT0_vect) {
int current = (PINB&0x03);
if(prev != current) { //チャタリング対応
int index = ((prev<<2) + current) & 0x0f;
count += dir[index];
prev = current;
}
}

void setup() {
//内蔵のプルアップ抵抗を有効にする場合は、DDRxで該当のピンを入力にした後
//そのピンをHIGHに設定する(有効にしない場合はLOWに設定する)
DDRB = (_BV(OUT1)|_BV(OUT2)); //pinMode(OUT1, OUTPUT); pinMode(OUT2, OUTPUT);
PORTB |= _BV(EN_A); //pinMode(EN_A, INPUT_PULLUP);
PORTB |= _BV(EN_B); //pinMode(EN_B, INPUT_PULLUP);
PORTB |= _BV(OUT1); //digitalWrite(OUT1, HIGH);
PORTB |= _BV(OUT2); //digitalWrite(OUT2, HIGH);

GIMSK |= (1<<PCIE); //PCINT割込みを有効
PCMSK = _BV(EN_A) | _BV(EN_B); //割込み許可ポートの設定
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}

void loop() {
int dt;
boolean cont_flg = false; //連続中フラグ
int cont_cnt = 0; //連続中の前回残りカウント

for(;;) {
cli(); //割り込み禁止
dt = count;
count = 0;
sei(); //割り込み許可

if(dt == 0) {
//今回カウントが0なら回転を止めたと判断
//残りもリセットしてスリープ,残りカウントはクリアしないほうが良さそう
cont_flg = false;
// cont_cnt = 0;
sleep_mode();
} else {
dt += cont_cnt;
if(cont_flg) {
//継続
if(dt > 0) {
//右回転(+)
while(dt >= RT_NEXT_COUNT) {
PORTB &= ~_BV(OUT1); //digitalWrite(OUT1, LOW);
_delay_us(BTNON_TIME_US);
PORTB |= _BV(OUT1); //digitalWrite(OUT1, HIGH);
_delay_us(BTNOFF_TIME_US);
dt -= RT_NEXT_COUNT;
}
} else {
//左回転(-)
while(dt + RT_NEXT_COUNT <= 0) {
PORTB &= ~_BV(OUT2); //digitalWrite(OUT2, LOW);
_delay_us(BTNON_TIME_US);
PORTB |= _BV(OUT2); //digitalWrite(OUT2, HIGH);
_delay_us(BTNOFF_TIME_US);
dt += RT_NEXT_COUNT;
}
}
cont_cnt = dt;
} else {
//初回
//クリック1回分のカウントがあれば実行
if(dt >= RT_FIRST_COUNT) {
//右回転(+)
PORTB &= ~_BV(OUT1); //digitalWrite(OUT1, LOW);
_delay_us(BTNON_TIME_US);
PORTB |= _BV(OUT1); //digitalWrite(OUT1, HIGH);
_delay_us(BTNOFF_TIME_US);
cont_cnt = dt - RT_FIRST_COUNT;
cont_flg = true;
} else if(dt + RT_FIRST_COUNT <= 0) {
//左回転(-)
PORTB &= ~_BV(OUT2); //digitalWrite(OUT2, LOW);
_delay_us(BTNON_TIME_US);
PORTB |= _BV(OUT2); //digitalWrite(OUT2, HIGH);
_delay_us(BTNOFF_TIME_US);
cont_cnt = dt + RT_FIRST_COUNT;
cont_flg = true;
} else {
cont_cnt = dt;
}
}
}
}
}

使用しているロータリエンコーダはクリック付きの物であり1クリックで4回のカウントが出るので単純に4回を1回として数えるだけとかクリックを無視して全カウントを数えるとか試行してみたが操作性が良くならなかった

ロータリエンコーダの動作を得てもボタンのエミュレート処理の方で遅延が発生するためリアルタイムに処理できないためである

テストプラグラムでは右回転だけしていてもチャタリングや高速回転で処理が追い付かない場合もあるのか左回転と判断してしまう事もあることが判っている

そこで最終的に回転結果をQue化にすることにした

Queといっても1つずつ取り出して処理する必要はないので回転数をカウントしておくカウンタであり溜まったカウンタの数から回転速度を想定しボタンエミュレートする

今回は2段階速度の判定で操作性が十分になった

最後に

プログラムは難しいものでないので速攻で出来た・・・のだけど・・・実は思うように動作しないバグがあって情けないことに解決まで3時間位掛かった

デバッグコードが埋め込めないので動作予想できる範囲でコードをコメントアウトしながらデバッグした結果

以下が問題だったことがやっとこさ判る

static const byte dir[] = { 0, 1, -1, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, -1, 1, 0 };

サイン付きデータなのにサイン無しのbyteになっていたのである

書き換え前はサイン無しデータ(元は-1は2)だったので変更するのを忘れてしまっていた

しかしこれはコンパイラでwarning出して欲しい(それともメッセージ設定があって設定するのをミスってるのかな?)

3.6Vの組充電池用充電器の試作

秋月電子のニッケル水素電池パックは安価で何かと使える3.6V充電池である

IMG_20170903_153320.jpg

これまで(リポを外した)ダイソーのUSB充電ライターの充電機能を利用して充電していた(真ん中のパーツ)

充電は問題なくできるのだがリポ用のため完全な満充電にはならないのが欠点

今後充電する事が増えそうなので専用の充電器を作製しようとしたら実は半年前に作製しようと設計していた(いろいろあって中止し忘れてしまっていたようだ)

diagram.png

ATTINY13aで充電制御する方式で設計,スケッチがまだなのでプログラミングしていたが,今のところ先日の充電器で十分なため記録だけにしておく(他に完了させないといけない物があるので落ち着いたら組み立てる予定)

暫定仕様
  • 全体の8~9割までは500mAの急速充電
  • 残りの1~2割は50%位で充電
  • 最終充電電圧を10秒間保持できていたら充電完了
  • LEDの点滅具合で充電状態が判るようにする
スケッチ
//
// ATMEL ATTINY13 / ARDUINO
//
//                 +-\/-+
// ADC0 (D 5) PB5 1|   |8 Vcc
// ADC3 (D 3) PB3 2|    |7 PB2 (D 2) ADC1
// ADC2 (D 4) PB4 3|    |6 PB1 (D 1) PWM1
// GND            4|   |5 PB0 (D 0) PWM0
//                 +----+
// 1: Reset
// 2: LED
// 3: Serial Out
// 4: GND
// 5: PWM(FET SW)
// 6:
// 7: ADC(充電池電圧確認)
// 8: Vcc 3.3V
//
#include <avr/io.h>

#define BAUD_RATE 38400
#include <BasicSerial3.h>

#define PIN_ADC 1   //PB2(ADC1)
#define PIN_LED PB3 //LED
#define PIN_OUT PB4 //SerialOut(Debug)
#define PIN_FET PB0 //FET

#define MCHR_VOLT (1400*3) //最大充電終止電圧(mV)
#define LAST_VOLT (1420*3) //充電終止電圧(mV)

static void serOut(const char *str) {
while(*str) TxByte(*str++);
}

//確認用シリアル出力
static void voltOut(int v) {
char bf[8];

itoa(v, bf, 10); //10は十進数
serOut(bf);
serOut("mV\r\n");
}

//電圧(mV)
static int voltRead() {
    ADCSRA = (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(0<<ADIF)|(0<<ADIE)|(0b100);
//ADC#3
    loop_until_bit_is_set(ADCSRA,ADIF); //ADC#4
    long v = (long)ADC; //long v = (long)analogRead(PIN_ADC);
    v *= 5000;                           //基準電圧5V
    v /= 1024;
    return((int)v);
}

void setup() {
    DIDR0 = _BV(PIN_ADC);                              //ADC#1: pinMode(PB2, INPUT);
    ADMUX = (0<<REFS0)|(0<<ADLAR)|PIN_ADC; //ADC#2: analogReference(DEFAULT);
    DDRB = (_BV(PIN_LED)|_BV(PIN_FET)|_BV(PIN_OUT));   //pinMode(PIN_LED, OUTPUT);
                                                       //pinMode(PIN_FET, OUTPUT);
                                                       //pinMode(PIN_OUT, OUTPUT);
    OSCCAL = 91;                           //87 - 96 (91, 92)
}

void loop() {
   int volt;

    serOut("Begin.\r\n");

    //MAX充電
   while((volt = voltRead()) < MCHR_VOLT) {
        voltOut(volt);
        PORTB |= _BV(PIN_LED);                         //digitalWrite(PIN_LED, HIGH);
        PORTB |= _BV(PIN_FET);                         //digitalWrite(PIN_FET, HIGH);
        delay(4000);
        PORTB &= ~_BV(PIN_LED);                        //digitalWrite(PIN_LED, LOW);
        delay(1000);
    }

    //残りを50%充電で完了させる
    int final = 5;
    do {
        voltOut(volt);
        PORTB |= _BV(PIN_LED);                         //digitalWrite(PIN_LED, HIGH);
        PORTB |= _BV(PIN_FET);                         //digitalWrite(PIN_FET, HIGH);
        delay(1000);
    PORTB &= ~_BV(PIN_FET);                        //digitalWrite(PIN_FET, LOW);
    PORTB &= ~_BV(PIN_LED);                        //digitalWrite(PIN_LED, LOW);
        delay(1000);
    if((volt = voltRead()) < LAST_VOLT) final = 5;
    } while(--final != 0);

//終了
serOut("End.\r\n");
PORTB &= ~_BV(PIN_LED);                            //digitalWrite(PIN_LED, LOW);
for(;;);
}
コードサイズ
  • arduinoのライブラリを利用すると1Kbytesを超えた
  • ADCを直接ハードウェア操作することで210bytes減る
  • その他も直接操作で最終的に780bytesになっている
  • 確認用のシリアル出力は削除できる
ADC関係
  • ADC#1: デジタル入力抵抗を無効(消費電流が減る)
  • ADC#2: REFS0=Reference: 0でVCC参照, 1で1.1V内部電圧源,ADLAR=0:右詰め,1:左詰め,下位2bitで00から11までADC0からADC3
  • ADC#3: ADEN=ADC有効,ADSC=ADC開始,ADIE=完了割込許可,下位3bitがクロック指定
  • ADC#4: ADIFビットが1の間はAD変換中

DSO138の操作性改善に挑戦

今年の1月くらいにJYE Techから新しくDSO150なるオシロスコープキットが出て,スペック的にはDSO138とあまり変わらないが,ケースを追加しロータリエンコーダで操作するようになったようだ

DSO150

ケース付きになって良さそう・・・最近Amazonでも取り扱い開始・・・しかも安いが,いわくつきだけどサインスマートのDSO138があるのでどうしようか・・・

そこで,DSO150を真似てDSO138を改造(改良かな?)してしまおうと考えた

DSO138

サインスマートDSO138のメイン基板,キット制作時にコンデンサの変更やボタンを交換してある

ロータリーエンコーダ―を付ける

DSO150にはDSO138(DSO062も同じ)では操作性の悪い(+)(-)ボタンをロータリーエンコーダ―に変更してあり,ロータリーエンコーダ―の扱いも慣れてきたことだし(+)(-)ボタンを制御するようにすればいけそうなので付けてみる

ここでATMegaを使うのもオーバースペックでサイズ的にも組み込みしにくいのでATtiny13aでドライブすることにした

まずは実験・・・しようとしたが・・・嵌りまくった

実験

開発環境で嵌る

昔構築したIDE1.6環境が怪しげなのでIDE1.8.1で新たに環境構築したが(全てにおいて)ボードへの書込みができない問題が発生

すったもんだして動くようになったがはっきりした原因は不明(つまり何をやったら動くようになったか特定できなかった)

おそらくとなるがhardwareフォルダに昔の情報データがあったため動作不良となっていたのではないか(hardwareフォルダ内で不必要なのは削除した)

開発支援ボードで嵌る

今回UNO互換ボードで(自己開発の)開発支援ボードを使ったがUNOに未対応だった

3.3Vピンがショートしていたり余計なピンが絶縁されていなかった設計不良が発覚(これまで3.3Vピンが出力されていないボードで動作させていたため)

シリアル出力で嵌る

シリアル出力されない場合があり原因不明(ノイズか?)

プログラム開発

コード1KBの世界なので苦労するかと思ったが1KBはやっぱ広い・・・と思うのはTK80やLKIT世代のせいか^^

ただしデータ64Bytesは辛い(PROGMEMもあるけど利用は要注意)

PG

もっとハードウェアレジスタの直接操作でサイズを減らせるけど余裕あったので判りやすいコードで済ませた(とは思っている)

ATtiny13aのPB0とPB1をロータリーエンコーダ入力とし,PB2とPB3をそれぞれ+-ボタンとして出力する

//DSO138改造
//ロータリエンコーダを取り付け
//
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

#define EN_A PB0
#define EN_B PB1
#define OUT1 PB2
#define OUT2 PB3

#define BTNON_TIME_US 40000

//割込みはsleepから抜けるだけで処理は無い
ISR(PCINT0_vect) {}

void setup() {
pinMode(EN_A, INPUT_PULLUP);
pinMode(EN_B, INPUT_PULLUP);
pinMode(OUT1, OUTPUT);
pinMode(OUT2, OUTPUT);
digitalWrite(OUT1, HIGH);
digitalWrite(OUT2, HIGH);

GIMSK |= (1<<PCIE); //PCINT割込みを有効
PCMSK = _BV(EN_A) | _BV(EN_B); //割込み許可
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}

void loop() {
unsigned char dt = 0;

for(;;) {
//前回値と今回値でインデックスを作る
dt = ((dt<<2) + (PINB&0x03))&0x0f;

if(dt == 0x07) { //right
digitalWrite(OUT1, LOW);
_delay_us(BTNON_TIME_US);
digitalWrite(OUT1, HIGH);
} else if(dt == 0x0d) { //left
digitalWrite(OUT2, LOW);
_delay_us(BTNON_TIME_US);
digitalWrite(OUT2, HIGH);
} else {
sleep_mode();
}
}
}

制御プログラムは難なく完成したがボタンONーOFF間隔の設定調整に時間を費やした

ボタンONーOFF間隔はロータリーエンコーダの回転速度に(そこそこは)合わせないとスムーズにならない(早くても遅くても駄目)

尚,変化なし時のウエイトは無くても良いことを実働では確認

既にロータリーエンコーダ―化している方もいたので参考にはさせてもらっている

エンコーダ

追加パーツは秋月D基板の取付穴が本体に整合したので右側に置いた

設定ボタンの複数化

DSO062では各設定項目の専用ボタンがあったがDSO138では6つの設定項目を1ボタンで順列選択する操作になった

DSO150ではグループ化して複数ボタンにしたようだ

同じようにするのはしゃくなのでボタンを3つにして選択できる設定項目をまとめた

DSO138の選択(select)ボタンで選択できる設定項目

  1. Horizonal Position
  2. Vertical Position Indicator
  3. Timebase(s/div)
  4. Trigger Mode
  5. Trigger Slope
  6. Trigger Level Indicator

3つのボタンを配置し以下のように割り当てた

  • 1,2  :H/V.Pos
  • 3    :S/Div
  • 4,5,6:Trigger

button

PG2

PB1,PB2,PB3をグループ化したボタン入力とし,本体の設定項目選択ボタンに接続したPB4へ出力する

//DSO138改造
//機能ボタンを追加
//

#include <avr/io.h>
//#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

//接続PIN
#define HVPOS            PB3        //PB0では動作しない(不明)
#define SECDIV           PB1
#define TRIGGER          PB2

#define BTNOUT           PB4
#define BTNON_TIME_MS    40        //ボタンON時間
#define BTNOFF_TIME_MS   20        //ボタンOFF時間

static int btint = 0;

//外部ピン変化割込み
ISR(PCINT0_vect) {
    //チャタリング10ms待ち
    _delay_ms(10);

    //ボタンの状態チェック(押下時のみ)
    if(!bit_is_set(PINB, HVPOS)) {
        btint = HVPOS;
    }
    else if(!bit_is_set(PINB, SECDIV)) {
        btint = SECDIV;
    }
    else if(!bit_is_set(PINB, TRIGGER)) {
        btint = TRIGGER;
    }
}

void setup() {
    //機能ボタン(入力)
    pinMode(HVPOS,   INPUT_PULLUP);
    pinMode(SECDIV,  INPUT_PULLUP);
    pinMode(TRIGGER, INPUT_PULLUP);
    //ハンドルボタン(出力)
    pinMode(BTNOUT, OUTPUT);
    digitalWrite(BTNOUT, HIGH);

    //ピン変化割込み許可
    GIMSK |= (1<<PCIE);                            //PCINT割込みを有効
    //PCMSK = (1<<PCINT1)|(1<<PCINT2)|(1<<PCINT3);//PB1,2,3の割込み許可
    PCMSK = (1<<HVPOS)|(1<<SECDIV)|(1<<TRIGGER);//割込み許可
    sei();
}


//    0.Horizonal Position
//    1.Vertical Position Indicator
//    2.Timebase(s/div)
//    3.Trigger Mode
//    4.Trigger Slope
//    5.Trigger Level Indicator

void loop() {
    int nowpos, movpos, btncnt;

    //nowposを復旧
    //(本体は電源OFFで記憶してなかったので処理を外す)
    //eeprom_busy_wait();
    //nowpos = (int)eeprom_read_byte((uint8_t *)0);
    nowpos = 2;
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    for(;;) {
        //_delay_ms(1);
        sleep_mode();

        cli();
        if(btint) {
            switch(btint) {
            case HVPOS:
                if(nowpos == 0) {
                    movpos = 1;
                //} else if(nowpos == 1) {
                //    movpos = 0;
                } else {
                    movpos = 0;
                }
                break;
            case SECDIV:
                movpos = 2;
                break;
            case TRIGGER:
                if(nowpos == 3) {
                    movpos = 4;
                } else if(nowpos == 4) {
                    movpos = 5;
                //} else if(nowpos == 5) {
                //    movpos = 3;
                } else {
                    movpos = 3;
                }
                break;
            }
            if(movpos < nowpos) {
                btncnt = movpos + 6 - nowpos;
            } else {
                btncnt = movpos - nowpos;
            }
            while(btncnt--) {
                _delay_ms(BTNOFF_TIME_MS);
                digitalWrite(BTNOUT, LOW);
                _delay_ms(BTNON_TIME_MS);
                digitalWrite(BTNOUT, HIGH);
                _delay_ms(BTNOFF_TIME_MS);
            }
            nowpos = movpos;
            //nowposを退避(本体は電源OFFで記憶してなかったので処理を外す)
            //eeprom_busy_wait();
            //eeprom_write_byte((uint8_t *)0, (uint8_t)nowpos);
            btint = 0;
        }
        sei();
    }
}

完成ボード

操作性はそこそこで(雰囲気がイメージでは判らないので上記画像選択でビデオが観えるようにした)劇的に良くなったとは言えない

スクロールする操作はボタンを押すよりロータリーエンコーダで良くなったとは思う

ボタン

赤:HOLDボタン,回路は本体のボタンと並列で付けている(ATtiny13aは感知しない)

黄:H/V.Posの切替

青:S/Div専用

黒:Trigger関係3箇所の選択

電源と電源SW

本オシロは家の中でもコンパクトなため扱いやすく見易い場所で利用することができるのがメリットである

しかしACアダプタではコンセントまでのケーブル取り回しが厄介なこともあり006Pの充電池(8.4V)を使用することが多い

だが電力消費が9V120mAあるため,連続使用時間が約1時間(持たないことも)程度となる

そこでコンパクトな電源の構想を延々と考えている

・・・小容量のバッテリの昇圧では厳しそう

・・・コンパクトで大容量なら2000mAh+クラスのリポで昇圧・・・だけど高価かな(スマホ充電用の5Vの旧品が安く出回ってはいる)

・・・電子ライターのリポを取り出し3個直列という方法は・・・もともと取扱に気を遣うリポを直列は面倒なので極力パス

・・・やはり単4ニッケル水素×7個か8個かな

電源は電源SWを含み検討中

その他(まとめ)
  • ピンの余裕がないので機能別にATtiny13aを2個使用
  • ケースは横幅が増えたため凝らない程度で作り直しする予定
  • ATtiny13aの使い方を改めて検証できたのと,その開発ボードの欠点(欠陥かな)が判明したので満足
  • こつこつと調整したので記事の公開が遅くなった(最終編集が4/2(日)となる)

ATTINY13用の開発支援ボードを作る(続き)

USBシリアル変換モジュールを使って送受信が可能になったのでボードの空きの部分(後になんらかの機能追加できるように空けていた)に丁度USBシリアル変換チップが余っていることもありUSBシリアル変換モジュールを追加することにした

チップ

安くUSBシリアル変換モジュールが作れないかなと思って購入していたパーツでようやく挑戦することになる(今なら超小型USBシリアル変換モジュールを使えば手間かからないかも)

回路図

VSOP用のボードが28ピン用のためスペースがあるのでUSBコネクタを付ける(FT231は20ピン)

USB

USB裏

チップを載せるために半田メッキする

半田メッキ

チップを置いて半田で温めて付けようとしたら・・・げげぇ幅が足りない・・・ボードをミスったか・・・ギリギリの線まで足を置いて後は半田を延ばして無理やり付けた(ピン1つがなかなか接触しなくて時間かかり壊れてなければよいが・・・)

半田付け

必要な部分のみピンを付けてボードは完成

ピン

実態結線図を作成して

実態結線図

※)都合良いパーツは無かったので、27Ω ⇒ 20Ω、47pF ⇒ 22pFを使用

ブレッドボードで確認

ブレッドボード版

ところがFT232RLでは正常だったのにFT231XSでは文字化けが発生してしまう

参考記事でOSCCALの調整で改善されるかもと調整を試みる

#include <BasicSerial3.h>

void setup( ) {
  pinMode(3, OUTPUT);
}

void serOut(const char* str) {
   while(*str) TxByte (*str++);
}

void loop() {
  char buf[4];
 
  for(uint8_t i = 0; i <= 128; i++) {
    digitalWrite(3, HIGH);
    itoa(i, buf, 10);
    OSCCAL = i;
    serOut("***** OSCCAL=");
    serOut(buf);
    serOut(" *****\r\n");
    delay(1000);
    digitalWrite(3, LOW);
    delay(1000);
  }
}

以下のように出たので91を設定してみたが改善せず

クロック調整

いろいろとプログラムを調整していたら長い文字列だと文字化けするようなので連続して送信する文字数の上限を設けてみたら解決

void serOut(const char* str) {
  while (*str) TxByte(*str++);
}

以下のように上限を8文字にした

void serOut(const char* str) {
  while(*str) for(int n = 0; *str && n < 8; n++) TxByte(*str++);
}

ブレッドボード上で送受信とも確認できたのでシールド基板上に取り付け完成

完成ボード

追加として以下を設置

  • 電源切り替えスイッチ(シールド上のUSBかArduinoの5Vピンかの切り替え)
  • 電源LED(緑)

使い方は以下を参照

ArduinoISP 使い方・書き込みテストArduino IDE で ATtiny 他の開発

消えると困るので転用し編集させてもらった

①開発ボードをArduinoUNOにセット

②ArduinoUNOにArduinoISPスケッチを書き込む

IDEの[ファイル]→[スケッチ例]→[11.ArduinoIAP]→[ArduinoISP]をマイコンボードに書き込む

③書込み装置選択

IDEの[ツール]→[書込み装置]の[Arduino as ISP]を選択

④ボード選択

IDEの[ツール]→[ボード:]で[ATtiny13(bitDuino13)]を選択

IDEの[ツール]→[Clock:]と進み[1.2MHz(Internal)]を選択

⑤テストスケッチを入力

#define PIN 3
#define DTIME 500

void setup() {
    pinMode(PIN, OUTPUT);
}

void loop() {
    digitalWrite(PIN, HIGH);
  delay(DTIME);
   digitalWrite(PIN, LOW);
   delay(DTIME);
}

⑥「マイコンボードに書き込む」ボタンをクリック

コンパイルと書き込みが行われLEDが約0.5秒間隔で点消灯する

⑦クロックを変更(工場出荷時は1.2MHz)

IDEの[ツール]→[Clock:]で[9.6MHz(Internal)]を選択

再度「マイコンボードに書き込む」ボタンをクリック

LEDが約4秒間隔で点消灯する(内蔵クロック1.2MHzで動作しているのにクロック9.6MHzとしてスケッチをコンパイルして書き込んだために起こる現象)

⑧ヒューズビット書き換え

IDEの[ツール]→[ブートローダの書き込み]を実行

ダミーのブートローダ書き込みによりヒューズビットの書き換えとプログラムの消去が行われる

もういちど,「マイコンボードに書き込む」ボタンをクリックしてスケッチをコンパイルして書き込むとLEDは約0.5秒間隔で点消灯する

 

ページ移動

  • ページ
  • 1
  • 2

ユーティリティ

タグクラウド

検索

エントリー検索フォーム
キーワード

Feed