ラズパイ・ピコ

2024年4月 7日 (日)

トラ技2024年5月号に「3.3/65535」

トランジスタ技術の最新号、2024年5月号を
パラパラめくりしていたら、p.70のリスト1に
怪しい記述を発見。
A/D値から電圧値を計算するための定数を出す
のに「3.3/65535」と。

Pp21
65536と65535の差はほんの僅か。

でも、リストの7行目のPID演算のところで、
6桁の数値が出ているんで、5桁数値の最小桁で
の1違いは大きくないかいなとちょいと心配。

電源電圧「3.3V」も、「ほんまかいな」だし。

元データはA/D値のまま使い、「CAL(校正)したらこうなった」
にして、「浮動小数点化したmap関数」を使って線形補間して
答えを出すてなほうが「理にかなっている」ような気がします。

ラズピコだと1/65535が出現:トラ技2022年5月

※検索
ラズパイマガジン2022年12月12日の訂正
   ・・・本文中の「1023」は「1024」、図2下の式の
  「4095」は「4096」の誤りです。
   ・・・Raspberry Piのところで分割数が「4095」と
  あるのは「4096」の誤り、Raspberry Pi Picoでは
  「65535」が「65536」、micro:bitとArduinoでは
  「1023」が「1024」の誤りでした。
訂正が出ています。

 

| | コメント (2)

2024年3月30日 (土)

ラズピコだと1/65535が出現

Arduinoでぐだぐだ言ったのが1023 vs 1024問題

トラ技のラズピコ特集、2022年5月号を見ていたら・・・
Pc12
A/D変換の値から電圧を計算するのに「1/65535」が
出ていました。

ただし言語は「python」。
analogioを検索してみると、Aanaloginは
16bitの値になるそうで、
https://learn.adafruit.com/circuitpython-essentials/circuitpython-analog-in
ここでは1/65536して電圧に変換しています。

https://www.denshi.club/pc/python/circuitpython/circuitpython-10-3.html
ここは、「65535は間違いなので」と注記があって
1/65536になっています。

https://logikara.blog/raspi-pico-basic/
ここは1/65536。

もう一つ、気になったのが
  v / (ref - v)
のところ。
Pc11

vが電圧値でrefが基準電圧つまり3.3Vなら、
adc.valueがフルスケールの65535になったときは
  v = 65535 / 65535 * 3.3 で
   = 3.3 となります。
すると、
  3.3 / (3.3 - 3.3)
で、ゼロ除算が発生。

図15のCDSが外れて、A/D値がフルスケールになると
ゼロ除算してしまうわけです。
1/65536にしていれば、v = 3.29995となり、
ゼロ除算は避けられます。

pythonでの数値型がよく分かってないので、
これでどんな挙動になるのかは知りません。
記事をぱっと見して、
  1/65535が出てきたぞ
  1023 vs 1024と同じ匂いか
っと、感じた次第です。

 

| | コメント (0)

2023年4月12日 (水)

Help me! ラズピコ、Philhower版だとスケッチをアップロードできない

Arduino IDE環境でゴソゴソしている「Raspberry Pi Pico」。

Arduino IDEでのラズピコ開発環境 Philhower版が正解でしょう
なんかと言いながら、ゴソゴソしたのですが、Philhower版だと
スケッチをアップロードできないのです。

ありゃま。ラズピコがおかしくなった。 PWMを調べたかったのに
これが2月半ば。
プログラムを書き込んだあとでも「BOOTスイッチ」を押しながら
USBに挿せば、外部ドライブとして認識されるはず。
この時から、ドライブとして認識してくれなくなりました。

そのせいか、Philhower版に切り替えると、エラーが出て
スケッチをアップロードできません。
しかし、「Mbed版」に切り替えると、ちゃんとアップでき
るのです。

Philhower版とMbed版でアップロードの方法が異なるようです。
同じピコをつないでいても、認識していたCOMポート番号も
変わっちゃうし・・・

Philhower版は、通信でBOOTモードにして、現れたドライブに
ファイルを書き込んでいるような気配です。
現PC、ピコのドライブが出てこないからエラーとなっている
ような感じです。

手元には3つのラズピコ基板がありますが、どれも同じ。
現PCではダメですが、他のPCだとちゃんとドライブとして
認めてくれます。
現PC、USB回りの何かがおかしくなってしまったようです。
  ※USBの口を変えてもだめ。 ケーブルでもない。

