Go Down

Topic: Adding a limit switch to stop a pwm motor code. (Read 4649 times) previous topic - next topic

ds2ktj

I think you are going about solving your problem the wrong way.  This RC ESC is PWM based you could easily use analogWrite to control the frequency of the pin without servicing it in a busy loop.  analogWrite is the perfect way to do this.  Test it out with a servo hooked up to one of the PWM pins.  The Servo library is way overkill for controlling one PWM (servo/esc) and a limit switch (or two).

IE (pseudocode - not tested or compiled but similar to something I have used for higher powered motor contro):

Code: [Select]

#define ESC_PWM_PIN 3 // The pin the ESC/SERVO is connected to
#define LIMIT_SW_PIN 2 // The Limit Switch Pin (INT0)
                                 // Limit switch connected to VDD through 10K pullup
                                 //                  PIN 2
                                 //           10K    |
                                 //     VDD---VVVV---+----o/  o--- GND

void motor_fwd () {
   // FORWARD FULL SPEED
   analogWrite(ESC_PWM_PIN,255)
}

void motor_rev() {
   // REVERSE FULL SPEED
   analogWrite(ESC_PWM_PIN, 0)
}

void motor_brk() {
   // SET BRAKE ON MOTOR  (you might need to tune this value where the brake is set on the ESC - and I know the castle has a configurable brake)
   analogWrite(ESC_PWM_PIN, 120);
}



void setup () {
  // Initialize the ESC PIN as an output and set the brake
  pinMode(ESC_PWM_PIN,OUTPUT);
  motor_brk();
  // INT0 - PIN2 - call motor_brk when the switch closes
  attachInterrupt(0,motor_brk,LOW);
}


bool limit_sw_state_last = 0;

void loop() {
bool limit_sw_state_cur = digitalRead(LIMIT_SW_PIN);

   // toggle direction versus limit sw state.
   if (limit_sw_state_cur == limit_sw_state_last) {
     // do nothing
   } elseif (limit_sw_state) {
    // limit switch pulled high
    motor_rev();
  } else {
    // limit switch pulled low
    motor_fwd();
  }

  limit_sw_state_last = limit_sw_state_cur;

}

}



AWOL

#16
Apr 13, 2011, 06:07 pm Last Edit: Apr 13, 2011, 06:11 pm by AWOL Reason: 1
Quote
This RC ESC is PWM based

The output may be, but the input is usually PPM.

Quote
The Servo library is way overkill for controlling one PWM (servo/esc)

That depends on much abuse your servo/ESC can withstand.

Hint: Arduino PWM a shade under 500Hz with poor resolution in the 5 to 10% duty cycle region,versus Servo library at 50Hz with very good resolution.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Chadwick

Hey thanks,

I'll let you know if that works. As of now I just have to fix the 11 errors I was getting. I think I was going at this the wrong way. I am kinda lost on this one, it was more than I expected!!

Yeah I will probably only run the motor for 30min or less. It is a 12,000 RPM motor even though it is geared down so I kinda don't need that speed, I'll definately be tweeking the code.  For errors see attached pictures. :~

WizenedEE

Put semicolons after every line that doesn't have an open bracket in it.

Also, for those saying to use the servo library: He's not using a servo.

Analogwrite is the way to go  8)

Also, I hope you're not trying to drive the motor directly, and are using some sort of transistor, or else you'll blow out that pin on the arduino.

zoomkat

Quote
Also, for those saying to use the servo library: He's not using a servo.
Analogwrite is the way to go 


The OP said he is using an RC ESC with the motor. Most of these ESCs are made to be conrolled via servo control pulses (PPM) so they can be plugged directly into the RC receivers with which they are normally used. Bottom line, the OP should have some idea of how the equipment he has works.
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

AWOL

@WizenedEE
Quote
Also, for those saying to use the servo library: He's not using a servo.

Analogwrite is the way to go 

Did you read the duty cycle and frequency from the OP's post?
It's between about 6 and 9% duty cycle at a little under 50Hz.


"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Chadwick

I have modified the code so it can now work with a castle link esc 160 amp or other ESC's.

1. Added the needed colons
2. ESC wouldn't work with 255 so changed forward to idle speed for testing is 130 and 180 for full speed.
3 Took off the reverse because the ESE is for planes only so If you have a car ESE that would work for you.

#define ESC_PWM_PIN 3 // The pin the ESC/SERVO is connected to
#define LIMIT_SW_PIN 2 // The Limit Switch Pin (INT0)
                                 // Limit switch connected to VDD through 10K pullup
                                 //                  PIN 2
                                 //           10K    |
                                 //     VDD---VVVV---+----o/  o--- GND

void motor_fwd () {;
   // FORWARD FULL SPEED
   analogWrite(ESC_PWM_PIN,180)
;}

void motor_brk() {;
   // SET BRAKE ON MOTOR  (you might need to tune this value where the brake is set on the ESC - and I know the castle has a configurable brake)
   analogWrite(ESC_PWM_PIN, 120);
;}



