www.robowars.org

RoboWars Australia Forum Index -> Technical Chat

Homebuilt ESC for small motors


Post new topic   Reply to topic
  Author    Thread
Jolijar



Joined: 22 Feb 2013
Posts: 96
Location: Dekalb, IL


 Reply with quote  
Homebuilt ESC for small motors

I am working on making a speed controller for small robots. It works using the
Ti - 754410NE chipset which is a dual H-bridge capable of driving up to 1 Amp per side.

I am planning on using it to drive two of these motors
http://www.sciplus.com/p/MABUCHI-12VDC-SPROCKET-MOTOR_50259

to make a small wedge for me to chase with Death by 1000 cuts.

I am not an Electrical Engineer or a computer programmer so this is messy.

Right now I am researching about the programming and the hardware

TODO
1. make the code accept proportional control right now it is full on or off
2. find out exactly what the arduino amtel 328p chip needs to be stand alone or possibly use the attiny chipset
3. design a pcb for ease of construction and programming.

here is my code so far.

code:

/////////////////////////////////////////////////////////////////////
// Really messy rc code for tank style driving version 0.01        //
// by Jeffrey Olijar                                               //
// Now you know who to blame if it doesn't work.                   //
/////////////////////////////////////////////////////////////////////
 
 unsigned long Ch1;
 unsigned long Ch2;
 unsigned long Lch1; // Last good value for Ch 1
 unsigned long Lch2; // Last good value for Ch 2
 unsigned long Ich1; // Initial Value for Ch 1
 unsigned long Ich2; // Initial Value for Ch 2

 const int motor1Pin = 3;   
 const int motor2Pin = 4;   
 const int motor3Pin = 6;   
 const int motor4Pin = 5;   
 
void setup() {
  Serial.begin(9600);
  Serial.print ("Ready!");
  pinMode(10, INPUT); // Ch1
  pinMode(11, INPUT); // Ch2

  pinMode(motor1Pin, OUTPUT);
  pinMode(motor2Pin, OUTPUT);
  pinMode(motor3Pin, OUTPUT);
  pinMode(motor4Pin, OUTPUT);
 
  Ich1 = pulseIn(10, HIGH, 20000); // Read the pulse width of Ch1
  Ich2 = pulseIn(10, HIGH, 20000); // Read the pulse width of Ch2
 
  Lch1 = Ich1; // Sets the Last good value to the Initial value
  Lch2 = Ich2; // Sets the Last good value to the Initial value
 
  }

void loop() {
  Ch1 = pulseIn(10, HIGH, 20000); // Read the pulse width of Ch1
  if (Ch1 == 0) {Ch1 = Lch1;} else {Lch1 = Ch1;} 
  Ch2 = pulseIn(11, HIGH, 20000); // Read the pulse width of Ch2
  if (Ch2 == 0) {Ch2 = Lch2;} else {Lch2 = Ch2;}
 
  Serial.print ("Channel 1: ");
  Serial.print (Ch1);
  Serial.println("");
  Serial.print ("Channel 2: ");
  Serial.print (Ch2);
  Serial.println("");

  if(Ch2<1400) {
    Serial.println("Left");
    digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge low
    digitalWrite(motor2Pin, HIGH);  // set leg 2 of the H-bridge high
    digitalWrite(motor4Pin, HIGH);   // set leg 1 of the H-bridge low
    digitalWrite(motor3Pin, LOW);  // set leg 2 of the H-bridge high
    }
  else if(Ch2>1600) {
    Serial.println("Right");
    digitalWrite(motor1Pin, HIGH);   // set leg 1 of the H-bridge low
    digitalWrite(motor2Pin, LOW);  // set leg 2 of the H-bridge high
    digitalWrite(motor4Pin, LOW);   // set leg 1 of the H-bridge low
    digitalWrite(motor3Pin, HIGH);  // set leg 2 of the H-bridge high
    }
  else {
    if(Ch1<1400){
      Serial.println("Reverse");
      digitalWrite(motor1Pin, LOW);   // set leg 1 of the H-bridge low
      digitalWrite(motor2Pin, HIGH);  // set leg 2 of the H-bridge high
      digitalWrite(motor4Pin, LOW);   // set leg 1 of the H-bridge low
      digitalWrite(motor3Pin, HIGH);  // set leg 2 of the H-bridge high
      }
    else if (Ch1>1600) {
      Serial.println("Foreward");
      digitalWrite(motor1Pin, HIGH);  // set leg 1 of the H-bridge high
      digitalWrite(motor2Pin, LOW);   // set leg 2 of the H-bridge low
      digitalWrite(motor4Pin, HIGH);  // set leg 1 of the H-bridge high
      digitalWrite(motor3Pin, LOW);   // set leg 2 of the H-bridge low
      }
    else {
      Serial.println("Neutral");
      digitalWrite(motor1Pin, LOW);  // set leg 1 of the H-bridge high
      digitalWrite(motor2Pin, LOW);   // set leg 2 of the H-bridge low
      digitalWrite(motor3Pin, LOW);  // set leg 1 of the H-bridge high
      digitalWrite(motor4Pin, LOW);   // set leg 2 of the H-bridge low
      }
    }
//delay(1000);  //makes the console not as spammy.
}