Arduino IDEでラズパイ・ピコ:Earle Philhower版で
去年の4月時点では、間違いなくPhilhower版も試せていたのです。
それが・・・アウトに。
どうしたものか・・・

Win7でのシリアルポートに関しては
Arduino IDEでRaspberry Pi Pico:Win7でのUSB問題解決です
これでうまいこと行ってました。
ところが、ある日からドライブとして認識してくれないという
問題が発生。
それが、Philhower版で、スケッチを書き込めない
ということにつながっているようなのです。

どこかに解決の糸口があれば・・・

FTDIのUSB通信アダプタを挿してCOMポートがどんどん進む問題
は、この記事のコメントで教えてもらって解決したことがありました。

| | コメント (4)

2023年4月 4日 (火)

Arduino IDEでのラズピコ開発環境 Philhower版が正解でしょう

Arduino IDEでのラズピコ開発環境でうだうだ言ってましたが、
環境が変わってしまったようで、ボードマネージャーに出なく
なっていた「Earle F. Philhower, III」版。

「環境設定」にある
「追加のボードマネージャーのURL」が変わっていた
(誰が変えた?私でしょうなぁ)のが原因でした。
こんな具合に「earlepPhilhower」版のパッケージを
選んだら、出てきました。

Aa2_20230404103201

ボードマネージャーにPICOと入れたら出てくるように
Aa3_20230404103201

Philhower版だと、シリアル通信のバッファサイズも触れそうです。
ヘッダーファイルやソースを追いかけれそうな気がします。

Philhower版での「pins_arduino.h」の在処、これでしょ。
・・AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\3.1.0\variants\rpipico

ピン接続の位置、Mbed版とは異なっています。

// LEDs
#define PIN_LED (25u)

// Serial
#define PIN_SERIAL1_TX (0u)
#define PIN_SERIAL1_RX (1u)

#define PIN_SERIAL2_TX (8u)
#define PIN_SERIAL2_RX (9u)

// SPI
#define PIN_SPI0_MISO (16u)
#define PIN_SPI0_MOSI (19u)
#define PIN_SPI0_SCK (18u)
#define PIN_SPI0_SS (17u)

#define PIN_SPI1_MISO (12u)
#define PIN_SPI1_MOSI (15u)
#define PIN_SPI1_SCK (14u)
#define PIN_SPI1_SS (13u)

// Wire
#define PIN_WIRE0_SDA (4u)
#define PIN_WIRE0_SCL (5u)

#define PIN_WIRE1_SDA (26u)
#define PIN_WIRE1_SCL (27u)



| | コメント (1)

2023年4月 3日 (月)

ラズピコのピン:自由になりそうだけど定義で固定されている

Arduino IDEでのラズピコのI/Oピン、RP2040そのものの
ハードでは自由に割り振りできるようになっているんですが、
pins_arduino.h」でほぼ固定されています。

ラズピコユーザー、まずはこのファイルを確認しと
きましょう。 ざっと、こんな具合。

// LEDs  基板上のLED
#define PIN_LED   (25u)
#define LED_BUILTIN PIN_LED

// Analog pins アナログ入力
#define PIN_A0 (26u)
#define PIN_A1 (27u)
#define PIN_A2 (28u)
#define PIN_A3 (29u)

// Serial シリアル:定義はSerila1だけ
#define PIN_SERIAL_TX (0ul)
#define PIN_SERIAL_RX (1ul)

// SPI  SPIも固定
#define PIN_SPI_MISO (16u)
#define PIN_SPI_MOSI (19u)
#define PIN_SPI_SCK  (18u)
#define PIN_SPI_SS  (17u)

// Wire  I2Cも固定
#define PIN_WIRE_SDA (4u)
#define PIN_WIRE_SCL (5u)

汎用I/Oは、基本これ以外の場所を選んでという使い方に
なります。

残りの「Serial2SPI1I2C1」を使うには
どうすりゃいいの?
は、まだ調べ切れていません。

Serila2は「UART Serial2(4, 5, NC, NC);」で行けたけど。

※追記
ラズピコ基板の
  水魚堂さんの回路図エディタBSch3-V部品ライブラリ
ピン名称、ちょっと追記しました。
Rp1
左側がこれまでの。
真ん中が、Xサイズをちょい増やして、TX/RX、SPI、
I2C信号を追加。
空いているポートがわかりやすいかと。
右のは 秋月のAE-RP2040マイコンボード

ここからダウンロードしてください。
・BSch3V用パーツライブラり bsch3v_lib_230403.zip
この中の「SPECIAL.LB3」に入れてます。
ご自由にどうぞ。


