10/19/2017

複数訪問予定地の天気予報(3時間と10日間を組合せ)表示

複数の離れた場所の訪問予定地がある際に、天気予報はどうなるのか調べる事があるが、何回も天気予報情報を開いて調べ、何枚もプリントし、それらを並べて漸く、自分の行動予定に伴う天気の今後の状況が把握できる。
もう少し効率的に調べて表示したいものだと思い、Excelのスクレーピング技術で表示するようにしてみた。当初は10日間天気予報のデータだけで纏めていたが、最初の3日間なら、3時間天気予報のデータを使う事が出来るので、3時間天気予報と10日間天気予報を組合せて表示させるようにしてみた。
310
マクロの内容は殆ど同じではあるが、3時間天気予報と10日間天気予報では、記載方法が少し違っている部分を変更してやる必要がある。(左図で表示した結果サンプルでは、データの幅が広くて画面からはみ出し、この画面では残り2日分が表示出来ていない。)

なお、場所に関するデータ(図のA~B列)の作成方法は、10日間天気予報と同じとした。3時間天気予報の部分は内部処理で補っている。

作成したマクロを以下に表示する。変更した部分は、10日間天気予報で作成したマクロと比較すれば、容易に分かると思うが、マクロの中に若干のコメントも記載したので、興味がある方には参考になると思う。

Webを読み取りExcel内に書き写した部分は、マクロの最後の部分で消去しているので、この部分をコメント表示にすれば、どのような書き写しが行われたかが分かり、参考になると思う。

尚、Excelシート内にマクロを実行するボタンを作成しておけば、便利だと思う。


《マクロ》

Sub WeatherScraper2()
'3時間天気予報と10日間天気予測を組み合わせ表示するようにした(2017/10/19)
 Dim i As Long, j As Long, k As Long, imax As Long
 Dim URL As String, URLSet As String
 Dim URL10days As String, URL3hours As String
 Dim charsell As String, dadd As String, sadd As String
 Dim nsell As Long, hnsel As Long
'雨の際のセルの色を付ける変数 rain 雨⇒20 雨天以外は色無し⇒0
 Dim rain As Integer
'雨量が多く設定色番号 rainhard  33 を使うときの雨量(現在設定は 2㎜以上)
 Dim rainhard As Integer
'qrainstr は降水量セルに書かれた文字、qrain は降水量
 Dim qrainstr As String, qrainnbr As String, qrain As Long

 rainhard = 2
' i: URLとして書かれた処理入力番号
 i = 1

'URLが書かれたセル内にデータがある間処理を続ける。
 Do Until Cells(i + 2, 2) = ""
 
'10days.htmlから3hours.htmlを作る
 URL10days = Range(Cells(i + 2, 2).Address)
 URL3hours = Replace(URL10days, "10days", "3hours")

'先ず3時間天気予報のURLをセットし、スクレーピングする。
 URLSet = "URL;" & URL3hours

 With ActiveSheet.QueryTables.Add(Connection:= _
        URLSet, _
        Destination:=Range(Cells(101, 61 + (i - 1) * 9).Address))
        .Name = "?kd=1&tm=d&vl=a&mk=1&p=1"
        .FieldNames = True
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = True
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .WebSelectionType = xlAllTables
        .WebFormatting = xlWebFormattingNone
        .WebPreFormattedTextToColumns = True
        .WebConsecutiveDelimitersAsOne = True
        .WebSingleBlockTextImport = False
        .WebDisableDateRecognition = False
        .WebDisableRedirections = False
        .Refresh BackgroundQuery:=False
 End With
 
'不要な4日目以降のデータ領域を削除する。
 Range(Cells(155, 61 + (i - 1) * 9), Cells(240, 70 + (i - 1) * 9).Address).Delete

'次に10日間天気予報のURLをセットし、スクレーピングする。
'この際、.RefreshStyle は xlOverwriteCells とする。
 URLSet = "URL;" & URL10days
 
 With ActiveSheet.QueryTables.Add(Connection:= _
        URLSet, _
        Destination:=Range(Cells(155, 61 + (i - 1) * 9).Address))
        .Name = "?kd=1&tm=d&vl=a&mk=1&p=1"
        .FieldNames = True
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = True
        .RefreshStyle = xlOverwriteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .WebSelectionType = xlAllTables
        .WebFormatting = xlWebFormattingNone
        .WebPreFormattedTextToColumns = True
        .WebConsecutiveDelimitersAsOne = True
        .WebSingleBlockTextImport = False
        .WebDisableDateRecognition = False
        .WebDisableRedirections = False
        .Refresh BackgroundQuery:=False
 End With

'不要なデータ領域を削除する。少し大きめの領域を削除
 Range(Cells(229, 61 + (i - 1) * 9), Cells(250, 70 + (i - 1) * 9).Address).Delete

'WebからExcelに書き写した表データ部分から、
'新たな表作成に必要なデータ部分をピックアップしてC列から右側に表記する。

 If i = 1 Then
'先ず、日・曜日を転記する。日と曜日のデータは、61列156行目から
    For j = 1 To 3
      Cells(1, 3 + (j - 1) * 8) = Cells(156 + (j - 1) * 7, 61)
    Next j
    
    For j = 4 To 5
      Cells(1, 27 + (j - 4) * 4) = Cells(177 + (j - 4) * 7, 61)
    Next j
    
    For j = 6 To 10
      Cells(1, 35 + (j - 6) * 4) = Cells(194 + (j - 6) * 7, 61)
    Next j
    
'時間枠(3:00,6:00,9:00,12:00,15:00,18:00,21:00,24:00)を記載する。
'これらの値は数値なので、シリアル値に換算するため24で割る。
    For j = 1 To 3
        For k = 1 To 8
          Cells(2, 3 + (k - 1) + (j - 1) * 8) = Cells(104, 62 + (k - 1)) / 24
        Next k
    Next j
    
'次に時間枠(3:00,9:00,15:00,21:00)を転記する。
'ここは文字列なので、其のまま転記すればよい。
    For j = 4 To 10
        For k = 1 To 4
          Cells(2, 27 + (k - 1) + (j - 4) * 4) = Cells(180 + (k - 1), 61)
        Next k
    Next j
  
'日付と時刻を見やすくするため、セルの書式設定、セルの結合を行う。
    For j = 1 To 3
      Cells(1, 3 + (j - 1) * 8).NumberFormatLocal = "G/標準"
      Range(Cells(1, 3 + (j - 1) * 8), Cells(1, 10 + (j - 1) * 8)).Merge
      Range(Cells(1, 3 + (j - 1) * 8), Cells(1, 10 + (j - 1) * 8)).HorizontalAlignment = xlCenter
        For k = 1 To 8
          Cells(2, 3 + (k - 1) + (j - 1) * 8).NumberFormatLocal = "[h]:mm"
        Next k
    Next j

    For j = 4 To 10
      Cells(1, 27 + (j - 4) * 4).NumberFormatLocal = "G/標準"
      Range(Cells(1, 27 + (j - 4) * 4), Cells(1, 30 + 4 * (j - 4))).Merge
      Range(Cells(1, 27 + (j - 4) * 4), Cells(1, 30 + 4 * (j - 4))).HorizontalAlignment = xlCenter
        For k = 1 To 4
          Cells(2, 27 + (k - 1) + (j - 4) * 4).NumberFormatLocal = "hh:mm"
        Next k
    Next j
End If

'天気に対するコメントを転記する。
     For j = 1 To 3
         For k = 1 To 8
           sadd = Range(Cells(107 + (j - 1) * 18, 62 + (k - 1)).Address)
           If InStr(sadd, "晴れ") > 0 Then
           rain = 0
           Else
           End If
           If InStr(sadd, "曇り") > 0 Then
           rain = 15
           Else
           End If

           If InStr(sadd, "雨") > 0 Then
           rain = 20
'降水量が書き込まれたセル[qrainstr]
'文字を数値[qrain]にして、rainhard 以上なら青い色を濃い青 33 にする。
           qrainstr = Range(Cells(112 + (j - 1) * 18, 62 + (k - 1)).Address)
           qrain = Val(qrainstr)
             If qrain > 0 Then
'「小雨」で、雨量が 0以上なら色は薄い水色(28)に設定する。
             rain = 28
             Else
             End If
             
             If qrain >= rainhard Then
'「小雨」で、雨量がここで設定した2mm以上なら色は濃い水色(33)に設定する。
             rain = 33
             Else
             End If
         Else
         End If
         
'セルに天気コメントを書き入れ、そのセルの色を付ける。
         Cells(3 + (i - 1), 3 + (k - 1) + (j - 1) * 8) = sadd
         Cells(3 + (i - 1), 3 + (k - 1) + (j - 1) * 8).Interior.ColorIndex = rain
         Next k
     Next j
     
'天気に対するコメント、データは62列より(晴れ、曇りなど)を転記する。
'ここからは、URLを読んだ数毎に、読込み列は+9する必要がある。
'Webから写し取ったセル内の天気コメントは、全て二重表現になるので、文字数を1/2にする。
     For j = 4 To 5
         For k = 1 To 4
           charsell = Range(Cells(180 + (k - 1) + (j - 4) * 7, 62 + (i - 1) * 9).Address)
'セル内の文字数を数える。
           nsell = Len(charsell)
'二重に書いているので数値を半分にする。
           hnsel = nsell / 2
'セル枠に書かれている文字の前半分
           sadd = Mid(charsell, 1, hnsel)

           If InStr(sadd, "晴れ") > 0 Then
           rain = 0
           Else
           End If
           If InStr(sadd, "曇り") > 0 Then
           rain = 15
           Else
           End If

           If InStr(sadd, "雨") > 0 Then
           rain = 20
'降水量が書き込まれたセル[qrainstr]には、文字形式で「2㎜」などと書かれている。
'全角1文字[㎜]の左側の文字を数値[qrain]にして、rainhard 以上なら青い色を濃い青 33 にする。
           qrainstr = Range(Cells(180 + (k - 1) + (j - 4) * 7, 65 + (i - 1) * 9).Address)
           qrainnbr = Left(qrainstr, InStr(qrainstr, "㎜") - 1)
           qrain = Val(qrainnbr)
             If qrain > 0 Then
'「小雨」で、雨量が 0以上なら色は薄い水色(28)に設定する。
             rain = 28
             Else
             End If
             
             If qrain >= rainhard Then
'「小雨」で、雨量がここで設定した2mm以上なら色は濃い水色(33)に設定する。
             rain = 33
             Else
             End If
         Else
         End If
         
'セルに天気コメントを書き入れ、そのセルの色を付ける。
         Cells(3 + (i - 1), 27 + (k - 1) + (j - 4) * 4) = sadd
         Cells(3 + (i - 1), 27 + (k - 1) + (j - 4) * 4).Interior.ColorIndex = rain
         Next k
     Next j

'6日目以降の処理は、1~5日目までの処理と同じだが、転記元の場所が違うので別処理とした
     For j = 6 To 10
         For k = 1 To 4
           charsell = Range(Cells(197 + (k - 1) + (j - 6) * 7, 62 + (i - 1) * 9).Address)
           nsell = Len(charsell)
           hnsel = nsell / 2
           sadd = Mid(charsell, 1, hnsel)
        
           If InStr(sadd, "晴れ") > 0 Then
           rain = 0
           Else
           End If
           If InStr(sadd, "曇り") > 0 Then
           rain = 15
           Else
           End If
         
           If InStr(sadd, "雨") > 0 Then
           rain = 20
           qrainstr = Range(Cells(197 + (k - 1) + (j - 6) * 7, 65 + (i - 1) * 9).Address)
           qrainnbr = Left(qrainstr, InStr(qrainstr, "㎜") - 1)
           qrain = Val(qrainnbr)
             If qrain > 0 Then

             rain = 28
             Else
             End If
             
             If qrain >= rainhard Then
             rain = 33
             Else
             End If
         Else
     End If
        
'セルに天気コメントを書き入れ、そのセルの色を付ける。
         Cells(3 + (i - 1), 35 + (k - 1) + (j - 6) * 4) = sadd
         Cells(3 + (i - 1), 35 + (k - 1) + (j - 6) * 4).Interior.ColorIndex = rain
         Next k
     Next j

'B列のデータが有る限り処理する為カウンターを1つ進めて、最初の処理点に戻す。
 i = i + 1
Loop

imax = i - 1

'表の幅をデータの文字長さに合わせて自動調整する。
'範囲は、C列からBB列まで
Range("C:BB").Columns.AutoFit

'表の罫線を引く。
'罫線を引く範囲は、C1から第54列の第(imax+2)行まで
Range(Cells(1, 1), Cells(imax + 2, 54)).Borders.LineStyle = xlContinuous

'セルの中のデータは幅方向の中央に置く
Range(Cells(1, 3), Cells(imax + 2, 54)).HorizontalAlignment = xlCenter

'直ぐに必要としないデータ領域を非表示にし、Webから写し取ったセル部分を削除する。
Columns("B").Hidden = True
Range(Columns(61), Columns(61 + 6 + imax * 7)).Delete

End Sub

10/17/2017

ロボットカーを作ろう・・・ 先ず外装部分を作ってみる

屋根裏や床下の自分が入っていけない場所の状況を把握したい・・・と思い、ロボットカーを作ってみようと思った。

以前、中国からシャシーを購入しようとしたが、2度ほどトラブルにあい、自分で全て企画してみることにした。

タミヤ製のギヤボックス等を使って、外装部分を組み立ててみた。プラモデルやキットでは無いので、オリジナルの形である。

