تحويل محرك عادي إلى محرك سيرفو برمجيا

تحويل المحرك العادي إلى محرك سيرفو

image001

توجد أنواع معروفة من المحركات الكهربائية، ولعل من أشهرها المحرك سيرفو. يقدم هذا المقال طريقة تحويل أي محرك عادي إلى محرك سيرفو بطريقة مبسطة.


تقديم

image002

المحرك سيرفو ليس مثل المحرك الخطوي. وبالتالي فهو يقوم بدوران في مجال محدد فقط. من أجل هذا يجب أن تحدد طول الذبذبة الرقمية ليتمكن المحرك من الدوران على راحته.

image003

 

 


ما نريد فعله

نريد تحويل محرك عادي إلى محرك يعمل عمل المحرك سيرفو.

image004


الأجزاء الرئيسية

 

العربية

الإنجليزية

الفرنسية

الكمية

القيمة أو الصيغة

يمكنك إيضا صناعته بنفسك

ميكروكنترولور

Microcontroller

Microcontrôleur

1

بطاقة أردوينو

image005اصنعها اليكترونيا – بطاقة أردوينو أونو

كنترولور المحرك

Motor Controller

Contrôleur de moteur

1

أيا كان، مثلا:

L298 Compact

image006

محرك عادي

DC motor

Moteur DC

1

أيا كان

image007

مقاومة متغيرة

Potentiometer

1

أيا كانت

image008

صندوق أتراس

Gear box

1

أيا كان بشرط أن يكون متلائما مع المحرك

 

 


الدارة الكهربائية

 

بالنسبة للدارة الكهربائية لهذا المشروع فهي سهلة جدا وهي كالآتي:

image009

في حقيقة الأمر، تظهر هذه الدارة طريقة مبسطة للتحكم بأي محرك عادي بتحريكه بسرعة محددة وتدويره نحو زاوية معينة. بالإستعانة بالمقاومة المتغيرة وبالميكروكنترولور أمكننا حينها بجعل المحرك يتحرك خلال 1024موضع في دورة واحدة حيث أن أقل زاوية للدوران هي 0.35درجة.

 


البرمجة

 

للمقاومة المتغيرة 3مرابط اثنين للطاقة والباقي هو مربط الإشارة. باستعمال الدالة analogReadومربط الإشارة يمكننا تحركي المحرك لـ 1024موضعا مختلفا خلال دورة واحدة فقط. يمكن استعمال الشيفرة التالية مع أي محرك DCعادي وتحويله إلى محرك سيرفو.

 

يمكنك تشغيل البرنامج Arduinoوتحويل الشيفرة التالية إلى بطاقة أردوينو لتبدأ العمل بمحركك كما هو موصوف. يمكنك تحميل الشيفرة التالية من خلال الضغط على الرابط: source.pde 

1 /*

2 

3    DIYServo 1.0

4     

5    Controller Motor Speed and Movement with Absolute Positioning

6     

7    A sketch for turning a standard DC gear motor into a servo

8    using a potentiometer.  Can also be used to add finer-grained

9    control over existing servos.

10     

11    Control over motor :

12        Speed (PWM)

13        Direction

14        Number of degrees to move (up to 1024) per move

15        How to long to wait between moves

16         

17    To get finer control (1024 degrees, instead of 360) of an existing

18    servo, remove the controller and any stop-pins, disconnect the

19    potentiometer wires.  Connect power lines from servo motor to a

20    DC motor controller, potentiometer wiper to an input pin on the arduino,

21    and the ouside potentiometer pins to 5v/GND. 

22     

23    Serial monitor:

24     

25        use 'l' to tell the servo to move left

26        use 'r' to tell the servo to move right

27        use 's' to stop the servo

28        use 'g' to go (run the servo)

29         

30         

31    (c) 2008 C. A. Church - www.dronecolony.com

32     

33    7/24/08 - initial version

34     

35 */

36 

37     

38      

39    // USING_CONTROLLER says whether we have to bring an

40    // enable pin high (such as for the Compact L298 controller)

41    // before sending PWM down the LT/RT pins

