PID control hardware?

This is for a college project, I'm not asking for help so much as advice. I need to write a PID algorithm and have it control an electromagnet. The only experience I have with this kind of stuff is C++ and arduino serial communications (with processing, not C++). Obviously the goal is to make the whole system as fast as possible, so could anybody recommend a programming language and hardware interface I might look into? Arduino on the whole seems a little slow, and I'm not  sure how fast the serial communications are or if something like USB might be better. Thanks in advance.

Question by alexhalford   |  last reply

pid control helicopter?

  hello i have digital potentiometer mcp1642 wichi have pid library setvalue on arduino which varry betwwen 0-256 and give resistance from 0-5k  and i connected it to remote control which has 400-4.2k ohm on manual resistance which 400 is max throttle and 4.2k is off motor and i have sonar sensore ez0 on helicopter thatread  atlitude by resoloution of inch and send to arduino and make i used to calculate error and then make pid control i make simple code but i start to tune p but i think i should start d , can any one help me how can i start to tune this   thing and is it true my scale in code i saw that at setvalue(111) helicopter hold good in sky so i decide to make it stable point which pid go around it  ,or maybe the problem is the sonar resoloution ..g? ecode #include #include "SPI.h" // necessary library int ss=53; // using digital pin 10 for SPI slave select int f=0; char *buffer; byte x; char array[27]; int counter=0; unsigned char r; int p=0; int last; int error=0; int wew; int required ; int kpipo; int n; void setup() {   pinMode(ss, OUTPUT); // we use this for SS pin   SPI.begin(); // wake up the SPI bus.   SPI.setBitOrder(MSBFIRST);    Serial.begin(9600);   Serial1.begin(9600); } void setValue(int value) {   digitalWrite(ss, LOW);   SPI.transfer(0); // send command byte   SPI.transfer(value); // send value (0~255)   digitalWrite(ss, HIGH); } void loop() {    while (Serial1.available()) {    x= Serial1.readBytes(buffer,1);    if(*buffer==0x52){    x= Serial1.readBytes(buffer,1);    array[0]=*buffer;    x= Serial1.readBytes(buffer,1);    array[1]=*buffer;    x= Serial1.readBytes(buffer,1);    array[2]=*buffer;    int Final_inch=(array[0]-48)*100 + (array[1]-48)*10 +(array[2]-48) ;   float Final_cm=Final_inch*2.54; //Serial.print(Final_inch); //Serial.println(" Inch "); if (f==0){ //Serial.println(" ana hoon ");   setValue(35);    } required = 50; error = required-Final_inch; Serial.print(error); Serial.println(" ana hoon "); p=abs(error); if(Final_inch == 21){    f=1;}    if(Final_inch == 22){    f=1;}    if(Final_inch == 23){   f=1;}      if(f==1){    Serial.println(" ana hnak "); if(error >0){     setValue(111-(error));}     if(error <0){     setValue(111+abs(error));}     }    }    } }

Question by britich   |  last reply

digital potentiometer pid?

Hello, i have digital potintiometer u/d fgive you 100 step for 10k ohm so 10k for 100 step, i use it as outpu of pid control that read the distance and set point of required distance and make p and i and d equation based on differance and summation i want to use that pid to altitude contol of helicopter ,the resistor that i change as output is connected to throttle when i increase to max(5k) it stop and min 1k it go ?max speed so  this work   code arduino **/ #include #include SoftwareSerial mySerial(52, 9,true); // RX, TX int f=0; char *buffer; byte x; char array[27]; int counter=0; unsigned char r; int p=0; int last; int error=0; int wew; int required ; int kpipo; int n; DigiPot pot(22,3,24); void setup() {    Serial.begin(9600);   mySerial.begin(9600); } void reading(){   mySerial.println(1); while (mySerial.available()) {    x= mySerial.readBytes(buffer,1);    if(*buffer==0x52){    x= mySerial.readBytes(buffer,1);    array[0]=*buffer;    x= mySerial.readBytes(buffer,1);    array[1]=*buffer;    x= mySerial.readBytes(buffer,1);    array[2]=*buffer;    } } delayMicroseconds(220); } void loop() {     if (f==0){   delay(600);}   f=1; reading();   int Final_inch=(array[0]-48)*100 + (array[1]-48)*10 +(array[2]-48) ;   float Final_cm=Final_inch*2.54;     Serial.print(Final_inch);   Serial.println(" Inch ");   //Serial.print(Final_cm);   //Serial.println(" cm "); required =29; error = required - Final_inch; //Serial.print(error); //Integral = Integral + Error; // accumulate the error integral //} //else { // Integral=0; // zero it if out of bounds //} kpipo=1; p =  (error * kpipo); // calc proportional term // I = //Integral*kI; // integral term //int D = (Last-Actual)*.1; // derivative term wew = (error/2) ;// scale Drive to be in the range 0-99 Serial.print(wew);//(wew) if (abs(wew)>400){    wew=0;} if ( wew >99) {  wew=99; } if (wew <-99) {  wew=-99; } n=abs(wew); if (wew < 0){ // Check which direction to go.     pot.increase(n);     delay(500);   } else { // depending on the sign of Error     pot.decrease(n);     delay(500); } last = Final_inch; // save current value for next time }

Question by britich   |  last reply

Need to know about drone PID in detail Answered

I would like to know more about PID. The math behind it, the calculations, the parameters, everything in detail. We know we can change the PID values on Mission Planner by observing the flight. That is what a customer does. But from a developer point of view I would like to know everything about drone PID.

Question by prash319   |  last reply

pid control motor using arduino

Hi forum I have problem i done my pid  code using arduino but the output value shows 0 or constant 250.Need your help,I attached the code. thank you

Topic by satya_82 

control dc motor using pid processing and arduino

Hi forum I done code for pid to control dc motor speed but the output value gives 0 or constant value 250 and the set point is still same 100.Hereby I attach the PID code.

Topic by satya_82   |  last reply

How do I integrate a PID temp controller into a microcontroller system?

I understand that most PID temp controllers have some sort of interface to change the set-point via buttons or similar controls but I want to control my set-point using a microcontroller(picaxe). I'm not looking to build or program PID control into my system I'm really only looking to integrate an existing system. any tips on how I might be able to achieve this?

Question by danjamesardoin   |  last reply

Is there a relay that uses a 110v trigger for a 12v output? Answered