※注記
これ、Arduino Mbed OS RP2040 Boads の環境での話。
Earle F. Philhower, III」版だとどうなるのか、
Arduino IDE、触ってみます。



| | コメント (2)

2023年3月30日 (木)

ラズピコで2chシリアル入出力のテスト

ラズベリーパイ・ピコのシリアル入力は二つ。(USBを除いて)
これを使って2ch入力のシリアルデータロガーを実現できたら
エエなぁっと、ごそごそしてます。

Arduino UNOベースでは1ch入力のは作ってあり、
現用中です。
  ・Arduino-UNO + SDカードでシリアルデータロガー 完成形 今度こそ
ニッケル水素電池の放電データなどはこれで
記録しています。

なぜ2ch入力のが欲しいかというと、あれこれ測定した
計測データの集計です。
例えば、温度や照度や電圧、電流。
センサー側はシリアルデータとして出力できるように作って
あるのですが、それらを集計するとき、別の装置が出すデータ
との結合に困っちゃうのです。

例えば、4ch入力アナログデータロガー
これも、アナログ値の記録とともに、外部からのシリアル
データを取り込めるようにしています。
 これが便利。
 シリアルデータの結合がロガー内で実現できちゃうのです。

あれこれ計っていると、2ch以上のシリアル入力を持っていて、
それをうまいことログできる装置が「いるぞ!」っというのが
お試しの理由です。

ラズピコは2つのシリアル通信機能を持てっています。
それを生かして、2chのログをできないかと試したのが
今回のゴソゴソです。

まずはこんな回路。
Ll1_20230330165801
  ↓ 左のピコ、裏返しはマズイぞと描き直しました
Ll51

手っ取り早くでっち上げた実物回路がこれ。
Ll00
ラズピコ基板が2枚。
GNDを共通にして、シリアルが2ch。

回路図左側のラズピコは、試しとなるシリアルデータを
出力するだけ。
1chは1秒おきに。 2chは乱数で送出周期を可変。

回路図右のラズピコはそれを受けて、USBに(PCに向けて)
出力するというテスト回路です。

ch1とch2の二つのデータを受けて集約して、USBに出力
するのです。
その集約方法、例えば・・・
Ll2_20230330165801
こんなモードを考えました。
こんな具合に、受信データをまとめます。
Ll3
mode0はそれぞれの受信データを別行にしてログ。

mode1は固定長のデータを1行にまとめて処理でき
るように。

mode2はデータの受信順序を確認できるように、
ch1を優先してch2は補助で。

Ll2_20230330165801

PCを使ってこれをするのは、USB通信アダプタをつないで
できるように、こんなソフトを作ってあります。
  ※これは仕事で!
Ll4

4chの入力まで対応しています。
通信があった日時情報とともにログします。
あちこちからやってくる通信データの内容確認、
整合性をチェックするのが目的です。

今回のは単純ログ。
受けた内容を取りこぼさずにログできればOKと。
その前段階のテストプログラムです。

 ・送信側
   ダウンロード - tx_data_2ch1.txt
 ・受信側
   ダウンロード - rx_data_2ch1.txt

これからもうちょい「身を付けて」(太らせて)
SDカードにログできるように手直しします。

もう一つ、こんなモードもいるかな。
ch1をマスター、ch2をスレーブに接続。
ch1がch2にコマンドを送って、ch2からの返答を
待つような通信だと、ch1の受信後、ch2を待って
から1行の電文にして出力。

mode0のように電文が別の行だと、後処理で
まとめなくてはなりません。
mode1のように1行が固定文字数だと、例えば
グラフ化のためGNUPLOTに食わすのも楽になります。

ATmega4809 だとシリアルが4本(40pin DIPだと3本)。
もっとチャンネルを増やせます。

それにしても、ラズピコの内部処理がつかみ切れません。
シリアル通信の割り込み、バッファを増やしたいんだけど、
・・・わからんまま。
  Arduino IDEで使ってる環境のせい?
  Earle F. Philhower, III 版だとどうだ?を
  調べるほうがエエかも。

| | コメント (0)

2023年3月29日 (水)

Arduino IDEでのラズピコ開発環境

Arduino IDEのボードマネージャーを
見たら、いつのまにやら「Earle F. Philhower, III」版
のが出てこなくなっています。

Pp11_20230329100701
ラズピコを触り始めた時は・・・出てきたような。
Arduino Mbed OS RP2040 Boads」というのだけに。
  ※下のは非推奨と