未だ、完成していません。主にシャシー周りの外装が終了しただけです。全て頭の中で企画し、身の回りで見つけ、部品に加工出来そうなものを使って、手あたりばったり組立ていったオリジナル品です。

配線は、外装部品類がどのように配置出来るかが決まらないと出来ないので・・・これからになります。プログラムと合わせて配線を進めるので時間がかかりそうです。

コンピュータはRaspberryPi3とArduinoUnoの2台を搭載します。ヘッドライトも明るいものを2個装着します。前方にUSBカメラを搭載します。電池は18650タイプを4個搭載し、無線でコントロールする予定です。

全長約270mm、全幅約130mm、全高約115mmで、以外に重量があります。
果たして、動くまでゆくかどうか・・・配線と同時にプログラム開発もあり、動くまでには相当な時間がかかりそうです。

Img_20171017_204254 Img_20171017_204326 Img_20171017_204349 Img_20171017_204437

10/14/2017

Windows10 ユーザーアカウント制御されるアプリの自動起動方法

毎日定刻にPC(Windows10)を起動させ、その際に、アプリも自動起動させたい。ある設定した時刻になったら、PCをシャットダウンさせるという事をやりたかったのだが、ようやく上手く設定が出来たようなので、忘れないうちにここにメモをしておく。

僕が使っているPCの構成(monitorの仕様、BIOS設定方法など)の問題も有ったように思うので、そのシステムの概要をここに記載しておく。

PCの概要

 Motherboard: Z97N-WiFi  LGA1150用 Mini-iTX (Gigabyte製)
 CPU: intel Core i5 4590 @3.30GHz BOX(Haswell Refresh)
 Memory: CORSAIR VENGEANCE 16.0GB
 Graphics: 内臓IGFX
 HardDisk: PLEXTOR 
 PC Case: Cooler Master  Elite 130 Cube
 電源: Enermax ELT500AWT  500W仕様
 OS: Windows10 Pro 64bit版

周辺装置

 Monitor: LG FLATRON IPS206T-PN  (DVI接続)
 Keyboard: FILCO Excellio FKB109EXJB
 Mouse: Microsoft  Mobile Optical Mouse (有線)

調べてみると、自動起動はBIOSの「RTCによる電源ON」から行い、シャットダウンは「タスクスケジューラ」から行えば良いらしい。

問題点は、
1)PC起動時にDelキーを押しても、BIOS画面を開くことが出来なかったこと。
2)BIOS画面を開くことが出来るように変更後、PCを起動後に、監視カメラ用アプリが連動して上手く立ち上がらなかったこと。
3)監視カメラ用のアプリは立ち上がったものの、ユーザーアカウント制御のために、アプリがそこで止まってしまうこと。
上記の問題は、下記のように設定して、問題が解消し、監視カメラ用アプリは自動的に起動した。

1)の問題は、僕が使っている自作PCを製作した際に選択したレガッシーBIOSの問題かもしれないし、あるいは、使っているモニターのPCとの接続仕様によるものかもしれない。
しかし、BIOSが表示できないという問題の原因は、どちらなのかを切り分ける事が出来ていない。

1.BIOS画面を表示するために、
 いろいろやっている間に、PCの起動ディスク(C:ドライブ)に余計な書き込みをしてしまい、PCが起動できなくなった。しかし、このような問題は起きてしまうものなので、事前にHDD(D:)の中には起動用のバックアップを作り、DVDにも起動用ディスクを作っておいた。

作業場所の問題があり、周辺機器(モニター、キーボード、マウス)を外して、このPCだけを別の部屋に移動させて設定作業を行った。

 ①PCからSSDを取り外して、別のPCに組み入れ、ここでSSDのパーティションを外し、初期状態にした。
 ②初期状態に戻したSSDを、再び元のPCに組み込み、マザーボード上のCMOSジャンパーピンをショートさせて、データをクリアし、周辺機器を接続して、電源ON。
 ③これで、電源ON直後に「Del」キーを押すことで、BIOS画面に入ることができた。

2.BIOS画面での設定
 BIOS画面を開いて、システム電源を計画的にONにする設定を行う。
 ①Power Management (電力管理) 画面で、Resume by Alarmに入り、
  Wake up hour と Wake up minute を設定した。
  僕は、午前4時30分にPCを起動させるようにしたいので、hourの入力は「4」を、minuteの入力は「30」とした。

  毎日同じ時刻に起動なので、Wake up day は 「0」のままである。
  また、秒まで拘らないので、Wake up second も 「0」のままである。

 ②予期せぬ停電などで、AC電源が失われた場合の電源復帰もここで設定しておく。
  僕は、Memory を選択し、AC電源が戻った際に、システムが停電する前の状態と同じ状態となるようにした。
  
 ③キーボードやマウスによる電源ONは不要なので、Disabledを選択した。

 ④「Save & Exit」を選択し、保存して終了! これで、PCの起動設定は出来たはずだ。
  
 ⑤設定の確認のため、ここで行っている他の設定準備が終わり、しばらく時間を置いた後に、
 例えば、10数分後にこのPCが自動起動するように、前述のResume by Alarmの時刻設定を行って、この状態を「Save & Exit」で保存しておくことにする。

 この確認作業が終われば、再びBIOS画面で起動させる時間を設定し直す必要がある。
 忘れないようにしないと・・・。

3.Windows10のパスワードなし起動
 僕は、「Windows 10で起動時のパスワード入力を省略する方法
」のURLを参考にさせていただいた。

4.スタートアップにアプリを登録する
 PCが起動したときに連動して自動起動させたいアプリは、スタートアップに入れれば良いらしい。
 ①アプリをスタートアップに登録するためには、登録するアプリをデスクトップ画面に仮置きする。
 注記)このとき、アプリのプロパティを開き、
  「互換性」のタグをクリックして、一番下にある「管理者としてこのプログラムを実行する」にチェックを入れてはいけない。これを行うと、アプリが起動しなくなる可能性が高い。

 ②Windowsボタンをマウス右クリックし、「ファイル名を指定して実行」メニューを選択する。
 ③開いた窓の中の枠内に 「shell:startup」 と入力し、「OK」をクリックする。

 ④新たに、エクスプローラーのスタートアップフォルダーが表示される。

  これまでに、アプリのスタートアップ登録をしていなければ、このフォルダーの中は空のはずだ。

 ⑤このスタートアップフォルダーに、デスクトップに仮置きしておいたアプリを、ドラックアンドドロップで移動させる。

 ⑥PCを再起動させる。

 この作業が完了すれば、監視カメラ用アプリはPC起動直後に起動するだろうと思っていた。
 アプリは起動したが、起動後『ユーザーアカウント制御(UAC)』という機能が働いて、「このアプリがPCに変更を加えることを許可しますか?」と聞いてくる! ここで「はい」と答える必要がないようにする必要がある。そうしないと、シャットダウンの時刻までアプリは止まったままである。

 それほど単純ではなかった。
まだ他の項目を設定する必要がある。

この課題を解消するためには、

5.まず、タスク スケジューラでタスクを作成する必要がある。
タスクスケジューラの起動は、タスクバーの「検索フォーム」に「task」と打ち込むと、表示される筈。メニューから「タスク スケジューラ」を選んでクリックする。

①画面右側の操作メニューから「タスクの作成・・・」を選び、

②開いた「タスクの作成」の窓の 全般タグ に、名前、説明を記入する。
 僕は、名前に「MotionDetectCamera」と記載し、説明は空欄とした。
 ・ユーザーがログオンしているときのみ実行する・・・ボタンをON
 ・最上位の特権で実行する・・・・・・・・・・・・・にチェックを入れる。
 ・構成の枠内は、・・・・・・・・・・・・・・・・・Windows10を選択する。
 まだOKボタンはクリックしない。 

③操作タグ をクリックし、
 新規をクリックして新しい操作を作る。
 プログラムの開始を選んで、

 プログラム/スクリプト欄 には、
「参照」をクリックして、アプリが格納されている場所(例えば、C:\Program Files(x86)\UC\) からプログラム (UC.exe) を探し場所を確認する。
 そして「C:\Program」とだけ入力する。

 また、引数欄には、「Files(x86)\UC\UC.exe」と入力する。
 僕は、開始(オプション)欄に 「/rl highest」と入力した。

 OKをクリックして戻る。

④トリガータグ をクリックし、
 新規をクリック ⇒ 特定のユーザーのボタンを選択する。
 OKをクリックする。

⑤条件タグ をクリックし、
 入っているチェックをすべて外す。
 設定後、OKをクリックする。

注記)アプリケーションプログラム(ここでは”UC.exe”)は、ID、パスワードの入力無しで起動できるように設定しておくこと。

これでもまだ「最上位の特権で実行する」が選択されているが、未だ『ユーザーアカウント制御(UAC)』で止められてしまう。

6.そのためユーザーアカウント制御の設定を変更する
先ず、モニター画面左下隅タスクバーの「検索フォーム」に「uac」と入力して、

「ユーザーアカウント制御設定の変更」をクリックし、「
ユーザーアカウント制御の設定」窓画面で、4段階の3段階目に設定してOKをクリックする。


7.最後に、PCをシャットダウンする設定を行う。

先程4.で設定したが、タスク スケジューラで、シャットダウン用のタスクを作成する必要がある。
タスク スケジューラの起動は、タスクバーの「検索フォーム」に「task」と打ち込むと、表示される筈。メニューから「タスク スケジューラ」を選んでクリックし起動させる。

①操作のタブをクリックし、今度は「基本タスクの作成」をクリックする。

②名前は、「自動シャットダウン」と付け、次へのボタンをクリックした。

③次の画面タスクトリガーでは、毎日のボタンを選択し、次へをクリックし、
  毎日の 開始時刻を設定する。
    僕は、当日の深夜「23:55:00」に設定し、次へのボタンをクリック。

④操作の画面では、「プログラムの開始」ボタンを選択し、次へ。

  プログラム/スクリプトには、
   「 shutdown 」
  引数の追加には、
   「 /s /f 」
  と入力し、次へ。

⑤完了画面で、「完了」ボタンをクリックする。

以上で、全ての設定作業が完了したので、PCを再起動、又はシャットダウンした後PCの電源ボタンを押してみる・・・・・アプリは立ち上がったかな?

別のPCで確認した結果 この設定で無事立ち上がった!

アプリプログラムが上手く立ち上がらないので、ここでの設定に問題があるのかと思って色々調べた結果、アプリプログラムには、32bit版と64bit版の2種類があり、PCが64bit OSだったので64bit版のアプリを選んでインストールして確認しようとしていたが、何度やってもアプリの起動がおかしいので、32bit版にインストールし直して確認してみた。
電源ON後、ユーザーアカウント制御(UAC)も表示されずにパスし、アプリ(UC.exe)も起動し、画面表示された。

10/02/2017

大清水から尾瀬・燧ケ岳 日帰り登山

Gps2 2017/9/28日23:30、川越駅西口バス停より関越交通の夜行バスを使って、大清水に入り、翌日9月30日に燧ケ岳(柴安嵓、俎嵓、ミノブチ岳)を登ってきた。

天気は、ほぼ予報通りで、写真のように青空も見えて良い天気であった。
燧ヶ岳への登山道は、ぬかるみの多い湿地帯の中を歩いて居るような道で、歩行は決して快適では無かった。僕は、ゴム長靴を履いていたので、足元の泥による汚れは何も気にすることなく歩くことが出来た。


燧ケ岳に登る 3合目を過ぎた辺りで、同じルートを歩いて居る若い女性に出会った。僕は疲れ始めて歩行速度も落ちてきていたので、彼女と雑談をしながら柴安嵓まで一緒に登ることが出来た。連れが居ると、疲れは一時的にでも忘れる事が出来る。彼女は休暇をとって友人と尾瀬に来て、確か長蔵小屋に泊まり、早朝より燧ヶ岳を目指して歩いてきたとのこと。友人は、尾瀬ヶ原を歩きに行ったそうだ。其々、別の尾瀬の楽しみ方をしている!柴安嵓を登った後は、赤田代にある温泉小屋に泊まり、尾瀬を満喫して帰るとの事だった。僕は熊沢田代の景色を見たいので、柴安嵓で記念写真を撮って貰い別れたが、とても感じの良い人だった。

熊沢田代の景色は、私のお気に入りの場所である。ここは、俎嵓側から見ても良いし、2つの池塘の先から振り返って燧ケ岳方向を見ても良い景色だと僕は思っている。今回は草紅葉が綺麗な色を放ち、また2つの池塘は、空の青を映し、綺麗な色の対比を見せてくれた。この場所を撮影した多くの風景写真でも、この日のように池塘が青く見えているものは殆ど無かったのではないかと思った。

熊沢田代を過ぎた登り階段で、急に右足の大腿四頭筋が攣ってしまった。脚を揉み解し、水分を補給して少し休んで、痛みを感じながら速度を落として暫く歩くと、痛みは徐々に引いて行った。しかし、ここから御池に下りるまでは、急で滑りやすい下り勾配が続く・・・。この燧ケ岳の山道の中では、一番嫌いな場所になる。神経を集中させながら慎重に下山した。
濡れていて段差も大きく、小さな岩も多く滑りやすく感じたが、硬めのインソールを中に入れたゴム長靴は、僕が普段使っている硬めのソールの登山靴より滑りにくいと思ったし、28kmも歩いて足に水膨れが出来なかった事には正直驚いた。

