SSブログ
前の10件 | -

メルカリの損益計算をする [PC]

引っ越しをトリガーに断捨離を始めてからお世話になったのがオンラインフリーマーケットだ
それは言わずと知れた「メルカリ」
問題となるのは、売れないためいくらまで下げるかの販売価格決めである
赤字のラインを知りたいのは私だけではないはず
販売価格から送料とメルカリに支払う手数料を引き算すると手元に残る金額がわかる
配送方法は41種類ありそれぞれ料金が異なる
また、メルカリに支払う販売手数料50%還元というキャンペーンも時々ある
便利ツールをExcelで作っておこうと誰もが思う
損益分岐点もわかるように・・・
DSC_0719.jpg

その作ったExcelシートから「損益分岐点」を下表に出力した
梱包材料はゼロ円、手数料は10%とし計算している
配送方法
損益分岐点
ネコポス233円
ゆうパケット256円
ゆうパケットパケットポスト317円
ゆうパケットパケットポストmini200円
定型郵便(25g以内)93円
定型郵便(50g以内)104円
定型外郵便(規格内50g以内)133円
定型外郵便(規格内100g以内)156円
定型外郵便(規格内150g以内)233円
定型外郵便(規格内250g以内)278円
定型外郵便(規格内500g以内)433円
定型外郵便(規格内1Kg以内)644円
定型外郵便(規格外50g以内)222円
定型外郵便(規格外100g以内)244円
定型外郵便(規格外150g以内)333円
定型外郵便(規格外250g以内)389円
定型外郵便(規格外500g以内)567円
定型外郵便(規格外1Kg以内)789円
定型外郵便(規格外2Kg以内)1156円
定型外郵便(規格外4Kg以内)1500円
クリックポスト206円
スマートレター200円
レターパックライト411円
レターパックプラス578円
宅急便コンパクト578円
宅急便(60)833円
宅急便(80)944円
宅急便(100)1167円
宅急便(120)1333円
宅急便(140)1611円
宅急便(160)1889円
宅急便(180)2333円
宅急便(200)2778円
ゆうパケットプラス578円
ゆうパック(60)833円
ゆうパック(80)967円
ゆうパック(100)1189円
ゆうパック(120)1333円
ゆうパック(140)1611円
ゆうパック(160)1889円
ゆうパック(170)2111円


そのExcelシート・・・
画面右側の表のH列は各配送方法に対応する「損益分岐点」となる金額
損益分岐点は以下から計算されている
・仕入価格
・手数料
・送料
・専用箱・封筒
・梱包材
mercari1.png

画面左上の黄色い部分がよく使用するセルである
「販売価格」と「配送方法」を設定すると桃色の丸で示すところに「利益」が表示される
配送方法はプルダウンメニューで選択できるようにしている
配送方法に対する「損益分岐点」より安くで販売しては赤字となるわけだ
「仕入価格」は、仕入れてから売る場合に、ここに仕入価格を入れればよいが、家で処分するものを売る場合はゼロでよい
「手数料(通常10%)」は、基本メルカリは手数料10%であるので10を入れておけばよいが、
販売手数料50%還元キャンペーンにミートしそうな時は、ここに5を入力すればよい
通常は黄色いセルだけに入力すればいいはずである
mercari2.png

画面の右部G列の「梱包材」は梱包材料の費用(半固定値)を入力しておけばよい
ネコポス、ゆうパケットを55円に設定しているのは、百円ショップの2枚入りA4クッション封筒を使っているため一枚55円の梱包費ということだ
3枚入りを利用しているよ!だったら37円にする
mercari3.png

ゆういち作 メルカリ損益計算
メルカリ損益計算.xlsx
■Google Driveリンクです
■このExcelシートはセルのロック(パスワードなし)をかけているが、
 ロックしていない箇所は仕入価格、販売価格、配送方法、手数料、梱包材
■このシートによって損害が発生しても、ゆういちは責任を負わないものとする


人気ブログランキング
nice!(8)  コメント(0) 
共通テーマ:日記・雑感

絵画を飾り佐多岬を思う [DIY家具]

ずいぶん前、マンション購入時に、叔父から新築祝いでいただいた絵画、
幾度か引っ越しをして、ここに落ち着くつい先日まで棚上げしていた
壁に飾るという仕事を・・・
この絵画は棚上げ期間が長かったせいで、来る日も来る日も
解放された世界を求めていたであろう

棚上げしていた理由は
(1) 絵画が2.2Kgであり重い
(2) 適切な設置方法を知らない
(3) 壁に穴があく
DSC_0622.JPG

裏はこのような造り
DSC_0623.JPG

壁に取り付ける方法をネット検索を駆使し、絞り込んでいくと
これだというものに辿り着いた
これであれば、ほぼ壁密着のため頭でイメージしていたような取付ができる
すぐに作業に取り掛かりたいためホームセンターに出かけてこれを2個入手
(株)八幡ねじ 吊り金具 Y-1
これで、前述の棚上げ理由の(1)と(2)が解決した
(3)は?家内から終の棲家であるので何も遠慮することはないと言われ背中を押してもらった
DSC_0631.JPG
DSC_0632.JPG

玄関ホールに設置することに
この瞬間、この絵画は手を打って喜んだことだろう
外から玄関に入り右側の壁、その壁の左側に取り付ける予定でいたのだが、
家内の反対により壁の右側に取り付けることにあっさり方針転換する
IMG_20240212_115101.jpg

シンワ製の「下地センサー」の出番となる
DSC_0620.JPG

適当なところで壁に密着させてスタートボタンを押しながら左右に壁をこすっていく
柱のエッジが見つかると教えてくれる
DSC_0627.JPG

柱のエッジがわかれば、柱の幅や、柱同士の間隔がわかる
この絵画取り付けに対して2本の適切な柱がわかった
DSC_0621.JPG

金具の上下を間違わないように、柱の中心に金具を取り付ける
DSC_0633.JPG

もう片方も、水平を確認しながら取り付け、壁側の2つの金具を木ネジで取付完了
この吊り金具は1個あたり4ネジだが、2ネジにしている
DSC_0635.JPG

絵画の裏側にも同じ金具を左右2つ取り付けた
この2つの金具は、壁の金具と上下逆にしなければならない
これも1個あたり2ネジにしている
DSC_0637.JPG

玄関ホールの壁右側に、絵画を引っ掛け設置が完了
引っ掛けるだけであるので簡単
実は、絵画の高さも十分検討している
絵画は目の高さがBestであるが、玄関ホールは土間から24cm上がって床のレベルとなる
絵画は土間に設置したため、床レベルと土間レベルの中間を狙い、土間から絵画中心まで170cmの高さに設置した
IMG_20240212_125859.jpg

この絵は、本土最南端佐多岬灯台(鹿児島県肝属郡南大隅町佐多馬籠)
[exclamation]佐多岬の読みは「SATAMISAKI」、四国の佐田岬は「SADAMISAKI」
ゆういちが佐多岬に通じる国道269号の海岸線を車で走ると、山本コウタローとウィークエンド「岬めぐり」のイントロが聞こえてくる。愛する人と別れ(死別なのか?)岬を訪れた男が青い海を見て悲しみを沈めるという詞だが、ゆういちは「岬めぐりのバスは走る」のフレーズが好きである
貴方も269号を走りながら目線を青い海から岬にパンすると必ず聞こえてくる!
快晴の夏にはその聞こえてくるメロディーもボリゥムアップする
佐多岬を紹介する広報誌等には必ず北緯31度だと緯度を誇示するのが定番であり、
ソテツやヘゴの自生地であることで納得いく
ゆういち自身、10年~20年に一度行ってみようかと思う忘れそうな不思議なスポット
その忘れた頃は、佐多岬の観光地はあれからどう変わったか気になるということだ
この絵画を玄関に飾ったのをきっかけに、ゆういちは佐多岬に足を延ばすことになるのか・・・?
DSC_0639.JPG

山本コウタローとウィークエンド「岬めぐり」


この写真はゆういちがフィルムカメラで1980年代に撮影したものである
絵画は1996年頃と思われる
絵画と写真を重ね合わせ、時代の変化を探したが
幸いにも、手付かずの自然を保持していると理解した
やっぱし、ゆういちはこの夏北緯31度まで南下し佐多岬にご挨拶に行くことだろう・・・
satamisaki_1980.jpg

To be continued.




人気ブログランキング
nice!(18)  コメント(0) 
共通テーマ:インテリア・雑貨

ウッドデッキにニャンコのケージを設置 [ペット]

我が家のニャンコは家猫、育て方が影響したのだろう・・・
外の空気が大好きだ、全世界どこの猫もそうだとは思うけれど
だから、ウッドデッキにケージを置いてリビングから出入りできるようにしてあげた
夕暮れ後も夏冬関係なく出たり入ったり
外猫を含め動物が庭にやってくると、我が家のニャンコは血が騒ぎ、ゆういちに侵入者があることを教えてくれる
ゆういちは、ニャンコが番犬の役目も果たすことに驚いた・・・
DSC_0605.jpg

