この例では、Arduinoを使用してFirgelliのフィードバックロッドアクチュエータからの信号を読み取り、これをロッドがどれだけ伸びたかの距離測定値に変換する方法を示します。このチュートリアルは、チュートリアルで説明されている原則に基づいています。Arduinoによるモータードライバーの速度制御」、続行する前にそのチュートリアルを確認することをお勧めします。
注:このチュートリアルは、基本的な電子原理、Arduinoハードウェアおよびソフトウェアに関する予備知識を前提としています。 Arduinoを初めて使用する場合は、GoogleおよびYouTubeの検索で利用できる多くの優れた初心者向けチュートリアルの1つから基本を学ぶことをお勧めします。カスタムアプリケーションのテクニカルサポートを提供するためのリソースがなく、これらの公開されているチュートリアル以外でデバッグ、編集、コードまたは配線図を提供しないことに注意してください。
コンポーネント
- フィードバックロッドリニアアクチュエータ
- 12V電源
- Arduino
- モータードライバー
- 外部ポテンショメータ(このチュートリアルの後半)
- 接続および圧着工具またははんだごてを作成するための電線
配線
位置を読み取るためのハードウェアとソフトウェアの概要
上記のように回路を組み立て、以下のコードをアップロードします。コードの16行目を特定のストローク長に変更する必要があります。現在、6インチのフィードバックロッドアクチュエータ用に設定されています。
このプログラムは、最初にアクチュエータを拡張および完全に収縮して、ポテンショメータからの最小および最大のアナログセンサーの読み取り値を見つけます(コードの27行目および28行目)。これが必要なのは、ポテンショメータの読み取り範囲が[0、1023]であるにもかかわらず、実際には、アクチュエータ内部のギア比によってポテンショメータが限界まで完全に回転できないため、この範囲が狭くなる可能性があるためです。
この最初の校正シーケンスに続いて、アクチュエータは連続的に伸縮し、リニアアクチュエータの現在の延長長さ(インチ単位)を表示するデータのストリームを出力します。
コード
https://gist.github.com/Will-Firgelli/8c78092ca850aa8a50ae36842b97150f/* Firgelli Automations
* Limited or no support: we do not have the resources for Arduino code support
*
* Program enables momentary direction control of actuator using push button
*/
#include <elapsedMillis.h>
elapsedMillis timeElapsed;
int RPWM = 10;
int LPWM = 11;
int sensorPin = A0;
int sensorVal;
int Speed=255;
float strokeLength = 6.0; //customize to your specific stroke length
float extensionLength;
int maxAnalogReading;
int minAnalogReading;
void setup() {
pinMode(RPWM, OUTPUT);
pinMode(LPWM, OUTPUT);
pinMode(sensorPin, INPUT);
Serial.begin(9600);
maxAnalogReading = moveToLimit(1);
minAnalogReading = moveToLimit(-1);
}
void loop(){
Serial.println("Extending...");
sensorVal = analogRead(sensorPin);
while(sensorVal < maxAnalogReading){
driveActuator(1, Speed);
displayOutput();
delay(20);
}
driveActuator(0, Speed);
delay(1000);
Serial.println("Retracting...");
sensorVal = analogRead(sensorPin);
while(sensorVal > minAnalogReading){
driveActuator(-1, Speed);
displayOutput();
delay(20);
}
driveActuator(0, Speed);
delay(1000);
}
int moveToLimit(int Direction){
int prevReading=0;
int currReading=0;
do{
prevReading = currReading;
driveActuator(Direction, Speed);
timeElapsed = 0;
while(timeElapsed < 200){ delay(1);} //keep moving until analog reading remains the same for 200ms
currReading = analogRead(sensorPin);
}while(prevReading != currReading);
return currReading;
}
float mapfloat(float x, float inputMin, float inputMax, float outputMin, float outputMax){
return (x-inputMin)*(outputMax - outputMin)/(inputMax - inputMin)+outputMin;
}
void displayOutput(){
sensorVal = analogRead(sensorPin);
extensionLength = mapfloat(sensorVal, float(minAnalogReading), float(maxAnalogReading), 0.0, strokeLength);
Serial.print("Analog Reading: ");
Serial.print(sensorVal);
Serial.print("\tActuator extension length: ");
Serial.print(extensionLength);
Serial.println(" inches");
}
void driveActuator(int Direction, int Speed){
switch(Direction){
case 1: //extension
analogWrite(RPWM, Speed);
analogWrite(LPWM, 0);
break;
case 0: //stopping
analogWrite(RPWM, 0);
analogWrite(LPWM, 0);
break;
case -1: //retraction
analogWrite(RPWM, 0);
analogWrite(LPWM, Speed);
break;
}
}
外部ポテンショメータを使用して位置を制御する
上記の例は、フィードバックロッドアクチュエータから読み取り値を取得する方法を示していますが、アクチュエータを特定の位置に移動したい場合、これをどのように行うのですか?次のセクションでは、アクチュエータの目的の設定値位置に対するユーザー入力として外部ポテンショメータを使用することにより、このような状況について説明します。実際には、この例を変更して、必要なフォームからユーザー入力を取得できます。
配線
位置制御のためのハードウェアとソフトウェアの概要
配線はこのチュートリアルの最初の部分とほぼ同じですが、外部ポテンショメータがアナログピンA1に接続されているだけです。
以下のプログラムは、外部ポテンショメータを介してユーザーが設定した位置に移動します。コードの18行目で、バッファー変数が設定されています。これは、後で36行目と39行目で使用されます。バッファー変数は、アクチュエーターの移動が停止する目的の設定値位置の周囲の範囲を示します。これは、2つのポテンショメーターに+/- 2単位で変動する傾向。そのため、バッファが含まれていない場合、アクチュエータは設定値の位置の周りで激しく振動します。これが実際に動作していることを確認するには、18行目のバッファーをゼロに設定します(アクチュエーターが損傷を引き起こす可能性があるため、長時間振動させないでください)。
コード
https://gist.github.com/Will-Firgelli/41ec87433f0aaa1abc33e79168076b3b/* Firgelli Automations
* Limited or no support: we do not have the resources for Arduino code support
*
* Program enables momentary direction control of actuator using push button
*/
#include <elapsedMillis.h>
elapsedMillis timeElapsed;
int RPWM = 10;
int LPWM = 11;
int sensorPin = A0;
int potPin = A1;
int potVal;
int sensorVal;
int Speed = 255;
int Buffer = 4;
int maxAnalogReading;
int minAnalogReading;
void setup() {
pinMode(RPWM, OUTPUT);
pinMode(LPWM, OUTPUT);
pinMode(sensorPin, INPUT);
pinMode(potPin, INPUT);
Serial.begin(9600);
maxAnalogReading = moveToLimit(1);
minAnalogReading = moveToLimit(-1);
}
void loop(){
potVal = map(analogRead(potPin), 0, 1023, minAnalogReading, maxAnalogReading);
sensorVal = analogRead(sensorPin);
if(potVal > (sensorVal+Buffer)){ //addition gives buffer to prevent actuator from rapidly vibrating due to noisy data inputs
driveActuator(1, Speed);
}
else if(potVal < (sensorVal-Buffer)){
driveActuator(-1, Speed);
}
else{
driveActuator(0, Speed);
}
Serial.print("Potentiometer Reading: ");
Serial.print(potVal);
Serial.print("\tActuator reading: ");
Serial.println(sensorVal);
delay(10);
}
int moveToLimit(int Direction){
int prevReading=0;
int currReading=0;
do{
prevReading = currReading;
driveActuator(Direction, Speed);
timeElapsed = 0;
while(timeElapsed < 200){ delay(1);} //keep moving until analog reading remains the same for 200ms
currReading = analogRead(sensorPin);
}while(prevReading != currReading);
return currReading;
}
void driveActuator(int Direction, int Speed){
switch(Direction){
case 1: //extension
analogWrite(RPWM, Speed);
analogWrite(LPWM, 0);
break;
case 0: //stopping
analogWrite(RPWM, 0);
analogWrite(LPWM, 0);
break;
case -1: //retraction
analogWrite(RPWM, 0);
analogWrite(LPWM, Speed);
break;
}
}