御池から七入へ下るところの「ブナ平」は、残念ながら未だ紅葉に至らず・・・紅葉までにはまだしばらく時間がかかりそうに思えた。僕は、緑に囲まれた古道の中を七入バス停に向かって下りたが、途中で急な階段を下りるところがあり、膝がまた攣るのではないかと心配になって、一般道を歩いてしまった。後から考えれば、ゆっくりした速度でも良いから、階段を下りていれば、七入バス停で当初予定通りのバスに乗れた可能性が高いと僕は思っている。

七入バス停への到着時間が、バス停車時刻の3分後になり、約1時間半後のバスを待たざるを得なくなった。何もない「七入バス停」で時間を潰すのは面白く無いので、キリンテ登山口の近くにあるバス停まで歩くことにした。そのバス停の傍には「みやまえ食堂」があるので、早めの夕食を摂ってバスの到着までその場所で待たせて戴こうという計画だ。食堂では、この地方の名物蕎麦「裁ち蕎麦」の大盛りを食べて、会津高原尾瀬口方面行き最終バスに乗った。(この食堂、34年前から開業してきたが、今秋10月24日で営業終了との事。何とも寂しくとても残念である。)

七入で乗車すべきバスに乗り遅れて、帰宅のスタート時刻は、1時間半遅くなったが、
特急電車に乗車できた為、自宅到着は、当初予定に対し30分の遅れとなった。

歩行距離と時間:

 持参した
GarminのGPS eTrex30(現在では旧型、後継機種としてeTrex30xがあるらしい)に依れば、歩いたルート(上記地図上で水色の線で示したルート)の歩行距離は 27.8km、所要時間は11時間30分であった。

 詳細は次のようであった。
Photo




 [04:15]04:07 大清水バス停
     04:51 一ノ瀬休憩所  小休止
     05:25 岩清水
 [06:20]05:54 三平峠
 [06:35]06:13 三平下(尾瀬沼山荘)
      ここでトイレ休憩
     06:41 尾瀬沼ビジターセンター
      ここで、朝食・トイレ休憩  (気温は 2℃)
            07:10 長英新道分岐
            07:44 一合目(h=約1745m、標高値はGPS表示値を使った。下記同様)
            08:01 二合目(h=約1810m)
            08:18 三合目(h=約1890m)
            08:34 四合目(h=約1960m)
            08:45 五合目(h=約2020m)
            08:56 六合目(h=約2085m)

            09:20 ミノブチ岳(h=約2213m)  小休止 約7分間
            09:34 八合目(h=約2235m)
            09:46 九合目(h=約2290m)
 [09:55]09:57 俎嵓(まないたぐら、h=2346m)  小休止 約15分間
 [10:20]10:36 柴安嵓(しばやすぐら、h=2356m)  小休止 約6分間
 [10:45]11:04 俎嵓           小休止 約13分間
 [11:45]12:04 熊沢田代
 [12:25]12:49 広沢田代
 [13:05]13:36 御池(みいけ)
 [14:40]14:59 七入(バス停)
     15:35 みやいり食堂(キリンテ登山口の少し北側に位置)
           七入~みやいり食堂:距離約 2.7km(約36分)

 大清水から御池までのルートは、事前にヤマケイオンラインを使って、コースタイムと登山計画書を作成しておいたので、その時の計画時刻を[ ]内に記載しておく。コースタイム倍率は1.00倍である。七入(バス停)の[ ]内時刻は、私が計画した到着時刻。

帰宅アクセス概要

 みやまえ食堂(2017年10月24日で閉店とのこと)前のキリンテバス停から
16:30頃 バス乗車(
みやまえ食堂前のキリンテバス停定刻より少し遅れていた・・・)
17:50頃 会津高原尾瀬口着
18:11 会津高原尾瀬口発(野岩鉄道特急リバティ会津148号浅草行き 指定席@1600円)
20:41 春日部着
20:45 春日部発(東武アーバンパークライン・大宮行き、8番線より)
21:07 大宮着
21:23 大宮発(JR埼京線通勤快速・川越行き)
21:46 川越着

事前の天気確認:

 僕は、下記の予報を調べて決行した。
 ①「てんきとくらす 燧ケ岳」、「10日間天気予報 尾瀬
 ②weather2"Oze-Tokura"

10月1日(日曜日)、「
ロングウォークちちぶ路」のイベントが計画されており、今年は是非参加したいと思っていたのだが・・・、階段を降りる時に大腿四頭筋だけがまだ少し痛むため、出席を取りやめてこのブログを書いている。
10月2日(月曜日)、脚の筋肉痛はすっかり治まった。

持参した道具など
①靴:ビバホームオリジナルのゴム長靴の中にSuperfeetのインソール(GREEN)を入れた。
②バックパック: Millet SAAS Fee2 30(L)
③上着:長袖Tシャツ、Arc'teryx Gamma LT Jacket、
防寒用薄手のダウンジャケット、
  着替え用:長袖Tシャツx1(使用せず)、登山用靴下x1
(使用せず)
④ズボン:替えなし。
⑤雨具: ゴアテックスの上着のみ持参したが使用せず。
⑥水: 500mlx 4本 ⇒ 使ったのは 2本半
⑦食料: 朝食用として「サンドウィッチ」、昼食用として「おにぎり」x 2個
⑧非常食: アンパンx1、ウイダーinゼリー エネルギーx1、アーモンドチョコレート
⑨ストック: LEKI Quantum
⑩ヘッドライト: Black Diamond ストーム 単4x4 (予備電池:単4x4)
⑪帽子:x1
⑫熊よけ:熊鈴、熊撃退スプレー
⑬カメラ: Nikon D800 & AF-S Nikkor 24-120mm
⑭財布:
⑮ファーストエイドセット: 常備薬、胃腸薬、バンドエイド等
⑯フェースタオル: 1本
⑰サングラス:x1
⑱手袋:x1
⑲GPS: Garmin eTrex30 (地図は、UUD製 Japan Digital Road Map Navigator and Topo 10m for Garmin GPS V5)
⑳トラベル用首枕:x1 (100均ショップ)


《写真》 撮影した写真を下記に、時系列的に並べた。
Dsc_7744 Dsc_7752Dsc_7759 Dsc_7765Dsc_7766 Dsc_7769Dsc_7846 Dsc_7774 Dsc_7780






Dsc_7784 Dsc_7791
 Dsc_7792Dsc_7794






Dsc_7809Dsc_7813Dsc_7815Dsc_7818Dsc_7736Dsc_7738












Dsc_7819 Dsc_7845 Dsc_7854Dsc_7866Dsc_7870Dsc_7881Dsc_7885_stitchDsc_7896Dsc_7903Dsc_7913Dsc_7924Dsc_7927Dsc_7931Dsc_7951Dsc_7971Dsc_7986Dsc_7996Dsc_8000_stitchDsc_7998 Dsc_8009Dsc_8028Dsc_8043Dsc_8045Dsc_8052Dsc_8055Dsc_8086 Dsc_8068Dsc_8077Dsc_8096Dsc_8137Dsc_8153Dsc_8162Dsc_8171Dsc_8175Dsc_8187Dsc_8195Dsc_8205Dsc_8208Dsc_8211Dsc_8214Dsc_8225Dsc_8242Dsc_8271Dsc_8275Dsc_8284 Dsc_8295Img_20170929_162153Img_20170929_155147Img_20170929_163009
























































































《歩行ルートデータ》
「track__29_sep_2017_oze_hiuchi_mountain.gpx」をダウンロード

09/30/2017

Webの10日間天気予報をExcelに書き写し編集する

日本気象協会の10日間天気予報のWebページのデータを写し取り、複数の場所のURLデータを一覧にして、天気の状況の変化をみるための処理を行う。Webページの表現方法が変更になって、以前作成したマクロでは処理が出来なくなっていたので見直す事にした。しばらくぶりに見るマクロで、処理をどのように書いていたか、思い出すのに一苦労した。

データ処理のマクロは、下記のようになる。
Webデータを書き写す際の間違いに気づいたので、今回はここも修正した。

「日本気象協会の10日間天気予報」を活用した、以前僕が発表したマクロは、今回発表のマクロ(下記)に変更して欲しい。

《注記》下記マクロの第80,84行目にCell位置指示の間違いが有ったので修正した。(2017/10/04)

《マクロ部分》

Sub WeatherScraper()
'URL内の記載状況が変わったため、マクロを見直し新バージョンとして作成(2017/09/28)
 Dim i As Long, j As Long, k As Long, imax As Long
 Dim URL As String, URLSet As String
 Dim charsell As String, dadd As String, sadd As String
 Dim nsell As Long, hnsel As Long
'雨の際のセルの色を付けるため 雨⇒20 雨天以外は色無し⇒0
 Dim rain As Integer
'雨量が多く設定色番号 33 を使うときの雨量(現在設定は 2㎜以上)
 Dim rainhard As Integer
'qrainstr は降水量セルに書かれた文字、qrain は降水量
 Dim qrainstr As String, qrainnbr As String, qrain As Long

'多降水量設定にする数値 僕は2mmとした。
 rainhard = 2
' i: URLとして書かれた処理入力番号
 i = 1

'URLが書かれたセル内にデータがある間処理を続ける。
 Do Until Cells(i + 2, 2) = ""

'URLの読み込み位置にデータが存在しているので、天気予報のURLをセットする。
 URLSet = "URL;" & Range(Cells(i + 2, 2).Address)

'WebからExcelシート内にデータを書き写す位置の記載方法が間違っていたので
'Destinationの中の表現を修正した。
 With ActiveSheet.QueryTables.Add(Connection:= _
        URLSet, _
        Destination:=Range(Cells(101, 53 + (i - 1) * 7).Address))
        .Name = "?kd=1&tm=d&vl=a&mk=1&p=1"
        .FieldNames = True
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .BackgroundQuery = True
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .WebSelectionType = xlAllTables
        .WebFormatting = xlWebFormattingNone
        .WebPreFormattedTextToColumns = True
        .WebConsecutiveDelimitersAsOne = True
        .WebSingleBlockTextImport = False
        .WebDisableDateRecognition = False
        .WebDisableRedirections = False
        .Refresh BackgroundQuery:=False
 End With

'WebからExcelに書き写した表データ部分から、
'新たな表作成に必要なデータ部分をピックアップしてC列から右側に表記する。
 If i = 1 Then
'先ず、日・曜日を転記する。日と曜日のデータは、"BA"列に書き写してあり、
' 102,109,116,123,130,  140,147,154,161,168に記載されている。
' これを、列 3,7,11,・・・ となるので ⇒ 3+(J-1)*4 に転記する。
    For j = 1 To 5
      Cells(1, 3 + (j - 1) * 4) = Cells(102 + (j - 1) * 7, "BA")
    Next j
    
    For j = 6 To 10
      Cells(1, 3 + (j - 1) * 4) = Cells(102 + 3 + (j - 1) * 7, "BA")
    Next j

'次に時間枠(3:00,9:00,15:00,21:00)を転記する。
    For j = 1 To 5
        For k = 1 To 4
          Cells(2, 3 + (k - 1) + (j - 1) * 4) = Cells(105 + (k - 1) + (j - 1) * 7, "BA")
        Next k
    Next j
    For j = 6 To 10
        For k = 1 To 4
          Cells(2, 3 + (k - 1) + (j - 1) * 4) = Cells(105 + 3 + (k - 1) + (j - 1) * 7, "BA")
        Next k
    Next j
  
'日付と時刻を見やすくするため、セルの書式、セルの結合をしておく。
    For j = 1 To 10
      Cells(1, 3 + 4 * (j - 1)).NumberFormatLocal = "G/標準"
      Range(Cells(1, 3 + 4 * (j - 1)), Cells(1, 6 + 4 * (j - 1))).Merge
      Range(Cells(1, 3 + 4 * (j - 1)), Cells(1, 6 + 4 * (j - 1))).HorizontalAlignment = xlCenter
        For k = 1 To 4
          Cells(2, 3 + (k - 1) + 4 * (j - 1)).NumberFormatLocal = "hh:mm"
        Next k
    Next j
End If

'天気に対するコメント、最初のデータはBB列(54列)より(晴れ、曇りなど)を転記する。
'ここからは、URLを読んだ数毎に、読込み列は+7する必要がある。
'Webから写し取ったセル内の天気コメントは、全て二重表現になるので、文字数を1/2にする。
     For j = 1 To 5
         For k = 1 To 4
           charsell = Range(Cells(105 + (k - 1) + (j - 1) * 7, 54 + (i - 1) * 7).Address)
'セル内の文字数を数える。
           nsell = Len(charsell)
'二重に書いているので数値を半分にする。
           hnsel = nsell / 2
'セル枠に書かれている文字の前半分
           sadd = Mid(charsell, 1, hnsel)

           If InStr(sadd, "晴れ") > 0 Then
           rain = 0
           Else
           End If
           If InStr(sadd, "曇り") > 0 Then
           rain = 15
           Else
           End If

           If InStr(sadd, "雨") > 0 Then
           rain = 20
'降水量が書き込まれたセル[qrainstr]には、文字形式で「2㎜」などと書かれている。
'全角1文字[㎜]の左側の文字を数値[qrain]にして、rainhard 以上なら青い色を濃い青 33 にする。
           qrainstr = Range(Cells(105 + (k - 1) + (j - 1) * 7, 57 + (i - 1) * 7).Address)
           qrainnbr = Left(qrainstr, InStr(qrainstr, "㎜") - 1)
           qrain = Val(qrainnbr)
             If qrain > 0 Then
'「小雨」で、雨量が 0以上なら色は薄い水色(28)に設定する。
             rain = 28
             Else
             End If
             
             If qrain >= rainhard Then
'「小雨」で、雨量がここで設定した2mm以上なら色は濃い水色(33)に設定する。
             rain = 33
             Else
             End If
         Else
         End If
         
