最近、Raspberry Pi を使った電子工作がマイブームです。このテーマでブログを書いていると、デジタル波形のイラストを作成する機会があります。でも、デジタル波形を書こうとするとなかなか手間がかかります。こんなことは誰でも思うことだろうと、ググってみました。
デジタル波形作成ツールという有償ものがありました。無償で試使用もできるので試してみましたが、本格派ツールだったのでどこから手を付けたらよいかわからず、即断念してしまいました。根性なしです。
その他ブラウザ上で作成できるものもありました。こちらは簡単だったんですが間延びした波形しかかけなかった(実は書けたのかもしれませんが方法がわかりませんでした)。こちらも断念しました。
もっとごろごろ出てくるのかなと思いましたが、結局いいのが見つかりませんでした。とうとうDIYerの魂に火が着きました。自分で使いやすいのを作ろう!作っちゃえ!
デジタル波形とは
デジタル波形とは、電圧や電流などの時間的な変化を表した曲線で、離散的(飛び飛び)な値を取る信号の波形です。下の写真はオシロスコープで観察したデジタル信号の波形です。青色の波形と黄色の波形の2チャンネル(2つの)信号です。
この波形をイラストにすると、以下のような感じでしょうか。こちらはエクセルの罫線を使って作成しました。これぐらいの波形であれば、さほど手間はかかりません。
以下のような波形を書こうと思うといやになりますね。上下の信号の関係を維持しながら書く必要があります。これが3本、4本で信号間の位置を合わせないといけないとなると、もうちゃぶ台ひっくり返しそうです。
デジタル波形作成ツールの作成
そこで、デジタル波形を簡単に作成できるツールを作ってみたいと思います。エクセルは全体がマス目になっていることと罫線を使って先ほどのような矩形を書けそうです。あと、エクセルはVBAというプログラム言語を使ってプログラムを作成することができます。VBA(Visual Basic for Applications)とは、Microsoft Officeのアプリケーションで利用できるプログラミング言語です。ExcelやPowerPoint、Accessなどの機能を拡張したり、カスタマイズしたりすることができます。VBAの主な用途は、作業の自動化やデータ処理、システム連携などです。業務の効率化や生産性向上の手段としてよく使われています。
私はMicrosoft 365をサブスクリプション契約しているのでエクセル、ワード、パワーポイントなど使いたい放題です。せっかく契約しているので使わな損々というやつですね。
二日ほど掛けて以下のような仕様で作成しました。
このような部品表を作成しました。デジタル波形を構成する部品に分解してみました。そして、エクセルの罫線で表現できるようにしてみました。各部品に記号としてアルファベットを1文字割り当てました。できるだけ覚えやすいようにしました。
例えば、記号のUはUpの略で立上がりの部品にしました。同様に記号のDはDownの略で立下りの部品にしました。その他、記号のHはHighの略、LはLowの略です。
あと、記号AからZまでは予備です。部品の点線四角の枠内であれば自由に罫線を追加することができます。
次は、色です。色のパターンに合わせて色ラベルとして数字1文字を割り当てました。最後の空は色ラベルがないことを意味しています。その場合は塗りつぶし無しになります。
パターンの色は、自由に変更することができます。パターンのセルの色をエクセルの色の塗りつぶしで変更することができます。
以下の領域がデジタル波形を作成するところです。記号入力の行の黄色マスクの1マスに部品の記号を1文字入力します。同様に色入力の行のピンク色マスクの1マスに色の数字1文字を入力します。また、文字入力の行の緑マスクの1マスに文字または文字列を入力します。色入力、文字入力共必要に応じての入力です。
実際に入力してみたところです。こんな感じで入力するだけです。
マス目にそれぞれ入力した後に波形に変換するコマンドの一覧です。
「波形生成」ボタンをクリックすると記号を波形に変換します。
「色設定」ボタンは、色の数字を色に変換して波形部分を色で塗りつぶします。
「文字入力」ボタンは、波形の文字を設定します。
「コピー」ボタンは、クリップボードに波形をコピーします。必要なところにペーストできるようになります。
最後に、列幅は波形幅を広げたり狭めたりできるようにエクセルのセル幅を変更できるようにしています。
以下は、実際に記号、色、文字を入力した状態で波形を作成した結果です。
以下は、2つの波形を作成して、作業エリアにコピーペーストしたところです。
作成した波形に線を引いたり、吹き出しを追加したりして説明用のイラストを作成できるようになります。
以下がデジタル波形作成ツールの全体像になります。
気づいて追加した機能
デジタル波形作成ツールで波形を作るのはよいのですが、相互に関係する複数本の波形を作成していると最初に作った波形を修正したい時がたびたびあることに気づきました。今のツールでは同時に1本しか作成できません。別の波形を作成しようとすると入力した記号などを削除する必要があります。
削除する前に入力したデータをバックアップしておく必要があります。でも、その手間が邪魔くさいのでログ機能を追加しました。
追加したログ機能は、コマンドのボタンをクリックすると結果をエクセルの別シート(ここではログシート)に記録するようにしました。こうすることで途中の結果もすべて保存することができます。必要な時にログからコピーペーストすれば復元することができます。
エクセルのシートのタブ部分です。ツールは「デジタル波形作成」シートにあります。ログ機能で保存される記録データは「ログ」シートにコピーされます。
以下のようにボタンを押すたびに入力したデータと波形データがコピー(バックアップ)されます。
VBAプログラム
こちらが作成したVBAプログラムです。360行程度です。空行やコメントもあるので実質200行弱でしょうか。できるだけ汎用的にするために2,3回書きなおしました。確認も含めて15時間ぐらいかかりました。
ページの最後にこのデジタル波形作成ツールをダウンロードできるようにしました。
'*****************************************************************************
' 簡単シリーズ
' デジタル波形のイラストを作成するVBAマクロ
'
' Copyright Miyabee-Craft.com
'*****************************************************************************
'
'シート名定義
Const デジタル波形作成シート = "デジタル波形作成"
Const ログシート = "ログ"
' 色とパターンの定義
Const 背景色なしセル = "C13"
' 記号入力範囲の定義
Const 記号入力範囲 = "AJ3:CR3"
' 記号入力の列範囲
Const 記号入力列範囲 = "AJ:CR"
' 色入力範囲の定義
Const 色入力範囲 = "AJ4:CR4"
'文字入力範囲の定義
Const 文字入力範囲 = "AJ5:CR5"
' 生成した波形のセル範囲
Const 出力範囲 = "AJ7:CR7"
' ログ出力範囲のセル範囲
Const ログ出力範囲 = "A1:BI1"
' ログ対象範囲のセル範囲
Const ログ対象範囲 = "AJ3:CR8"
' 記号を波形パーツに変換してデジタル波形を生成する
Private Sub CreateWaveForm_Click()
Dim ws As Worksheet
Dim searchRangeK As Range, searchRangeP As Range
Dim inputRange As Range, outputRange As Range
Dim cell As Range, matchCellK As Range, matchCellP As Range
Dim targetCell As Range
Dim lastRowK As Integer, lastRowP As Integer
Dim i As Integer
' シートを取得
Set ws = ThisWorkbook.Sheets(デジタル波形作成シート)
' 入力範囲
Set inputRange = ws.Range(記号入力範囲)
' 出力範囲
Set outputRange = ws.Range(出力範囲)
' K列の最終行を取得(1つおきに値があるので最後の値まで検索)
lastRowK = ws.Cells(Rows.Count, "K").End(xlUp).Row
lastRowP = ws.Cells(Rows.Count, "P").End(xlUp).Row
' ループ処理でAJ3:CI3の各セルをチェック
i = 0
For Each cell In inputRange
' K列 & P列の範囲を設定
Set searchRangeK = ws.Range("K4:K" & lastRowK)
Set searchRangeP = ws.Range("P4:P" & lastRowP)
Set matchCellK = Nothing
Set matchCellP = Nothing
' K列内で一致するセルを探す
On Error Resume Next
Set matchCellK = searchRangeK.Find(What:=cell.Value, LookAt:=xlWhole)
On Error GoTo 0
' K列で見つかった場合はP列を検索しない
If matchCellK Is Nothing Then
' P列内で一致するセルを探す
On Error Resume Next
Set matchCellP = searchRangeP.Find(What:=cell.Value, LookAt:=xlWhole)
On Error GoTo 0
Else
' K列で見つかったためP列の検索をスキップ
Set matchCellP = Nothing
End If
' K列、P列に該当があれば I列、N列の罫線をコピー
If Not matchCellK Is Nothing Then
' K列に該当した場合、I列の罫線をコピー
Set targetCell = ws.Cells(matchCellK.Row, 9) ' I列の対応するセル
CopyBorders targetCell, outputRange.Cells(1, i + 1)
ElseIf Not matchCellP Is Nothing Then
' P列に該当した場合 N列の罫線をコピー
Set targetCell = ws.Cells(matchCellP.Row, 14) ' N列の対応するセル
CopyBorders targetCell, outputRange.Cells(1, i + 1)
End If
i = i + 1
Next cell
' ログ出力
OutputLog
' オブジェクトの解放
Set ws = Nothing
Set searchRangeK = Nothing
Set searchRangeP = Nothing
Set inputRange = Nothing
Set outputRange = Nothing
Set cell = Nothing
Set matchCellK = Nothing
Set matchCellP = Nothing
Set targetCell = Nothing
End Sub
' セル背景色を変更する
Private Sub ChangeCellColor_Click()
Dim ws As Worksheet
Dim searchRange As Range, inputRange As Range, outputRange As Range
Dim cell As Range, matchCell As Range, colorSourceCell As Range
Dim lastRow As Integer
Dim i As Integer
' シートを取得
Set ws = ThisWorkbook.Sheets(デジタル波形作成シート)
' 入力範囲
Set inputRange = ws.Range(色入力範囲)
' 出力範囲
Set outputRange = ws.Range(出力範囲)
' G列の最終行を取得
lastRow = ws.Cells(Rows.Count, "G").End(xlUp).Row
' ループ処理での各セルをチェック
i = 0
For Each cell In inputRange
' G列で検索
Set searchRange = ws.Range("G3:G" & lastRow)
Set matchCell = Nothing
' G列内で一致するセルを探す
On Error Resume Next
Set matchCell = searchRange.Find(What:=cell.Value, LookAt:=xlWhole)
On Error GoTo 0
' 一致するセルがあれば、そのC列のセルの背景色を取得
If Not matchCell Is Nothing Then
Set colorSourceCell = ws.Cells(matchCell.Row, 3) ' C列の対応するセル
Else
' 空欄の場合、背景色なしのセルを設定
Set colorSourceCell = ws.Range(背景色なしセル)
End If
' 背景色をコピー
CopyBackColor colorSourceCell, outputRange.Cells(1, i + 1)
i = i + 1
Next cell
' ログ出力
OutputLog
' オブジェクトの解放
Set ws = Nothing
Set searchRange = Nothing
Set inputRange = Nothing
Set outputRange = Nothing
Set cell = Nothing
Set matchCell = Nothing
Set colorSourceCell = Nothing
End Sub
' 波形に文字を入力する
Private Sub SetCharacter_Click()
Dim ws As Worksheet
Dim inputRange As Range, outputRange As Range
Dim cell As Range
Dim i As Integer
' シートを取得
Set ws = ThisWorkbook.Sheets(デジタル波形作成シート)
' 入力範囲
Set inputRange = ws.Range(文字入力範囲)
' 出力範囲
Set outputRange = ws.Range(出力範囲)
' G列の最終行を取得
lastRow = ws.Cells(Rows.Count, "G").End(xlUp).Row
' ループ処理での各セルに値(文字)をコピーする
i = 0
For Each cell In inputRange
outputRange.Cells(1, i + 1).Value = cell.Value
i = i + 1
Next cell
' ログ出力
OutputLog
' オブジェクトの解放
Set inputRange = Nothing
Set outputRange = Nothing
Set cell = Nothing
Set ws = Nothing
End Sub
' 罫線をコピーする関数(罫線がある場合のみコピー)
Sub CopyBorders(source As Range, target As Range)
Dim i As Integer
Dim srcBorder As Border, tgtBorder As Border
' すべての罫線(上下左右+斜め)を処理
For i = 5 To 12
Set srcBorder = source.Borders(i)
Set tgtBorder = target.Borders(i)
tgtBorder.LineStyle = xlNone
' 罫線がある場合のみコピー
If srcBorder.LineStyle <> xlNone Then
With tgtBorder
.LineStyle = srcBorder.LineStyle
.Weight = srcBorder.Weight
.Color = srcBorder.Color
End With
Else
' 罫線がない場合はクリア(不要なら削除)
tgtBorder.LineStyle = xlNone
End If
Next i
End Sub
Sub CopyBackColor(source As Range, target As Range)
' 背景色をコピーする
target.Interior.Color = source.Interior.Color
End Sub
' 指定範囲の列幅を変更する
Private Sub ChangeColumnWidth_Click()
Dim ws As Worksheet, logSheet As Worksheet
Dim txtValue As String
Dim colWidth As Double
Dim targetRange As Range, logRange As Range
' シートを取得
Set ws = ThisWorkbook.Sheets(デジタル波形作成シート)
Set logSheet = ThisWorkbook.Sheets(ログシート)
' ユーザーフォームのテキストボックスから値を取得
txtValue = ws.OLEObjects("TextBox_ColumnWidth").Object.Value
' 入力チェック(数値かどうか & 0より大きいか)
If IsNumeric(txtValue) Then
colWidth = CDbl(txtValue)
If colWidth > 0 Then
' 指定範囲の列幅を変更
Set targetRange = ws.Range(記号入力列範囲)
Set logRange = logSheet.Range(ログ出力範囲)
targetRange.ColumnWidth = colWidth
logRange.ColumnWidth = colWidth
MsgBox "列幅を " & colWidth & " に変更しました。", vbInformation, "成功"
Else
MsgBox "数値は0より大きい必要があります。", vbExclamation, "エラー"
End If
Else
MsgBox "数値を入力してください。", vbExclamation, "エラー"
End If
' オブジェクトの解放
Set targetRange = Nothing
Set logRange = Nothing
Set logSheet = Nothing
Set ws = Nothing
End Sub
' 生成した波形をクリップボードにコピーする
Private Sub CopyToClipBoard_Click()
Dim ws As Worksheet
Dim targetRange As Range
Dim cell As Range
Dim lastCell As Range
' シートを取得
Set ws = ThisWorkbook.Sheets(デジタル波形作成シート)
' コピーするセル範囲
Set targetRange = ws.Range(記号入力範囲)
' 初期状態では範囲なし
Set lastCell = Nothing
' 指定範囲の先頭から順に確認
For Each cell In targetRange
If cell.Value <> "" Then
Set lastCell = cell ' 空欄でない場合、最終セルを更新
ElseIf Not lastCell Is Nothing Then
Exit For ' 空欄が出たら終了
End If
Next cell
' 最終セルが見つかった場合、先頭セルから最終セルまでの範囲を設定
If Not lastCell Is Nothing Then
' 波形のセル範囲を選択
targetRange.Resize(1, lastCell.Column - targetRange.Column + 1).Offset(4, 0).Select
Else
' 全部空欄ならNothing
MsgBox "波形は生成されていません。", vbOKOnly, "エラー"
End If
' 波形のセル範囲をコピー
targetRange.Resize(1, lastCell.Column - targetRange.Column + 1).Offset(4, 0).Copy
' メッセージ表示
MsgBox "選択範囲をクリップボードにコピーしました。", vbInformation, "コピー完了"
' オブジェクトの解放
Set targetRange = Nothing
Set lastCell = Nothing
Set cell = Nothing
Set ws = Nothing
End Sub
' 実行結果のログを出力する
Private Sub OutputLog()
Dim wsSource As Worksheet, wsDest As Worksheet
Dim sourceRange As Range, destRange As Range, bottomLeftCell As Range
Dim lastRow As Long
' シートの設定
Set wsSource = ThisWorkbook.Sheets(デジタル波形作成シート) ' 元データのシート
Set wsDest = ThisWorkbook.Sheets(ログシート) ' ログ用のシート
' コピー元の範囲
Set sourceRange = wsSource.Range(ログ対象範囲)
' ログシートのA列の最終行を取得(データがある最終行)
lastRow = wsDest.Cells(Rows.Count, 1).End(xlUp).Row
' 初回のコピー先の先頭セルの設定
If lastRow = 1 And wsDest.Cells(1, 1).Value = "" Then
' ログシートが空の場合、A1から開始
lastRow = 0
End If
' コピー先の範囲(最終行+2のA列から)
Set destRange = wsDest.Cells(lastRow + 2, 1)
' 値と書式をコピー(罫線・列幅などもコピー)
sourceRange.Copy
destRange.PasteSpecial Paste:=xlPasteValuesAndNumberFormats ' 値と数値の書式
destRange.PasteSpecial Paste:=xlPasteFormats ' 書式(罫線など)
' クリップボードをクリア
Application.CutCopyMode = False
' 最後に日付情報を追加(左下のセルを取得(最下行の最左列))
' ログの末尾セルを判定するために設定する
Set bottomLeftCell = destRange.Cells(destRange.Rows.Count + 5, 1)
With bottomLeftCell
.Value = Format(Now, "yyyy/mm/dd HH:MM:SS")
.HorizontalAlignment = xlLeft
End With
' オブジェクトの解放
Set wsSource = Nothing
Set wsDest = Nothing
Set sourceRange = Nothing
Set destRange = Nothing
Set bottomLeftCell = Nothing
End Sub
ダウンロード
エクセルVBAで作成したデジタル波形作成ツールです。簡単を主眼に波形の説明などイラストとして使用できるように作成しました。そのためデジタル波形を設計するためのツールではないことご了承ください。
なお、このファイルにはVBAマクロを含んでいるため、開く際に警告が表示されます。
以下のDownload Now!をクリックしてください。
まとめ
今回は、Raspberry Pi のブログにデジタル波形を書きたいがためにデジタル波形作成ツールを作成してみました。実際に使ったブログも投稿したいと思います。
また、ツールはエクセルVBAを使ってプログラムしました。セルを自在に扱えるVBAの便利さを味わうことができました。使いこなせばいろんな便利なことができそうです。
コメント