ソロでたのしむ

キャンプ、電子工作、DIY、乗り物などの趣味を紹介

テント内で焚き火!っぽいランタンの炎を楽しむ

キャンプで、そろそろ寝ようかな〜という時に、大自然に囲まれていた雰囲気とテント内の雰囲気のギャップに、少しガッカリしたことがあります。

火器が使えないテント内では、LEDの灯りなどを使うことになりますが、目に刺さるような白色に、日常を感じてしまい、焚き火の炎に照らされて醸成されていたリラックスモードが、一気に無くなってしまったように気分に...

一方で、このところキャンプに行っていないどころか、買い物だけしか外出していませんが、このような時だからこそ!ということで、「外でもお家でもキャンプ」気分を盛り上げる小道具を増やそうと思います。

そこで今回は、テント内でも使える「焚き火の炎」を作って、どこでもキャンプファイヤーの光を、手軽に楽しめるようにしてみます!

テント内で焚き火!っぽいランタンを楽しむ

 

ランタンを見つめ続けた結果!

キャンプ用のLEDランタンは、停電などの非常時にも使えますよね!

私は、屋内ではいつも目につく場所に置いて、来たるべき次回のキャンプに備えて時々充電したり、来てほしくない非常時に備えたりしています。

キャンプや夜釣りで活躍していたLEDランタンですが、唯一の欠点が、明るすぎることです。

キャンプ用LEDランタンを改造します

焚火などの穏やかな明かるさに慣れた状態で、この光量を直視してしまうと、目が焼けるかのように感じます。

もっとキャンプで使いたくなるランタンにしたいと思いつつも、キャンプに行かない室内生活で、視野に入れるように置き続けていて、ふと思いつきました。

のように光らせたら、室内とキャンプのどちらでも、良い雰囲気作りができる!

少し前になりますが、フロアランプを焚き火風に光らせることができたので、それより少ないLEDを使えば良いランタンの改造は、難しくはない筈です。

早速、炎をランタンに封入してみましょう。

LEDランタンを改造

炎の光パターンを作るために、5Vで駆動するマイコンを使います。

2年ほど使い続けているランタンは、もともと白色LEDが使われており、またUSB(5V)で充電できるものなので、電源系はそのまま使えそうです。

炎のランタン作成に使うもの

まずは、WS2812Bが一定間隔で配置されているカラーLEDテープを準備しました。

WS2812Bで炎を作ります

写真には2種類のものが写っています。

今回は、少ないスペースにより多くのLEDを埋め込みたいので、外側でぐるぐるっとしているLEDの間隔が少ないものを使います。

材料として他に入手したのは、炎のパターンを作るために働いていただく、Arduinoだけです。

配線類などの副資材は、既にあるものや廃材を利用します。

LEDランタンの中身

自己責任!となるので、少しドキドキしながら、LEDランタンを開封します。

赤色の配線がプラス、青色の配線がマイナス...かと思いきや、一箇所だけ赤色のマイナス線がありますね。

(自己責任で)LEDランタンを分解
(自己責任で)LEDランタンを改造
  • 茶色の基盤;電源管理
  • 青色の円柱;リチウム電池
  • 緑色の基盤;スイッチ管理とLEDの定電流化

ということのようです。

回路の電圧を測ってみると、4V以上でている様子で、ギリギリですが思惑どおりArduinoも動かせそう!

本来であれば電圧変換すべきですが、とりあえず、オリジナルの回路をそのまま使って、様子をみましょう〜

ただし、もともとのLEDには定電流ダイオードを通して電源が供給されていましたが、ArduinoとWS2812Bには、定電流ダイオードを通さずに電源供給して、たくさん働いていただきます。

大まかな回路構成がわかったので、もともとのLEDWS2812Bに交換して、光り方を制御するArduinoを追加する作業に進みます。

ArduinoとWS2812Bを配線しましょう

LEDランタンには白色LEDが3本使われていたので、同じ長さになるように切断したWS2812Bテープ3本を、直列で配線します。

今回使うのは7個x3列の、合計21個ですね。

WS2812Bを3列に並べて使います
Arduinoをランタンに埋め込む!

ArduinoからWS2812Bへの信号線は、黄色の配線1本のみです。

他には、それぞれに電源線2本を接続するだけ!

作業の途中で、Arduinoのデジタルピンではなく、アナログピンに信号線をハンダ付けしてしまうというトラブルがあったものの、サクサクっとハンダ付けを終わらせて、準備しておいたプログラム(スケッチ)を書き込みます。

WS2812Bの炎パターン
ランタンのLEDをWS2812Bに改造

さて、電源を入れて試運転してみましょう。

...していたとおりに光っています!

いつも思うのですが、この瞬間の安堵感と嬉しさは、格別です〜

しっかり動くことがわかったので、後はランタンを組み立て直すだけですが、より炎っぽさを表現するために、シェード様のものを追加しておきます。

LEDの点光源感がバレてしまうと炎としては不自然なので、ボカシを入れるイメージです。

ランタンにキャンプファイヤーを封入

シェードには、よくある梱包材を廃材利用しました。

右の写真はシェード1枚での発光の様子ですが、まだ点光源感が残っていたので、左の写真のように二重のシェードを入れることにしました。

焚火風ランタンを自作

完成状態での点灯チェック!

本物の炎のようで、しばらく見入ってしまいました。

光り方は、動画でもご確認いただけます。

回路

今回つくる回路は、一か月ほど前に作った光ファイバーアートの時と、WS2812Bの個数を除いて全く同じです。

www.solocamptouring.com

回路図は、こちらで紹介しています。

WS2812Bは、配線数が少なくていいですね!

作業風景は、早送りですが動画でも紹介しています。

youtu.be

スケッチ

ご参考で、Arduinoのスケッチ(プログラム)です。

WS2812Bを使うため、GitHubのFastLEDライブラリを使用させていただきます。

炎の発光は、Fire2012WithPaletteのスケッチを応用しました。

#include "FastLED.h"
#define DATA_PIN    5
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define HEIGHT 7
#define WIDTH 3
#define NUM_LEDS HEIGHT*WIDTH
#define lighting_PER_SECOND 30 // Mainly for fire frame pattern

CRGB leds[NUM_LEDS];
CRGBPalette16 gPal;

int BRIGHTNESS = 20;
int scaleVol = 230; // Scale the heat value from 0-255
int SPARKING = 220; //50-200 out of 255
int COOLING = 50; // 20-100: Less = taller flames.  More = shorter flames. 

bool gReverseDirection = false;

void setup() {
  delay(1000); //delay for recovery
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
}

void loop()
{
  gPal = CRGBPalette16( CRGB::Black, CRGB::Red, CRGB::Yellow, CRGB::White);
  static uint8_t heat[NUM_LEDS]; // Array of temperature readings

  // Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / HEIGHT) + 2)); //heat-randam8 with a floor of 0
    }
  
  // Heat from each cell drifts 'up' and diffuses a little
    for( int k= HEIGHT - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
      heat[2*HEIGHT-1-k] = (heat[2*HEIGHT-1-k + 1] + heat[2*HEIGHT-1-k + 2] + heat[2*HEIGHT-1-k + 2] ) / 3;
      heat[2*HEIGHT+k] = (heat[2*HEIGHT+k - 1] + heat[2*HEIGHT+k - 2] + heat[2*HEIGHT+k - 2] ) / 3;
    }
    
    //  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int x = random8(6);
      int y ;
      if(x > 3){
        y = 2*HEIGHT-4+x;
      } else if(x > 1){
        y = 2*HEIGHT+1-x;
      } else {
        y = x;
      }
      heat[y] = qadd8( heat[y], random8(160,255) ); //heat+randam8
    }

    // Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      uint8_t colorindex = scale8( heat[j], scaleVol);
      CRGB color = ColorFromPalette( gPal, colorindex);
      int pixelnumber;
      if( gReverseDirection ) {
        if(j < HEIGHT){
          pixelnumber = (HEIGHT-1) - j;
          }else if(j < 2*HEIGHT){
          pixelnumber = HEIGHT+j;
          }else{
          pixelnumber = (3*HEIGHT-1) - j;
          }
      } else {
        pixelnumber = j;
      }
      leds[pixelnumber] = color;
    }

// Let's light them now
  random16_add_entropy( random());
  FastLED.show();  // send the 'leds' array out to the actual LED strip
  FastLED.delay(1000 / lighting_PER_SECOND);
// End of lighting
  
}

以前に作ったフロアランプはWS2812Bを4列配置しましたが、今回のランタンは3列です。

また、今回は発光パターンを赤色の炎だけに限定したので、ランタンのスケッチは、フロアランプに比べて、たいへん短くなっています。

最後に、ランタンとフロアランプの炎を並べて、記念撮影

どちらも、なかなか良い雰囲気で、他の明かりを消して、室内で楽しんでいます!

夜に外から見たら、怪しいと思われているかもしれませんね。

WS2812Bで、炎パターンで光るライトを自作

光ファイバーの夜景アートが欲しい!

前回に引き続き、お部屋で楽しむノスタルジーシリーズです。

きらきらと、小さな光点が点滅したり色を変える夜景のアート、数十年前に流行りましたよね!

思い返せば、その頃から自作好きだったようで、夜のブルックリン橋のポスターを買ってきて、背景のビルの窓に、光ファイバーを一本づつ埋め込んだな〜と思い出します。

最近になって、この夜景アートが欲しくなり、ネットなどで調べているのですが、なかなか見つかりません。

薄型ディスプレイが出回っている昨今では、流行らないのでしょうか?

入手しづらいとわかると、あの幻想的にも感じた光が、どうしても欲しい!との思いが、なおさら増してきます。

またまた、無いものは作るしかない!ということで、お部屋で過ごす時間を使って、自作してみます。

Fiber optic picture DIY

夜景のポスター

今回の「光る夜景アート」のDIYにあたり、最初にベースとなる夜景のポスターを探してみました。

...しかし、私が探しているA3サイズの大きさで、感性を揺さぶるようなポスターは、なかなか見つかりません。

空が真っ赤に染まっているような夕焼けの景色はあるのですが、どちらかというと日が沈み切った後の景色が欲しい!

まあ、慌てずに探しましょう~と、1か月ほど構想を温めていた頃、普段から行くことがあるホームセンターの奥の方で、一枚の絵に目が止まりました。

タイで見つけたオーロラのアートフレーム

何、このオーロラの発色? 綺麗すぎます!

夕焼けに染まる街のアートフレームもありましたが、このグラデーションがかかったグリーンの空から、目が離せません。

10分ほど絵を眺めてつつ妄想にふけっていて、いい事を思いついてしまいました。

このオーロラをで光らせたら、おもしろそう!

お手頃価格で、DIYにちょうどいい大きさのこのアートフレーム、即購入しました。

ちなみに、このアートフレームは時計です。

オーロラのアートフレーム

オーロラが発生している夜空に、くっきりと時間が表示されていて、少し違和感がありますね。 

お家に帰ってきてアートフレームの中身を確認した時に、時計機能は撤去することにしました。

アートフレームの中のデジタル時計

時計を埋め込むのにちょうどいい入れ物が見つかったら、時計ユニットは再生いたします。

街の夜景とオーロラを同時に楽しむ

一目惚れしたアートフレームには、山の上空のオーロラに照らされて、海沿いの人里が描かれています。

漁師町といった雰囲気でしょうか? 私の勝手なイメージでは、カニ漁の漁船が係留されている筈です!

今回は、LEDから光ファイバーケーブルで導光して漁師町をライティングすると共に、オーロラはLEDの光を裏から当てます。

もうすっかり使い慣れたカラーLED、WS2812Bが25個直列で繋がったテープを使って、最初の3個は漁師町、残りの22個はオーロラ用とします。

ARDUINOで、ファイバー ライト ピクチャーを自作

山の影を作りましょう

アートフレーム全体は、キャンバス生地の裏側から光らせます。

夜空に、山の稜線が漆黒の姿を映すようにしたいので、山の輪郭に沿って、板を入れておきます。

この板は、光ファイバーケーブルの光源を取り付けるスペースとしても、活躍してもらいます。

街の夜景

街といっても、漁師町なので、派手すぎず、かといって寂しくは感じない程度の光りをつくります。

光源となるLED3個は、ランダムなタイミングで、それぞれの色を変えていきます

数えてはいませんが、たくさんの光ファイバーケーブルの端末を、町の光りとして埋め込んで、反対側の端末は、LED3個の光源近くに束ねました。

光ファイバーケーブルで光るアートを作りましょう

夜空に揺れるオーロラ

アートフレームの上方に22個のLEDを並べて、徐々に色を変えつつ、光量のゆらぎを作ります

個々のLEDごとに色と光量を制御できるWS2812Bのメリットをいかした表現で、実際のオーロラをイメージして、光量のゆらぎの大きさ発生頻度などをトライ&エラーで決めます。

瞬く星も、この光源を使って、数個つくっておきました。

WS2812B LEDでアートを光らせる

回路図

回路と言っても、ものすごく簡単なものです。

手動で光量や色を変更することも無いので、可変抵抗(ボリューム)も使いません。

回路図はFritzingで作成しました。

LED lighting circuit for Fiber light picture

回路の作成シーンや、アートフレームの改造風景は、動画でも紹介しています。

youtu.be

参考;夜景アートを光らせるArduinoこスケッチ(プログラム)

簡単な命令文で、綺麗な光を演出できるGitHubのFastLEDライブラリを使わせていただきます。

おかげさまで、随分と短いスケッチになりました。

#include "FastLED.h"
#define DATA_PIN    5
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define HEIGHT 25              //  aurora 22 + village 3
#define WIDTH 1
#define NUM_LEDS HEIGHT*WIDTH
#define lighting_PER_SECOND 10 // aurora pattern changr per sec.

CRGB currentleds[NUM_LEDS];
CRGB leds[NUM_LEDS];
int BRIGHTNESS = 160; //out of 255
int auroraSparkMax = 90; // aurora spark volume 0-100 out of 255 -BRIGHTNESS
int auroraSparkMin = 60; // aurora spark volume 0-100 out of 255 -BRIGHTNESS
static uint8_t heat[NUM_LEDS]; // Array of temperature readings
uint8_t gHue = 1; // starting color out of the patterns 0to255  


void setup() 
{
  delay(1000); //delay for recovery 
  FastLED.addLeds<LED_TYPE, DATA_PIN, GRB>(leds, NUM_LEDS);
}

void loop()
{
 unsigned long startMillis= millis();  // Start of sample window
 FastLED.setBrightness(BRIGHTNESS); 
 fadeToBlackBy( leds, NUM_LEDS, 200);
 
// make aurora and village light
  // aurora each cell heat slides
  EVERY_N_MILLISECONDS( 200 ) {
    for( int i = NUM_LEDS-1; i > 3; i--) {
     heat[i] = heat[i-1]  ; 
     }
     heat[3] = random8(auroraSparkMin, auroraSparkMax) ;
  }
     for( int j = 3; j < NUM_LEDS; j++) {
     leds[j] += CHSV( gHue + j, 255, heat[j]);
    }


  // village color

  EVERY_N_MILLISECONDS( 100 ) {
    for( int j = 0; j < 3; j++) {
    heat[j] = BRIGHTNESS  ;   
     int ColorChange = random8(250);
     if (ColorChange < 1){
     uint8_t gHueVillage = gHue + 127; 
     leds[j] += CHSV( gHueVillage, 255, heat[j]);
     currentleds[j] = leds[j] ;
     }else{
     leds[j] = currentleds[j] ;
     }
     uint8_t colorindex = scale8( heat[j], 255);
     }
  }
  
// Let's light them now
  FastLED.show();  // send the 'leds' array out to the LED strip
  FastLED.delay(1000 / lighting_PER_SECOND);
  
  EVERY_N_MILLISECONDS( 500 ) { 
    gHue++ ;
  }
  
// End of lighting

}

オーロラと街の光は、どちらも徐々に色を変えていきますが、意図的に違う色になるようにしています。

どちらかが緑色(に近い色)の時は、もう一方は紫色(に近い色)といったイメージです。

