中華STM32基板のBlackpillを味見しています.
前回は、ADCを2ch運用しましたが、サンプル周波数は500Hzと遅かったです.
今回は、サンプル周波数を20kHzまで上げます.
無理矢理で40kHzまで行けるかな?って感触ですが、20kで止めておきました.律速は割り込みroutineでbuffer copyとかする部分ですので高速化の余地はありそうですが、さりとて100kHzまで上げられる気はしません.
なお、CPU STM32F401のADC性能では1MHz近いサンプルが可能のようです.
ーーーー
やったことのリスト
・サンプリング周波数は20kHz
・連続する1000ptsをメモリにストア
・同1000ptsをCDC(USB COM)でPCへ送信する
・サンプリング周期はTIM3の出力する50uSecで決める (つまりhardware自走)
・ADC入力はIN1とIN9の2本 (2ch scan)
・ADCは1トリガで2サンプル (2ch scan)
・DMAを使う
・DMAはIN1サンプル→DMA→IN9サンプル→DMAという動作をする
・すなわち、TIM3→ADC(IN1)→DMA→ADC(IN9)→DMAがhardwareで自走する
・ADC完了をIRQで知る
・同IRQで1000pts x 2ch分のbufferに積む
・同IRQでbuffer fullになったらUSB送信を起動
・USB転送終了をIRQで知る
・USB busyの最中はADC IRQでbufferに積まない (buffer衝突防止)
・ADCは12bitなので、1サンプルあたりASCIIの3bytesをbufferに積む
・ゆえに1USB送信あたり1000x2x3=6000bytes
・USB FULL SPEED(12Mbps)で6000bytes送信するのにover head込みで50mSecぐらいかかっている(実測)
ーーーー
前回も触れましたが、いろんな疑問点について
Q:STM32CubeIDEとArduinoIDEのどちらを使う?
A:STM32CubeIDE
ArduinoIDEだとUSB関連のexampleが見当たらず使いませんでした.
STMCubeIDEのCDC exampleを雛形にして改造しました.
Q:TIM3+ADC+DMAを起動するやりかた
A:HAL_Delay(3000);
HAL_TIM_Base_Start_IT(&htim3);
HAL_ADC_Start_DMA(&hadc1, &buffer[0], 2);
main()の最初の方の各種Initの後で1回だけこれをやると、あとはhardwareが自走してくれます.詳細は前回を参照.
HAL_Delay(3000)は必須です.USB接続の直後は不安定なので3秒待ちます.
Q:ADC終了割り込みはどれを使えばいいんだ?
A:HAL_ADC_ConvCpltCallback()
事情は前回を参照.
Q:USB終了割り込みはどれを使えばいいんだ?
A:CDC_TransmitCplt_FS()
USB COMのUSBの転送終了を知るにはこれが良いようです.
USB転送終了までbufferへのADC dataの上書きを禁止するためにこの割り込みを使います.
Q:DMAのdata widthは8/16/32bitのどれにしようか?
A:32bitにした
事情は前回を参照.
Q:USB転送終了calbackでやること
A:busy flugを下げる
USB転送が終わると自動的にこの関数がcallされます.
CDC_TransmitCplt_FS(){
uint8_t result = USBD_OK;
UNUSED(Buf);
UNUSED(Len);
UNUSED(epnum);
usb_busy = 0; ←これを追加
return result;
}
Q:HAL_ADC_ConvCpltCallback()で何をやる?
A:改造の中心部がここ、main()の上の辺りにでも追加、weak宣言されてる
#define PTS 1000 連続サンプル数1000
#define CH 2 ADC 2ch scan
#define BUFSIZE (3*PTS*CH) USB bufferサイズ6000bytes
int usb_busy = 0; USB busyフラグ
static uint32_t buffer[4]; ADC dataを都度格納する場所
static uint8_t usbbuf[BUFSIZE+100]; USB buffer確保
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
static int N = 0;
if(usb_busy==0){
char c[15];
sprintf(c,"%03X",buffer[0]); IN1 ASCII変換
usbbuf[N++] = c[0]; strcat()は遅いので使うのやめた
usbbuf[N++] = c[1];
usbbuf[N++] = c[2];
sprintf(c,"%03X",buffer[1]); IN9 ASCII変換
usbbuf[N++] = c[0];
usbbuf[N++] = c[1];
usbbuf[N++] = c[2];
}
if(N>=BUFSIZE){ 6000bytes積んだらUSB起動
usbbuf[BUFSIZE] = '\n';
N=0;
usb_busy=1; USB転送はmain()で起動する
}
}
追記:sprintf()も遅いので自作のitoa()に変えたら50kHzサンプルで動きました.
Q:main()でUSB転送を起動するには?
A:while()でCDC_Transmit_FS()をcallする
while (1) {
if(usb_busy==1) CDC_Transmit_FS(&usbbuf[0],BUFSIZE+1);
}
ーーーー
STM32CubeMXの設定について.
ADCの設定
DMAの設定TIM3の設定
その昔、サンプリング周波数は、帯域幅の二倍と聞いたことある
返信削除なんで二倍かわすれました
Mp3のエンコードで128khz
とかあったから256kHzでサンプリングするのかしら?
MP3はサンプル48kHzが多くて、128kとかいうのはたいていビットレートかと思われます.
削除>サンプリング周波数は、帯域幅の二倍
削除「帯域幅」っていうか、サンプリング対象の「最大周波数」ですね。
※「標本化定理」で、ググって下さい。あと、基本事項なので、デジタル信号処理の教科書には必ず載ってますよ。
>Mp3のエンコードで128khz
mp3 とかの、「xxKHz」とかは、これとはまた別の話です(無関係では無いが)
(このコメント欄に記すには余白が狭すぎるので、以下略。)
そうでした、なるほど すこし思いだしました
削除>ESP32のほうがいろいろと高速かもしれない
返信削除私もそんな気がします。
※でもそれは「ネイティブ開発環境(ESPIDE)」を使った時の話で、
Arduino にしちゃうと、あんまり早く無いカモです。あと、USBは(RISC-V版を除いて)使えません。
「esp32 oscilloscope」は、検索すると、海外含めていっぱい出てきますね。
削除github にも、たくさん落ちてますね。
wifiはsocketってやつでdata受けるんでしょうか.socketって使ったことないんです.
削除>socketって使ったことない
削除ESP32とかは、
・そういう細かいところを知らなくても使えるのがウリ
のハズなので、繋がってしまえば、単に、
・とあるプロセスに「STDIN」「STDOUT」があるだけ(シリアル In/Out と言ってもイイ)
です。
※大体、殆どの通信系(TCP/IP、 USBとかも)は、つまるところ、
・RS-232C 上位互換
と、言っても過言では無いです。
※open、close、read、write があるだけ。これですべて事足ります。
(細かいことを言わなければ。速度とかパフォーマンスを追求し出すと、イロイロ知らないといけなくなりますが。)
そもそも、Socket = RS232Cの(物理的な)コネクタ みたいなイメージです
削除コネクト/ディスコネクト=コネクタを差し込む/抜く と思っていいです
※WebPageをブラウザに表示、とかは、また「別のレイヤー」なので、別の話です。http(s)プロトコルの知識が必要になる。
Unixの開発者は、
削除・すべてを、「STDIN」「STDOUT」で、記述したい
と思って、みーんな、「共通API 」(open close read write)だけて、
「いろんなプログラムを、使いまわしできる」ように設計しました。
※なので、「ファイル」「シリアル」「TCPIPネットワーク」「USB」は、ぜーんぶ、この基本APIだけは共通です。
(勿論「固有API」は、個別に必要になりますが、たいがい、決まった「おまじない」を唱えれば済む。)
リダイレクト大好きです
削除リダイヤル使ってます
削除Unix開発者えらい バークレー?
削除「カリフォルニア大学バークレー校」は、「ソケットAPI」を、開発したところですね。
削除「STDIN」「STDOUT」は、それよりもっと前からあるハズ。
https://ja.wikipedia.org/wiki/%E3%83%91%E3%82%A4%E3%83%97_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF)
※Windows も、この辺にかなり影響を受けてるので、同様のAPIは持ってます。
復活の呪文はリブート
削除※なんか、こういうのを「サクッと作れる」
返信削除・Mixed Signal FPGA
とか、あればいいのに。と、時々思います。
・A/D ブロックと、CPUブロックと、ちょっとした Glue-logic が記述できればいい
だけでしょ? 現時点でも「Verilog とかで、記述だけ」なら出来ますね。
どこかで作ってくれないかな・・・
ADのADAU1401がもっと融通の利く仕様だったらいいのに、PCにdata送信とかできなくてなんだかなぁでした
削除CPUブロックでなくて再販した電子ブロックはだいぶひかれましたが買いませんでした
削除電子ブロック100が昭和50年頃に¥6800ぐらいしていてなかなか高価な玩具でした.買いました.
削除>昭和50年頃に¥6800ぐらい
削除今だと、
・1万4千円くらいの価値(消費者物価指数から計算)
みたいですが。
※Nintendo Switch のほうが高いな。(37980円[税込])
意外と安い感じがする。
実は、私の家(実家)にも、これ
削除https://www.denshiblock.co.jp/siryoindex.html
電子ブロック ST-100
が、ありました。
※復刻版がある「EX-150」とは、シリーズが違う。こっちのが、古いようです。
定価¥4,950 だった模様。
わたしもST100でした.
削除初代は1965年からあったようですね.ゲルマニウムか.
「ST-100」の、「ST」とは、
削除・Silicon Transistor
の意味のようです。
※ちなみに、私が持っていた ST-100 に使われてたのは、
・2SC372(ツバ付きのやつ。新しい奴はツバが付いて無い。)
だった記憶があります。
Yeah! 2SC372.
削除でもなぜか、ネットで出てくる回路図で使われてるのは、
削除・2SC945
なんだよなー。あと、「2SC372」ジャナクテ「2SC373」だったかも知れない。
372であってるとおもいます
削除いや、現物が、
削除・2SC373
だった記憶があります。
※多分「大人の事情」(単に、入手できなかったので代用したロット)
だったのだと思いますが・・・・
というか、これで当時、
2SC373≒2SC372 (細かいこと言わなきゃ、代用可能)
ということを知りました。
CQ出版のトランジスタ互換表を思い出しました
削除2SC372 2SC945 2SC1185 の流れ?
返信削除さらに2458とかだったか
削除だんだん小さくなる
削除ハンダづけの手間を考えるにSOT23ぐらいまでにしとうございます
削除スキャナーの基板をみて 部品どりしてリサイクルとおもいましたが 0.3ミリピッチで 人間技ではありません
削除秋葉原で買った実体顕微鏡がこんなこともあろうかと用意してましたが使う気力がなく てが震えて使えないなとおもいました 手は震えてはいないのですが何となく絶望感
Seeed XIAO RP2040をなにかにつかえないかと800円くらいで買いました
返信削除端子はusb と ピン端子のみ
Lan用端子はなし
使い道ありそうでしょうか
たしか 1.4インチ液晶でspi接続でもしようかと買った気がします
気圧表示くらいかなあ
え、ラズパイの一種です?
削除フラットヘッドスキャナーを部品どりして 3Dプリンタでも作ろうと妄想してます 薄型スキャナーはダメなことがわかったです 使える部品がないです
返信削除太いガイド用の丸い鉄棒もなかった
Aliexpressでどうぞぞうぞ
削除