'セルに天気コメントを書き入れ、そのセルの色を付ける。
         Cells(3 + (i - 1), 3 + (k - 1) + (j - 1) * 4) = sadd
         Cells(3 + (i - 1), 3 + (k - 1) + (j - 1) * 4).Interior.ColorIndex = rain
         Next k
     Next j

'基本的に1~5日目までの処理と同じだが、記載されている場所が違うので別処理とした
     For j = 6 To 10
         For k = 1 To 4
           charsell = Range(Cells(105 + 3 + (k - 1) + (j - 1) * 7, 54 + (i - 1) * 7).Address)
           nsell = Len(charsell)
           hnsel = nsell / 2
           sadd = Mid(charsell, 1, hnsel)
        
           If InStr(sadd, "晴れ") > 0 Then
           rain = 0
           Else
           End If
           If InStr(sadd, "曇り") > 0 Then
           rain = 15
           Else
           End If
         
           If InStr(sadd, "雨") > 0 Then
           rain = 20
           qrainstr = Range(Cells(105 + 3 + (k - 1) + (j - 1) * 7, 57 + (i - 1) * 7).Address)
           qrainnbr = Left(qrainstr, InStr(qrainstr, "㎜") - 1)
           qrain = Val(qrainnbr)
             If qrain > 0 Then

             rain = 28
             Else
             End If
             
             If qrain >= rainhard Then
             rain = 33
             Else
             End If
         Else
         End If
        
'セルに天気コメントを書き入れ、そのセルの色を付ける。
         Cells(3 + (i - 1), 3 + (k - 1) + (j - 1) * 4) = sadd
         Cells(3 + (i - 1), 3 + (k - 1) + (j - 1) * 4).Interior.ColorIndex = rain
         Next k
     Next j

'B列のデータが有る限り処理する為カウンターを1つ進めて、最初の処理点に戻す。
 i = i + 1
Loop

imax = i - 1

'直ぐに必要としないデータ領域を非表示にし、Webから写し取ったセル部分を削除する。
 Columns("B").Hidden = True
 Range(Columns(53), Columns(53 + imax * 7)).Delete

End Sub

《注記》 ここで、もしWebから転記した生データを確認したいのなら、このマクロの「Range(Columns(53), Columns(53 + imax * 7)).Delete」部分をコメント行にすればよい。そうすれば、第53列目から後半の列に、転記されたデータを見る事が出来る。

《Excelシートの書き方》

ExceldataExcelシートの書き方の事例を記載する。

①先ず、Google検索で
日本気象協会 10日間天気予報 青森県」をキーワードにして、該当するURLを検索する。
②検索された一覧より、
『青森市の10日間天気(6時間ごと) - 日本気象協会 tenki.jp』 を選ぶ。ここでのポイントは、(6時間ごと)というキーワードが入っているものを選ぶこと。
③②で選んだ画面を開き、URLをコピーする。
 この例では、『https://tenki.jp/forecast/2/5/3110/2201/10days.html
』となっている。
 10日間天気予報のデータが含まれているという事を htmlの直前に書かれている 
10days で確認しておく。
④これを、ExcelシートのB列に貼り付ける。
 貼り付ける順番は、自分が訪問したい場所順に、第1番目の訪問場所のURLは3行目に、第2番目の訪問場所は4行目に記載、・・・。必要な訪問場所を順番に貼り付ける。
⑤天気予報を確認したい場所のURL貼り付けが終われば準備完了である。
 マクロは、B列にデータが無くなれば処理を終了するようになっている。

 ・C列からAP列に処理結果が記載され、WebからこのExcelシート内に転記したデータは消去するようにしてある。
 ・
C列からAP列のセル幅は、標準値になっているので、見やすくするために列幅の自動調整をするのが良い。

⑥A列の第3行目以降は、URLの説明書きとして使用するのが良い。
 また、AQ列~AZ列もコメント書きに使用することが出来る。

⑦マクロを実行させた上記のデータでの結果(2017/10/01 23:00処理)は、下記のようになった。(ご参考)
10










《表示結果をより見易くするために》
 2017/10/04追記

①表の幅をデータの文字長さに合わせて、C列からAP列までを自動調整する。
表のC1から第42列(AP列)の第(imax+2)行まで罫線を引く。
③②の
セル中のデータは、セルの幅方向の中央に置く。
これを行うためには、上記マクロの第184行のところに、下記のマクロを挿入すればいい。

'表の幅をデータの文字長さに合わせて自動調整する。
'範囲は、C列からAP列まで
Range("C:AP").Columns.AutoFit

'表の罫線を引く。
'罫線を引く範囲は、C1から第42列(AP列)の第(imax+2)行まで
Range(Cells(1, 3), Cells(imax + 2, 42)).Borders.LineStyle = xlContinuous

'セルの中のデータは幅方向の中央に置く
Range(Cells(1, 3), Cells(imax + 2, 42)).HorizontalAlignment = xlCenter

09/26/2017

燧ケ岳登山と御池古道を歩く計画

2017/9月上旬より、青森の八甲田山を歩く計画を立てて、紅葉のタイミングと天気予報を見ているが、なかなかいいタイミングにならない。

それで、他の場所の天気予報と紅葉の状況を調べてみて、今週、燧ケ岳と御池古道を歩くことにした。

当初、2017/9月29日の関越交通の夜行バスで大清水に入り、翌日9月30日に燧ケ岳を登り、御池古道を歩きたいと思ったが、9/25の夜に夜行バスの予約を調べると、9/29(金曜日)出発の便は、既に満車状態となっていた。

山歩きの日程を前後させた時、天気予報はどうなのかと「http://www.myweather2.com/Hill-and-Mountain/Japan/Oze-Tokura.aspx?sday=3」で調べてみると、当初予定の登山日30日(土)の「尾瀬・戸倉」の天気予報は、細かな雨が降る可能性があり、午前9時頃の雲の量は、8割ほどあるような状況であることが分かった。

それで、上記のツールを使って、当初計画の前日29日(金)の天気予報の状況を調べてみると・・・、雨はほとんど降らず、午前9時頃には晴れ間もあるように表示された。それで早速、28日の夜行バスを予約することにした。

バスを予約した約1時間後、このブログを書くために、「尾瀬・戸倉」の天気予報の状況を再度確認してみた。午前9時の雲の量は90%に近い状況に変わっていた。
天気予報は、他に「てんきとくらす 燧ケ岳」、「10日間天気予報 尾瀬」等でも調べているが、天気は、下り坂なのかもしれない。

バスの切符を買おうか、どうしようか・・・迷う所だ。切符の予約成立条件は、本日中に購入という事なので、本日午後6時頃まで待って、天気の様子をみて見る事にしよう。

駄目なら、10月1日(日曜日)に出発して、月曜日に歩くという事も考えてはみるが・・・1日は、「ロングウォークちちぶ路」のイベントが計画されており、今年は是非参加したいと思っており、月曜日は町のトレーニングジムでの運動があることから・・・どの計画を採用するか、悩ましい。

《その後》
26日(本日)の午後5時半に、天気予報
http://www.myweather2.com/Hill-and-Mountain/Japan/Oze-Tokura.aspx?sday=3を確認してみると、天気はまずまずの状況になったので、近くのコンビニエンスストアでチケットを購入してきた。

歩行予定のルートをGarminのBaseCampで作成してみた。ルートは画面下側より上に向かって描かれたマゼンダ色の線である。
Oshimizuhiuchimtmiikenanairi_routeハイライトは、燧ケ岳登山、熊沢田代・広沢田代、御池古道である。


09/21/2017

計画:大杉谷から大台ヶ原までを縦走したい

NHKアーカイブスで大杉谷から大台ヶ原までの秋のトレッキングを放送していたのを見て、ますます行きたくなった。
大台ヶ原から大杉谷へ下りたいという計画を2013年に立てていながら、未だ実行に移していなかった。それで、NHKの放送内容を参考に、もう一度計画を練り直してみることにした。

具体的な計画を策定するに際して、下記の情報を集める必要がある。
1)JR三瀬谷までどうやってアクセスするか?
  安価な交通手段である夜行バスを使ってアクセスすることが出来るだろうか?
2)道の駅奥伊勢おおだいから大杉谷登山口まで行くバス「大杉渓谷登山バス(予約制)」の発車時刻は、どうなっているか?
3)大台ヶ原の登山可能な日程(入山規制)は?
4)大台ヶ原から自宅までの帰宅スケジュールは、どのようになるか。

《検討》

1)先ず、前記2)の
大杉渓谷登山バスの時刻表を確認してみた。
 「エス・パール交通」が運行している。出発日の3日前までに予約しなければならない。

 「ツアー名:登山口行コース」

  『道の駅奥伊勢おおだい』10:30発。
  『奥伊勢フォレストピア』10:45発(予約がない場合は止まりません)
  『大杉谷登山センター』 トイレ休憩 登山届提出
  『大杉峡谷登山口』12:00到着 
    ツアー料金 1名 2,500円 最少催行人数4名より となっている・・・
    4人以下なら決行できないか・・・

Oosugidani Photo  更に調べてみると、廃止代替路線バスがあるが、「大杉」までしか行かない。
 バス停「大杉」と登山口までの距離は、どの程度なのか?
調べてみると、左図のようになり、徒歩で2時間半かかる。バス停「大杉」到着時刻は11:28なので、これでは登山口到着時刻が午後2時になってしまう。10月中旬、陽があるうちに山小屋に到着するのは到底無理と思われる。

したがって、この計画でJR三瀬谷駅側から大杉谷を目指すのは到底無理かもしれない。
タクシー料金を調べてみよう・・・

 距離的に近いJR船津駅から大杉谷登山口までの距離は、32.2kmあり、車で約1時間半かかるとのGoogleMap結果である。「タクシー料金を調べる」というサイトで料金を検討すると、普通車で約11000円ほどかかることが分かった。これでは、3人ぐらいで組まないと、ちょっと料金の負担が大きい。


2) 4名参加者が集まり、登山バスが運行したと想定すると、JR三瀬谷駅にはどのようにしてアクセスするか・・・

    『道の駅奥伊勢おおだい』10:30発に乗車するためには、JR三瀬谷駅には10時には到着していたい。

  三重県尾鷲行きの夜行バス(片道@7700円、3列独立席)は、紀伊長島(国道422号と県道751号の交差点付近)に停車する(到着予定時間は、午前05:47である)。そのバス停からJR紀伊長島駅までのアクセスは平坦な道を 約1.5km歩けば到着できる。GoogleMapでは、歩行時間は約22分かかるとなっている。
  JR紀伊長島駅発 08:01 ⇒ JR三瀬谷駅着 08:38 となる。(2017/10/11で検討)

 三重県尾鷲行きの夜行バスが紀伊長島の次に停車するのは、尾鷲駅の手前、JR相賀駅の近くにある三重交通海山営業所(到着予定時間は、午前06:07である)である。ここならJRの駅まで約400mの距離の場所になる。駅までは10分とかからないだろう。

  JR相賀駅発
(JR紀勢本線・多気行 07:39 ⇒ JR三瀬谷駅着 08:38 となる。(2017/10/11で検討

三重交通海山営業所で降車する方が、無駄に歩かなくても良いので便利そうだ。

3)大台ヶ原の入山規制
  毎年11月下旬から翌年4月下旬までが冬季閉鎖期間
  大和上市駅~大台ヶ原までの奈良交通バスは、11月23日が最終日
  でも、10月末以降では、きっと紅葉は期待できないだろう。

4)大台ヶ原発 大和上市駅行バス(奈良交通バス)
  最終の定期運行バスは、 15:30 (平日、土休日共)となっている。
  上市駅到着予定時間は、 平日 17:23、土休日 17:21

  奈良か京都まで行き、帰路も夜行バスを使えるだろう。

5)大杉谷での宿泊を調べなければ・・・



大台ヶ原だけ歩くコースについても考えてみると・・・

大台ヶ原で入山許可が不要な「東大台」の紅葉を見に行く案について考えてみる。ビジターセンターから正木峠や大蛇嵓を廻ると約9kmになるらしい。開山期間は例年4月下旬から11月下旬で、冬期は入山できない。

大台ヶ原の紅葉は、例年10月中旬頃になるか・・・

大和上市駅から大台ヶ原までバスで約1時間45分

先ず、関東から奈良駅まで夜行バスでアクセスし、奈良駅から大和上市駅まで近鉄線で行く。あるいは、京都駅で下車して、京都から大和上市駅まで近鉄線でアクセスする。

後者の方が、奈良駅での乗り換え時間を有効に使えるので良さそうだ。

06:06 近鉄京都線急行・橿原神宮前行 @1230
    3番線発(乗車位置:前[4両編成]・前[6両編成]) / 3番線着
07:12 着
07:18 発 橿原神宮前 で近鉄吉野線急行・吉野行へ乗換
    5番線発 / 1番線着
08:04 着 大和上市駅

大台ヶ原 探勝日帰りきっぷがお得らしい 京都駅から(近鉄電車発駅〜大和上市駅までの往復乗車券)+バスのチケット(奈良交通バス上市駅〜大台ヶ原までの往復乗車券)+(大台ヶ原物産店でのポストカード引換券)を入れて(往復)京都駅で購入すると @5,440円 (チケットを其々別々に購入すると、@1230x2+@2000x2=6460円になるので、1000円ほど節約できる)

往路のバス @2000

09:00 発 上市駅
10:51 着 大台ヶ原

大台ヶ原散策モデルコースを歩いて・・・

復路は、

