DigisparkにCharlieplexingは不向きかな。その2 [Arduino]
調べていたら、aitendoで12連LEDを発見したので購入。
12バーLEDアレイ - aitendo
https://www.aitendo.com/product/11443

ついでにこれも。
超極細エナメル線★φ0.1★10m巻き★ - aitendo
https://www.aitendo.com/product/4733

それで作ってみました。抵抗もチップ抵抗を使用。

で、こんな感じ。

12バーLEDアレイ - aitendo
https://www.aitendo.com/product/11443

ついでにこれも。
超極細エナメル線★φ0.1★10m巻き★ - aitendo
https://www.aitendo.com/product/4733

それで作ってみました。抵抗もチップ抵抗を使用。

で、こんな感じ。

DigisparkにCharlieplexingは不向きかな。 [Arduino]
以前にもマトリックスLEDでCharlieplexingの応用で駆動するのをやりましたが、Digisparkのようなピン数の少ないものほどよい適応かなと思って作ってみました。
結論からいくと、Digisparkではやや動作がおかしいので、Arduino Nano互換機でやりました。
10ポイント青色バーLEDアレイOSX10201-B ディスプレイ・表示器 秋月電子通商-電子部品・ネット通販
https://akizukidenshi.com/catalog/g/gI-04294/

これをCharlieplexingで光らせるには4ピンあればOKです。(4ピンあれば12個のLEDまでいける)
端切れ基盤にICソケットとピンヘッダと抵抗を載せてポリウレタン銅線で配線。


いざDigisparkでやってみると、なにかおかしい。
光っちゃいけないところがぼやっと光ったりする。
理由として考えられること:
・リセットピン(P5)をI/Oピンとして使うとドライブ能力が低い
・純粋なピンはP0、P2しかなく、他はUSBやbuilt-in LEDとつながっている
という感じだと推測しています。
たとえば、A → B と電流が流れてLEDを光らせる場合、 A → C → B という経路にはほぼ流れないんだけど、ピンの条件が均一でないために A → C → B という経路でもそこそこ流れてしまうのかなって。
仕方ないので、Arduino Nanoの互換機で試してみました。

結論からいくと、Digisparkではやや動作がおかしいので、Arduino Nano互換機でやりました。
10ポイント青色バーLEDアレイOSX10201-B ディスプレイ・表示器 秋月電子通商-電子部品・ネット通販
https://akizukidenshi.com/catalog/g/gI-04294/

これをCharlieplexingで光らせるには4ピンあればOKです。(4ピンあれば12個のLEDまでいける)
端切れ基盤にICソケットとピンヘッダと抵抗を載せてポリウレタン銅線で配線。


いざDigisparkでやってみると、なにかおかしい。
光っちゃいけないところがぼやっと光ったりする。
理由として考えられること:
・リセットピン(P5)をI/Oピンとして使うとドライブ能力が低い
・純粋なピンはP0、P2しかなく、他はUSBやbuilt-in LEDとつながっている
という感じだと推測しています。
たとえば、A → B と電流が流れてLEDを光らせる場合、 A → C → B という経路にはほぼ流れないんだけど、ピンの条件が均一でないために A → C → B という経路でもそこそこ流れてしまうのかなって。
仕方ないので、Arduino Nanoの互換機で試してみました。

// Drive 10 LEDs with 4 pins
//
// A A A B B B C C C D D D
// +---------------------+ | |
// | | | | | | | | | | | | | |
// | _ _ _ _ _ _ _ _ _ _ | _ _ Cathode(K)
// | ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ | ^ ^ Anode(A)
// | | | | | | | | | | | | | |
// +---------------------+ | |
// B C D A C D A B D A B C
//
const uint8_t LEDsK[12] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3 }; // Cathode side (0:A, 1:B, 2:C, 3:D)
const uint8_t LEDsA[12] = { 1, 2 ,3, 0, 2, 3, 0, 1, 3, 0, 1, 2 }; // Anode side
const uint8_t LEDsPn[4] = { 2, 3, 4, 5 }; // Arduino pin number (or DDRxn, PORTxn)
static uint8_t pos = 0, dir = true; // Position and Direction(0:-, 1:+) of light
void setup() {
}
void loop() {
lightUpD( dir ? pos++ : pos-- );
delay(50);
if(pos == 9 || pos == 0) dir = 1 ^ dir;
}
void lightUp(uint8_t n){ // Arduino form
for(uint8_t i=0; i<4; i++) {
if( LEDsA[n]==i || LEDsK[n]==i ) { // If the pin is connected to the anode or cathode of the LED,
pinMode( LEDsPn[i], OUTPUT ); // set to output pin
digitalWrite( LEDsPn[i], LEDsA[n]==i ); // set cathode LOW, Set anode HIGH
} else {
pinMode( LEDsPn[i], INPUT ); // Set to Hi-
}
}
}
void lightUpD(uint8_t n){ // port D version
for(uint8_t i=0; i<4; i++) {
bitWrite( DDRD , LEDsPn[i], LEDsA[n]==i || LEDsK[n]==i );
bitWrite( PORTD, LEDsPn[i], LEDsA[n]==i );
}
}
Digisparkで音楽演奏【PLL OC1A編】 [Arduino]
以前のスケッチを手直し。
ボードマネージャは、ATTinyCore でも Digistump AVR Boards でも行けるようにしてみた。
8MHzでもなんとか遅延はなさそうで、乾電池2本でも動作できるはず。

結局もう1つ改造Digispark作成。
壊れたイヤホンからケーブルをリユースして録音用パーツを作成。
以下、スケッチ。
次は、矩形波じゃないやつで。
ボードマネージャは、ATTinyCore でも Digistump AVR Boards でも行けるようにしてみた。
8MHzでもなんとか遅延はなさそうで、乾電池2本でも動作できるはず。