トラ技2022年5月号で、これをっと推奨されていた
「Earle F. Philhower, III」さんのはどこへ?

ラズピコ、USB以外のシリアル通信ポートが二つ
載っています。
Serial1とSerial2で行けるはずだったんですが、
今の環境だと、Serial2を使うのに
こんなおまじないが必要でした。
 UART Serial2(4, 5, NC, NC);  // そのままではSerial2が
            // 使えないのでピン番号指定を実行

シリアルの送受バッファの問題もあり、
ラズピコ、なかなかむつかしいです。

※追記
「Earle F. Philhower, III」版の設定が出なくなっていたの、
  「追加のボードマネージャーのURL」
が変わっていたのが原因でした。
設定し直したらちゃんと出現しました。


| | コメント (0)

2023年2月24日 (金)

ラズピコ analogWriteの誤差

ラズピコのanalogWriteで 1/255 ~ 254/255と
デューティ比を変えた時、出力されるH/Lパルス幅から
実測したデューティ比の差を示したのがこのグラフ。
設定値を1変化させた時の測定クロック数の差を書き
加えました。
Cap112

16MHzのクロック数で128(8μs)が続いた後、、
13あるいは14カウントごと96(6μs)
出現しています。

この13と14がどこから来るのか・・・
その推測です。

ピコのクロックは125MHz
analogWriteの周波数は500Hz。
PWMの分解能が255
  で、125e6 ÷ 500 ÷ 255 = 980.392

RP2040のPWM分周回路、最大が 1/255.9375。
  m・n/16で設定できます。

980.392は256を越えるので1/256すると 3.82966
整数部が 3 で 小数部が 0.82966
小数部は 1/16 単位なので
  0.82966 × 16 = 13.2745

「13」と「14」の間
こんな数字が出てきました。

元クロック周波数とPWM周波数、そして分解能から
求める分周比、そして最終的なパルス幅設定値の計算に
浮動小数点を使っているからかと推測できます。

ラズピコのPWM。やっぱしanalogWriteは捨てちゃえ #2
これ↑の手法、PWMの分解能とH/Lパルス数は整数と整数の
乗数で設定するので実パルスとの誤差は生じません。
その代わり、主クロックからPWMの周波数を計算するところで
誤差が生じます。

PWMでDACするなら(analogWriteを名乗るなら)、デューティ比
に誤差が出るのはあきません。

 

| | コメント (0)

2023年2月22日 (水)

ラズピコのPWM。やっぱしanalogWriteは捨てちゃえ #2

2023年2月21日:ラズピコのPWM。 やっぱしanalogWriteは捨てちゃえ
この続き。

ラジオペンチさんのコメント
  「せっかくだから analogWritePure なんて関数・・・」と
ありましたので、難しいことはせずにサクッとまとめてみました。
   ※サクッとで、エラーチェックや
    数値範囲チェックはしてません。

関数は2つ。

 int pwmStart(pin_size_t pin, int val, int range, int frq)
まず、これで
 分解能 range と 周波数 frq から、
val値に対する乗数を計算します。
 pinはPWM出力ピン番号。 valはPWM幅。

というのはピコのPWM、クロックが125MHzで分周器の最大が
8bitの256未満 (m・n/16の浮動小数点で設定できる)という
制限があるのです。

PWM周波数500Hzで8bit分解能だと分周比が976.56になって
しまい、256.0を越えてしまいます。
そこで、PWM幅を得るval値にmlt値を乗じるようにして、
分周比が256.0を越えないようにします。

PWM周波数1kHzで分解能が100だと分周比が1/250で、
PWM幅valへの乗数が5となります。
val値0でL、100でH。
1~99でデューティ1%~99%が出てきます。

pwmStartの返り値である乗数(mlt)を得たあとは、
この関数↓でPWM幅を出力。
 void pwmVal(pin_size_t pin, int val, int mlt)
浮動小数点計算が不要な分、処理が早くなります。

テストプログラムを走らせるとこんな感じ。
  USBで通信 出力ピンをオシロで観察

# Pico PWM Test #5 (2023-02-22) Entでタイトル出力
# PWM Port >22      出力ピン番号
# PWM Freq (500Hz) >1000 PWM周波数
# PWM Range (256) >100   分解能 0~100で
PWM:22 m:5 1/250.000   mltとclkdiv値

# PWM Data >10  10だとデューティ10%
10/100 10.000%
# PWM Data >99
99/100 99.000%
# PWM Data >45
45/100 45.000%
# PWM Data >33
33/100 33.000%