15:30 発 大台ヶ原
17:23 着 上市駅

ここから京都まで戻って、夜行バスで帰宅・・・

09/07/2017

関東から八甲田山と岩手山を歩きに行くプラン

東北の秋の紅葉を見に、八甲田山と岩手山を歩きに行きたいと思い、プランを立ててみることにした。7月の岩木山と八甲田山を歩きに行ったことはあるが、秋は初めてだ・・・

ざっくりとした計画は、
 ①関東から青森駅まで夜行バスで移動し、
 ②青森駅から定期路線バスで
酸ヶ湯温泉まで行き、八甲田山を歩いて、
   酸ヶ湯温泉から青森駅まで戻る。
 ③青森駅から盛岡駅まで高速バスで移動し、岩手山の登山口になるべく近い場所で宿泊。→盛岡駅前周辺で宿泊して、早朝に大更駅まで移動、そこから登山口までタクシー利用。
   とにかく、盛岡駅西側のバス路線は少ないので、タクシーを使うしか手は無さそうだ。
 ④早朝に「焼走りコース」から登り、バス停のある御神坂駐車場の方向に降りる計画を考える。バスに乗れる時間に降りられれば、盛岡駅までバスで行くことが出来る。
  また、網張温泉に降りるという案も考えられるが、歩行距離が少し長くなるので、ゆっくり温泉に浸かる時間は無さそうだ・・・。
 ⑤盛岡駅から夜行バスで帰省する。
 あるいは、盛岡駅で更に一泊して、翌日八幡平を歩くという事もできそうだ。

上記のような計画とし、もう少し細かく時間をチェックしてみよう。

《もう少し具体的な計画》
①関東から青森までの夜行バス
 夜行バス比較ナビ でシートタイプ・価格・到着時間を調べる。以前価格が安価だと思い、4列のシートで東京から青森まで行ったが、隣席の人柄によっても居心地が大きく変わる。僕はその時は殆ど眠れなかったため、岩木山の登山は力が出ずに大変な思いをした。そのため、価格は少し高くても 3列独立シートが良い。しかし、みずうみ2号に乗るためには、青森駅到着時刻は午前7時30分ごろまでには到着していたい。
 夜行バスの青森駅到着時刻は、酸ヶ湯温泉行きのバスの時刻表を確認して、夜行バスを決める必要があるが、僕が見つけることが出来たのは「パンダスカイ 20:30上野駅発⇒青森駅着 06:50」。これは、4列シートしか無いのだ!

②青森駅から酸ヶ湯温泉迄のバス

 青森駅発 酸ヶ湯温泉行バス の時刻表 
  みずうみ2号に乗れるようであれば、青森駅発の時刻は 7:50am で、酸ヶ湯温泉到着時刻は 9:18am である。(平成29年4月10日~平成29年11月12日

 自分が夏に八甲田山を歩いた際の歩行時間を確認してみると、

以下のようになっていた。

07:43 駅前のバス停にJRバスが到着
  途中、かやの茶屋でトイレ休憩
08:53 酸ヶ湯温泉着
09:04 登山開始
09:06 酸ヶ湯薬師前
10:33 仙人岱ヒュッテ分岐
10:35 八甲田清水
10:40 小岳分岐
11:16 鏡沼(かがみぬま)
11:25 大岳山頂
         山頂で8分ほど休憩
11:54 大岳避難小屋
        昼食(約17分休憩) ⇒この時間は多少短縮できるだろう。
13:09 280段の木の階段
        下毛無岱の休憩所で約30分休憩 ⇒この時間も多少短縮できるだろう。
14:37 酸ヶ湯温泉着(登山終了)
16:45 酸ヶ湯温泉発
17:45 新青森駅着
18:03 青森駅着

③酸ヶ湯温泉から青森駅行きのみずうみ5号の時刻表
 確認すると、9/19~11/17の間の酸ヶ湯温泉発時刻は、14:53pmである。これを逃すと、次は約2時間後のバスまで待たねばならない。
14:53pm
酸ヶ湯温泉発のバスに乗車できれば、青森駅着時刻は、16:14pmである。


④青森駅から盛岡行き高速バスに乗車
    バスの出発時刻まで約1時間あるので、駅弁などを購入して、バス内で食事するか・・・
  17:20pm青森駅前発 ⇒ 20:04pm盛岡駅西口着 @3300円

この時刻だと、駅前に宿泊して、大更駅へは
翌日に鉄道で行くのが良さそうだが・・・
(大更(おおぶけ)駅前のビジネスホテル西根(0195-75-1800)


  因みに、大更まで行ける午後8時15分以降の列車は、
  IGRいわて銀河鉄道荒屋新町行き があり 20:40pm
盛岡駅発 ⇒ 21:18pm大更駅着

盛岡駅前の宿泊場所を選べば、・・・ 夕食は少し時間が遅いが、居酒屋でという選択肢も可能だ。
  ・ホテル ジン(シングル @3,704~13,704円/人 )
  ・東横イン盛岡駅前
シングル @5,800円
  ・R&Bホテル盛岡駅前(シングル 凡そ@5,500円)
  ホテルエース盛岡(盛岡駅から徒歩約10分 朝食付き5800円、2017/06/10 ヤマレコより)
  大更駅周辺の宿泊なら、駅前に
  ・ビジネスホテル西根(電話: 0195-75-1800)がある。


⑤盛岡駅から大更(おおぶけ)駅まで

  登山用の昼食等の手配は、前日か当日、盛岡駅で購入すること。
  
大更駅前には、コンビニなどは一切無さそうである。

    5:06am 盛岡駅発IGRいわて銀河鉄道大舘行き ⇒ 5:42am 大更駅着
  6:55am 盛岡駅発IGRいわて銀河鉄道大舘行き ⇒ 7:35am 大更駅着

⑥大更駅から焼走りの登山口まで
  タクシーで約15分

   駅の近くのタクシー会社は、
     西根観光タクシー(株)  電話:
0195-76-3131
     平舘タクシー大更営業所 電話:0195-76-2525

    《参考》滝沢駅→(みたけタクシー Tel:0196-88-1335
)→馬返しキャンプ場:3480円(2017/06/10:ヤマレコより)

⑦登山コース

   タクシーで登山口への到着時刻: 8:00頃と考えて・・・

 ・登り:焼走りコース(ヤマケイオンラインで見積)
    登山口(焼走りの湯)8:00→第2噴出口跡9:30(5分)→ツルハシ10:45→平笠不動避難小屋11:45(10分:昼食)→岩手山(薬師岳)12:35→不動平避難小屋13:05(5分)→御神坂駐車場(バス停)15:20

 もう一つの案は、松川渓谷で一泊し紅葉を見て、その後、八幡平山頂まで足を延ばすという計画を思いついた。
 ・この場合には、
登り:焼走りコース登山口(焼走りの湯)から松川温泉に入るには、距離が長いため、早朝に出発する必要がある。
  
⑧登山後の盛岡駅までのアクセス
  御神坂駐車場(バス停)発 盛岡バスセンター行きは、16:24(最終バス)発
 盛岡駅前到着予定時刻は、17:10着
 
 滝沢相の沢温泉まで歩き温泉で疲れと汗を流せれば・・・と思って調べたけど、閉業(源泉くみ上げポンプの故障のため
平成28年10月1日から休業、12月31日で廃止)しているようです。それならば、登山は休憩時間をもう少しとって・・・

 もし、下記のような計画で 松川温泉側に降りた場合、
《焼走り(07:00)・・・第2噴出口跡(08:30)・・・ツルハシ(09:40)[休憩 5分]・・・平笠不動避難小屋(10:45)[休憩 5分]・・・岩手山(薬師岳)(11:30)[休憩 5分]・・・不動平避難小屋(12:05)[休憩 5分]・・・分岐(12:50)[休憩 5分]・・・大地獄(13:25)・・・切通し(13:40)[休憩 5分]・・・姥倉分岐(14:15)・・・源太ヶ岳登山口(15:55)

 松川温泉発盛岡駅方面行きは、16:20発となっている。あまり余裕は無いが・・・

⑨立ち寄り湯
 1) 盛岡駅南側の雫石川を渡ったところに、「開運の湯」(電話:019-656-4126)という立ち寄り湯がある。その立ち寄り湯から盛岡駅までは、1.6km徒歩出20分ほどの場所である。
 営業時間は、午前10時から夜中の午前0時までのようだ。

 2) 盛岡駅の北東方向に「ながまち梅の湯」がある。こちらは、駅から650mであり、徒歩約10分。ただし、営業時間は21:50まで。

⑩夜行バス出発までの待機場所
 
盛岡駅南口2階の待合室が24時くらいまで空いているらしい。新幹線の改札の手前あたり。元々、ドトールの店舗を兼ねた待合室として作られたので明るくて座席数もあって人も適度にいるとの事。(Yahoo!知恵袋より

 ・盛岡駅から東京方面行きの夜行バスは、金曜日の利用料金が特に高額なので、要注意!
 ・ドリーム盛岡(らくちん)号盛岡駅東口1番22:30発は、
  月~木曜日:@6500円、金曜日:@8500円
  池袋駅東口 5:25着

⑪山の天気予報

  ・八甲田山の(日本気象協会)天気予報
  ・岩手山の(日本気象協会)天気予報
  ・青森市10日間天気予報
  ・盛岡市10日間天気予報

⑫ライブカメラ
  気象庁八甲田山(大川原)のライブカメラ八甲田山(地獄沼)のライブカメラ
  国土交通省 岩手山のリアルタイム情報
  八甲田山、酸ヶ湯温泉ライブカメラ
  青森県の地図と雨雲の様子(雨雲レーダー)
 
⑬紅葉情報
 ・青森県観光情報サイト アプティネットより 平成29年度 青森県内の紅葉情報
 ・八甲田山紅葉情報(八甲田ロープウェイ)
 ・松川渓谷の紅葉情報
 ・八幡平紅葉情報


⑭松川温泉から八幡平頂上まで行けるバスの連絡便
 ・平成29年度『八幡平自然散策バス ~夏号・秋号~』
  秋号(10/1~10/22): 
   松川温泉発 10:33 ⇒ 八幡平頂上着 11:00
   八幡平頂上発 14:50 ⇒ 盛岡駅前着 16:55

   岩手県北バス
定期運行バスの場合
   八幡平頂上発 15:35 ⇒ 茶臼口発 15:45 ⇒ 盛岡駅前着 17:28

  参考コース) 
 レストハウス⇒鏡沼・眼鏡沼⇒頂上⇒ガマ沼・八幡沼展望台⇒源太別⇒見返り峠⇒レストハウス: 所要2時間30分

 2015年9月に僕が歩いた