結局もう1つ改造Digispark作成。
壊れたイヤホンからケーブルをリユースして録音用パーツを作成。
以下、スケッチ。
// Digispark version Score Replay Sketch
// Clock : 16.5/16/8 MHz, PLL : 66/64 MHz
#include "notes2.h" // Definition data of notes ( pitch (scale & octave), and note value (length))
#include "Kewpie3min.h" // "The Parade of the Tin Soldiers" by Leon Jessel
#define MAX_TRACK 4 // Maximum number of tracks
// Number of cycles that are the wavelength of the basic 12-note scale (from C0 to B0) (@ 8 MHz, with an interrupt every 256 clocks)
static const uint16_t CYC_SCALE[] = { 1911, 1804, 1703, 1607, 1517, 1432, 1351, 1276, 1204, 1136, 1073, 1012 };
void setup(){
pinMode( 1, OUTPUT ); // Audio output (PB1,OC1A)
pinMode( 0, INPUT_PULLUP ); // Switch (PB0)
// *** Register Settings (Timer1, for DAC) *** PLL 64MHz, No prescaling. 8bit=256clock to make PWM, so 250kHz.
TIMSK &= ~_BV(TOIE1); // TIMSK(T/C Interrupt Mask Register) - TOIE1(T/C1 Overflow Interrupt Enable) CLEAR : Disable ISR(TIMER1_OVF_vect) (for Digistump AVR Boards)
PLLCSR |= _BV(PCKE); // PLLCSR(PLL Control and Status Register) - PCKE(PCK Enable) SET : PCK clock(fast 64 MHz) is used as T/C1 clock source
TCCR1 = B01100001; // TCCR1(T/C1 Control Register) : PWM A Enable. OC1A cleared on compare match. OC1A not connected. No prescale
OCR1A = 0; // OCR1A(T/C1 Output Compare RegisterA) : Set output to 0
OCR1C = 255; // OCR1C(T/C1 Output Compare RegisterC) : Set upper limit to 255
// *** Register Settings (Timer0, for Data) *** Data processing interval 31.25kHz(256clk@8MHz or 512clk@16MHz)
TIMSK &= ~_BV(TOIE0); // TIMSK(T/C Interrupt Mask Register) - TOIE0(T/C0 Overflow Interrupt Enable) CLEAR : Disable ISR(TIMER0_OVF_vect) (for ATTinyCore)
TCCR0A = B00000011; // TCCR0A(T/C0 Control Register A) : OC0A/OC0B disconnected, Fast PWM
TCCR0B = B01001010; // TCCR0B(T/C0 Control Register B) : Fast PWM, TOP:OCR0A, clk/8 (From prescaler)
OCR0A = F_CPU / 250000; // OCR0A (T/C0 Output Compare A Register) : TOP 8MHz:32, 16MHz:64, 16.5MHz:66
}
void loop(){
while( digitalRead(0) ); // Wait until the switch is pressed
while( !digitalRead(0) ); // Wait until the switch is released
playDsPLL( Kewpie3min ); // Playback
}
void playDsPLL(const uint16_t *d){ // Digispark PLL version (16.5/16/8 MHz support)
uint8_t Tracks; // Number of tracks
const uint16_t *NoteP[MAX_TRACK]; // Pointer for each track of the score
uint16_t NoteCycle, n; // Number of interrupt cycles required for the length of the reference note (96th note) and its counter (n)
uint16_t note; // Note (pitch + note value) information read from PROGMEM
uint8_t len[MAX_TRACK]; // Length of note (how many 96th notes) (subtraction counter)
uint16_t cyc[MAX_TRACK], c[MAX_TRACK];// Number of interrupt cycles (cyc) required for one sound wavelength cycle and its counter (c)
uint16_t env[MAX_TRACK]; // Sound amplitude (envelope)
uint16_t out[MAX_TRACK]; // Output value
uint8_t lap = 20; // Sound transitional cycles(laptime) (for Attenuation calculator)
// *** Preparing Scores ***
NoteCycle = 8000000 / 256 *4*60 / pgm_read_word_near(d++) / MIN_NOTE; // Number of cycles required for reference note
for( Tracks = 0; Tracks < MAX_TRACK; ) { // Get the number of tracks and the start position of each track from the song data
if( pgm_read_word_near(d++) != 0 ) continue; // Skip until the break comes
if( pgm_read_word_near(d) == 0 ) break; // If two zeros follow, end of data
len[ Tracks ] = 1; // Initialize the note length subtraction counter to the remaining 1
NoteP[ Tracks++ ] = d; // Get location in memory, Count up the number of tracks
}
n = Tracks; // Initialize the score processing so that it can be performed immediately after the start of the do loop
// *** Playback ***
do {
// * Processing Scores *
if( --n < Tracks ) { // Processing of score for each reference note length
if( !--len[n] ) {
note = pgm_read_word_near( NoteP[n]++ );
len[n] = (uint8_t) note; // The lower 8 bits are the length of the note (how many times the length of a 96th note)
cyc[n] = (note>>8) ? CYC_SCALE[ (note>>8) & 0xf ] >> (note>>12) : 0; // Upper 4 bits are octave, next 4 bits are pitch class (0-11), 0 for rests
c[n] = 0; // Initialize the counter for the number of cycles to create one square wave cycle
env[n] = 0xffff; // Initially, the maximum amplitude
}
if( !n ) n = NoteCycle;
}
// * Waveform Processing / Output *
switch( Tracks ) { // Create output data, Square wave with duty ratio of 1:1
case 4: out[3] = ( ( c[3] = (++c[3]==cyc[3]) ? 0 : c[3] ) < (cyc[3]>>1) ) ? env[3] : 0; [[fallthrough]];
case 3: out[2] = ( ( c[2] = (++c[2]==cyc[2]) ? 0 : c[2] ) < (cyc[2]>>1) ) ? env[2] : 0; [[fallthrough]];
case 2: out[1] = ( ( c[1] = (++c[1]==cyc[1]) ? 0 : c[1] ) < (cyc[1]>>1) ) ? env[1] : 0; [[fallthrough]];
case 1: out[0] = ( ( c[0] = (++c[0]==cyc[0]) ? 0 : c[0] ) < (cyc[0]>>1) ) ? env[0] : 0;
}
switch( Tracks ) { // OC1A(ATtiny85:PB1) Change output by number of tracks
case 1: OCR1A = out[0] >>8; break;
case 2: OCR1A = ((out[0]>>1) + (out[1]>>1)) >>8; break;
case 3: OCR1A = ((out[0]>>1) + (out[1]>>2) + (out[2]>>2)) >>8; break;
case 4: OCR1A = ((out[0]>>2) + (out[1]>>2) + (out[2]>>2) + (out[3]>>2)) >>8;
}
switch( --lap ) { // Amplitude attenuation (Distribute processing per loop)
case 4: env[3] -= (env[3]>>9); break;
case 3: env[2] -= (env[2]>>9); break;
case 2: env[1] -= (env[1]>>9); break;
case 1: env[0] -= (env[0]>>9); break;
case 0: lap = 20; // every 640usec(32usec*20) @16MHz (Adjustable)
}
while( !(TIFR & _BV(TOV0)) ); // Waiting for Timer0 overflow (every 32usec)
TIFR |= _BV(TOV0); // Clear T/C0 Overflow Flag
//if( ! digitalRead(0) ) break; // Ends when PB0 is pressed.
if( !(PINB & _BV(0)) ) break; // Ends when PB0 is pressed.
} while( note ); // Exit if note data is 0
OCR1A = 0; // Set output to 0
}
次は、矩形波じゃないやつで。
Digisparkで音楽演奏【楽譜サンプル】 [Arduino]
あたらしい楽譜の記載法で入力はやや楽に。