I know that this is probably the most backwards way to do things (and yes, I know, probably extremely stupid [but I'm also new to relays..]) , but I am in the process of trying to make a heated platform for my RepRap (I have gen 6, thus the reason for this). I have a PID controller, and I have the board running off an ATX power supply. So, what I would like to know if there is a relay that can use the 110v the PID controller to turn on/off the power from the ATX to the heat bed.  Thanks in advance! 

Question by DoctorWoo   |  last reply

This arduino code does not work as expected, any help? there seems to be an issue with the digitalWrite function. Answered

Recently, I wanted to make a laboratory grade linear semi-precision power supply using an Arduino, LCD, some comparators, and MOSFETs. Idealistically, I want measurements to be 3 significant figures of precision (0.1% accuracy @ 30V), voltages as high as 30V, and max current of 10A. The power supply is most likely going to be just a single regulated output, maybe if I feel lucky I will make 2 regulated outputs once I get the darn Arduino code to work. The Arduino's job is to simply set and read the output voltage, and is not part of the control loop. That is what the comparators are for. (I learned the hard way that using the Arduino within the control loop just results in parasitic oscillations because the Arduino is a clocked device and can only self correct at timed intervals.) Anyway, below is the code. I made explanations of all portions of it as clear as possible, and I also give the wiring used for the LCD, 4 buttons, and analog inputs used to set and read the voltage and current. However, the issue arises when I upload the code, the setVI button does not work unless I press both it and the RS button at same time. I made the many of the integers display in the serial output to diagnosing easier hopefully. I can see the setVI integer and my dudd integer only goes HIGH when  either it and the RS buttons are pressed simultaneously, or when the RS butten is held down for a long enough time. However, as far as I am aware, nowhere in the code do I manipulate that code so setVI goes HIGH dependant on other buttons, so I am bewildered by this parasitic phenomenon. Is my Arduino MEGA broken? I had a similar problem in the past, where I had multiple analogRead statements It strangely seemed to factor in the outputs of other input pins. Anyway, here is the code. Maybe someone could upload it and tell me if it functions properly on their arduino? That would help me determine if it is indeed a software issue. (p.s. I use an Arduino ripoff called the Funduino, but it is not broken in any way, I don't think?) Any and all help would be greatly appreciated, thank you in advance, -Max-. p.s. To make the code below legible, please copy/paste it in an IDE or in notepad and convert it into a monospaced font, it will make it very easy to follow. //---------------------------------------------------------------------------------------------------------------// /* Arduino Software for lab power supply. Wireing guide:        **Wiring for 16x2 LCD:**       * LCD RS pin to digital pin 12       * LCD Enable pin to digital pin 11       * LCD D4 pin to digital pin 5       * LCD D5 pin to digital pin 4       * LCD D6 pin to digital pin 3       * LCD D7 pin to digital pin 2       * LCD R/W pin to ground       * 10K resistor:       * ends to +5V and ground       * wiper to LCD VO pin (pin 3)    **Wiring for buttons:**       * RS       button to pin 6  (as a digital input) -- Switches from reading read current/voltage values to setting those values, and Vice Versa.       * VIselect button to pin 7 (as a digital input) -- Switches to the 'set' mode and flips from setting the voltage to setting the current.       * UP       button to pin 8  (as a digital input) -- Increments the voltage or current up when in the 'set' mode.       * DOWN     button to pin 9  (as a digital input) -- Increments the voltage or current up when in the 'set' mode.    **Analog inputs/outputs:**       *A0   -- Measures a potential of a resistor divider that can output a voltage of 0-5V based on the 0-30V output this PSW capable of.       *A1   -- Measures the current flow through a resistor to measure current. (Some reason there seems to be a pulldown resistor on this pin, so the voltage does not float.)       *Vout -- This will be later implemented if I get a DAC, for the increased resolution. (1024 is just not enough in my opinion. At least 12 bits)       *Aout -- This will be later implemented if I get a DAC, for the increased resolution. (1024 is just not enough in my opinion. At least 12 bits) */ int UP    = 0;      // These are the 2 buttons used to incrementally int DOWN  = 0;      // step up or down the voltage on the output int RS = 0;         // These 2 buttons tell the LCD to either read out the voltage on the analog pins. (I plan to change this so it reads from a 14 bit ADC and writes int setVI = 0;      // the voltage output through a 14 (or 16 bit) bit ADC. I need 3 significant digits, or at least 0.1% accuracy. int dudd = 0;       // this dudd (dummy variable) is just here to prove that digitaslreading pin 7 works very weird! Any help on this? int preRS = 1;      // Anything with a "Pre" before it is simply what said integer/variable on the last loop. I use these to prevent a parasitic int presetVI = 1;   // oscillation of states that they control, so when a button is pressed, it will not jump between 2 states every cycle. int preUP    = 0; int preDOWN  = 0; float Aset = 0.00;  // I need these to be "floated" so I can set the exact value of these to 3 significant digits. float Vset = 0.00;  // Aset and Vset define what the output voltage *should* be, and are defined with the UP/DOWN buttons. int VIselection = 1;// this variable will invert when Aset button is pressed. Similar to the IVselect, this number will also invert int READorSET = 1;  // Bset button is pressed. This allows the mode to be changed from SET mode or the READ output mode, thus allowing                     // one to compare the output voltage and current to the set value, as well as set the output voltage and current. #include LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// initialize the library with the numbers of the interface pins void setup() { //-------------------------// I tried making diagnosting this thing easier by making all the important data availible in the serial monitor.   lcd.begin(16, 2);   Serial.begin(9600);   Serial.print("INPUTS         RS:           READorSET:       setVI & dudd:        VIselection:");   Serial.println(""); } void loop() {   float V = (30.00*analogRead(A0))/1024.00;   //These are what I use to read the voltage output of my power supply. I will have a voltage divider on the output,   float A = (15.000*analogRead(A1))/1024.000; //to limit the voltage range from 0-30V to 0-5V. Same concept goes for the current measurement.   int dudd  = digitalRead(7);//   RS    = digitalRead(6);//RS stands for "Read/set"   setVI = digitalRead(7);//VI is stands for "Current/Voltage set"   UP    = digitalRead(8);//UP is simply a button used to set voltage & current   DOWN  = digitalRead(9);//DOWN is simply a button used to set voltage & current     if(presetVI == LOW && setVI == HIGH){VIselection = -VIselection;}   if(preRS    == LOW && RS    == HIGH){READorSET   =   -READorSET;}     Serial.print("\t        ");  // prints an inital space.     Serial.print(RS);            // prints the RS reading. It should be '1' when pin 7 is HIGH.     Serial.print("\t        ");     Serial.print(READorSET);     // prints the READorSET reading. This should only change when the RS button is pressed.     Serial.print("\t        ");     Serial.print(setVI);         // prints the setVI reading. It should be '1' when pin 7 is HIGH.     Serial.print("\t");     Serial.print(dudd);         // prints the setVI reading. It should be '1' when pin 7 is HIGH.     Serial.print("\t        ");     Serial.println(VIselection); // prints the VIselection reading. This should only change when the setVI button is pressed.         //if(presetVI == LOW && setVI == HIGH && READorSET == 1) {READorSET = -READorSET; VIselect = -VIselect;}      // This line of code just makes so that when I need to go from the voltage read screen to      // the set mode, I can just press the VIselect button. It just makes things more intuitive, but could be      // causeing the error, so I nulled it. I also nulled it out another portion that will keep the voltage or      // current setting the same when using the VI buttton to select the set mode. (otherwise it has to be      // double pressed to return to, say, the current setting, if that is where you left off.)   if(UP == HIGH && DOWN == LOW && VIselection == -1){if(Aset <= 10.00) {Aset += 0.05;}}   if(DOWN == HIGH && UP == LOW && VIselection == -1){if(Aset >= 0.10) {Aset -= 0.05;}}     if(UP == HIGH && DOWN == LOW && VIselection == 1) {if(Vset <= 30.00) {Vset += 0.05;}}   if(DOWN == HIGH && UP == LOW && VIselection == 1) {if(Vset >= 0.05) {Vset -= 0.05;}}     if (RS == HIGH){digitalWrite(13, 1);}   if (RS == LOW){digitalWrite(13, 0);} //============================================================================================================//   if (READorSET == 1){      //this is the defualt screen, and shows the output voltage and current.     lcd.clear();              lcd.setCursor(0, 0);     lcd.print("VOLTAGE:");     lcd.setCursor(0, 1);     lcd.print("CURRENT:");     lcd.setCursor(10, 0);     lcd.print(V);     lcd.setCursor(15, 0);     lcd.print("V");     lcd.setCursor(10, 1);     lcd.print(A);     lcd.setCursor(15, 1);     lcd.print("A");   }   if (READorSET == -1){   // This is the portion of the code allowing me to set the current and voltage     lcd.clear();          // using the up/down buttons.       if (VIselection == -1){         lcd.setCursor(0, 0);         lcd.print("  SET CURRENT:");         lcd.setCursor(5, 1);         lcd.print(Aset);         lcd.print("A ");       }       if(VIselection == 1){         lcd.setCursor(0, 0);         lcd.print("  SET VOLTAGE:");         lcd.setCursor(5, 1);         lcd.print(Vset);         lcd.print("V ");       }   } //============================================================================================================//   presetVI = setVI; // At the end of each loop, the current variable settings that were used are set equal   preRS = RS;       // to the 'pre' versions of the code. This allows me to basically measure the when                     // the button is initially pressed, and/or released. Using this method with the delay()                     // function, however, is a bit buggy, but I did have it working well enough before. If you                     // tap the button too quickly. You almost have to hold it for a split second. If you                     // know a better, simpler way of doing this, please tell me, thank you.                       delay(80);        // The delay helps stabilize the reading on the LCD, but if it is too large, than the                     // refresh rate suffers, and the buttons respond slower. However, setting too low will                     // cause the reading on the display to change so rapidly, it is illegible. }

Question by -max-   |  last reply

how to read power level of battery? Answered

Hello i have battery on helicopter and i need to read power of this battery to use it in pid gain ,i read voltage using voltage divider and calculate it and i sense current before motors and calculate power, but i dont think this is working, can you help me for that?

Question by britich   |  last reply

plot serial data? Answered

Hello  i need to know how to plot serial data on computer , i have a data that comes from sonar sensor via xbeee to pin 19 rx on arduino mega , i can read those value but i need to plot it versus time and save its value  for pid results. i tried simplot and it work but it dosent save data, and im stuck on matlab and i couldnt make it work.

Question by adiga123   |  last reply

Why is my quadcopter toppling when i try to fly it?

I built a quad copter. I have done all the calibrations correctly (accel, compass, rc, esc). When I arm the drone, motors and propellers are spinning. But when i give more throttle to try to hover it, it doesnt fly upward steadily. Instead it lifts backwards and falls. Why is this happening? Should I change some PID setting?

Question by prash319   |  last reply

sys/time.h missing when compiling in MS VC++

I am trying to use opencv for my arduino robot. Here's the problem: when I try to compile?rebuild in VC++, it says that /* * The program used in the YouTube video * * This program allow to rotate a webcam to track an object. This is * done by using Arduino to control a servo motor. The communication * is done using a serial connection (through USB or native). * * To compile it under Linux (assuming OpenCV was previously installed): * *   g++ -O2 -W -Wall -lhighgui -o tracking * * See the documentation to get the Arduino program. * * Author: Frédéric Jolliton * Date: january 22, 2011 * Documentation: */ #include #include #include #include #include //-------- PID parameters -------- // See // These values must be chosen CAREFULLY. The strategy to find good // values is to set `ci' and `cd' to 0.0, then try to find a value of // `cp' that works the best (without too much oscillation) then, from // that, lower `cp' and increase `cd' until the system is able to // stalibilize more quickly. Increase `ci' if the system take time to // move to the target position. There are more complexes method to // find the "right" values. static double cp = 0.2; static double ci = 0.0; static double cd = 0.02; /* * Get the current time in seconds */ static double gettime() {   struct timeval tv;   gettimeofday(&tv;, 0);   return tv.tv_sec + tv.tv_usec / 1e6; } int main() {   CvCapture*          capture = cvCreateCameraCapture(0);   if (capture == 0) {     std::cerr << "Failed to open the camera.\n";     return 1;   }   /*    * Window to display the input image.    */   cvNamedWindow("RGB", CV_WINDOW_AUTOSIZE);   cvMoveWindow("RGB", 0, 0);   /*    * Window to display the mask (the selected part of the input image)    */   cvNamedWindow("Mask", CV_WINDOW_AUTOSIZE);   cvMoveWindow("Mask", 0, 505);   /*    * The settings window    */   cvNamedWindow("Settings", 0);   cvMoveWindow("Settings", 652, 505);   // The hue range to select.   int                 hue_level_start = 0;   int                 hue_level_stop = 12;   cvCreateTrackbar("Hue level (start)", "Settings", &hue;_level_start, 255, 0);   cvCreateTrackbar("Hue level (stop)", "Settings", &hue;_level_stop, 255, 0);   // The minimum saturation level.   int                 sat_level = 100;   cvCreateTrackbar("Saturation level", "Settings", &sat;_level, 255, 0);   // Target position.   int                 target = 320;   cvCreateTrackbar("Target", "Settings", &target;, 640, 0);   /*    * Window to display the tracking state    */   cvNamedWindow("Track", CV_WINDOW_AUTOSIZE);   cvMoveWindow("Track", 646, 0);   FILE*               serial = fopen("/dev/ttyACM0", "w");   if (serial == 0) {     printf("Failed to open serial port\n");   }   sleep(1);   IplImage*           chan1 = 0;   IplImage*           chan2 = 0;   IplImage*           chan3 = 0;   IplImage*           hsv = 0;   IplImage*           monitor = 0;   IplImage*           result = 0;   double              angle = 1500.0; // the position of the camera   int                 tcolor = 0; // target color - Used to switch to predefined hue levels.   double              last_time = 0.0; // last time we updated PID   int                 last_known_x = 320; // last known position of the target.   double              last_error = 0.0;   double              i = 0.0; // integral term (here because it is accumulating)   int                 last_sent_value = -1;   for (int n = 0;; ++n) {     //-------- Get the input image --------     IplImage*           frame = cvQueryFrame(capture);     if (frame == 0) break;     cvShowImage("RGB", frame);     //-------- Allocate images --------     if (hsv == 0) {       // Allocate images if it is the first iteration.       hsv     = cvCreateImage(cvGetSize(frame), 8, 3); // 8 bits, 3 channels       chan1   = cvCreateImage(cvGetSize(frame), 8, 1); // 8 bits, 1 channels       chan2   = cvCreateImage(cvGetSize(frame), 8, 1);       chan3   = cvCreateImage(cvGetSize(frame), 8, 1);       monitor = cvCreateImage(cvGetSize(frame), 8, 3);       result  = cvCreateImage(cvGetSize(frame), 8, 3);     }     //-------- Process the input image --------     cvCvtColor(frame, hsv, CV_BGR2HSV); // convert to HSV (Hue-Saturation-Value)     cvSplit(hsv, chan1, chan2, 0, 0); // extract Hue & Saturation     // Create a mask matching only the selected range of hue values.     if (hue_level_start <= hue_level_stop) {       cvInRangeS(chan1, cvScalar(hue_level_start), cvScalar(hue_level_stop), chan1);     } else {       cvInRangeS(chan1, cvScalar(hue_level_stop), cvScalar(hue_level_start), chan1);       cvSubRS(chan1, cvScalar(255), chan1);     }     // Create a mask matching only the selected saturation levels.     cvCmpS(chan2, sat_level, chan2, CV_CMP_GT); // Test Saturation     cvAnd(chan1, chan2, chan3); // Merge masks     cvErode(chan3, chan3, 0, 2); // Suppress noise     // Find the position (moment) of the selected regions.     CvMoments           moments;     cvMoments(chan3, &moments;, 1);     int                 r = sqrt(moments.m00);     int                 x = moments.m10/moments.m00;     int                 y = moments.m01/moments.m00;     //-------- Mask window --------     // blue = hue selection, green = saturation selection, red = selected regions     cvConvertScale(frame, monitor, .3, 0); // faded out input     cvSet(monitor, cvScalar(255, 0, 0), chan1); // blue overlay     cvSet(monitor, cvScalar(0, 255, 0), chan2); // green overlay     cvSet(monitor, cvScalar(0, 0, 255), chan3); // red overlay     if (x > 0 && y > 0) {       cvCircle(monitor, cvPoint(x, y), r, cvScalar(0, 0, 0), 4, CV_AA, 0);       cvCircle(monitor, cvPoint(x, y), r, cvScalar(255, 255, 255), 2, CV_AA, 0);     }     cvShowImage("Mask", monitor);     //-------- Tracking state --------     cvCopy(frame, result, 0); // input image     cvLine(result, cvPoint(target - 60, 0), cvPoint(target - 60, 480), cvScalar(0, 0, 0), 2);     cvLine(result, cvPoint(target, 0), cvPoint(target, 480), cvScalar(0, 0, 255), 3);     cvLine(result, cvPoint(target + 60, 0), cvPoint(target + 60, 480), cvScalar(0, 0, 0), 2);     if (x > 0 && y > 0) {       cvCircle(result, cvPoint(x, y), 10, cvScalar(0, 0, 0), 6, CV_AA, 0);       cvCircle(result, cvPoint(x, y), 10, cvScalar(0, 255, 255), 4, CV_AA, 0);     }     cvShowImage("Track", result);     //-------- Handle keyboard events --------     int key = cvWaitKey(33);     if (key == 27) break;     switch (key) {     case 'r':       // Reset the current position. This is used to check how fast       // the system can return to the correct position.       angle = 1500;       break;     case 't':       // Quickly switch to a different tracking color (red or blue)       tcolor = 1 - tcolor;       if (tcolor == 0) {         cvSetTrackbarPos("Hue level (start)", "Settings", 0);         cvSetTrackbarPos("Hue level (stop)", "Settings", 12);       } else {         cvSetTrackbarPos("Hue level (start)", "Settings", 109);         cvSetTrackbarPos("Hue level (stop)", "Settings", 116);       }       break;     default:       // ignore other keys.       break;     }     //-------- PID processing --------     // If the object is out of the window, use last known position to     // find it.     if (x < 0 || x > 640) {       x = 2.5 * (last_known_x - 320) + 320;     } else {       last_known_x = x;     }     double              time = gettime();     double              dt = time - last_time;     if (last_time == 0.0)       dt = 1.0;     last_time = time;     // the error we want to correct     double              error = x - target;     // the proportional term     double              p = error * cp;     // update the integral term     i += error * dt * ci;     // Clamp integral term     if (i > 30.0)       i = 30.0;     else if (i < -30.0)       i = -30.0;     // the derivative term     double              d = (error - last_error) / dt * cd;     last_error = error;     // the PID value     double              pid = p + i + d;     // Clamp PID     if (pid < -100)       pid = -100;     else if (pid > 100)       pid = 100;     // Update the position from the PID value.     angle += pid;     // Clamp angle     if (angle < 0)       angle = 0;     else if (angle > 2000)       angle = 2000;     printf("pos = %d, P = %f, I = %f, D = %f, angle = %f, dt = %f\n", x, p, i, d, angle, dt);     //-------- Send the position to Arduino --------     if (serial != 0) {       int                 current_value = angle;       // Send the new position if it changed since the last time.       if (current_value != last_sent_value) {         fprintf(serial, "%d\n", current_value);         printf("SENT %d\n", current_value);         last_sent_value = current_value;       }     }   }   cvReleaseCapture(&capture;); } Here's the problem, when i try to compile/rebuild, it says that 

Question by GraffikeL   |  last reply

What do I need to perform speed control of a 100W 12V DC motor using an Arduino?

I am planning to use PID control using an Arduino's PWM abilties. I have a 100W 12V DC brushed gearedmotor. I want to maintain speed at 40RPM with variable load. Can I use for instance normal L298 H-bridge circuitry or do I need relay circuitry that can handle the amperage? Any input would be appreciated.

Question by StefanNel   |  last reply

Replacement for this FET?

Okay... so long story short, i have this little transistor that i need the non-surface mounted version of. The part # is PHD3055E. I can only find the datasheet, And can't find it anywhere for sale. So i thought i'd come here and ask, Any ideas on what could replace this? Here's the datasheet in the google docs viewer.;;=en&gl;=us&pid;=bl&srcid;=ADGEESg3724yaKjv666t2rqjyyXVjvQp5HpfKIXr3723cJt4Y_bqPXypg_oySVo3Q9eOgiMBHIG4zDYsHVk73N0whYfHI3PTtv8kTeA_FzIxSWhNnkzgniEWSIQLls8aeQVgmyBDhZyI&sig;=AHIEtbRm4XdPQEc-wzTiPkqsGwSO1qblnA

Question by ReCreate 

Help for realising a linefollower tankbot

Hello, I want to realize a linefollowing tank bot. I got this following parts: - Arduino Mega 2560 - Arduino MotorShield Rev03 - Pololu QTR-8RC Array - Pololu RP5 Tankchassis (6V DC Motors) Now all parts are together and the code must be completed. Therefore I found a really nice PID-based tutorial for linefollower: I create a program, but after calibrating the sensors, the bot doesn't drive on the line. It makes no sense were it drives. Most time it do 90° turns and so on. Do you find a better solution for my code? [code] #include #include   /////////////////////////// // define constants   // /////////////////////////// #define AUTO_CALIB  false      // Autokalibrierung aktivieren #define DEBUG_ENABLE   true               // false=keine Serial Ausgaben #define NUM_SENSORS    8                  // Anzahl der verwendeten Sensoren #define TIMEOUT        2500               // waits for 2500 microseconds for sensor outputs to go low #define EMITTER_PIN    QTR_NO_EMITTER_PIN         // Default: kein Emitterpin definiert #define MOTOR_SPEED    100               // PWM Signal 0-255 (Basismotorgeschwindigkeit) #define MOTOR_MAX_SPEED 255       // PWM Signal für Maximalgeschwindigkeit #define KP     0.2                    // KP-Wert für PID Regler #define KD     5                     // KD-Wert für PID Regler ( Beachte: Kp < Kd) #define SERVO_PIN1  11       // PWM Ausgang für Servo1 #define SERVO_PIN2  12       // PWM Ausgang für Servo2 #define CALIB_LED   13       // LED Ausgang für Kalibrierungsphase ////////////////////////// // define variables     // ////////////////////////// // Zuweisung der Sensoren 0-7 an die digitalen IO's 22-29 QTRSensorsRC qtrrc((unsigned char[]) {22, 23, 24, 25, 26, 27, 28, 29}, NUM_SENSORS, TIMEOUT, EMITTER_PIN); unsigned int sensorValues[NUM_SENSORS]; int MotorLeftSpeed=3;                  // PWM pin for speed control left int MotorRightSpeed=11;                // PWM pin for speed control right int MotorLeftDirection=12;            // digital pin for direction control left int MotorRightDirection=13;            // digital pin for direction control right int MotorLeftBrake=9;                  // digital pin for brake control left int MotorRightBrake=8;                 // digital pin for brake control right int lastError = 0; ///////////////////// // Initialisierung // ///////////////////// void setup() {     // Initialisierung verschiedner IOs   pinMode(CALIB_LED, OUTPUT);    // Definiert LED Ausgang für Kalibierungsphase       // Initialisierung linker Motor   pinMode(MotorLeftDirection, OUTPUT);      // Definiert Ausgang für den linken Motor   pinMode(MotorLeftBrake, OUTPUT);          // Definiert Bremse für den linken Motor   pinMode(MotorLeftSpeed, OUTPUT);   // Definiert Geschwindigkeitsausgang für linken Motor   // Initialisierung rechter Motor   pinMode(MotorRightDirection, OUTPUT);     // Definiert Ausgang für den rechten Motor   pinMode(MotorRightBrake, OUTPUT);         // Definiert Bremse für den rechten Motor     // Initialisierung Servo Motoren   servo1.attach(SERVO_PIN1);     // Zuweisung PWM PIN für Servo1   servo2.attach(SERVO_PIN2);     // Zuweisung PWM PIN für Servo2   if (DEBUG_ENABLE)   {    Serial.begin(9600);    Serial.print("Debug Modus aktiviert:\n");     }     delay(500);     digitalWrite(CALIB_LED, HIGH);    // turn on Arduino's LED to indicate we are in calibration mode   for (int i = 0; i < 400; i++)   // make the calibration take about 10 seconds   {     qtrrc.calibrate();           // reads all sensors 10 times at 2500 us per read (i.e. ~25 ms per call)   } delay(20);      // The 20 ms delay in the calibration code is intended to make the routine take a reasonable amount of time.     digitalWrite(CALIB_LED, LOW);     // turn off Arduino's LED to indicate we are through with calibration       if (DEBUG_ENABLE)    {    // print the calibration minimum values measured when emitters were on       for (int i = 0; i < NUM_SENSORS; i++)    {   Serial.print(qtrrc.calibratedMinimumOn[i]);   Serial.print(' ');    }    Serial.println();       // print the calibration maximum values measured when emitters were on    for (int i = 0; i < NUM_SENSORS; i++)    {   Serial.print(qtrrc.calibratedMaximumOn[i]);   Serial.print(' ');    }    Serial.println();    Serial.println();   }   delay(1000);   } /////////////////// // Main Program  // /////////////////// void loop() {   // read calibrated sensor values and obtain a measure of the line position from 0 to 5000 // To get raw sensor values, call: //; instead of unsigned int position = qtrrc.readLine(sensorValues); // Variable positon zeigt die genaue Position (0-7000) an   unsigned int position = qtrrc.readLine(sensorValues); // get calibrated readings along with the line position, refer to the QTR Sensors Arduino Library for more details on line position. int error = position - 3500;  // 3500 is the desired position   if (DEBUG_ENABLE)   {    // print the sensor values as numbers from 0 to 1000, where 0 means maximum reflectance and    // 1000 means minimum reflectance, followed by the line position    for (unsigned char i = 0; i < NUM_SENSORS; i++)    {     Serial.print(sensorValues[i]);     Serial.print('\t');    }    Serial.print(position);    // comment this line out if you are using raw values   } int motorSpeed = KP * error + KD * (error - lastError); lastError = error; int rightMotorSpeed = MOTOR_SPEED + motorSpeed; int leftMotorSpeed  = MOTOR_SPEED - motorSpeed;     if (rightMotorSpeed > MOTOR_MAX_SPEED ) rightMotorSpeed = MOTOR_MAX_SPEED;    // Verhindert dass die Maximalgeschwindigkeit überschritten wird if (leftMotorSpeed > MOTOR_MAX_SPEED ) leftMotorSpeed  = MOTOR_MAX_SPEED;    // Verhindert dass die Maximalgeschwindigkeit überschritten wird if (rightMotorSpeed < 0) rightMotorSpeed  = 0;          // Verhindert einen negativen Geschwindigkeitswert if (leftMotorSpeed < 0) leftMotorSpeed   = 0;          // Verhindert einen negativen Geschwindigkeitswert   {   // Ansteuerung der Motoren durch PID Berechnung   digitalWrite(MotorRightBrake, LOW);     // Motorbremse rechts deaktivieren   digitalWrite(MotorLeftBrake, LOW);     // Motorbremse links deaktivieren   digitalWrite(MotorRightDirection, HIGH);   // Motor rechts im Uhrzeigersinn  --> fährt vorwärts   digitalWrite(MotorLeftDirection, LOW);    // Motor links gegen den Uhrzeigersinn  --> fährt vorwärts   analogWrite(MotorRightSpeed, rightMotorSpeed);  // Motorgeschwindigkeit rechts in Abhängigkeit des PID Reglers   analogWrite(MotorLeftSpeed, leftMotorSpeed);  // Motorgeschwindigkeit links in Abhängigkeit des PID Reglers }           } [/code]

Topic by julianpe   |  last reply

Guidance & Info about Quadcopter Project?

Greetings lads, I'm new in forum and since I made some research the past days I'd like to get some guidance about constructing & programming a Quadcopter from scratch since I'm completely new on a project like that. Quadcopter Frame: Thinking about to construct an aluminum 70cm diameter frame which will weight around 500g. What kind of motors should I get in order the frame with the board,motors etc. will be able to lift? Board: I'm thinking to use Arduino Uno or Raspberry Pi 2.0 ( With a little bit of research I made I conclude that Raspberry could make my life a little bit easier since you can add wifi on it. The quadcopter will be controlled via a pc/laptop through wifi). What can you suggest and why? ESC: As far as I've seen in most of similar projects people using ESCs in order to control the motors throttle. Can you avoid that, with programming PIDs that make the same job in order not to use more hardware? About PIDs and Code in General: Thinking about to simulate the whole project in Simulik, Matlab and somehow (if it's possible) to convert the Matlab Code into C++ and download it on the chip. What do you think about that? About the whole project: I'm trying to minmize the hardware as much as it's possible (use only 4x motors, the board with the chip on it, cables and probably some sensors) in order to minimize the total weight of construction and ofc the price. That's all for a start. I'm gladly waiting for your answers and ideas. Cheers  :)