# PWM Data >  Entだけ入力で最初から
# PWM Port >
# PWM Port >19  出力を19ピンに
# PWM Freq (500Hz) >800  周波数を800Hzに
# PWM Range (256) >1000  分解能を1000に
PWM:19 m:1 1/156.250  mltとclkdivが確定

# PWM Data >120
120/1000 12.000%
# PWM Data >990
990/1000 99.000%
# PWM Data >10
10/1000 1.000%

# PWM Port >19
# PWM Freq (500Hz) >1200  1200Hz
# PWM Range (256) >4096  分解能12bitで
PWM:19 m:1 1/25.431  mltとclkdivが確定
# PWM Data >100
100/4096 2.441%
# PWM Data >4000
4000/4096 97.656%
# PWM Data >4095
4095/4096 99.976%
# PWM Data >4090
4090/4096 99.854%

1Hz単位でPWM周波数が設定できます。
PWM分解能も「2^n」だけでなく、100とか1000に
できるので、10進でPWMデューティを設定する時に
便利かと。
分解能が偶数だと、半値で1/2デューティが得られます。

※テストプログラム
  ・ダウンロード - pwm_serial_in5.txt

Arduino IDEの環境によってはコンパイルエラーが出るかも。

※ pwmStart() 実行時間
Pp1_20230222141401

※ pwmVal() 実行時間
Pp2_20230222141401



| | コメント (2)

2023年2月21日 (火)

ラズピコのPWM。 やっぱしanalogWriteは捨てちゃえ

2023年2月20日:ラズピコのPWM。 なんかおかしいような #2
この続き。

ここ↓で、PWMを使ったタイマー割り込みを試していました。
2022年4月12日:Arduino IDEでラズパイ・ピコ:1msタイマー割り込み
それの応用で500HzのPWMを確認してみます。
  ※analogWriteを捨てるための実験です

/****************************/
/* PWM出力 */
/****************************/
#include "pwm.h" // PWM処理に必要
// PWMデータ
int pwm_port; // PWMポート番号
int pwm_range = 256; // PWM レンジ 初期値は256
int pwm_data; // PWM設定値データ
/***** PWM出力 *****/
// pinに出力 valがPWM H区間 最大がrange
// val=0ならL出力 val=rangeならH出力
// ピコのクロックは125MHz
// val,rangeを10倍して処理
// set_clkdivは256.0未満 m・n/16で分周
// set_wrap,set_chan_levelはuint16_tなので65535がmax
void pwmWrite(pin_size_t pin, int val, int range)
{
uint sn; // slice number
gpio_set_function(pwm_port, GPIO_FUNC_PWM); // ポートはPWM出力で
sn = pwm_gpio_to_slice_num(pwm_port); // スライス番号を得る
pwm_set_clkdiv(sn, 97.66); // 1.28MHzに
pwm_set_wrap(sn, (10 * range) - 1); // 256で500Hz
pwm_set_chan_level(sn, (pwm_port & 1), 10 * val); // ch-A,ch-B
pwm_set_enabled(sn, true); // PWMスタート
}

グラフにすると、よく分かるかと。
   ※前のと同じスケールで
Cap110
   ※拡大
Cap111
へんな周期性は見えません。

「半値」のあたりはこんな具合。

・range = 255で
PWM発生  実測値   n/255で  実測値   差分
n 1/255 H H+L
126 255 15744 31864 49.412% 49.410% -0.002%
127 255 15870 31865 49.804% 49.804% -0.000%
128 255 15995 31865 50.196% 50.196% 0.000%
129 255 16120 31865 50.588% 50.588% 0.000%
130 255 16245 31865 50.980% 50.981% 0.000%

・range = 256で
PWM発生  実測値   n/255で  実測値   差分
n 1/256 H H+L
126 256 15745 31990 49.219% 49.219% -0.000%
127 256 15870 31990 49.609% 49.609% -0.000%
128 256 15995 31990 50.000% 50.000% 0.000%
129 256 16120 31990 50.391% 50.391% 0.000%
130 256 16245 31990 50.781% 50.781% 0.000%

実測値は16MHzのクロックでサンプリングしたHとLのパルス幅です。
128/255も128/256も期待値が出ています。

◆テストプログラム
  ・ダウンロード - pwm_serial_in4.txt

(.inoではなく.txtにしてます。 UTF-8Nエンコード)

| | コメント (3)

より以前の記事一覧