ラズピコのPWM。 なんかおかしいような
ありゃま。ラズピコがおかしくなった。 PWMを調べたかったのに
これの続き。
書き込み出来なかったのはUSB回りのゴソゴソ。
よく分からんけど。
2022年4月13日:Arduino IDEでRaspberry Pi Pico:Win7でのUSB問題解決です
これで使ったZagig.exeを触ってたら
書き込みできるようになりました。
さて、ラズピコのPWM。
なんかおかしい。
単純な整数値でPWMしてたら誤差なんて出ない(1clkの変動
はあるだろけど)はず。
analogWriteと名乗るからにはちゃんとしてほしい。
まず、テストで使ったスケッチ
・ダウンロード - pwm_serial_in1.txt
(ファイルタイプを.inoではなく.txtにしてます)
・USBでシリアル通信。
・スケッチを書き込み後ターミナルを起動。
・最初の「CR」入力でタイトルを出力。
・次に使うPWMポート番号を入力。
# PWM Port >
そのポートに対しデューティ50%の
(つもりの)波形を出力
・その次からPWMデータ入力を繰り返し。
# PWM Data (0...255) >
0~255の入力で設定したポートに
analogWriteでPWM値を設定
・「CR」だけだとPWMポート番号入力に戻る。
・データを「-1」で設定したらPWM値を順番に
増加させるモードに
1~254まで2秒ごとに+1。
254で停止。
設定したPWM値はSerial1にも出力。
これをデューティチェッカの出力とともに記録。
デューティチェッカの出力サイクルが1秒なので
ピコは2秒ごとにPWM値を変更。
設定したデューティ「n/255」値とデューティチェッカで
拾ったH/Lクロック数から計算した実デューティの差を
グラフにしたら、こうなりました。
デューティ比の差が「-0.1~0.0」を周期的に変動。
なんなんだこれは。
まず、測定した生データ。
設定したPWM値とデューティチェッカで拾った値です。
・ダウンロード - pico_pwm2a.txt
そこからそれぞれのデューティ比を計算。
・ダウンロード - pico_pwm3a.txt
その2つのデューティの差をグラフにしたのが↑。
| 固定リンク
「ラズパイ・ピコ」カテゴリの記事
- Help me! ラズピコ、Philhower版だとスケッチをアップロードできない(2023.04.12)
- Arduino IDEでのラズピコ開発環境 Philhower版が正解でしょう(2023.04.04)
- ラズピコのピン:自由になりそうだけど定義で固定されている(2023.04.03)
- ラズピコで2chシリアル入出力のテスト(2023.03.30)
- Arduino IDEでのラズピコ開発環境(2023.03.29)
「1023 vs 1024」カテゴリの記事
- Arduino サーミスタを使った温度測定で 【ゼロ除算問題】(2023.03.23)
- A/Dコンバータでサーミスタの抵抗値を読む サーミスタをつなぐ場所は?(2023.03.21)
- こんなところに「256-1」が(2023.03.08)
- ラズピコのPWM。やっぱしanalogWriteは捨てちゃえ #2(2023.02.22)
- ラズピコのPWM。 やっぱしanalogWriteは捨てちゃえ(2023.02.21)
コメント
素晴らしい、全体像が明らかになりましたね。PWMの周期の2msを1/256ステップで表現するためには7.8125us刻みにしないといけない。しかし実際に指定出来るのは2us刻みの値なので、8usステップに時々6usステップを混ぜてるってことなんでしょうね。
ところで話の元になった1.4mVの誤差の原因は、この調査結果から説明出来そうにないと思うのですがどうでしょう。無い知恵を絞って思い当たるのは、PWMのリップルの突き抜け?デジボルのリニアリティ?LPFに使ったコンデンサの誘電体吸収?
くらいですが、真の原因は何でしょうね。
投稿: ラジオペンチ | 2023年2月16日 (木) 19時29分
analogWriteの動作、まだちゃんとソースを追いかけていません。
ざっとgrepした感じだと、
・・・AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\1.13.1\cores\rp2040\wiring_analog.cpp
に
extern "C" void analogWrite(pin_size_t pin, int val) {
が出てきます。
そこでは・・・浮動小数点を使ってゴソゴソしてます。
PWMデューティ実値測定値の変動は、ひょっとして
浮動小数点計算のゆらぎ(0.1単位での)にあるのかと。
ラズピコのanalogWrite(PWM)もArduino UNOと同じで、
PWMポートが0でL、255でHになり、半値の128でデューティ
50%が出てきません。
※過去記事での問題点指摘はコレ↓
http://igarage.cocolog-nifty.com/blog/2020/08/post-0d2777.html
で、トラ技の実測値誤差、「誤差は1.4mV以下」と記されているので、設定値より大きかったのか小さかったのかが不明です。
※こちらの実験では小さく出るとの結果。
さて、その原因。
PWM値を0~255まで1ステップで変化させて確かめたんじゃなく「5ステップ」あたりの測定間隔だったとか。
図8を拡大するとDACバイナリ値の1目盛40の中に測定点の■が8つあります。
それが/|/|のノコギリ波誤差をサンプリングして、別の誤差波形が出たんじゃないかと思うのです。
投稿: 居酒屋ガレージ店主(JH3DBO) | 2023年2月17日 (金) 09時02分
ひょっとすると、ピコの環境を構築している Arduino IDE の具合で変わるのかもしれません。
例えば、「Arduino IDEでRaspberry Pi Pico:PWMでD/A出力してA/D入力を試す」
http://igarage.cocolog-nifty.com/blog/2022/04/post-75c555.html
ここでは、
// PWMでD/A出力
analogWriteFreq(4000); // PWM周波数4kHz
analogWriteResolution(12); // 12bit分解能(0~4095)
とPWM周波数をセットしてました。
しかし、現状の環境では「Freq」は「not declared」と言われる・・・
調べると、
// PWM RP2040-specific calls
void analogWriteFreq(uint32_t freq);
void analogWriteRange(uint32_t range);
void analogWriteResolution(int res);
というのがあるのですが、これらが出てくるのは「rp2040\1.13.1」の環境。
しかし、今の構築環境は「3.5.1」らしい。
これには「Freq」「Range」が無いようです。
そして、analogWriteの本体
void analogWrite(PinName pin, int val)
{
pin_size_t idx = PinNameToIndex(pin);
if (idx != NOT_A_PIN) {
analogWrite(idx, val);
} else {
mbed::PwmOut* pwm = new mbed::PwmOut(pin);
pwm->period_ms(2); //500Hz
float percent = (float)val/(float)((1 << write_resolution)-1);
pwm->write(percent);
}
}
最後の
「pwm->write(percent);」でデューティを設定しています。
ちゃんとしたPWM、ATmega328PのArduino UNOではタイマーレジスタを直接触わりました。
ピコでも、もっと深いところの関数を探し出して設定すべきなんでしょね。
追いかけるのがしんどく(もうエエやんに)なってきました。
投稿: 居酒屋ガレージ店主(JH3DBO) | 2023年2月17日 (金) 10時17分
VScodeを使うと関数の定義部まで簡単に飛べるので私もやってみたのですが、mbed::PwmOutあたりで良く判らなくなって止めました。パスは、
C:\Users\User\AppData\Local\Arduino15\packages\arduino\hardware\mbed_rp2040\3.0.1\cores\arduino\mbed\drivers\include\drivers\PwmOut.h
まあトラ技の155ページの図8のグラフはラズピコの性能だけを表わしている訳では無い、とは言えそうですね。
投稿: ラジオペンチ | 2023年2月17日 (金) 18時12分
PwmOut.hを眺めてますと、
void period_ms(int us);
と
void pulsewidth_us(int us);
というのが見つかります。
これだと整数値で設定できそうですが、使い方の例を探し出せてません。
anlogWriteで使われている、
void write(float value);
では、duty-cycleを浮動小数点で設定。
こんな解説になってます。
0.0f (representing on 0%) and 1.0f (representing on 100%)
実デューティ値との差、この浮動小数点がクセモノなのかと。
しかし・・・
半値(128)で50.000%にならないanlogWriteはイヤです。
投稿: 居酒屋ガレージ店主(JH3DBO) | 2023年2月18日 (土) 09時30分
続き・・・ラズピコのPWM。 なんかおかしいような #2
http://igarage.cocolog-nifty.com/blog/2023/02/post-699a97.html
投稿: 居酒屋ガレージ店主(JH3DBO) | 2023年2月20日 (月) 11時45分