バルミューダ用の5cc計量カップを3Dプリンタで作る
バルミューダのトースター、スチーム用に5ccのコップデザインの付属の計量カップを使んだけど、この計量カップは一般には市販されて無くて、かつ小さいのでうっかり無くしそうなので、作って印刷してみた。
Fusion 360 でモデリングして印刷。5cc はざっくりと計れれば良いので、計量部は 半径1.1cm、高さは1.31cmで。オフィシャルのカップは内側に5ccと書かれた凹があってわかりやすいけど、家庭用プリンターだと精度でなさそうなので作っていない。
一度印刷してみてたところ、
あたりが不満だったので、微調整して再印刷した。
印刷に使ったプリンタは Afinia H480。7.7g の ABS で約40分。
0.1g 測定できるハカリで実際に計量してみたらだいたい5g弱で水がすくえてた。積層跡とトップの印刷跡がいかにも3Dプリンター。
付属品と比べるとあからさまにデザイン面で劣るし、マットな質感も出せてないんだけど、無くした時用ということで。
なお印刷に必要なデータ(STLとか)などは Fusion 360 のサイトから落とせる。
3D CAD すごく難しいイメージだったのだけど、Fusion 360 は個人利用なら基本無償だし、直感的に操作できて便利。
バルミューダのトースター、実家へのプレゼントと自宅用に二つ買ったけど、大変満足度高い。
1mA単位で計れる OLED USB電流チェッカー
mbed で MAX7219 + 8桁7セグメントLEDを使う
ebayで約200円で売られている、MAX7219 + 8桁7セグメントLEDを mbed で動かした。
SPIで制御するのだけど、MISO は必要なく、繋ぐ線は
- (mbed) MOSI -> (MAX7219) DIN
- (mbed) SCK -> (MAX7219) CLK
- (mbed) CS -> (MAX7219) CS
の3本で良い。
オフィシャルが提供している mbed のライブラリコードを使う場合、全桁自分で制御する (decode_mode が 0x00) 前提でコードを書く必要がある。
例えば全桁 - (マイナス)表示をしたい場合は
Max7219 max7219(MOSI, NC, SCK, CS); max7219_configuration_t cfg = { .device_number = 1, .decode_mode = 0xFF, .intensity = Max7219::MAX7219_INTENSITY_7, .scan_limit = Max7219::MAX7219_SCAN_8 }; max7219.init_device(cfg); max7219.enable_device(1); max7219.clear_display_test(); for(uint8_t i = 1; i < 9; i++) { max7219.write_digit(1, i, 0b1010 /* minus */); }
のように書く必要があって面倒。
ではシンプルに実現してるので、mbed で動くように移植してみた(cho45 さんから許可いただきました)。
SPI spi(MOSI, NC, CLK);
MAX7219 max7219(spi, CS);
max7219.begin();
max7219.print("-1234.567");
3.3V で動くのか
そもそも MAX7219 は仕様書によると電源電圧が 4V~5.5V、 ロジックの HI が MIN 3.5V だったので 3.3Vを電源とするmbedと同じ3.3V電源で動かないと思ってたんだけど動いてしまった。
また、MAX7219 のICの価格が、digikey だと8$ほどするけど、ebay だと LED 込みで2$しない価格で安すぎる…。B級品なのかコピー品なのか。
組み込み関係の事をブログ記事を書くこと
↑で触れてる lowreal.net の影響が大きくて。組み込み開発に興味無かったときは、エントリーを読んでも理解できなかったんだけど、今は大変参考になるし、Google 検索しても結構な頻度で引っかって助かっている。なのでメモ的なことでも記事にしている。
HX711で重さを量る
ハカリなど重さを量るには、一般的にロードセルとひずみゲージセンサーを使って実現している。HX711 は安価なひずみゲージを読み取るためのICで、24bit ADCを搭載していて、ICにクロックを送ることでデータを受け取る。ebay では実装済の物が一つ100円以下で買える。
ロードセルは単体で買っても、ロードセルを設置ことが大変。その辺のハカリをバラすと入っているし、そのまま設置できるので大変楽。ロードセルにはVDD/GNDと、ひずみゲージの+-の線があるので、それをHX711のE+(VDD),E-(GND)、A+, A- (チャンネルAを使う場合)に接続すればOK。
HX711 用ライブラリ
Arduino 用はあるけど、mbed 用でちゃんと動く物がなかったので書いた。
HX711 hx711(dataPin, clockPin); hx711.setScale(100000f); # ひづみゲージにや電源よって最適な値は異なる hx711.tare(); float gram = hx711.getGram();
で動く。HX711 の仕様書を読んだメモ
https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf
- DOUT が LOW になったら準備完了
- 同期に用いる PD_SCK にあわせて 24bit 分のデータをDOUTから MSB で出力する
- その後のPD_SCKでのHIGH/LOWの回数にあわせて、次回のゲインが決まる
- 標準は 128 (1回のHIGH/LOW)
- CH A を使う場合は 128 もしくは 64
- CH B を使う場合は 32 をセットする。
# HX711.hpp #ifndef HX711_h #define HX711_h #include <mbed.h> const float defautScale = 490000.0f; const float lbToGram = 453.5f; class HX711 { private: DigitalIn dataPin; DigitalOut clockPin; uint8_t gainPulse; uint32_t offset; float scale; public: HX711(PinName dataPinName, PinName clockPinName) : dataPin(dataPinName), clockPin(clockPinName, 0) { offset = 0; gainPulse = 1; scale = defautScale; } void tare() { offset = avg(10); } const float getOffset() { return offset; } float readGram(uint8_t times = 10) { float res = (float)avg(times) - offset; return res / scale * lbToGram; } uint32_t avg(uint8_t times = 10) { uint32_t res = 0; for(uint8_t i = 0; i < times; i++) { res += read(); } return res / times; } bool isReady() { return dataPin == 0; } void setGainPulse(uint8_t _gainPulse) { gainPulse = _gainPulse; read(); } void setScale(const float _scale) { scale = _scale; } const float getScale() { return scale; } uint32_t read() { uint32_t res = 0; uint8_t i = 0; while (!isReady()); for(i = 0; i < 24; i++) { clockPin = 1; res = res << 1; clockPin = 0; if (dataPin == 1) { res++; } } for (int i = 0; i < gainPulse; i++) { clockPin = 1; clockPin = 0; } res ^= 0x00800000; return res; } }; #endif
nrf51 の nano.specs で printf で float の値を表示する
float の値を printf に表示したいだけなのに時間がかかった…。
newlib-nano を使ってるので、
にあるとおり、
-u _printf_float
を ldflags に追加すれば良い。
mbed の cli 環境下で追加する。
[4]>_<X mbed --version 0.9.5 [4]>_<X mbed compile \? usage: make.py [-h] [-m MCU] [-t TOOLCHAIN] [--color] [--cflags CFLAGS] [--asmflags ASMFLAGS] [--ldflags LDFLAGS] [-c] [-o OPTIONS] [-p PROGRAM] [-n PROGRAM] [-j JOBS] [-v] [--silent] [-D MACROS] [-S] [-f GENERAL_FILTER_REGEX] [--automated] [--host HOST_TEST] [--extra EXTRA] [--peripherals PERIPHERALS] [--dep DEPENDENCIES] [--source SOURCE_DIR] [--duration DURATION] [--build BUILD_DIR] [-N ARTIFACT_NAME] [-d DISK] [-s SERIAL] [-b BAUD] [-L] [--rtos] [--rpc] [--eth] [--usb_host] [--usb] [--dsp] [--fat] [--ublox] [--testlib] [-l LINKER_SCRIPT] make.py: error: unrecognized arguments: ?
を見ると、--ldflags に値を渡せば良さそう。なんだけど、こいつが内側の make.py で呼び出している gcc.py に値を渡していないので、設定しても無駄。
mbed toolchain を直接弄って指定する。
## .temp/tools/toolchains/gcc.py if use_nano: self.ld.append("--specs=nano.specs") self.ld += ["-u _printf_float"] # 追加
あと同階層にある gcc.pyc は削除しておく。
ううう…。
nRF5x-DK のファームウェアを更新する
nRFのDKのJLinkを使ってのファームウェア書き込み、windows 環境のnRFgo からだと5%ぐらいの確率で、Linux環境だとJLinkExeで書き込むとほぼ二回目で失敗する。調べたらファームウェアアップデートしとけ情報があった。
Fixed flashing issue
めっちゃ該当するやん!
nRF-DK は SW5 押しっぱで起動すると、USBリムーバブルディスクとしてのマウント名が JLink から Bootloader に変わる。
このモードで、落としたファームウェアをマウントしたディスクに書き込んで完了。と思いきや完了しない。再起動して JLink で再度繋いだタイミングで、確認ダイアログが出てそこでOKを押すと更新される模様。
二日かけてやっと開発環境がまともになってきた気がする…。
1~5V -> 5Vへの昇圧DCDCコンバータ
3V->5Vへの昇圧が必要になったので袋から出してきた。英語だと boost converter か step-up converter。
ebay で約一個60円で売ってる。載っているICはBL8530-501SMぽい。どこにも繋がってない D+/D- 端子があってなんだろう、と思ったら
こういうUSBで5V出力できるよう用のモジュールでも使ってるのね。
ebayの安価な商品群、将来必要になりそうな物もとりあえず買っておくと使い道が来て便利。