Question by Gidovoskos   |  last reply

i would like to know is there way to make SATA/IDE To USB2.0 Adapter?

I have this old dvd burner and i would like to hock it to my laptop so i find this SATA/IDE To USB2.0 Adapter but because i dont live in USA i cant order it for my countrie that is why i would like to know if some one knows how to make one i see this adapter on this site thanks

Question by spywizard   |  last reply

How can I power 16 LED's with 2 AA batteries? What type of LED's do I need for this? Answered

I found a website that boasts a safety vest with 16 LED's powered by 2 AA batteries (see link at bottom). This confused me because I have a setup of 16 LED's in "series", but my setup requires 18v to operate. Is it the rating of my LED's? What "size" LED's do I need to get to minimize the voltage requirements?If you're curious, I set the LED's up for my daughters Power Wheels for headlights and tail lights.

Question by    |  last reply

quadcopter with kk board and arduino?

We are using a kk board 2.1.5 to control the  quad copter  and it works just fine.Well now we want to move a bit further and start making our own self stabilization algorithms based on slam algorithms . I want the public's opinion on using both the KK board (to auto stabilize ,don't want to mess around the PID  )  and adding a arduino duo in between the KK board and the receiver . So basically the idea is that the receiver signals are going to be altered using some mathematical functions to add features such as obstacle detection and avoidance  . My friend was rasing some doubts regarding this  as the signal input and pwm output might not be in sync Thanks in advance 