カーテンをそっと開けてみると
気持ちいいんだろう!ヘソ天していることもしばしば
こんなリラックスしている様子を見れば、侵入者もなく平穏であることがわかる
ところで、ニャンコよ許せ!洗ったスリッパも干せる
DSC_1979.jpg

そのケージは、アイリスオーヤマ コンビネーションサークル P-CS-932
サイズは、横93cm×奥行65cm×高さ122cm
トレーは使用していない
仔猫時代に使用していたものがお蔵入りしていたためウッドデッキ用に転用した
話変わって、ニャンコよ許せ!絞った雑巾も干した
DSC_0603.JPG

ニャンコの出入りのために、
既存の網戸に、ホームセンターで購入した「犬猫出入り口」という商品を取り付ける
開口寸法は縦17cm、横15cm、パッタン式の扉付きだ
DSC_1599.JPG

取り付けを開始!
ニャンコには内緒・・・
網戸を外し、そぉ~っと平置きした
DSC_1600.JPG

「犬猫出入り口」のフレームを網戸のコーナーに仮固定していると、
気が付いたニャンコがやってきた
DSC_1601.JPG

網の裏表から黒いフレームで挟んで、ネジ止めする
ネジ止めが終わったら、フレームの内側の網をカッターで切り取ればよい
DSC_1602.JPG

どんなに集中して作業をしても、きれいに切り取ることができなかったため、ニッパーを使ってエッジに沿って飛び出したトゲを切る
DSC_1606.JPG

取り付けが完了した
縦の青い物(約φ60mm)はというと、
100均で売られている「プールスティック」、発泡ポリエチレン製だ
ケージを極力サッシ側に寄せても、網戸とケージの隙間が7~8cmあり脱走の危険性がある
そのため「プールスティック」をケージの外側に結束バンドで取り付けている
DSC_1604.JPG

初めてのパッタン扉には慣れないため、自ら外には出られない
無理やりケツを押してウッドデッキに押し出したところだ
DSC_1605.JPG

上側も隙間があるのだが、我が家のニャンコが網戸の外側をよじ登って脱走するなんて考えられないのでそのままにしている
DSC_0602.JPG

このパッタン扉の出入りを一か月以上は訓練したが、我が家のニャンコは上達しなかった
よって、現在はパッタン扉だけ取り外している
夏場、17cm×15cmの穴から虫が入ってくる確率の問題である
前述のニッパーで切った部分が、刺々しくニャンコが出入りする度に気にする様子をみせる
そこで、ゆういちは仕舞ってあったハンダゴテを取り出し、熱く準備を整え、
刺々しい部分を、ハンダゴテで撫でるように処理した
刺々しさは無くなったが、ニャンコが出入りする度に臭いを気にする様子を見せるようになった
この、臭い問題は時間が解決した
DSC_1603.JPG

晴れた日は、必ず朝日を浴びる我が家のニャンコ
ニャンコは井之頭五郎流にこう言った、
「いいじゃないか、いいじゃないか、[晴れ]この突き刺さる光は、きょう俺の一日分のエネルギーを満たしてくれる、フッ」
DSC_0608.JPG

めでたし、めでたし

【この記事で紹介している商品】

ダイオ化成 網戸用犬猫出入り口 (猫・小型犬用) 縦17cm×横15cm PD1923015cm×17cm

ダイオ化成 網戸用犬猫出入り口 (猫・小型犬用) 縦17cm×横15cm PD1923015cm×17cm

  • 出版社/メーカー: イノベックス(Innovex)
  • メディア: ホーム&キッチン



人気ブログランキング
nice!(10)  コメント(0) 
共通テーマ:ペット

鹿児島から受信できる航空無線 [アマチュア無線]

鹿屋市の自宅から受信可能な航空機の範囲を調べてみた
ゆういちが無線機で確実に聞き取ったコールサインをFlightrader24で調べ白地図に赤丸でプロットしていくと・・・最も遠い航空機は約260Km、よって、少なくとも青い円内は受信可能エリアであることがわかった
福岡空港周辺は距離的には受信できそうであるが、高度が低いため受信機会がないのかもしれない
九州の西側から聞こえないのは航空機が飛んでいないからであろう
Receivable.png

✑ ✑ ✑ ✑ ✑ ✑ ✑ ✑ ✑ ✑

受信機はICOMのアマチュア無線トランシーバーIC-705、
アンテナはダイヤモンドアンテナX50(144/430MHzのデュアルバンド)を使用
受信する周波数は、この環境で実際にエアバンドを手動で探索し、何らかの交信を受信した周波数を拾い上げた。下の画面が手動で探している様子である。
青いザラザラは横方向が周波数、縦方向が時間を示している。
中央付近緑色の縦線は現在の受信周波数135.558MHzであるが、その左に赤丸で示す位置に何らかの電波があることがわかるのだ。だから手動でも電波を探すのは非常に楽だ
manual_search.png

IC-705には、その拾い上げた24個の周波数をメモリーしてスキャンした
スキャンは無限ループである
※下動画は受信音無し、BGMが出るのでご注意!


以下がその24個の周波数
※鹿屋航空基地は除いている

※名称
_周波数[MHz]_
鹿児島TWR118.20
種子島RDO118.75
北九州セクター118.90
四国南北セクター119.35
鹿児島APP119.40
鹿児島DEP121.40
飛行訓練用123.40
F11セクター124.55
鹿児島APP126.00
熊本DEP126.50
F15セクター127.50
カンパニー1129.70
カンパニー2130.10
カンパニー3130.45
F16セクター132.30
沖之南セクター132.35
中国高高度セクター133.15
南九州西セクター133.85
Unknown133.90
四国南セクター134.35
カンパニー4135.10
南九州高高度セクター135.30
N52セクター135.65
鹿児島FSC135.80

※上表項目:名称については未確認

交信を受信すればスキャンが止まり交信内容が聞こえてくる
「Good Day!」で締めくくる交信や、外国人操縦士の「オハヨウゴザイマシタ」(笑)
便名間違い等々・・・
交信が終われば再びスキャンが始まる
交信内容から航空機のコールサイン+便名を聞き取り、パソコンに表示されているFlightrader24から航空機の現在位置を知ることができるわけだ
コールサインの聞き取り方のコツ・・・
航空会社名の聞き方に慣れればよい
例えば「JAL4649」便は、冒頭「ジャパナエア」から始まり「フォーシックスフォーナイナー」
分かりづらい例をあげれば「SNJ2020」、これは「ニュースカイ・ツージロツージロ」である
交信にはフライトレベルや周波数変更、航空機の方向などの多くの数字が聞こえてくるため、先に述べたように慣れが必要だ
下記がICAOとコールサイン(読み)の関係、このあたりを飛行している航空会社をピックアップした
航空無線Handbookも参考にしよう

ICAO
コールサイン
ANAall nippon
APJair peach
CPAcathay
EVAeva
JALjapan air
JLjapan air
PALphilippines
SIAsingapore
SKYsky mark
SNJnew sky
SJXstarwalker


PCのインターネットブラウザーGoogle Chromeを使用し、
ゆういちはFlightrader24をこのような画面で表示させている
航空機のコールサイン+便名を見つけやすくするために・・・
fr24_1.png

設定方法
Flightrader24の画面下にある黄色丸で示す「Settings」をクリック
fr24_2.png

Radar(Dark)を選択
DAY/NIGHT LINE:OFF
fr24_3.png

さらに、このSettingsのウィンドウを下にスクロールして
AIRCRAFT ICON SIZE:Auto
ANIMATED AIRCRAFT:ON
AIRCRAFT LABELS:ON
「Call sign」 をプルダウンから選択
LABEL BACKGROUND:ON
fr24_4.png

Flightrader24の画面下にあるオレンジ丸で示す「Widgets」をクリック
fr24_2.png

ENABLE WIDGETS:OFF
WIDGETSをOFFにすることで画面左のウィジェットが消えスッキリする
fr24_6.png

ゆういち流の航空機を探す方法は・・・
Flightrader24内の検索窓は利用していない
Google Chromeにフォーカスしている状態で[CTRL]+[F]を押すと、下記のようにテキストサーチする検索窓が表示されるので、聞き取ったコールサイン+便名を入力する
ヒットすると、コールサインのバックに色が付く
コールサインの一部だけ聞き取れた場合でも、迷わず入力することによって探しやすくなる
以上が、ゆういち流
fr24_5.png

自宅からは空港が遠いため管制塔からの無線を聞くことはできず、航空路管制(Area Control Center)の航空機側の無線を聞くことがほとんどであるため「福岡コントロール・・・」や「神戸コントロール・・・」は頻繁に耳にすることになる
航空無線(エアバンド)に興味を持っていただけたら、受信にチャレンジしてみてはいかがでしょうか?
実は、航空無線の受信設備を所有していなくてもLiveATC.netで主要都市の航空無線(エアバンド)を聞くことができることを最後にお伝えしておく。
・・・
それを早く言ってくれって?