42    // set this to 0 if you don't need an enable pin

43     

44     

45 #define USING_CONTROLLER 1

46 

47    // enable pin

48 #define MOTOR_EN_PIN     8

49    // right direction pin

50 #define MOTOR_RT_PIN     6

51    // left direction pin

52 #define MOTOR_LT_PIN     9

53 

54 

55    // READ_AVG is how many readings to average

56    // set it to one less than the actual #

57    // e.g.: 10 readings = set to 9

58    //

59    // the more you average, the more accurate your reading is likely to

60    // be -- too many though, and you'll start missing changes if the motor

61    // is moving quickly

62     

63 #define READ_AVG       9

64 

65 

66 

67    // motor speed is from 0-255, test with low values

68    // as not all will move consistently for you

69     

70 int motor_speed    = 75;

71 

72    // how many ms to pause between allowed movements

73     

74 int motor_pause_tm = 1000;

75 

76    // how many 'degrees' (absolute differences between

77    // potentiometer readings) to move before pausing

78     

79 int motor_move_deg = 5;

80 

81    // a counter for how many degrees we have moved

82     

83 int move_deg_cnt   = 0;

84 

85    // setting to a default value

86     

87 int  motor_cur_pin = MOTOR_RT_PIN;

88 

89    // control indicators

90 bool motor_started = false;

91 bool motor_paused  = false;

92 bool first_run     = true;

93 bool motor_run     = false;

94 

95 long paused_tm;

96 

97 

98    // our current and previous potentiometer readings

99     

100 int cur_reading = 0;

101 int pre_reading = 0;

102 

103 int steps   = 0;

104 

105    // our current readings array, and our previous average readings array

106     

107 int vals[READ_AVG + 1];

108 int prev_posts[2]  = { 0, 0 };

109 

110     

111 

112 void setup() {

113     

114  Serial.begin(19200);

115  Serial.println("Ready");

116 

117  memset( (char *)vals, 0, sizeof(int) * (READ_AVG + 1) );

118 

119      // set motor control pins

120     

121  if( USING_CONTROLLER )

122      digitalWrite(MOTOR_EN_PIN, HIGH);

123   

124  digitalWrite(MOTOR_LT_PIN, LOW);

125  digitalWrite(MOTOR_RT_PIN, LOW);

126   

127 }

128 

129 void loop() {

130 

131    // see if any input has come in the serial port

132     

133   check_input();

134    

135       // figure out how many degrees we've moved (if at all)

136     

137   move_deg_cnt = move_deg_cnt + read_pot();

138    

139   if( motor_run == true ) {

140        // if the motor is supposed to be running

141 

142    // the following check is to prevent attempting to rotate all the

143    // way around on a potentiometer that has a stop.  If yours doesn't

144    // have a stop in it, ou can remove this check

145     

146     if( (motor_cur_pin == MOTOR_RT_PIN && prev_posts[1] >= 1020 ) ||

147         ( motor_cur_pin == MOTOR_LT_PIN && prev_posts[1] <= 3   ) ) {

148          

149         // we've reached our maximum point (don't want to harm our

150         // potentiometer

151          

152       motor_run     = false;

153       motor_started = false;

154       motor_paused  = false;

155        

156               // bring pin low

157         

158       digitalWrite(motor_cur_pin, LOW);

159        

160               // print status

161         

162       Serial.println("Have Reached Edge of Movement");

163     }

164     else if( motor_started == false ) {

165         // the motor is supposed to be running, but we haven't started

166         // it yet

167          

168         // PWM output

169          

170       analogWrite(motor_cur_pin, motor_speed);

171        

172                // set status values

173          

174       motor_started = true;

175       motor_paused  = false;

176       first_run     = true;

177     }

178     else if( move_deg_cnt >= motor_move_deg && motor_paused == false && first_run == false) {

179          

180         // we've gone our specific # of degrees, pause by stopping the

181         // motor

182          

183       Serial.println("Pausing");

184        

185       digitalWrite(motor_cur_pin, LOW);

186       motor_paused = true;

187        

188               // record when we started our pause (so we know when to stop)

189         

190       paused_tm     = millis();

191     }

192     else if( motor_paused == true && (millis() - paused_tm) > motor_pause_tm ) {

193          

194             // if enough time has passed to stop pausing

195         

196         Serial.println("Unpausing");

197         motor_paused = false;

198         paused_tm     = millis();

199          

200             // set move_deg_cnt to zero when re-starting to avoid any

201        // jitter while paused

202         

203         move_deg_cnt = 0;

204          

205             // generate PWM

206         analogWrite(motor_cur_pin, motor_speed);

207          

208     }

209   }

210 

211 }