「Kewpie3min.h」
イントロ部分を和音がきれいになるようにちょこっとアレンジしてみた。
スケッチも手直ししてみたので次回。

「Kewpie3min.h」
イントロ部分を和音がきれいになるようにちょこっとアレンジしてみた。
static const uint16_t Kewpie3min[] PROGMEM = { // "The Parade of the Tin Soldiers" by Leon Jessel
168, 0 ,
RSe , g5s , g5s , g5e , g5e , e5e , e5e , f5q , RSe , g5s , g5s , g5e , g5e , C5e , C5e , d5q , RSe , g5s , g5s , g5h , d5h , g4h , RSq , g5e , g5s , g5s ,
e5e , RSe , g5e , RSe , g5e , RSe , RSe , g5s , g5s , f5e , RSe , g5e , RSe , g5e , RSe , RSe , g5s , g5s , e5e , RSe , g5e , RSe , b5e , RSe , a5e , RSe , g5e , F5e , f5e , e5e , d5e , RSe , RSe , g5s , g5s ,
e5e , RSe , g5e , RSe , g5e , RSe , RSe , g5s , g5s , d5e , RSe , b5e , RSe , b5e , RSe , RSe , a5s , a5s , a5e , RSe , a5e , RSe , d6e , RSe , d6e , RSe , g5q , g5s , G5s , a5s , A5s , b5e , g5e , a5e , g5e ,
e5e , RSe , g5e , RSe , e5e , g5e , RSe , g5e , f5e , RSe , g5e , RSe , f5e , g5e , RSe , g5e , e5e , RSe , g5e , RSe , b5e , RSe ,a5e , RSe , g5e , F5e , f5e , e5e , d5e , RSe , RSe , g5s , g5s ,
e5e , RSe , g5e , RSe , g5e , RSe , RSe , g5s , g5s , f5e , RSe , a5e , RSe , a5e , RSe , c6e , RSe , e6e , RSe , RSq , d6e , RSe , RSq ,
//c6e , RSe , g5e , RSe , c6e , RSe , RSq , // OP
c6e , g5s , G5s , a5s , A5s , b5e , c6e , RSe , c4q , // ED
0,
RSq , RSq , C5e , C5e , d5q , RSq , RSq , A4e , A4e , b4q , RSq , RSe , F5h , c5h , RSe , g5h , RSq ,
RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e ,
RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , b3e , RSe , b3e , RSe , b3e , RSe , b3e , RSe , a3e , RSe , a3e , RSe , a3e , RSe , a3e , g3q , RSq , RSh ,
RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e ,
RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , a3e , RSe , a3e , RSe , a3e , RSe , a3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e ,
//RSe , g3e , RSe , g3e , g3e , RSe , RSq , // OP
g3e , RSe , RSq , c4e , RSe , c3q , // ED
0,
RSq , RSw , RSw , RSe , RSe , f5h , b4h , RSq , g4h ,
RSe , e3e , RSe , e3e , RSe , e3e , RSe , e3e , RSe , f3e , RSe , f3e , RSe , f3e , RSe , f3e , RSe , e3e , RSe , e3e , RSe , e3e , RSe , e3e , RSe , f3e , RSe , f3e , RSe , f3e , RSe , f3e ,
RSe , e3e , RSe , e3e , RSe , e3e , RSe , e3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , g3e , RSe , F3e , RSe , F3e , RSe , F3e , RSe , F3e , RSw ,
RSe , e3e , RSe , e3e , RSe , e3e , RSe , e3e , RSe , f3e , RSe , f3e , RSe , f3e , RSe , f3e , RSe , e3e , RSe , e3e , RSe , e3e , RSe , e3e , RSe , f3e , RSe , f3e , RSe , f3e , RSe , f3e ,
RSe , e3e , RSe , e3e , RSe , e3e , RSe , e3e , RSe , f3e , RSe , f3e , RSe , f3e , RSe , f3e , RSe , e3e , RSe , d3e , RSe , f3e , RSe , f3e ,
//RSe , e3e , RSe , e3e , e3e , RSe , RSq , // OP
e3e , RSe , RSq , RSe , RSe , c2q , // ED
0,
RSq , RSw , RSw , RSe , RSe , RSe , e5h , a4h , RSe , RSh ,
c3q , g2q , c2q , g2q , d2q , g2q , d2q , g2q , c3q , g2q , c2q , g2q , d2q , g2q , d2q , g2q ,
c3q , g2q , c2q , g2q , d2q , g2q , d2q , g2q , a2q , d2q , F2q , d2q , g2q , RSq , RSh ,
c3q , g2q , c3q , c3q , g2q , d2q , g2q , g2q , c3q , g2q , c3q , c3q , g2q , d2q , g2q , g2q ,
c3q , g2q , c3q , c3q , f2q , c2q , f2q , f2q , c3q , g2q , d2q , g2q ,
//c3q , g2q , c3q , RSq , // OP
c3e , RSe , RSq , RSq , RSq , // ED
0, 0 };
スケッチも手直ししてみたので次回。
DigisparkのPLLとlow-pass filterとアンプと [Arduino]
上位のArduino Uno(ATmega328)にはなくて、Digispark(ATtiny85)にはあるものとして、PLL(位相同期回路: phase locked loop)があります。
まず、使用するには、、
PLLCSR(PLL Control and Status Register)
Bit 1 - PLLE: PLL Enable はシステムクロック元としPLLが選択されているので元々1。
Bit 2 - PCKE: PCK Enable を1にすることで、タイマー/カウンタ1のクロック元をPLLにします。
Bit 7 - LSM: Low Speed Mode(32MHz) ですが、そのまま 0 で高速モード(64MHz)。
・注意点
★システムクロック(16/8/1MHz)に関わらず64MHz(LSM: Low Speed Mode時は32MHz)
(ただしOSCCAL (Oscillator Calibration Register)をいじるとシステムクロックと一緒に微調整はできます)
★タイマー/カウンタ1だけ
(ただしDigisparkではボードマネージャでDigistump AVR Boardsの場合でISR(TIMER1_OVF_vect)が使用されてしまっている)
・使用用途
とりあえず、高速PWMによる疑似DACかな。
64MHz / 256(8bit) = 250kHz が、キャリア周波数ということでした。
まあ、Uno(16MHz)で9bitだと 16MHz / 512(9bit) = 31.25kHz だとノイズらしいノイズは分かりませんでしたが、半分の15.625kHzだとノイズが分かりました。
あと、外部出力の際には、low-pass filterがないとアンプが壊れるよっていうのが各所に書いてありました。
low-pass filterの具体的な値の計算式は理解できなかったので、以下のサイトのPLL音声出力時の回路図を参考とさせていただきました。
PB4(OC1B)から1kΩの抵抗と、そこからGNDとの間に0.1μFのコンデンサとなっていました。