Question by cthaliyath   |  last reply

Do I need to write programme for multiwii nanowii?

Its probably a dumb question but I was just curious. I received my multiwii nanowii module today and I was going through some multiwii codes. I found out the multiwiiconfig.h code and the gui for that. And apparantly it gives you pitch, roll and yaw and everything that you need. Now my question is; if you just use that piece of code, is there any need to write a seperate code for simple balancing? Like I just want to achieve some simple quad-copter balancing. So do I need to create some PID code for that? or if I just use the multiwiiconfig.h, I can achieve the stabilty?

Question by Bam Boy   |  last reply

An structable that imitates and improves Wacom's Inkling

Hello all! Just surfing the web for some drawingtablets, that is where I found (duh! d'oh)Wacom Inkling;=9226&gm;=3 It looks cool, but: * I wonder if Wacom is "more compatible" with products they sell, in other words, buy Inkling buy other Wacom related products to make it compatible with each other. *Pen, pressure sensitive, but can you swap the inkleader with any you like? Especially(correct?) (I'm Dutch ;) ) the pen. When the ink has dried up, you don't want to buy another Wacom pen which takes ages to ship. It doesn't seem that hard to recreate something similar without my assumptive drawbacks. But is there a whizzkid that would like to make and instructable like this? Please? :) Regards Thomas