↓↓↓エアバンド受信にはICOM IC-R6はコスパいいです!↓↓↓

アイコム IC-R6 エアーバンドスペシャル 黒

アイコム IC-R6 エアーバンドスペシャル 黒

  • 出版社/メーカー: アイコム
  • メディア: エレクトロニクス




人気ブログランキング
nice!(10)  コメント(0) 
共通テーマ:趣味・カルチャー

鹿屋市から受信できるFM局 [アマチュア無線]

鹿屋市の自宅からFM放送が何曲聞こえるか調べてみた
下記キャプチャ画像はMBCラジオ、AM放送(中波)で放送しているFM補完放送である
さて、何曲受信できたのか?
FM942.png

使用したのは一般的なラジオではなく、
アマチュア無線機(IC-705)と、それに接続された外部アンテナを使用しての結果
外部アンテナは144/430MHzデュアルバンドグランドプレーン
中継局も含めて19局受信を確認

要約として
・受信良好な周波数は5つ
・種子島の局が受信できるのは送信出力が1KW
・種子島はラジオ第1の補完放送をやっている
・NHK-FM(鹿児島)は良好に受信できない
・エフエム鹿児島(鹿児島)は全く受信できず

[2024/1/13現在]

放送局名周波数(MHz)※受信レベル
FRIENDS FM 76276.2
エフエム鹿児島(枕崎)76.6
FMかのや77.2■■■■■
FMしぶし78.1■■
エフエム鹿児島(鹿屋)79.0■■■■■
NHKラジオ第1(種子島)79.3■■■
FMきもつき80.2
MBCラジオ(種子島)82.3■■■
JOY FM(宮崎)83.2■■■■
NHK-FM(阿久根)83.7■■
NHK-FM(鹿屋)84.1■■■■■
NHK-FM(種子島)84.4■■
NHK-FM(鹿児島)85.6■■
NHK-FM(宮崎)86.2■■
MBCラジオ(姶良霧島)86.7
MRTラジオFM(宮崎)90.4■■■
MBCラジオ(鹿児島)92.8■■■■■
MBCラジオ(北薩)93.7
MBCラジオ(大隅)94.2■■■■■

※受信レベル:
1:何らかのキャリアーを受信した
2:時々放送内容がわかる
3:聞けるがノイズが大きい
4:明瞭だがノイズを伴う
5:たいへんクリアーに聞こえる

少し昔のFM放送局:
物持ちがいいゆういちは、1978年頃のラジオ関連雑誌の一部を取り出した
それは日本国内のFM放送局一覧(中継局は含まない)
ほぼNHKが占めているが★印だけが民間放送局である
その民間FM局は東京、大阪、名古屋、福岡、4社しかない時代だった
手書きの印が付いている局はEスポで受信した局、この当時も受信地は鹿児島
FM_radio_1978.jpg

おわり

人気ブログランキング
nice!(11)  コメント(0) 
共通テーマ:日記・雑感

炊飯器がH02エラー [DIY電気]

時は2023年12月24日クリスマスイブ、今晩のご飯を準備しようかというタイミングに
電気炊飯器の表示窓に「H02」と表示されていることに気がついた
その炊飯器は、Panasonic SR-HX109、2020年製
近くのスーパーで骨付き鶏もも肉を買ってきてクリスマスイブの準備万端だったのに、
笑うしかないので、余裕で笑ってあげた
その余裕はどこから来たのかというと、電源の抜き差しで改善すると思ったからだ・・・
しかし、サンタクロースからのプレゼントは「故障」という言葉だった

調べたら
「ふたの温度を検知するセンサーの不具合の可能性があります。
点検や部品の交換が必要です。お買い上げの販売店、
またはパナソニック修理ご相談窓口に点検・修理をご依頼ください」
修理の目安金額:13,000円~20,000円

何度電源の抜き差しをやっても改善されず、「炊飯ボタン」も無反応
DSC_0543.JPG

クリスマスイブの支度時だったが、
修理の目安額で鼻血が出そうだったが寸止めして、
すぐに分解の工程に臨むことにした
ふたのセンサー?とりあえずふたを開けてみたが
サンタさんは微笑まなかった
DSC_0544.JPG

取っ手を少し上げると、ネジ(黄色丸で示す)を発見し外してみる
DSC_0545.JPG

カバーを外すと、すぐに白い線が断線していることに[ひらめき]気がつく
この細くて白い線の断線が原因であることは火を見るより明らかだ
DSC_0546.JPG
DSC_0549.JPG

本体側とふた側を接続している線のひとつである
この線を接続するにはふた側の線が短かく、ふた側の分解作業が必要となる
ふたの分解はネット検索でも有用な情報が得られなかったため、爪楊枝を差し込みながらマイナスドライバーでじっくり戦った
DSC_0550.JPG

その時が来た!パカっと音がするや否や
サンタさんが舌打ちしたような気がした
DSC_0551.JPG

完全に開き、サンタさんも覗き込んだかもしれない
DSC_0552.JPG

開いたが、フレキケーブル(リボンのような白と黒のケーブル)一本でつながっているので、つなげたまま作業することにした
DSC_0553.JPG

断線していた白い線同士をそのまま接続するわけにはいかない
ゆういちが所有する緑の線で、はんだでつなぎ合わせた
黒い被覆は熱収縮チューブ
あらかじめ熱収縮チューブをいれておき、接続部に合わせたらはんだごての熱で収縮させる
DSC_0555.JPG

ホットメルトで線材の束を固める
DSC_0556.JPG

問題の白い線は、このデバイス部に配線されていた
温度センサーであるか?
DSC_0557.JPG

ふたの爪を開けるのは苦労したが、元に戻すのは「パチ、パチ」と爪がかみ合う音をたてながら
容易に元通りとなった
最後にこのカバーを取り付けるだけだ
DSC_0560.JPG

ふたの開閉で断線する設計は素人だな・・・ゆういちが呟いた
それも3年程度で・・・、サンタも呟いた
DSC_0561.JPG

今回は、バックアップとしてIHクッキングヒーターで初めて炊飯をするという機会を得られ
無事に白ご飯と、骨付き鶏もも肉をいただくことができている
サンタさん、炊飯器の修理いっしょに付き合ってくれてありがとよ、
疲れたよ。

人気ブログランキング
nice!(11)  コメント(4) 
共通テーマ:日記・雑感

NEKO BENTO のソースコード [DIY電気]

過去記事でも3回ご紹介してる「猫用自動給餌器をリモコン制御に改造」の続編
「PetSafe おるすばんフィーダー デジタル2食分 バージョン2」という製品を改造しての改造シリーズ第4弾はプログラムソースコードの公開となる
PICマイコンを組み込んでおり、C言語のソースコードである

Summary:
犬猫の餌を入れておいて希望する時間後に蓋が開く商品であるが、ゆういちの希望する仕様ではなかったので改造した
マイコンは割り込みルーチンで時刻を持つ、また家電リモコンからの毎日時刻校正コマンドを受信するため時刻は正確である
左蓋、右蓋のOPEN時刻をセット可能、家電リモコン(スマホから操作)でOPENすることも可能
一か月以上もRUNして問題ないためバグは究極にゼロに近いと思っている

外観はこんな商品
シンプルはゆういちの好みである
DSC_0523.JPG

左右の蓋が開いた状態
DSC_0525.JPG

後ろには、黄色いスイッチ2つとAC/電池切り替えスイッチ増設
DSC_0524.JPG

手に持っているのがオリジナル基板
取付済みが自作基板
DSC_0522.JPG

自作基板は、Fusion PCBにガーバーデーターを送って製作した
MicrochipのPIC16F88マイコン搭載である
DSC_0526.JPG

表示器は小型のOLEDを採用している
PICマイコンが持つフォントデーターは234バイト、文字は[0]~[9], [A]~[Z], [:],[?],[-]、最低限のフォントしか持たない
DSC_0528.jpg

その自作基板の回路図はEagleで設計
nekobento_sch.png

プリント基板設計もEagle
シルク印刷で示すJP1,JP3はOLEDの表示モジュールのマウントパターン
基板表裏どちらでもマウントできるようにしている
nekobento_board.png

1980年代制御プログラムをコーディングしていた、
当時勤めていた会社の上司からプログラミングに対してコメントを受けることもあった
上司はアランドロンだった
ゆういちが上司はアランドロンと似ていると言い出したのではない、誰かが言ったので上司とアランドロンはヒモ付いただけである
アランドロンはゆういちに教えた、メインプログラムはグルグル回してタイマーで判断して複数ある処理プロセスに飛ばせばマルチタスクが実現する・ボンジュールと・・・
アランドロンから伝授した手法はゆういちが作り続けてきた多くのソフトに利用させていただいた
ゆういちのメインルーチンは必ず
while(1){ } である
特にこの手法を必要としないソフトも、while(1){ }、まずはこの手法を利用する
なぜならタスクを増やしたい場合に柔軟に対応できるからだ
このソフトもその手法を少しだけ利用させていただいている