トレッキングコースは、
八幡平の駐車場(レストハウス)→鏡沼→八幡平山頂→展望台→八万沼→源太森→茶臼山荘→茶臼口バス停 と辿る 山を下るコースである。 pdf版トレッキングマップが八幡平市観光協会のURLから入手できる。 コース距離 5.9km コースタイム 下り 2時間20分 であった。 (この時の僕のブログ記事

08/30/2017

プリアンプC-2aの冷却

オーディオ・プリアンプC-2aの天板が、夏季は特に高温になるので、冷却するのに良いものは無いかと探していた。ノートPC用の冷却ファンを天地逆にしてC-2aに乗せれば、上手く冷却してくれそうなものを見つけたので、やってみた。
僕が購入したのは、『BESTEK ノートパソコン 冷却台 冷却ファン搭載 ノートPC用クーラー 11.6~17インチ対応 BTCPN2BK
』 Amazonで1580円(配送無料)。

ファン音も極めて静かなので、音楽を聴くときの邪魔にならない。

Img_20170830_094808画面背面からこちら側に風を吹かせるノートPC用の冷却ファン。
上面(画面)側には、ノートPCを置いても風が抜けていくように、多くの溝が作られている。
Amazonの紹介記事では、ファンの駆動方法は液圧駆動とある・・・。

サイズ:38×28×3cm
重量:約720g、素材:ABS、作動電圧;DC 3.5~5.0V、
作動電流:<5.0mA 、ファンのサイズ:φ16cm(二つ) 、
ファンの回転スピード:800±200 RPM 、付属品:USBケーブル



Img_20170830_094840 これが、冷却ファンの裏面側で、空気を取り入れ口側になる。C-2aの上面に この形で載せる。

この面から空気を取り入れて、裏面側に風を吹き出す。
風の強さは、それほど強くない。
写真の装置手前側に、電源スイッチ、パイロットランプとUSBケーブルの差込口が2箇所設けられている。
添付のUSBケーブルの長さは50cmほどしか無いので、僕はUSBの差込口をラック後面側にした。



Img_20170830_101208_3

ラック内のプリアンプC-2aの上に乗せようとしているところ。
ラックの上下間隔が30mmほどと狭いため、風が周るだろうか・・・少し心配ではある。因みに、このファンの厚みも30mm。







Img_20170830_172116
C-2aの温度をもう少し下げるために、ファンの風量がもう少し欲しいなぁと思って、裏ブタを明けてみたが、USBからの5Vでドライブしているだけだった・・・残念!






.


Unnamed_1_2 HiLetgo 2A DC-DC ブーストステップアップ 転換モジュール Micro USB 2V-24V to 5V-28V 9V 12V 24V を購入した。中国から約6日間で到着した!早速これに組み込んで電圧を少し上げてみることにした。
オリジナルの基板の回路図を読んで、基板の一部をカットした。
そこに、下図のように配線を半田付けして、テスターを見ながら可変抵抗のネジを回して出力電圧を7Vに設定した。(5V入力に対して、初期設定は14Vになっていた。)




Img_20170906_170401_3Img_20170906_175625_2 Img_20170906_202835



07/23/2017

Arduino を使ってexercise の音楽と時間管理をしたい

Aruduinoを使ってエクササイズの音楽と時間管理をしてみたい。
先ずは、Arduinoで時間管理が出来るのか・・・試してみなければ・・・。

《リモコンで、
こんなことがしてみたい
①いわゆるラジカセの電源ON/OFF
②音楽の演奏順や演奏番号を指定
③ボリュームの増減や音量の指定

僕が現在想定しているラジカセは「東芝製 SD/USB/CDラジオ TY-CRX71(W)」で、メディアはSDカードを考えている。

この機種は、SDカードを挿入しておいて本体の電源を入れても、SDカードが認識されないので、確認不十分だが、リモコンで出来る操作はOFFのみかもしれない。
リモコンによるプログラムの手順などを確認する必要がある。
リモコンにある音量ボタンは「-/+」だけなので、Arduinoでどのようにすれば音量を変えられるか、確認する必要がある。

以上のような、確認不十分な課題があるが、とにかくArduinoで時間管理できれば、いわゆるラジカセは別のものに変更して、よりコントロールの行いやすいものにするという方法もあるだろう。

Img_20170723_171122 それで、Arduinoを使って時間管理するスケッチを作ってみることにした。

時間制御関数を調べてみると、Arduinoにはミリ秒やマイクロ秒で制御できる関数がある。この関数を使えば、開始時間からの制御が出来る。
時間関数については、Arduinoがスタートしてからの時刻のずれが問題にならないようにするため、

 millis() :Arduinoが起動してからの時間(ミリ秒)を返す

を使うことにした。また、時間をチェックするところは、ユーザー関数を作成した。

次に、エクササイズの決められた実行時間(1分間)と休憩時間(1分間)を、ほぼ正確に繰り返し(エクササイズ8回と休憩7回後、5分間の休憩を)制御するようにするため、繰り返しした際の条件判定・制御文をどうすれば良いか、随分迷った。
これに関連する制御文は、
 ① (if と) for を組み合わせた制御文
   for(初期処理;条件;変更処理){処理群}

 ② while 制御文
   while(条件){処理群}

 ③ do-while 制御文
   do{処理群}while(条件)

僕は、上記の制御文を試してみて、エクササイズの繰り返し判定には①を、時間の判定には③を用いて下記のようなスケッチを作成した。

リモコンの制御部分は、ここでは print文としてスケッチを作成してある。後で制御コードを調べた後に組み替えたい。

処理速度が速くないArduinoなので、Arduinoは2台の構成を考えている。
・ 1台は親機で、時間管理とラジカセの添付リモコンに代り、リモコンデータを送信する。
・ もう一台は、子機で、親機からの別のリモコンデータを受信して、MP3データで作成された音声を発音する。これは、以前のブログで紹介した記事「TVリモコンを使ってArduinoを喋らせる」を参考に作ることになると思う。

これらの詳細は、次回以降明らかに出来ると思う。ここでは、自分用のメモとして、下記Sketchをここに書いておく。

《時間管理のSketch案》

// Arduino を使った時間管理のための sketch
// 音量位置 Vol1:min, Vol2:med, Vol3:max
//
long i=0;
int  n=0;
int  m=0;
unsigned long atime;  // 告知時刻
unsigned long    tc;  //
unsigned long   tc2;  //
unsigned long t0 = millis();  // 時刻の初期化

// セットアップ
void setup(){
  Serial.begin(9600);
// CD  Playerへの指示
  Serial.println("Player の 電源ON");
  Serial.println("Player の 音楽を選択する");
  Serial.println("Player の Play!");
  
// CD  Playerへの指示
  Serial.println("Player の 音量 Vol1 へ");
  
  atime =15;
  
// ここから カウンター m=0 から 3回ループする
for (m=0; m<3; m++){
  Serial.println(" ");
  Serial.print("m = ");
  Serial.println(m+1);
  
// MP3 Playerへの指示:15秒前と告知する
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  Serial.println(" ");
  Serial.println("スタート15秒前です!");

  atime = atime + 5;  // 5秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  Serial.println(" ");
  Serial.println("10秒前です!");
  
// ここから カウンター n=0 から 8回ループする *****基本の運動ループ部分*****
for (n=0; n<8; n++ ){
// CD  Playerへの指示
  Serial.println("Player の 音量を Vol1 へ");
  
  Serial.print("n = ");
  Serial.println(n);
  
  atime = atime + 5;  // 5秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  Serial.println(" ");
  Serial.println(" 5秒前です!");
  
  atime = atime + 2;  // 2秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  tone(8, 440);
  Serial.println(" ");
  Serial.println(" 3秒前です!");
  noTone(8);
  
  atime = atime + 1;  // 1秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  tone(8, 440);
  Serial.println(" ");
  Serial.println(" 2秒前です!");
  noTone(8);
  
  atime = atime + 1;  // 1秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  tone(8, 440);
  Serial.println(" ");
  Serial.println(" 1秒前です!");
  noTone(8);
  
  atime = atime + 1;  // 1秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  tone(8, 880);
  Serial.println(" ");
  Serial.print(n+1);
  Serial.println(" 回目の 1分間エクササイズ Go!!!!!!!!!!!!!!");
  noTone(8);
// CD  Playerへの指示
  Serial.println("Player の 音量を Vol3 へ");
  
  atime = atime + 55;  // 55秒後に告知
  CountTimer( atime);
// CD  Playerへの指示
  Serial.println(" ");
  Serial.println("Player の 音量を Vol1 へ");

  atime = atime + 2;  // 2秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  tone(8, 440);
  Serial.println(" ");
  Serial.println(" 3秒前です!");
  noTone(8);

  atime = atime + 1;  // 1秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  tone(8, 440);
  Serial.println(" ");
  Serial.println(" 2秒前です!");
  noTone(8);
  
  atime = atime + 1;  // 1秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  tone(8, 440);
  Serial.println(" ");
  Serial.println(" 1秒前です!");
  noTone(8);
  
  atime = atime + 1;  // 1秒後に告知
  Serial.print("atime=");
  Serial.println(atime);
  CountTimer( atime);
  tone(8, 880);
  Serial.println(" ");
  Serial.print(n+1);
  Serial.println(" 回目の 1分間 Brake!!!!!!!!!!!!!!!!!!!!!!!");
  noTone(8);
// CD  Playerへの指示
  Serial.println("Player の 音楽を変更する");
  
  atime = atime + 50;  // 50秒後に告知
}
// 5分間休憩の時間をセット
  atime = atime - 50;
  atime = atime + 5*60 - 15;  // 4分45秒後に告知
  Serial.println(" ");
  Serial.print(m+1);
  Serial.println(" 回目の 5分間 Brake!!!!!!!!!!!!!!!!!!!!!!!");
// CD  Playerへの指示
  Serial.println("Player の 音量を Vol2 へ");
}
// CD  Playerへの指示
  Serial.println("Player をストップさせる");
  Serial.println("Player の電源 OFF");
}
void loop() { }
int CountTimer(unsigned long tsec)
{ // 時間をカウントチェックするためのユーザー関数
  // t0   : 正となる時刻
  // tsec : このサブプログラムで秒読みする時間

  int i=0;  // millis() を読むカウンター
  unsigned long tc;  // tc  : 現時刻
  unsigned long t2 = tsec*1000;    // t2  : t0からの tsec秒経過した時刻

  tc = millis();
  
  while( tc < t2 ){
  tc = millis();
  i=i+1;
  }
 return;
}

07/18/2017

Arduino で Sonic Radar を作る

Img_20170629_220931 Arduinoと超音波距離センサー「HC-SR04」(秋月電子から購入) を使った電子工作の中に面白いものを見つけたので、作ってみた。

これは、「Sonic Radar」というもので、デバイスから超音波を発して、跳ね返ってきた音を受信し、その時間で距離を計測するというものである。PCの助けを借りると、モニター画面上に映し出された表示結果は、レーダー画像を見ているような雰囲気がある。
参考にさせて戴いたURLは、
「ROBOTIC
TUTORIALS.COM」の中の、Ultrasonic based RADAR である。

ハードウェアの組立は、結線箇所も少なく簡単に出来る。ハードウェアの組立に関しては、多くの他のブログでも紹介記事があるので、参考にするとよい。
しかし、PCの画面に結果を表示するためには、Processingというソフトウェアの助けを借りなければならない。
僕は、Processingに関する知識が今は無いので、ネット上にあるものを拝借して出来るものをいろいろ探し回ってみた。私の組上げたシステムで表示できるもは、なかなか見つからなかった。ようやく見つけたのが、このURLである。どちらのSketch も殆どオリジナルのままである。しかし、表示部分に文字の重なりなどの問題があったので、フォントの大きさを変えたり、表示位置を変更し使わせて戴いている。
(注記:Sketch の中で init pin と言っているのは Trig Pin の事である。 まずArduinoを起動してから、次に Processing を起動してやれば良い。Processing が起動したとき、Arduino側の動きが一瞬停まるが、直ぐに同期して、PCの画面上に画像を映し出してくれる。)

《 Arduino Sketch 》

#include 
/*
code for arduino bord ultrasonic radar system.
*/            
Servo leftRightServo;         // set a variable to map the servo
int leftRightPos = 0;         // set a variable to store the servo position
const int numReadings = 10;   // set a variable for the number of readings to take
int index = 0;                // the index of the current reading
int total = 0;                // the total of all readings
int average = 0;              // the average
int echoPin = 6;              // the HC-SR04's echo pin
int initPin = 7;              // the HC-SR04's Trig pin
unsigned long pulseTime = 0;  // variable for reading the pulse
unsigned long distance = 0;   // variable for storing distance
/* setup the pins, servo and serial port */
void setup() {
  leftRightServo.attach(9);
  // make the init pin an output:
  pinMode(initPin, OUTPUT);
  // make the echo pin an input:
  pinMode(echoPin, INPUT);
  // initialize the serial port:
  Serial.begin(9600);
}  
/* begin rotating the servo and getting sensor values */
void loop() {
  for(leftRightPos = 0; leftRightPos < 180; leftRightPos++) {  // going left to right.
    leftRightServo.write(leftRightPos);
      for (index = 0; index <=numReadings;index++) {  // take x number of readings from the sensor and average them
        digitalWrite(initPin, LOW);
        delayMicroseconds(50);
        digitalWrite(initPin, HIGH);          // send signal
        delayMicroseconds(50);                // wait 50 microseconds for it to return
        digitalWrite(initPin, LOW);           // close signal
        pulseTime = pulseIn(echoPin, HIGH);   // calculate time for signal to return
        distance = pulseTime/58;              // convert to centimetres
        total = total + distance;             // update total

        delay(10);
      }
    average = total/numReadings;    // create average reading
 
    if (index >= numReadings)  {    // reset the counts when at the last item of the array
      index = 0;
      total = 0;
    }
    Serial.print("X");              // print leading X to mark the following value as degrees
    Serial.print(leftRightPos);     // current servo position
    Serial.print("V");              // preceeding character to separate values
    Serial.println(average);        // average of sensor readings
  }
  /*
  start going right to left after we got to 180 degrees
  same code as above
  */
  for(leftRightPos = 180; leftRightPos > 0; leftRightPos--) {  // going right to left
    leftRightServo.write(leftRightPos);
    for (index = 0; index <=numReadings;index++) {
      digitalWrite(initPin, LOW);
      delayMicroseconds(50);
      digitalWrite(initPin, HIGH);
      delayMicroseconds(50);
      digitalWrite(initPin, LOW);
      pulseTime = pulseIn(echoPin, HIGH);
      distance = pulseTime/58;
      total = total + distance;
      delay(10);
    }
    average = total/numReadings;
    if (index >= numReadings)  {
      index = 0;
      total = 0;
    }
    Serial.print("X");
    Serial.print(leftRightPos);
    Serial.print("V");
    Serial.println(average);
   }
}

《 Processing 用のSketch》

/*
Radar Screen Visualisation for HC-SR04
 Maps out an area of what the HC-SR04 sees from a top down view.
 Takes and displays 2 readings, one left to right and one right to left.
 Displays an average of the 2 readings
 Displays motion alert if there is a large difference between the 2 values.
 */
import processing.serial.*;   // import serial library
Serial arduinoport;           // declare a serial port
float x, y;              // variable to store x and y co-ordinates for vertices   
int radius = 350;        // set the radius of objects
int w = 300;             // set an arbitary width value
int degree = 0;          // servo position in degrees
int value = 0;           // value from sensor
int motion = 0;          // value to store which way the servo is panning
int[] newValue = new int[181];  // create an array to store each new sensor value for each servo position
int[] oldValue = new int[181];  // create an array to store the previous values.
PFont myFont;                   // setup fonts in Processing
int radarDist = 0;       // set value to configure Radar distance labels
int firstRun = 0;        // value to ignore triggering motion on the first 2 servo sweeps

/* create background and serial buffer */
void setup() {
  // setup the background size, colour and font.
  size(750, 450);
  background (0); // 0 = black
  myFont = createFont("verdana", 12);
  textFont(myFont);
  // setup the serial port and buffer
  arduinoport = new Serial(this, Serial.list()[0], 9600);
}

/* draw the screen */
void draw() {
  fill(0);                     // set the following shapes to be black
  noStroke();                  // set the following shapes to have no outline
  ellipse(radius, radius, 750, 750);  // draw a circle with a width/ height = 750 with its center position (x and y) set by the radius
  rectMode(CENTER);            // set the following rectangle to be drawn around its center
  rect(350, 402, 800, 100);    // draw rectangle (x, y, width, height)
  if (degree >= 179) {         // if at the far right then set motion = 1/ true we're about to go right to left
    motion = 1;                // this changes the animation to run right to left
  }
  if (degree <= 1) {           // if servo at 0 degrees then we're about to go left to right
    motion = 0;                // this sets the animation to run left to right
  }
  /* setup the radar sweep */
  /* 
   We use trigonmetry to create points around a circle.
   So the radius plus the cosine of the servo position converted to radians
   Since radians 0 start at 90 degrees we add 180 to make it start from the left
   Adding +1 (i) each time through the loops to move 1 degree matching the one degree of servo movement
   cos is for the x left to right value and sin calculates the y value
   since its a circle we plot our lines and vertices around the start point for everything will always be the center.
   */
  strokeWeight(7);             // set the thickness of the lines
  if (motion == 0) {           // if going left to right
    for (int i = 0; i <= 20; i++) {  // draw 20 lines with fading colour each 1 degree further round than the last
      stroke(0, (10*i), 0);    // set the stroke colour (Red, Green, Blue) base it on the the value of i
      line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w); // line(start x, start y, end x, end y)
    }
  } else {                     // if going right to left
    for (int i = 20; i >= 0; i--) {  // draw 20 lines with fading colour
      stroke(0, 200-(10*i), 0);      // using standard RGB values, each between 0 and 255
      line(radius, radius, radius + cos(radians(degree+(180+i)))*w, radius + sin(radians(degree+(180+i)))*w);
    }
  }
  /* Setup the shapes made from the sensor values */
  noStroke();                  // no outline
  /* first sweep */
  fill(0, 50, 250);            // set the fill colour of the shape (Red, Green, Blue)
  beginShape();                // start drawing shape
  for (int i = 0; i < 180; i++) {    // for each degree in the array
    x = radius + cos(radians((180+i)))*((oldValue[i])); // create x coordinate
    y = radius + sin(radians((180+i)))*((oldValue[i])); // create y coordinate
    vertex(x, y);              // plot vertices
  }
  endShape();                  // end shape
  /* second sweep */
  fill(0, 110, 0);
  beginShape();
  for (int i = 0; i < 180; i++) {
    x = radius + cos(radians((180+i)))*(newValue[i]);
    y = radius + sin(radians((180+i)))*(newValue[i]);
    vertex(x, y);
  }
  endShape();
  /* average */
  fill(0, 170, 0);
  beginShape();
  for (int i = 0; i < 180; i++) {
    x = radius + cos(radians((180+i)))*((newValue[i]+oldValue[i])/2); // create average
    y = radius + sin(radians((180+i)))*((newValue[i]+oldValue[i])/2);
    vertex(x, y);
  }
  endShape();
  /* if after first 2 sweeps, highlight motion with red circle*/
  if (firstRun >= 360) {
    stroke(150, 0, 0);
    strokeWeight(1);
    noFill();
    for (int i = 0; i < 180; i++) {
      if (oldValue[i] - newValue[i] > 35 || newValue[i] - oldValue[i] > 35) {
        x = radius + cos(radians((180+i)))*(newValue[i]);
        y = radius + sin(radians((180+i)))*(newValue[i]);
        ellipse(x, y, 10, 10);
      }
    }
  }
/* set the radar distance rings and out put their values, 50, 100, 150 etc.. */
  for (int i = 0; i <=6; i++) {
    noFill();
    strokeWeight(1);
    stroke(0, 255-(30*i), 0);
    ellipse(radius, radius, (100*i), (100*i)); 
    fill(200, 200, 200);
    noStroke();
    text(Integer.toString(radarDist+50), 380, (305-radarDist), 50, 50);
    radarDist+=50;
  }
  radarDist = 0;
/* draw the grid lines on the radar every 30 degrees and write their values 180, 210, 240 etc.. */
  for (int i = 0; i <= 6; i++) {
    strokeWeight(1);
    stroke(0, 55, 0);
    line(radius, radius, radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w);
    fill(200, 200, 200);
    noStroke();
    if (180+(30*i) >= 300) {
      text(Integer.toString(180+(30*i)), (radius+10) + cos(radians(180+(30*i)))*(w+10), (radius+10) + sin(radians(180+(30*i)))*(w+10), 25, 50);
    } else {
      text(Integer.toString(180+(30*i)), radius + cos(radians(180+(30*i)))*w, radius + sin(radians(180+(30*i)))*w, 60, 40);
    }
  }
/* Write information text and values. */
  noStroke();
  fill(0);
  rect(350, 402, 800, 100);
  fill(0, 100, 0);
  text("Degrees: "+Integer.toString(degree), 100, 380, 100, 50);  // use Integet.toString to convert numeric to string as text() only outputs strings
  text("Distance: "+Integer.toString(value), 100, 400, 100, 50);  // text(string, x, y, width, height)
  text("Radar Plot Graph ", 540, 380, 250, 50);
  fill(0, 50, 250);
  textSize(22);
  text("SP ROBOTICS : RADAR ", 570, 480, 650, 200);
  textSize(12);
  fill(0);
  rect(70, 60, 150, 100);
  fill(255, 255, 0); 
  text("Screen Key:", 100, 50, 150, 50);
  fill(0, 50, 250);
  rect(30, 53, 10, 10);
  text("First sweep", 115, 70, 150, 50);
  fill(0, 110, 0);
  rect(30, 73, 10, 10);
  text("Second sweep", 115, 90, 150, 50);
  fill(0, 170, 0);
  rect(30, 93, 10, 10);
  text("Average", 115, 110, 150, 50);
  noFill();
  stroke(150, 0, 0);
  strokeWeight(1);
  ellipse(29, 113, 10, 10); 
  fill(150, 0, 0);
  text("Motion", 115, 130, 150, 50);
}

