Arduinoでアナログメーターを動かす

Arduinoで0-5Vの電圧を出力して計器を動かす

ArduinoのPWMポートを利用することで、任意の電圧を出力することができます。ここでは、5Vを出力したときにフルスケールになるように対象計器の内部抵抗を調整済みであるものとします。調整方法はこちらを参考にしてください。

ソース設計その1

シリアル通信で速度情報を受け取って、0-5Vに変換して出力するスケッチのサンプルです。
速度情報として、シリアル通信(19200bps)で改行とともにArduinoに送信すると動作します。速度は1桁~3桁のどれでも可。
(例:12km/hの場合は[12]+改行, 110km/hの場合は[110]+改行)

char input[4]; // 文字列格納用
int i = 0; // 文字数のカウンタ
long in, out;

#define MAX 255 // フルスケール時のPWM出力値
#define MIN 0 // ゼロ時のPWM出力値
#define FS 120 // フルスケール時の速度

void setup() {
	pinMode(10, OUTPUT); // 10番ピンを出力に使用
	Serial.begin(19200);
}

void loop() {
	if (Serial.available()) {
		input[i] = Serial.read();

		if (input[i] == '\n') {
			if (i == 3) in = (input[0] - 48) * 100 + (input[1] - 48) * 10 + (input[2] - 48);
			if (i == 2) in = (input[0] - 48) * 10 + (input[1] - 48);
			if (i == 1) in = (input[0] - 48);

			out = in * (MAX-MIN) / FS + MIN;
			Serial.print(out);
			analogWrite(10, out);
			i = 0;
		}
		else {
			i++;
		}
	}
}

ソース設計その2

ソースその1は、電圧と速度が比例する場合に適用できますが、計器によっては目盛りの間隔が不均等な場合があります。
本ソースは、5km/h刻みで電圧を指定できるようにしたものです。
速度は1桁~4桁のどれでも可。4桁の場合は4桁目を小数点として扱います。
(例:12.3km/hの場合は[0123]+改行, 110.1km/hの場合は[1101]+改行)

char input[5];   // 文字列格納用
int i = 0;  // 文字数のカウンタ
int speed;

#define INTERP(xi,xi1,yi,yi1,x) (yi + ((( yi1 - yi ) * ( x - xi )) / ( xi1 - xi )))

const int ar[]={
0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,
0,5,13,23,34,45,55,66,77,88,99,110,122,133,145,156,167,178,189,199,210,220,231,243,255
};
// 上段が速度、下段が0-5Vを256段階に割った数値。実際の針の振れ方を見ながら書き換えてください。

void setup(){
	  pinMode(10, OUTPUT); // 10番ピンを出力に使用
	  Serial.begin(19200);
}

int interp1dim(const int x,const int*ar){
	  int i;
	  if(x<=ar[0]){ return ar[25]; }else if(x>=ar[25-1]){
	    return ar[25*2-1];
	  }  
	  for(i=1;i<25;i++){ if(ar[i]>=x) break;
	  }
	  return INTERP(ar[i-1],ar[i],ar[i+25-1],ar[i+25],x);
}
 
void loop() {
   if (Serial.available()) {
	    input[i] = Serial.read();

	    if (input[i] == '\n') {
		      if (i==4) speed = (input[0]-48)*100 + (input[1]-48)*10 + (input[2]-48)+ (input[3]-48)/10;
		      if (i==3) speed = (input[0]-48)*100 + (input[1]-48)*10 + (input[2]-48);
		      if (i==2) speed = (input[0]-48)*10 + (input[1]-48);
		      if (i==1) speed = (input[0]-48);
		      Serial.print(speed);
		      analogWrite(10, interp1dim(speed,ar));
		      i = 0;
	    }
	    else { i++; }
  }
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

*
*