اهلا بك

الكاتب

مرحبا بكم

البحث فى المدونه

اشترك ليصلك كل جديد

احصل على كل جديد فى عالم التدوين لحظه بلحظه اشترك الان

الثلاثاء، 24 فبراير 2015

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

تحويل المحرك العادي إلى محرك سيرفو
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عادي وتحويله إلى محرك سيرفو.

/*
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 }

التعليقات
0 التعليقات

0 التعليقات:

إضغط هنا لإضافة تعليق

إرسال تعليق

Blogger Widgets