Technoblogy - Waveform Generation using an ATtiny85
http://www.technoblogy.com/show?QVN
とか
Technoblogy - Four Sample Player
http://www.technoblogy.com/show?2XJD
また、次のページには、PB4(OC1B)から220μFの電解コンデンサを介してスピーカとつないでありました。
Technoblogy - Tiny Synth
http://www.technoblogy.com/show?Q7H
他では、100μFだったりするのもありました。
Technoblogy - Audio Pitch Shifter
http://www.technoblogy.com/show?1L02
できあいのアンプとつないでみました。

そのままアンプにつなぐと、音が大きすぎて音が割れるので、回路図のとおり10kΩの半固定抵抗をつけました。
まず、使用するには、、
PLLCSR(PLL Control and Status Register)
Bit 1 - PLLE: PLL Enable はシステムクロック元としPLLが選択されているので元々1。
Bit 2 - PCKE: PCK Enable を1にすることで、タイマー/カウンタ1のクロック元をPLLにします。
Bit 7 - LSM: Low Speed Mode(32MHz) ですが、そのまま 0 で高速モード(64MHz)。
・注意点
★システムクロック(16/8/1MHz)に関わらず64MHz(LSM: Low Speed Mode時は32MHz)
(ただしOSCCAL (Oscillator Calibration Register)をいじるとシステムクロックと一緒に微調整はできます)
★タイマー/カウンタ1だけ
(ただしDigisparkではボードマネージャでDigistump AVR Boardsの場合でISR(TIMER1_OVF_vect)が使用されてしまっている)
・使用用途
とりあえず、高速PWMによる疑似DACかな。
64MHz / 256(8bit) = 250kHz が、キャリア周波数ということでした。
まあ、Uno(16MHz)で9bitだと 16MHz / 512(9bit) = 31.25kHz だとノイズらしいノイズは分かりませんでしたが、半分の15.625kHzだとノイズが分かりました。
あと、外部出力の際には、low-pass filterがないとアンプが壊れるよっていうのが各所に書いてありました。
low-pass filterの具体的な値の計算式は理解できなかったので、以下のサイトのPLL音声出力時の回路図を参考とさせていただきました。
PB4(OC1B)から1kΩの抵抗と、そこからGNDとの間に0.1μFのコンデンサとなっていました。

Technoblogy - Waveform Generation using an ATtiny85
http://www.technoblogy.com/show?QVN
とか
Technoblogy - Four Sample Player
http://www.technoblogy.com/show?2XJD
また、次のページには、PB4(OC1B)から220μFの電解コンデンサを介してスピーカとつないでありました。
Technoblogy - Tiny Synth
http://www.technoblogy.com/show?Q7H
他では、100μFだったりするのもありました。
Technoblogy - Audio Pitch Shifter
http://www.technoblogy.com/show?1L02
できあいのアンプとつないでみました。

そのままアンプにつなぐと、音が大きすぎて音が割れるので、回路図のとおり10kΩの半固定抵抗をつけました。
Digispark関連の追加のボードマネージャのURL [Arduino]
Digispark関連の追加のボードマネージャのURL (additonal Boards Manager URLs)

追加したものは、以下に保存されるっぽい。
%appdata%\..\local\Arduino15\packages\
具体的には、、
C:\Users\%USERNAME%\AppData\Local\Arduino15\packages\
追加の.jsonファイルはその一つ上位のフォルダに。
★Digispark関連と、そのほか興味はあるけどまだ試していないボードの追加のボードマネージャのURL★
■ ATTinyCore by Spence Konde
Dr. Azzy's Electronics (作者のページ)
http://drazzy.com/e/
GitHub - SpenceKonde/ATTinyCore: Arduino core for ATtiny 1634, 828, x313, x4, x41, x5, x61, x7 and x8
https://github.com/SpenceKonde/ATTinyCore
ATTinyCore/Installation.md at master · SpenceKonde/ATTinyCore · GitHub
https://github.com/SpenceKonde/ATTinyCore/blob/master/Installation.md
★additonal URL:
http://drazzy.com/package_drazzy.com_index.json
ATtinyで遊ぶときに欠かせない。
これにもDigisparkが含まれている。
デフォルトだと、時間関連に対して、Timer0を使っている。(Digistumpはtimer1を使用)
DigiKeyboard.h などは使えない。
他に megaTinyCore というので tinyAVR 0/1/2-series 用のも作ってみえます。
■ kosakalab
Arduino IDE で ATtiny 他の開発 Make kosakalab
https://make.kosakalab.com/make/electronic-work/arduino-ide-dev/
★additonal URLs:
Arduino IDE に ATtiny10/13 の開発環境を組み込む
https://kimio-kosaka.github.io/bitDuino13/package_bitDuino13_index.json
Arduino IDE に ATmaga88P/328P/644P 他の開発環境を組み込む
https://kimio-kosaka.github.io/ATMegaCore/package_ATMegaCore_index.json
ATTinyCoreで対応していないATtiny13とか、足多めのATmega644Pとか。
■ Digistump AVR Boards
digisparktutorialsconnecting [Digistump Wiki]
http://digistump.com/wiki/digispark/tutorials/connecting
★additonal URL:
http://digistump.com/package_digistump_index.json
Digistump公式のかな。
Timer1を時間関連で使用されている。
DigiKeyboard.h などで簡単にHID (Human Interface Device)を作れる。
■ Improved version of Digistump avr core for Arduino
GitHub - ArminJoDigistumpArduino Improved version of Digistump avr core for Arduino
https://github.com/ArminJo/DigistumpArduino
★additonal URL:
https://raw.githubusercontent.com/ArminJo/DigistumpArduino/master/package_digistump_index.json
Digistump AVR Boardsの代用で、いろいろ改良されているらしい。
今後触ってみたいと思っていた MH-ET LIVE Tiny88 というものも、Version 1.7.4までは対応していた。
■ MH-ET LIVE Boards
GitHub - MHEtLive/MHEtLiveArduino
https://github.com/MHEtLive/MHEtLiveArduino
★additonal URL:
https://raw.githubusercontent.com/MHEtLive/arduino-boards-index/master/package_mhetlive_index.json
MH-ET LIVE Tiny88 だけ、説明なさすぎ。
■ MightyCore
GitHub - MCUdude/MightyCore: Arduino hardware package for ATmega1284, ATmega644, ATmega324, ATmega324PB, ATmega164, ATmega32, ATmega16 and ATmega8535
https://github.com/MCUdude/MightyCore
★additonal URL:
https://mcudude.github.io/MightyCore/package_MCUdude_MightyCore_index.json
大きめ、足多めのATmega使いたいとき。
■ esp8266
GitHub - esp8266/Arduino: ESP8266 core for Arduino
https://github.com/esp8266/Arduino
★additonal URL:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
■ esp32
GitHub - espressif/arduino-esp32: Arduino core for the ESP32
https://github.com/espressif/arduino-esp32
★additonal URL:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
■ Seeeduino Xiao
https://wiki.seeedstudio.com/jp/Seeeduino-XIAO/
★additonal URL:
https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
■ Raspberry Pi Pico/RP2040
GitHub - earlephilhower/arduino-pico: Raspberry Pi Pico Arduino core, for all RP2040 boards
https://github.com/earlephilhower/arduino-pico
★additonal URL:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
Raspberry Pi Picoは、Arduino公式版(ボードマネージャ追加不要)とearlephilhower/arduino pico版がある。これは後者。