ファイバーライトピクチャーの自作

夜景アートというと、大都会の景色を連想しますが、偶然出会ったオーロラの景色に一目惚れしたことで、今回は一風変わった夜景アートを作ることになりました。

私としては、一本のLEDテープを光源に使い、オーロラと街の夜景を上手く表現できたと感じています。

このところ続いているお家で楽しむシリーズですが、今回は、懐かしさが漂うファイバー ライト ピクチャーを自作してみました。

スペースレールのモーター音を静かにしたい!

Light up the SPACERAIL

こんにちは。

皆様は、お家時間をいかがお過ごしでしょうか?

私は最近、お家に籠っている時間を使って、

スペースレールという知育おもちゃを、少しだけ改造して組み立てました!

「そういえば昔に持っていた!」と、懐かしく思い出される方も多いと思いますが、おそらくそれは、1983年くらいから5年ほど販売されていたスペースワープですね!

私も相当昔にスペースワープを組み立てたことがありますが、大人になった今回は、アップデートされて蘇ったスペースレールに、少し改造を織り込んで作成してみます。

お部屋のオブジェとして動かし続けるには、どうすれば良い?という観点で、小技も繰り出します!

SPACERAILのモーターの音を静かにしましょう!

スペースレール(SPACERAIL) 

スペースレールは、上の写真のようにレールを組み立てて、直径1/2インチ(1cmくらい)のボールを、上手く転がそう!という、パズル的な要素がある玩具です。

組み立てキットは14種類あり、難易度レベルが9段階で付与されています。

組み立て時間は、最も簡単なもので1時間、最高難易度のものだと60時間くらいかかるらしいとのこと!

スペースワープの時代には、レベル3に相当するものを組み立てたと記憶していますが、今回はレベル4.1に挑戦します。

大人の楽しみ方

さて、お部屋のオブジェにしましょう!というコンセプトで作るスペースレールは、スペースワープ時代の記憶を辿ると、2点ほど改良したくなります。

  1. エレベーターからボールが落ちることがある
  2. エレベーターを動かしているドライブユニットの音が大きい

f:id:solocamptouring:20210725161634j:plain

1 は、エレベーターの途中にあるボールが、他のボールがエレベーターに突入してくる時の衝撃で落ちることが多かったと思いますので、なんらかの落下防止ガードを付けたいと思います。

については、手の込んだ改善が必要だと思われます。

DCモーターと、その動力をエレベーターに伝えるギアの双方が、ウィ~ンという大きめな音を発生する原因となっている様子...

Inside the drive unit of Spacerail

静かな部屋で動かし続けるためには、少し耐えがたいドライブ音は消してしまって、ボールが転がる音と、エレベーターにボールが吸い込まれる瞬間の音だけにしたい!

静かに動かすのであれば、ステッピングモーター化がお手軽でしょう!ということで、モーターの種類を変えて、静音化してみます。

ステップモーター :  28BYJ-48 

ステッピングモーターは、速度(回転数)や位置を制御しやすいので、3Dプリンターにも使われていますね。

今回使うステッピングモーターは、ドライバーとセットで売られていることが多い28BYJ-48です。

ステップモーター 28BYJ-48をSpacerailに仕込む

上の写真で、右に写っているのが、そのステッピングモーターです。

スペースレールのドライブユニットのハウジングに収まりそうな、ちょうどいい大きさですね。

ドライバーとセットで安価に入手できる28BYJ-48は、マイコンボードで簡単に動かせます。

私がよく使うマイコンッボードは、Arduino Nanoという、小さいタイプのものです。

少しArduinoに興味がでてきた!という方は、使い方などを纏めている記事があるので、よろしければ参考にしてみてください。

www.solocamptouring.com

早速、必要な部品を入手して、ステッピングモーター化に取り組みます。

モーター交換のためのハンダ付け作業や、ハウジングの加工を終えて、静か~に動くドライブユニットが完成しました。

スペースレールを、ステップモータで動かす
Spacerailの、静かに動くドライブユニットが完成

作業の様子は、早送りですが、動画内で紹介しています。

ステッピングモータを動かす回路図

Fritzingで作成した回路図を紹介いたします。 

作るのが大変そうに見えるかもしれませんが、回路図の右半分は、ステッピングモータと、そのドライバなので、既製品です。

DCモーターからステッピングモーターに改造 ARDUINO使い方

この回路では、USB接続の5V電源を使います。

ハンダ付け作業も少なく、配線をつなぐと、下の写真のような状態になります。

Arduinoとスッテプモーターで、スペースレールを動かす

スペースレールを組み立てましょう

ドライブユニットの試運転して、満足できるレベルの静音になっていることを確認したら、いよいよスペースレールを組み立てます。

説明書を見ながら、まずは支柱を立てていきます

スペースレールを組み立てます
Spacerail installation

1時間以上かけて、支柱の作業を終えました!

次に、レールを切ってから、取り付けていきます

説明書で指示されているレールの長さは少し余裕を持たせているようで、実際に装着した後で余った部分をさらに切断します。

ちなみに、同経路のレール左右でも、余る長さが違ってきます。

スペースレールのレール取付け
Install rails on the Spacerail

2時間以上かけて、レールも完成しました。

途中で、ボールを試走させながらレールを微調整しているので、予想以上に時間がかかります。

これらの作業と、静かに動くドライブユニットの様子は、動画でもご確認いただけます。

youtu.be

ほとんどの作業を早送り再生しているので、動画内では超高速で完成していますね。

エレベータータワーから落ちてしまうボールの対処方法

エレベータの中間地点を登っているボールが、他のボールがエレベータに突入してきた時の衝撃で落ちてしまうことがあります。

もう少ししっかりとボールを固定してくれる設計ならいいのに~」と言っていても仕方がないので、衝撃が加わってもボールが落ちないようにする手立てを考えます。

エレベータータワーから落ちてしまうボールの対処方法

これ、何かわかりますか?

はい! 食品を包んだりする時に使う、台所用ラップの芯です。

らせん状に切れ目を入れて、エレベータータワーの長さ(高さ)に合わせて切断したら、すぽっと入れるだけでボールの落下を防止できます。

ちょうどいい直径のアクリルパイプがあれば、もっと完成度が増すと思われますが、ラップの芯でも、それほど違和感はありません。

お家に在りそうな物での対策としては充分でしょう!

ボールの落下がなくなり、モーターもほぼ無音になったので、お部屋の置き物として、長時間動かし続けられるものになりました。

けっこう時間がかかりましたが、組み立て作業も楽しかった!

今日も、スペースレールの前に椅子を置いて、ボールの動きを目で追い続けています。

さて、次は何を作ってみようかな?

おまけ その1; ライトアップしてみました

テーマパークのジェットコースターを思い起こさせるスペースレール、無事故かつ静音化して、オブシェとして動かし続けることに成功しました。

お部屋で眺めていて、もう少し幻想的にしたいと思い、ライトアップしてみました。

その様子を、約15分間にわたり録画してみます。

youtu.be

録音した音は、全く手を加えていないので、ボールの音だけが聞こえる様子をご確認いただけると思います。

おまけ その2;ステッピングモータを動かすスケッチ(プログラム)

ご参考で、スケッチを紹介いたします。

ステッピングモーターのドライバーに対して、コイルに順番に電気を流しなさい~と命令しているだけの、簡単なスケッチです。

int motorPin1 = 4;    // Blue   - 28BYJ48 pin 1
int motorPin2 = 5;    // Pink   - 28BYJ48 pin 2
int motorPin3 = 6;    // Yellow - 28BYJ48 pin 3
int motorPin4 = 7;    // Orange - 28BYJ48 pin 4
int volumePin = 3;
int motorSpeed;
int motorSpeedtimes = 2;

int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

void setup() {
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  motorSpeed  = 1024 * (motorSpeedtimes + 1) - (analogRead(volumePin) * motorSpeedtimes) ; //0to1023 change into speed
  clockwise();
}

void anticlockwise()
{
  for (int i = 0; i < 8; i++)
  {
    setOutput(i);
      delayMicroseconds(motorSpeed) ;
}
}
void clockwise()
{
  for (int i = 7; i >= 0; i--)
  {
    setOutput(i);
      delayMicroseconds(motorSpeed);
}
}
void setOutput(int out)
{
  digitalWrite(motorPin1, bitRead(lookup[out], 0));
  digitalWrite(motorPin2, bitRead(lookup[out], 1));
  digitalWrite(motorPin3, bitRead(lookup[out], 2));
  digitalWrite(motorPin4, bitRead(lookup[out], 3));
}

それでは、皆さま良いお家時間をお過ごしください!

お家でエレクトリカルパレード

 

いつでも正確な時計を自作。GPSからの情報を秒単位で表示します

こんにちは。在宅時間が増えてきていると思いますが、お元気でおすごしですか?

私は(も)、アウトドアで過ごす予定がたてられない生活をしています。

しかし、そんな時こそキャンプでも使えるガジェットを自作すべき!ということで、在宅勤務でもアウトドアでも使える、いつでも正確な時間を教えてくれる時計を作ってみます。

 

いつでも時間が正確な時計を作ってみる

マイコン「Arduino」は難しくない!

最初に、「デジタル時計なんて自作できるのか?」問題について、少しだけ私の所感を紹介させていただきます。

マイコンを使う工作なんて無理〜と思っていた私が、Arduinoに出会ったのは、数年前です。

その頃すでに、日本語でArduinoの使い方を紹介されているサイトなどがありましたが、専門用語が多くて少し難解だったり、応用しづらかったりして、やはり基礎知識がないと無理なのかな?と最初は思いました。

海外のサイトからも情報を得たりしながら、いろいろ作ることに成功した現在、結論を言うと、「基本的なエクセルの関数計算を使うことができるなら、難しくない!」です。

Arduinoの場合は、プログラムのことを「スケッチ」と呼びますが、スケッチを描くのと同じくらい簡単ですよ!ということのようです。

表計算ソフトのエクセルで「もし〇〇ならば、△△を計算(実行)」の関数を使ったことがあれば、Arduinoスケッチの8割くらいは理解できると思います。

実際に私は、if~else~式を乱用して、スケッチを作っています。残りは数字の種類(整数、桁数)などを少し勉強すれば、だいたい理解できました。

ひとつ作品を成功させると、可能性が無限に広がったような気持ちになって、何かを表示するだけでなく、動かしたり光らせたりする作品など、いろいろ作ってきました。

もし興味がおありでしたら、見てみてください。

www.solocamptouring.com

 

人工衛星の情報で、正確な時間を入手

さて、前置きが長くなりましたが、置き時計を作ります。

最近は、腕時計でも採用されているものがありますが、地球のまわりを飛んでいる人工衛星から、正確な時間情報をいただきます

使う部品はこれだけです。

GPS時計を自作します

  • Arduino
  • NEO-6M GPSモジュール
  • 1602 LCDモジュール
  • 220Ω 抵抗
  • 1kΩ 可変抵抗 

あとは、試作用の汎用基盤などの小物ですね。

GPSモジュールとLCDモジュールは、電力消費がそれほど多くないので、この後で紹介する回路図とは少し違って、USB接続したArduinoからの5Vアウトプットで駆動しています。

GPS時計の回路図

いつもお世話になっているFritzingで回路図を作成しました。

LCDモジュールへの配線数が多いですが、GPSモジュールへの配線はわずか3本です!

これだけで正確な時間情報がいただけるなんて、嬉しいですね。

GPS clock 1604 LCD_回路図

組み立てましょう

はんだ付けって大変!なのですが、便利な道具があると、ずいぶん楽になります。

若かりし頃は、横着なやり方もしていましたが、分別ができる年頃になってから、便利な道具に助けてもらうことを覚えました。

電線どうしのはんだ付けなど、もう一本手が欲しい~と思いながら苦戦していましたが、クリップ付きのはんだこて台があると、本当に楽です。

ハンダ付けを含めた作成の様子は、タイムラプスの動画にしてみました。

youtu.be

完成したことろで、お部屋のテレビ台に置いてみると、こんな感じです。

USBで駆動するGPS置時計

きちんと、秒単位で正確に働いています!

青色の背景に白い文字が浮かび上がっていて、雰囲気も良いですね。

ちなみに、このGPS時計は、電源を入れた後、表示するまで少しだけ時間がかかりますが、一度電波を受信した後は、今のところ表示が止まったりすることはありません。

アウトドアなら問題なく、また置時計として使うにも、電波が受信できる場所であれば、大丈夫でしょう。

GPS時計のスケッチ(プログラム) 

これまで紹介させていただいた作品の中では、おそらく最もシンプルなスケッチです。

バンコク時間に合わせたスケッチになっているので、日本時間を表示する場合は、6行目の

#define time_offset 25200 // define a clock offset of 3600*7 seconds (7 hour) ==> TH = UTC + 7

の部分を、

#define time_offset 32400 // define a clock offset of 3600*9 seconds (9 hour) ==> JP = UTC + 9

にします。 

スケッチは、TinyGPS++と、Arduino Time Librariesのライブラリを、インストールしてから使います。

#include <TinyGPS++.h>    
#include <TimeLib.h>          
#include <SoftwareSerial.h>   
#include <LiquidCrystal.h>    
TinyGPSPlus gps;
#define time_offset   25200  // define a clock offset of 3600*7 seconds (7 hour) ==> TH = UTC + 7
#define S_RX    9
#define S_TX    8
SoftwareSerial SoftSerial(S_RX, S_TX);   
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // LCD connections (RS, E, D4, D5, D6, D7)
 
// variable definitions
char Time[]  = "00:00:00";
char Date[]  = "2000/00/00";
byte last_second, Second, Minute, Hour, Day, Month;
int Year;
 
void setup(void)
{
  SoftSerial.begin(9600); 
 
  lcd.begin(16, 2); 

// welcome display
  lcd.setCursor(0, 0); 
  lcd.print("   GPS  CLOCK   ");
  lcd.setCursor(0, 1); 
  lcd.print("ARDUINO  POWERED");

  delay(5000);
  lcd.clear()  ;
}
 
void loop()
{
  while (SoftSerial.available() > 0)
  {
    if (gps.encode(SoftSerial.read()))
    {
// get time from GPS
      if (gps.time.isValid())
      {
        Minute = gps.time.minute();
        Second = gps.time.second();
        Hour   = gps.time.hour();
      }
 
// get date from GPS
      if (gps.date.isValid())
      {
        Day   = gps.date.day();
        Month = gps.date.month();
        Year  = gps.date.year();
      }
 
      if(last_second != gps.time.second())  
      {
        last_second = gps.time.second();
        setTime(Hour, Minute, Second, Day, Month, Year);
        adjustTime(time_offset);
 
// update time
        Time[6] = second() / 10 + '0';
        Time[7] = second() % 10 + '0';
        Time[3]  = minute() / 10 + '0';
        Time[4] = minute() % 10 + '0';
        Time[0]  = hour()   / 10 + '0';
        Time[1]  = hour()   % 10 + '0';
 
// update date array
        Date[2] = (year()  / 10) % 10 + '0';
        Date[3] =  year()  % 10 + '0';
        Date[5]  =  month() / 10 + '0';
        Date[6] =  month() % 10 + '0';
        Date[8]  =  day()   / 10 + '0';
        Date[9]  =  day()   % 10 + '0';
 
// show time & date
        print_wday(weekday()); 
        lcd.setCursor(4, 0);    
        lcd.print(Time);         
        lcd.setCursor(0, 1);    
        lcd.print(Date);         
      }
    }
  }
}
 
// for displaying day of the week
void print_wday(byte wday)
{
  lcd.setCursor(11, 1);  // move cursor to column 5, row 1
  switch(wday)
  {
    case 1:  lcd.print("(SUN)");   break;
    case 2:  lcd.print("(MON)");   break;
    case 3:  lcd.print("(TUE)");   break;
    case 4:  lcd.print("(WED)");   break;
    case 5:  lcd.print("(THU)");   break;
    case 6:  lcd.print("(FRI)");   break;
    default: lcd.print("(SAT)");
  }
}

本当に短いスケッチですね~

今回は、簡単に自作できるGPS時計の紹介でした。