212 

213 int read_pot() {

214 

215 //read the voltage on the potentiometer:

216  cur_reading = analogRead(0);

217  int diff = 0;

218 

219  

220      // we're going to average the last READ_AVG reads

221    // put in a value for our current step

222     

223  vals[steps] = cur_reading;

224  

225      // if we've saved enough values to go ahead and perform an average...

226     

227 if( steps == READ_AVG ) {

228      

229     // reset our read counter

230      

231   steps = -1;

232    

233       // determine the average value read

234    // -- this is mostly to deal with big jitter

235     

236   int tot = 0;

237   int avg = 0;

238    

239       // sum up totals

240     

241   for (int i = 0; i <= READ_AVG; i++)

242     tot += vals[i];

243    

244    

245   avg = tot / READ_AVG + 1;

246 

247       // ignore current reading if it was either of our last two readings

248    // avoid bouncing back and forth between two readings (slight voltage

249    // variation in the same range)

250     

251   if( avg == prev_posts[0] || avg == prev_posts[1] ) {

252      return(0);

253   }

254    

255       // determine the absolute difference between the current average

256    // and the previous average

257     

258   diff = avg > prev_posts[1] ? avg - prev_posts[1] : prev_posts[1] - avg;

259 

260    

261       // if there's a difference between the averages

262     

263   if( diff > 0 ) {

264        

265    // print our new reading

266        

267    Serial.println(avg, DEC);

268 

269      // move our last reading back, and put our current reading in

270    // our array to track the last two positions

271     

272    prev_posts[0] = prev_posts[1];

273    prev_posts[1] = avg;

274 

275    // update this so the pause check knows that we have changed a position

276    // (otherwise, starting in a position oher than 0 will mess up our

277    // pause check)

278     

279    first_run = false;

280   }

281 

282    

283 }

284 

285     // increment our saved value # for the next loop

286     

287 steps++;

288 

289    // return the difference recorded

290 return(diff);

291  

292  

293 }

294 

295   

296 void check_input() {

297  if ( Serial.available()) {

298    char ch = Serial.read();

299 

300    switch(ch) {       

301      case 'g':

302        Serial.println("Go - Running Motor");

303        motor_run = true;

304        digitalWrite(13, HIGH);

305        break;

306      case 's':

307        Serial.println("Stopping Motor");

308        motor_run = false;

309        motor_started = false;

310        analogWrite(motor_cur_pin, 0);

311        digitalWrite(13, LOW);

312        break;

313      case 'l':

314        motor_cur_pin = MOTOR_LT_PIN;

315        Serial.println("Direction = LEFT");

316        break;

317      case 'r':

318        motor_cur_pin = MOTOR_RT_PIN;

319        Serial.println("Direction = RIGHT");

320        break;

321    }

322  }

323 }

 


تأليف

 

المؤلف: Chris Church

الصفحة الشخصية: http://dronecolony.com/about-2/

ترجمة بتصرف: محمد السهلي 

 


المراجع

 

http://dronecolony.com/2008/07/24/diy-servo-with-arduino-dc-motor-and-potentiometer/


 

 

التعليقات   

 
# Guest 2015-05-19 01:54
قام المدير بحذف هذا التعليق
 
 
# Guest 2015-04-06 18:48
قام المدير بحذف هذا التعليق
 
 
# Guest 2015-03-20 13:54
قام المدير بحذف هذا التعليق
 

أضف تعليق


كود امني
تحديث


Go to top