2021年12月12日日曜日
GPU
2021年9月30日木曜日
BL190HW、いい加減にしてくれ…
最近、突然宅内ネットから『外』が見えなくなる。在宅勤務中に起こるととっても困る…。
なんでなのか結構しばらく悩んでたんだけど、BL190HWを再起動すると正常になる。で、設定をざっと確認してみると、異常時IPv4 DNSサーバー欄が空欄になっている。こいつが問題。
再起動から最短数時間は問題ない一方で、こいつはログをとれないことから、外側のDHCPサーバーからアドレス更新されたから、とか、そういう確認は全くできない。何せ突然DNSサーバー欄が空白になる。
auのサービスに連絡したところで、お決まりの、『WAN側サーバーに異常ログは無い』『電源入れ直せ』『初期化しろ』、挙句には『見に行く』『交換する』というお決まりのルートになる(今回はとりあえず『初期化しろ』で踏みとどまった)。auは原因究明するつもりがあるのかどうか? そんなことを電話で言ったところで、電話受けてるコールセンターさんが困るだけでらちが開かない。
これ、うちだけなら確かに個体の問題かもしれないけど、どうやらそうではない。『BL190HW DNS 空欄』あたりで調べると、やはり他にもお困りの方がいる。
とりあえず、あんまり引っかかってほしくない一台だけ8.8.8.8を見てもらって、その他はdnscacheを立てて、そちらを参照するようdhcpを変更しようと思う…。dnscacheなんて、だいぶ長いこと使ってないや。
2021年9月9日木曜日
GY-521
春頃に使ったGY-521、amazonでまとめて5個買いだったこともありまだ残っています。ちょっと思いついたコトがあって、新しいものを開封して、試験的に動かしてみました。
前回は、あんまり深く考えずにi2cをそのままパタパタさせてたんですが、今回はその目的のライブラリを使うに際しi2cまわりも一緒に存在しているので、ライブラリ付属のコードをそのまま頂いて動かして見ようとしてたんですが、うんともすんとも言わない。
元のコードが例によってmbed2用なので、、mbed6用に書き換えたりしてはいますが、基本線は変わらないわけで、調べてみるとwhoamiで引っかかってる。デバイスの応答は、0x68じゃなくて0x98。こんな中途半端なビット化け?と思って調べて見つつ、改めてしげしげモジュール眺めてみると、デバイスにはMPU6050Aと刻印されている。ふーんと思ってinvensense/TDK調べてみるとそんなデバイスは出てない様子。
参照:https://forum.arduino.cc/t/mpu-6050-a-module-problems-who-am-i-reports-0x98-not-0x68-as-it-should-fake-mpu-6050/861956
Amazonにある写真では、MPU6050になってるんだけどね…。
春に使ったときも、whoami最初は見たような記憶があるんだけど、あんまり気にせずだったと思います。今回はこれに磁気センサを追加してAHRSとして動かすことも考えてたんですけどね…。はてさて。
2021年7月31日土曜日
Time server
半分仕事でやったことなんでここには書いてなかったんですが、これをやっていたとき、並行して、GPSから出力されるppsを使ったタイムサーバーを、NanoPi NEOを使って仕立ててました。
さすが外部のntpサーバーを見ているより高い精度の時刻が得られているようですが、何分バラックセットで運用しているので、ケーブル引っ掛けたり何だりしてしまう関係で、箱に入れることを考えつつ、ただ箱が置かれると、家族的には『なにこれ?』となることを請け合いなので、何か表示でもしておこう、というところに取りかかることにしました。
LCDつなげる
実際、ntpサーバーって地味ですよね…。ただ動いていることを示しておきたいだけなので、今まで、手元にはありつつ、Arduinoで使おうかなーと思いつつ調達したものの、眠っていたキャラクタLCDを使ってみることにしました。たしか、こちらだと思いますが、バックライト用のピン位置が標準とは違うものです。
4ビットモードで使えるだろうとはいえ、Linuxサイドからなるべく簡単にコトませたいので、アマゾン頼みI2C I/Fを調達し手搭載(このLCDでは、バックライト端子のみ別配線する工夫が必要ですが…)、NanoPiへの配線も4線で。Osoyoさんのサンプルコードを使って、表示確認まで済ませました。
何を表示するのか?
キャラクタLCD、16文字2桁しかないし、つけっぱなしで寿命どのくらいなんかなーと言うことが若干気になりつつもまぁ5年くらいは動くのかな…。
で、表示内容は、こいつがなんなのか(つまり"Time Server")、GPSから得られるその日付時刻(UTCですが…)、測位モードにエアの状態、衛星は見えてるかいくつ? くらい、さすればこのntpは今GPS使えてるか自走モードかくらいは判別できるので、その辺繰り返し表示しておけばよいかなー。
どやって表示するか?
ntpサーバーはgpsd使っているし、表示テストに使ったサンプルコードはpythonだしそれなら後で表示内容簡単に変えられるし、そこにgps情報を付け加えればえっかなと、ざっくり。"python gpsd"でググるとgps3というpythonパッケージが目に止まって動かしてみる。何々?十分な情報とれそうだ、でもそんなに色々情報使いはしないけど、と思って使ってみると、測位に使っている衛星個数情報を取り出せない。ま、測位モードだけ判れば良いかとおもい、その表示を行わせてみると、時間更新がうまくいかないし、どうもgpsdから与えられる情報にゴミが含まれることがあるのか、クラッシュする(pythonプログラムが落ちるわけではないが止まってしまう)。使っているGPSその物に依存する可能性はあるけど、これじゃちょっと辛い…。
改めて検索しこれを試すと、シンプルだし時刻データもちゃんと更新される。osoyoのコードそれを付け加えたのが次のコード。gps3が問題なく動くなら、satellitesも同じようにリストになってると思うので、それ調べて測位に使われているならカウントしてやれば良いだろうと思う。
#
# Project Tutorial Url:http://osoyoo.com/?p=1031
#
# GPSd related codes: class GpsPoller() etc.
# Written by Dan Mandle http://dan.mandle.me September 2012
# License: GPL 2.0
#
import smbus
import time
import threading
from gps import *
gpsd = None
class GpsPoller(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
global gpsd
gpsd = gps(mode=WATCH_ENABLE)
self.current_value = None
self.running = True
def run(self):
global gpsd
while gpsp.running:
gpsd.next()
# Define some device parameters
I2C_ADDR = 0x27 # I2C device address, if any error, change this address to 0x3f
LCD_WIDTH = 16 # Maximum characters per line
# Define some device constants
LCD_CHR = 1 # Mode - Sending data
LCD_CMD = 0 # Mode - Sending command
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line
LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line
LCD_BACKLIGHT = 0x08 # On
#LCD_BACKLIGHT = 0x00 # Off
ENABLE = 0b00000100 # Enable bit
# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005
#Open I2C interface
bus = smbus.SMBus(0) # NanoPi NEO / Rev 1 Pi uses 0
#bus = smbus.SMBus(1) # Rev 2 Pi uses 1
def lcd_init():
# Initialise display
lcd_byte(0x33,LCD_CMD) # 110011 Initialise
lcd_byte(0x32,LCD_CMD) # 110010 Initialise
lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
lcd_byte(0x01,LCD_CMD) # 000001 Clear display
time.sleep(E_DELAY)
def lcd_byte(bits, mode):
# Send byte to data pins
# bits = the data
# mode = 1 for data
# 0 for command
bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT
bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT
# High bits
bus.write_byte(I2C_ADDR, bits_high)
lcd_toggle_enable(bits_high)
# Low bits
bus.write_byte(I2C_ADDR, bits_low)
lcd_toggle_enable(bits_low)
def lcd_toggle_enable(bits):
# Toggle enable
time.sleep(E_DELAY)
bus.write_byte(I2C_ADDR, (bits | ENABLE))
time.sleep(E_PULSE)
bus.write_byte(I2C_ADDR,(bits & ~ENABLE))
time.sleep(E_DELAY)
def lcd_string(message,line):# Send string to displaymessage = message.ljust(LCD_WIDTH," ")lcd_byte(line, LCD_CMD)for i in range(LCD_WIDTH):lcd_byte(ord(message[i]),LCD_CHR)def main():# Main program block# Initialise displaylcd_init()gpsp.start()while True:gps_satellites = gpsd.satellitesnum_sats_available = 0for item in gps_satellites:satdata = str(item)num_sats_available = num_sats_available + satdata.count("Used: y")lcd_string("GPS time server ",LCD_LINE_1)gps_mode = gpsd.fix.modeif gps_mode == 1:mode_string = "SATs not fixed"elif gps_mode == 2:mode_string = "2D mode, "+str(num_sats_available)+"SATs"elif gps_mode == 3:mode_string = "3D mode, "+str(num_sats_available)+"SATs"else:mode_stroing = "Unknown"lcd_string(mode_string, LCD_LINE_2)time.sleep(2)# next page display -- timegps_time = gpsd.utcdt_today = gps_time[:10]dt_time = gps_time[11:20]+"(UTC)"lcd_string(dt_today,LCD_LINE_1)lcd_string(dt_time,LCD_LINE_2)# next page display -- timegps_time = gpsd.utcdt_today = gps_time[:10]dt_time = gps_time[11:20]+"(UTC)"lcd_string(dt_today,LCD_LINE_1)lcd_string(dt_time,LCD_LINE_2)time.sleep(3)if __name__ == '__main__':gpsp = GpsPoller()try:main()except (KeyboardInterrupt, SystemExit):print ("\nKilling Thread...")gpsp.running = Falsegpsp.join()finally:lcd_byte(0x01, LCD_CMD)
以上、テストラン中。後は箱作りですが、それはまた今度。最悪、LCDバックライト寿命については、ジャンパでon/offできるので、トグルスイッチでもつけるかな…。
2021年6月14日月曜日
Lichee Zero Dock その1
カメラ、というか動画をいじろう、ということを前から思ってて、カメラモジュールも持ってるものの、なかなか手をつけられずにおりました。手元のボードコンピュータたち、カメラI/F、いわゆるCSIがあるのは、ラズパイ3Bと、PineA64なんですが、ラズパイは言わずと知れた「指定センサ以外はまず使えない」、A64は別の仕事をしている関係で容易に使えず。ということで、何かないかなー、A64は8bitパラレルCSIはOKだけどMIPIは使えないなーと思ってた所に、次の2つを見つけました。
別段新登場、ということではなく、今までそういう目で探してなかった、ということなんですが、一つはM1n、もう一つはLichee Zero Dock、どちらもSipeed製。2枚合わせてもラズパイ買うより安い…(いや比べる事自体正しくない)。で、M1nは、Linuxはちょっと難しそうでRTOS必要そう、かつ、目的がちょっと違うので、一旦置いておいて、Licheeからいじってみることにしました。
Lichee Zero Dock
Lichee Pi Zero? Lichee Zero? どっちでも良いみたいですが、それをコアにして、すこーし周辺I/Fコネクタを追加したもの、と言って良いかと思います。ただ、Zeroはブレボに刺して使うイメージですが、Dockはさらにコネクタなどが乗っている都合で、ブレボに刺してもあんまり嬉しい状況にはなりません。Ethernetを使えてほしかった関係で、ZeroではなくZero Dockを調達してます。そういうわけで、最低限必要そうなUARTだけとりあえず引きだすためのボードを用意しました。電源も、UARTのところから引けるんですが、母艦側がちょっと苦しいので、5V電源を追加してあります(UART側は当然外します)。以下では省いてるんですが、最初、ちょっとLCDをつないでみたときは、LCDバックライト依存性あるとはいえ電源が窮屈だったようでした。
OSと初期設定
Sipeedのサイト から mindb_dd.tar.gzをダウンロード、tar xfして出てくるlichee_zero-mindb_alpha.ddをmicroSDにdd。起動してみると、このddイメージはDebian Jessieです。
この段階ではethernetは生きていません。でもネットにはつなぎたいので、Wi-Fiどうかなと思いTL-WN725NをUSBにつなぐと、r8188euで認識してくれました。
『最小パッケージ』なので、NetworkManagerとかいないので、interfacesとwpa_suppliant.confを作成してまずは動かします。
wpa_supplicant.confのスケルトンはあるので、wpa_passphraseでssidとパスコードからpskを作らせます。
/etc/network/interfacesにwlan0を追加し、wpa-confがwpa_supplicant.confを示すようにしてやります。これでネットワークにつながりました。
armbianみたいにパーティション自動最大化とかはしてくれないので、マニュアルでパーティションサイズ変更してresize2fs実施します。
fdisk /dev/mmcblk0
/用パーティション一旦削除して、改め最大値で確保します。
write→quit→reboot(partprobeとかないので)
立ち上がり後resize2fs -f /dev/mmcblk0p2
Lichee Zeroには、内蔵メモリ64Mしかないのでswap足しておきます(128M追加)。
dd if=/dev/zero of=<filename> bs=1M count=128
swapon
/etc/fstabに追加して再起動時でも有効にします。
さすがにDebian JessieはLTS的にも切れてるので、せめてstretchにupgrade。カーネルは4.10.2のまま。stretchにupgradeするときには、debian-keyringのupdateが必要なことを忘れがち、ということと、多分、Wi-Fiがfirmware必要なので、追加しておきます(大丈夫だったかもしれない)。しかし、ethernetが使えないのは痛い…。
ethernet
サイズ的な大小はあるにせよ、こういう「規模」が当たり前だった昔ならいざ知らず、いまだとこのクラスのマシン用イメージはセルフではなくクロスビルドが普通だよな…と思いつつ、こちらのサイトに、ethernetを有効とする手順紹介があるので、それを元にセルフビルドしてやります。中国語は読めないので、Web翻訳使いながら読みます。
u-bootはdenxではなく同じサイトにリンクがあるこちらとこちらを使います。
makeできたら次で書き込む。
dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8
u-boot直しただけではu-bootレベルで触れる、と言うだけなので、Linux側も、ドライバ、デバイスツリーを修正します。そのため、カーネルソース、次を利用。
時間計らなかったけど半日は掛からなかったようです。
make install modules_installではなく、dtbとzImageを/bootにcpしてreboot → お、LEDが点灯& ethernet稼働!
カーネルをより新しく…
これで4.12.0-rc1。しかし、それにしてもこのカーネルはちょいと古く、linux-sunxiサイト見ても、主目的であるカメラサポートは5.0以降となっている。そのため、このイメージはここでストップして、改めて5.10のイメージ作成にチャレンジする。
最新u-bootにすべきかもしれないけど、device treeが結構違っているようで、マージには相当手間が掛かりそうなので一旦捨て置いて、Linuxカーネルソース5.10.42をcloneして、sunxi_defconfigしてbuild、ほぼ5時間で終了。
/bootにdts、zImageをcpして、make modules_install、rebootで5.10.42は起動しました。
なお、カーネルdevice treeには、u-boot同様の変更が必要です(Linuxサイドが新しいので、一部、語を変更する必要がある。)
次の問題
だが、USBが動いていない模様で、u-bootで有効にできていないようであることが判明。u-bootを使った確認方法。
U-Boot 2017.01-rc2-00057-g32ab1804cd-dirty (Jun 13 2021 - 15:14:29 +0900) Allwinner Technology
CPU: Allwinner V3s (SUN8I 1681)
Model: Lichee Pi Zero
DRAM: 64 MiB
MMC: SUNXI SD/MMC: 0
*** Warning - bad CRC, using default environment
Setting up a 480x272 lcd console (overscan 0x0)
dotclock: 10000kHz = 10000kHz: (1 * 3MHz * 20) / 6
In: serial@01c28000
Out: serial@01c28000
Err: serial@01c28000
Net: phy interface0
eth0: ethernet@1c30000
starting USB...
USB0: musb_init_controller failed with status -22
probe failed, error -5
USB error: all controllers failed lowlevel init
Hit any key to stop autoboot: 0
=>
ということなので、ここのレベルでUSBを有効にできていない。mindbにあるu-bootではちゃんと使えているのだが、.configがなく…。
結構、config様々試してみたんですが動いてくれず。素人目なので確実ではないけども、u-bootのUSBまわりを追ってみると、V3sのサポートが足らないような気がする。Ethernetについても、最新のu-bootでもまだのようなので(patchが流れていた)、V3s自体、まだ十分にサポートされてはいないようです。
がまぁ、ネットワークは動いていることだし、カメラをつなぐことを考えてみたいと思います。
とりあえず今回ここまで。
2021年3月28日日曜日
BL190HWとArcher C6
…、どうもC6経由のdhcp割り当てがうまくない。有線clientがいるのでBL190HWにdhcpやらせてC6はブリッジモード運用なんだが、時にC6経由で中継されるリクエストがきっかけなのか、BL190がアドレスを振り出さなくなってしまう。
こうなるとBL190の再起動が必要。日に数回発生し得るので、ファイルサーバーにもdhcpサーバーをやらせて、しばらく割り当て状況を監視、だな。
2021年3月12日金曜日
Nucleo64+ArduinoLCD+MPU6050の明日はどっちだ? (承前。GPS追加搭載。)
前回、加速度センサつなげて温度計つなげて、って所までで止めてて、GPSもつなぎたいな…というところで終わりにしていたんですが、その時までにGPSを試していなかったのか、と言うと、そういうわけではなく、GPS側の設定の問題と、シリアルの取扱い方が判らなくて、詰まってたんです。
手元にあるのはUART接続の古いGPSモジュールなので、UART経由でデータを読んでやる必要があります。
ArduinoにはTinyGPSPlusと言う優れものがあり、年末のArduino UNOではそれ使いました。mbedにもそのポーティングがあるんですが、先だって書いたとおり、それがmbedいくつ向けか、という微妙な点があります。それに纏わり引っかかった、mbedにおけるシリアルの取り扱いの変遷があります。
リアルタイム性を含めてのことなのかなとも思いますが、シリアルやらでデータを交換する時に、C言語までの知識ではgetc()/putc()使う、って教わるように思うんですが(本職の皆さん違ってたらごめんなさい)、getc()もputc()も、mbed 2にはあれど、mbed 6には存在しないんです。
おまけに、mbedには、2014年頃まで、トラ技誌に付録でついたLPC11U35のボードのおかげか(そいつが前回記事で、なんとmbed 6はサポート外なんかい…となったきっかけなんですけど)、日本国内で流行った時期があった関係で、概ね2016年以前のmbed実績のblogなどは、mbed 2、ほぼそれで書かれており、getc()/putc()を使用、せいぜい、serialとrawserialという区分けまでで、はて、mbed 6はどうしたら…となっていたわけです。
Mbedサイトで、シリアルにはBufferedとUnbufferedがあって、getc()じゃなくてread()で取り込む…てのは読んで判ったわけですが、どちら使ってもOSが落ちhaltしちゃう。前回の時は、そこまで追求できなかったんです。
で、改め、unbufferedの時、何で落ちてるのか調べようと思って始めたのが今回なんですが、なぜかdebuggerを使うようbuildすると、もうdebuggerとの通信の時点でOSが落ちちゃう。OSが吐くログは、STLink絡みで問題があるようだけど、とてもそんな所までデバッグする能力はないので、bufferedでどこまで動くか見てみよう、ということで、取り込んだものをprintfさせてみると、どうもnon-printable charを拾っている感じ。これはもしかして、TinyGPSPlusが要求するNMEAを喋ってないんじゃないの?とようやく思い当たりました。
GPSモジュール自体は、NMEAを出力するよう設定して、バックアップバッテリを接続していたので、NMEAのままだと思い込んでいたんですが(古いので、それがないと、電源投入時に、NMEAではない初期状態の出力になっちゃう)、何かのはずみにバッテリへの結線が外れてたんです…。つまりGPSデフォルトで出力していました。それでTinyGPSPlusが解釈できていないことが原因だったと。
それを直し、改めてNMEAを出力するよう設定して走らせてみると…
右の写真ではまだ衛星補足していませんが、時間が取れていることから、ようやく、GPSが出力するデータを読めるようになったようです。衛星捕捉できれば、ちゃんとLAT・LNG表示してくれます。
写真では分かり辛いですが、Arduino LCDを載せたF411RE、SK-16に、クッション付き両面テープを置いて張り付け、その左がわちょうどUSBコネクタの下あたりにGY-521を、同じように両面テープで張り付け、手前側にGPSバックアップ用CR1220が張り付けてあります。
GPSと、Arduino LCDに搭載されているmicroSDへの書き込み開始スイッチを蓋に張り付けてやって、なんとか収まるようにしました(LCD+F411REの背が微妙に高いのと、ちょいと配線量が多くて、ふたがちゃんとしまりきらないですが…)。
これでも、LM75Aによると、F411REとLCDの間は、LCDバックライトで温められてるとはいえども36℃ほどで収まっているようです。
それにしても、ここに持ってくるまでに、こんなに時間掛かるとは…(何分古いGPSなので、時計はrolloverしてます…)。mbedにはだいぶ悩まされました。
性質的には、GPSはunbufferedで動かす必要があるようには思うんですけど、OSクラッシュは、GPSがNMEA話しているかどうかには関係なく、私程度のソフトウエア知識では対応できましぇーん!
3/29追記:
昨晩、なぜUnbufferedSerialだとクラッシュするのか、はっと気づきました。プログラムフロー的に非同期な扱いをする部分で、同期乗り換えを必要とすることやっちゃダメっすよね。
さっきそれ直して、UnbufferedSerialを使ってGPSを読み、エンコードし、加速度センサなどの出力と併せて表示できるようにできました。
これで、GPSの時刻データも毎秒表示されます(buffered serialで、バッファしたもの解釈させると、取りこぼしの上数分単位でしか更新できなかったんです…)。
サンプルコードがあるからって、それを鵜呑みにしといちゃダメすね…。特にBuffered Serial / Unbuffered Serialみたいなtiming issueがある実装に対しては。