NEKO_BENTOメインプログラム For CCSC Compiler
/**********************************************
   TITLE: NEKO BENTO

   FILENAME: neko_bento.c
   TARGET DEVICE: PIC16F88, 10MHz X'tal
   DATE:  2019.05.11 - 2023.12.14

   VERSION  00 2019.08.04 OLED表示機能
   VERSION  01 2019.09.19 FOR NEW PCB(Fusion PCB)
   VERSION  02 2019 11.02 TIME CLOCK ADJUST
   VERSION  03 2022 01.02 起動時黄色ボタン押していたら時刻入力をスキップ

   AUTHOR: Yuichi
***********************************************/

#include <16f88.h>
#use delay(clock=10000000)

#FUSES  HS,NOWDT,NOPROTECT,PUT,NOMCLR,NOBROWNOUT,NOLVP
#use i2c(master,sda=PIN_B1,scl=PIN_B4,FAST)
#ignore_warnings 203
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>

#define TIMEADJ 187  //LARGE NUMBERS=FAST CLOCK  SMALL NUMBERS:CLOCK is Delayed
                    //大きい数字は時計が進む、小さい数字は時計が遅れる
#define EEPROM_SAVED 0xcc
// OKNG
#define OK          0
#define NG          1

//24Hを超える(単位は分)、60*24-1=1439 以上は無効とするため
//1440以上であればいいが、切りのいい1500としている
#define INVALID_TIME 1500

// AポートのI/Oビット配置
// 上からLSBで割り当てればよい
// plビットをHIGHにするには PORTA.pl=1 とすればいい
struct porta_pin_map1 {      // This structure is overlayed
    BOOLEAN Infrared_rx;
    BOOLEAN pushsw;
    BOOLEAN left;
    BOOLEAN right;
    BOOLEAN pl;       //pilot lamp
} PORTA;
struct porta_pin_map2 {      // This structure is overlayed
    BOOLEAN reserve2;
    BOOLEAN sda;
    BOOLEAN reserve3;
    BOOLEAN reserve4;
    BOOLEAN scl;
    BOOLEAN reserve5;
} PORTB;

#byte PORTA = 0x05
#byte PORTB = 0x06

struct font_bit{
    BOOLEAN b0;
    BOOLEAN b1;
    BOOLEAN b2;
    BOOLEAN b3;
    BOOLEAN b4;
    BOOLEAN b5;
    BOOLEAN b6;
    BOOLEAN b7;
};

#include "hinagata.h"     // 型宣言
#include "Infrared_rx.h"     // Infrared Rmote cont

//割り込みでカウントアップする変数
int16 g_209ms_count = 0;

// get_4_number()で返される値
struct g_four_digit{  //リモコンボタン4桁で時間入力
  int16   data;  //分
  BOOLEAN timeout;  //timeoutしたらTRUE
} g_four_digit;

// 蓋を開ける時間 0時0分から何分後に蓋を開けるかの設定
// 0-1439 は有効
//   INVALID_TIME は無効
int16 g_cover[2];

// Clock
// このプログラムでは時と分をそれぞれカウントせず、分だけカウントしている
// 0~1439分で24時間
int16   g_minutes=0;  // 分カウント

// cover open flag
BOOLEAN g_open[2] = {FALSE,FALSE};  //蓋が開いたら一分間だけTRUEになる

// OLED光ってるSTATUS
BOOLEAN g_oled = FALSE;
// OLEDをSLEEPにするための時間計測
int16   g_oled_cnt = 0;

// 6*8 bitmap font
// Alphaは大文字のみ
BYTE const font[39][6]={
{0x7C,0xFE,0x82,0xFE,0x7C,0x00}, //0
{0x00,0x04,0xFE,0xFE,0x00,0x00}, //1
{0xE4,0xF2,0xB2,0xBE,0x9C,0x00}, //2
{0x44,0xC6,0x92,0xFE,0x6C,0x00}, //3
{0x1C,0x12,0xFE,0xFE,0x10,0x00}, //4
{0x4E,0xCE,0x8A,0xFA,0x72,0x00}, //5
{0x7C,0xFE,0x8A,0xFA,0x70,0x00}, //6
{0x00,0x02,0xF2,0xFE,0x0E,0x00}, //7
{0x6C,0x9E,0xBA,0xF2,0x6C,0x00}, //8
{0x1C,0xBE,0xA2,0xFE,0x7C,0x00}, //9
{0xC0,0x72,0x4E,0x7E,0xF8,0xE0}, //A 10
{0xFE,0xFE,0x92,0x92,0xFE,0x6C}, //B
{0x7C,0xFE,0x82,0x82,0xEE,0x6C}, //C
{0xFE,0xFE,0x82,0xC6,0x7C,0x38}, //D
{0xFE,0xFE,0x92,0x92,0x92,0x00}, //E
{0xFE,0xFE,0x12,0x12,0x12,0x00}, //F
{0x7C,0xFE,0x82,0xD2,0x76,0xF4}, //G
{0xFE,0xFE,0x10,0x10,0xFE,0xFE}, //H
{0x00,0x00,0xFE,0xFE,0x00,0x00}, //I
{0x60,0xE0,0x82,0xFE,0x7E,0x00}, //J
{0xFE,0xFE,0x38,0xF4,0xE2,0x00}, //K 20
{0xFE,0xFE,0x80,0x80,0xC0,0x00}, //L
{0xFE,0x1E,0x78,0xE0,0x18,0xFE}, //M
{0xFE,0x1C,0x38,0x70,0xFE,0x00}, //N
{0x7C,0xFE,0x82,0x82,0xFE,0x7C}, //O
{0xFE,0xFE,0x22,0x22,0x3E,0x1C}, //P
{0x3C,0x7E,0x42,0xE2,0xFE,0xBC}, //Q
{0xFE,0xFE,0x12,0x32,0xFE,0xDC}, //R
{0x4C,0x9E,0xBA,0xF2,0x64,0x00}, //S
{0x02,0x02,0xFE,0xFE,0x02,0x02}, //T
{0x7E,0xFE,0xC0,0x80,0x7E,0x00}, //U 30
{0x0E,0x3E,0xF0,0xC0,0x70,0x0E}, //V
{0x1E,0xFE,0xE0,0x7C,0xE0,0x3E}, //W
{0x8E,0x7E,0x38,0xFC,0xE2,0x00}, //X
{0x06,0x1E,0xF8,0xF0,0x18,0x06}, //Y
{0x82,0xE2,0xFA,0xBE,0x8E,0x82}, //Z
{0x00,0x00,0x24,0x24,0x00,0x00}, //:
{0x0C,0x0E,0xA2,0xB2,0x1E,0x0C}, //?
{0x00,0x10,0x10,0x10,0x10,0x00}, //-
};

// OLED PRINT POSITION
int oled_x=0;
int oled_y=0;

/*---------------------------------------------
   Timer interrupt interval 209ms
   0.4us*8*(65535-7)=209ms
---------------------------------------------*/
#INT_TIMER1
void watch_handler( void )
{
    // set_timer1(0)だとフルカウントする。0->FFFF->0 で割り込み発生
    // set_timer1(12)だと12少ないカウント、12->FFFF->0 で割り込み発生
    set_timer1( TIMEADJ ); // 65535-11
    ++g_209ms_count; // 209msごとにカウントアップ
    if(g_209ms_count > 286 ){ // 209ms*286=60sec
       g_209ms_count = 0;
       g_open[0]=g_open[1]=FALSE; // Cover open flag clear
       ++g_minutes;
       if( g_minutes > 1439 ){  // 24Hour
          g_minutes = 0;
       }
    }
}