So far I have it working with the small square slot car motors via usb
I need to go get a voltage regulator so I can use my lipo batteries to power it.

If anyone wants to help feel free to contribute.

Post Sat Mar 30, 2013 5:07 pm 
 View user's profile Send private message Visit poster's website
frogbiscuit



Joined: 26 Aug 2010
Posts: 82
Location: Wollongong


 Reply with quote  

The pulsestream needs to be converted from unipolar to bipolar. Sounds like you inhaled the unipolar ok, now just generate 2 PWM pulsestreams per channel with a microcontroller.

PCBs with DIP and double density surface mount chips are easy to home etch & solder. Quad density needs professional boards.

Post Sun Mar 31, 2013 9:37 pm 
 View user's profile Send private message
Jolijar



Joined: 22 Feb 2013
Posts: 96
Location: Dekalb, IL


 Reply with quote  

I saw how to control a motor with pwm for single direction using a transistor but if I hook up the pwm to both logic pins I don't see how it will work as one needs to be high and one needs to be low. they would need to pulse at the same time?


I plan on experimenting with the code now.


Here is the perf board many wires will be shorter once I get the software done it will all be on that single board.

I need to find some caps for the power regulator
I am planning on running the 328p with the on board 8mhz clock to bring the parts count down.

Post Mon Apr 01, 2013 8:44 am 
 View user's profile Send private message Visit poster's website
frogbiscuit



Joined: 26 Aug 2010
Posts: 82
Location: Wollongong


 Reply with quote  

I gotta say, for not being an electronics or computer guy, you sure pulled a lot o' stuff together. Good man.
The uController needs 6 digital lines. 2 to pull in the 2 axes of the radio and 4 out to the motors. Each of the 2 axes' signals needs to be re-chopped into 2 output lines. That's where logical thinking comes in. When the stick goes forward, one line is active and when the stick goes back then the other is active. One output goes to the top left & bottom right of the H, the other to the topright and bottom left.

Post Mon Apr 01, 2013 9:42 am 
 View user's profile Send private message
Jolijar



Joined: 22 Feb 2013
Posts: 96
Location: Dekalb, IL


 Reply with quote  

The one thing I am good at is research. I learn from what others have done and modify it for my use. I just discovered that I can just pulse the motor enable pin for speed control.

Now I need a way to convert the signal from the RX from 1000 to 2000
to 255 to -255 so I can control the speed... back to research. Smile

Post Mon Apr 01, 2013 10:05 am 
 View user's profile Send private message Visit poster's website
Jolijar



Joined: 22 Feb 2013
Posts: 96
Location: Dekalb, IL


 Reply with quote  

Okay so I found a library for Arduino called Halfbridge
and I figured out how to control the motors via PWM
Right now with the code below
CH1 controls one motor
CH2 controls the other motor

I need to figure out mixing then it should be good

code:

#include <HalfBridge.h>

int ch1;
int ch2;

int ch1speed;
int ch2speed;

Motor motors[2] = { Motor(10, 3, 5), Motor(11, 6, 9) };

void setup()
{
  pinMode(12, INPUT); // Set our input pins as such
  pinMode(13, INPUT);
  Serial.begin(9600);
  motors[0].init();
  motors[1].init();
}

void loop()
{
  ch1 = pulseIn(12, HIGH, 25000); // Read the pulse width of 
  ch2 = pulseIn(13, HIGH, 25000); // each channel
 
  ch1speed = map(ch1,1000,2000,-500,500);
  ch1speed = constrain(ch1speed, -255, 255);

  ch2speed = map(ch2, 1000,2000, -500, 500); //center over zero
  ch2speed = constrain(ch2speed, -255, 255); //only pass valid pwm values
                           
  Serial.print("ch1: "); //Serial debugging stuff
  Serial.println(ch1speed);

  Serial.print("ch2: "); //Serial debugging stuff
  Serial.println(ch2speed);

  Serial.println(); //Serial debugging stuff
 
 
  motors[0].setSpeed((ch1speed));
  motors[1].setSpeed((ch2speed));
  //delay(1000);
}


Post Mon Apr 01, 2013 12:42 pm 
 View user's profile Send private message Visit poster's website
Jolijar



Joined: 22 Feb 2013
Posts: 96
Location: Dekalb, IL


 Reply with quote  

And got it Smile

code:


#include <HalfBridge.h>

int ch1;
int ch2;

int ch1speed;
int ch2speed;
int ch1motor;
int ch2motor;

Motor motors[2] = { Motor(10, 3, 5), Motor(11, 6, 9) };

void setup()
{
  pinMode(12, INPUT); // Set our input pins as such
  pinMode(13, INPUT);
  Serial.begin(9600);
  motors[0].init();
  motors[1].init();
}