追加したものは、以下に保存されるっぽい。
%appdata%\..\local\Arduino15\packages\
具体的には、、
C:\Users\%USERNAME%\AppData\Local\Arduino15\packages\
追加の.jsonファイルはその一つ上位のフォルダに。
★Digispark関連と、そのほか興味はあるけどまだ試していないボードの追加のボードマネージャのURL★
■ ATTinyCore by Spence Konde
Dr. Azzy's Electronics (作者のページ)
http://drazzy.com/e/
GitHub - SpenceKonde/ATTinyCore: Arduino core for ATtiny 1634, 828, x313, x4, x41, x5, x61, x7 and x8
https://github.com/SpenceKonde/ATTinyCore
ATTinyCore/Installation.md at master · SpenceKonde/ATTinyCore · GitHub
https://github.com/SpenceKonde/ATTinyCore/blob/master/Installation.md
★additonal URL:
http://drazzy.com/package_drazzy.com_index.json
ATtinyで遊ぶときに欠かせない。
これにもDigisparkが含まれている。
デフォルトだと、時間関連に対して、Timer0を使っている。(Digistumpはtimer1を使用)
DigiKeyboard.h などは使えない。
他に megaTinyCore というので tinyAVR 0/1/2-series 用のも作ってみえます。
■ kosakalab
Arduino IDE で ATtiny 他の開発 Make kosakalab
https://make.kosakalab.com/make/electronic-work/arduino-ide-dev/
★additonal URLs:
Arduino IDE に ATtiny10/13 の開発環境を組み込む
https://kimio-kosaka.github.io/bitDuino13/package_bitDuino13_index.json
Arduino IDE に ATmaga88P/328P/644P 他の開発環境を組み込む
https://kimio-kosaka.github.io/ATMegaCore/package_ATMegaCore_index.json
ATTinyCoreで対応していないATtiny13とか、足多めのATmega644Pとか。
■ Digistump AVR Boards
digisparktutorialsconnecting [Digistump Wiki]
http://digistump.com/wiki/digispark/tutorials/connecting
★additonal URL:
http://digistump.com/package_digistump_index.json
Digistump公式のかな。
Timer1を時間関連で使用されている。
DigiKeyboard.h などで簡単にHID (Human Interface Device)を作れる。
■ Improved version of Digistump avr core for Arduino
GitHub - ArminJoDigistumpArduino Improved version of Digistump avr core for Arduino
https://github.com/ArminJo/DigistumpArduino
★additonal URL:
https://raw.githubusercontent.com/ArminJo/DigistumpArduino/master/package_digistump_index.json
Digistump AVR Boardsの代用で、いろいろ改良されているらしい。
今後触ってみたいと思っていた MH-ET LIVE Tiny88 というものも、Version 1.7.4までは対応していた。
■ MH-ET LIVE Boards
GitHub - MHEtLive/MHEtLiveArduino
https://github.com/MHEtLive/MHEtLiveArduino
★additonal URL:
https://raw.githubusercontent.com/MHEtLive/arduino-boards-index/master/package_mhetlive_index.json
MH-ET LIVE Tiny88 だけ、説明なさすぎ。
■ MightyCore
GitHub - MCUdude/MightyCore: Arduino hardware package for ATmega1284, ATmega644, ATmega324, ATmega324PB, ATmega164, ATmega32, ATmega16 and ATmega8535
https://github.com/MCUdude/MightyCore
★additonal URL:
https://mcudude.github.io/MightyCore/package_MCUdude_MightyCore_index.json
大きめ、足多めのATmega使いたいとき。
■ esp8266
GitHub - esp8266/Arduino: ESP8266 core for Arduino
https://github.com/esp8266/Arduino
★additonal URL:
http://arduino.esp8266.com/stable/package_esp8266com_index.json
■ esp32
GitHub - espressif/arduino-esp32: Arduino core for the ESP32
https://github.com/espressif/arduino-esp32
★additonal URL:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
■ Seeeduino Xiao
https://wiki.seeedstudio.com/jp/Seeeduino-XIAO/
★additonal URL:
https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
■ Raspberry Pi Pico/RP2040
GitHub - earlephilhower/arduino-pico: Raspberry Pi Pico Arduino core, for all RP2040 boards
https://github.com/earlephilhower/arduino-pico
★additonal URL:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
Raspberry Pi Picoは、Arduino公式版(ボードマネージャ追加不要)とearlephilhower/arduino pico版がある。これは後者。
タグ:Digispark
Digispark 16.5MHzの謎に迫る [Arduino]
Digispark は V-USBのとき、16MHzではなく16.5MHzと気持ち(3%ほど)速めの設定になっています。
USBの処理のために3%ほど速くしてくれているのだと思います。(たぶん)
そもそもATtiny85は、外部クリスタルなしでは8MHzなのですが、そこからいろいろあって16MHzや16.5MHzを作りだしているようです。
そのあたりを調べてみました。
まずfuse。