早くキャンプに持っていきたい!

電波が届かないキャンプでも正確な時間な時計

それでは最後に、皆様がお家時間もアウトドア時間も楽しまれるよう、祈念しております。

炎も躍るサウンド レベル メーター。IKEAのフロアランプをカラフルに改造

今回は、お家でキャンプ気分シリーズの、スピンオフ編です。

焚き火を眺めてすごす、キャンプでの優雅な時間を、屋内でも楽しみたい!ということで、背が高いフロアランプを、カラーLEDを使って改造して、焚き火台風にしてみます。

 

炎が躍るサウンド レベル メーター。WS2812Bでファイヤーします

焚き火とサウンドレベルメーター

アウトドアを楽しめない週末が続くと、いろいろな思いがこみ上げてきます。

  • 殺風景な部屋に、フロアランプが欲しい!
  • キャンプに行けないのであれば、部屋で焚き火気分を楽しめないかな?
  • 外出できないのであれば、しばらく封印していたDIYでもやってみようか...

こんな妄想たちを、一気に実現するには、焚き火風のフロアランプを自作するしかない!と確信しました。

テーマパークの仕掛けで見かける、本物の炎のような、フェイクな焚き火です。

ファンの風によって布をチラつかせて、さらに光も当てることで、本物の焚き火と錯覚してしまう、あれですね。

購入した方が安くすみそうな気がしますが、自作もできそうな気がします。

 

しかし、構造を考えていて、音について悩みが生じます。

くつろぎの時間を過ごしたいところで、ファンの音に耐えられるだろうか?と。

テーマパークのような、他の音が存在する場所なら気にならないと思いますが、プライベートな部屋ではファンの音は雑音でしかありません。

ファンを使わずに炎のような光を実現するには、小さな光源がたくさん必要になりそう...と考えていて、それならLEDで表現してみましょう!と、コンセプトがみえてきました。

LEDの直接光では、炎のように見せるのは難しいと思われるので、日本の伝統的なフロアライト、行燈の中にLEDたちを閉じ込めてしまいます。

行燈の中に焚き火があっても、いいじゃない!

行燈をサウンド レベル メーターに!

不規則に揺らぐ焚き火の光は、見ていて飽きませんよね〜

あの揺らぎを人為的に表現するには、乱数発生プログラムを使ってLEDを不規則に光らせることが近道だと思いました。

...でも、それだけだと不規則すぎて面白くない気もします。

相変わらずの捻くれ者ぶりを発揮してしまったので、一週間ほど悩んでみました。

時間をかければ閃くこともあるようで、ふと音楽に合わせて光らせてみたら面白いのでは?と思いつきます。

行燈の中で、炎と、音楽に合わせて光が踊っているフロアーランプ!

これは欲しい!と納得できるアイデアが浮かんだので、さっそく制作に取り掛かります。

IKEAで行燈選び

アウトドアには行けない日が続いているものの、家具屋さんのIKEAが家の近くにあり、毎週末のように通って、気分転換をしています。

そんなIKEAには、今回の行燈サウンド レベル メーターの改造ベースにピッタリの、フロアランプがあることを知っています。

IKEAのフロアランプに、カラフルなLEDを仕込もう!

フードの材質が紙なので、光の指向性があるLEDとの相性もバッチリです。

いつもIKEAでは散歩スピードでショールームを楽しんでいますが、今回は売り場に直行して、フロアランプを入手してきました。

Arduinoと接続するモジュール

フロアランプを、行燈風サウンド レベル メーターとして光らせるために、個別に制御できるRGB LEDのWS2812Bをを使います。

「〇〇番目のLEDさんは、△△色に光ってください〜」

という情報さえ流せば、その通りに光るので、多くのLEDを個別に光り方を変えるのに便利なものです。

1mあたりにWS2812Bが60m個並べられているカラーLEDテープを3mと、サウンドセンサーモジュール、そして可変抵抗(ボリューム)3個を入手しました。

以前に、可変抵抗1個を使ってナイトライダー風サウンド レベル メーターを作ったことがありますが、今回はフロアランプでもあるので、

  • 光量
  • 光らせ方

の3項目を可変抵抗で選択できるように進化させます。

表示イメージとパターン

 もともとは、「焚火 in 行燈」コンセプトで始めたプロジェクトですが、純粋にサウンド レベル メーター風のパターンも含めて、合計7種類の光らせ方を準備します。

 行燈なので、まずは白色で光らせます。

写真は紫色のように写っていますが、実際には白色です。

WS2812Bで行燈を改造。(白色)

 サウンドレベルのバーが立ちます。色は炎のように、オレンジのグラデーションです。

WS2812Bで行燈を改造。(サウンド レベル メーター 赤色)

 サウンドレベルのバーが立ちます。色は可変抵抗で選択した単色です。

WS2812Bで行燈を改造。(サウンド レベル メーター 好きな色)

 サウンドレベルのバーが立ちます。色は徐々に変化します。

WS2812Bで行燈を改造。(サウンド レベル メーター 色は徐々に変化)

 焚き火風に光らせます。色は、「オレンジ白色」の3色です。

WS2812Bで行燈を改造。(ファイヤー 赤色)

 焚き火風に光らせます。色は、「水色白色」の3色です。

WS2812Bで行燈を改造。(ファイヤー 青色)

 焚き火風に光らせます。色は、「可変抵抗で選択した色白色」の2色です。

WS2812Bで行燈を改造。(ファイヤー 好きな色)

 焚き火風に光らせます。色は、「徐々に変化する白色」の2色です。

WS2812Bで行燈を改造。(ファイヤー 徐々に変化する色)

回路図

Arduinoで自作するサウンド レベル メーターの回路図

Fritzingで回路図を作成しました。

マイクモジュールは、MAX4466を搭載したものを使っています。

3個の可変抵抗(ボリューム)は、

  • R1;光量
  • R2;表示7パターンの切り替え
  • R3;色

の調節(選択)をするために使います。

Arduinoを使って、LEDを炎のパターンで光らせる

Arduinoのアナログ入力には、それぞれの可変抵抗から電圧で情報が送られます。

  • 電圧; 0〜5V
  • Arduinoの読み取り値; 0〜1023(整数)

0〜1023をArduinoのスケッチ(プログラム)で選択肢に置き換えれば、LEDの発光を調節できます。

今回は180個が繋がっているものを使うWS2812Bは、先程も簡単に紹介しましたが、それぞれのLEDが個別に信号処理して、色や光量を認識して発光するので、信号線1本と電源の、合計3本の電線を繋ぐだけで、自在に光を制御できる優れものです。

WS2812Bで、炎のランプを!

スケッチは、記事の最後に掲載しておきますね。

炎が踊るフロアーランプ

LEDの配置

LEDを、ランプ中心部の柱にどう配置するか?について、少し試行錯誤しました。

  • 螺旋状に巻く?
  • 縦の列状に配置する?

結論から言うと、縦に配置した方が、LEDの貼り付け作業も、炎やサウンドレベルメーターのスケッチ(プログラム)の作成も楽です。

私は4列で配置することにしました。

WS2812B ファイヤー

180個のWS2812Bテープなので、

「45行x4列 」

になる筈ですが、試行錯誤の段階でちょっとした事故があり、数セルが使えなくなってしまったので、やむなく43x 4の配置になりました。

ウエルカム点灯

電源投入時の動作は、3種類を仕込んでおきます。

  1. ランダム点滅(白色)

    f:id:solocamptouring:20210626123315j:plain

  2. 白色光を上下に一回走らせる

    f:id:solocamptouring:20210626123321j:plain

  3. レインボー色の光を上下に一回走らせる

    f:id:solocamptouring:20210626123435j:plain

静止画だと、どれだけ綺麗に光っているか?が伝わらないですが、光り方はメイキング動画でも、ご確認いただけます。

 

youtu.be

スケッチ(プログラム)

スケッチは、色々なパターンの光らせ方が準備されている、GitHubのFastLEDライブラリをベースにさせていただきます。

炎(fire)パターンは、派生バージョンも含めていくつか紹介されており、Fire2012WithPaletteの、炎を作成する部分のスケッチを使用させていただき、4列の炎専用に少し手を加えました。

もっと短いスケッチにできると思いますが、メモリー容量に余裕があるので良い!ということにして、同じ命令文が何度もでてきます。

#include "FastLED.h"
#define DATA_PIN    5
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define HEIGHT 43
#define WIDTH 4
#define NUM_LEDS HEIGHT*WIDTH
#define MAX_BRIGHTNESS 90      // Full is 164
#define MIN_BRIGHTNESS 5       // 25% is better
#define lighting_PER_SECOND 30 // Mainly for fire frame pattern

CRGB leds[NUM_LEDS];
CRGBPalette16 gPal;

const int sampleWindow = 50; // Sound sample window width in mS
unsigned int sample;
int SoundCenterAdjust = 0; // max 1024/2
int SoundLevelAdjust = 6; // defo and min 1 In case bar is small with the usual sound
int BRIGHTNESS = 50;
int scaleVol = 230; // Scale the heat value from 0-255
int SPARKING = 130; //50-200 out of 255
int COOLING = 70; // 20-100: Less = taller flames.  More = shorter flames. 
int colorSelect;
int micPin = 2;
int blightPin = 3;
int selectPin = 4;
int colorPin = 5;
int val = 0;
int numLedsToLight = 0;
long numLedsToLightCal = 0;
bool welcomeLight = true;
bool gReverseDirection = false;


void setup() {
  delay(3000); //delay for recovery
  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
}

// List of patterns to cycle through
typedef void (*SimplePatternList[])();

SimplePatternList gPatterns = { allwhite, soundBarFire, soundBarSelect, soundBarRotate, fireRed, fireBlue, fireSelect, fireRotate};

uint8_t gCurrentPatternNumber = 0;  // Index number of which pattern is current
uint8_t gHue = 96;                  // rotating "base color" used by many of the patterns 0to255
// End of the list of patterns to cycle through


void loop()
{
// Data collection
  // Choose the blightness
   if (analogRead(blightPin) < 50) {
    BRIGHTNESS = 0 ;
   } else {
    BRIGHTNESS = map(analogRead(blightPin), 50, 1024, MIN_BRIGHTNESS, MAX_BRIGHTNESS) ;
   } 
    FastLED.setBrightness(BRIGHTNESS); 

  // Choose the color
   if (analogRead(colorPin) < 50) {
    colorSelect = 0 ;
   } else if (analogRead(colorPin) < 950) {
    colorSelect = map(analogRead(colorPin), 50, 949, 0, 255) ;
   } else {
    colorSelect = 255;
   }

  // Choose the pattern
   val = analogRead(selectPin); //check the volume to choose the pattern
      if (val < 130) {
    gCurrentPatternNumber = 0;
       } else if (val < 260){
    gCurrentPatternNumber = 1;
       } else if (val < 390){
    gCurrentPatternNumber = 2;
       } else if (val < 520){
    gCurrentPatternNumber = 3;
       } else if (val < 650){
    gCurrentPatternNumber = 4;
       } else if (val < 780){
    gCurrentPatternNumber = 5;
       } else if (val < 910){
    gCurrentPatternNumber = 6;
       } else {
    gCurrentPatternNumber = 7;      
       }
    gPatterns[gCurrentPatternNumber](); // Call the current pattern function once, updating the 'leds' array

// End of data collection


// Welcome lighting
  if (welcomeLight == true) {
  // random speckles that blink in and fade smoothly
    for(int led = 0; led < 150; led++) { 
    fadeToBlackBy( leds, NUM_LEDS, 100);
    int pos = random16(NUM_LEDS);
    leds[pos] += CRGB::White;
    FastLED.show();  
    delay (100-led/2);
    }  
    
  // white up and down
    for(int led = 0; led < HEIGHT; led++) { 
    fadeToBlackBy( leds, NUM_LEDS, 100);
    leds[led] += CRGB::White ; 
    leds[HEIGHT*2-1-led] += CRGB::White ; 
    leds[HEIGHT*2+led] += CRGB::White ; 
    leds[HEIGHT*4-1-led] += CRGB::White ; 
    FastLED.show();    
    delay (80);
    }

    for(int led = 0; led < HEIGHT; led++) { 
    fadeToBlackBy( leds, NUM_LEDS, 100);
    leds[HEIGHT-1-led] += CRGB::White ; 
    leds[HEIGHT+led] += CRGB::White ; 
    leds[HEIGHT*3-1-led] += CRGB::White ; 
    leds[HEIGHT*3+led] += CRGB::White ; 
    FastLED.show();    
    delay (80);
    }
  
  // rainbow up and down
    for(int led = 0; led < HEIGHT; led++) { 
    fadeToBlackBy( leds, NUM_LEDS, 100);
    leds[led] = CHSV(255*led/HEIGHT, 255, 255) ; 
    leds[HEIGHT*2-1-led] = CHSV(255*led/HEIGHT, 255, 255) ; 
    leds[HEIGHT*2+led] = CHSV(255*led/HEIGHT, 255, 255) ; 
    leds[HEIGHT*4-1-led] = CHSV(255*led/HEIGHT, 255, 255) ; 
    FastLED.show();    
    delay (80);
     }
 
    for(int led = 0; led < HEIGHT; led++) { 
    fadeToBlackBy( leds, NUM_LEDS, 100);
    leds[HEIGHT-1-led] = CHSV(255*led/HEIGHT, 255, 255) ; 
    leds[HEIGHT+led] = CHSV(255*led/HEIGHT, 255, 255) ; 
    leds[HEIGHT*3-1-led] = CHSV(255*led/HEIGHT, 255, 255) ; 
    leds[HEIGHT*3+led] = CHSV(255*led/HEIGHT, 255, 255) ; 
    FastLED.show();    
    delay (80);
    }    
    welcomeLight = false;  //End welcome lighting
  }else{

// Let's light them now
  random16_add_entropy( random());
  gPatterns[gCurrentPatternNumber]();
  FastLED.show();  // send the 'leds' array out to the actual LED strip
  FastLED.delay(1000 / lighting_PER_SECOND);
  EVERY_N_MILLISECONDS( 300 ) { gHue++; } // slowly cycle the color through the rainbow
// End of lighting
    }  
}


void fireRed() 
{
  gPal = CRGBPalette16( CRGB::Black, CRGB::Red, CRGB::Yellow, CRGB::White);
  static uint8_t heat[NUM_LEDS]; // Array of temperature readings

  // Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / HEIGHT) + 2)); //heat-randam8 with a floor of 0
    }
  
  // Heat from each cell drifts 'up' and diffuses a little
    for( int k= HEIGHT - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
      heat[2*HEIGHT-1-k] = (heat[2*HEIGHT-1-k + 1] + heat[2*HEIGHT-1-k + 2] + heat[2*HEIGHT-1-k + 2] ) / 3;
      heat[2*HEIGHT+k] = (heat[2*HEIGHT+k - 1] + heat[2*HEIGHT+k - 2] + heat[2*HEIGHT+k - 2] ) / 3;
      heat[4*HEIGHT-1-k] = (heat[4*HEIGHT-1-k + 1] + heat[4*HEIGHT-1-k + 2] + heat[4*HEIGHT-1-k + 2] ) / 3;
    }
    
    //  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int x = random8(19);
      int y ;
      if(x > 14){
        y = 4*HEIGHT+16-x;
      } else if(x > 9){
        y = 2*HEIGHT-9+x;
      } else if(x > 4){
        y = 2*HEIGHT+4-x;
      } else {
        y = x;
      }
      heat[y] = qadd8( heat[y], random8(160,255) ); //heat+randam8
    }

    // Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      uint8_t colorindex = scale8( heat[j], scaleVol);
      CRGB color = ColorFromPalette( gPal, colorindex);
      int pixelnumber;
      if( gReverseDirection ) {
        if(j < HEIGHT){
          pixelnumber = (HEIGHT-1) - j;
          }else if(j < 2*HEIGHT){
          pixelnumber = HEIGHT+j;
          }else if(j < 3*HEIGHT){
          pixelnumber = (3*HEIGHT-1) - j;
          }else{
          pixelnumber = 3*HEIGHT+j;
          }
      } else {
        pixelnumber = j;
      }
      leds[pixelnumber] = color;
    }
}