/*---------------------------------------------
   main module
---------------------------------------------*/
void main( void ){
    int32 scode;
    char title[20];
    BOOLEAN select_time = 0;
    sprintf( title , "\fNEKO\nBENTO %s", "03"); //VERSION HERE
    set_tris_a( 0x03 );     // BIT0(IR) BIT1(SW) IS IN
    set_tris_b( 0x12 );     // SDA, SCL is INPUT
    PORTA = 0;
    PORTB = 0;
    if( read_eeprom( 0 ) != EEPROM_SAVED ){ // Never save
        g_cover[0] = INVALID_TIME; //Left
        g_cover[1] = INVALID_TIME; //Right
    }else{
        g_cover[0] = make16( read_eeprom(2), read_eeprom(1) );
        g_cover[1] = make16( read_eeprom(4), read_eeprom(3) );
    }
    delay_ms(300);
    oled_init();
    oled_resume( TRUE ); //NO SLEEP
    printf( oled_putc, "%s", title );
    delay_ms( 1000 );
    // If not Push Yellow Double Switchs
    if( PORTA.pushsw != 0 ){
        printf( oled_putc, "\f SET TIME\n ? " );
        sets_clock();
    }
    //delay_ms( 1000 );
    printf( oled_putc, "\f START");
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 ); // 8bit max 3.2us
    PORTA.pl = 1; //START NOTICE
    set_timer1( TIMEADJ );
    enable_interrupts( INT_TIMER1 );
    enable_interrupts( GLOBAL );
    while(1){
        // このループは約2msぐらい
        scode = Infrared_read();
        ++g_oled_cnt;  //時間計測
        // IOのアサート
        if( scode != 0 ){
            if( scode == PS2_L1 ){ // LEFT COVER [L1]
                oled_resume( TRUE );
                printf( oled_putc, "\f L OPEN" );
                open_bento( 0 );
            }else if( scode == PS2_R1 ){ // RIGHT COVER [R1]
                oled_resume( TRUE );
                printf( oled_putc, "\f R OPEN" );
                open_bento( 1 );
            }else if ( scode == PS2_ENTER ){ // 両方開ける[ENTER]
                oled_resume( TRUE );
                printf( oled_putc, "\fALL OPEN" );
                open_bento( 0 );
                open_bento( 1 );
            }else if( scode == PS2_L3 ){ // set left time [L3]
                oled_resume( TRUE );
                printf( oled_putc, "\f L OPEN\n ? " );
                get_4_number();
                if( g_four_digit.timeout == FALSE ){
                    g_cover[0] = g_four_digit.data;
                    save_data();
                    printf( oled_putc, "\f LEFT\n  SAVED");
                }
            }else if( scode == PS2_R3 ){ // set right time [R3]
                oled_resume( TRUE );
                printf( oled_putc, "\f R OPEN\n ? " );
                get_4_number();
                if( g_four_digit.timeout == FALSE  ){
                    g_cover[1] = g_four_digit.data;
                    save_data();
                    printf( oled_putc, "\f RIGHT\n  SAVED");
                }
            }else if( scode == PS2_TIME ){ // セットしたLR蓋が開く時刻表示と現在時刻表示
                oled_resume( TRUE );
                select_time ^= 1;
                if( select_time == 1 ){
                    printf( oled_putc, "\f L " );
                    if( g_cover[0] == INVALID_TIME ){
                        printf( oled_putc, "--:--\n" );
                    }else{
                        printf( oled_putc, "%02ld:%02ld\n", g_cover[0]/60, g_cover[0]%60 );
                    }
                    printf( oled_putc, " R " );
                    if( g_cover[1] == INVALID_TIME ){
                        printf( oled_putc, "--:--" );
                    }else{
                        printf( oled_putc, "%02ld:%02ld",  g_cover[1]/60, g_cover[1]%60 );
                    }
                }else{
                    printf( oled_putc, "\fCUR TIME\n %02ld:%02ld", g_minutes/60 , g_minutes%60 );
                }
            }else if( scode == PS2_AUDIO ){ // 現在時刻を設定する [2] [0] [5] [2] -> 20時52分
                oled_resume( TRUE );
                printf( oled_putc, "\f SET TIME\n ? " );
                sets_clock();
                printf( oled_putc, "\f START");
            }else if( scode == PS2_PROGRAM ){ // Time Adjust 3時00分にセットする
                                           // スマート家電リモコンから定期的にコマンドが来る
                g_209ms_count=47;
                g_minutes = 180;
            }else if( scode == PS2_TITLE ){ // DISPLAY VERSION
                oled_resume( TRUE );
                printf( oled_putc, "%s", title );
            }
            delay_ms( 300 );
        }//if
        // TimerでLEFT蓋を開ける
        if( g_minutes == g_cover[0] && g_open[0] == FALSE ){
            open_bento( 0 );
            g_open[0] = TRUE;  //蓋が開いているフラグは一分後にタイマー割り込みでリセットされる
        }
        // TimerでRIGHT蓋を開ける
        if( g_minutes == g_cover[1] && g_open[1] == FALSE ){
            open_bento( 1 );
            g_open[1] = TRUE;
        }
        // リモコンが押されなくなって一定時間経過したら
        if( g_oled_cnt > 8000 ){
            oled_resume( FALSE );  // SLEEP MODE
        }
        if( PORTA.pushsw == 0 ){
            oled_resume( TRUE );
            printf( oled_putc, "\fALL OPEN" );
            open_bento( 0 );
            open_bento( 1 );
            delay_ms( 3000 );
        }
    }//while
}
/*---------------------------------------------
   SAVE DATA
---------------------------------------------*/
void save_data( void )
{
    disable_interrupts( INT_TIMER1 );
    disable_interrupts( GLOBAL );
    write_eeprom(0,EEPROM_SAVED );
    write_eeprom(1,g_cover[0] & 0xff );
    write_eeprom(2,(g_cover[0] >> 8) & 0xff );
    write_eeprom(3,g_cover[1] & 0xff );
    write_eeprom(4,(g_cover[1] >> 8) & 0xff );
    delay_ms(10);
    enable_interrupts( INT_TIMER1 );
    enable_interrupts( GLOBAL );
}
/*---------------------------------------------
   MANUAL SET CLOCK
---------------------------------------------*/
void sets_clock( void )
{
    get_4_number();
    if( g_four_digit.timeout == FALSE && g_four_digit.data != INVALID_TIME){
        g_minutes = g_four_digit.data;
        g_209ms_count = 0;
    }
}

/*---------------------------------------------
   OPEN BENTO COVER
---------------------------------------------*/
void open_bento( BOOLEAN flag )
{
   if( flag == 0 ){
       PORTA.left = 1;
   }else{
       PORTA.right = 1;
   }
   delay_ms( 300 );    // wait
   PORTA.left = 0;
   PORTA.right = 0;
   delay_ms( 600 );
}
/*---------------------------------------------
   Input 4 botton
   現在時刻設定、蓋を開ける時刻設定で使用される
   From PS2 [0]-[9]
   Return 0-1439, INVALID_TIME
          タイムアウトしたフラグで返す
 --------------------------------------------*/
void get_4_number( void )
{
    long  loop_count=0;  //タイムアウト計測用
    int32 scode; //リモコンコード
    int   digit=0; //桁ポインタ
    long  data[5]; //桁ごとの分データ
    long  num;  //数字ボタンに対応する数値が入る
    int   lutable[11] = {1,2,3,4,5,6,7,8,9,0}; //scodeの4LSBでこのLUTを見る
    long  minutes_data[5] ={600,60,10,1}; //Digitごとの単位
    delay_ms( 300 );
    printf( oled_putc, "----" );  //数字が入力されていない状態表示
    oled_x -= 4;    //表示位置を4文字分戻す
    PORTA.pl = 0;
    while(1){
        ++loop_count;  //この関数のTimeout計測
        scode = Infrared_read();
        if( scode != 0 ){
            if( scode >= PS2_1 && scode <= PS2_0 ){
                num = lutable[scode & 0x0f];  // covert to num
                if( num <= digit_max(digit,num) ){ //入力数値の制限
                    data[digit] = ( num * minutes_data[digit] );
                    printf( oled_putc, "%ld",num );
                    ++digit;  // next digit
                    delay_ms( 300 );
                }
            }
            if( scode == PS2_LEFT ){  //BACK SPACE
                if( digit != 0 ){ // digit 0 以外で動作するように
                    --oled_x;
                    printf( oled_putc, "-" );
                    --oled_x;
                    --digit;
                    delay_ms( 300 );
                }
            }
            // TIMER CANCEL
            // タイマーでNEKO弁当は開けない
            if( scode == PS2_L3 || scode == PS2_R3 ){
               delay_ms( 300 );
               g_four_digit.timeout = FALSE;
               g_four_digit.data = INVALID_TIME; //INVALID_TIME is Invalid
               PORTA.pl = 1;
               return;
            }
            loop_count=0;
        }
        // Sets Success
        // 4桁入力されたらこの関数を終える
        if( digit == 4 ){
            g_four_digit.timeout = FALSE;
            g_four_digit.data = data[0]+data[1]+data[2]+data[3];  //最終データ、分データ
            PORTA.pl = 1;
            return;
        }
        // PL blink while RUN this function
        if( loop_count > 77 ){
            PORTA.pl ^= 1;
            loop_count = 0;
        }
#if 0
        // time out 10sec
        if( loop_count > 2307 ){  // 2307 maybe 6s
            g_four_digit.timeout = TRUE;
            return;
        }
#endif
    }
}
/*---------------------------------------------
 Digit MAX
 時刻を4桁入力する際にそれぞれの桁の最大値を返す
 24:00が最大なので、最初の桁は最大が[2]である
 最初の桁に[2]を入力した場合は次の桁の最大とは[3]となる
 最初の桁に[1]を入力した場合は次の桁の最大とは[9]となる
---------------------------------------------*/
int digit_max( int digit, int num )
{
    int max;
    static int digit0num;
    switch( digit ){
      case 0:
         max = 2;
         digit0num = num;
         break;
      case 1:
         max = (digit0num == 2) ? 3 : 9;  // digit0によって最大値が変わる
         break;
      case 2:
         max = 5;  //Minutesの10の桁は最大5
         break;
      case 3:
         max = 9;  //Minutesの1の桁は最大9
         break;
      default:
         break;
    }
    return( max );
}