void loop()
{
  ch1 = pulseIn(12, HIGH, 25000); // Read the pulse width of 
  ch2 = pulseIn(13, HIGH, 25000); // each channel
 
  ch1speed = map(ch1,1000,2000,-500,500);
  ch1speed = constrain(ch1speed, -250, 250);

  ch2speed = map(ch2, 1000,2000, -500, 500); //center over zero
  ch2speed = constrain(ch2speed, -250, 250); //only pass valid pwm values
                           
  ch1motor = ch1speed + ch2speed;
  ch2motor = ch1speed - ch2speed;
 
  Serial.print("ch1: "); //Serial debugging stuff
  Serial.println(ch1motor);

  Serial.print("ch2: "); //Serial debugging stuff
  Serial.println(ch2motor);

  Serial.println(); //Serial debugging stuff
 
  motors[0].setSpeed((ch1motor));
  motors[1].setSpeed((ch2motor));
  delay(10);
}


Post Mon Apr 01, 2013 12:58 pm 
 View user's profile Send private message Visit poster's website
frogbiscuit



Joined: 26 Aug 2010
Posts: 82
Location: Wollongong


 Reply with quote  

Dewd! In your loins lie the seeds of destruction to lay waste legions of mediocrebots, and its not your machine that'll do it but your thinking.
Research this: position vs speed.

Post Tue Apr 02, 2013 4:51 am 
 View user's profile Send private message
Jolijar



Joined: 22 Feb 2013
Posts: 96
Location: Dekalb, IL


 Reply with quote  

Thanks for the encouragement. I'll look into that now.
I just ordered a new ATTINY84 and a 20mhz resonator to go with it. should be able to fit the entire controller on a 25mm chunk of perfboard.

Post Tue Apr 02, 2013 11:17 am 
 View user's profile Send private message Visit poster's website
Valen
Experienced Roboteer


Joined: 07 Jul 2004
Posts: 4436
Location: Sydney


 Reply with quote  

one small tip, look at "slew rate limiting" IE limit the rate at which you can change the speed/direction of the motor, it'll help prevent current spikes.
_________________
Mechanical engineers build weapons, civil engineers build targets

Post Tue Apr 02, 2013 12:15 pm 
 View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger ICQ Number
Jolijar



Joined: 22 Feb 2013
Posts: 96
Location: Dekalb, IL


 Reply with quote  

I finished the prototype. I don't have suitable wheels yet so I havent driven it around but it seems to be working great. I ended up using a larger chunk of perf board. When I design a version for PCB it will be much smaller.



Post Sat Apr 06, 2013 7:14 am 
 View user's profile Send private message Visit poster's website
Jaemus
Experienced Roboteer


Joined: 01 Apr 2009
Posts: 2674
Location: NSW


 Reply with quote  

Very cool, grab a video when its driving
_________________
<Patrician|Away> what does your robot do, sam
<bovril> it collects data about the surrounding environment, then discards it and drives into walls

Post Sat Apr 06, 2013 2:24 pm 
 View user's profile Send private message Send e-mail MSN Messenger
Jolijar



Joined: 22 Feb 2013
Posts: 96
Location: Dekalb, IL


 Reply with quote  

I took a break from this for awhile. I switched chipsets to a smaller smt chip that is available via sparkfun. It drives alright so far but I am a bit concerned about the failsafe in the program.

I have written a program that works with orange rx recievers however I am not sure it will work with others.

Right now my program looks at each channel and reads the value. If the value is outside of the normal range then it will failsafe. if the value is not outside the normal range then it does its normal function.

Does anyone know if there is a standard way that recievers failsafe?

Post Thu Nov 27, 2014 5:45 am 
 View user's profile Send private message Visit poster's website
Jolijar



Joined: 22 Feb 2013
Posts: 96
Location: Dekalb, IL


 Reply with quote  

Alright so fast forward 2 years and believe it or not I am still working on this.

I have a couple of prototypes built. They seem to work quite well so far. I am still working on getting the code the way I want it (it works but I am not 100% happy with the calibration routine) then I will be testing these with various motors to see exactly what they can handle. I believe that it will work for most beetleweight sized robots and smaller all for about the weight of a single plush 10 (that includes the receiver and the 2 channel esc board)

There is a video on my Hackaday io page if you guys want to check it out.


https://hackaday.io/project/12367-dual-rc-motor-driver-for-robotics

Post Sat Jul 23, 2016 7:12 am 
 View user's profile Send private message Visit poster's website
marto
Experienced Roboteer


Joined: 08 Jul 2004
Posts: 5459
Location: Brisbane, QLD


 Reply with quote  

Cool. Looks like it has developed into a nice little board.

Steve
_________________
Steven Martin
Twisted Constructions
http://www.botbitz.com

Post Sat Jul 23, 2016 9:48 am 
 View user's profile Send private message Send e-mail MSN Messenger
  Display posts from previous:      

Forum Jump:
Jump to:  

Post new topic   Reply to topic
Page 1 of 1


Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Last Thread | Next Thread  >
Powered by phpBB: © 2001 phpBB Group
millenniumFalcon Template By Vereor.