工場出荷時と異なるのは、、
・Fuse Extended Byte
Self-programming enabledが、1→0で自己プログラミング機能が許可されています。
USBから書き込めるということでこれは当然。
・Fuse Low Byte
7ビット目のCKDIV8と、3~0ビット目のCKSEL3~CKSEL0が変更されています。
CKDIV8 は、0→1となり、システムクロックの8分周はしないということでこれも当然。
CKSEL3~CKSEL0 を CKSEL[3:0] 0001 に設定することで、
Clock source setting を High Frequency PLL Clock として、divided by four として、16MHz にしているようです。
つづいてRegister。
クロックに関係しそうなのは、CLKPR, PLLCSR, OSCCALです。
手持ちのDigisparkに以下のスケッチを書き込み、LEDの点灯時間を目視で確認することでこれらのレジスタの値を調べました。

・0x26 CLKPR (Clock Prescale Register)
CLKPS[3:0] Clock Division Factor のところで16MHz, 16.5MHz時は、分周なし(1分周), 8MHz時は2分周, 1MHz時は16分周となっていました。
・0x27 PLLCSR (PLL Control and Status Register)
Bit 7 – LSM: Low Speed Mode(32MHz) はそのまま 0 で高速モード(64MHz)。
Bit 2 – PCKE: PCK Enable もそのまま 0で、はタイマ/カウンタ1のクロック元はシステムクロック。
Bit 1 – PLLE: PLL Enable は1に変更されていますが、システムクロック元としてPLLが選択されているので当然。
Bit 0 – PLOCK: PLL Lock Detector も1に変更で、PLLが基準クロックに固定化されている、と。
・0x31 OSCCAL (Oscillator Calibration Register)
あらかじめ工場で設定された値が自動的に入るようにできているようです。
手持ちのDigisparkでは、
16/8/1MHz時は、0x91(10進で145) (おそらく工場での設定値のまま)
16.5MHz時は、0x99(10進で153)
となっていました。
このレジスタで3%のclock upをしていたようです。
USBの処理のために3%ほど速くしてくれているのだと思います。(たぶん)
そもそもATtiny85は、外部クリスタルなしでは8MHzなのですが、そこからいろいろあって16MHzや16.5MHzを作りだしているようです。
そのあたりを調べてみました。
まずfuse。

工場出荷時と異なるのは、、
・Fuse Extended Byte
Self-programming enabledが、1→0で自己プログラミング機能が許可されています。
USBから書き込めるということでこれは当然。
・Fuse Low Byte
7ビット目のCKDIV8と、3~0ビット目のCKSEL3~CKSEL0が変更されています。
CKDIV8 は、0→1となり、システムクロックの8分周はしないということでこれも当然。
CKSEL3~CKSEL0 を CKSEL[3:0] 0001 に設定することで、
Clock source setting を High Frequency PLL Clock として、divided by four として、16MHz にしているようです。
つづいてRegister。
クロックに関係しそうなのは、CLKPR, PLLCSR, OSCCALです。
手持ちのDigisparkに以下のスケッチを書き込み、LEDの点灯時間を目視で確認することでこれらのレジスタの値を調べました。
#define isBitSet(byte, bit) ((byte) & (1 << (bit)))
void setup() {
pinMode( 0, INPUT_PULLUP ); // tactile switch
pinMode( 1, OUTPUT ); // builtin LED
}
void loop() {
uint8_t i;
while( digitalRead(0) );
delay(1000);
//0x31 OSCCAL
for(i=0; i<8; i++) {
digitalWrite( 1, HIGH);
delay( isBitSet( OSCCAL, 7-i) ? 500: 100 );
digitalWrite( 1, LOW );
delay(500);
}
delay(2000);
// 0x27 PLLCSR
for(i=0; i<8; i++) {
digitalWrite( 1, HIGH);
delay( isBitSet( PLLCSR, 7-i) ? 500: 100 );
digitalWrite( 1, LOW );
delay(500);
}
delay(2000);
// 0x26 CLKPR
for(i=0; i<8; i++) {
digitalWrite( 1, HIGH);
delay( isBitSet( CLKPR, 7-i) ? 500: 100 );
digitalWrite( 1, LOW );
delay(500);
}
}

・0x26 CLKPR (Clock Prescale Register)
CLKPS[3:0] Clock Division Factor のところで16MHz, 16.5MHz時は、分周なし(1分周), 8MHz時は2分周, 1MHz時は16分周となっていました。
・0x27 PLLCSR (PLL Control and Status Register)
Bit 7 – LSM: Low Speed Mode(32MHz) はそのまま 0 で高速モード(64MHz)。
Bit 2 – PCKE: PCK Enable もそのまま 0で、はタイマ/カウンタ1のクロック元はシステムクロック。
Bit 1 – PLLE: PLL Enable は1に変更されていますが、システムクロック元としてPLLが選択されているので当然。
Bit 0 – PLOCK: PLL Lock Detector も1に変更で、PLLが基準クロックに固定化されている、と。
・0x31 OSCCAL (Oscillator Calibration Register)
あらかじめ工場で設定された値が自動的に入るようにできているようです。
手持ちのDigisparkでは、
16/8/1MHz時は、0x91(10進で145) (おそらく工場での設定値のまま)
16.5MHz時は、0x99(10進で153)
となっていました。
このレジスタで3%のclock upをしていたようです。
タグ:Digispark
Digisparkで複数のタクトスイッチを扱う [Arduino]
Digisparkは使用できるピンが少ないので工夫が必要。
analogRead()で複数のタクトスイッチを扱う方法が、以下のページです。
I/Oピン一つで読めるキーパッドの設計サービス
https://synapse.kyoto/tool/ResDiv/page001.html
抵抗分圧により複数のボタンの識別をしています。
ライブラリもあるようですが、ブラックボックス化したくないので自作します。
抵抗値の計算もできますが、大まかな値を確認し、自分が持っている抵抗(E6系列中心でまちまち)でもできるよう、エクセルで分圧の計算もしました。
Vout= Vcc × (R2+R3+…+Rn) / (R1+R2+…+Rn)
閾値は、それぞれの分圧の中間値として、それを10ビット(0~1023)の値に換算しました。

