人気ブログランキング | 話題のタグを見る

前記事
で購入しない方がいいと言ったが、下記の対策をすれば、とても綺麗でレシピも優しく、壊れないのでちょっと生産拠点をくつろげる場所にするのに、買ってもいいかも(75%オフなら安いし)。


家具アドオン(Furniture Add-On)のガイドブックを開き・閉じると、
バグで、その都度消えない透明エンティティ(ブロックではなく、動物や敵)が残ってしまう。

なので、ガイドブックをイメージ取り込みして、日本語に訳した。

これで二度と開かなくて済むようになる。


【重要】
ちなみに残ってしまった場合、実績解除が出来なくなるが、チートONにしてからそのチャンクに行き、読み込みが終わってからコマンドで、

/kill @e[type=エンティティID]
エンティティID=ees_furn:guidebook_hitbox

を実行する。

近くにいれば[type=…]は省略可能。

◎ PCでチートフラグをOFFに戻すツール(NBT Editorなど)を使って、エクスポートした.mcworldを書き換えて、再度インポートすれば元に戻る(SwitchなどはReamls経由でPCへ持っていく)。

【日本語版】
[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_03381934.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_03383090.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_06295937.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_03384574.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_03384987.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_06300566.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_07102909.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_07103562.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_07104018.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_07104605.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_09314756.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_09321626.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_09323406.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_09325154.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_09332367.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_09334108.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_09335774.png

[マイクラ統合版] 家具アドオン [ガイドブック日本語翻訳] (7/16)_a0034780_09342155.png

これでガイドブックを全て翻訳したので、安心して家具アドオンを使える。
(最初にメモ帳みたいなアイコンで入手するけど、すぐ捨てる事)



# by k1segawa | 2026-07-16 03:52 | Comments(0)

(2026/7/13 05:21追記)
現在月曜朝でも無料なので8/4辺りまでは購入できるようだ。
お試し期間は長い方がいいから早い方がいいけどね。

■ 自然な景観(現実に近いなだらかな山や丘、平原のぐあい - バニラの急峻な山岳や谷間とは違う)が追加

1. Realistic Bioms Add-Onが追加されている。
これは軽いのにバニラの景観を自然に近づけるアドオンで、地形生成系。
※ +αで、バイブラントビジュアルが無くとも影MOD的な湿地帯の霧や雨しぐれも掛かる。
太陽や月が大きくなり、動物等はバニラのまま(土が少し動的になる)でなじみやすい。
夜、手に松明を持つと明るくなるので、ピースフルで流星や一番星を見ながら散策するのが楽しい。
※ 山々の遠景を高高度で眺められるくらいになってから入れるべきアドオンで、序盤は不要。

33%オフ 660円(本来990マインコイン)
18MB
実績解除も出来る。
SwitchやPS5などのコンシュマー機に優しい。
バニラを大きく変化させないが、松明の光の広がり方が丁寧でセンスがある。

2. マッシュアップだが、絶対的な自然な景観にこだわるなら(新規バイオーム追加ではなく)、Realism Craftも重いけど良い。
180MBと圧倒的な容量だ。
新規作成となる。
※ バイブラントビジュアル無しだと霧、遠景暗転(遠くほど暗くなる表現)は掛からない。遠景の不透明(大気を通した)は掛かる。
その代わり、動的なリアルさ(風や草の揺れ、流れ星、新たな動物 - かたつむりとか渡り鳥、蝶々等)が追加され、バニラの「一人寂しい」感じが軽減されるwww
技術的にはスゴイ。
でも、松明の光の広がり方などで分かるし、動物の顔がなぜバニラがあれなのか、理解していないし、子供の落書きみたいだ。
(少しアホっつぽいし、少しデジタルっぽいのがマイクラに合う - リアルでないのが良い。ギリギリ公式のひよこまで)

PC向けか。
33%オフ 1100円(本来1690マインコイン)

注:
2は実績解除が無効になるので注意。
だがそれも納得の出来だ。
なぜならツールや武器、ボスや動物、さらにアクションの変更まで追加されるから。
バニラのテクスチャも書き換えられて、違和感も少ない(Action&Staffに比べて明るいファンタジーっぽくない)。
バイブラントビジュアル無しでも十分だ。
これだけ入って1100円は個別に買うより安い。
中盤以降でもう実績解除は苦しくなって、テクスチャやアクションの変更に抵抗が無く、新しい変化を求めるPC勢ならおすすめだ。

注:
1も2もだが、リソースパックで出てこない時は、
最初のメニュー(マイクラ終了が出来る画面)
>マーケットプレイス
>ライブラリ(自分の購入したアドオン)
>検索ボックスで"Realism"や"Realistic Biom"と検索
>左の欄から追加コンテンツ
>スクロールして探してクリック
>無料ウィークエンド!ボタンを押す
>既存と新規
のどちらかを選ぶと追加可能。

日替わりで追加されていくのかな?


あと、家具アドオンが75%オフで330円だが、
有名海外アドオン評価配信者によると、
バグがあって、ガイドブックを開き閉じると、ガイドブックのあった場所(3ブロック - それも変な配置で。横2と斜め手前に1個)に透明な破壊不可能エンティティ(モブ判定)が残ってしまい、どうしようも出来なくなるとの事。
1年前の事だが、本日購入したが直っていなかった。残念。
(このスタジオはものすごい数出してて、たぶん直す気は無い)
なので購入しない方がいい(別のクリエイティブワールドでガイドブックを開いて調べ、メインでは絶対開かないくらいの気持ちでやらないと)。

(2026/7/16追加)
で、ガイドブックを画像付きで日本語訳したので、ガイドブックは開かなくて良くなった。
(おわり)

動画の中で、家具の素材部分をオリジナル素材の2色で塗り分けられるのと、その素材部分2種類をバニラ素材から指定できるという、画期的(木と布のペイントブラシ)とは褒めているが。
実績解除をあきらめれば、チートONで、/kill @n(最も近くのエンティティ)で削除可能。

(おわり)

2026年7月11日(日本時間12時現在)から、サマーセールの一環で、24日間14時間(8月4日か5日くらいまで)の無料アドオンが追加されている。

[マイクラ統合版] 2026/7 期間限定 無料ウィークエンド開始! [アドオン] (7/11)_a0034780_12432616.png

期間限定なので、フル機能が遊べるが8月4日前後になると動作しなくなるので、続けて遊ぶ場合はそのアドオンを買うか、マーケットプレイス パスへの加入が必要となる。

とりあえず、ダウンロードしておいて、新規ワールドで試してみると良い。
(既存のワールドには気に入るまで適用(インポート)しない)

ダウンロードするアドオンの一覧だ。

・ エターナルエンド
・ 居住者 2.1
・ Cut the Rope
・ アイテム合成追加コンテンツ
・ Jetpacks
・ MOB LIGHTS
・ Traning Dummies
・ アルティメットブラスターズ
・ PVP Add-On

33%オフの物もあり、元々1300円くらいから430円程度まで色々。

8月4日前後で無効になったら、リソースパックからの削除+ストレージのキャッシュクリアをすればクリーンになる。

居住者 2.1は有名なホラーアドオンだし、PVPも老舗だ。
簡単なCut the Ropeでファンタジーっぽくなったり、Jetpacksで宇宙にロケットを飛ばしたり、アルティメットブラスターズで武器強化しても面白い。

どれも評価が高いし、24日間あるから、じっくり楽しんでみると良い。
(無料ウィークエンドなので本日の週末土曜日だけのダウンロードかもしれない←7/13月曜でも無料のままだったのでまだまだ大丈夫→7/15水曜でマーケットプレイス パスへの加入ボタンに変わっていたのでやはり週末だけの一時的な体験版だったようだ)

★ 普通のリソパのように恒久的にPC内などに保存されるのではなく、その都度マケプレから「無料ウィークエンド!」ボタンで追加する(追加するワールドを既存or新規から選ぶ)。
追加したワールド内にはアドオンとして残っているが、リソパとしては表示されない。表示されなくても入ってはいる。


# by k1segawa | 2026-07-11 12:38 | マイクラ | Comments(0)

XPクリスタルバンク を買ってみた。

死亡で失われる経験値を、あらかじめ保存・引き出せるアドオンだ。

ホットバーに全ての追加アイテムを示す。

[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_16274440.png
(XPバンク|XPパーソナル|XPディスペンサー|ガイドブック|wiki|ハンマー|バール|レンチ|空き)


【先に結論】

サバイバル初期を楽にはしてくれない。実質中盤以降。

理由:レシピにネザーアイテムが必要なので、聖職者か醸造台の村を探すか、ネザーに行かないといけない。
初心者ソロ(自分も)は購入注意。
マルチプレイの場合、経験値が共有なのがメリット(ベテランに助けてもらえる)。


【目的】

余った経験値がもったいなかったので、アイテム回復ただ一点のために購入した。
(天空トラップタワー作成後かつ修繕のエンチャント後)

評価が高いのはマルチか、唯一無二のオーブ排出と経験値無限化やXPが保存出来る持ち運びアイテムがある点。


◇◇◇


☆ アイテム一覧

XPバンク ・・・ 経験値を預ける・引き出す
XPパーソナル アカウント ・・・ 個人用XPバンク持ち運び用
XPディスペンサー ・・・ 経験値オーブとして排出する(修繕用)

ハンマー ・・・ XPバンク類をアイテム化
バール ・・・ XPバンク類を移動
レンチ ・・・ XPバンク類を回転

ガイドブック ・・・文字のみの使用説明書(レシピ等)
wiki ・・・ 絵による概念図(1ページ)


☆ レシピ

■1. XPバンク

グローストーンの粉:1
金インゴット:2
エメラルドブロック:1
黒曜石:3
[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_16312360.png
設置して、
叩く(左クリック):全預け入れ(保存)
使う(右クリック):全または一部引き出し(中断あり)
対象は経験値。預け入れは全部だが、引き出しは再度右クリックで中断可能(3レベル/秒ぐらいで速い)。
20分毎に利息が付く。
経験値をたくさん入れて長時間放っておけば実質無限化出来る。

移動には、あとの「ハンマー」が必要で、「右クリック」でアイテム化する。


グローストーンは、聖職者と取引で入手する。
またはネザーへ行く。

黒曜石はダイヤのつるはしが必要だが、ピラミッドや壊れたネザーゲートで入手できるかも。

XPバンクは全プレイヤー共用で、どこでも誰でも預けられ、どこでも誰でも引き出せる。

ワールドに複数あってもよい(リンクしている)。
マルチプレイでサブアカウントから預けてもよい。

マルチプレイの時、他のプレイヤーが保存した経験値を使う事が出来る。

経験値オーブを吸収する事はできない。

(オーブはプレイヤーしか吸収できない)


■2. XPパーソナル アカウント

エメラルド:4
レッドストーンの粉:1

[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_16594152.png
個人用XPバンク。
持ち運び用で設置は出来ない。
レシピが簡単なので、死亡時の備えとしては有能。

使う(右クリック):次の画面を表示し、保存と引き出しが可能。

[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_17075349.png
(つづき)
…友達と XPを共有し、さらに毎日利息を獲得したい方は「XPクリスタルバンク」をぜひご利用ください。

XPバンクとは別。利息も付かない。
次に示す「XPディスペンサー」に経験値を供給することは出来ない。

※ 名前にアカウントと付いているが、同じアカウントなら別のワールドでも経験値が引き継げるわけではない。


■3. XPディスペンサー

エメラルド:4
金インゴット:4
XPバンク:1
[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_17171062.png

XPバンクに貯まっている経験値を、経験値オーブに戻して排出する。
修繕したい武器などを回復する事が出来る。

叩く(左クリック):排出開始・途中終了
使う(右クリック):同上

経験値オーブが出なくなると終了する。

演算距離4チャンクを超えても排出可能。たぶんワールド全域で利用可能。

XPバンクはインベントリ内やチェストにしまっていてもOK。

移動は「ハンマー」で「右クリック(使う)」が必要。

設置した様子はXPバンクと似ている。XPバンクは前にアメリカ連邦銀行みたいなマーク(パルテノン神殿の柱)が付いているので、近寄って正面を見るか、
少し遠くからだと、正確に上下対称なひし形のがXPディスペンサーで、四角錐(すい)のような少し下半身が小さいのがXPバンク。
[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_20024348.png
(左がXPバンク、右がXPディスペンサー)


■4. ハンマー

丸石:1
木の棒:1
[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_18191749.png
設置したアイテムをアイテム化する(移動)。

XPバンク、XPディスペンサー、wikiが対象。

右クリック(使う)である点に、注意。


■5. バール

木の棒:2
鉄インゴット:2
[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_18234119.png

設置したアイテムをその場で「前後に」移動する。
右クリック(使う):後ろ
左クリック(叩く):前

左右に動かしたい場合は、面倒だが設置したアイテムの横に回って、そちらからクリックする必要がある。


■6. レンチ

原木:1
木の棒:1
[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_18294485.png
設置したアイテムを回転する。
右クリック(使う):右回転
左クリック(叩く):左回転

8回で元に戻る。
(XPバンクの場合)


■7. ガイドブック

本:1
エメラルド:1
[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_18370561.png
使用説明書。
アドオン有効化後、最初に与えられる。

最初のページの、翻訳がまだ不安定。

説明内容はレシピぐらい。


■8. wiki

紙:1
エメラルド:1
グローストーンの粉:1
[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_18435239.png
図解1ページのみ。
ツールは3つ。
叩く(パンチ)と使う(インタラクト)。
[マイクラ統合版] XPクリスタルバンク [330円アドオン] (7/8)_a0034780_18502810.png
最初正面でなく右斜め横に配置されてしまう。一回見たら削除する。

閉じるためには、ハンマー・右クリックが必要なので注意。


☆ 注意

XPパーソナルを持っていくと、わざわざXPバンクの所に行かなくとも保存は可能。

XPディスペンサーは0.5レベル/秒くらいのゆっくりな速度で経験値オーブを出す。

サバイバル初期ではXPバンク自体の作成負荷が重いので(ネザーアイテム)、結局楽にはならない。


☆ 結果

このアドオンは、中盤以降の経験値トラップで余るくらいの経験値を入手可能なレベルの人が買うか、
よく死んで経験値を無駄にする人が買う。
つまり、やりこんでる人には刺さる。

細々とXPパーソナルで保存したり、XPバンクで無限化したり。

ただ初心者には優しくない(運よく村人やピラミッドがあればOK)。


☆ 感想

マイクラ統合版の序盤難易度を、優しくし過ぎないようアドオンの作成負荷を高くする事でコントロールしてるMS・モヤングの方針が変わらない限り仕方がない(難しいからそれを乗り越えた時ハマる)。

コントロールしている物
移動スピードや強さや防御力、入手難易度など


# by k1segawa | 2026-07-08 06:31 | マイクラ | Comments(0)

(2026/6/24追加)
メインにコマンド入力機能追加。ウエイト時間の問題>各pio系関数毎にウエイト追加。液晶クリアのみウエイト増加(液晶用lcd_commandウエイト短縮)
(おわり)

前回の記事で、Geminiが割とあっさり動作するコードを教えてくれた。

☆1
 
自分が最初に書いたソースは、
pioset関数とpioput関数を必ず1組のペアとして発行するソースだった(pioputで出力ピンの連続設定は除く)のだが、

Geminiが教えてくれたソースは、
pioset関数のみで入力切り替えだけして、入力に指定したピンが繋がっているSDA/SCLポートを、Hiにする方法だった。
同様に、Lowにするのもpioput関数だけで0を指定し、元々1だった入力ピンに繋がっていたSDA/SCLポートを0(Low)にする。

別に組で使わなくても行ける場合もある事を教えてくれた。

それで実際動作しているので、ユーザマニュアルには書かれていない、自分が勝手に解釈して間違っていた、正しいピンの使い方なのだろう。

根拠はたぶん他にあるPC-G850Gのソフトのソース。

それも、pioをC言語でアクセスするソース。

pio系関数は、Sharpの内部ROM上のライブラリのAPI(IOCS)なので、z88dkなどからの外部ライブラリでは呼び出せないはず(pio系関数のような形では)。

とすると、ポケコンのC言語で組んだアプリで、ポートアクセスするアプリとはなんだろう?

PC-E500(メモリマップドI/O)の非Z80系CPU、PC-E200やPC-G850VのZ80系CPUのForthとかあるけど、あれはポートアクセスも出来るはずだから、そこが参照元ソースなのか?

ポートアクセスできる言語をインプリメントしたアプリなら、それも参考になるから、PC-E500用のBACICコンパイラがあるからそれも、ポートアクセス機能(メモリマップドI/Oだから直接はpio関数との類推は出来ないと思うが)があれば、元ソースにはなる?

どうやってAIは正しいソースを得たのだろう。

そして、最初の検討時に、ChatGPTに抵抗の付け方を聞いた際に、プルアップならどんなポートアクセスが普通か例を示してもらったら、piosetとpioputの組で示されて、自分でもそうだと思っていたから、そのまま補強材料として、必ずペアで発行する物だと思ってしまった。

ChatGPTは部分的に、Geminiは全体の課題として、質問を投げかけたのでこんな違いが出たのだろう。
pio関数をペアでソース組んでる時は、相手側はデジタル回路ではなく、スイッチとLEDの回路だったからそれでも動いたのかもしれない。

なかなかAIも使い方が難しいな。

☆2

Geminiのソースも、そのままでは余りにも状態変化が遅すぎたので、ウエイト時間の調整など入れなければ実用には厳しかった。
ただ、確実にウエイトが長い方が、動作は安定していた。
ウエイトの短縮は、試行錯誤して決めたものだった。
(10→5に半分にするのは何とか良くて、10→2とかにすると動作しなかった)

なので、Geminiも完ぺきではない。

今も不安定でうまくいかない時もある。
ただリセットしたり、繰り返したりすると動作するので、前提とする回路に問題があるのではないかと疑っている。

これはデジタル回路の基本で、DIP型の標準ICを探している時に、最近もっとも使われているICの種類を聞いて出てきたのが、CMOS(MOSFET)回路だった。
この回路の使用上の注意を聞いたら、ピンにシュミットトリガやパスコンを入れて、立ち上がりや立下りが遅い周波数のCPUや、ノイズ信号の対策をすべきと出てきた。

今のSDA/SCLポートはシュミットトリガーを入れて、綺麗な矩形波にした方がいいのかもしれないし、GNDにもパスコンを入れた方がいいのかもしれない。

そういうことがわかってきて、自分やGeminiに提案した時の前提回路が、実はCMOSの弱点までカバーできていないのかもしれないと思いついた。

☆3

また、Geminiのソースは2回に分けて聞いたためか、ウエイト関数が重複している(i2c_waitとdelay_ms)。

この冗長性が必要なのか、かえって動作を不安定にしてしまっているのかが分からない。

やはりそれを指摘するには、I2Cの知識が必要で、やっぱり全く知らない部分をAIに作ってもらっても、正しいか判断できないし、修正プロンプトも作成できない。

☆4

なんやかんやで、まだ完ぺきではない。

今はI2Cをコマンド入力できるようにして、シェルのようにその場でダイレクト入力してテストしている。

そこでもたまに失敗するので、本当はpio系関数を呼び出しているところ全部に、ウエイトが足りないのではないかと疑問視している。
(Z80のC言語であっても、pio系関数の連続呼び出しは、SDAとSCLの立ち上がり時間の差のMINが十分短すぎるのかもしれないと考えている)

☆☆☆

今のコマンド入力可能なソースはこちら:

// 保持時間用のウェイト関数(長めにとっています)
int i2c_wait(int c) {
int a,i; // コンパイラ最適化防止のvolatileがないのでa+=i;returnで代用
a=0;

for(i = 0; i < c; i++) a+=i;

return a;
}

// I2C スタート条件を出力する関数
void i2c_start() {
int rtn;

// 1. 初期状態:両方のピンを入力に設定し、プルアップ抵抗で確実に「Hi」にする
pioset(0x03); // bit0(SDA)=1, bit1(SCL)=1 を入力に
rtn=i2c_wait(5);

// 2. 先に「出力」に切り替えてから、SDA(4ピン)を「Lo」に落とす
// SCLは入力(Hi)を維持したまま、SDAだけが「Hi → Lo」になります(スタート条件)
pioset(0x02); // bit0(SDA)=0(出力), bit1(SCL)=1(入力のままHi)
rtn=i2c_wait(5);
pioput(0x00); // bit0(SDA)=0(Loに落とす)
rtn=i2c_wait(5);

// 3. 次にSCL(5ピン)も「出力」に切り替えて「Lo」に落とす
// これで両方のピンがLoに固定され、データ送信の準備が整います
pioset(0x00); // bit1(SCL)も0(出力)にする
rtn=i2c_wait(5);
pioput(0x00); // bit1(SCL)=0(Loに落とす)
rtn=i2c_wait(5);
}
// 1バイトデータを送信し、液晶からのACK(0=成功, 1=失敗)を返す関数
// ※事前のスタート条件により、SCL=Lo, SDA=Lo (両方出力) から始まる前提です
int i2c_write_byte(unsigned char data) {
int i,w;
int ack_bit;
int rtn;
unsigned char bit_val;

// --- 1〜8ビット目のデータ送信ループ ---
for(i = 0; i < 8; i++) {
// MSBファースト(最上位ビットから順に)データを取り出す
// 送るビットが1ならHi(0x01)、0ならLo(0x00)
if((data & 0x80))
bit_val = 0x01;
else
bit_val = 0;
// bit_val = (data & 0x80) ? 0x01 : 0x00;→三項演算子がないので
data <<= 1; // 次のビットのために左シフト

// SCL=Loの状態で、SDAの出力を変更する
pioput(bit_val);
rtn=i2c_wait(5);

// SCLをHiにして液晶にデータを読み込ませる
// (SCLを1にするために、入力(開放)ではなく、出力のままHiにするのが確実です)
// ※bit1(SCL)を1にするため、SDAの状態(bit0)と合わせる
pioput(bit_val | 0x02);
rtn=i2c_wait(5);

// SCLをLoに戻す
pioput(bit_val);
rtn=i2c_wait(5);
}

// --- 9ビット目:液晶からのACK(応答)を確認する処理 ---
// 1. まずSDA(4ピン/bit0)を入力モードに切り替えて、液晶が自由にSDAをLoにできるようにする
// SCL(5ピン/bit1)は出力モード(0)のまま維持します
pioset(0x02); // bit0=1(入力), bit1=0(出力)
rtn=i2c_wait(5);

// 2. クロック(SCL)をHiにする
pioput(0x02); // bit1(SCL)=1
rtn=i2c_wait(5);

// 3. この「SCLがHi」のタイミングで、液晶がSDAをLoに引き下げているかをpiogetで確認する
// bit0(SDA)が0(Lo)なら液晶が正常にデータを受け取った合図(ACK)です
w = pioget();
if ((w & 0x01) == 0) {
ack_bit = 0; // ACK成功(正常)
} else {
ack_bit = 1; // NACK失敗
}

// 4. クロック(SCL)をLoに戻す
pioput(0x00); // bit1(SCL)=0
rtn=i2c_wait(5);

// 5. 次の通信に備えて、SDA(4ピン)を再び出力モード(0)に戻しておく
pioset(0x00); // 両方出力モードへ
rtn=i2c_wait(5);

return ack_bit; // 0なら液晶が正しく認識しています
}
// I2C ストップ条件を出力する関数
void i2c_stop() {
int rtn;
// 1. 最初は両方「Lo(出力)」の状態で、ピンが確実にLoであることを確認する
pioset(0x00); // 両方出力モード
rtn=i2c_wait(5);
pioput(0x00); // 両方Lo
rtn=i2c_wait(5);

// 2. まずSCL(5ピン)だけを「入力」に切り替えて、プルアップ抵抗の力で「Hi」にする
// SDAはLo(出力)を維持したまま、SCLだけが先に「Hi」になります
pioset(0x02); // 注0x01->0x02 // bit0(SDA)=0(出力のまま), bit1(SCL)=1(入力にしてHiへ)
rtn=i2c_wait(5);

// 3. 最後にSDA(4ピン)も「入力」に切り替えて、プルアップ抵抗の力で「Hi」にする
// 「SCLがHi」の状態で、SDAが「Lo → Hi」へ立ち上がります(ストップ条件成立)
pioset(0x03); // bit0(SDA)=1(入力にしてHiへ), bit1(SCL)=1(入力のまま)
rtn=i2c_wait(5);
}
// 1つのレジスタにデータを書き込む補助関数
void i2c_write_reg(unsigned char slave_addr, unsigned char reg_addr, unsigned char data) {
i2c_start();
i2c_write_byte(slave_addr << 1); // スレーブアドレス+Writeビット(0)
i2c_write_byte(reg_addr); // 操作したいレジスタ番号
i2c_write_byte(data); // 設定データ
i2c_stop();
}

// バックライトを単独で光らせる関数
// r, g, b には 0(消灯) 〜 255(最大輝度) を指定します。
void set_backlight_rgb(unsigned char r, unsigned char g, unsigned char b) {
// 1. バックライトICの初期化(スレーブアドレス: 0x62)
// MODE1(レジスタ0x00) と MODE2(レジスタ0x01) を通常動作モードに設定
i2c_write_reg(0x62, 0x00, 0x00); // MODE1 を 0x00 に
i2c_write_reg(0x62, 0x01, 0x00); // MODE2 を 0x00 に

// 2. LEDの出力状態を設定(レジスタ0x08)
// 各LEDピンを「PWMによる個別輝度制御モード」に割り当てます
i2c_write_reg(0x62, 0x08, 0xAA); // LEDOUT を 0xAA に

// 3. 各色の輝度を設定(各色専用のPWMレジスタ)
// ※Grove LCDの仕様上、レジスタ2=青, 3=緑, 4=赤 に割り当てられています
i2c_write_reg(0x62, 0x04, r); // レジスタ0x04 = RED
i2c_write_reg(0x62, 0x03, g); // レジスタ0x03 = GREEN
i2c_write_reg(0x62, 0x02, b); // レジスタ0x02 = BLUE
}

// 液晶専用のミリ秒単位の長いウェイト関数
void delay_ms(int ms) {
int i, j; // volatileを削除
for(i = 0; i < ms; i++) {
for(j = 0; j < 80; j++); // 環境に合わせて1ミリ秒になるよう調整してください
}
}
// 液晶(0x3E)に「コマンド」を1バイト送る補助関数
void lcd_command(unsigned char cmd) {
i2c_start();
i2c_write_byte(0x3E << 1); // スレーブアドレス+Write(0) = 0x7C
i2c_write_byte(0x00); // コントロールバイト(0x00 = 次のバイトはコマンド)
i2c_write_byte(cmd); // コマンド本体
i2c_stop();
delay_ms(2); // 液晶の処理待ち(基本2ms空ければ安全です)
}
// 液晶文字側(0x3E)の初期化関数
void init_lcd_display() {
// 1. 電源立ち上がり直後の安定待ち
delay_ms(2);

// 2. ファンクションセット(基本設定)
// 0x38 = 8ビットモード, 2行表示, 5x8ドットフォント
lcd_command(0x38);
delay_ms(5); // 少し長めに待つ

// 3. ディスプレイON/OFF制御
// 0x0C = ディスプレイON, カーソルOFF, カーソル点滅OFF
// ※このコマンドが成功すると、薄い四角いブロック(背景)が消えます
lcd_command(0x0C);

// 4. 画面クリア
// 0x01 = ディスプレイ表示クリア(画面を真っ白にする)
lcd_command(0x01);
delay_ms(8); // クリア処理は時間がかかるため長めに待つ

// 5. エントリーモードセット
// 0x06 = 文字を書いた後、カーソルを自動で右に移動(画面スライドなし)
lcd_command(0x06);
}
// 液晶(0x3E)に文字を1文字表示する関数
void lcd_putchar(char ascii_code) {
i2c_start();
i2c_write_byte(0x3E << 1); // スレーブアドレス(0x7C)
i2c_write_byte(0x40); // コントロールバイト(0x40 = 次のバイトは文字データ)
i2c_write_byte(ascii_code); // 表示したい文字のASCIIコード
i2c_stop();
i2c_wait(5); // 液晶の書き込み待ち
}

// 連続して文字列を表示する関数
void lcd_print(char *str) {
while(*str) {
lcd_putchar(*str++);
}
}

main()
{
int rtn;
FILE* fp;
// 文字列モード:/の後は行末または/まで文字とみなす(1)//は/ 0は16進2桁やStart(S)/Stop(E)
int smode;
// HEX文字1文字目(1)
int hmode;
int i;
char instr[256];
char *r; // fgets用
char c; // 1文字ワーク
unsigned char w,hex; // ワーク、HEX1バイトワーク

// 11ピンをパラレルでオープンする
fp = fOpen("pio","a+"); //←タグの関係でoが全角大文字だが半角小文字にする

// バックライトを「白色(最大輝度)」で単独点灯させる
set_backlight_rgb(255, 255, 255);

// 液晶文字側(0x3E)の初期化関数
init_lcd_display();

// 液晶(0x3E)に文字を1文字表示する関数
lcd_putchar((char)'A');

while(1)
{
// 入力待ち
printf(">");
r = fgets(instr,sizeof(instr),stdin);

if(*r==0) exit(1); // エラー終了
if(instr[0]==0x0A) exit(1); // Enterのみでループ終了

// 文字列判定
i=0;
smode = 0; // /以降全てstrとする(1)
hmode = 0; // 数字2文字(2文字必須)でHEX(上位4ビット)を表す1文字目
hex = 0; // 1文字目の値
while(i<strlen(instr)-1) // 0A(改行)の前までループ
{
c = instr[i];
//printf("i=%02d:%02X:%02d\n",i,c,strlen(instr)+1);

if(smode == 1)
{
if(c=='/')
{
// "//"以外の場合
if(instr[i-1] != '/')
{
// /…/でsmode 解除(例/ABC/の、後の/)
smode = 0;
hmode = 0;
hex = 0;
i++;
continue;
}
// 文字として/を送りたい場合//と書く
}
rtn=i2c_write_byte(c);
if(rtn==1) exit(1); // NAK or Err

hmode = 0;
hex = 0;
i++;
continue;
}

// smode == 0
if(c=='S')
{
i2c_start();
i++;
}
else if(c=='E')
{
i2c_stop();
i++;
}
else if(c=='/')
{
smode = 1;
i++;
}
else
{
w=c-(0x30*(c<'A'))-(0x37*(c>'9'));
if((w<0)+(w>15)==0)
{
// 0-9,A-F
hex=hex*16+w;

if(hmode == 1)
{
rtn=i2c_write_byte(hex);
if(rtn==1) exit(1); // NAK or Err

hmode = 0;
hex = 0;
i++;
}
else
{
hmode = 1;
i++;
}
}
else
{
// 無視してhmodeもリセット
hmode = 0;
hex = 0;
i++;
}
} // else
} // while
} // while(1)

// 終了4ピン(SDA)、5ピン(SCL)を入力にし、プルアップ抵抗の力でHiに解放する
pioset(3);

fclose(fp); // 忘れずにcloseする
}





PC-G850Vで見易い様にしたソースはこちら:

1010 int i2c_wait(int c) {
1020 int a,i;
1030 a=0;
1040 for(i = 0; i < c; i++) a+=i;
1050 return a;
1060 }
1070 void i2c_start() {
1080 int rtn;
1090 pioset(0x03);
1100 rtn=i2c_wait(5);
1110 pioset(0x02);
1120 rtn=i2c_wait(5);
1130 pioput(0x00);
1140 rtn=i2c_wait(5);
1150 pioset(0x00);
1160 rtn=i2c_wait(5);
1170 pioput(0x00);
1180 rtn=i2c_wait(5);
1190 }
1200 int i2c_write_byte(unsigned char data) {
1210 int i,w;
1220 int ack_bit;
1230 int rtn;
1240 unsigned char bit_val;
1250 for(i = 0; i < 8; i++) {
1260 if((data & 0x80))
1270 bit_val = 0x01;
1280 else
1290 bit_val = 0;
1300 data <<= 1;
1310 pioput(bit_val);
1320 rtn=i2c_wait(5);
1330 pioput(bit_val | 0x02);
1340 rtn=i2c_wait(5);
1350 pioput(bit_val);
1360 rtn=i2c_wait(5);
1370 }
1380 pioset(0x02);
1390 rtn=i2c_wait(5);
1400 pioput(0x02);
1410 rtn=i2c_wait(5);
1420 w = pioget();
1430 if ((w & 0x01) == 0) {
1440 ack_bit = 0;
1450 } else {
1460 ack_bit = 1;
1470 }
1480 pioput(0x00);
1490 rtn=i2c_wait(5);
1500 pioset(0x00);
1510 rtn=i2c_wait(5);
1520 return ack_bit;
1530 }
1540 void i2c_stop() {
1550 int rtn;
1560 pioset(0x00);
1570 rtn=i2c_wait(5);
1580 pioput(0x00);
1590 rtn=i2c_wait(5);
1600 pioset(0x02);
1610 rtn=i2c_wait(5);
1620 pioset(0x03);
1630 rtn=i2c_wait(5);
1640 }
1650 void i2c_write_reg(unsigned char slave_addr, unsigned char reg_addr, unsigned char data) {
1660 i2c_start();
1670 i2c_write_byte(slave_addr << 1);
1680 i2c_write_byte(reg_addr);
1690 i2c_write_byte(data);
1700 i2c_stop();
1710 }
1720 void set_backlight_rgb(unsigned char r, unsigned char g, unsigned char b) {
1730 i2c_write_reg(0x62, 0x00, 0x00);
1740 i2c_write_reg(0x62, 0x01, 0x00);
1750 i2c_write_reg(0x62, 0x08, 0xAA);
1760 i2c_write_reg(0x62, 0x04, r);
1770 i2c_write_reg(0x62, 0x03, g);
1780 i2c_write_reg(0x62, 0x02, b);
1790 }
1800 void delay_ms(int ms) {
1810 int i, j;
1820 for(i = 0; i < ms; i++) {
1830 for(j = 0; j < 80; j++);
1840 }
1850 }
1860 void lcd_command(unsigned char cmd) {
1870 i2c_start();
1880 i2c_write_byte(0x3E << 1);
1890 i2c_write_byte(0x00);
1900 i2c_write_byte(cmd);
1910 i2c_stop();
1920 delay_ms(2);
1930 }
1940 void init_lcd_display() {
1950 delay_ms(2);
1960 lcd_command(0x38);
1970 delay_ms(5);
1980 lcd_command(0x0C);
1990 lcd_command(0x01);
2000 delay_ms(8);
2010 lcd_command(0x06);
2020 }
2030 void lcd_putchar(char ascii_code) {
2040 i2c_start();
2050 i2c_write_byte(0x3E << 1);
2060 i2c_write_byte(0x40);
2070 i2c_write_byte(ascii_code);
2080 i2c_stop();
2090 i2c_wait(5);
2100 }
2110 void lcd_print(char *str) {
2120 while(*str) {
2130 lcd_putchar(*str++);
2140 }
2150 }
2160 main()
2170 {
2180 int rtn;
2190 FILE* fp;
2200 int smode;
2210 int hmode;
2220 int i;
2230 char instr[256];
2240 char *r;
2250 char c;
2260 unsigned char w,hex;
2270 fp = fOpen("pio","a+"); //←タグの関係でoが全角大文字だが半角小文字にする
2280 set_backlight_rgb(255, 255, 255);
2290 init_lcd_display();
2300 lcd_putchar((char)'A');
2310 while(1)
2320 {
2330 printf(">");
2340 r = fgets(instr,sizeof(instr),stdin);
2350 if(*r==0) exit(1);
2360 if(instr[0]==0x0A) exit(1);
2370 i=0;
2380 smode = 0;
2390 hmode = 0;
2400 hex = 0;
2410 while(i<strlen(instr)-1)
2420 {
2430 c = instr[i];
2440 if(smode == 1)
2450 {
2460 if(c=='/')
2470 {
2480 if(instr[i-1] != '/')
2490 {
2500 smode = 0;
2510 hmode = 0;
2520 hex = 0;
2530 i++;
2540 continue;
2550 }
2560 }
2570 rtn=i2c_write_byte(c);
2580 if(rtn==1) exit(1);
2590 hmode = 0;
2600 hex = 0;
2610 i++;
2620 continue;
2630 }
2640 if(c=='S')
2650 {
2660 i2c_start();
2670 i++;
2680 }
2690 else if(c=='E')
2700 {
2710 i2c_stop();
2720 i++;
2730 }
2740 else if(c=='/')
2750 {
2760 smode = 1;
2770 i++;
2780 }
2790 else
2800 {
2810 w=c-(0x30*(c<'A'))-(0x37*(c>'9'));
2820 if((w<0)+(w>15)==0)
2830 {
2840 hex=hex*16+w;
2850 if(hmode == 1)
2860 {
2870 rtn=i2c_write_byte(hex);
2880 if(rtn==1) exit(1);
2890 hmode = 0;
2900 hex = 0;
2910 i++;
2920 }
2930 else
2940 {
2950 hmode = 1;
2960 i++;
2970 }
2980 }
2990 else
3000 {
3010 hmode = 0;
3020 hex = 0;
3030 i++;
3040 }
3050 }
3060 }
3070 }
3080 pioset(3);
3090 fclose(fp);
3100 }



コマンド入力機能の使い方:

実行すると、RGB液晶とAが表示された(時々失敗するが)後、ポケコン側に入力プロンプト(>)が表示され、入力待ちになる。

>S7C40/B⏎

とすると、Aの後ろにBが表示される(時々失敗する)。
AB

>E
でストップする(はず)。

意味:
Sはスタートで、Eがストップ。7Cが2桁必須の16進数(英字は大文字)で、7Cは液晶のスレーブアドレスを1ビット左シフトして0とORしたもの。
40は液晶独自のコントロールバイトで40が以降データ送信を示し、続けて2桁16進数で送信データを決める。/は行末まで/以外なら文字をASCIIコードに置き換えてデータ送信する。

/ABC/で文字列、/文字列(行末)でも良い。//で/を文字データとして指定可能。
またエンターキーのみでプログラム終了。fgetsは文字列の最後に改行(0A)を付けるので、(00)と合わせて除くと最大254文字入力可能。

EはなくてもSでリセットになるので、SとEを2行に分けずとも、毎回S開始ならそれでもよい。

>S7C40/CDEF⏎

ABCDEF

でも良いという事。

(Eが文字列として含まれている点に注意)

>S7C40/G/ES7C40/H/E

ABCDEFGH

マルチステートメントっぽく。GとHを2回に分けて1行で送信。

>S7C40//

ABCDEFGH/

※ これでも時々失敗する事から、
コマンド間のウエイトではなく、pio系関数の連続した部分にもっとウエイトを入れなければならないか、
または回路にシュミットトリガーかパスコンを入れなければならない、はず。

P.S.1
(2026/6/24追加)
まだ液晶クリア後の文字表示に失敗、および文字データ連続表示で失敗するので、液晶クリアのウエイト時間と連続文字表示時のウエイトに少し増加が必要なのかも。
ひょっとすると、ウエイトよりもその前段階で何か必要(特に文字データは本来最後のデータのみコントロールバイトが0であるとデータシートに書いてあるので)。
(おわり)

P.S.
AIは正確に指定しなければ間違うし、正確に知っていない場合には、ある程度のアドバイスとして受け取れるから、新しい未知の領域の勉強には好都合だ。
間違っている範囲が少なければ、自分で学習・調査する意欲も沸くし、対象範囲も小さくて十分だ。

結局、一発で正解を求めたいとか、全く知らないのに完璧な回答が欲しいとか、そのような無茶な要求をしなければ、
AIは新しい事を学ぶのにとても良いティーチャーとなる。

◎ FIREや定年退職して時間を持て余す人が、ちょっとした興味がある事を深耕したい時にぴったりかも。


# by k1segawa | 2026-06-22 03:32 | ポケコン | Comments(0)

(2026/6/17追記)
ウエイト時間が多いので修正した。動画は長い待ち時間のまま。
(おわり)

前の記事まで、I2CやGoogle Sheetに書いて解析してたけど、結局動かなかった。
で、Geminiに聞いてみた。
あっさり動いた。

ウエイト修正ソース:
// 保持時間用のウェイト関数(長めにとっています)
int i2c_wait(int c) {
int a,i; // コンパイラ最適化防止のvolatileがないのでa+=i;returnで代用
a=0;

for(i = 0; i < c; i++) a+=i;

return a;
}

// I2C スタート条件を出力する関数
void i2c_start() {
int rtn;

// 1. 初期状態:両方のピンを入力に設定し、プルアップ抵抗で確実に「Hi」にする
pioset(0x03); // bit0(SDA)=1, bit1(SCL)=1 を入力に
rtn=i2c_wait(5);

// 2. 先に「出力」に切り替えてから、SDA(4ピン)を「Lo」に落とす
// SCLは入力(Hi)を維持したまま、SDAだけが「Hi → Lo」になります(スタート条件)
pioset(0x02); // bit0(SDA)=0(出力), bit1(SCL)=1(入力のままHi)
pioput(0x00); // bit0(SDA)=0(Loに落とす)
rtn=i2c_wait(5);

// 3. 次にSCL(5ピン)も「出力」に切り替えて「Lo」に落とす
// これで両方のピンがLoに固定され、データ送信の準備が整います
pioset(0x00); // bit1(SCL)も0(出力)にする
pioput(0x00); // bit1(SCL)=0(Loに落とす)
rtn=i2c_wait(5);
}
// 1バイトデータを送信し、液晶からのACK(0=成功, 1=失敗)を返す関数
// ※事前のスタート条件により、SCL=Lo, SDA=Lo (両方出力) から始まる前提です
int i2c_write_byte(unsigned char data) {
int i,w;
int ack_bit;
int rtn;
unsigned char bit_val;

// --- 1〜8ビット目のデータ送信ループ ---
for(i = 0; i < 8; i++) {
// MSBファースト(最上位ビットから順に)データを取り出す
// 送るビットが1ならHi(0x01)、0ならLo(0x00)
if((data & 0x80))
bit_val = 0x01;
else
bit_val = 0;
// bit_val = (data & 0x80) ? 0x01 : 0x00;→三項演算子がないので
data <<= 1; // 次のビットのために左シフト

// SCL=Loの状態で、SDAの出力を変更する
pioput(bit_val);
rtn=i2c_wait(5);

// SCLをHiにして液晶にデータを読み込ませる
// (SCLを1にするために、入力(開放)ではなく、出力のままHiにするのが確実です)
// ※bit1(SCL)を1にするため、SDAの状態(bit0)と合わせる
pioput(bit_val | 0x02);
rtn=i2c_wait(5);

// SCLをLoに戻す
pioput(bit_val);
rtn=i2c_wait(5);
}

// --- 9ビット目:液晶からのACK(応答)を確認する処理 ---
// 1. まずSDA(4ピン/bit0)を入力モードに切り替えて、液晶が自由にSDAをLoにできるようにする
// SCL(5ピン/bit1)は出力モード(0)のまま維持します
pioset(0x02); // bit0=1(入力), bit1=0(出力)
rtn=i2c_wait(5);

// 2. クロック(SCL)をHiにする
pioput(0x02); // bit1(SCL)=1
rtn=i2c_wait(5);

// 3. この「SCLがHi」のタイミングで、液晶がSDAをLoに引き下げているかをpiogetで確認する
// bit0(SDA)が0(Lo)なら液晶が正常にデータを受け取った合図(ACK)です
w = pioget();
if ((w & 0x01) == 0) {
ack_bit = 0; // ACK成功(正常)
} else {
ack_bit = 1; // NACK失敗
}

// 4. クロック(SCL)をLoに戻す
pioput(0x00); // bit1(SCL)=0
rtn=i2c_wait(5);

// 5. 次の通信に備えて、SDA(4ピン)を再び出力モード(0)に戻しておく
pioset(0x00); // 両方出力モードへ
rtn=i2c_wait(5);

return ack_bit; // 0なら液晶が正しく認識しています
}
// I2C ストップ条件を出力する関数
void i2c_stop() {
int rtn;
// 1. 最初は両方「Lo(出力)」の状態で、ピンが確実にLoであることを確認する
pioset(0x00); // 両方出力モード
pioput(0x00); // 両方Lo
rtn=i2c_wait(5);

// 2. まずSCL(5ピン)だけを「入力」に切り替えて、プルアップ抵抗の力で「Hi」にする
// SDAはLo(出力)を維持したまま、SCLだけが先に「Hi」になります
pioset(0x02);/* 0x01->0x02 */ // bit0(SDA)=0(出力のまま), bit1(SCL)=1(入力にしてHiへ)
rtn=i2c_wait(5);

// 3. 最後にSDA(4ピン)も「入力」に切り替えて、プルアップ抵抗の力で「Hi」にする
// 「SCLがHi」の状態で、SDAが「Lo → Hi」へ立ち上がります(ストップ条件成立)
pioset(0x03); // bit0(SDA)=1(入力にしてHiへ), bit1(SCL)=1(入力のまま)
rtn=i2c_wait(5);
}
// 1つのレジスタにデータを書き込む補助関数
void i2c_write_reg(unsigned char slave_addr, unsigned char reg_addr, unsigned char data) {
i2c_start();
i2c_write_byte(slave_addr << 1); // スレーブアドレス+Writeビット(0)
i2c_write_byte(reg_addr); // 操作したいレジスタ番号
i2c_write_byte(data); // 設定データ
i2c_stop();
}

// バックライトを単独で光らせる関数
// r, g, b には 0(消灯) 〜 255(最大輝度) を指定します。
void set_backlight_rgb(unsigned char r, unsigned char g, unsigned char b) {
// 1. バックライトICの初期化(スレーブアドレス: 0x62)
// MODE1(レジスタ0x00) と MODE2(レジスタ0x01) を通常動作モードに設定
i2c_write_reg(0x62, 0x00, 0x00); // MODE1 を 0x00 に
i2c_write_reg(0x62, 0x01, 0x00); // MODE2 を 0x00 に

// 2. LEDの出力状態を設定(レジスタ0x08)
// 各LEDピンを「PWMによる個別輝度制御モード」に割り当てます
i2c_write_reg(0x62, 0x08, 0xAA); // LEDOUT を 0xAA に

// 3. 各色の輝度を設定(各色専用のPWMレジスタ)
// ※Grove LCDの仕様上、レジスタ2=青, 3=緑, 4=赤 に割り当てられています
i2c_write_reg(0x62, 0x04, r); // レジスタ0x04 = RED
i2c_write_reg(0x62, 0x03, g); // レジスタ0x03 = GREEN
i2c_write_reg(0x62, 0x02, b); // レジスタ0x02 = BLUE
}

// 液晶専用のミリ秒単位の長いウェイト関数
void delay_ms(int ms) {
int i, j; // volatileを削除
for(i = 0; i < ms; i++) {
for(j = 0; j < 80; j++); // 環境に合わせて1ミリ秒になるよう調整してください
}
}
// 液晶(0x3E)に「コマンド」を1バイト送る補助関数
void lcd_command(unsigned char cmd) {
i2c_start();
i2c_write_byte(0x3E << 1); // スレーブアドレス+Write(0) = 0x7C
i2c_write_byte(0x00); // コントロールバイト(0x00 = 次のバイトはコマンド)
i2c_write_byte(cmd); // コマンド本体
i2c_stop();
delay_ms(5); // 液晶の処理待ち(基本2ms空ければ安全です)
}
// 液晶文字側(0x3E)の初期化関数
void init_lcd_display() {
// 1. 電源立ち上がり直後の安定待ち
delay_ms(2);

// 2. ファンクションセット(基本設定)
// 0x38 = 8ビットモード, 2行表示, 5x8ドットフォント
lcd_command(0x38);
delay_ms(5); // 少し長めに待つ

// 3. ディスプレイON/OFF制御
// 0x0C = ディスプレイON, カーソルOFF, カーソル点滅OFF
// ※このコマンドが成功すると、薄い四角いブロック(背景)が消えます
lcd_command(0x0C);

// 4. 画面クリア
// 0x01 = ディスプレイ表示クリア(画面を真っ白にする)
lcd_command(0x01);
delay_ms(5); // クリア処理は時間がかかるため長めに待つ

// 5. エントリーモードセット
// 0x06 = 文字を書いた後、カーソルを自動で右に移動(画面スライドなし)
lcd_command(0x06);
}
// 液晶(0x3E)に文字を1文字表示する関数
void lcd_putchar(char ascii_code) {
i2c_start();
i2c_write_byte(0x3E << 1); // スレーブアドレス(0x7C)
i2c_write_byte(0x40); // コントロールバイト(0x40 = 次のバイトは文字データ)
i2c_write_byte(ascii_code); // 表示したい文字のASCIIコード
i2c_stop();
i2c_wait(5); // 液晶の書き込み待ち
}

// 連続して文字列を表示する関数
void lcd_print(char *str) {
while(*str) {
lcd_putchar(*str++);
}
}

main()
{
FILE* fp;

// 11ピンをパラレルでオープンする
fp = fOpen("pio","a+");→(ここはタグの関係でoが全角大文字→半角小文字にする)

// バックライトを「白色(最大輝度)」で単独点灯させる
set_backlight_rgb(255, 255, 255);

// 液晶文字側(0x3E)の初期化関数
init_lcd_display();

// 液晶(0x3E)に文字を1文字表示する関数
lcd_putchar((char)'A');

// 4ピン(SDA)、5ピン(SCL)を入力にし、プルアップ抵抗の力でHiに解放する
pioset(3);

fclose(fp); // 忘れずにcloseする
}

PC-G850VのCで見やすい様、コメント消去とタブ=1にしたもの(ウエイト修正済み):
1010 int i2c_wait(int c) {
1020 int a,i;
1030 a=0;
1040 for(i = 0; i < c; i++) a+=i;
1050 return a;
1060 }
1070 void i2c_start() {
1080 int rtn;
1090 pioset(0x03);
1100 rtn=i2c_wait(5);
1110 pioset(0x02);
1120 pioput(0x00);
1130 rtn=i2c_wait(5);
1140 pioset(0x00);
1150 pioput(0x00);
1160 rtn=i2c_wait(5);
1170 }
1180 int i2c_write_byte(unsigned char data) {
1190 int i,w;
1200 int ack_bit;
1210 int rtn;
1220 unsigned char bit_val;
1230 for(i = 0; i < 8; i++) {
1240 if((data & 0x80))
1250 bit_val = 0x01;
1260 else
1270 bit_val = 0;
1280 data <<= 1;
1290 pioput(bit_val);
1300 rtn=i2c_wait(5);
1310 pioput(bit_val | 0x02);
1320 rtn=i2c_wait(5);
1330 pioput(bit_val);
1340 rtn=i2c_wait(5);
1350 }
1360 pioset(0x02);
1370 rtn=i2c_wait(5);
1380 pioput(0x02);
1390 rtn=i2c_wait(5);
1400 w = pioget();
1410 if ((w & 0x01) == 0) {
1420 ack_bit = 0;
1430 } else {
1440 ack_bit = 1;
1450 }
1460 pioput(0x00);
1470 rtn=i2c_wait(5);
1480 pioset(0x00);
1490 rtn=i2c_wait(5);
1500 return ack_bit;
1510 }
1520 void i2c_stop() {
1530 int rtn;
1540 pioset(0x00);
1550 pioput(0x00);
1560 rtn=i2c_wait(5);
1570 pioset(0x02);
1580 rtn=i2c_wait(5);
1590 pioset(0x03);
1600 rtn=i2c_wait(5);
1610 }
1620 void i2c_write_reg(unsigned char slave_addr, unsigned char reg_addr, unsigned char data) {
1630 i2c_start();
1640 i2c_write_byte(slave_addr << 1);
1650 i2c_write_byte(reg_addr);
1660 i2c_write_byte(data);
1670 i2c_stop();
1680 }
1690 void set_backlight_rgb(unsigned char r, unsigned char g, unsigned char b) {
1700 i2c_write_reg(0x62, 0x00, 0x00);
1710 i2c_write_reg(0x62, 0x01, 0x00);
1720 i2c_write_reg(0x62, 0x08, 0xAA);
1730 i2c_write_reg(0x62, 0x04, r);
1740 i2c_write_reg(0x62, 0x03, g);
1750 i2c_write_reg(0x62, 0x02, b);
1760 }
1770 void delay_ms(int ms) {
1780 int i, j;
1790 for(i = 0; i < ms; i++) {
1800 for(j = 0; j < 80; j++);
1810 }
1820 }
1830 void lcd_command(unsigned char cmd) {
1840 i2c_start();
1850 i2c_write_byte(0x3E << 1);
1860 i2c_write_byte(0x00);
1870 i2c_write_byte(cmd);
1880 i2c_stop();
1890 delay_ms(5);
1900 }
1910 void init_lcd_display() {
1920 delay_ms(2);
1930 lcd_command(0x38);
1940 delay_ms(5);
1950 lcd_command(0x0C);
1960 lcd_command(0x01);
1970 delay_ms(5);
1980 lcd_command(0x06);
1990 }
2000 void lcd_putchar(char ascii_code) {
2010 i2c_start();
2020 i2c_write_byte(0x3E << 1);
2030 i2c_write_byte(0x40);
2040 i2c_write_byte(ascii_code);
2050 i2c_stop();
2060 i2c_wait(5);
2070 }
2080 void lcd_print(char *str) {
2090 while(*str) {
2100 lcd_putchar(*str++);
2110 }
2120 }
2130 main()
2140 {
2150 FILE* fp;
2160 fp = fOpen("pio","a+");→(ここはタグの関係でoが全角大文字→半角小文字にする)
2170 set_backlight_rgb(255, 255, 255);
2180 init_lcd_display();
2190 lcd_putchar((char)'A');
2200 pioset(3);
2210 fclose(fp);
2220 }

動作環境の様子:
[PC-G850V] ポケコンでI2C通信 実機動作 + Cソース (6/16)_a0034780_04234148.png

ズームアップ:
[PC-G850V] ポケコンでI2C通信 実機動作 + Cソース (6/16)_a0034780_04234772.png
動画:
[PC-G850V] ポケコンでI2C通信 実機動作 + Cソース (6/16)_a0034780_04482745.png

前はスレーブアドレスのACKエラーで、文字背景の黒をクリアさえ出来なかった。

動画はちょっとウエイト時間が長かったかな。

前記事と同じだが回路図も。
[PC-G850V] ポケコンでI2C通信 実機動作 + Cソース (6/16)_a0034780_03010363.png
開発環境は、
USB変換ケーブルを作り(買ってつなぐ)、Teraterm(最後^Z)やPC-Linkなどでファイル送信。
TEXTで、SioのFormatで設定(9600,8,1,none,CR LF,1A,yes,RS/CS)し、Loadで読込んで、
2ndF+TEXTでCompilerのCキーでコンパイル、GoのGキーで実行。
(毎回TEXTで、DeleteでYを押して削除)

デバッグ:
g800のROM載せで、コンパイルチェック、Trace

ユーザ領域:
*USER
FREE:0100-1FFF

液晶:
Grove-LCD RGB Backlight V2.0

# by k1segawa | 2026-06-16 04:15 | ポケコン | Comments(0)