void setup () {
  // Initialize the ESC PIN as an output and set the brake
  pinMode(ESC_PWM_PIN,OUTPUT);
  motor_brk();
  // INT0 - PIN2 - call motor_brk when the switch closes
  attachInterrupt(0,motor_brk,LOW);
}


bool limit_sw_state_last = 0;

void loop() {;
bool limit_sw_state_cur = digitalRead(LIMIT_SW_PIN);

   // toggle direction versus limit sw state.
   if (limit_sw_state_cur == limit_sw_state_last) {
     // do nothing
  } else {;
    // limit switch pulled low
    motor_fwd();
  }

  limit_sw_state_last = limit_sw_state_cur;

}



-------> One question I have yet Is in this code the limit switch is needed to be clicked once to run then hold the limit switch in manually, and the limit switch twice and it causes a brake/stop. I have to hold down the limit switch to brake and once released the motor begins running.

What I am trying to do is to make it so the arduino once powered on runs the code and motor running if the limit switch is clicked that the switch acts like a latched switch and holds the brake without me holding down the switch. I tried digital write and I am still learning how to write code. Other than that the code works great. To power on the arduino, I would just power it on with another switch.

Any help would be apreciated Thanks!!

PaulS

Code: [Select]
void motor_fwd () {;
   // FORWARD FULL SPEED
   analogWrite(ESC_PWM_PIN,180)
;}

If you are not yet at the point in your learning of C/C++ that you know where ; belong, and where they do not, I think you need to put the Arduino away for a while, and concentrate on learning the language.

Quote
1. Added the needed colons

C uses very few colons. Semicolons, on the other hand, are used in a lot more places, but no where near as many as you are indiscriminately sprinkling them.

Quote
2. ESC wouldn't work with 255 so changed forward to idle speed for testing is 130 and 180 for full speed.

What happened why you tried? An ESC typically has a range of values, similar to a servo, that it moves to. Why are you PWMing an ESC anyway? Typically, they are driven using the Servo library?

Quote
3 Took off the reverse because the ESE is for planes only so If you have a car ESE that would work for you.

What's an ESE? Why are you removing functionality that others might need?

Chadwick

It is ESC. It is a motor controller used for airplanes. I'm sure you could have figured that one out. I'm using it for a project that is light weight so that is why I chose it. As for the semicolons the first code above didn't work with out them, and debugging it that is where arduino said the semicolons needed to go. As I said I am fairly new at this, but doesn't mean I should give up. I already am achieving what I came to achieve, and that is to make a ESC brake with a limit switch in a certain way. If people want the original code it is above. And if you come on here to criticize then you need to get a day job. :P 

AWOL

#24
Jun 06, 2011, 03:50 pm Last Edit: Jun 06, 2011, 03:55 pm by AWOL Reason: 1
Quote
analogWrite(ESC_PWM_PIN,180)

How many more times do we need to tell you not to use analogWrite?

Quote
As for the semicolons the first code above didn't work with out them, and debugging it that is where arduino said the semicolons needed to go.

There are plenty of C examples available, and I've never seen this
Code: [Select]
void motor_fwd () {;
  // FORWARD FULL SPEED
  analogWrite(ESC_PWM_PIN,180)
;}

as an example of semicolon usage before.
The first semicolon is an empty statement and doesn't need to be there. The second belongs at the end of the analogWrite statement, not on the next line.

(And before anyone jumps in, yes, I know the compiler doesn't care which line the semicolon goes on or whether or not an empty statement is there, but the next poor sod who has to read it might)
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Chadwick

The funny thing is that the arduino took it with all the semicolons. If it works than it works for me. Your right I should use analog write I meant to put that instead. But back to my problem after the first click of the limit switch the motor runs and then have to hold the switch in to brake. What I was trying to do is make it so that the second click of the switch that it locks the brakes instead of me holding the switch. The rest of the code works great. One thing that I had no idea is that the ESC needed to be told to brake were I had origanially thought that it senses not input and then brakes, but that is why the 120 sent to the ESE, so I understand that after seeing the code.

PaulS

Quote
How many more times do we need to tell you not to use analogWrite?

Quote
Your right I should use analog write I meant to put that instead. But back to my problem

The problem seems to one of reading comprehension.

AWOL

Quote
Your right I should use analog write

NO you should use Servo.write.

Quote
The funny thing is that the arduino took it with all the semicolons. If it works than it works for me.

As I said, the compiler doesn't care how much whitespace exists between the end of a statement and the semicolon, so long as the statement is lexically correct.
However, the next person who reads your code may decide that your eccentric, non-standard layout suggests that either
a) You're a maverick who simply doesn't care or
b) ignorant.

Quote
The rest of the code works great

I wonder how stressed the ESC is, and by how much you may have shortened its working life.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Chadwick

Ah Servo.write Thanks!! If I come across as ignorant sorry, Just wanting to learn. I think the ESC will handle it. It is a 160 amp with data logging can monitor pretty much everything from temperature to current. I am an electronics expert so if anything brakes I can fix. But the coding I am not so good at since I got my arduino 4 month ago. I am just optimistic. Can't put a man on the moon if you don't try!!  :D

Go Up