void fireRotate() 
{
  gPal = CRGBPalette16( CRGB::Black, CHSV( gHue, 255, 192), CRGB::White);
  static uint8_t heat[NUM_LEDS]; // Array of temperature readings

  // Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / HEIGHT) + 2)); //heat-randam8 with a floor of 0
    }
  
  // Heat from each cell drifts 'up' and diffuses a little
    for( int k= HEIGHT - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
      heat[2*HEIGHT-1-k] = (heat[2*HEIGHT-1-k + 1] + heat[2*HEIGHT-1-k + 2] + heat[2*HEIGHT-1-k + 2] ) / 3;
      heat[2*HEIGHT+k] = (heat[2*HEIGHT+k - 1] + heat[2*HEIGHT+k - 2] + heat[2*HEIGHT+k - 2] ) / 3;
      heat[4*HEIGHT-1-k] = (heat[4*HEIGHT-1-k + 1] + heat[4*HEIGHT-1-k + 2] + heat[4*HEIGHT-1-k + 2] ) / 3;
    }
    
    //  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int x = random8(19);
      int y ;
      if(x > 14){
        y = 4*HEIGHT+16-x;
      } else if(x > 9){
        y = 2*HEIGHT-9+x;
      } else if(x > 4){
        y = 2*HEIGHT+4-x;
      } else {
        y = x;
      }
      heat[y] = qadd8( heat[y], random8(160,255) ); //heat+randam8
    }

    // Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      uint8_t colorindex = scale8( heat[j], scaleVol);
      CRGB color = ColorFromPalette( gPal, colorindex);
      int pixelnumber;
      if( gReverseDirection ) {
        if(j < HEIGHT){
          pixelnumber = (HEIGHT-1) - j;
          }else if(j < 2*HEIGHT){
          pixelnumber = HEIGHT+j;
          }else if(j < 3*HEIGHT){
          pixelnumber = (3*HEIGHT-1) - j;
          }else{
          pixelnumber = 3*HEIGHT+j;
          }
      } else {
        pixelnumber = j;
      }
      leds[pixelnumber] = color;
    }
}

void fireBlue() 
{
  gPal = CRGBPalette16( CRGB::Black, CRGB::Blue, CRGB::Aqua,  CRGB::White);
  static uint8_t heat[NUM_LEDS]; // Array of temperature readings

  // Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / HEIGHT) + 2)); //heat-randam8 with a floor of 0
    }
  
  // Heat from each cell drifts 'up' and diffuses a little
    for( int k= HEIGHT - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
      heat[2*HEIGHT-1-k] = (heat[2*HEIGHT-1-k + 1] + heat[2*HEIGHT-1-k + 2] + heat[2*HEIGHT-1-k + 2] ) / 3;
      heat[2*HEIGHT+k] = (heat[2*HEIGHT+k - 1] + heat[2*HEIGHT+k - 2] + heat[2*HEIGHT+k - 2] ) / 3;
      heat[4*HEIGHT-1-k] = (heat[4*HEIGHT-1-k + 1] + heat[4*HEIGHT-1-k + 2] + heat[4*HEIGHT-1-k + 2] ) / 3;
    }
    
    //  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int x = random8(19);
      int y ;
      if(x > 14){
        y = 4*HEIGHT+16-x;
      } else if(x > 9){
        y = 2*HEIGHT-9+x;
      } else if(x > 4){
        y = 2*HEIGHT+4-x;
      } else {
        y = x;
      }
      heat[y] = qadd8( heat[y], random8(160,255) ); //heat+randam8
    }

    // Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      uint8_t colorindex = scale8( heat[j], scaleVol);
      CRGB color = ColorFromPalette( gPal, colorindex);
      int pixelnumber;
      if( gReverseDirection ) {
        if(j < HEIGHT){
          pixelnumber = (HEIGHT-1) - j;
          }else if(j < 2*HEIGHT){
          pixelnumber = HEIGHT+j;
          }else if(j < 3*HEIGHT){
          pixelnumber = (3*HEIGHT-1) - j;
          }else{
          pixelnumber = 3*HEIGHT+j;
          }
      } else {
        pixelnumber = j;
      }
      leds[pixelnumber] = color;
    }
}

void fireSelect() 
{
  gPal = CRGBPalette16( CRGB::Black, CHSV( colorSelect, 255, 192), CRGB::White);
  static uint8_t heat[NUM_LEDS]; // Array of temperature readings

  // Cool down every cell a little
    for( int i = 0; i < NUM_LEDS; i++) {
      heat[i] = qsub8( heat[i],  random8(0, ((COOLING * 10) / HEIGHT) + 2)); //heat-randam8 with a floor of 0
    }
  
  // Heat from each cell drifts 'up' and diffuses a little
    for( int k= HEIGHT - 1; k >= 2; k--) {
      heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3;
      heat[2*HEIGHT-1-k] = (heat[2*HEIGHT-1-k + 1] + heat[2*HEIGHT-1-k + 2] + heat[2*HEIGHT-1-k + 2] ) / 3;
      heat[2*HEIGHT+k] = (heat[2*HEIGHT+k - 1] + heat[2*HEIGHT+k - 2] + heat[2*HEIGHT+k - 2] ) / 3;
      heat[4*HEIGHT-1-k] = (heat[4*HEIGHT-1-k + 1] + heat[4*HEIGHT-1-k + 2] + heat[4*HEIGHT-1-k + 2] ) / 3;
    }
    
    //  Randomly ignite new 'sparks' of heat near the bottom
    if( random8() < SPARKING ) {
      int x = random8(19);
      int y ;
      if(x > 14){
        y = 4*HEIGHT+16-x;
      } else if(x > 9){
        y = 2*HEIGHT-9+x;
      } else if(x > 4){
        y = 2*HEIGHT+4-x;
      } else {
        y = x;
      }
      heat[y] = qadd8( heat[y], random8(160,255) ); //heat+randam8
    }

    // Map from heat cells to LED colors
    for( int j = 0; j < NUM_LEDS; j++) {
      uint8_t colorindex = scale8( heat[j], scaleVol);
      CRGB color = ColorFromPalette( gPal, colorindex);
      int pixelnumber;
       if( gReverseDirection ) {
        if(j < HEIGHT){
          pixelnumber = (HEIGHT-1) - j;
          }else if(j < 2*HEIGHT){
          pixelnumber = HEIGHT+j;
          }else if(j < 3*HEIGHT){
          pixelnumber = (3*HEIGHT-1) - j;
          }else{
          pixelnumber = 3*HEIGHT+j;
          }
      } else {
        pixelnumber = j;
      }
      leds[pixelnumber] = color;
    }
}

void soundBarFire() 
{

  // Sound level to lighting LED amount
   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level
   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(micPin);
      if (sample < 1024)
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save the min levels
         }
      }       
   }
   peakToPeak = signalMax - signalMin ;  // max - min = peak-peak amplitude
   numLedsToLightCal = ((peakToPeak-SoundCenterAdjust)*HEIGHT*SoundLevelAdjust)/1024 ;
   if(numLedsToLightCal >= HEIGHT){
    numLedsToLight = HEIGHT;
   }else {
   numLedsToLight = numLedsToLightCal; // adjusting to the output of the mic 
   }
    fadeToBlackBy( leds, NUM_LEDS, 200);

  for(int led = 0; led < numLedsToLight; led++) { 
  leds[led] += CHSV( 2*(numLedsToLight-1-led), 255, 192);
  }
  for(int led = HEIGHT*2-numLedsToLight; led < HEIGHT*2; led++) { 
  leds[led] += CHSV( 2*(led-(HEIGHT*2-numLedsToLight)), 255, 192);
  }
  for(int led = HEIGHT*2; led < HEIGHT*2+numLedsToLight; led++) { 
  leds[led] += CHSV( 2*(HEIGHT*2+numLedsToLight-1-led), 255, 192);
  }
  for(int led = HEIGHT*4-numLedsToLight; led < HEIGHT*4; led++) { 
  leds[led] += CHSV( 2*(led-(HEIGHT*4-numLedsToLight)), 255, 192);
  }
}

void soundBarSelect() 
{

  // Sound level to lighting LED amount
   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level
   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(micPin);
      if (sample < 1024)
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save the min levels
         }
      }       
   }
   peakToPeak = signalMax - signalMin ;  // max - min = peak-peak amplitude
   numLedsToLightCal = ((peakToPeak-SoundCenterAdjust)*HEIGHT*SoundLevelAdjust)/1024 ;
   if(numLedsToLightCal >= HEIGHT){
    numLedsToLight = HEIGHT;
   }else {
   numLedsToLight = numLedsToLightCal; // adjusting to the output of the mic 
   }
    fadeToBlackBy( leds, NUM_LEDS, 200);


  for(int led = 0; led < numLedsToLight; led++) { 
  leds[led] += CHSV( colorSelect, 255, 192);
  }
  for(int led = HEIGHT*2-numLedsToLight; led < HEIGHT*2; led++) { 
  leds[led] += CHSV( colorSelect, 255, 192);
  }
  for(int led = HEIGHT*2; led < HEIGHT*2+numLedsToLight; led++) { 
  leds[led] += CHSV( colorSelect, 255, 192);
  }
  for(int led = HEIGHT*4-numLedsToLight; led < HEIGHT*4; led++) { 
  leds[led] += CHSV( colorSelect, 255, 192);
  }
}

void soundBarRotate() 
{

  // Sound level to lighting LED amount
   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level
   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(micPin);
      if (sample < 1024)
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save the min levels
         }
      }       
   }
   peakToPeak = signalMax - signalMin ;  // max - min = peak-peak amplitude
   numLedsToLightCal = ((peakToPeak-SoundCenterAdjust)*HEIGHT*SoundLevelAdjust)/1024 ;
   if(numLedsToLightCal >= HEIGHT){
    numLedsToLight = HEIGHT;
   }else {
   numLedsToLight = numLedsToLightCal; // adjusting to the output of the mic 
   }
    fadeToBlackBy( leds, NUM_LEDS, 200);

   for(int led = 0; led < numLedsToLight; led++) { 
   leds[led] += CHSV( gHue, 255, 192); 
   }
  for(int led = HEIGHT*2-numLedsToLight; led < HEIGHT*2; led++)  { 
   leds[led] += CHSV( gHue, 255, 192); 
  }
  for(int led = HEIGHT*2; led < HEIGHT*2+numLedsToLight; led++) { 
   leds[led] += CHSV( gHue, 255, 192); 
  }
  for(int led = HEIGHT*4-numLedsToLight; led < HEIGHT*4; led++) { 
   leds[led] += CHSV( gHue, 255, 192); 
  } 
}

void allwhite() 
{
  // all led white color
  fill_solid(leds, NUM_LEDS, CRGB::White); 
}

 

今回は、フロアランプに焚火を仕込みましょう!というコンセプトで、お家ですごす時間を楽しくしてみました。

毎週末を使って、製作期間は一か月ほどかかりましたが、初めて見る人には「フロアランプが燃えている!」と思わせそうな完成度で、満足しています。

WS2812Bでファイヤーパターンのフロアライト

室内で焚火はできないアパート暮らしですが、お部屋に焚き火風の光があると、本当にキャンプしているような気分になって、うっとりと見入っています。

ソロキャンプで使うタクティカルなリュックとバッグ。MOLLE(モール)システムでカスタマイズ

ソロキャンプに似合うバッグ

静かな雰囲気を楽しむようなソロキャンプスタイルでは、リュックサックに全てのキャンプ道具を積み込んで、身軽に出かけたくなります。

そんなキャンプの時に似合うのが、タクティカル系のリュックですね!

 

このような、ウェビング(ストラップ)がたくさん縫いこまれているリュックサックは、ポーチ類が簡単に脱着できるので、その時々のキャンプ条件に合わせて、持っていくものをポーチごと付け替えできるのも嬉しい機能です。

見るからにタクティカル(戦術的)で機能的な、このリュックサック、遅ればせながら私も欲しくなってきたのですが、ふとウェビングがあれば、いつも使っているバッグ類も、簡単に変身させられるのでは?と思いつきました。

周りにあるバッグを改めて確認してみると、同じくらいの幅のウェビングが、だいたい一か所は使われています。

ノースフェイスの防水リュックにもMOLLEシステムのウェビングが

これはカスタマイズして楽しめそう!だと思い、早速ウェビングに取り付けるアタッチメント類のセットを、入手してみました。

MOLLEアクセサリーでキャンプ用バッグにカスタマイズ

このアタッチメント類を活用し、普段使っているバッグにポーチや小物を追加して、個性的で機能的なソロキャンプ用のバッグに変身するかを試してみます!

キャンプにピッタリの、タクティカルなバッグを見つけた

OLLE(モール)システムでソロキャンプに似合うバッグにしよう!タクティカルにカスタマイズ

MOLLE、モール、モーリーシステム?

ポーチをバッグに連結するアタッチメント類を入手するにあたり、そのシステムや規格について調べてみました。

1インチ幅のウェビングを使うMOLLEシステムは、アメリカで軍をはじめ警察や消防でも採用しているシステムです。

MOLLEは、Modular Lightweight Load-carrying Equipment(モジュラー ライトウェイト ロードキャリーイング イクイップメント)の省略名称です。

このMOLLEシステムを採用しているベストやベルト、バッグなどは、PALS(Pouch Attachment Ladder System;ポーチ アタッチメント ラダーシステム)と呼ばれる、

  • ハシゴ状に配置されたウェビングがついているか、
  • もしくはそのウェビングに取り付けられる構造

になっています。

PALSウェビングの規格は

  • 幅1インチ(約2.5cm)で、
  • 縦方向の間隔1インチでハシゴ状に配置し、
  • 1.5インチ(約3.8cm)間隔でベースの生地に縫いこまれて

います。

少し説明が長くなってしまいましたが、まとめると、MOLLEシステムを使ったポーチ類などは、PALSに簡単に付け外しができる仕組みになっています。

ちなみに、日本ではMOLLEを「モール」と発音することが多いですが、本場アメリカでは「モーリー」に近い発音のようです。

MOLLEアタッチメント類の使い方

入手したアタッチメント類について、それぞれの使い方を写真で簡単に紹介いたします。

ウェビング グリムロック(Dリング)

 普通のカラビナと、形も使い方も似ていますが、MOLLEシステム用のウェビンググリムロックは、頂上部のロックボタンを押してはずすと、外側に開きます。

MOLLEウェビング グリムロック(Dリング)
MOLLEウェビング グリムロックでキャンプ用バッグ

開いた状態でのみ、ウェビングに取り付けられるようになっているので、閉じて使っている通常時には、意図せず紛失する可能性は低いですね!

逆に、装着していたものを取り外すときに、普通のカラビナの感覚で操作すると開きっぱなしになり、何かに引っかかりやすくなってしまいます。

かっこ良さと引き換えに、開けたら閉じる!をクセ付けしようと思います。

ウェビング クリップ(コネクティング バックル)

ウェビングやストラップを2本束ねて挟む、MOLLE用のクリップです。

MOLLEウェビング クリップでキャンプ用のバッグをつくる
MOLLEコネクティング バックルでキャンプ用のバッグをつくる

上の写真では、ポーチに縫製されているPALSウェビングと、MOLLE規格のベルトを止めてみました。

ウェビングクリップがあれば、幅1インチ以下のウェビングがついているバッグ類に、MOLLE対応ポーチを取り付け可能です。

ウェブドミネーター

 名前を初めて聞いた時は、インターネット上の凄そうなもの(人)を連想しましたが、「ウェブ」は「ウェビング」の省略形だとわかって、納得しました!

MOLLEウェブドミネーターでキャンプ用のバッグをつくる

ウェブドミネーターには、ゴムコードと、それを引っかけられる溝がついていて、余分なストラップを束ねて保管できるようになっています。

せっかくのゴムコードなので、何か他の使い方がないかと思い、とりあえず、クルクルと丸めたタオルを留めてみました。

キャンプ用ポーチに、MOLLEウェブドミネーターでタオルを留める