Topic by TT2   |  last reply

SUPER accurate servo?

I need to make a device that can move two small servos within 0.01 or less degree rotation (yes, degrees, not radians!).  Currently, everthing I've seen comes up greater than half a degree.  It must have position feedback (stepper without encoder won't work), and the whole thing must fit in a 1/2"x6" tube.  It only needs to move maybe 30-40oz-in, but will always have that load (so backlash isn't a huge issue, but still should be minimal).  A COTS device is best, but it can be homemade, preferably under $50 or so, maybe up to $100 max.  It doesn't need to move fast or continuously, maybe 90 in 0.5 seconds.  It will be run by a microcontroller with a lot of IO pins, and PID control.  Any ideas, products or anything would be great, Thanks in advance. 

Question by jduffy54   |  last reply

Arduino with NXT servo position won't stabilize?

I'm using the arduino PID and encoder libraries to run an NXT servo for position.  Problem is, it won't move quickly to where I want, or accurately, or without oscillating all at the same time (and never for accuracy).  I need it to go to exact encoder points with minimal oscillation or delay (I plan on using it in a delta bot.)  I know it's not the best motor for the job, but 1) I already have enough, it costs me nothing more, 2)they're very accurate, and I know they CAN be run just fine (the NXT itself works great).   I've looked on websites and stuff for tuning, but nothing I found works, because of the weirdness of the motor itself (which can start quickly, but takes up to 400 milliseconds to stop).  The best tuning parameters I found so far are 5.5, 15, 0.75 (P,I,D).     

Question by jduffy54   |  last reply

Making a lightstand from a mono pod?

Hello all,  This is my first time posting on instructables.  I've found and used so many great photogrpahy ideas on here I figured someone might be able to help me out with a little problem I'm trying to solve.   I got 5 of these:;=10440897&PID;=1225267&nm;_mc=AFC-C8Junction&cm;_mmc=AFC-C8Junction-_-cables-_-na-_-na&Item;=N82E16830997069 I got all 5 of them for $5 total because of a $30 giftcard I had.  They were on sale for $7 each.   I'm trying to figure a way I can use these as lightstands for my speedlights.  I've had the thought of building an X type base out of wood with a bolt coming up through the base of the monopod but I was thinking of trying to find somethign that would be a bit more portable an X I could fold down somehow but that would still support the monopod.   I'd be grateful for any ideas?

Topic by bentlax33   |  last reply

Having problems with Arduino code for Self Balancing Robot

Whenever I try to Compile this code arduino gives me this error E:\Balance Bot\BalanceBot2_PID_Control\BalanceBot2_PID_Control.ino: In function 'void setup()': BalanceBot2_PID_Control:38: error: 'class MPU6050' has no member named 'Initialise'    sensor1.Initialise();            ^ E:\Balance Bot\BalanceBot2_PID_Control\BalanceBot2_PID_Control.ino: In function 'void loop()': BalanceBot2_PID_Control:43: error: 'class MPU6050' has no member named 'Update'    sensor1.Update(); Now when I also include this library which contains GetGyroReading, GetAccelerometerReading etc variable it again give me the same error. I am pretty new to arduino programming and is trying out some PID controls. my_mpu_library: BOmotorpair library: Project I am following

Question by DanishA22   |  last reply

Smart amplifier design building blocks help? (making an amp w/ auto-volume adjust by controlling gain with running avg)

I am currently working on a simple headphone audio amp that automatically adjusts volume to my preference, regardless of what video I click on when it is plugged into a computer. I am tired of some video's being so quiet that I have to crank up the volume to overdrive to hear it, while other video's blast out sound and burst my eardrums. And of course when watching photonicinduction videos, he often can be hard to hear his voice at really low volume at like 12 at night when everyone is asleep, but then the sparks and hammers come into the picture, it is often too late to crank the volume back down, and thus makes your ears bleed or waking everyone up in the neighborhood! X-(. (Luckily he has included sound warnings, but I am lazy, and will engineer things that do the hard work of adjusting volume for me! :)   ) In a way, I understand that this will minimize the dynamic range, which I suppose hardcore "audiophiles" will go NUTS over me actually WANTING to do that, but none the less, That is what I want. My design currently is just a simple emitter follower with a NPN and PNP transistor is the class AB operation, and to minimize crossover distortion and give a definite gain, I have negative feedback op amp from the output of the totem pole transistor arrangement back to the inputs that feed the base of the low and high side transistor. (obviously, the transistors by themselves are low impedance output, (CV mode) and high impedance input, and have a gain of like 1.) Sorry, no schematics, but you capable of googling it if you want to see what I am describing. As it is, it works fine. HOWEVER, it does not do the automatic volume, or gain control. That is set in stone by a resistor divider network between the feedback and ground (the basic non inverting amp feedback config.) I do not want a fixed gain. I want a electrically adjustable gain. The thing I plan to use to do the automatic adjustment would be a peak detector on the input, which is probably going to be a simple diode and capacitor with a buffer, and a discharge resistor (or constant current drain) across the capacitor to gradually lower the max output, or possibly an integrating op amp that effectively takes a running average. The output of that needs to control GAIN of the primary amplifier, and I want to be able to control the PID of that thing, maybe by tuning the a LCR circuit, or what have you. It is all nice and analog, just the way I like it! :) If ONLY there was some magical (and common) component that I could control the resistance anywhere in the feedback loop, of with a given voltage w/ respect to ground... I was thinking of like a MOSFET, but I would have to deal with the non linearity of the input vs output impedance, which probably changes with respect to everything from the current flowing through the channel, the voltage relative to ground at the source, the temperature, the alignment of the planet's, what mood god is in, etc etc etc. That is too many factors for an open loop control on to model in discrete stuff! And digital potentiometers are out of the question since, well they are digital, I want an elegant simple solution, and the are $$ and difficult to deal with. They have so many requirements that need to be addressed.  I prefer a elegant discrete transistor circuit, but op amps and other basic building blocks are acceptable, (this thing I want to be built over a weekend with with jellybean parts from by junk bin.) if you happen to know of a specific audio chip that does this for me, please mention it, but I will probably not use it, but maybe analyze the internal circuitry and learn how it works.

