Arduino初心者熱烈大歓迎質問スレ part25
■ このスレッドは過去ログ倉庫に格納されています
~---~~-~~---~----~~-~-~~---~--~~~-~-~~-~-~~----~~~~~~~---~~~~-~--~~~------~~ -~--~~~--~---~-~~~~-~~--~-~~-~-~-~~-~-~-----~----~~-~--~~-~--~-~-~~~~~-~--~~ ~~-~~--~-~-~--~-~~~--~-~~~~--~~-~~-~---~--~-~~--~~-~---~~~~-~~~---~~---~---- --------~~~~~---~~-~~~--~~~---~-~~~~~~---~-~---~-~~-~-~~----~-~-~----~~~~~~~ -~--~--~--~~-------~-~~~~-~--~~~~~~-~~-~~--~~~~~~-~~~-~------~-~---~~-~-~~-- -~~~~~--~~~-~~~-~-~--~-----~~~--~~~-~~~~-~~---~~-~~--~------~~-~-~---~-~--~- -~~-~-~-~~~~~~-~--~~~~-----~~-~~~---~~-~--~---~~--~~----~-----~--~~-~~-~-~~~ ~~~---~-~~~-~~-~~~-~----~~~~----~~----~-~----~-~~~~-~--~~--~~~~-~-~-~~--~--- ~-------~---~--~-~-~~~--~~--~~~-~-~--~--~~~~~-~~~--~~--~--~~--~~~~~~-~-~~--- --~--~~~~~~--~~~~~~---~~~~~----~----~~~--~~~~~~--~-------~~~~--~~~~~-------- -~--~~-----~--~-~~~~~~~~~~~-~~~~-~~-~---~~--~-~--~~--~-~~--~~-~-------~~~--- ----~~--~-~~---~~~-~--~--~~-~~~~~~~~-~-~~-~~--~--~~-~~-----~-~---~-~~~~-~--- ~--~~-~-~~~--~-----~~----~~~----~-~-~~-~----~--~~~~---~~-~-~~~--~~~-~-~~~-~~ ~~-~-~~~-~~-~~~~-~-~---~~--------~---~~-~-~-~--~--~--~~~~~~--~~-~~-~~---~--~ ~~-~~~~~-~~~---~~------~~~~----~-~-~--~-~--~~-~-~~--~~-~~----~-~~-~~--~---~~ ~~---~~-~~~-----~-~--~~-~~--~~~~~---~-~-~~--~~~~--~~~--~~~-~~--~----~~---~-- ~----~--~~-~~~-~~~---~-----~~-~~--~-~~-~~-~~~~~-----~-~~~~~~~--~~--~----~--~ ~~-~~------~~~~~-~-~---~~~---~-~---~~-~-~~-~~---~-~-~~-~--~--~---~~-~~~~-~~- ~~~--~~-~~~--~~-~~--~~-~~---~-~~~-~~~~----~~------~~---~--~-~--~-~~--~-~-~~- ----~--~-~~~~--~-~-~--~--~~~-~~-~--~-~~-~~-~~-~-~~--~---~-~-~-~~~---~~~--~-~ ~--~~-~~-~-~---~~~~---~---~~~--~~----~-~~--~~~-~-~-~-~~-~-~-~~~~-~~-~-~----- -~~~~~~~~---~-~-~-~-~~------~~~~~----~-----~---~~-~~---~~~--~~~-~~~--~--~-~~ ~~~~---~~-~~--~~--~~~--~-----~----~-~~---~~-~~------~--~~~-~~-~-~-~~-~-~~~~~ ~-~-~-~--~-~~~~-~~---~-~~~~-~-~--~~----~~~~~~~-------~-~~-~~-~--~~~-----~~-- ~~---~--~~~~~--~--~-~~-~~~--~~-~~~~~---~-~~~~-----~-~-~-~~~-~-~------~~---~- ~-~~~~-~-~~~------~~~~-~-~~-------~---~-~~~~-~~----~---~-~~--~~~~----~~~-~~~ ~--~~~~-~-----~~-~~-----~-~-~~~~~-~-~--~~--~--~~~-~--~-~~~~~~~~~-~-~-------- ~---~---~-~-~~-~-~~~-~--~~~-~--~--~~-~-~--~~-~-~~-~~~~~--~-~~--~---~~----~-~ ~---~~~~~~-~-~~~-~-~~-~--~--~~--~~~~~~~---~--~--~-~~----~~~-----~~-~-~-~---- -~-~~--~~----~--~~-~--~~-----~~--~--~~~--~-~~~~---~-~~~-~~---~-~-~--~~-~~~~~ -~--~~-~--~--~--~--~~--~--~-~-~----~~~--~-~~~---~-~-~-~-~~~~~~-~---~~-~-~~~~ ~~~~---~--~~~--~----~~~~~~--~--~~-~-~~~~~-~---~-~~-~~-~-~-~--~-~-~-~--~----- --~-----~~--~~~-~-~~~--~~~-~--~--~---~~--~--~-~~--~~~~~---~~~--~~~-~-~~-~--~ ~~-~~-~~--~~-~~~-~--~-~~~----~~-~-~--~-~~-~~-~-~~-~----~--~--~~---~-~~-~-~-- -~~~-~--~-~~~----~-~~--~-~~--~~-~~--~-~~-~~--~~~~~-~~~-~--~---~~~--~----~--- ~~~--~----~----~~---~~-~~~~~----~-~~~-~~---~~~~~-~--~-~-~~-~~--~~-~--~---~~- -~--~~~---~-~~~~-~~~---~-~-~~~-~~-~~-~~~~--~~~~--~-~--~-~~----~~----~~------ ~~---~~~~~-~~----~~--~~-~-~-~~~--~~~----~~~~~~--~~--~--~------~---~~--~~~--~ -~---~~~~~--~~-~----~~---------~-~-~--~~-~-~~~-~~~~-~~~~~~----~--~-~-~--~~~~ ~~--~-~---~---~-~-~-~~-~-~~---~~--~---~-~---~~-~~-~-~~-~--~-~~-~~-~~~-~--~~~ -~-~~----~~~~~-~-~~-~---~~----~-~-~~-~-~-~--~~~-~-~~~--~-~~-~~---~~~-~-~---- ~-~--~-~---~--~~-~------~~-----~-~~~~-~-~-~---~-~~---~~~~-~~~~-~~~~~----~~~~ -~~~---~---~~~~~-~~--~-~-----~-~--~~~~~----~~~-~~--~-~~~--~~-~~~~~-~------~- -~-----~-~~~-~~~~-~~---~-~-~~~--~~~-~-~--~---~-~~--~~~---~-~-~~~-~-~--~~--~- ~-~~~--~~-~~~~~~--~-~-~~~--~-~-----~~~~-------~-------~~~--~~-~-~-~-~~-~-~~~ --~-~---~~-~~-~--~-~-~---~~--~--~----~--~~~~~----~-~-~-~-~-~~~~~~~~-~--~~-~~ -~-~~-~--~~--~-~~--------~-~~~~-~-~~~-~-----~-~~~~~~~---~-~~~~---~-~~~---~-~ -~-------~~~~-~~~-~~--~~~-----~-~~---~~-~~-~-~~-~---~~~~-~--~-~-~~-~--~--~~~ ~~-~-~~-~~~~-~~---~-----~~~--~~~-~-------~--~--~~-~~~---~~-~~~-~~--~~-~-~~-- -~---~--~--~---~~-~---~~--~-~~-~~-~~-----~~~---~~~--~~~----~~-~~~~~-~--~~~~~ 初心者です お願いします… 温度センサーから読み出した値の10回平均を出力したいです。 ネットで色々調べたのですがうまく行きません… 一番簡単な記述はどんな具合になりますでしょうか? スケッチは以下です void loop(){ int val = analogRead(A0); // 温度センサーの出力値を読み取る float volt = map(val, 0, 1023, 0, 5000); // センサの出力値を電圧に変換 float temp = map(volt, 300, 1600, -30, 100); // 電圧を温度に変換 この変換されたtempを10回取得してから10で割って、 Serial.print(temp-average);で出力したいです。 for文を使って色々と試してはみましたが… よろしくお願いします。 最初の1回目から9回目はどう扱うの? というか色々と試したとあるけど貼ってもらったほうが早いと覆うよ 書き方が悪かったようです 10回計測した平均値のみを取り出して出力したい…の誤りでした。 float total = 0; for(int i=0;i<10;i++){ val = analogRead(A0); // 温度センサーの出力値を読み取る volt = map(val, 0, 1023, 0, 5000); // センサの出力値を電圧に変換 temp = map(volt, 300, 1600, -30, 100); // 電圧を温度に変換 total += temp ; delay(適当に); } Serial.print(total/10); >>7 概略だけど、大域変数を宣言してsetup()で初期値を0にする 次にloop()内で局所変数の配列を宣言して、その配列[大域変数]に各回のセンサー値を代入しては、大域変数をインクリメントする これを大域変数が9になるまで繰り返し、配列[0]から[9]まで加算して10で割り、Serial.print()で出力して大域変数を0に戻す と言うのでは? >>8 どううまくないのか書かないと。 あとスケッチは全部書く。 各行の間にserial出力を入れてSerial Monitorで値を見る。 /* 温度センサーDS18B20で10回計測した平均 */ #include <DallasTemperature.h> OneWire oneWire(4); // 温度センサーのDATピン DallasTemperature sensors(&oneWire); float Tempdata[10]; // 取得データ列 int TempdataMax=0; // 取得データ数 int TempdataCnt=0; // リングバッファのポインタ void setup() { Serial.begin(9600); sensors.begin(); // 温度センサー初期化 } void loop() { sensors.requestTemperatures(); // 温度取得要求 188ms Tempdata[TempdataCnt]=sensors.getTempCByIndex(0); if (TempdataMax<10) TempdataMax++; float tmpavr=0; // 平均の算出 for (int i=0;i<TempdataMax;i++) tmpavr+=Tempdata[i]; tmpavr=tmpavr/TempdataMax; Serial.print("datacnt="); Serial.print(TempdataMax); Serial.print(" new="); Serial.print(Tempdata[TempdataCnt]); Serial.print(" average="); Serial.print(tmpavr); Serial.println(""); TempdataCnt=(TempdataCnt+1) % 10; delay(300); } インデント崩れると思うので CTRL+t で整形してちょ 配列組むとプログラムサイズが大きくなるから 単純に10回足して割る10ではどう? そうだね、移動平均を使えば1000個の平均も取れる 近似値になってしまうけど、ピーキーな値を取り除くなら有効 /* 温度センサーDS18B20で100回計測した擬似移動平均 */ #include <DallasTemperature.h> #define SAMPLE_COUNT 100 // サンプル数 OneWire oneWire(4); // 温度センサーのDATピン DallasTemperature sensors(&oneWire); float tmptotal; // 取得データの合計値 int TempdataMax = 0; // 取得データ数 void setup() { Serial.begin(9600); sensors.begin(); // 温度センサー初期化 } void loop() { float tmpavr; sensors.requestTemperatures(); // 温度取得要求 188ms float tmpnew = sensors.getTempCByIndex(0); if (TempdataMax < SAMPLE_COUNT) { TempdataMax++; tmptotal += tmpnew; } else { tmptotal = tmptotal / SAMPLE_COUNT * (SAMPLE_COUNT - 1) + tmpnew; } tmpavr = tmptotal / TempdataMax; Serial.print("datacnt="); Serial.print(TempdataMax); Serial.print(" new="); Serial.print(tmpnew); Serial.print(" average="); Serial.print(tmpavr); Serial.println(""); delay(300); } >>13 センサーの中には計測に0.7秒かかるのもあるから DS18B20を高精度12bitモードで使用した場合がそれなんだけど それだと7秒後に結果がでる 用途によるけどあまり実用的では無いよね おお!こんなにレスが… 徹夜で悩んでたので寝てしまっていました… >>10 さんのやり方で計測を20回にして少し精度の高い値を取れました ありがとうございます! >>13 さんもありがとうございます!こんな高度なコードは自分には まだ無理そうですが今後の為に保存しておきます。 他の皆さんもありがとうございました! 最終コードは以下のようになりました void setup() { Serial.begin(9600); void loop() { float total = 0; for (int i = 0; i < 20; i++){ int val = analogRead(A0); float volt = map(val, 0, 1023, 0, 5000); float temp = map(volt, 300, 1600, -30, 100); total += temp; delay(100); } Serial.println(total / 20); } 間違えました >>8 さんのやり方でうまく行きました >>12 さんのやり方はまだ自分には少しコードでしたの誤りです 他の回答くれた皆さんもありがとう! サンプルコードは少ないコードで解りやすく簡潔にが鉄則 Pro Microで、MsTimer2による割り込みで呼ばれた関数内でWireによるI2Cを行うと Wire.endTransmission実行時に固まり、PCとの接続もできなくなって RSTピンを2回GNDに落として接続と書き込みをし直さないといけなくなるんだけど WireとMsTimer2を一緒に使っちゃいけないとか何かある? このあとTimerOneも同時に別の目的で走らせようと思ってるんだけど・・・ >>20 サンキュー同じの見つけてた 確かにsei()を入れたら意図した動作をするようになった リファレンスにsei()とcli()が載ってないなあ どうしても必要な場合以外、通信の記述はメインループでやるように書くのが吉 割り込み処理中に別の割り込みの記述するとか 長い処理書くとか頭おかしいのか? 割り込み処理内にはフラグ立てるとか カウンターのインクリメント程度に留めて メイン側でフラグ見て処理すべきだろ 割り込み処理内に色んなことしてたら スタックの消費もバカにならんし デバッグもめんどくさいだろうに 初心者なんだからそんなもんだろ わけのわからんエラーが山のように出たり 場当たり対応して他の割り込みころしてたり 色々痛い目にあって成長してくもんだ 質問です! 3つの信号出力を持っているセンサーが2つあって、Arduinoへの入力は3本1系統しかないから、レールを切り替えるように手動で切り替えられるようにしたい。 ピンヘッダを考えたけど、もっと省スペースで済ませられる方法はある? スケッチの質問なんですが関数を作成した時、LOOPの前と後どちらに書いた方がいいとかありますか?色々とスケッチを見ていると決まりはないように見えるのですが気になっていまして。 前に書かないとエラーになった時あったな だからいつも前に書いてる >>28 暗黙の宣言、暗黙の関数宣言 とかでググってみてください。 Arduino IDEでは>>29 の言うように一時期あったけど、いまはどうでもいいみたい、好みで。 水温センサーをarduinoで利用したい。 amazonとかで買える汎用のセンサーをお湯とか使って何度でいくつの抵抗値か調べようと思ってる。 調べた特性をグラフにしてarduinoのアナログ入力で読み取る予定。そこで気になったんだけど、グラフが比例してれば、プログラムの対応は出来る。 もしグラフがしっかり比例していなかった場合は、どうプログラムを組めばいいのかな? どんなセンサー使うつもり? 熱電対でやったことあるけど誤算範囲でほぼ完璧にリニアだった。 補正すること自体を体験的にやってみたいなら別だけど意味無くね? >>33 普通にXYグラフ描くつもりでいい グラフ描くときに比例してるとこで区切って座標とって描くだろ? データとしてはその点の数だけのXY座標があるじゃん で、入力値がX座標のどこにあるか判別して その両側の2点を得る あとはmap命令で済むだろ >>33 温度センサーはDS18B20がオススメ 抵抗値や電圧じゃなくて温度がデジタルで読める 校正とかいらない 防水ステンレスキャップで延長コードついたのも200円くらい >>35 まだ調査してないから、リニアか分からないけど、車の社外水温メータpivotに付いてた水温センサーをそのまま使いたかったんだよ。 他の人が教えてくれたデジタルのセンサーでもいいんだけど、センサー先端のネジとかをどうやって作ればいいんだろう? >>36 この方法が自分の知識で今すぐ出来るやり方だと思う。変換テーブルはまだ使ったことないけど、勉強してみます。 ありがとう。 >>29 >>31 遅くなりましたがありがとうございます >>33 ExcelとかRで回帰分析して回帰式を用意するのが良いと思う。 プログラムは1次式ではなく、求めた回帰式を利用するだけなので簡単。 33が回帰式のモデルとなる式(2次式、3次式、etc)を用意する必要があるのと回帰分析の知識が必要。 ググればなんとかなるとは思う。 >>36 の書き方だとプログラムするのに誤解しちゃうかもな 両側の2点を得る、じゃなく分岐処理するだけでよい せいぜいグラフは3つの直線で済むだろう そうすると3つのmap命令を用意して あとは入力値で分岐処理、だな >>42 入力値で分岐して、その中のmap関数で数値を出すんですね。グラフの特性に合わせて分岐を増やせばいいのか・・・ なんとかやれそうです。 ありがとう! >>41 回帰分析をググったけど、まだarduinoにスケッチするとこまで行くのは難しそう。 みんなこんなすごいのを、さらっとやっちゃうんですか?スゴいです。 >>44 Arudinoでは回帰分析はしないよ。多分できなくはないけど大変だよ。 調べたサンプルの回帰分析はPCでして、読み取り値のxからyを推定する回帰式を作るんだよ。 33は比例と書いているけど、回帰分析ならば、1次式以外にも3次式とか対数式に近似する回帰式も作れるよ。 回帰式さえ作っちゃえば、Arudino側は回帰式に読み取り値xを入れれば、yが返ってくるので、読み取り値で条件分岐するとかが不要になるよ。 >>45 仕事の合間に回帰式を勉強してきました。重回帰分析じゃないんで、一次関数でいけるかな。式さえ出来れば関数作ってコールしてデータ入れれば結果が出せますね。式が出来るかなぁ。まずはグラフを作るか。テスターと温度計用意だね。 >>46 1次ならググるとExcelのデータ分析を利用する例がたくさん出るから頑張って。 最低でも10から20はサンプル必要だろうから、実際の特性調査の方が時間が掛かると思うよ。 折れ線グラフを扱う汎用的なのを作っておくといろいろ便利だよん みんな凄いなあ 初心者から見るとカッコいい〜 オレも頑張るぞっと pythonも少しやり始めたんだけど 分析してグラフ化はこっちに任せたほうが良さそうだね >>33 自分もDS18B20が楽で良いと思う。 ただ、校正はいらないけど個体毎の誤差は結構あるので、最初にまとめて温度とアドレス控えておいた方が良いかも。5個買って1℃位の差があったので、そこは補正してる。 技術的な質問じゃなくて、法律・倫理的な質問なんだけど、 LeonardとかでVIDやPIDを書き換えるのって違法になる? メーカーが金を出して所得した番号を使う時点で違法確定なのか、 販売はNGだが、個人ならokなレベルなのか、 それとも技適警察みたいにネット上では批判される程度のものなのか。 業界団体規格なので違法にはならんでしょう。USBx.x準拠とかうたったら優良錯誤で違法になるかもしれんけど。 Arduino UNOの回路をばくって、USB付きの目覚し時計を自作して売ったら、何か駄目な事ってある? >>54 基本的に回路に著作権はない arduinoに関してはarduinoと名乗らなければ問題ない 逆にarduinoの回路はavrにusbシリアルくっつけただけに過ぎないわけだが ブートローダーやusbシリアル変換に使ってるavrのファームは別な話になるけどね >>38 車載の水温センサーなんかは基本的にサーミスタでB特性の値から計算するのが普通だけどね 安いしただの抵抗だから耐久性も高いし必要十分な精度あるし 自作しようとするならネジに穴開けて埋め込むだけでいいし 昔の車なんかで見かけたのは精度いらなきゃ線1本で引き回しておしまい >>57 車載だと壊れにくくシンプルなの優先するだろうから ラジエターの冷却液の沸騰上限と凍結下限さえわかれば 途中の温度狂っててもなんでもいいのでは? CPUの内部温度もサーミスタですよね >>58 燃料の噴射量にも関わるので、あまり雑にはできない。 車内の水温計ならそんなレベル。 >>58 >CPUの内部温度もサーミスタですよね PN接合の順方向電圧を使います。 >>58 まぁ水温で何をするかというと燃料補正 水温が低いときの増量や水温上がってきたときの補正とか せいぜい10度単位とかだよ シリアルモニタのウインドウが表示されないのですが、どうすれば良いでしょうか。 ポート認識はしていて、(windowsタスクバーを見る限り)シリアルモニタ起動もしている様なのですが。 互換品のelegoo uno r3で、ソフトの再インストールはしました。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる