2020年7月11日土曜日

複数のOLED(SH1106 128x64 I2C & SPI)をNANOで制御

OLEDシリーズ、第5弾だと思うのですが(-_-;)
やっぱ表示モノは面白いです。こんなに嵌るとは思いませんでした^^;

ちょっと思いつきで、1個のArduinoで複数のOLEDを制御してみました。

まずは、[スケッチの例]のリストの下の方のスケッチ例の
[sh1106_128x64_i2c]を開いて

シリアルを複数のやる時は、
mySerial.begin(9600);
とかで名前を変えられてたので
たぶん、同じ様にいけるんじゃないかな?
一番怪しいのは、この32行目
*********
display(OLED_RESET);

display_01(OLED_RESET);
*********
に変えてみます。

で、スケッチ全体の
「display.」⇒「display_01.」に

こんな風に置換して

いざ、コンパイル!

お~っ!通りました!

動くかな~
書き込んでみると~
動きますね~\(^o^)/

上手くいったので

[スケッチの例]のリストの下の方の
[sh1106_128x64_spi]を開きます。

SPIは、ピン数が多い分、引数も多いです。

実は、最近、SPI I/FのOLEDが届いたのです。
ドライバは、SH1106の128x64です。

スケッチと順番が異なってて配線を間違えそうなので
シルク表示と同じ順番になるように書き換えて、PINもPD8~PD12にします。
SCK:OLED_SCK
SDA:OLED_MOSI
RES:OLED_RESET
DC :OLED_DC
CS :OLED_CS

スケッチのここを書き換えるだけです。

配線して書き込むと、無地動作しました。
BLUEのOLEDで、目視では、真っ青ですが、写真ではかなり白っぽいです。