/* get values from serial port */
void serialEvent (Serial arduinoport) {
  String xString = arduinoport.readStringUntil('\n');  // read the serial port until a new line
  if (xString != null) {  // if theres data in between the new lines
    xString = trim(xString); // get rid of any whitespace just in case
    String getX = xString.substring(1, xString.indexOf("V")); // get the value of the servo position
    String getV = xString.substring(xString.indexOf("V")+1, xString.length()); // get the value of the sensor reading
    degree = Integer.parseInt(getX); // set the values to variables
    value = Integer.parseInt(getV);
    oldValue[degree] = newValue[degree]; // store the values in the arrays.
    newValue[degree] = value;  
 /* sets a counter to allow for the first 2 sweeps of the servo */
    firstRun++;
    if (firstRun > 360) {
      firstRun = 360; // keep the value at 360
    }
  }
}

07/14/2017

Arduinoで(太陽)光の方向を追いかける2軸サーボ(New Algorithm)

Img_20170708_153936 Img_20170708_153958 Img_20170706_101405 Img_20170706_101420













Arduino Nanoで(太陽)光の方向を追いかける装置をブレッドボード上に作ってうまく稼働したので、小さなユニバーサル基板(60mm x 40mm)の上に部品を置いて製作してみた。
ケースも100均ショップで、適当な大きさの円筒形貯金箱を入手したので、その中に基板を入れ、ケース上面にLDRセンサー(前回作ったもの)を装着したサーボを固定した。

装置が新しくなったので、それに併せて光を追いかけるスケッチも自分のオリジナルな発想でロジックを考え、光の方向を探索する時間も短縮できるようにした。その結果、光を追いかける速度は格段に速くなり、室内などでテストした際、室内灯を消灯すると、初期の位置に戻り、点灯すると直ちに灯りの位置を向く。またセンサー部に手を翳すと、手の影を嫌ってより明るい方向を向くように動くので、その仕草がなかなか可愛い。

と書いてから、本当に明るい方向を向いているのだろうか・・・と初期の動きが気になったので、センサーを経度方向約170度分を周して、そこで明るい場所を探索の初期値にするようにスケッチを追加した。
緯度方向は、初期値を決め打ちして、探査をしていないので、そのために初期値の緯度・経度値から位置を確定するまでに少し時間がかかる場合がある。

スケッチは当初のものより少し長くなってしまった。しかし、まあまあ納得がいくようになったのでスケッチを公開することにする。
緯度方向の初期値探査が欲しい場合には、私のスケッチに倣って探せば良いし、経度方向の初期探査が不要なら、(34~55行までと関連のある部分を)外せばいい。それでも大きな問題無く稼働すると思う。

《Sketch》

// The Sunlight Tracker New Algorithm  by Savvy 2017.07.14
//
#include <Servo.h>
Servo servohori;
int svLimitMax = 175;
int svLimitMin =   5;
int servoh     = svLimitMin;   // Initial value of search angle

Servo servoverti; 
int svLimitHigh = 120;
int svLimitLow  =   5;
int servov      =  45;  // Initial value of search angle

// Assign the wireing color to LDRs
int ldrtopl = 2;  // top left LDR Green wiring
int ldrtopr = 1;  // top right LDR Yellow wiring
int ldrbotl = 3;  // bottom left LDR Blue wiring
int ldrbotr = 0;  // bottom right LDR Red wiring

int topl;
int topr;
int botl;
int botr;

int hstep;
int vstep;
int alpha;
int  beta;

 void setup () {
  servohori.attach(10);    // horizontal motor servo  (Blue wiring)
  servoverti.attach(9);    // vertical motor servo  (Green wiring)

// search initial horizontal angle between servo limit min-max angle
  int i    = 0;
  int imin = 0;
  int lx[]  = { 9999, 9999, 9999, 9999, 9999, 9999, 9999};
  int hstp  = (svLimitMax - svLimitMin) / 6;
  int lxmin = 9999;
  alpha = svLimitMin;
  beta  = servov;

  for ( i=0; i<7; i++ )
  {
   lx[i] =  wlight( alpha, beta);
   alpha = alpha + hstp;
   if( lx[i] < lxmin )
   { lxmin = lx[i];
    imin = i;
     }
  }
  delay(200);
  // this is the initial location of horizontal servo
  servohori.write( svLimitMin + hstp*imin );
}
void loop(){
  // Read the servo set angle at the moment
  servoh = servohori.read();
  servov = servoverti.read();
  
  // Read the light number of each LDR
  topl = analogRead(ldrtopl);
  topr = analogRead(ldrtopr);
  botl = analogRead(ldrbotl);
  botr = analogRead(ldrbotr);
  
  // calculate the average value
  int avgtop   = (topl + topr) / 2;   // average of top LDRs
  int avgbot   = (botl + botr) / 2;   // average of bottom LDRs
  int avgleft  = (topl + botl) / 2;   // average of left LDRs
  int avgright = (topr + botr) / 2;   // average of right LDRs

  if( (avgtop < 1012) & (avgbot < 1012) )  // the servo acts while in the light
  {
    hstep = xstep(avgright,avgleft);  // determination of the horizontal serch step angle
    servoh = servoh + hstep;
    
    if((svLimitMin < servoh) & (servoh < svLimitMax))  // acts between max - min limits
    { 
       servohori.write(servoh);
    }
    
    vstep = xstep(avgtop,avgbot);   // determination of the vertical serch step angle 
    servov = servov + vstep;
    
    if((svLimitLow < servov) & (servov < svLimitHigh))
    {
        servoverti.write(servov);
    }       
  }
  delay(200);
}
int xstep(int avg1, int avg2)
  // classify the step value from the two light value
{
  int jcase = avg1 - avg2;
  int result;
    
    if(jcase < -30 ) {
      result = 10; 
    }
    if((-30 <= jcase) & (jcase < -10)){
      result = 3;
    }
    if((-10 <= jcase) & (jcase <  -2)){
      result = 1;
    }
    if(( -2 <= jcase) & (jcase <  2)){
      result = 0;
    }
    if(( 2 <= jcase) & (jcase < 10)){
      result = -1;
    }
    if(( 10 <= jcase) & (jcase < 30)){
      result = -3;
    }
    if( 30 <= jcase ){
      result = -10;
    }
    return result;
}
int wlight(int alpha, int beta)
{
   servohori.write(alpha);
   servoverti.write(beta);
   int loc  = (analogRead(ldrtopl) + analogRead(ldrtopr) + analogRead(ldrbotl) + analogRead(ldrbotr)) / 4; 
   delay(200);
   return loc;
}

07/04/2017

Arduinoで作る太陽光の方向を向く2軸サーボ

Img_20170704_203131 Img_20170629_224615 Arduino Nano (ATmega328)を使って、(太陽)光のある方向を向く2軸サーボ装置を作ってみた。
・Arduinoは、 Nano を
・ServoMotorは、 SG92R を 2個使い
・フォトレジスターは、 手元にあったものを 4個使った。はじめは、抵抗値の基本値を選ぶ必要があるのか・・・と思ったが、ロットが揃っているものなら、それを使って良さそうだ。