予想外に良い感じでタオルがついています!

キャンプでの使い方としては、野営地に到着して最初に広げることになるグランドシートを、丸めて留めておくと便利そうです。

キーリング(キーホルダー)

「タクティカル」という言葉が似合う雰囲気の、ベルト付きキーホルダーです。

ポーチのPALSウェビングに、キーリングべルトのマジックファスナーで付けてみました。

MOLLEキーリング(キーホルダー)でキャンプ用のバッグにする

コレと決めたモノをつけるだけではなく、キャンプ中に使う細々としたグッズを、使わない時に一時的にぶらさげておくのにも便利そうです。

ポーチ類だけではなく、ベルトやベストに付けておいても便利そうですね。

そのための、MOLLEシステムのベストなんてものもあるようです!

回転Dリング

ウェビング上の好きな位置につけられる、Dリングです。

Dリングの向き(角度)は、45度ごとに調整できるので、ナナメ方向にも取り付けできます。

MOLLE 回転Dリング

このアタッチメントだけは、ベースを90度回転させる形で、1インチよりも細い幅のウェビングにも対応できるようになっています。

ベルトループ

 最後に、いろいろと使えそうな、マジックファスナー付きのベルトループです。

MOLLE ベルトループ

PALSウェビングがついているポーチ類の結合に使う他にも、いろいろな物をぶら下げる時のループとしても使えます。

キャンプでは数本持っておくと、何かと便利なアタッチメントです。

いつものバッグを変身させます! 

それでは実際に、普段使っているバッグ類をカスタマイズしてみます。

ノースフェイスのBCフューズボックス2に、こっそりDリングをつける

手始めに、家族が使っているノースフェイスのリュック(BC Fuse Box2)に、持ち主にはナイショでDリングを付けてみました。

ノースフェイスのリュックにMOLLEのDリングを付けてみた

あまりのシンデレラフィットに、毎日使っている持ち主には、まだ気づかれていません!

ちなみに、このリュックのストラップ部はデイジーチェーンとして設定されており、ウェビングの幅はPALS規格とほぼ同じですが、リュック本体への縫い目は斜めになっています。

通勤用のボディーバッグを、タクティカル風にしてみたら?

ブロック遊びのようにに組み立てられるMOLLEシステムが楽しすぎるので、勢いで、通勤で使っているNEOPROのボディーバッグのイメージチェンジを狙います。

バッグ背面のウェビングと、肩掛け用ストラップのそれぞれに、MOLLEポーチを装着してみました。

MOLLEシステムで、通勤用のボディーバッグもキャンプが似合うタクティカル風に

ブラックで色を統一しているのが幸いして、アウトドア用途化!という本来の目的を忘れて、このまま通勤で使ってもいいかも?と思わせる一体感です。

ウェブドミネーターを2か所つけたら、折り畳み傘の持ち運びも便利になりそうです。

ボディーバッグ本体を背中側にして肩掛けした時に、お腹側のちょうどいい位置にくるMOLLEポーチも使いやすく、正背面ともにバッグになっているボディーバッグが普及しないのが不思議なくらいです。

ハイキングやデイキャンプ程度であれば、このボディーバッグが活躍してくれそうです。

リュックサックを、キャンプが似合うタクティカル風にします!

 最後に、大本命のリュックサックを、イメージチェンジさせてみます。

バイク用品ブランド「FOX」のリュックで、少し古いものですが、気に入って今でも使い続けています。

もとから容量はそこそこあるリュックなので、背面ではなく前面の肩ストラップにポーチを追加してみます。

既に写真で何度も登場しているMOLLEポーチは、このために入手しました!

MOLLEシステムを使ってリュックサックをキャンプが似合うタクティカル風にかえる

キャンプで使うにしては少しオシャレ感がある、透かし模様の生地を使ったリュックですが、MOLLE ポーチを付けたことで、タクティカルな雰囲気に一変します!

MOLLEシステムに対応したポーチは、この写真の2種類の他にも、スマホホルダーやドリンクボトルホルダー、サングラスケースなど様々な種類があり、キャンプスタイルや持っていくものに合わせて選択できます。

ダッフルバッグ形状も、キャンプには便利!

MOLLEシステムで自由に組み合わせられる楽しさが病みつきになり、さらにキャンプに似合う、自分だけの荷物入れを作りたくなり、他のポーチやアタッチメント類も物色しはじめました。

どうせなら便利に活用したいので、少し長尺のキャンプ用品に対応できるものにしたい!と思います。

トライポッドやランタンスタンドで使うような、太めのポール類をキャンプに持っていく場合がありますが、長さがあるものが多いと持ち運びが大変だったりしますよね。

そこで、ポール類を余裕を持って入れられる長さの、MOLLEシステム対応のライフルケースを入手してみました。

MOLLE(モール)システムのバッグでキャンプに行く

ポールの他にも、軽量テントやハンモックなどを同時に入れられる容積のものにしたので、このバッグだけでソロキャンプに行けます。

大開口で開けられるようなジッパー配置になっているので、キャンプ地での設営や撤収作業も楽ですね。

テントやハンモックなどを入れられるMOLLE(モール)システムバッグ

そして最大の便利ポイントですが、荷物が収まりきらなかったり長さが足りないといった時に、ポール類はウェブドミネーターでバッグの外側にも取り付けることができます。

意外にもキャンプ道具がちょうどよく収まるMOLLE対応ライフルケースですが、さっそくポーチやアタッチメント類でカスタマイズして、上の写真の状態で楽しく便利に使っています!

色と明るさを変えられる集魚灯。ArduinoとLEDボードで自作したら爆釣モードに入った!

先日、初めての夜釣りで小さい根魚を釣り上げました。

f:id:solocamptouring:20190427081000j:plain

手のひらに収まる、あまりにも可愛いサイズだったので、海に元気にお帰りになりました。

次回は、なんとしてでも大きな根魚に出会いたいので、魚が集まりやすい集魚灯を自作して、夜釣りに導入したいと思います。

f:id:solocamptouring:20190427134321j:plain

魚が集まる集魚灯の色

集魚灯に魚が集まってくる理由を調べてみました。

陸地からのチョイ投げタイプの海釣りで使う集魚灯は、発光性プランクトンや夜光虫を模したものです。

集魚灯の光に、プランクトンや夜光虫を食べる虫や小魚が寄ってきて、さらにそれらを捕食する魚も寄ってくるようです。食物連鎖でなんでも釣れそうですね!

発光性プランクトンといえば青色緑色のイメージです。

しかし、疑似餌(ルアー)が、実際にはありえない配色のものがよく釣れたりするので、集魚灯に最適な色も、実際に試してみないとわかりません。

そこで、自由に色を変えられる集魚灯を作って、その時々の最適な色を探ってみたいと思います。

集魚灯の自作

なるべく簡単に、そして安く集魚灯を作ってみます。

魚を集める機能を追い求めるので、見栄えは二の次です!

集魚灯の部品を準備します

Arduino

コンパクトな大きさで使いやすいArduino Nano(互換品)を使います。

写真は、今回使ったDC5Vの外部電源入力用の部品も写っています。

f:id:solocamptouring:20190427091835j:plain
f:id:solocamptouring:20190427104755j:plain

Arduinoのスケッチ(プログラム)は、記事の最後に掲載しています。

WS2812Bボード

集魚灯の発光部は、WS2812B を7個 配置した円形ボードを使います。

直径23mmと小型なので、堤防で根魚を狙う時などの集魚灯には、ちょうどいい性能と大きさです。

自作した集魚灯に使うWS2812B

ミサイルスイッチ

スイッチはなくても集魚灯は動かせるのですが、実際に使う時の雰囲気づくりのために、他の作品でもミサイルスイッチを使っています。

プロジェクトボックスのスペースをとってしまいますが、ミサイルスイッチで電源を入れる儀式をしてから使うと、何かが起きそうで気分が盛り上がります。

今回は、青色のミサイルスイッチで、釣れるスイッチのおまじないをします。

集魚灯の電源はミサイルスイッチで
集魚灯のプロジェクトボックス

可変抵抗(ボリューム)

集魚灯をコントロールするために、可変抵抗を使います

  • 光の色
  • 光の強さ

をそれぞれ選択できるように、2個の10KΩ可変抵抗を準備します。

コネクターとコード

海中に入れる発光部は5mのコードでコントローラに繋ぎます。

持ち運びやすくしたいので、AWG28の細い電線が3本入っているコードを準備しました。

コントロールボックスと発光部をつなぐコードは、コネクターで接続します。

Arduinoの自作作品に似合うコネクター

通販サイトでは「航空コネクタ」で検索するとみつかる、この少し仰々しいコネクターも、雰囲気づくりのために愛用しています。

集魚灯の回路をつくる

 WS2812Bボードは、電源線2本と信号線1本の合計の3本の電線をつなぐだけで、様々な光らせ方ができる優れものです。回路も単純な構成になるので、自作品には便利に使えます。

回路図は、Fritzingで作成しました。

f:id:solocamptouring:20190427101733j:plain

スペースの都合で、回路図にWS2812Bは5個だけ表現されていますが、実際には7個が直列につながっています。

発光部を除いて、配線をはんだ付けしてみました。

自作集魚灯の回路

今回は配線が少ないので、Arduinoには直接はんだ付けしています。

はんだごての熱でArduino上の部品を壊さないように、注意しながら作業を進めました。

プロジェクトボックスに回路を入れる

コントローラを仕上げるために、プロジェクトボックスに各部品の取付穴をあけます。

コネクターだけは、ボックスに外側から固定する形なので、配線をはんだ付けする前にボックスにねじ止めします。

続いて、スイッチと可変抵抗も、ボックスの上面に内側から取り付けます。

Arduino Nanoは、ボックス内に両面テープで貼り付けておきました。

自作集魚灯のコントローラ
自作集魚灯のコントローラの中

蓋を閉じたら、コントロールボックスの完成です。

試しに光らせてみましょう

5mの3芯コードの両端に、WS2812Bボードとコネクタをつけて、実際に光らせてみました。

自作集魚灯がほぼ完成

集魚灯として本命案の青色や緑色は、一種類だけでなく、可変抵抗のツマミをまわすことで多彩な色をつくりだすことができます。

集魚灯としての効果は無いかもしれませんが、 ツマミをまわして赤色や黄色などの色も作れます。

記事の最後で紹介しているスケッチでは、色を調整する可変抵抗のツマミを右にいっぱいまで回すと、ゆっくりと全ての色に変わっていくようにしています。

発光部の防水化

WS2812Bボードは、水深5mの水圧でも耐えられるように、透明樹脂で覆って防水化します。 

透明樹脂を流し込むケースに何を使おうか考えていたら、卓球の玉に目がとまりました。

大きさが発光部にちょうどよく、乳白色なので周囲に光を拡散してくれそうです。

さっそく玉の上部を切開します。

錘をつける針金を発光部の穴に通して玉の中にいれた後に、クリスタルレジン を流し込みました。

そのまま動かさないようにして樹脂が固まったら完成ですが、待ちきれないなので再度光らせてみます。

玉の下部に無造作に貼られているマスキングテープは、クリスタルレジンが流れ出ないように塞いでいるもので、樹脂が固まったら取り除きます。

自作集魚灯の発光部

狙いどおり、乳白色の卓球の玉全体で、いい感じで光っています。

自作集魚灯のシェイクダウン

後日、ためしに使ってみました。

釣りには不向きな強風の日に、漁港の堤防の風裏になる場所で、昼過ぎから釣り竿をたらしつつ、夜を待ちます。

明るいうちは何も釣れないままで時間が過ぎていき、あたりが暗くなったところで集魚灯の電源を入れて、釣りをしている場所から2mほど離れた海中に投入してみました。

すると、魚が活発に動く時間になったのもあると思いますが、種類は同じで前回よりも(成長したので!?)大きめの魚が、ほぼ入れ食いとなりました!

自作集魚灯に群がる根魚
色を変えて海中で淡く光る自作集魚灯

キャッチ&リリースを繰り返しましたが、あまりにも簡単に釣れるので、何匹釣ったか数えるのは途中でやめてしまいました。これは、もう夜釣りでは手放せません!

効果的な光の色は、少し青色が入った緑色が良さそうですが、これはもう少し継続的に試してみたいと思います。

集魚灯のスケッチ(プログラム)

GitHubのFastLEDライブラリを使って、簡単な命令文で光らせているので、短いスケッチになっています。

#include "FastLED.h"
#define DATA_PIN    4
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define HEIGHT 1
#define WIDTH 7
#define NUM_LEDS HEIGHT*WIDTH

CRGB leds[NUM_LEDS];

const int sampleWindow = 20; // Sample window width in mS
unsigned int sample;
int colorSelect;
int colorPin = 2;
int selectPin = 5;
int val = 0;
int numLedsToLight = 0;
int numLedsSide = 0;
int volumeLight = 0;

void setup() {

  delay(3000); //delay for recovery

  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
}

uint8_t gHue = 96; // rotating "base color" used by many of the patterns

void loop()
{
  colorSelect = analogRead(colorPin); //check the volume to choose the color

  if (analogRead(colorPin) < 50) {
    colorSelect = 0 ;
  } else if (analogRead(colorPin) < 950) {
    colorSelect = map(analogRead(colorPin), 50, 949, 0, 255) ;
  } else {
    colorSelect = gHue;
  }

  val = analogRead(selectPin); //check the volume to choose the volume

  if (val < 205) {
    volumeLight = 3;
  } else if (val < 1000) {
    volumeLight = map(analogRead(selectPin), 205, 1000, 3, 50);
  } else {
    volumeLight = 50;
  }

  FastLED.setBrightness(volumeLight);

  fill_solid(leds, NUM_LEDS, CHSV( colorSelect, 255, 192));

  FastLED.show();  // send the 'leds' array out to the actual LED strip

  EVERY_N_MILLISECONDS( 300 ) {
    gHue++;  // slowly cycle the "base color" through the rainbow
  }
}

カヤックを載せやすいルーフキャリア。タフレックのアルミキャリアをカスタマイズ

カヤックをルーフキャリアにする。タフレックのアルミキャリア


ルーフキャリアに、長さ3m以上で重さ30Kgほどの荷物(カヤック)を、頻繁に載せたくなりました。

今すでに使っているルーフキャリアを改造して、すこしでも楽に積載できるようにしたいと思います。

私が使っているルーフキャリア

最初に、ジムニーに使っているキャリアについて、簡単に紹介いたします。

横から見たデザインに力強さがある、タフレックのルーフキャリア を選んで、不満なく使っています。

天板部が鉄のものとアルミのものがありますが、写真はアルミ天板のものです。

私の使い方での剛性は充分にありつつ、軽いのでキャリア自体を車から脱着する時の持ち運びも一人でできます。

そして、これから紹介するプチ改造では、「このための構造では?」と思ってしまうほど重要なポイントですが、サイドバーが丸パイプなのも、このキャリアの特徴です。

ルーフキャリアに積みたい長尺物

タフレックのアルミルーフキャリアを入手した時には、載せるものを特に決めていませんでした。

キャンプ道具をルーフに積むことがあるかもしれない!くらいにしか考えてなく、実際には雨で濡れたタープを運んだりと、半年に一度活躍する程度です。

しかし、ここにきてカヤックを始めたくなり、このキャリアに長さ3.15m、重さ約30Kgのカヤックを、おそらく頻繁に載せることになりました。

これだけの重さがある長尺物だと、一人で載せたり降ろしたりするために、ルーフキャリアを上手に活用したくなり、そのために少し改造したくもなります。

とりあえずやりたいのが、横から積み込む時の支点となるサイドバーのローラー構造化です。

長尺物を載せやすいルーフキャリアに工夫する。タフレックのアルミキャリア

横側のパイプが回転してくれれば、カヤックを車の横に立てかけた後に、ルーフ上に持ち上げる時に、楽になること間違いありません。

そしてもう一点、手を加えておきたいのが、長尺物を積んだ時には不要になる、前後ガードパイプの取り外しです。

f:id:solocamptouring:20190210163611j:plain