Question by -max-   |  last reply

PSU design (major revisions): Transformer calculations help?

Recently I have attempting to design a proper dual-rail power supply that will allow me to set a voltage as low as +-1V up to +-30V in 0.1V increments at (hopefully) 3 significant digits (at least for the lower voltage settings). Anyway, this supply is also going to be current limited to up to 5A,again, it can be set to just about anything. I plan on using an Arduino micro-controller to set the output. In order to do this, I plan on using the analogWrite functions, or better yet, a legit DAC. There will be 4 outputs from the Arduino that will set the power supply output by applying a 0-5V voltage on the input of the 2 current limits and 2 voltage sets. (one for the negative rail, one for the positive). However, I have kept running into the same problem: how do I plan on driving this linear power supply with up to 200W*? My first idea was to use a a MOT, due to their high-power capabilities, and re wind the secondary with the right number of turns to achieve this output. However, I have heard that these transformers are not optimal for continuous running due to their poor and cheap design. (losses are very high). My second idea was to search around for a 250VA transformer. However, even until now, the VA rating confuses me. How does VA compare to W? I know this has something to due with reactive power, real power, and apparent power. However, I have no intuition of any of these 'powers.' How would I go about calculating the correct size transformer for the job, also, I am going to assume this linear power supply has the properties of a resistive load, since it is rectified and smoothed with a filter capacitor, so practically nothing should react with the AC power. (unless there is something more to the full-bridge rectifier setup I am considering.) This is when I came across unwound toroidal cores found on eBay for $25, the perfect price range! However, this has raised more questions! to start off, beyond turns ratio, I do not know now many turns I need for the AC side of things. I know intuitively and from experience, mains-frequency transformers do not work with only one (or even few) winding(s). I think this has to do with saturation, but I'm no expert by any means. and the inductive reactance of the transformer's primary. How do I calculate losses, inductance, and other important parameters of a homemade transformer like this? Things get very nasty when I look back at rewinding an old transformer. Now I have all these questions about inductive reactance, power, currents, magnetic flux and saturation, but also, about determining the original power rating of something like a very old small welding transformer or one from a large 10A car-battery charger. Is it possible to approximate the power by measuring the dimensions of the core? How close will this approximation be?  After getting frustrated with this, I considered alternative approaches. What if I purchased 2 ~20V ~6A SMPS (switch mode power supplies) connected them in series, and connect the center tap of my linear supply to the joining point between the 2 SWPS's? Would this be unstable and be bad for the SMPS if a load was connected between the 'outputs' of this new center tapped supply? Would any sort of balancing be required? Also, a bigger problem includes how this will be connected to my linear PSU design. With a low voltage @ high currents, I would be wasting a LOT of power, power that has to be dissipated away from the transistors. This heat can approach 200W, which is company unreasonable! Anyway, I would them have to either a switching preregulator, or modify the SMPS's so the voltage can be controlled easily and varied between, say, 3V to 20V. absolute accuracy is not required, close enough, and rest of my PSU should handle it. This becomes seemingly impractical too, and many other considerations need to be made. What should I do? what are the calculations and factors I need to know? i do not have an LCR meter to measure inductance, so trial and error is out. Does anyone here have experience at this? Help would be greatly appreciated! *The 200W figure was calculated by taking 40V, (What I believe would be a safe to allow some slack for +-5V voltage drop across my 2 shunts and transistors) and multiplying it to 5A of current for the maximum power output. ------------------------------------------------------------------------------------------------------------------- I have added an image of my current design, and I have modularized it the best I could. The YELLOW is all my current power-management circuitry. Currently just a transformer with many taps, going to a currently-undesigned switch box that will change the voltage on the output, which is then rectified and enters a filtering capacitor, finally entering the circuit.  The GREEN field is the voltage set. It is the most major part of the PID feedback loop, along with the ORANGE field. It works simply by feeding a voltage to the positive of a op amp configured as a comparator, and with negative feedback from the output. It then outputs a signal to the transistor, turning it either more ON, or more OFF depending on how the output voltage compares to the +Vset. The negative portion is largely the same, but the input voltage needs to be inverted so the output voltage is set negative properly. I was not able to use less than 2 op amps for this portion, unfortunately. The ORANGE field is current set. It works by measuring the voltage drop across the shunt resistor, and outputting a unity voltage that is referenced to ground, instead of to the positive rail. (It took me forever to finalize and perfect that!!!) Anyway, this voltage is then fed into a op-amp configured as a comparator to drive the transistor. The BLUE field is my switching regulation topology, which is controlled by both the ORANGE and GREEN fields. Do you like my use of diodes as a super-simple voltage or current selection switch? the op amp that outputs a lower voltage is the one that gets 'listened to' by the transistors. This way, current and voltage mode enable properly. This does add a small problem when it comes to powering the op amps, all of them have to be powered off of slightly higher voltages to swing the full range due to the voltage drops of those diodes. In the PINK field is simply a single-transistor solution to a constant current load. This allows the regulator to be regulated even at very low voltage set levels. This is why I am able to achieve a +-0.5V on the output (at least within LTspice) Finally, and most unimportantly, the light PURPLE fields have a simple ultra high-gain difference amplifiers that will detect if the output current and current set are the same, and turn On or OFF the respective LEDs. The green LEDs are voltage-mode indicators, and the red LEDs are to show when current-limiting mode comes on.