/*---------------------------------------------
 文字列表示する
 CCSCの特殊な使い方をする printf( vfd_putc, *fmt, hikisuu )
 というようにprintfで使う
 data; 文字
---------------------------------------------*/
void oled_putc( char c )
{
    int array;
    if( c == '\n' ){ //改行
        oled_x = 0;
        oled_y = 1;
        return;
    }
    if( c == '\f' ){ //画面クリア
        oled_clr(0);
        return;
    }
    if( isdigit(c) ){
        array = c - '0'; //数字だったら(0-9に変換)
    }else if( isalpha(c) ){
        array = toupper(c) - 55;
    }else if( c == ':'){
        array = 36;
    }else if( c == '?' ){
        array = 37;
    }else if( c == '-' ){
        array = 38;
    }else{
        array = 50; // Invalid char is SPACE
    }
    char1216( array, oled_x, oled_y );
    ++oled_x;  //次回のためにx表示位置変更
    if( oled_x > 8 ){
        oled_x = 0; //次回のためにx表示位置変更
        oled_y ^= 1; //次回のためにy表示位置変更
                     //yは0と1のみなので反転演算
    }
}

/* ----------------------------------------------------------------
    OLEDの初期化
---------------------------------------------------------------- */
void oled_init(void)
{
   i2c_start();
   i2c_write(0x78); // OLED slave address
   i2c_write(0x00); // Control byte Co=0, D/C#=0
   i2c_write(0x8d); // disable charge pump
   i2c_write(0x10);
   delay_ms(1);
   i2c_write(0xa8); //SET MUX RATIO
   i2c_write(0x3f);
   i2c_write(0xd3); //SET DISPLAY OFFSET
   i2c_write(0x00);
   i2c_write(0x40); //SET DISPLAY START LINE
#if 0
   i2c_write(0xa0); //SET SEGMENT RE-MAP
   i2c_write(0xc0); //SET COM OUTPUT SCAN DIRECTION
   i2c_write(0xda); //SET COM PINS HARDWARE CONFIGURATION
   i2c_write(0x02);
#else
   i2c_write(0xa1); //SET SEGMENT RE-MAP
   i2c_write(0xc8); //SET COM OUTPUT SCAN DIRECTION
   i2c_write(0xda); //SET COM PINS HARDWARE CONFIGURATION
   i2c_write(0x22);
#endif
   i2c_write(0x81); //SET CONTRAST CONTROL
   i2c_write(0x3f);    // MAX 7F
   i2c_write(0xa4); //DISABLE ENTRE DISPLAY ON
   i2c_write(0xa6); //SET NORMAL DISPLAY
   i2c_write(0xd5); //SET OSC FREQUENCY
   i2c_write(0x80);
   i2c_write(0x8d); //ENSBLE CHSRGE PUMP REGULATOR
   i2c_write(0x14);
   i2c_write(0xaf); //DISPLAY ON
   i2c_stop();
}
/* ----------------------------------------------------------------
    OLEDの画面クリア

      data : 埋めるデータ
---------------------------------------------------------------- */
void oled_clr(int data) // OLED 画面消去
{
   int32 i;
   oled_x = oled_y = 0;
   i2c_start();
   i2c_write(0x78); // OLED slave address
   i2c_write(0x00); // Control byte Co=0, D/C#=0
   i2c_write(0x20); // Set memory addressing mode
   i2c_write(0x00); // Horizontal addressing mode
   i2c_write(0x21); // Set column address
   i2c_write(0x00); // Column start address 0
   i2c_write(0x7F); // Column end address 127d
   i2c_write(0x22); // Set page address
   i2c_write(0x00); // Page start address 0
   i2c_write(0x03); // Page end address 3d
   i2c_stop();
   i2c_start();
   i2c_write(0x78); // OLED slave address
   i2c_write(0x40);
   for(i=0; i<512; i++){ // 128COL * 4page
     i2c_write(data); // Out data
   }
   i2c_stop();
}

/* ----------------------------------------------------------------
    OLED resume
      flag:
        true is NORMAL MODE
        false is SLEEP
---------------------------------------------------------------- */
void oled_resume( int flag)
{
    if( flag != g_oled ){
        i2c_start();
        i2c_write(0x78); // OLED slave address
        i2c_write(0x00); // Control byte Co=0, D/C#=0
        if( flag == false ){
            i2c_write( 0xae ); // SLEEP
        }else{
            i2c_write( 0xaf ); // DISPLAY ON
        }
        i2c_stop();
        g_oled = flag;
    }
    g_oled_cnt = 0;
}
/* ----------------------------------------------------------------
    OLED SETS PRINT POSITION
---------------------------------------------------------------- */
void oled_gotoxy( int x, int y)
{
    oled_x = x;
    oled_y = y;
}
/* ----------------------------------------------------------------
     OLEDに一文字出力
       font_code:
          配列を指定(0~)
       cx:
          出力水平位置(0~8)
       cy:
          出力垂直位置(0~1)
---------------------------------------------------------------- */
void char1216( int font_code, int cx, int cy ) // 12x16dot FONT
{
    int x;
    struct font_bit FONT_BIT1;  //before 8bit font
    struct font_bit FONT_BIT2;  //after extent 8bit font
    i2c_start();
    i2c_write(0x78); // OLED slave address
    i2c_write(0x00); // Control byte Co=0, D/C#=0
    i2c_write(0x20); // Set memory addressing mode
    i2c_write(0x00); // Horizontal addressing mode
    i2c_write(0x22); // Set Page Address
    i2c_write(cy*2); // Page Start
    i2c_write(cy*2+1); // Page End
    i2c_write(0x21);  // Set Column Address
    i2c_write(cx*13);  // Start Address(0-9)
    i2c_write(cx*13+11);  // End Address
    i2c_stop();
    i2c_start();
    i2c_write(0x78); // OLED slave address
    i2c_write(0x40);

    // 6*8 FONTを2倍にする処理、粗い文字となるがFONTデータが少量ですむ
    // MSBはOLED画面下方向
 
    // 1st page
    // FONT_BIT1.b0 -> FONT_BIT2_b0
    // FONT_BIT1.b0 -> FONT_BIT2_b1
    // FONT_BIT1.b1 -> FONT_BIT2_b2
    // FONT_BIT1.b1 -> FONT_BIT2_b3
    // FONT_BIT1.b2 -> FONT_BIT2_b4
    // FONT_BIT1.b2 -> FONT_BIT2_b5
    // FONT_BIT1.b3 -> FONT_BIT2_b6
    // FONT_BIT1.b3 -> FONT_BIT2_b7

    // next page
    // FONT_BIT1.b4 -> FONT_BIT2_b0
    // FONT_BIT1.b4 -> FONT_BIT2_b1
    // FONT_BIT1.b5 -> FONT_BIT2_b2
    // FONT_BIT1.b5 -> FONT_BIT2_b3
    // FONT_BIT1.b6 -> FONT_BIT2_b4
    // FONT_BIT1.b6 -> FONT_BIT2_b5
    // FONT_BIT1.b7 -> FONT_BIT2_b6
    // FONT_BIT1.b7 -> FONT_BIT2_b7

    if( font_code > 49 ){  // SPACE(BLANK) Draw
        for( x=0 ; x<24 ; ++x ){
            i2c_write( 0 );
        }
    }else{
        for( x=0 ; x<6 ; ++x ){
            FONT_BIT1 = font[font_code][x];
            //FONT_BIT1からFONT_BIT2へBITを振り分ける
            FONT_BIT2.b0 = FONT_BIT2.b1 = FONT_BIT1.b0;
            FONT_BIT2.b2 = FONT_BIT2.b3 = FONT_BIT1.b1;
            FONT_BIT2.b4 = FONT_BIT2.b5 = FONT_BIT1.b2;
            FONT_BIT2.b6 = FONT_BIT2.b7 = FONT_BIT1.b3;
            i2c_write( (int)FONT_BIT2 ); //横方向に同FONTを2 DOT
            i2c_write( (int)FONT_BIT2 ); //これで2 DOT分
        }
        for( x=0 ; x<6 ; ++x ){
            FONT_BIT1 = font[font_code][x];
            //FONT_BIT1からFONT_BIT2へBITを振り分ける
            FONT_BIT2.b0 = FONT_BIT2.b1 = FONT_BIT1.b4;
            FONT_BIT2.b2 = FONT_BIT2.b3 = FONT_BIT1.b5;
            FONT_BIT2.b4 = FONT_BIT2.b5 = FONT_BIT1.b6;
            FONT_BIT2.b6 = FONT_BIT2.b7 = FONT_BIT1.b7;
            i2c_write( (int)FONT_BIT2 );
            i2c_write( (int)FONT_BIT2 );
        }
    }
   i2c_stop();
}
//EOF