このパイプは、もともと格納式ですが、格納状態がキャリアの天板の高さより、少しだけ飛び出します。

カヤックのような平らなものを載せた時には、このパイプに重量がかかってしまうので、積載物を一部だけで支持することを避けるためにも、取り去ってしまおうと考えました。

それでは、ルーフキャリアにこれらの改造をしていきます!

タフレックのアルミルーフキャリアを改造します

ルーフキャリアは、車から降ろした後に、ある程度バラバラにしておきます。

10mmおよび8mmのソケットツールと、プラスドライバーがあれば作業できます。

長尺物の積み込み用ローラーをつける

ホームセンターで、外形32mmのアルミパイプと、それに合うパイプクッションを入手してきました。

f:id:solocamptouring:20190210164427j:plain

アルミパイプは55mmの長さに切断して、切断面のバリをとるために、やすりをかけておきます。

切断したアルミパイプにパイプクッションを被せて、パイプの長さにあわせてハサミでクッションを切ります。

f:id:solocamptouring:20190210165223j:plain

このパイプを、タフレックのサイドパイプに被せるかたちで組み付ければ完成です。

私の場合は片側だけローラー化できればいいので、運転席側だけを改造しました。

なお、追加したアルミパイプの走行時ガタつき防止のために、結束バンドを使っています。

この部分については、もっといい方法を思いついたらバージョンアップしていきます。

前後のガードパイプの取り外し

サイドバーをローラー化するためにルーフキャリアをバラバラにした際に、前後のガードパイプも取り外しておきました。

すっきりとしたので、長尺物を載せてタイダウンベルトで固定する時にも、作業がしやすくなっています。

思いのほか簡単にできました

今回、カヤックという長尺物をルーフキャリアに載せたいという想いから、ルーフキャリアを改造してみました。

構想に数週間かけてしまいましたが、実際の作業は半日もかからずに終わる、簡単な改造でした。

アルミパイプが追加されましたが、もともとついていたガードパイプを取り外したので、どちらかというと軽くなり、キャリア自体の車への付け外しも楽になっています。

f:id:solocamptouring:20190301045134j:plain

サイドバーが丸パイプのタフレックのキャリアだからこそできた、少し重量がある長尺物を搭載しやすくするプチ改造ですが、一年以上使ってみて、その積みやすさに毎回助けられています!

 

冬のテント内でも安全な暖房器具。酸欠にならないファンヒーターを自作します

f:id:solocamptouring:20181217045809j:plain

ポリエステルやナイロンなど、火に弱くて気密性の高い素材で作られているドーム型テントでは、中で火器を使うことができません。

そのようなテントの中で安全に使える暖房器具は、電気で発熱するもの以外には、なかなか見当たりません。

100ボルトの交流電源がないキャンプ場でも、テント内で暖かくすごしたいので、バッテリー電源を使って省電力で駆動しつつも、しっかり暖かい暖房器具を、簡単に自作してみます。

テント内で安全に使える暖房機器が欲しい!温水ヒーターの自作

軽量ドーム型テント内での暖房器具に求めること

f:id:solocamptouring:20181217050337j:plain

ポリエステルやナイロン素材のテント内での暖房には、事故を起こさないという観点から、

  • 火(燃焼)は使わない
  • 高温にならない

ことが求めらます。

燃焼を伴う、ガスや灯油などを使う化石燃料ストーブや、薪や炭も使えません。

安全な暖房器具として思いつくのが電気で発熱するものですが、暖まるためには数十ワットが必要なため、コンセント電源がないキャンプ場ではバッテリーや発電機が必要になり、荷物が増えてしまいます。

そこで、発熱はテントの外の火力で行い、テント内に50℃以下の熱を送る方法を考えてみました。

f:id:solocamptouring:20181217050222j:plain

テント内を温める熱循環システム

テントの外でつくった熱をテント内に持ってくるための装置について、各機能ごとに考えてみました。

テント外での発熱部

電気を使わないテント外での熱源として、真っ先に思いつくのが焚き火やBBQです。

焚き火は、こまめな火の管理が必要なので、火に目が届きにくいテント内で、長時間過ごすことは不可能です。

火力が長持ちする炭を使う場合、酸素の流入をうまく制限できれは、数時間は放置できそうです。

火災がおきにくい周りが囲まれたもので、空気流入を制限して長時間にわたり炭を燃焼させやすい燃焼器具としては、ウッドストーブが使いやすそうです。

ウッドストーブを七輪がわりにして炭が使えることは、別に記事でも紹介しています。

www.solocamptouring.com

 自作する暖房器具も、ウッドストーブで炭を使って、熱源とします。

火災予防としては、上から可燃物が落ちてきた時などのガード用で、小型のアルミテーブルの下で使うようにします。

f:id:solocamptouring:20181217051221j:plain

熱をテント内に運ぶ

テントの耐熱性から、テント内に送る熱は50℃以下をねらいます。

熱を運ぶ液体としては、水がもっとも簡単に取り扱うことができそうです。

ここまでで、ウッドストーブと湯たんぽの間を、温水が行き来するイメージが浮かんできました。

テント内での放熱

ウッドストーブで温めた水を、テント内まで循環して放熱するとなると、放熱器としてラジエーターのようなものが必要になります。

ふと、夏場にパソコンが相当熱くなって対応策を調べた時に、水冷式のパソコンの存在を知ったのを思い出しました。

水冷式パソコンの部品を調べてみると、多くの小型のラジエーターがあり、今回のテント暖房用にちょうどいい大きさのものもあります。

テント内で使うラジエーターとポンプは、水冷式パソコン用の部品を使うことにします。

テントで使う暖房システムの全体像

 ウッドストーブの熱で水を温める方法については、最後まで悩みました。

外径9mm程度の銅管をコイル状にしてウッドストーブに置く方法にこだわったのですが、ちょうどいい形や大きさの完成品は見つけられませんでした。

また加工が楽なナマシ銅管は、少し予算オーバーなうえに、折れることなくコイル状に加工できるか心配です。

最終的に、放熱部同様に水冷式パソコンの部品を使って温水を作ることにしました。

高温になるCPUなどの熱を吸収するために使われる、アルミの水冷ブロックプレートです。

水冷PCのヒートシンクをキャンプの暖房に使う

このブロックプレートを、ウッドストーブの上に置いて循環水を温めます。

主な準備品をまとめてみます。

水冷PC用部品の流用

  • 水冷ブロックプレート
  • ラジエーター
  • ポンプ
  • リザーバータンク
f:id:solocamptouring:20181217052532j:plain
f:id:solocamptouring:20181217052540j:plain
f:id:solocamptouring:20181217052548j:plain

車用品の流用

  • 内径8mmの耐熱ホース (長さ2m)

その他の部品

  • 小型ファン(PC空冷用のもの)
  • システム固定用の小物類
  • 12Vバッテリー

発熱に電力は使わないので、消費電流は

  • ポンプ: 0.5アンペア
  • ファン: 0.2アンペア

で合計1アンペア以下となり、モバイルバッテリーでも動かせそうです。

今回は小型の12Vバッテリーを使って、出力制限が無い状態で動かしてみます。

暖房システムの組み立て

全ての部品が内径8mmのホースでつながるので、ホースを必要な長さで切断する以外には、特に部品の加工はしないで組み立てていきます。

放熱用ラジエーターは、裏面に金網を、表面には電動ファンを取り付けます。

f:id:solocamptouring:20181217052839j:plain
f:id:solocamptouring:20181217052847j:plain

ラジエーターモジュールは、暖房として時用する時に、ちょうどいい位置に固定することが重要です。

全てのパーツが収納できるプロテクションボックス内に、蝶番で取り付けました。

f:id:solocamptouring:20181217053552j:plain

そのプロテクションボックスですが、他の部品も入れて持ち運びができる大きさで、頑丈なものがキャンプに似合いそうです。

他の用途で使っていた、TRUSCOのプロテクターツールケースを転用することにしました。

暖房性能を確認してみました

ウッドストーブ内の炭に火をつけます。

実際にキャンプで使う時には、上側をアルミのテーブルでガードする予定です。

プロテクションボックス内の暖房器具を組み立てて、リザーバータンクから循環水を注入します。

ウッドストーブはテントから少し離れた場所に置いて使いたいので、ホースの長さは往復各1mで、合計2mです。

約1リットル強の水で、循環システムが満たされました。

テント内で安全に使える暖房機器。ソロキャンプ用のヒーターを自作します。

ヒートシンクをウッドストーブ上に置いて、電動ファンとポンプの電源を入れてみます。

5分もたたずに循環水の温度が上がり、ラジエーターを通したファンの風が、暖かくなってきました。

youtu.be

温風は、おそらく30~40℃くらいです。実際にキャンプで使う時には、正確に計測する予定です。

ウッドストーブ上のヒートシンクは、ラジエーターで温度が下がった水が常に流れ込むため、手でも触れる温度を保っています。

思惑どおりの暖房効果を得られたので、次の冬季キャンプで使ってみます。

スマホ見ながらパソコン作業したい!ノートPCスタンドのプチ改造

持ち運びや移動が楽なタブレットパソコンを、家の中でさらに使いやすくするために、スタンドを導入してカスタマイズしました。

ノートPCスタンドをカスタマイズして、モバイルパソコンでの作業が快適に

私のタブレットパソコンの使い方紹介

参考で、私のタブレットパソコンは、LenovoのYOGA BOOKです。

軽くてコンパクトなので、外出時の携帯に便利なだけでなく家の中でも、机、テーブル、ソファー、ベッドなど、どこでもパソコン作業ができる点が気に入っています。

家の中でタブレットパソコンを使って作業する時には、数時間ごとに気分と姿勢を変えて、ソファーに深く腰掛けたり、床に座り込むようなことがあります。

そのような姿勢の時に、膝の上にパソコンを置いて作業すると、位置が低いために首などに負担がかかります。

この苦しい体勢から脱却できるように、ノートパソコンスタンドを導入することにしました。

どこでも使えるノートパソコンスタンドを選択

ノートパソコンスタンドを選ぶにあたり、重要視したのは、

  • 収納時にコンパクトになる
  • 軽い
  • いろんなパターンに応用できる

ことです。

いろいろなスタンドを比較した結果、このタイプを選びました。

 

選択時に重要視したポイントについて、実際に使ってみて気づいた事などを紹介いたします。

収納性

折り畳みや角度調整は、脚の関節部の中心にあるボタンを軽い力で押しながら角度を変えます。

角度の目盛りは、左右の関節を同じ角度にするのに便利です。

f:id:solocamptouring:20180918051141j:plain

関節を全て折り畳めば、天板とほぼ同じ厚さまで薄くなるので、家具と壁の隙間スペースなど、部屋の広さを阻害しない場合に収納できます。

軽さ

大部分の部品はアルミでできており、総重量は約1Kgです。

片手で難なく持ち運ぶことができます。

多くの使用パターン

脚の関節3ヶ所で、角度だけでなく、高さも自由に変えられます。

天板に軽く手を置いてキーボードやマウスを使っていますが、関節の剛性は充分で、作業時に天板が揺れる事はありません。

多関節の角度を変えて脚を伸ばせば、高さ約50cmのPCテーブル風になります。

f:id:solocamptouring:20180918202942j:plain

一番低い状態では、卓上でキーボードの角度を傾けて使いたい時にも応用できます。

f:id:solocamptouring:20180918202106j:plain

 

選択の決め手は価格

紹介してきたように、多くのパターンに融通が効くにもかかわらず、角度だけ変えられる卓上用スタンドと大差ないお値段だったので、迷わずこれを選びました。

なお、私が入手したPCスタンドには、脚の穴にネジでつける、マウス用のプラスチックのボードが付属しています。

便利そうですが、スタンドを収納する時など、脚を折り畳むときには取り外さないといけません。

f:id:solocamptouring:20180918051227j:plain

 スタンドを頻繁に収納する私は、付属のマウスボードは使用しないことにしました。

タブレットパソコンが10.1インチと小さいので、天板の余ったスペースでも、余裕をもってマウスを使えます。

ノートパソコンスタンドをカスタマイズします

これまで紹介している写真で既にお気づきだと思いますが、もっと便利に使えるようにカスタマイズしました。

PCの滑り防止

入手したノートPCスタンドは、天板を斜めにして使う時のパソコン滑り落ち防止用として、プラスチックのストッパーが2個が付属しています。

f:id:solocamptouring:20180918051426j:plain

厚みがあるパソコンを使うことを考慮したのだと思いますが、このストッパーは薄いパソコンで使うと、高さ方向の飛び出し量が多くなり、キーボードをうつ時に邪魔だったり、手首に当たってしまったりします。

そこで、このストッパーは使わずに、両面テープ付きのスポンジを貼って、パソコンが落ちるのを防止するとともに、傷付きも防ぐことにしました。

f:id:solocamptouring:20180918051524j:plain

パソコンの上や横の外形に合わせた位置にもスポンジを貼って、四方への滑りを防止しています。

スマホを見ながら、パソコン作業できるようにします

通常のパソコンで作業する際は、モニターが複数あると便利です。

タブレットパソコンで作業するときでも、似たような環境を作りたいと思います。

スマホの画面を見ながら作業できるように、スタンドの右上でマウス用スペースの奥の方に、スマホホルダーを取り付けます。

f:id:solocamptouring:20180918051649j:plain

使わずに余っていた、おそらく車のアクセサリー用のユニバーサルステーに、クリップタイプの100均スマホホルダーをボルト締めして、天板に貼り付けました。

f:id:solocamptouring:20180918051703j:plain

スマホやiPodタッチで、調べものをしたり動画を見たりしながら、PC作業ができるようになりました。

ちょっとしたカスタマイズですが、小さな画面が増えただけで、作業中の充実感が増したように感じます。

ノートパソコンスタンドは、とっても便利だと実感

ノートPCスタンドがあると、タブレットパソコンを家中どこでも快適便利に使えます。

一番ありがたみを感じているのはソファーに深く座ってパソコン作業する時で、前かがみになる事がなくなったので、たいへん楽な姿勢で作業を続けられます。

私のように、いろんな場所で高さや姿勢を変えながらパソコン作業する場合には、おすすめしたいスタンドです。

人の動きに同調する1/fゆらぎのつくりかた。USB扇風機を改造してみます(動画あり)

USB扇風機を癒しの1/fゆらぎ風に改造して、パソコン前スペースを快適化

空調の効いた屋内でも、いつも風を感じていたい!ので、パソコンのUSB端子を電源とする小型扇風機を使ってみる事にしました。

せっかくなので、自然風のような1/fゆらぎの風を感じられるように改造してみます。

1/fゆらぎについて

1/fゆらぎとは、振幅が周波数 f に反比例する波の集合波形です。

ゆらぎは平均値からの変動幅なので、周波数が小さい、ゆっくりとした波の成分ほど大きく変動するという意味になります。

人体も1/fゆらぎをしていて、周りの1/fゆらぎ を感じると、共鳴して精神安定などの効果があると考えられています。

USB電源のミニ扇風機

改造ベースとなる扇風機は、しっかり風を感じられて静かなものを選びます。

飛行機でSBも採用例がある二重反転プロペラ(コントラペラ)で、効率よく空気を押し出すものが良いようです。

たまたま、実際に使っている人のパソコン前を、静かなので扇風機に気付かずに通った時に、予想外の風量に驚かされたこともあり、写真の二重反転プロペラを持つ扇風機を選びました。

f:id:solocamptouring:20180719045658j:plain

リズム時計製のコントラペラ扇風機で、他にも「くまのプーさん」や「ミッキー」をデザインモチーフとしたバージョンもあります。

私は、一番安かったオーソドックスな形の薄紫色をチョイスしました。

この扇風機は、風量をハイ/ローの二段階に切り替えられます。

ローはそのまま使えるようにして、ハイに切り替えると1/fゆらぎの風になるように改造します。

Arduino と赤外線センサーで1/fゆらぎをつくる

1/fゆらぎの風は、扇風機と人との距離に応じて変動するようにします。

基本は、距離が

  • 近いと弱風
  • 遠いと強風
  • さらに遠いと停止(OFF)