あと、analogRead()は遅いらしいので、すべてのボタンは押されたときの電圧がdigitalRead()のLow判定電圧未満としておき、digitalRead()でLowになったら、あらためてanalogRead()で値を読むということにしました。
digitalRead()のLow判定電圧ですが、
Arduino Unoの入力スレッショルド電圧を測ってみる(閾値電圧) | のぶらぼ
https://nobulabo.com/arduino-uno-threshold-level/
「HIGH⇒LOW(VIL)は2.2V、LOW⇒HIGH(VIH)は2.6V、その差であるヒステリシス電圧は0.4Vであることがわかりました。」
とありました。
ATtiny25/V / 45/V / 85/V のデータシート
https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
186, 187ページの「22.7 Pin Threshold and Hysteresis」の項目をみるとVcc 5Vのとき
HIGH⇒LOW(VIL)は2.25V、LOW⇒HIGH(VIH)は2.5V あたりです。
タクトスイッチが押されたとき(HIGH⇒LOW)を確認したいので、分圧電圧を2.25V未満に抑えることにしました。
押されたボタン(SW1~SW4)の番号の回数分 LEDを点滅させるスケッチです。
analogRead()で複数のタクトスイッチを扱う方法が、以下のページです。
I/Oピン一つで読めるキーパッドの設計サービス
https://synapse.kyoto/tool/ResDiv/page001.html
抵抗分圧により複数のボタンの識別をしています。
ライブラリもあるようですが、ブラックボックス化したくないので自作します。
抵抗値の計算もできますが、大まかな値を確認し、自分が持っている抵抗(E6系列中心でまちまち)でもできるよう、エクセルで分圧の計算もしました。
Vout= Vcc × (R2+R3+…+Rn) / (R1+R2+…+Rn)
閾値は、それぞれの分圧の中間値として、それを10ビット(0~1023)の値に換算しました。

あと、analogRead()は遅いらしいので、すべてのボタンは押されたときの電圧がdigitalRead()のLow判定電圧未満としておき、digitalRead()でLowになったら、あらためてanalogRead()で値を読むということにしました。
digitalRead()のLow判定電圧ですが、
Arduino Unoの入力スレッショルド電圧を測ってみる(閾値電圧) | のぶらぼ
https://nobulabo.com/arduino-uno-threshold-level/
「HIGH⇒LOW(VIL)は2.2V、LOW⇒HIGH(VIH)は2.6V、その差であるヒステリシス電圧は0.4Vであることがわかりました。」
とありました。
ATtiny25/V / 45/V / 85/V のデータシート
https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
186, 187ページの「22.7 Pin Threshold and Hysteresis」の項目をみるとVcc 5Vのとき
HIGH⇒LOW(VIL)は2.25V、LOW⇒HIGH(VIH)は2.5V あたりです。
タクトスイッチが押されたとき(HIGH⇒LOW)を確認したいので、分圧電圧を2.25V未満に抑えることにしました。
押されたボタン(SW1~SW4)の番号の回数分 LEDを点滅させるスケッチです。
// Check multiple buttons with one pin for digispark
//
// Vcc--R1--+----+-R2-+-R3-+-R4-+ (R1:4.7k, R2:680, R3,R4:1k)
// | sw1 sw2 sw3 sw4
// P2 +----+----+----+----GND
//
const uint16_t Vth[] = {0, 64, 199, 320}; // threshold (intermediate value between voltages -> 10bit)
void setup() {
pinMode(2, INPUT); // P2:Buttons (D2/A1)
pinMode(1, OUTPUT); // P1:Built-in LED (D1)
}
void loop() {
uint8_t btn=0; // pressed button number (0 if none are pressed)
uint16_t val; // variable to store the value read
if( !digitalRead(2) ) { // Read Button number
delay(10); // chattering control
val = analogRead(1); // read the input pin
for(btn=1; btn<sizeof(Vth)>>1 && val>Vth[btn]; btn++); // Advance the btn until the Vth is exceeded
while( !digitalRead(2) ); // Wait until the button is released
}
for(; btn; btn--) { // Blinks the LED for the number of button numbers
digitalWrite(1, HIGH);
delay(100);
digitalWrite(1, LOW);
delay(200);
}
}
タグ:Digispark
Digisparkでマウス&キーボード [Arduino]
スーパーファミコンのコントローラーでマウスポインターの操作とマルチメディアキーの操作をしてみる。
調べてみると、同時に使えるライブラリーがあるらしい。
GitHub - adafruitAdafruit-Trinket-USB Arduino libraries allowing Trinket to act as USB devices
https://github.com/adafruit/Adafruit-Trinket-USB/

「Code ▼」をクリックして「Download ZIP」で保存。
その中の「TrinketHidCombo」というフォルダをフォルダごと、スケッチブックの保存場所(環境設定で指定のところ)にある「libraries」というフォルダ内にコピーするだけらしい。
環境設定をいじってなければ、以下のフォルダ。
%userprofile%\Documents\Arduino\libraries
十字キーでマウスのカーソル操作。Y, Bボタンでクリック。
X, Aボタンでの音量の操作もできるようになりました。
ブラウザ等の「戻る」ボタンも欲しいと思って調べてみると、
HID Usages and Descriptions - hut1_3_0.pdf
https://www.usb.org/sites/default/files/hut1_3_0.pdf
これ(↑)の p.130 の 「0x0224 AC(Application Control) Back」っぽい。
でも、pressMultimediaKey()関数の引数が「uint8_t (符号なし8bit整数型)」なので無理。
ただ、「Alt + ←」で代用は可能かも。
スケッチは以下のとおり。
・TrinketHidComboのライブラリを使用した。
・コントローラーが外れていてもおかしなことにならないようにした。
(DATA1のピンをINPUT_PULLUPにした)
・ボタンの状態を、符号なし16bit整数型をやめて配列に入れた。
(メモリの無駄だけど操作が楽に)
・最後のTrinketHidCombo.poll() (あるいはpressとか)を最低10msecごとに呼び出さないといけないって書いてあった。
調べてみると、同時に使えるライブラリーがあるらしい。
GitHub - adafruitAdafruit-Trinket-USB Arduino libraries allowing Trinket to act as USB devices
https://github.com/adafruit/Adafruit-Trinket-USB/