Question by -max-   |  last reply

Hack your Servo V1.00: Make a powerful linear actuator using a standard hobby Servo

Hack your Servo V1.00: Make a powerful linear actuator using a standard hobby Servo   Provided you have the tools and the servo you can built this for under a couple of bucks. The actuator extends with a rate of about 50mm/min. It is rather slow but very powerful. Watch my video at the end of the post where the small actuator lifts 10kg vertically.   Materials List Tools list   - hobby servo - standard hobby brass tubing             -OD: 4.0mm, ID: 3.4mm             -OD: 5.8mm, ID: 4.5mm - standard hobby styrene tubing                                                 -OD: 4.8mm, ID: 3.5mm - M4 studding - 2 x M5 washers - 2 x M4 nuts - 5 minute epoxy - cyanoacrylate - grease - multi-strand cables - heat-shrink tubing   - standard tools – screwdrivers, scalpel, files etc. - dremmel multi-tool with ceramic abrasive disk, or similar - hand-drill + 4.9mm + 2.5mm drill-bits - M3 tap - M4 tap - soldering iron - glue gun - small vice - small saw - sanding paper (relatively fine) - small flame torch Procedure - I will be giving instructions based on the dimensional parameters of the Hitec HS-300. The procedure remains the same for any type servo. I strongly recommend you read the whole post before you start. So lets make a start, shall we?   - Open your hobby servo, remove control electronics, feedback potentiometer and mechanical stop on the servo’s output gear.   - Solder new cables on the servo motor’s leads.   - Drill two 4.9mm holes on the servo case bottom cover. These should be located longitudinally along the centre line and 9.5 mm from each end (this applies on the Hitec HS-300 and is also true for many standard servos but depending on your servo type there might be differences). The M4 thread will come out from the servo body using one of these two so this hole must be located directly below the centre of rotation of the servo’s output gear. Be very careful since this alignment is very important! If you don’t get it right you might have to use a new servo! The more accurate you are, the longer your servo will endure. -  Measure the dimensions of the rotating shaft of the potentiometer on the servo’s original electronics – note the geometry in general. The shaft should be flattened right at the tip in order to prevent it from freely-rotating once inserted into the servo’s output gear.   - Take the M4 studding (M4 thread) pick one end and by using the dremmel and the abrasive wheel tool, replicate the tip of the servo’s potentiometer on that end. Start by decreasing the diameter of the thread, rotating it steadily by hand against the abrasive disk (normally to 3.5mm in diameter and at least 6mm in length). Try to think of your fingers as the chuck of a slow-turning lathe. Once the diameter of the thread is down to the pot’s shaft diameter, flatten the tip according to the potentiometer’s tip. The idea is that the thread must be inserted in the servo’s output gear in the same way the potentiometer did before. The better the fit the longer your servo will endure. - On the flat tip of the M4 thread, screw the two M4 nuts approximately 20mm down its length. Following that, insert the two M5 washers. - Insert the thread inside the servo and adjust the distance of the nuts and washers down the thread such that the servo case bottom cover closes properly and the motor rotates efficiently. Basically, you have to make sure that once the thread and the servo are assembled there is no pressure between the servo case bottom cover and the nut-washer assembly. Similarly, you have to make sure that once the thread and the servo are assembled there is no gap between the servo case bottom cover and the nut-washer assembly. Once again, the better the fit the more your linear actuator will endure.   - Once you find the optimum position carefully disassemble the servo, remove the washers from the thread and use a drop of cyanoacrylate on the side of the nut that was in contact with the washers in the assembly. Let the glue to settle for 5 minutes. Unscrew the second nut by 10mm towards the flat end of the thread, and prepare a small epoxy mix.   - Put the mix between the two nuts and screw the second nut back in place. Once in place also use some epoxy on the back of the second nut as well. Ideally you should sand all contacting areas before you apply the epoxy glue. Leave to settle for at least 6 hours (even if you use a 5 min epoxy). - Secure tightly the 4mm diameter brass tube onto a vice by flattening the mounting end and use the M4 tap VERY carefully tapping as deep as possible (at least 15mm). Using the dremmel cut 10mm out of the threaded part of the tube and then verify that the created thread runs along the whole length of the small threaded tube by screwing it onto an M4 screw. Keep the 4mm threaded tube on the screw for handling purposes. Apply a layer of solder on the outside surface. - Take the 5.8mm diameter brass tube pick one end and try to sand at least 5mm into the tube (on the inside). Mount the brass tubing on the vice without squishing it and apply a thin layer of solder on the inside.   - Ignite the flame torch, take the 4mm threaded tube (holding it by the screw) and move it on the soldered end of the 5.8mm diameter brass tube which should still be mounted on the vice. Using the flame torch heat-up both tubes and carefully insert the 4mm threaded tubing inside the 5.8mm tubing until is fully inside. Use a pair of pliers and insert the brass tube by holding the end of the screw that sticks out. Hold the threaded tube levelled inside the 5.8mm tube until the solder settles. If you do not have a flame torch use a candle, your soldering iron and your patience :). Remove the screw. The end result will be the cylinder of your linear actuator. - The cylinder length should be equal to: the actuator’s desired working length (stroke) + length of the 4mm threaded tube which is inside the 5.8mm tube + 10mm for the mounting hinge at the cylinder end.   - The thread length should be: the actuator’s desired working length (stroke) + length of threaded tube which is inside the 5.8mm tube + length of the thread which resides inside the servo casing, which is model-dependant.   - Take the non-threaded/non-soldered side of the cylinder and drill a 2.5mm hole through, 5mm from the tip. - Cover the entire length of the cylinder with heat-shrinking tube and cut-off any excess bits. The 2.5mm through holes made earlier on the non-threaded side of the cylinder are now covered. Use the drill again to expose them and tap them through, using the M3 tap. Screw a 20mm long M3 studding or simply cut-off the head of a 20mm long M3 screw. This will act as your cylinder mounting hinge.   - Take the 4.8mm styrene tubing and M4 tap it 10mm deep. Cut a small ring 5mm in length and screw it in the M4 thread fully, from the side of the nut that was in contact with the washers (long side of the M4 thread). This will act as bushing between the thread and the servo’s case bottom cover. Ideally you should use nylon, copper or metal bushing. - Secure the motor cables inside the servo casing using a glue-gun and use heat-shrinking tube to cover them. Assemble the servo including the thread, the styrene bushing and the washers.   - Screw-on the cylinder and you are good to go! Here is a video of the small actuator lifting 10kg For those of you that have watched my video on the MTR Rover     will understand where the idea of hacking the servo came from ;))   Soon we will be posting assembly instructions, code and schematics on how to modify a standard servo to get full PID speed and position control with 10-bit resolution over 360 degrees – continuous ;)     I look forward for your comments!    

Topic by Antonb   |  last reply