にします。

赤外線センサーは、正面の平面体に対しては安定して距離を測れますが、服などの凹凸物に対しては少しばらつきがある測定結果になります。

これを逆手にとって、ばらつきが

  • 大きい時は、ゆっくり風量を変える
  • 小さい時は、早く風量を変える

ことで、1/fゆらぎの風をつくります。

これをモーターの回転数を変化させて実現するために、Arduinoを使って赤外線センサーで計測した扇風機前のもの(人)との距離から、モーターの目標スピードと、目標スピードに変わるまでの時間を決めて、PWM制御のパルスで出力します。

PWM(Pulse width modulation、パルス幅変調)は、電圧一定で、周期も一定のパルス波形です。このパルスを電源に使いつつ、ONパルスの幅を変える(=デューティ比を変える)と電圧の平均値が変わるため、結果として電圧を変えた時と同じ効果があります。

Arduino を使う回路

回路図は、Fritzingで作成しました。

f:id:solocamptouring:20180722133259j:plain

赤外線センサーGP2Y0E02Aの接続

シャープの、赤外線式の測距モジュールGP2Y0E02Aには、4本の端子があります。

  1. VDD(3.3V電源)
  2. GND
  3. Vout(出力)
  4. GPIO1

1番はArduinoの3.3Vに、2番はGNDに接続します。

3番のVoutは、電圧で距離情報を返してくるので、Arduinoのアナログピン(回路図ではA3ピン)に接続します。

4番のGPIO1は、電圧がVDD付近であれば計測、GND付近であればスタンバイ(計測しない)モードとなります。Arduinoのデジタルピン(回路図ではD5ピン)からの5V信号を、抵抗3個とダイオードで約3.3Vに減圧して接続します。

赤外線センサーGP2Y0E02Aの接続(USB扇風機の癒し改造)

モーターの接続

PWMで速度を変えるため、Arduinoのデジタルピン7からパルス信号を出力します。

パルス信号はトランジスタのベースに送ってスイッチングして、モーターに電流供給します。

パルスがLOW(0V)の時に、モーターの逆起電力からトランジスタを守るために、ダイオード(D1)を、モーターと並列に使用します。 

トランジスタとベース抵抗値の計算

トランジスタ2SD882を使う回路設計

使用するUSB扇風機は、商品説明によると定格電流210mAです。

トランジスタは、余裕を持って作動させられる2SD882を使います。

  • Ic=210mA
  • hFE=100倍
  • VBE=0.8V

の値を使って、ベースに接続する抵抗値を求めます。

RB=(5-0.8)/(0.21/100)=2000Ω

2000Ωの抵抗RBを使用して、トランジスタのベースとArduinoのデジタルピン(D7)を接続します。 

作動を安定させるため、抵抗RBと平行にコンデンサを、またトランジスタのBE間に抵抗を入れておきます。

扇風機から、そのまま使う電子部品

f:id:solocamptouring:20180719050203j:plain

使用するUSB扇風機の、ハイ/ロー切り替えの元回路は、

  • ハイ側: 電源は、2個の直列配置モーターに直接供給
  • ロー側: 2個の定電流ダイオード(直列)を通して、2個の直列配置モーターに電源供給

となっていました。

ロー側の定電流ダイオードは、電源のプラス側からマイナス側に移設して、そのまま使います(回路図では、2個をまとめてD4と記載)。

スイッチをハイ側に切り替えると、Arduinoの電源が入り、トランジスタを通してPWMでモーターを駆動するように、回路を作ります。

USB扇風機にArduinoを搭載して、癒しの1/fゆらぎ風に改造

1/fゆらぎ扇風機のスケッチ(プログラム)

1/fゆらぎのつくりかた

赤外線測距センサーで計測した距離は、100回測定した平均値を使います。

得られた距離に応じて、

  • 5〜60cm: PWMのデューティ比を50%〜100%に変化
  • それ以外: 停止

として、目標速度と、そこに到達するまでの時間を設定します。

また、目標速度に到達するまでの間も距離を測定して、その時点におけるデューティー比のゆらぎ(計算値と、距離測定値から置き換えた数値の差を1/3したもの)を変化量として瞬時に加えます。

デューティー比のゆらぎが負(マイナス)の場合は、数値に応じて短い間、電源を遮断して即答させます。

距離が60cmより遠い場合は、人(私)が扇風機前から席を外したと判断して停止し、以後1秒毎に距離測定して、人が戻ってきたら再開します。

USB扇風機をArduinoで改造

スケッチの紹介

int trigPin = 5;
int pwmOutput = 7;
int distResult = 0;
long distA = 0 ;
int i = 0 ;
int j = 0 ;
int frequencyWindChange = 0 ;
int speedOutput = 0 ;
int speedCurrent = 50 ;
int speedNowTarget = 50 ;
int speedOldGoal = 50 ;
int speedGoal = 50 ;
int speedAdjust = 0 ;
int speedAdjustParameter = 3 ;

void setup() {
pinMode(trigPin, OUTPUT); 
pinMode(pwmOutput, OUTPUT); 
delay (100);
digitalWrite(trigPin, HIGH);
}

void loop() {
  
     long voltAns ;
     voltAns = IDMread(3)  ;           // アナログピン3番のセンサーの値を読込む
     long distAns1 = map(voltAns,0,1023,0,500) ; // 電圧値に変換する(0から5V)
     long distAns2 = map(distAns1,55,220,50,4) ;  // 電圧値から距離に変換する(0.55から2.2Vを50から4cm)
     int distResult = distAns2; 

  if(distResult > 60){
  analogWrite(pwmOutput, 0) ;
  speedOldGoal = 50 ;  
  delay(1000) ;
  }else{
  speedGoal = map(distResult,0,65,50,100) ;
  frequencyWindChange = abs(speedGoal - speedOldGoal) ;

    for (j=0 ; j < frequencyWindChange; j++) {
   speedNowTarget = speedOldGoal + (speedGoal - speedOldGoal)/frequencyWindChange*j ;

      
    long voltAns ;
     voltAns = IDMread(3)  ; 
     long distAns1 = map(voltAns,0,1023,0,500) ; 
     long distAns2 = map(distAns1,55,220,50,4) ; 
     int distResult = distAns2; 
     
     speedAdjust = (map(distResult,0,65,50,70) -  speedNowTarget)/speedAdjustParameter ;
     speedOutput = 255*(speedNowTarget + speedAdjust)/100 ;
     if(speedAdjust < 0){
      analogWrite(pwmOutput,0);
      delay(70*abs(speedAdjust));
     }
     analogWrite(pwmOutput,speedOutput);
     delay(200);
     } 
     
   speedOldGoal = speedGoal ;  
  }
}

// 赤外線測距モジュールから読み込む処理
int IDMread(int PinNo) {
     distA = 0 ;
     for (i=0 ; i < 100; i++) {
          distA  = distA + analogRead(PinNo) ;   // アナログピンから読取る
     } 
     return distA/100 ;                        // 100回の平均値を返す
}

癒しの風を感じてみます

扇風機のプロペラ回転数は細かく変動しています。時々、自然に風のような、ゆっくりとした大きな変動もあり、1/fゆらぎらしくなっています。

回転数に応じてプロペラの残像が刻々と変化するので、ぼ~っと見ていても飽きません。

また、席をはずして戻ってきた時には、停止状態から自動で動き始めるので、「おかえり!」と言われたようで、少し幸せな気持ちになります。

youtu.be

ちょっとした改造ですが、Arduinoと測距センサーを使うことで、オフィスなどの密閉された屋内空間でも、自然のような風のそよぎを感じる事ができて、眠気を誘うほど快適になります。

LEDサウンドレベルメーターの自作。RGB LEDのWS2812Bをナイトライダー風に光らせる

LEDサウンドレベルメーターの自作。WS2812Bをナイトライダー風に光らせる

ナイトライダーのK.I.T.T.をご存知ですか?

私と同年代の方々は、頭の中でテーマソングの演奏が始まってしまったのではないでしょうか。

おさらいしておくと、ナイトライダーは80年代のアメリカのドラマで、主人公マイケル.ナイトと彼に仕える人工知能を搭載した車の話です。

K.I.T.T.は人工知能の名前で「キット」と呼ばれていました。調べてみてわかったのですが、Knight Industries Two Thousand(ナイト2000)の頭文字をとったものだったそうです。

今回再現するのは、キットが喋る時に連動するボイスインジケータ の光り方だけで、ディテールにはこだわりません。

ドラマでは「了解です、マイケル」などたくさん喋っていましたが、私は運転していて話しかけられても照れるので、キットの声は再現しません。

かわりに、車内の音の大きさに反応するようにして、音楽や人の声にあわせて光るようにします。

市販品があった!

 今回Arduinoで自作しようと決意する前に、市販品で同じようなものがないか探してみたところ、過去に販売されていました。

シガーソケットに差し込むタイプのUSB電源(2個)ですが、いくつかのパターンで喋るようです。

しかし、もう生産されていないようで、日本でもアメリカでもオークションサイトで高値で取引きされています。

簡単に入手できれば、ボックスだけ使って光り方はArduinoで制御したかったのですが、残念です。

Arduinoと接続するモジュール

 ボイスインジケータ を再現するにあたり、WS2812Bを8x8個並べたカラーLEDモジュールと、サウンドセンサーモジュールを使います。

LEDはバーグラフタイプのモジュールの方が実物に近いのですが、ちょうどいい大きさのものが見つからなかったので、使いやすいWS2812Bで進めます。

 サウンドセンサーで検知した音の大きさに応じて、キットのように上下方向にグラフを立てて、カラーLEDモジュールに表示します。

 表示イメージとパターン

 8x8マトリックスLEDのうち6x8個を使って、ボイスインジケータを再現します。

 実物同様の赤色だけで光るパターンの他に、他の色で光ったり、余っている2x8個を違う光り方で装飾したりするパターンにも切り替えられるようにします。

パターン① KITTを再現します(赤色)。

ナイト2000のボイスインジケータをArduinoとWS2812Bで再現

パターン② KITT風で、色を徐々に変化させます。

ナイト2000のボイスインジケータをArduinoとWS2812Bで再現

パターン③ パターン①に加え、3本のインジケーターの間の余っているスペースに光を流します。今回は上下ですが左右に流れる光こそナイトライダーのイメージそのものですね。

パターン④ パターン②に加え、3本のインジケーターの間の余っているスペースに光を流します。

f:id:solocamptouring:20180408122511j:plain
f:id:solocamptouring:20180408122530j:plain

パターン⑤ KARRも再現します(本当はアンバーですが、私の趣味で緑色)。

パターン⑥ KARR風で、色を徐々に変化させます。

KARRのインジケータをArduinoとWS2812Bで再現
パターン⑤(左)と、パターン⑥(右)

パターン⑦ パターン⑤に加え、3本のインジケーターの間の余っているスペースに光を流します。

f:id:solocamptouring:20180408123033j:plain
f:id:solocamptouring:20180408123048j:plain

 

回路図

ナイト2000のボイスインジケータをArduinoとWS2812Bで再現

Fritzingで回路図を作成しました。

マイクモジュールは、MAX4466を搭載したものを使っています。

可変抵抗(ボリューム)を使い、表示7パターンを切り替えられるようにします。

スケッチ(プログラム)は、記事の最後に掲載しておきます。

完成しました!

 まずブレッドボード上で回路を組んで、ipodタッチで出した音をマイクで拾いながら、マイク感度とLED残像調整をしてスケッチを完成させました。

ナイト2000のボイスインジケータをArduinoとWS2812Bで作成

 

完成後の作動状況は動画で確認できます。

7種類の光り方だけ見たい場合は、2:37くらいから確認してみてください。


Arduino project #3 「サウンドレベルメーターをWS2812Bでつくる」Sound level meter with WS2812B

 

 

今回作ったものは、車のオーバーヘッドコンソールに組み込んで光らせますが、その場所には既に、以前の記事で紹介した8x8LEDが搭載されていて、レインボーカラーなどで光っています。

www.solocamptouring.com

 今回のナイトライダー化は、既に搭載されているArduinoにマイクモジュールを追加して、スケッチ(プログラム)を書き換えるだけなので、車での作業はあっという間に終了しました。

f:id:solocamptouring:20180415185857j:plain

スケッチを紹介します

簡単なスケッチ(プログラム)で思い通りの光らせ方ができるGitHubのFastLEDライブラリを使います。

LED光の残像効果は、スケッチ内のfadeToBlackBy()の部分で調整しています。

#include "FastLED.h"
#define DATA_PIN    4
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
#define HEIGHT 8
#define WIDTH 8
#define NUM_LEDS HEIGHT*WIDTH
CRGB leds[NUM_LEDS];
#define BRIGHTNESS  3

const int sampleWindow = 20; // Sample window width in mS 
unsigned int sample;
int volts;
int micPin = 2;
int selectPin = 5;
int val = 0;
int numLedsToLight = 0;
int numLedsSide = 0;

void setup() {
  delay(3000); //delay for recovery
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS); 
}

// List of patterns to cycle through.  Each is defined as a separate function below.
typedef void (*SimplePatternList[])();
SimplePatternList gPatterns = { kittOriginal,  kittColor, kittOriginalWithSinelon,  kittColorWithSinelon,  karrOriginal,  karrColor,   karrOriginalWithSinelon };

uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current
uint8_t gHue = 96; // rotating "base color" used by many of the patterns
  
void loop()
{
   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level
   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;
 
   // collect data for a while
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(micPin);
      if (sample < 1024)
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save the min levels
         }
      }
   }
   peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
   volts = (peakToPeak*5/130); // adjusting to the output of the mic 


 val = analogRead(selectPin); //check the volume to choose the pattern
      if (val < 150) {
    gCurrentPatternNumber = 0;
       } else if (val < 300){
    gCurrentPatternNumber = 1;
       } else if (val < 450){
    gCurrentPatternNumber = 2;
       } else if (val < 600){
    gCurrentPatternNumber = 3;
       } else if (val < 750){
    gCurrentPatternNumber = 4;
       } else if (val < 900){
    gCurrentPatternNumber = 5;
       } else {
    gCurrentPatternNumber = 6;      
       }

 
  gPatterns[gCurrentPatternNumber](); // Call the current pattern function once, updating the 'leds' array
  FastLED.show();  // send the 'leds' array out to the actual LED strip

  EVERY_N_MILLISECONDS( 300 ) { gHue++; } // slowly cycle the "base color" through the rainbow
}

void sinelon()
{
  fadeToBlackBy( leds, NUM_LEDS, 8);
  int pos = beatsin16(13,16,23);
  leds[pos] += CHSV( gHue, 255, 192);
}
void sinelonTwo()
{
  fadeToBlackBy( leds, NUM_LEDS, 8);
  int pos = beatsin16(13,40,47);
  leds[pos] += CHSV( gHue, 255, 192);
}

void onecolorsinelon()
{
  fadeToBlackBy( leds, NUM_LEDS, 8);
  int pos = beatsin16(13,16,23);
  leds[pos] += CRGB::MidnightBlue;
}

void onecolorsinelonTwo()
{
  fadeToBlackBy( leds, NUM_LEDS, 8);
  int pos = beatsin16(13,40,47);
  leds[pos] += CRGB::MidnightBlue;
}

void kittOriginal() 
{
       if(volts < 4){
        numLedsToLight = volts; 
          if(volts < 1){
          numLedsSide = 0; 
          }else{
          numLedsSide = numLedsToLight-1; 
          }
       }else{
        numLedsToLight = 4;
        numLedsSide = 3;      
       }
        fadeToBlackBy( leds, NUM_LEDS, 20);
        for(int led = 4-numLedsSide; led < 4; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 4; led < 4+numLedsSide; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 12-numLedsSide; led < 12; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 12; led < 12+numLedsSide; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 28-numLedsToLight; led < 28; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 28; led < 28+numLedsToLight; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 36-numLedsToLight; led < 36; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 36; led < 36+numLedsToLight; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 52-numLedsSide; led < 52; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 52; led < 52+numLedsSide; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 60-numLedsSide; led < 60; led++) { 
            leds[led] += CRGB::Red; 
        }
        for(int led = 60; led < 60+numLedsSide; led++) { 
            leds[led] += CRGB::Red; 
        }
}