「Code ▼」をクリックして「Download ZIP」で保存。
その中の「TrinketHidCombo」というフォルダをフォルダごと、スケッチブックの保存場所(環境設定で指定のところ)にある「libraries」というフォルダ内にコピーするだけらしい。
環境設定をいじってなければ、以下のフォルダ。
%userprofile%\Documents\Arduino\libraries
十字キーでマウスのカーソル操作。Y, Bボタンでクリック。
X, Aボタンでの音量の操作もできるようになりました。
ブラウザ等の「戻る」ボタンも欲しいと思って調べてみると、
HID Usages and Descriptions - hut1_3_0.pdf
https://www.usb.org/sites/default/files/hut1_3_0.pdf
これ(↑)の p.130 の 「0x0224 AC(Application Control) Back」っぽい。
でも、pressMultimediaKey()関数の引数が「uint8_t (符号なし8bit整数型)」なので無理。
ただ、「Alt + ←」で代用は可能かも。
スケッチは以下のとおり。
// SFC(SNES) controller to HID // _______________+----- GND (Brown)
// digispark(USB 16.5MHz) Trinket Lib. // |_O_O_O_O_|_O_O_O_) connector
#define DAT 0 // | | | +------------> DATA1 (Red)
#define PS 1 // | | +--------------< P/S (Orange)
#define CLK 2 // | +----------------< CLK (Yellow)
#include "TrinketHidCombo.h" // +------------------- VCC (White)
void setup() {
pinMode( DAT, INPUT_PULLUP );
pinMode( PS , OUTPUT );
pinMode( CLK, OUTPUT );
digitalWrite( CLK, HIGH );
TrinketHidCombo.begin();
}
void loop() {
uint8_t sfc[12];
digitalWrite( PS , HIGH );
digitalWrite( PS , LOW );
for(uint8_t i=0; i<12; i++) {
sfc[i] = digitalRead( DAT )^1;
digitalWrite( CLK, LOW );
digitalWrite( CLK, HIGH );
} // 0:B, 1:Y, 2:SEL, 3:STA, 4:UP, 5:DOWN, 6:LEFT, 7:RIGHT, 8:A, 9:X, 10:L, 11:R
TrinketHidCombo.mouseMove(
( sfc[ 7] - sfc[ 6] ) <<2 , ( sfc[ 5] - sfc[ 4] ) <<2 , // cross key:mouse cursor
sfc[ 0] * MOUSEBTN_RIGHT_MASK + sfc[1] * MOUSEBTN_LEFT_MASK ); // Y:left, B:right click
if( sfc[ 8] ) TrinketHidCombo.pressMultimediaKey( MMKEY_VOL_DOWN ); // A:Volume Down
if( sfc[ 9] ) TrinketHidCombo.pressMultimediaKey( MMKEY_VOL_UP ); // X:Volume Up
delay(10);
TrinketHidCombo.poll(); // do nothing, check if USB needs anything done
delay(10);
}
・TrinketHidComboのライブラリを使用した。
・コントローラーが外れていてもおかしなことにならないようにした。
(DATA1のピンをINPUT_PULLUPにした)
・ボタンの状態を、符号なし16bit整数型をやめて配列に入れた。
(メモリの無駄だけど操作が楽に)
・最後のTrinketHidCombo.poll() (あるいはpressとか)を最低10msecごとに呼び出さないといけないって書いてあった。
タグ:Digispark
Digisparkでスーパーファミコンのコントローラーを使う [Arduino]
前提として、スーパーファミコン型のUSBジョイパッドを買ったほうが簡単で安いというのは無しで。
また、この手の話題はすでにライブラリまで作っている方もみえて、何番煎じかという感じです。
うちの近くのハードオフに、スーパーファミコンのコントローラーの中古があるにはあるのですが、手垢で汚い・傷あり・変色・ボタンスカスカ・110円じゃなくて330円。
ですが、とりあえず1個よさそうなものを選んで購入。
Aliexpressでソケットも購入。
こんな感じで、、


先日つくった改造Digisparkと接続できるパーツを仕上げたのですが、改造Digisparkが死亡したため、以前に購入したmicroUSB版 Digisparkを出してきました。

ブレッドボートでつないで、十字キーを読み取るという以下のスケッチで動作確認できました。
メディアキーでボリュームの操作もしたかったんだけど、なぜかできず。
また、この手の話題はすでにライブラリまで作っている方もみえて、何番煎じかという感じです。
うちの近くのハードオフに、スーパーファミコンのコントローラーの中古があるにはあるのですが、手垢で汚い・傷あり・変色・ボタンスカスカ・110円じゃなくて330円。
ですが、とりあえず1個よさそうなものを選んで購入。
Aliexpressでソケットも購入。
こんな感じで、、


先日つくった改造Digisparkと接続できるパーツを仕上げたのですが、改造Digisparkが死亡したため、以前に購入したmicroUSB版 Digisparkを出してきました。

ブレッドボートでつないで、十字キーを読み取るという以下のスケッチで動作確認できました。
// SFC(SNES) controller to HID // _______________+----- GND (Brown)
// digispark(USB 16.5MHz) version // |_O_O_O_O_|_O_O_O_) connector
#define DAT 0 // | | | +------------> DATA1 (Red)
#define PS 1 // | | +--------------< P/S (Orange)
#define CLK 2 // | +----------------< CLK (Yellow)
#include "DigiKeyboard.h" // +------------------- VCC (White)
void setup() {
pinMode( DAT, INPUT );
pinMode( PS , OUTPUT );
pinMode( CLK, OUTPUT );
digitalWrite( CLK, HIGH );
DigiKeyboard.sendKeyStroke(0);
}
void loop() {
uint16_t sfc = 0;
digitalWrite( PS , HIGH );
digitalWrite( PS , LOW );
for(uint8_t i=0; i<12; i++) {
sfc |= ( digitalRead( DAT )^1 ) << i;
digitalWrite( CLK, LOW );
digitalWrite( CLK, HIGH );
}
// 0:B, 1:Y, 2:SEL, 3:STA, 4:UP, 5:DOWN, 6:LEFT, 7:RIGHT, 8:A, 9:X, 10:L, 11:R
if( sfc & (1<< 4) ) DigiKeyboard.sendKeyStroke( 0x52 ); // UP -> KEY_ARROW_UP
if( sfc & (1<< 5) ) DigiKeyboard.sendKeyStroke( 0x51 ); // DOWN -> KEY_ARROW_DOWN
if( sfc & (1<< 6) ) DigiKeyboard.sendKeyStroke( 0x50 ); // LEFT -> KEY_ARROW_LEFT
if( sfc & (1<< 7) ) DigiKeyboard.sendKeyStroke( 0x4f ); // RIGHT -> KEY_ARROW_RIGHT
DigiKeyboard.delay(10);
}
メディアキーでボリュームの操作もしたかったんだけど、なぜかできず。
タグ:Digispark