数百円のDigispark基板を購入してから放置しており、本格採用する気はありませんが興味がある人がいたので試してみました
digisparkでRCサーボ信号入出力とフルカラーLED
構成としては、画面中央やや左のDigispark基板が入力としてFutaba受信機からRCサーボ信号を読み、出力として豆サーボを動かしWS2812のフルカラーLEDを光らせています
電源は外部BECの5Vをそのまま使っており、受信器とかサーボとかLEDの電源と共通です
まだポートは2つ余ってるので、これに可変抵抗を付ければサーボ制御も出来るとは思いますが、どの程度性能が出るかは分かりません(速度上げると発振しそう)
ちなみに、WS2812は約50mA/1個らしいので使用している16個なら0.8A、本体の500mA電源なら10個、外付けの4Aなら80個ぐらいですかね
Digisparkのセットアップ方法とかは検索すれば沢山出てくるので省略します(使用しているのはrev.3です)
注意点としては
・標準のシリアル通信は無く、DigiUSBが使えるが何故か他の入出力と共存できないっぽい(?)
・メモリが小さいので、以下のRCサーボ信号入出力とフルカラーLEDのプログラムで75%専有
・ブートローダの関係で?、起動に数秒待たされるので運用中に再起動すると困る用途には使えない
感想としては
・上記理由によりデバッグがしにくいので(多分)、新規開発用には向かない
→他Arduinoでこなれた事を小型化目当てで移植するのが良さそう
一応ソースコード載せときますが、丁寧に解説する気は無いので悪しからず
ニュートラルで豆サーボ中立・LED白で、左右に倒すと豆サーボも同じように動き、LEDも虹色が動きます
ノイズが多かったので200回平均取ってますが、賢いやり方では無いですしそもそも電気的に対策した方が良さそうですね
既に基板小さいですが、基板の半分がレギュレータなのに使ってなくて勿体無いので、ATtiny85だけ実装した超小型基板作っても面白いですが多分面倒なのでやらないです
#include <SoftRcPulseIn.h> #include <SoftRcPulseOut.h> #include <Adafruit_NeoPixel.h> enum{ PULSE_MIN=1020, PULSE_MID=1520, PULSE_MAX=2020 }; enum{ CODE_MIN=0, CODE_LOW=6, CODE_HIGH=9, CODE_MAX=15, CODE_GAIN=64 }; enum{ FCLED_PIN=0, LED_PIN=1, PULSE_PIN=2, SERVO_PIN=3 }; #define FCLED_LIM 16 Adafruit_NeoPixel strip = Adafruit_NeoPixel(FCLED_LIM, FCLED_PIN, NEO_GRB + NEO_KHZ800); SoftRcPulseIn ImpulsionVoie1; SoftRcPulseOut ServoMotor; #define PULSE_NUM 200 byte pulse[PULSE_NUM]; uint16_t pulse_cnt = 0; // Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { if(WheelPos < 85) { return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } else if(WheelPos < 170) { WheelPos -= 85; return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } else { WheelPos -= 170; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } } byte pulse2code( uint16_t pulse ){ if( pulse < PULSE_MIN ) return CODE_MIN; else if( pulse > PULSE_MAX ) return CODE_MAX; return (pulse - PULSE_MIN) / CODE_GAIN; } uint16_t code2pulse( byte code ){ return code * CODE_GAIN + PULSE_MIN; } void setup(){ pinMode(LED_PIN, OUTPUT); //LED on Model B ImpulsionVoie1.attache(PULSE_PIN); ServoMotor.attach(SERVO_PIN); strip.begin(); strip.show(); } void loop(){ uint32_t pulse_sum = 0; if( ++pulse_cnt >= PULSE_NUM ) pulse_cnt = 0; pulse[pulse_cnt] = pulse2code( ImpulsionVoie1.largeur_us() ); for( int i=0; i<PULSE_NUM; i++ ) pulse_sum += pulse[i]; byte pulse_ave = pulse_sum / PULSE_NUM; if( pulse_ave < CODE_LOW || pulse_ave > CODE_HIGH ){ digitalWrite(LED_PIN, HIGH); for(int i=0; i<FCLED_LIM; i++ ) strip.setPixelColor(i,Wheel((i+pulse_ave*2)*256/FCLED_LIM)); ServoMotor.write_us( code2pulse(pulse_ave) ); } else{ digitalWrite(LED_PIN, LOW); for(int i=0; i<FCLED_LIM; i++ ) strip.setPixelColor(i,100,100,100); ServoMotor.write_us( PULSE_MID ); } strip.show(); SoftRcPulseOut::refresh(0); }