赤外線受信サブルーチン For CCSC Compiler
////////////////////////////////////////////////////////////////
//
// Infrared_X.H 
// 赤外線リモコン受信プログラム for ソニー
//
// AUTHOR: Yuichi
//
// NOTE:
//    (1)構造体の宣言例
//      struct porta_pin_map {      // This structure is overlayed
//        BOOLEAN unused1;
//        BOOLEAN Infrared_rx;
//        BOOLEAN sw;
//        BOOLEAN beep;
//        BOOLEAN Infrared_tx;
//        int     unused2 : 3;
//      }PORTA;
//    (2)1つのタイマーを使用
//      setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128 );//12.8us long
//
// FUNCTION:
//   int32 Infrared_read( void );
//   int32 ep_Infrared_read20bit( void );
//   int   ep_Infrared_measure_pulse( void );
//   int   ep_Infrared_measure_leader( void );
//   int   ep_Infrared_measure_hilow( void );
//
////////////////////////////////////////////////////////////////

// Infrared BIT LEVEL
#define Infrared_LOW      0
#define Infrared_HI       1
#define Infrared_LEADER   2
#define Infrared_OUT      3

#define TV_BLUE   0x0f004ba4
#define TV_RED    0x0f004ba5
#define TV_GREEN  0x0f004ba6
#define TV_YELLOW 0x0f004ba7
#define TV_DATA   0x0f004b95
#define TV_TENKEY 0x0f004b8c
#define TV_CH1    0x0c000080
#define TV_CH2    0x0c000081
#define TV_CH3    0x0c000082
#define TV_CH4    0x0c000083
#define TV_CH5    0x0c000084
#define TV_CH6    0x0c000085
#define TV_CH7    0x0c000086
#define TV_CH8    0x0c000087
#define TV_CH9    0x0c000088
#define TV_CH10   0x0c000089
#define TV_CH11   0x0c00008a
#define TV_CH12   0x0c00008b

#define PS2_1     0x14049D00  //Play Station2 リモコン
#define PS2_2     0x14049D01
#define PS2_3     0x14049D02
#define PS2_4     0x14049D03
#define PS2_5     0x14049D04
#define PS2_6     0x14049D05
#define PS2_7     0x14049D06
#define PS2_8     0x14049D07
#define PS2_9     0x14049D08
#define PS2_0     0x14049D09
#define PS2_L1    0x140DAD5A
#define PS2_L2    0x140DAD58
#define PS2_L3    0x140DAD51
#define PS2_R1    0x140DAD5B
#define PS2_R2    0x140DAD59
#define PS2_R3    0x140DAD52
#define PS2_DISPLAY 0x14049D54
#define PS2_MARU    0x140DAD5D //RT
#define PS2_PEKE    0x140DAD5E //RB
#define PS2_SANKAKU 0x140DAD5C //LT
#define PS2_SIKAKU  0x140DAD5F //LB
#define PS2_TIME    0x14049D28
#define PS2_UP      0x14049D79
#define PS2_DOWN    0x14049D7A
#define PS2_LEFT    0x14049D7B
#define PS2_RIGHT   0x14049D7C
#define PS2_START   0x140DAD53
#define PS2_CLEAR   0x14049D0F
#define PS2_ENTER   0x14049D0B
#define PS2_AUDIO   0x14049D64
#define PS2_PROGRAM 0x14049D1F
#define PS2_TITLE   0x14049D1A

/*---------------------------------------------
   Infraredを受信して32bitデーターを返す
   リピート時間制御:繰り返し時間よりも早くこの関数を
   実行すれば即returnする
---------------------------------------------*/
int32 Infrared_read( void )
{
    int32 code;
    if( ep_Infrared_measure_leader() != Infrared_LEADER ){  // リーダー検出
        return(0);
    }
    code = ep_Infrared_read20bit();     // 12-20ビット入力
    return( code );
}

/*---------------------------------------------
  Infraredを受信して32bitデーターを返す
   必ず、ヘッダー受信の後に実行するようにプログラムしなければならない
   global変数 g_Infrared_bit_lengを使う
   RETURN:
     32bit data
     0C 00 00 95  <- POWER ON(12bit)  
     0F 00 4B CA  <- 決定(15bit)
     14 04 9D 32  <- DVD再生(20bit)
     32ビットの上位8ビットはInfraredのビット長を示し、下位24ビットはコード
---------------------------------------------*/
int32 ep_Infrared_read20bit( void )
{
    int   a_cnt, a_data;
    int32 a_Infrared_bit_leng = 0;
    int32 a_code;
    int32 a_shift;
    a_code = 0;
    a_shift = 1;
    a_Infrared_bit_leng = 0;
    for( a_cnt=0 ; a_cnt<20 ; ++a_cnt ){
        a_data = ep_Infrared_measure_hilow();        
        if( a_data == Infrared_OUT ){
            break;  // END
        }
        if( a_data == Infrared_HI ){
            a_code |= a_shift;
        }
        a_shift <<= 1;
        ++a_Infrared_bit_leng;
   }
   // BIT長が12,15,20のいずれかであれば有効とする
   if( a_Infrared_bit_leng == 12 ||
       a_Infrared_bit_leng == 15 ||
       a_Infrared_bit_leng == 20 ){
           a_code |= (a_Infrared_bit_leng << 24);
   }else{
           a_code = 0;
   }
   return( a_code );
}

/*---------------------------------------------
  InfraredのLEADERパルスを検出する
   LEADERパルスは負の2400us幅である。立下りエッジから300us後
   がLOW,600us後がLOW,600us後がLOW,600us後がLOW,600us後がHI
   であればLEADERと判断する。

  "0"     ~~~~|_|~~~~~~~~~~~~~~~~~~~~~~~ width=600us
  "1"     ~~~~|____|~~~~~~~~~~~~~~~~~~~~ width=1200us
  LEADER  ~~~~|__________|~~~~~~~~~~~~~~ width=2400us
---------------------------------------------*/
int   ep_Infrared_measure_leader( void )
{
    int16 uscnt=0;
    if( !PORTA.Infrared_rx ){
        return( Infrared_OUT );
    }
    do{
        if( uscnt > 400 ){         // uscnt400は約800us
            return( Infrared_OUT );   // 800us経過してもLOWにならない
        }
        delay_us(1);
        ++uscnt;
    }while( PORTA.Infrared_rx );        // LOWになったか
    delay_us(300);
    if( PORTA.Infrared_rx == 0 ){
        delay_us(600);
        if( PORTA.Infrared_rx == 0 ){
            delay_us(600);
            if( PORTA.Infrared_rx == 0 ){
                delay_us(600);
                if( PORTA.Infrared_rx == 0 ){
                    delay_us(600);
                    if( PORTA.Infrared_rx == 1 ){
                        // ここまでくると本当のLEADERパルス
                        return( Infrared_LEADER );
                    }
                }
            }
        }
    }
    return( Infrared_OUT );
}
/*---------------------------------------------
  InfraredのHI又はLOWパルスを検出する
   必ずLEADERパルスの直後から呼び出して検出すること
   立下りエッジから900us後にHIであれば"0"パルス、LOWであれば
   "1"パルスと判断する。

  "0"     ~~~~|_|~~~~~~~~~~~~~~~~~~~~~~~ width=600us
  "1"     ~~~~|____|~~~~~~~~~~~~~~~~~~~~ width=1200us
  LEADER  ~~~~|__________|~~~~~~~~~~~~~~ width=2400us
---------------------------------------------*/
int   ep_Infrared_measure_hilow( void )
{
    int  level;
    int16 uscnt=0;
    do{
        if( uscnt > 400 ){         // uscnt400は約800us
            return( Infrared_OUT );   // 800us経過してもLOWにならない
        }
        delay_us(1);
        ++uscnt;
    }while( PORTA.Infrared_rx );        // LOWになったか
    delay_us(900);                   // LOWのなった瞬間から900us後に
    level = PORTA.Infrared_rx;          // HI/LOWを読み込む
    while( !PORTA.Infrared_rx );        // HIになるまでここで待つ
    if( level ){
        return( Infrared_LOW );
    }else{
        return( Infrared_HI );
    }
}

//EOF


ありがとうございますm(__)m For アランドロン
ゆういちの上司はアランドロンの髪型と似てるだけじゃなかったけ?
おわり

過去の記事:
猫用自動給餌器をリモコン制御に改造
猫用自動給餌器をリモコン制御に改造、その2
猫用自動給餌器をリモコン制御に改造、その3


人気ブログランキング
nice!(10)  コメント(0) 
共通テーマ:趣味・カルチャー

アース棒打ち込んだ [アマチュア無線]

アマチュア無線仲間から30cm長のアース棒をいただいた
多少はノイズが減り、アンテナ(GP)の性能が向上するようにと・・・
昔、洗濯機などを購入するとにアース棒が付属品として同梱されていたことを思い出す
集合住宅の上階であれば打ち込む場所もなく処分に困ったことがあったかもしれない
しかし、今のゆういちにとっては貴重品
DSC_0511.JPG

無線部屋近くのエアコン室外機付近にアース棒を打ち込んで、既設のエアコンダクトの中を通して無線機に接続する、いいんじゃないか・・・心の声で喋ってみた
GND_E_SCH.jpg

