2022年10月14日金曜日

3Dプリンタ フィラメント接合器開発(2)Adruino PROGMEMなんだかなー

フィラメント接合器をつくろう!
↓フィラメントの切れ端がもったいない.

V6 hotendを流用してフィラメントを溶かすヒーターを作ります.温度制御はarduinoでやります.MEGA2560なんつう高価なPCBを使う気はないです.

サーミスタで温度を測定するArduino programが今回のお題です.

回路は、サーミスタを4700Ωで5Vプルアップし、ArduinoのADC A0へ接続するだけ.これはRamps1.4と同じ回路です.
サーミスタは、NTC 3590 100kと通称されるもので、25℃で100kΩです.こちらのpdfに-30~289℃までの温度vs抵抗値テーブルがあるので、そのテーブル全部をsourceに記述して温度表示に使います.

温度vs抵抗値テーブルのsource codeの最初だけコピペするとこんなかんじ.
volatile const float t[] PROGMEM ={-30,-29,-28,-27,-26,-25,-24,-23,...
volatile const float r[] PROGMEM ={1733.2,1630.408,1534.477,1444.903,...

このPROGMEMが曲者でした.

このテーブルの総サイズは5kBぐらいあるかと思うので、ArduinoのATMEGA328とかいうCPUの2kBしかないSRAMには展開できません.それゆえ「FLASHに置け」という意味のコンパイラオプションがPROGMEMです.

ここまでは別に問題は無かったのですが、参照時に問題あり.
r[i]みたく参照しても化けてて動きません.
Arduino IDEの処理系のバグかと思ってVS codeに変えても動きません.

解決しました.
PROGMEMに置いた例えばfloatを参照する場合は、こうしなくちゃいけないんだってさ.
 float rtable = pgm_read_float_near(r+i);
なんだよめんどくさい.
変数を置くセグメントがあっちかこっちかというだけじゃないの?
なのにさ、どうして参照するのにpgm_read_float_near(r+i)ってしなくちゃいけないのかねぇ?
しかも、r+iみたくポインタ引数じゃないとダメで、r[i]のような配列指定だとダメ.
まるでEEPROMの取扱いじゃんかといいたい.

そんなかったるい壁がありましたが、温度測定は無事出来ました.ライターで炙ったら温度上昇しましたし.

次はヒーターの制御へ.
これからFET買いに秋月電子へいきまーす.(手持ちでいいFETが無かった)

1へ    3へ

ーーーー
参考までに、温度測定のソースコードを貼っておくね.VS codeのsourceだけど、Arduino IDEでも動くと思うけど、知らんけど...

#include <Arduino.h>

volatile const float t[] PROGMEM ={-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289};

volatile const float r[] PROGMEM ={1733.2,1630.408,1534.477,1444.903,1361.22,1283,1209.327,1140.424,1075.949,1015.588,959.05,906.0117,856.2883,809.6506,765.8865,724.8,685.6507,648.8929,614.3649,581.9169,551.41,522.6908,495.6674,470.2286,446.2714,423.7,402.056,381.6658,362.4488,344.3301,327.24,311.0397,295.7506,281.3157,267.682,254.8,242.5827,231.0321,220.108,209.7724,199.99,190.5578,181.6319,173.1822,165.1804,157.6,150.4253,143.6234,137.1726,131.0528,125.245,119.6582,114.3559,109.3221,104.5415,100,95.8191,91.8392,88.0494,84.4395,81,77.6238,74.4091,71.3472,68.4301,65.65,62.9838,60.442,58.0181,55.706,53.5,51.3708,49.3391,47.3998,45.5483,43.78,42.0555,40.4092,38.8369,37.335,35.8999,34.616,33.3855,32.2059,31.0748,29.99,28.9053,27.866,26.87,25.9153,25,24.1099,23.2565,22.4381,21.6531,20.9,20.1741,19.4774,18.8087,18.1666,17.55,16.9459,16.3659,15.8089,15.2739,14.76,14.2813,13.8206,13.3774,12.9507,12.54,12.1347,11.7447,11.3694,11.008,10.66,10.3243,10.001,9.6895,9.3893,9.1,8.8171,8.5444,8.2816,8.0283,7.784,7.5538,7.3316,7.1172,6.91,6.71,6.5265,6.349,6.1772,6.0109,5.85,5.6832,5.5221,5.3663,5.2156,5.07,4.9291,4.7928,4.661,4.5334,4.41,4.2906,4.1751,4.0632,3.9549,3.85,3.741,3.6357,3.5338,3.4353,3.34,3.255,3.1726,3.0927,3.0152,2.94,2.8634,2.7893,2.7173,2.6476,2.58,2.5144,2.4507,2.389,2.3291,2.271,2.2135,2.1577,2.1035,2.051,2,1.9513,1.904,1.858,1.8134,1.77,1.7319,1.6947,1.6586,1.6233,1.589,1.552,1.516,1.4811,1.4471,1.414,1.3812,1.3494,1.3184,1.2883,1.259,1.2301,1.2019,1.1745,1.1479,1.122,1.0956,1.0699,1.0449,1.0206,0.997,0.9757,0.955,0.9348,0.9151,0.896,0.875,0.8547,0.8349,0.8157,0.797,0.7806,0.7646,0.749,0.7338,0.719,0.7029,0.6873,0.6721,0.6574,0.643,0.6302,0.6177,0.6055,0.5936,0.582,0.5717,0.5617,0.5519,0.5423,0.533,0.5225,0.5122,0.5022,0.4925,0.483,0.4733,0.4639,0.4547,0.4457,0.437,0.4284,0.42,0.4118,0.4038,0.396,0.3884,0.381,0.3739,0.3668,0.36,0.3533,0.3467,0.3403,0.3341,0.328,0.322,0.3161,0.3104,0.3048,0.2993,0.294,0.2888,0.2836,0.2786,0.2737,0.2689,0.2642,0.2596,0.2551,0.2507,0.2464,0.2422,0.238,0.234,0.23,0.2262,0.2223,0.2186,0.215,0.2114,0.2079,0.2045,0.2011,0.1978,0.1946,0.1914,0.1883,0.1853,0.1823,0.1794,0.1765,0.1737,0.171,0.1683,0.1656,0.163,0.1604,0.1579,0.1555,0.1531,0.1507,0.1484,0.1461,0.1439,0.1417,0.1396,0.1375,0.1354,0.1334,0.1314,0.1295,0.1275,0.1257,0.1238};

void setup() {
  Serial.begin(9600); // display to COM port
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  int sensorValue = analogRead(A0); // ADC port is A0
  float voltage = sensorValue * (5.0 / 1023.0); // 10bit ADC, max 5V
  Serial.println(voltage);
  Serial.println(sensorValue);
  // voltage = 5 * rth / ( rth + 4700)
  // voltage rth + voltage 4700 = 5 rth
  // 4700 voltage = (5-voltage) rth
  // 4700 voltage / ( 5 - voltage ) = rth
  float rth; // thermistor kohm
  rth = 4700 * voltage / ( 5 - voltage ) / 1000 ; // kohm
  Serial.println(rth);
  int i;
  for(i=0;i<320;i++){
    float rtable = pgm_read_float_near(r+i);
    if(rtable<rth) break;
    else  i++;
  }
  float ttable = pgm_read_float_near(t+i);
  Serial.println(ttable); // display temperature

  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on
  delay(100);         // wait for mSec
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off 
  delay(500);         // wait for mSec
}

0 件のコメント:

コメントを投稿