このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。
今後のプログラミング演習のために、7seg LED と押しボタンのあるトレー ニングキットを作成します。 部品、回路図を提供しますので、各自作成してきてください。
| 機材 | 数量 |
|---|---|
| 7segLEDカソードコモン | 1 |
| LED(3or5mm,赤or黃or緑) | 7 |
| LED3mm(赤or黃or緑) | 4 |
| 三色LED OSTA5131A | 1 |
| 三色LED用キャップ | 1 |
| ダイオード1N4007 | 4 |
| トランジスタ2SA1441 | 2 |
| トランジスタ2SC1815 | 2 |
| NchMOSFET 2SK4017 | 2 |
| フォトトランジスタL-51ROPT1D1 | 1 |
| モータドライバL293DN | 1 |
| 抵抗100Ω | 2 |
| 抵抗120Ω | 3 |
| 抵抗220Ω | 1 |
| 抵抗330Ω | 25 |
| 抵抗22kΩ | 2 |
| 抵抗1kΩ | 6 |
| 抵抗1MΩ | 1 |
| セメント抵抗0.1Ω5W | 1 |
| 半固定抵抗5kΩ | 3 |
| コンデンサ0.1μF | 2 |
| マブチモータ FA-130RA | 1 |
| ピンソケット1x6 | 1 |
| ピンソケット1x8 | 1 |
| ピンヘッド1x40 | 1 |
| タクトスイッチ | 3 |
| 単3電池2本用ボックス | 1 |
| 単3電池3本用ボックス | 1 |
| 9V電池用スナップ | 1 |
| 電池9V | 1 |
| 電池単3 | 3 |
| arduinoシールド用基板 | 1 |
| 錫メッキ線 | 30cm |
| パックシリコーンチューブ1mm2mm | 15cm |
| ラッピングワイヤ | 10cm |
青い線は基板裏面の配線。赤い線は基板表面の配線。黄色い線は無視すること。
抵抗のリードは曲げて配線に使う。
抵抗とジャンパを取り付ける。ジャンパは片方をはんだ付けして、反対側 の必要な長さにペンで印を付け、被覆を落としてはんだ付けする。
Arduino との接続は、Arduino にピンを差してはんだ付けするとぴったり 揃う。
const byte out[] = {6,7,8,9,10,11,12,13,A0,A1,A2,A3,0xff};
const byte button1 = 4;
const byte button2 = 5;
void setup() {
for(byte i = 0; out[i] != 0xff; i++){
pinMode(out[i], OUTPUT);
}
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
}
void writeArray(bool signal){
for(byte i = 0; out[i] != 0xff; i++){
digitalWrite(out[i], signal);
}
}
void loop() {
static bool prev = HIGH;
static bool now = HIGH;
static bool condition = HIGH;
now = digitalRead(button2);
if(now == HIGH && prev == LOW){
condition ^= true;
}
prev = now;
writeArray(condition == digitalRead(button1));
}
;
.include "m328Pdef.inc"
.cseg
.org 0x0000
rjmp reset
.org INT_VECTORS_SIZE
reset:
ldi r16,high(RAMEND)
out SPH,r16
ldi r16,low(RAMEND)
out SPL,r16
.equ onb = 0b00111111
.equ ond = 0b11000000
.equ pullup = 0b00110000
.equ onc = 0b00001111
ldi r16,onb
out ddrb, r16
ldi r16,ond
out ddrd, r16
ldi r16,pullup
out portd, r16
ldi r16,onc
out ddrc, r16
.def now = r17
.def prev = r18
.def cond = r19
clr prev
ser cond
.macro clrport
in r16,@0
andi r16,~@1
out @0,r16
.endmacro
.macro setport
in r16,@0
ori r16,@1
out @0,r16
.endmacro
main:
in now,pind
sbrc prev,pind5
rjmp pressed
sbrs now,pind5
rjmp notpressed
nowpressed:
ldi r16,1<<pind4
eor cond,r16
notpressed:
pressed:
andi prev,~(1<<pind5)
or prev,now
eor now, cond
sbrc now,pind4
rjmp swon
swoff:
clrport portb,onb
clrport portd,ond
clrport portc,onc
rjmp main
swon:
setport portb,onb
setport portd,ond
setport portc,onc
rjmp main
.exit
;
.include "m32U4def.inc"
.cseg
.org 0x0000
rjmp reset
.org INT_VECTORS_SIZE
reset:
ldi r16,high(RAMEND)
out SPH,r16
ldi r16,low(RAMEND)
out SPL,r16
.equ onb = 0b11110000
.equ onc = 0b10000000
.equ ond = 0b11000000
.equ one = 0b01000000
.equ onf = 0b11110011
.equ pullup4 = 0b00010000 ; D4
.equ pullup5 = 0b01000000 ; C6
ldi r16,onb
out ddrb, r16
ldi r16,onc
out ddrc, r16
ldi r16,ond
out ddrd, r16
ldi r16,one
out ddre, r16
ldi r16,onf
out ddrf, r16
ldi r16,pullup4
out portd, r16
ldi r16,pullup5
out portc, r16
.def nowc = r17
.def prev = r18
.def cond = r19
.def nowd = r20
clr prev
ser cond
.macro clrport
in r16,@0
andi r16,~@1
out @0,r16
.endmacro
.macro setport
in r16,@0
ori r16,@1
out @0,r16
.endmacro
main:
in nowc,pinc
in nowd,pind
sbrc prev,pinc6
rjmp pressed
sbrs nowc,pinc6
rjmp notpressed
nowpressed:
ldi r16,1<<pind4
eor cond,r16
notpressed:
pressed:
andi prev,~(1<<pinc6)
or prev,nowc
eor nowd, cond
sbrc nowd,pind4
rjmp swon
swoff:
clrport portb,onb
clrport portc,onc
clrport portd,ond
clrport porte,one
clrport portf,onf
rjmp main
swon:
setport portb,onb
setport portc,onc
setport portd,ond
setport porte,one
setport portc,onf
rjmp main
.exit
;
.include "m4809def.inc"
.cseg
.org 0x0000
rjmp reset
.org INT_VECTORS_SIZE
reset:
ldi r16,low(RAMEND)
out CPU_SPL,r16
ldi r16,high(RAMEND)
out CPU_SPH,r16
.equ ona = 0b00000010
.equ onb = 0b00000011
.equ onc = 0b00000000
.equ ond = 0b00001111
.equ one = 0b00001111
.equ onf = 0b00010000
.macro enableport
lds r16,@0
ori r16,@1
sts @0,r16
.endmacro
.macro pullupport
lds r16,@0
ori r16,PORT_PULLUPEN_bm
sts @0,r16
.endmacro
enableport PORTA_DIR,ona
enableport PORTB_DIR,onb
enableport PORTC_DIR,onc
enableport PORTD_DIR,ond
enableport PORTE_DIR,one
enableport PORTF_DIR,onf
pullupport PORTC_PIN6CTRL ; pin4 = C6
pullupport PORTB_PIN2CTRL ; pin5 = B2
.def nowc = r17
.def prev = r18
.def cond = r19
.def nowb = r20
clr prev
ser cond
.macro clrport
lds r16,@0
andi r16,~@1
sts @0,r16
.endmacro
.macro setport
lds r16,@0
ori r16,@1
sts @0,r16
.endmacro
main:
lds nowc,PORTC_IN
lds nowb,PORTB_IN
sbrc prev,6
rjmp pressed
sbrs nowc,6
rjmp notpressed
nowpressed:
ldi r16,1<<2
eor cond,r16
notpressed:
pressed:
andi prev,~(1<<6)
or prev,nowc
eor nowb, cond
sbrc nowb,2
rjmp swon
swoff:
clrport PORTA_OUT,ona
clrport PORTB_OUT,onb
clrport PORTC_OUT,onc
clrport PORTD_OUT,ond
clrport PORTE_OUT,one
clrport PORTF_OUT,onf
rjmp main
swon:
setport PORTA_OUT,ona
setport PORTB_OUT,onb
setport PORTC_OUT,onc
setport PORTD_OUT,ond
setport PORTE_OUT,one
setport PORTF_OUT,onf
rjmp main
.exit
volatile 宣言を使う
スケッチ例の Blink を改造して、自分の1秒待つ関数 mydelay を作ろう。
以下のプログラムで1秒点灯するように ??? の部分に数字を入れよう。
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
void mydelay(){
for(volatile long i=0; i< ???; i++){
}
}
void loop(){
digitalWrite(LED_BUILTIN, HIGH);
mydelay();
delay(10);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
volatile 宣言を使う
演習6-1の volatile 宣言を外すと動きがどう変化するか確かめよう。
static 宣言を使う
以下のプログラムの長短を考えよう。
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
bool flag = true;
void loop(){
digitalWrite(LED_BUILTIN, flag);
flag = !flag;
delay(1000);
}
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
void loop(){
static bool flag = true;
digitalWrite(LED_BUILTIN, flag);
flag = !flag;
delay(1000);
}
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
void loop(){
bool flag = true;
digitalWrite(LED_BUILTIN, flag);
flag = !flag;
delay(1000);
}
クラス宣言を使う
以下のプログラムの動作を考えよう。
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
class Led {
bool flag = true;
public:
void invert(){
flag = !flag;
digitalWrite(LED_BUILTIN, flag);
}
};
Led led;
void loop(){
led.invert();
delay(1000);
}
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
class Led {
bool flag = true;
public:
void invert(){
flag = !flag;
digitalWrite(LED_BUILTIN, flag);
}
};
void loop(){
static Led led;
led.invert();
delay(1000);
}
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
class Led {
bool flag = true;
public:
void invert(){
flag = !flag;
digitalWrite(LED_BUILTIN, flag);
}
};
void loop(){
Led led;
led.invert();
delay(1000);
}
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
class Led {
bool flag = true;
public:
void invert(){
flag = !flag;
digitalWrite(LED_BUILTIN, flag);
}
};
void loop(){
static Led* p = new Led();
p->invert();
delay(1000);
}
クラスを使って機能を抽象化
以下のプログラムの動作を考えよう。
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
class Led {
int times;
void blinkLed(){
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
public:
Led(int t):times(t){}
void flash(){
for(int i=0; i<times; ++i){
blinkLed();
}
delay(1000);
}
};
void loop(){
static Led led(3);
led.flash();
}
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
class Led {
int times;
void blinkLed(){
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
public:
Led(int t):times(t){}
void flash(){
for(int i=0; i<times; ++i){
blinkLed();
}
delay(1000);
}
};
void loop(){
static Led* leds[]={new Led(1), new Led(2), new Led(3), NULL};
for(Led** p = leds; *p != NULL; ++p){
(*p)->flash();
}
}
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
class Led {
int times;
void blinkLed();
public:
Led(int t);
void flash();
};
Led::Led(int t):times(t){}
void Led::blinkLed(){
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
void Led::flash(){
for(int i=0; i<times; ++i){
blinkLed();
}
delay(1000);
}
void loop(){
static Led* leds[]={new Led(1), new Led(2), new Led(3), NULL};
for(Led** p = leds; *p != NULL; ++p){
(*p)->flash();
}
}
右のメニューから複数タブを作って、プログラムを分割する。
#include "Led.h"
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
void loop(){
static Led* leds[]={new Led(1), new Led(2), new Led(3), NULL};
for(Led** p = leds; *p != NULL; ++p){
(*p)->flash();
}
}
class Led {
int times;
void blinkLed();
public:
Led(int t);
void flash();
};
#include "Arduino.h"
#include "Led.h"
Led::Led(int t):times(t){}
void Led::blinkLed(){
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
void Led::flash(){
for(int i=0; i<times; ++i){
blinkLed();
}
delay(1000);
}
演習6-1を利用して、1秒間の間だけ高速で点滅させて半分の明るさにする halfBlink メソッドを作りなさい。
だんだん明るくなってだんだん暗くなるような softBlink メソッドを作りなさい。
やり過ぎ感のある、継承によるオブジェクトの作り分け
void setup(){
pinMode(LED_BUILTIN,OUTPUT);
}
class Led {
void blinkLed(){
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
protected:
virtual int times()=0;
public:
virtual ~Led(){}
void flash(){
for(int i=0; i<times(); ++i){
blinkLed();
}
delay(1000);
}
};
class Led2 : public Led {
protected:
virtual int times(){
return 2;
}
};
class Led3 : public Led {
protected:
virtual int times(){
return 3;
}
};
void loop(){
static Led* leds[]={new Led2(), new Led3(), NULL};
for(Led** p = leds; *p != NULL; ++p){
(*p)->flash();
}
}