打ち込む直前、地中にある配管の存在が頭を過った
エアコン室外機のそばには、
建屋から30~40cmほど離れて雨水マスがある
また建屋に密着するように縦樋が砂利で埋まっている
雨水マスの蓋を開けてみるとすぐ近くの縦樋からの接続穴と、建屋に平行しているであろうと思われる接続穴が確認できる
DSC_0519.JPG

雨水マス同士が接続されているパスは建屋から30~40cm離れていると推測し、アース棒は建屋の壁から20cm以内であれば問題ないと判断し写真の位置にハンマーを使って打ち込み始めた
砂利下の防草シートを突き破りコンコンコンっと・・・
DSC_0512.JPG

なるべく地中に潜り込んでほしいため、この様な杭でアース棒の頭をピンポイントに狙い打ち込んだが、納得いく深さまでは潜り込まなかった
DSC_0514.JPG

打ち込みが終わると何もなかったように砂利を撒いて、この工程を終える
DSC_0518.JPG

アース線はここから部屋の中へ入線する
DSC_0510.JPG

室外はダクトを外してアース線を這わせる
DSC_0516.JPG

ダクト下側、緑色の線がアース線
DSC_0515.JPG

無線機にねじ止めする圧着端子の取付が終わり作業完了(2023/12/9)

次に、
圧着端子を無線機のアース端子に付けたり離したり、変化を確認してみた
HFアンテナを所有しないため144/430のデユアルバンドGPで、HFから430MHzまでのノイズや信号強度の変化を確認した
顕著に変化が見られたのが50M帯
アース線を接続すると、信号強度が+1になったのか?ノイズが+1したのかはわからないが
何らかの変化があった

◆アースなし
Sメーター = 2
20231210_162819.png

◆アースあり
Sメーター = 3
20231210_162828.png

事後になるが、このようなアース線の引き回しをせず、既設の冷媒管を利用し下記(1) (2)の接続作業だけでよかったかもしれないと思う
(1) 無線機 → エアコン室内機アース端子
(2) 室外機 → アース棒
なぜならばエアコン室内機と室外機は導電性のある冷媒管で接続されているから

無線機は安定化電源から電源供給を受けているため、
次回は無線機から安定化電源へアース接続してみよう


人気ブログランキング
nice!(8)  コメント(0) 
共通テーマ:趣味・カルチャー

草刈り機のヘッド部の掃除 [DIY電気]

マキタの充電式草刈機
伸び盛りの子どもたちのようにグングン育つ草木の季節が終わった
清掃もかねての点検とする
DSC_0487.JPG

型式は MUR189D
DSC_0490.JPG

ヘッド部の分解掃除をするためにネジ8本を外した、が!
DSC_0488.JPG

しかし、開かない
爪があるのかどうかもわからない
無理やり開けるとバキっとしそうだ
DSC_0492.JPG

3時間ぐらい試行錯誤して・・・
ウソです10分ぐらい試行錯誤して
この金属の丸い部品を取ればいいということがわかった
DSC_0493.JPG

外したらこんな部品
このヤロウが先に外れるとは思いもしなかった
DSC_0494.JPG

外した部分には枯草・・・
DSC_0495.JPG

パカっと割って、きれいに並べた
DSC_0496.JPG

モーターは簡単に外れる
DSC_0497.JPG

グリスが塗布されているのでカバーごと洗浄するのはやめてブラシで掃除するだけにした
DSC_0498.JPG

この部品も簡単に外れた
DSC_0499.JPG

グリスが塗ってあるためカバーを水洗い清掃できなかったのが
残念であった
来年も回すぞ!

人気ブログランキング
nice!(16)  コメント(0) 
共通テーマ:日記・雑感

平屋にアマチュア無線のアンテナ [アマチュア無線]

自宅にGPアンテナ(144/430MHz)を設置する構想を始めたのは二か月ほど前だったか?
何の変哲もない平屋の住宅、
アマチュア無線家にとっては夢が膨らまない
二階建てであればベランダに自力で取付することもできたであろうに、
うちのどこにGPアンテナを取り付けようかと、熟考せずにサラっとフリーハンドで書いてみた
ANT(1)とANT(2)を・・・
ANT(2)は太陽光発電パネルの発電効率にも影響あるだろうし、太陽光発電パネル破損事故の元になりかねないため即刻棄却とした。わかっていたのだが、ただ屋根馬式のアンテナを書いてみたかっただけである
なんとなく書いたらスッキリした
スッキリするや否やANT(1)で進めることにした
my_antenna1.jpg

もう少し考えを進めていくと、高いことに越したことはないということで下図天辺(A案)に取り付けることにしようとしたが、建築図面から読み解くと柱が無い可能性があるため、柱のあるB案にすることにした
その後、アンテナ設置業者さんと打ち合わせを始め屋根裏に上がっていただいて柱確認をしていただいたら、ボードが貼ってあり柱の確認は全くできないと言いながら屋根裏から降りてこられた
重量物を取り付けられる柱がある確信がとれず
A案、B案は廃案となる
my_antenna2.jpg

残念ではあるが、最終的に下図、家の端に取り付けることに決定した
柱があることが確定しているからである
C案ということにする
アンテナ設置業者さんとの取り決めで、アンテナ、アンテナマスト、壁面取付金具、同軸ケーブルの4点はこちらで調達することにした
my_antenna3.jpg

次に、壁面取付金具の選定である
壁面取付方式の場合、軒先や破風があるため、それらより外側に突き出さなければならない
破風の長さを測ると400mmあるのだ
400mmを超える壁面取付金具を探すとマスプロ電工の伸縮型 サイドベース SB32K51にたどり着いた
side_base_2.jpg

SB32K51の取説にも言及されている強度を向上する方法を参考に
2つ取り付けることにした
side_base_1.jpg

CQオームさんで購入した第一電波工業 X50 144/430MHz帯高利得
2バンドグランドプレーンアンテナ
DSC_0411.JPG

これがアンテナ本体、X50はステッキのように太いが、軽い!
耐風速60m/secと規格欄に書かれている
DSC_0412.JPG

壁取付アーム、マスプロ サイドベース SB32K51
2つ、Amazonから購入
DSC_0420.jpg

アンテナマストの調達はホームセンターに足を運んだ
家電コーナーで日本アンテナ アンテナマスト(φ32×1800mm)を発見!しかし重い重い!
重さを確認したら売り場に戻して、部材コーナー向かいステンレス製のパイプを発見し購入した
長さは日本アンテナのものより2cm長いだけである
これがモリ工業 MGオールステンパイプ(ステンレス製パイプ)
日本アンテナのアンテナマストより軽い
DSC_0429.jpg

下写真は、購入を見合わせた日本アンテナのアンテナマスト
DSC_0408.JPG

同軸ケーブルは取り扱いに難があるかもしれないが、電気的特性を優先してCQオームさんから8DFB×15mを購入
小指の太さぐらいある、写真は撮り忘れた

ゆういちが調達した部材の要約
(1) 第一電波工業 X5 144/430MHz帯高利得2バンドグランドプレーンアンテナ 11,800円
(2) 藤倉(フジクラ)ケーブルセット 8DFB15mMPMP LITE 15,184円
(3) 壁取付アーム、マスプロ サイドベース SB32K51 @4,900円×2台=9,800円
(4) モリ工業 MGオールステンパイプ φ32×1820 2,280円

重量をまとめると
(1) 0.9Kg
(2)
(3) 2.6Kg×2
(4) 約1kg

TOTAL: 7.1Kg

2023年11月19日
信頼できるアンテナ設置業者さんによる取付作業が完了した
破風を超えさせるため、マスプロ サイドベースは450mmの長さに固定
マスプロ サイドベースの取付ピッチは600mm
地上高低い!
給電点まで4mぐらいか?
交信した相手に「地上高・・・メーターです」、何て言おうか?
給電点までだったら4m、アンテナの先端だったら6mか、
真ん中をとって、地上高5mとしよう
下写真のシャッター戸袋手前に、幸運にも未使用のエアコン用の穴があり入線させ、防雨カバーを取り付けてもらっている
防雨カバーと言ってもエアコンのドレインダクト用の部品みたいだ
DSC09261.JPG

給電点付近
アンテナマストにGPアンテナに付属のUボルトで固定
DSC09262.JPG

瓦とアンテナマストの間隙は約50mm
DSC09264.JPG

自宅の表側から撮影すると何となく高く見える・・・
DSC09268.jpg

ご参考:144/430MHzのSWR by IC-705
145_SWR.png
430_SWR.png

取付費用は?ナイショ
何度も打ち合わせや事前確認に我が家に来ていただいたアンテナ設置業者さんに感謝
めでたし、めでたし

【この記事で紹介している商品】




第一電波工業 Diamond 144/430MHz帯高利得2バンドグランドプレーン X50

第一電波工業 Diamond 144/430MHz帯高利得2バンドグランドプレーン X50

  • 出版社/メーカー: 第一電波工業
  • メディア: エレクトロニクス




人気ブログランキング
nice!(10)  コメント(0) 
共通テーマ:趣味・カルチャー
前の10件 | -