Webで見つけたサイト「Arduino Solar Tracker(http://www.electronicshub.org/arduino-solar-tracker/
」などを参考に製作した。

Img_20170704_090341 Img_20170704_090529 Img_20170704_090634 フォトレジスタと抵抗の固定は、小型のユニバーサル基板の上に半田付けし、光の方向を捉え易くするために、写真のように十字型の覆いを設けた。この部分の回路図は、参考にさせてもらったブログの通りであると思う。

基板の後ろから見て、右下(赤色の配線⇒A0)、右上(黄色の配線⇒A1)、左上(緑色の配線⇒A2)、左下(青色の配線⇒A3)とした。

サーボモーターは、水平方向の制御線を水色⇒D10へ、垂直方向の制御線を白⇒D9へと繋いだ。

Solar_trackerflow_chart_20170704 最初、スケッチは参考にしたブログのものをそのまま使ったが、収束に時間がかかる事と、収束した状態でもサーボを動かしているので、左図のようにフローチャートを作成して、収束時間を短縮し、収束したらサーボモータを停めるようにスケッチを変更した。細かな所は、左図を確認すれば解るだろうと思う。


スケッチは、制御の状態を確認したかったので、オリジナルのスケッチに対してシリアルモニターに途中の状態を出力するように追記した。

出力結果を確認し、光源の位置から離れていると思われる場合には、光源に向かうサーボモータ回転角の刻み幅を大きくし、光源に近づいてくると、刻み幅を小さくするようにした。


閾値は明るさの差 eps を”5”としたが、動き方を見て調整するのが良いだろう。

稼働させてみると、光のある方向への収束時間は随分早くなったように思う。

スケッチは、下記のようである。

// The Sunlight Tracker 2017.07.04
//
#include <Servo.h>
Servo servohori;
int servoh = 90;
int servohLimitHigh = 170;
int servohLimitLow = 10;
int hstep = 1;
int eps = 5;

Servo servoverti; 
int servov = 30; 
int servovLimitHigh = 120;
int servovLimitLow = 10;
int vstep = 1;

//Assigning LDRs
int ldrtopl = 2; //top left LDR Green wiring
int ldrtopr = 1; //top right LDR Yellow wiring
int ldrbotl = 3; // bottom left LDR Blue wiring
int ldrbotr = 0; // bottom right LDR Red wiring

 void setup () {
  Serial.begin(9600);   // to check the sketch, print out to the monitor
  servohori.attach(10); // horizontal motor servo  (Blue wiring)
  servohori.write(servoh);
  servoverti.attach(9); // vertical motor servo  (Green wiring)
  servoverti.write(servov);
  delay(500);
 }

void loop(){
  servoh = servohori.read();
  servov = servoverti.read();
  Serial.print("Location of Servo   Horizontal:");
  Serial.print(servoh);
  Serial.print("deg,  Vertical:");
  Serial.print(servov);
  Serial.println("deg");
  
  //capturing analog values of each LDR
  int topl = analogRead(ldrtopl);
  int topr = analogRead(ldrtopr);
  int botl = analogRead(ldrbotl);
  int botr = analogRead(ldrbotr);
  Serial.println(" ");
  Serial.println("Captured LDR value ");
  Serial.print("TL:");
  Serial.print(topl);
  Serial.print("  TR:");
  Serial.println(topr);
  Serial.print("BL:");
  Serial.print(botl);
  Serial.print("  BR:");
  Serial.println(botr);
  
  // calculating average
  int avgtop = (topl + topr) / 2;   //average of top LDRs
  int avgbot = (botl + botr) / 2;   //average of bottom LDRs
  int avgleft = (topl + botl) / 2;  //average of left LDRs
  int avgright = (topr + botr) / 2; //average of right LDRs

  if (avgtop < avgbot) {
    Serial.print("Average Value  ");
    Serial.print("Top:");Serial.print(avgtop);
    Serial.print(" < ");
    Serial.print("Bottom:");Serial.println(avgbot);
    
    vstep = abs(avgtop-avgbot);
    if( vstep < eps ){
      Serial.println("Top is lighter than Bottom =< turn Up");
      vstep = 1 + vstep/4;
      Serial.print("servov = ");Serial.print(servov);Serial.print("+");
      Serial.println(vstep);
      servoverti.write(servov + vstep); 
      }
    else {  // to stabilize the servo-motor
      Serial.print("|Top-Bottom|=<");Serial.print(eps);
      Serial.println(" then Stop the Vertical servo");     
    }
    if (servov > servovLimitHigh) { 
      servov = servovLimitHigh;
     }
    delay(10);
  }
  else if (avgbot < avgtop) {
      Serial.print("Average Value of LDR  ");
      Serial.print("Bottom:");Serial.print(avgbot);
      Serial.print(" < ");
      Serial.print("Top:");Serial.println(avgtop);

    vstep = abs(avgtop-avgbot); 
    if( vstep > eps ){   
      Serial.println("Bottom is lighter than Top => turn Down");
      vstep = 1 + vstep/4;
      Serial.print("servov = ");Serial.print(servov);Serial.print("-");
      Serial.println(vstep);     
      servoverti.write(servov - vstep);
    }
    else {  // to stabilize the servo-motor
      Serial.print("|Top-Bottom|=<");Serial.print(eps);
      Serial.println(" then Stop the Vertical servo");       
    }
    if (servov < servovLimitLow) {
    servov = servovLimitLow;
    }
    delay(10);
  }
  else {
  }
  
  if (avgleft > avgright) {
      Serial.print("Average Value of LDR  ");
      Serial.print("Left:");Serial.print(avgleft);
      Serial.print(" > ");
      Serial.print("Right:");Serial.println(avgright);

      hstep = abs(avgleft-avgright);
    if( hstep > eps ){  
      Serial.println("Right is lighter than Left => turn Right");
      hstep = 1 + hstep/4;
      Serial.print("servoh = ");Serial.print(servoh);Serial.print("+");
      Serial.println(hstep);
      servohori.write(servoh + hstep);
    }
    else {   // to stabilize the servo-motor
      Serial.print("|Left-Right|=<");Serial.print(eps);
      Serial.println(" then Stop the Horizontal servo");         
    }
    if (servoh > servohLimitHigh) {
    servoh = servohLimitHigh;
    }
    delay(10);
  }
  else if (avgright > avgleft) {
      Serial.print("Average Value of LDR  ");
      Serial.print("Right:");Serial.print(avgright);
      Serial.print(" > ");
      Serial.print("Left:");Serial.println(avgleft);    

    hstep = abs(avgleft-avgright);
    if( hstep > eps ){   
      Serial.println("Left is lighter than Right => turn Left");
      hstep = 1 + hstep/4;
      Serial.print("servoh = ");Serial.print(servoh);Serial.print("-");
      Serial.println(hstep);     
      servohori.write(servoh - hstep);
    }
    else {  // to stabilize the servo-motor
      Serial.print("|Left-Right|=<");Serial.print(eps);
      Serial.println(" then Stop the Horizontal servo");
    }
    if (servoh < servohLimitLow) {
      servoh = servohLimitLow;
     }
    delay(10);
  }
  else  {
  }
  delay(50);
}


《備考》
ここに、
 hstep : 水平方向回転サーボモータの回転刻み角度
  vstep : 垂直方向回転サーボモータの回転刻み角度
 esp : 左右、上下のフォトレジスタから読取った値を比較した際のサーボモータの停止判定値

問題は、周囲が暗くなると、灯りを探し回るので、この動きを止める必要がありそうだ。
多分、フォトレジスタで計測した際の明るさが、ある程度大きくなったら、サーボモータの動きを止めれば良いと思う。これは、次にソーラーパネルと組み合わせる計画があるので、その際に改造するつもりだ。

06/11/2017

Processing 3.3.4 のインストール

Arduino で Sonic Radar の画像処理を行うには、Processingが必要な事が分かったので、早速インストールしてみることにした。
他のアプリと同じようにやってみてもインストールされないし・・・

ネットで調べてみると、「Processing2のダウンロードとインストール」が見つかり、参考にしてWindows64bit版で試してみた。

ところが、解凍しても上手くいかない・・・僕が使った解凍ソフトは、お気に入りの
Lhaplus V1.73 (2017/06/11時点の最新版は 1.74)」だが、エラーが発生し、巧くゆかないようだ。それで「7-Zip」で解凍してみた。問題無く解凍出来る。

Cドライブの Program Files の中に、僕は「Processing」というフォルダを作成し、解凍したファイルを全て移動させた。
参考にさせて戴いたブログのProcessing v2 には「launch4j」というフォルダがあるが、僕が解凍したものでは、そのフォルダは存在していなかったので、解凍内容が少し違っている。

そして、「Processing.exe」のショートカットアイコンをデスクトップに貼り付けた。

Provessing3 デスクトップの『Processing ショートカットアイコン』をクリックすると、左図のように起動した!


05/27/2017

肩を温める USB電源(5V)を使った自作ヒーター

Img_20170527_071241 50肩になってしまった。就寝中に肩が冷えると痛みが増す。肩部を温めるための何かいい方法は無いものかと探していたが、そのようなものは、意外に見つからない。別の電子工作のアイデアを探していた時、カメラレンズや鏡筒のための「結露対策ヒーターの作り方」というブログに出会った。
USB(5V)から電源をとり、1mほどの長さのニクロム線に500mAの電流を流してレンズなどを温めるというアイデアになっている。この方法を応用できないか・・・とやってみた。


僕は、Amazonから これに必要な部品①,②を購入
①単位長さ当たりの抵抗値が、参考にしたブログに記載のものと同等レベルのニクロム線 (557円、送料込み)
  ワイヤ径0.4mm、  抵抗値 8.674Ω/m、 AWG26、 15m巻き
  使うのは1mほどの長さなのだが、この単位でしか購入できなかった。

注記)抵抗線は、線径が細くなるほど単位長さ当たりの抵抗値が高くなる。
 用途に応じて線径を決めるのが良い。
  (例) 矢印(⇒)の右側は、10Ωになる抵抗線(ニクロム線)の概略長さ
    0.7mm - 2.93Ω/m ⇒ 341cm
    0.6mm - 4.103Ω/m ⇒ 244cm
    0.5mm - 5.755Ω/m ⇒ 173cm 
    0.4mm - 8.674Ω/m ⇒ 115cm
    0.3mm - 15.42Ω/m ⇒ 65cm
    0.25mm - 22.21Ω/m ⇒ 45cm

②耐熱ガラスチューブ内径1.5mm (@156円+配送料560円)
  1mの長さがこの値段。使うのは1.2mほどになるので、1mでは短い・・・
  不足する長さの分については、僕は細目の熱収縮チューブを使った。
  実は、細い熱収縮チューブも購入し、ニクロム線をその中に入れようとしたが、50cmほど挿入したところから、挿入する抵抗が高くなり、1mのニクロム線を貫通させることは無理そうなので、耐熱ガラスチューブを使うことにした。この問題は透水性がありそうなので、電気の絶縁性能がどうかな・・・と不安である。

 その他、アッセンブリに必要な部品として、熱収縮チューブ、圧着スリーブ、自己融着テープ、USBケーブル、モバイルバッテリー等があるが、身の回りにあるものから、かき集めた。

参考にしたブログにも注意事項が細かく書かれていたが、
私がここに書いているのは私のメモであって、これと同じようなものを作ろうとして、いかなる事故が起きたとしても、私は一切の責任を負いません。自作するに際しての責任は、全てあなたの自己責任になります。

《作り方》

Img_20170526_115611 Img_20170526_120530結露対策ヒーターの作り方」を参考に、5V、500mAでほのかに温かいという仕様にすべく、抵抗線(ニクロム線)の値も市販品から 8.674Ω/m のものを選んで、入手後プラスチックスケールの上に抵抗線を貼り付け、20cm当たりの抵抗値を実測してみた。
抵抗値は 1.7Ωであった。

そのため、抵抗値が10Ωになるように、抵抗線の長さをほぼ 118cmと決めた。

Img_20170526_125638 Img_20170526_132144 Img_20170526_124651 Img_20170526_132550 ニクロム線は、絶縁のない裸状態なので、ショートさせたりする危険性を避けるために、
耐熱ガラスチューブを被せ、ガラスチューブ長さが不足する両端部を細目の熱収縮チューブを被せて、写真のようにニクロム線を被覆した。
バッテリーに繋いでみたが、この状態ではずっと手で握って居られるほど低い温度である。
多分、
耐熱ガラスチューブの効果が高すぎるのかもしれない。しかし、ガラスチューブ表面の温度は時間が経過すれば、内部も外部も同じ状態(平衡状態)になるはずである。

耐熱ガラスチューブを使わず、熱収縮チューブを使って絶縁するという(参考にしたブログと同じ)方法もあるが、細い熱収縮チューブを使うと、0.4mmの径のニクロム線を1mの長さ通すのは至難の業が必要になる。ガラスチューブは接触抵抗が低いので、難なく通すことが出来る。

肩用のサポータにこのニクロム線を縫い付けるのだが、ニクロム線の長さはある程度必要なため、温度を上げるためにニクロム線長さを短縮したくはないので、当初計画通り10Ωを保持する長さのままとした。

Img_20170526_133605 Img_20170526_161449 Img_20170526_161513 USBケーブルの端を開き、圧着スリーブを用いてニクロム線と接続した。この上にも太めの熱収縮チューブを被せ、その後、自己融着テープを用いて絶縁保護とその部分の補強を行った。


《使用の状況》

温かさ : 組込む前に、もう少し細かく詰めれば良かった。温度は低めで、もう少し上げられれば・・・と思う。

ニクロム線の配置間隔をもう少し詰めた方が良さそうに思う。そのためには、ニクロム線の単位長さ当たりの抵抗値をもう少し低いものを使って、扱える線の長さを延ばし配置すればと考えられる。

例えば前述の「線径-単位長さ当たりの抵抗値」を参考に、0.6mmの線径の抵抗線を使えば、10Ωとするには244cmとれる為、今回使った線径0.4mmの線配置の空いた場所に線を配置できる。そのため、面当たりに近づき、より「ほんわか」した温かさを実現できそうだ。

«Arduino用mp3シールドを使い TVリモコンで指定したMP3ファイル再生

October 2017
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

Recent Trackbacks

無料ブログはココログ