そのSPI用のExample[[sh1106_128x64_spi]の
フラッシュメモリ、グローバル変数(RAM)の使用量です。

I2C用のExample[[sh1106_128x64_i2c]も
フラッシュメモリ、グローバル変数(RAM)の使用量は全く同じです。
このまま、SPI用とI2C用を合体すると
使用量オーバーは確実のようです。

では、I2CのExampleスケッチから
ロゴ、円、TEXTなどを取り去って、LINEアートだけにして
コンパイル!
ん~ん、フラッシュメモリの使用量はかなり減ったけど
グローバル変数使用量が思ったより減ってないですね~(T_T)

まあ、やってみることにします。
LINEアートだけにしたI2C用のスケッチに
SPI用を追加していきます。

SPI.h:SPI用、Wire.h:I2C用 です。

1つ目のOLEDは、I2Cタイプで、「display_01」にします。

2つ目のOLEDは、SPIタイプで、「display_02」にします。

void setup() は、これです。

最初からsetup()までのスケッチは、これです。
*********
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>

#define OLED_01_RESET 4
Adafruit_SH1106 display_01(OLED_01_RESET);

#define OLED_02_CLK    8
#define OLED_02_MOSI   9
#define OLED_02_RESET 10
#define OLED_02_DC    11
#define OLED_02_CS    12
Adafruit_SH1106 display_02(OLED_02_MOSI, OLED_02_CLK, OLED_02_DC, OLED_02_RESET, OLED_02_CS);

void setup()   {
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display_01.begin(SH1106_SWITCHCAPVCC, 0x3C);  // initialize for OLED_01 I2C
  display_02.begin(SH1106_SWITCHCAPVCC);  // initialize for OLED_02 SPI
}
*********

void loop() 内は、exampleのスケッチの一部を単純に
display_01 と display_02 に同じものを交互に描画するだけです。

まずは、コンパイルだけ
おっ!グローバル変数は、まだ余裕があります\(^o^)/

書き込んでみると~
お~~っ!意外やあっけなく動きました\(^o^)/
今回はArduino NANOにしております。
コンパクトにOLEDメーターができそうです。

ちなみに、その後、わかったのですが
SPI.h:SPI用、Wire.h:I2C用 がなくても動きました。
OLED制御分までAdafruitライブラリに含まれてるんですね。
まあ、メモリ使用量は変わらないので、お守りに入れておいてもいいでしょう(-_-;)

所が~~~
display_01には、ラインアートだけ
display_02には、TEXTだけを表示させようとしたら、
後で思うに、何でこんな行に追加したんだろう(-_-;)
display_01にライン1本描画する毎に
display_02にTEXTを出したかった気もするが・・・(-_-;)
*********
void loop() {

//* for文の後に置いても、No.1にも表示される
  display_02.setTextSize(1); 
  display_02.setTextColor(WHITE);
  display_02.setCursor(80, 1);
  
  display_01.clearDisplay();
  display_02.clearDisplay(); 

  for (int16_t i=0; i<display_01.width(); i+=4) { //・・・A
    display_01.drawLine(0, 0, i, display_01.height()-1, WHITE);
    display_02.print("No.2 SPI"); 
    display_01.display();
    display_02.display(); 
  }

  for (int16_t i=0; i<display_01.height(); i+=4) {//・・・B
    display_01.drawLine(0, 0, display_01.width()-1, i, WHITE);
    display_01.display();
  }
  delay(250);
}
*********

display_01:左、、display_02:右 ですが
左にもTEXT「No.2 SPI」が描画されて、
右には、上のスケッチ「・・・A」のforルーチンのラインが描画されるのです(T_T)
「・・・B」のforルーチンのラインは左だけに描画されます。

そこでTEXT表示ルーチンを「・・・A」のforルーチンの外に出し後に置くと
*********
void loop() {

  display_01.clearDisplay();

  for (int16_t i=0; i<display_01.width(); i+=4) { //・・・A
    display_01.drawLine(0, 0, i, display_01.height()-1, WHITE);
    display_01.display();
  }

  display_02.setTextSize(1); //★ FONT Size x1
  display_02.setTextColor(WHITE); //★
  display_02.setCursor(80, 1); //★

  display_02.clearDisplay();
  display_02.print("No.2 SPI"); //★・・・どの場所においてもNo.1にもTEXTが表示される
  display_02.display(); //★

  for (int16_t i=0; i<display_01.height(); i+=4) { //・・・B
    display_01.drawLine(0, 0, display_01.width()-1, i, WHITE);
    display_01.display();
  }
  delay(250);
}
*********

ラインアートのスケッチ「・・・A」部は、
右:display_02には描画されなくなりました。

が、右:display_02 だけのTEXT「No.2 SPI」描画のはずが
左:display_01にも「No.2 SPI」が描画されるのです(T_T)
ラインアートのスケッチ「・・・B」部は、右:display_02には描画されません。
もしかして「print()」命令は、複数対応できないのかな~(T_T)

ここまで来ると何とかしたいですね~
気分転換してもうひと頑張りします^^;
・・・そうだ!左のdisplay_01にもTEXTを描画してみよう
*********
void loop() {

  display_01.clearDisplay();
  display_01.setTextSize(1);
  display_01.setTextColor(WHITE);
  display_01.setCursor(80, 30);
  display_01.print("No.1 I2C");
  display_01.display();

  for (int16_t i=0; i<display_01.width(); i+=4) {
    display_01.drawLine(0, 0, i, display_01.height()-1, WHITE);
    display_01.display();
  }

  display_02.clearDisplay();
  display_02.setTextSize(1);
  display_02.setTextColor(WHITE);
  display_02.setCursor(80, 1);
  display_02.print("No.2 SPI"); 
  display_02.display();

  for (int16_t i=30; i<64; i+=2) {
    display_02.drawLine(0, i, 127, i, WHITE);
    display_02.display();
  }
*********

上手くいきました\(^o^)/
最初からdisplay_01とdisplay_2を分ければ良かったんですね~
このスケッチ全体は、Google Driveのここ
「MultiOLED_I2C_SPI_D.ino」です。

最初に入れたTEXTの位置が悪くて、ちょっと手こずりましたが(-_-;)
本命の、1つのArduinoで2つのメーターをやりたいと思います。
まずは、この時やったVolt MeterをI2C-typeでは、
メモリ使用量は、これです。

次は、その後やったタコメーターをSPI-typeでやると、
メモリ使用量は、これです。
単純に足し算されると完全にメモリオーバーです。

上の2つを夫々、display_01、display_02にして
変数名が被らないように修正して、単純に合体します。
ぎりぎりでもいいからオーバーしないことを祈って、コンパイル!
おっ!オーバーしてないです。これはいけますね~

いざ、書き込み!・・・・・・動きました!
NANOの入力pinを指で触るとメーターが振れるので
正常に動作してます\(^o^)/

1個のArduino NANOで、2個のOLED(I2CとSPI)を制御できました。
NANOだとボードも小さいのでコンパクトに納められそうです。
上記のようなメーターであれば、3個までメモリはもちそうですね~
スケッチは、Google Driveのここ
「MultiOLED_I2C_SPI_Volt_Tacho_Meter_A.ino」です。

USBは書き込み時しか使わないので
同じATmega329P328Pチップが乗ってるProMiniの方が小さくできそうですね~
NANOの価格とほぼ同じですが、この辺りをポチっておきます^^;
US$ 1.25(21% OFF、送料 $ 0.62)



書き込み用のUSB~Serial変換器は、使い慣れたCH340Gのをポチッ!
US$ 0.82(10% OFF)

こうなると、3つやってみたくなりました^^;
I2Cは、チップ抵抗を移動してアドレス変えないといけないので
SPI 2個とI2C 1個でやろうと思います。
上の2個の時のVolt MeterとTachometerに加え
3個目にもVolt Meterを追加しました。
コンパイル!
お~っ!2個の時からフラッシュメモリ 73 ⇒ 81%と
グローバル変数 69 ⇒ 71%!思ったより増加が少ないですね~^^;

で、2個のSPI typeの配線は、
CSだけOLED毎に独立させればいいかとやったのですが、
 display_0x.begin(SH1106_SWITCHCAPVCC);
を最後にやったSPI OLEDだけ描画され、他方のSPI typeは真黒なのです。
DCも分離してみますが、ダメです(T_T)

ん~ん SPIができないはずはない、Google先生に聞いてみると
ここにSPI OLED 2個の結線図がありました。
眺めると、まさかのRESETが独立配線になってます(・o・)

で、結局、CSとRESETの2本を独立に配線にしたら
3個で動きました\(^o^)/
左 WHITE:I2C type(display_01)
右 BLUE:SPI type(display_02)
中 BLUE:SPI type(display_03)
中央のは表示だけ「A」で中身は電圧計です^^;
スケッチは、Google Driveのここ
「MultiOLED_I2C_SPIx2_Volt_Tacho_Meter_A.ino」です。

配線はこれです。
SPIのOLEDは、Fritzingパーツがないですね~
仕方ないのでGIMPでパーツ作って、パワポで作図です(T_T)

ここまできたら、調子に乗って限界まで!
4個いけそうです^^; 同じく電圧計スケッチを追加して
2 ⇒ 3 ⇒ 4個で
フラッシュメモリ 73 ⇒ 81 ⇒ 88%
グローバル変数 69 ⇒ 71 ⇒ 74%
この調子だと、5個でも96%と77%辺りと推測され、
NANOの端子もD6、D13、A0、A7空いてるので5個までいけるでしょう。
まあ、メモリ的にもI/O的にも、限界は、5個ってことですね。

反応は若干遅れ気味です。0.2~0.3秒辺りのようです。
一応、スケッチはGoogle Driveのここ
「MultiOLED_I2C_SPIx3_Volt_Tacho_Meter_A.ino」です。

えいっ!ここまできたら5個だ!
また電圧計スケッチを追加してコンパイル!
さすがに「メモリが少なく・・・」の警告がでましたが、
予想に近い使用量です。
2 ⇒ 3 ⇒ 4 ⇒ 5個で
フラッシュメモリ 73 ⇒ 81 ⇒ 88 ⇒ 95%
グローバル変数 69 ⇒ 71 ⇒ 74 ⇒ 80%
6個は無理ですね~^^;

5個並べるのも大変でしたが、圧巻ですね~
」「」「」はフェイクで、中身は全部電圧計「」と同じです^^;
さすがに応答速度が0.5secに迫る遅さです(-_-;)
もはやオブジェ化してきましたが、スケッチは同Google Drive
「MultiOLED_I2C_SPIx4_Volt_Tacho_Meter_A.ino」です。

ちょっと、loop()1周の最後にPIND命令で
オンボードのRXとTX LEDをトグルしたら
5個の全部の更新にほぼ0.43secですね~

配線図は、パスです(-_-;)
最後に、5個での反応速度を動画で!

その後、Multi OLEDを調べていると、GitHubのここ
I2Cの高速Read/Writeライブラリかな?を見つけました。

更にGitHubのこっちには、それを使って
I2Cの同じアドレスでも8台まで同時に接続できるライブラリがありました。
0x3Cと0x3Dのアドレスであれば、夫々8台で全16台のOLEDを制御できるようです。
しかも9wire・・・・8台で9本かな?


ちょっと忘備録、
実は、Exampleのラインアートの「display.width()」の意味がわからず
探してるとこの「SH1106 Class Reference」ってのが見つかりました。
adafruit_sh1106ライブラリにかなり近いようです。
更に同サイトのここに詳細なリファレンスがあります。

2020年7月4日土曜日

USB WiFi AdapterでHome NetworkのPCに繋がらない

マーティーPCは、13inchのNotePCですが、
ある日、突然、内蔵のWiFiとBluetoothが動作しなくなりました。
ドライバ入れ直しでダメなので、どうも逝ってしまわれたようなのです(T_T)

そこで、USB Adapterを仕入れました。
距離や速度は、特に気にしないのですが
一応、2.4G/5G両対応がいいかなと、これにしました。
US$ 3.58(30% OFF、送料 $ 1.18)

標準ドライバでいいと思ったら、違うようですね~

ドライバを探さないといけません
別の店にSpecがあり、「Chipset: RTL8811」 のようです。

REALTEKサイトのここ

Emailを入力しないとダウンロードできませんね~(-_-;)

Captchaと同じ文字を入力して[Go!]
こうゆの増えてきましたね~
人間かどうか判断するためですが、
未だこの文字、ロボットには読めないんだろうか?

やっとダウンロードできました。

解凍したら、Setup.exeを実行します。

途中「Cisco EAP」なんてのが出てます。
realtekは、Cisco傘下かな?

再起動します。

デバイス名は、
「Realtek 8811CU Wireless LAN 802.11ac USB NIC」
になってます。
取り敢えず、インターネットにはすんなり繋がって一安心^^;

ちなみに、後でAliExpressを散歩すると
これがFree Driverで、Windows標準Driverでいけるようです。
US$ 4.99(35% OFF、送料 $ 3.57)
別の店ですが、本体も送料も高いです。
Chipsetは、マーティーが買ったのと同じRTL8811なんですがね~(-_-;)


所が、マーティー工房のイントラネットには、
Windows10、Windows7に、WindowsXPもあるのですが、
ネットワークドライブのアイコンを叩いてもアクセスできません(T_T)
有線LANでは、アクセスできるのです。

Windows10 Home 64bitですが
前のNotePCは、ありがたい自動更新のお陰で再起不能になりました(T_T)
あまりに更新が邪魔だし、これ以上殺されると困るので٩(๑`^´๑)۶
Windows10 Update Brockerなるもので更新を殺しています。
なので、ずっと Version 1803のままです^^;

ネットワーク診断すると
名前解決ができてないようです。

名前解決となるとNetBIOSが怪しいです。
有線LANの「ネットワーク接続の詳細」では、
「NetBISO over TCP/IP」:[はい
になってますが、

USB WiFi Adapterでは、
「NetBISO over TCP/IP」:[いいえ
になってます。
原因はこれのようですね~

しからば、ここで
[NetBISO over TCP/IPを有効にする] にして

コマンドプロンプトで「ipconfig /all」して確認しますが、
「NetBISO over TCP/IP・・・・・: いいえ」のままで
切り替わらないのです(T_T)

有線LANは、これで問題ないんですがね~(T_T)

マーティーの知識はここまでなので、探しまわってみると
ここに、
タイトル「NetBIOS Over TCP/IP が有効にならない場合の対処方法」
ズバリの回答がありました!
更新日:2020年04月14日でとても新しいので期待がもてます。
単語の解説やら、とても詳しいサイトで、ありがたいことですm(_ _)m

早速、この通りにやって
マーティーの日誌にも手順を記録します。

まずは、USB WiFi AdapterのGUIDなるものを調べる必要があるとのこと。
コマンドプロンプトで
wmic nicconfig get Caption, SettingID」と入力しEnterすると、
ズラッとでるので、先のデバイスドライバに出てた名前を探して、
そこ(赤枠部)の{}内のコードを記録しておきます。
マーティーの場合{B82B9482-・・・・・・14B3}です。

レジストリを起動して

この先は、レジストリを編集します。
少しの間違いでもPCのが起動しなくなる可能性がとても高い作業です。
自己責任ということでご了承願いますm(_ _)m
まずは、もしもの場合に備えて、全体をエクスポートしておきます。

[HKEY_LOCAL_MACHINE]-[SYSTEM]-[CurrentControlSet]
-[Services]-[NetBT]-[Linkage]
を開いて
ここの[Bind][Export][Route]の3箇所にGUIDを追加していきます。

まず、[Bind]で右クリックして[修正]をクリック

このBOXが出るので、先に調べておいたUSB WiFi AdapterのGUID
マーティーの場合{B82B9482・・・・・・14B3}なので、
2行を追加(赤枠部)して[OK]します。
\Device\Tcpip_{B82B9482・・・・・・14B3}
\Device\Tcpip6_{B82B9482・・・・・・14B3}

入力したコードに空白が含まれると
この様に怒られることがあるようです。
ここは[OK]して、
再度[修正]で開いて
入力したコードをじっくり確認する必要があります。

次は[Export]で右クリックして[修正]をクリック

このBOXが出るので、先に調べておいたUSB WiFi AdapterのGUID
2行を追加(赤枠部)して[OK]します。
さっきのと{・・・}の前の文字が異なってるので要注意です。
\Device\NetBT_Tcpip_{B82B9482・・・・・・14B3}
\Device\NetBT_Tcpip6_{B82B9482・・・・・・14B3}

最後は[Route]で右クリックして[修正]をクリック

このBOXが出るので、先に調べておいたUSB WiFi AdapterのGUID
2行を追加(赤枠部)して[OK]します。
これも前の2つと{・・・}の前の文字が異なってるので要注意です。
"Tcpip6" "{B82B9482・・・・・・14B3}"
"Tcpip" "{B82B9482・・・・・・14B3}"

レジストリエディタを終了して、

一旦、再起動します。

マーティー工房のイントラネットのWindowsXPのリンクを叩くと、
めでたく開けました\(^o^)/
実は、一時諦めてOLEDにハマってたので、
1ヶ月ほど放置して有線LANで過ごしてたのです(-_-;)
また快適な無線生活が戻ってきました^^;

コマンドプロンプトから
「ipconfig /all」すると、
「NetBISO over TCP/IP・・・・・: 有効」に変わってます。

これも
「NetBISO over TCP/IP」:[はい]になりました!

しかし、
他のPCの共有フォルダ、割り当てしたネットワークドライブの
アイコンをクリックすれば、開くようになりましたが
相変わらず、エクスプローラーのネットワークに出てきません(T_T)

ここに全部チェック入れてもダメだし

[管理ツール]の[サービス]で
この7つのサービスを「自動(遅延開始)」にして[開始]してもダメ(T_T)
・Function Discovery Provider Host
・Function Discovery Resource Publication
・Network Connections
・UPnP Device Host
・Peer Name Resolution Protocol
・Peer Networking Grouping
・Peer Networking Identity Manager
(Peerの所のショット)

ショートカットを作っておくしかないですね~
それにしても、内蔵WiFiデバイスでは、問題なくて、
Windws10のVersionもBuildも変わってないのに、
USB Adapterだけ起こるのは、何故なんだろう?
ドライバっぽい気もしますが、やっぱM/Sさんが怪しい~(-_-;)
でも、Win10のUPDATEは、また不具合で時間取られるの嫌だからやりません。
Winを使わなければいいんですがね^^;