void kittColor() 
{
       if(volts < 4){
        numLedsToLight = volts; 
          if(volts < 1){
          numLedsSide = 0; 
          }else{
          numLedsSide = numLedsToLight-1; 
          }
       }else{
        numLedsToLight = 4;
        numLedsSide = 3;      
       }
        fadeToBlackBy( leds, NUM_LEDS, 20);
        for(int led = 4-numLedsSide; led < 4; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 4; led < 4+numLedsSide; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 12-numLedsSide; led < 12; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 12; led < 12+numLedsSide; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 28-numLedsToLight; led < 28; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
        for(int led = 28; led < 28+numLedsToLight; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 36-numLedsToLight; led < 36; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 36; led < 36+numLedsToLight; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 52-numLedsSide; led < 52; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 52; led < 52+numLedsSide; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 60-numLedsSide; led < 60; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
        for(int led = 60; led < 60+numLedsSide; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
}

void kittOriginalWithSinelon() 
{
  sinelon() ;
  sinelonTwo() ;
  kittOriginal() ;
}

void kittColorWithSinelon() 
{
  onecolorsinelon() ;
  onecolorsinelonTwo() ;
  kittColor()  ;
}
void karrOriginal() 
{
       if(volts < 4){
        numLedsToLight = volts; 
        numLedsSide = volts;  
        }else{
        numLedsToLight = 4;
        numLedsSide = 4;      
        }
        fadeToBlackBy( leds, NUM_LEDS, 20);
        for(int led = 8-numLedsSide; led < 8; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 0; led < 0+numLedsSide; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 16-numLedsSide; led < 16; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 8; led < 8+numLedsSide; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 28-numLedsToLight; led < 28; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 28; led < 28+numLedsToLight; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 36-numLedsToLight; led < 36; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 36; led < 36+numLedsToLight; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 56-numLedsSide; led < 56; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 48; led < 48+numLedsSide; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 64-numLedsSide; led < 64; led++) { 
            leds[led] += CRGB::Green; 
        }
        for(int led = 56; led < 56+numLedsSide; led++) { 
            leds[led] += CRGB::Green; 
        }
}
void karrColor() 
{
       if(volts < 4){
        numLedsToLight = volts; 
        numLedsSide = volts;  
        }else{
        numLedsToLight = 4;
        numLedsSide = 4;      
        }
        fadeToBlackBy( leds, NUM_LEDS, 20);
        for(int led = 8-numLedsSide; led < 8; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
        for(int led = 0; led < 0+numLedsSide; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
        for(int led = 16-numLedsSide; led < 16; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 8; led < 8+numLedsSide; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
        for(int led = 28-numLedsToLight; led < 28; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 28; led < 28+numLedsToLight; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
        for(int led = 36-numLedsToLight; led < 36; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
        for(int led = 36; led < 36+numLedsToLight; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
        for(int led = 56-numLedsSide; led < 56; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 48; led < 48+numLedsSide; led++) { 
            leds[led] += CHSV( gHue, 255, 192); 
        }
        for(int led = 64-numLedsSide; led < 64; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
        for(int led = 56; led < 56+numLedsSide; led++) { 
            leds[led] += CHSV( gHue, 255, 192);
        }
}
void karrOriginalWithSinelon() 
{
  sinelon() ;
  sinelonTwo() ;
  karrOriginal() ;
}

 

 

シフトチェンジの邪魔にならない軽自動車用アームレストを自作(JB23ジムニー)

シフトチェンジの邪魔にならない軽自動車用アームレストを自作(JB23ジムニー)

軽自動車のJB23ジムニー、運転席の左側にはアームレストがなく、高速道路などの長距離運転では左手が疲れてきます。

ハンガリーのRati製のアームレスト"Armster 2" がネットでの評判が良く、作りも良さそうで喉から手が出るくらい欲しいのですが、私の小遣い額を上回っていて今すぐ入手できそうにありません。

まずはアームレストのうれしさを確かめてみよう!と思い、見栄えは二の次でサクサクと自作してみることにしました。

自作コンセプト

一番のねらいはシフトチェンジしなくていい高速道路での走行時にヒジを置けることです。自然な位置にヒジを置けて、その時の手のひらはトップギアに入っているシフトレバー上に置けるようにします。
 
次に大事なのが、街中走行時のシフトチェンジの邪魔にならないようにすることです。シフト操作時にヒジが当たらないように設置します。
 
せっかくアームレストをつけるので、中に収納スペースも作ります。
 
そして急ブレーキなどでアームレストが車内で飛んでケガをする事がないように、しっかり固定します。ポリシーとして車両の見える部分に穴はあけないようにしているので、何かに引っかけるか両面テープを使って、固定を実現します。

構造を考える

構造を決めるにあたって、コンセプトの①と②を両立するために、アームレストの可動機構が必要になります。

アームレストを跳ね上げるかスライドするかの2択ですが、跳ね上げ式は急ブレーキでも落ちてこない構造実現に手間がかかると判断し、スライド式とします。

街中走行時の自作アームレストの状態
高速走行時の自作アームレストの状態
街中走行時(左)と高速走行時(右)のアームレスト状態

スライド式のヒジ置き面は、その下に設ける収納スペースのふたを兼ねるようにして、コンセプト③も実現します。


コンセプト④の固定については、減速Gに耐えられることを最重要項目とします。アームレストをコンソールの後面に固定できればいいので、下の図のようにコンソールと床面の間に金具を差し込みます。

f:id:solocamptouring:20180311082229p:plain

コンソール上面は両面テープで固定して、アームレストが前後左右にずれないようにします。

作ってみました

 工作レベルで作るので、簡単に加工できる木の板を使います。

車と人(=私)に合わせて寸法を決めてボックス形状を組み上げたら、缶スプレーで黒色に塗った後に見える面だけフェルトを貼り付けます。

 

ヒジ置き部のスライド構造には引き出し用のアイワのスライドレールを使いました。 

f:id:solocamptouring:20180311093050j:plain

 閉じている状態での固定には家具の磁石部品を使います。

f:id:solocamptouring:20180311093834j:plain
f:id:solocamptouring:20180311093839j:plain
下から写した閉状態(左)と開状態(右)

完成した全体写真も紹介いたしますが、普段見えない部位は多いに手抜きをして作っているので、見苦しい状態です。

軽自動車用アームレストを自作

裏面に木でつけた凸形状は、コンソールのカップホルダー凹形状に嵌るようにして、組付け後のズレ防止の役割を持たしています。

車に取り付けました

まずは、アームレストを使っていない時の状態を紹介します。

f:id:solocamptouring:20180311094342j:plain
f:id:solocamptouring:20180311094354j:plain
ヒジ置きが閉じた街中走行状態

上にのせているペリカンケースの底面には磁石をつけて、ヒジ置き面につけた鉄板に磁力で固定しています。

次に、アームレストを使うために前に出した状態です。

上と下の写真で、シートサイドとアームレストの位置関係の違いが見てとれます。

f:id:solocamptouring:20180311094407j:plain
f:id:solocamptouring:20180311094419j:plain
ヒジ置きを前に出した高速走行時の状態

ヒジ置きとして使う時は、磁力で固定しているペリカンケースも使って、ヒジがのる面の位置と高さを微調整しています。

 私の体形にあわせて作ったため、シフトチェンジスペースとアームレストの機能が絶妙な位置関係で両立しています。

高速道路での長距離走行でも腕が疲れにくくなったばかりでなく、軽自動車では貴重な追加の収納スペースをつくることができました。

内装を カーボン調にするお手軽DIY。JB23ジムニーのエアコン操作パネル

 

3MのダイノックでJB23ジムニーのエアコン操作パネルを豪華にするお手軽DIY

ちょっとプラスチック感が漂うJB23ジムニーのエアコン操作パネルを、簡単にカーボン調や木目調などの豪華仕様にするDIYを紹介します。

上の写真は、カーボン調にした状態です。作業手順で紹介する写真もDIY完了後に撮りなおしたものなので、パネルは既にカーボン調になっています。

作業手順

年式によって仕様に差があるので作業内容に少し違いがありますが、作業の流れは同じです。

センターパネル取り外し

最初に、灰皿のスペース内にある3本のスクリューを外します。

f:id:solocamptouring:20180309083315j:image

灰皿スペースの鉄板が外れました。

f:id:solocamptouring:20180309083447j:image

センターパネルは、車両後ろ方向に引くとツメが外れます。下の灰皿の開口部から始めて、順に上のツメを外していくと簡単に外れます。

この時点ではシガーソケットとハザードスイッチのコネクターが繋がったままなので、あまり強く引く事はせず、センターパネルが数センチ浮くぐらいまでで止めておきます。

 

センターパネルのツメが全部外れたら、シガーソケットとハザードスイッチのコネクターを抜きます。

シガーソケットのコネクターは引き抜くだけで外れます。

f:id:solocamptouring:20180309092711j:image

ハザードスイッチのコネクターはツメでロックしています。白いコネクターのツメ根元の出っ張り形状を押しながら抜きます。

f:id:solocamptouring:20180309093033j:image

センターパネルが外れました。

f:id:solocamptouring:20180310211414j:plain

エアコン操作部のパネルを外す

エアコン操作ユニットを外してから作業してもいいのですが、壊さないように注意して作業すれば、操作ユニットは付けたままで今回模様替えするパネルだけ取り外せます。

まずは内外気の切り替えノブを車両後ろ方向に引き抜きます。

f:id:solocamptouring:20180310044419j:plain

今回豪華仕様にするパネルは、上3カ所と下3カ所のツメでユニットにとまっています。

上の端のツメから順番にマイナスドライバーなどで、優しく外していきます。パネルは力を入れすぎると壊れますが、反面たわみやすいので一度外したツメは手を離しても元に戻らず、順番にツメを外していくのは簡単です。

全てのツメが外れたら、パネルが外れます。

f:id:solocamptouring:20180309121616j:image

写真は完了状態ですが、外したパネルにカーボン調などのシートを貼ります。

最初に少し大きめに切り出したシートをパネルに被せて、凹凸部はドライヤーをあてて伸ばしつつ一旦貼ってしまいます。

その後で、外形と穴部分の余分なシートをクラフトナイフなどで切り落とします。

パネルにシートを貼り終わったら、外す時とは逆の手順で部品を組み付けて完成です。

カーボン調などのシートについて

今回のDIYはほぼ平坦面への貼り付けなので、カー用品店で売っているシートでも失敗しないと思います。

 

最初は簡単に貼れる部位でも、一カ所貼ってみて上手くいくと他の部位にもやってみたくなります。平坦面だけでなく曲面の部品も衣替えしたくなった場合には、3Mのダイノックを使うことをお勧めします。

ダイノックは種類が豊富で、カーボン調や木目調の他にもアルミ調などの多くの柄があります。

シート自体も(一部の柄を除き)よく伸縮するので、ドライヤーを当てて作業すると貼られる物の形状に追従させながら貼る事ができます。

さらに、粘着面と粘着面がくっていてしまったり折れ線が入ってしまっても、ドライヤーを当てることにより高い確率で再生可能です。

 色や柄も豊富にラインナップされています。一例です。

3M™ ダイノック™ フィルム

余ったシートでスマホカバーの模様替え等をしても楽しめます。

ジムニーの天井の棚をイレクターパイプとカーゴネットと板で自作 (JB23)

JB23ジムニーの天井にイレクターパイプで棚をつくる

収納スペースの少ないジムニーの天井に棚をつけて、車内スペースを有効活用します。

車中泊用のベッドを自作する場合にもよく使われている矢崎化工のイレクターパイプで骨格をつくり、板やネットで収納スペースを生み出しました。

 棚のレイアウト

JB23ジムニーの天井にイレクターパイプで棚をつくる
棚の配置と、イレクターパイプの取付先となるアシストグリップ

イレクターパイプの車体への取り付けには、上右の写真のアシストグリップの取り付け穴を使います。

イレクターパイプは前から後ろまで1本で貫通させる人や、後ろだけ設置する人などに分かれますが、私は前と後ろで分割しつつ前後とも設置します。

パイプの長さは前側は30cm後ろ側は60cmを選択し、ちょうどいい感じでおさまりました。

イレクターパイプの取り付け方法

JB23ジムニーの天井にイレクターパイプをジョイントで取り付ける

ジョイント品番J-102Bを使います。ただしジョイントに元からある小さな取付穴(Φ3.6)は使いません。取り付け後に隠れる位置に、M6ボルト用の穴をドリルであけて使います。

Φ3.6の穴があいているフランジ部は切り落とした方が、車に取り付け後の仕上がりが綺麗ですが、残っていても少し天井に跡がのこるだけで私は気にならないのでそのままにしておきました。

M6ボルトは長さ25mmのものを使いましたが、20mmでも大丈夫です。

JB23ジムニーの天井にイレクターパイプで棚をつけるためのボルト

 10mmの工具は片口めがねレンチしか持っておらず、狭い隙間から少しづつ締めこんでいくのは大変でしたが、なんとか取り付け完了できました。

f:id:solocamptouring:20180218132611j:plain

 後ろ側のパイプにネットをはる

 使いたかったのは、ラリーカーのヘルメットハンモックのような、ベルトを編んだものです。しかし安価で入手できるものがなく、自作するのも大変そうだったので諦めました。

 第一希望のものが入手できなかったので、とりあえず100円ショップの自転車用ネットを4個つないで使っていました。

しかし、上に載せたサンシェードのような軽いものですら、走行中にトランポリン状態になる事が気になりました。

f:id:solocamptouring:20180218141533j:plain

 後日、カーゴネットを追加して使用したところ適度な弾力性となり、今ではサンシェードの他にもポロシャツや帽子等を載せて使っています。

前側のパイプにあう棚を作る

左右のパイプ間ピッチ(90cm弱)にあわせた棚板は、少しでも軽くしたかったので5mm厚の合板を20mmの角材で補強して作りました。

車両に仮付けしてみて気付いたのですが、ペットボトルなどの物入れとして使うとなると棚の高さが下がり目の前の圧迫感がでてきます。雑誌が入る程度の10cm弱の隙間だけを天井との間に設定することにしました。

棚の表面は内装色とほぼ同じ色の合皮を貼りましたが、無地では寂しい雰囲気です。

そのため他の記事で紹介しているミサイルスイッチやカラーLEDを追加していった結果、気付いたら豪勢なコンソールになってしまいました。

裏側は見栄え無視で作成したのでお見せするのは恥ずかしい状態ですが、表と合わせて写真公開します。

何度かの増改築で、裏側の見苦しさが倍増しています。4か所のスポンジは雑誌などの物を載せる部分のすべり止め効果をねらっています。

写真の棚の内側下端に、間接照明にしていたテープLEDの残骸が残っていますが、今は使っていません。

下側中央から少し右のベルトで留めた黒い箱には、カラーLEDを制御するArduinoや6V定電圧化回路が入っています。

前側のパイプに棚をつける

作った棚は、ジョイント品番J-113Aを使って固定しました。

f:id:solocamptouring:20180218144056j:plain

ここでも、 ジョイントに元から空いている穴を少し広げて、M6のボルトが貫通するようにしています。

オーバーヘッドコンソール(モニター)の取り付け方法

最後に、電動格納式モニターとLCDモニターがついているコンソールの取り付け手法について紹介いたします。

棚板よりも前に位置していますが、後ろ側は棚板に引っかけるだけで、前側は室内ミラーの取付穴から出したステー上の板に締め付けています。

f:id:solocamptouring:20180218113951j:plain
f:id:solocamptouring:20180128073528j:plain
左が締め付け用のステーと板。右がコンソールを横からみた写真

コンソールの上側は天井と接触しているので、締め付け一点だけでもしっかり装着されています。

f:id:solocamptouring:20180203123541j:plain

棚とコンソールに使った表皮が、ジムニーの内装色とほぼ同じなので天井に溶け込んでおり、「後からつけた感」が少なくなっています。