This program is for an RC car with a steer servo and drive(motor) servo.
I have some code that works and turns a motor. However, the code uses an extern servo object. I can't figure out how to use the servo object within the class. I have tried putting the object as a private variable but the servo would just move to the far right and start making a grinding sound. The drive servo wouldn't even move.
Please let me know how to make the servo object inside the class. I have searched online for how to do this but for some reason using objects in my class is not working for me.
Drive.h file
#ifndef DRIVE_H
#define DRIVE_H
#include <Servo.h> //Servo library, included with the Arduino IDE
#include <Arduino.h>
extern Servo steer;
extern Servo motor;
#define GO 1600 //PPM speed for forward motion on motor servo, 1665-1695 in long grass (like
//the west lawn) 1600 is preferable for solid ground (cement, gravel, etc)
#define BACK 1350 //PPM speed for reverse motion on motor servo,
//1000 in long grass, 1200 for solid ground
#define STOP 1500 //PPM speed for idle on the motor servo
#define STRAIGHT 90 //Steering servo straight command
#define LEFT 120 //Steering servo left turn command
#define RIGHT 0 //Steering servo right turn command
class Drive
{
public:
void left();
void right();
void straight();
void init(int steerPin, int drivePin);
void forward(int delayTime);
void backward(int delayTime);
void stop(int delayTime);
private:
//Servo steer, motor;
//Servo *steer, *motor;
};
#endif
Drive.cpp File
#include "Drive.h"
void Drive::init(int steerPin, int drivePin){
steer.attach(steerPin);
motor.attach(drivePin);
}
void Drive::backward(int delayTime){
motor.write(BACK);
delay(25);
motor.write(STOP);
delay(25);
motor.write(BACK);
delay(delayTime);
}
void Drive::forward(int delayTime){
motor.write(GO);
delay(delayTime);
}
void Drive::left(){
steer.write(LEFT);
}
void Drive::straight(){
steer.write(STRAIGHT);
}
void Drive::right(){
steer.write(RIGHT);
}
void Drive::stop(int delayTime){
motor.write(STOP);
delay(delayTime);
}
create objects like you would in any scope:
#include <Servo.h>
class Drive {
public:
Drive(uint8_t leftServo, uint8_t rightServo) : leftServoPin(leftServo), rightServoPin(rightServo) {}
void init(){
rightServo.attach(rightServoPin);
leftServo.attach(leftServoPin);
}
void goStraight(int distance) {
rightServo.write(distance);
leftServo.write(distance);
}
private:
Servo rightServo;
Servo leftServo;
uint8_t leftServoPin;
uint8_t rightServoPin;
};
Drive car(8,9);
void setup() {
car.init();
car.goStraight(90);
}
void loop() {
// put your main code here, to run repeatedly:
}
That doesn't work for me. I tried it just like you showed.
tedlasai:
That doesn't work for me. I tried it just like you showed.
¿what do you mean "That doesn't work"?
I edited my code to do what you were saying for me to do.
#include "Drive.h"
void Drive::init(int steerPin, int drivePin){
steer.attach(steerPin);
motor.attach(drivePin);
}
void Drive::backward(int delayTime){
motor.write(BACK);
delay(25);
motor.write(STOP);
delay(25);
motor.write(BACK);
delay(delayTime);
}
void Drive::forward(int delayTime){
motor.write(GO);
delay(delayTime);
}
void Drive::left(){
steer.write(LEFT);
}
void Drive::straight(){
steer.write(STRAIGHT);
}
void Drive::right(){
steer.write(RIGHT);
}
void Drive::stop(int delayTime){
motor.write(STOP);
delay(delayTime);
}
With setup
void setup() {
Serial.begin(115200); // connect serial
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
drive.init(9,10);
drive.straight();
drive.stop(1000);
}
/
void loop() {
drive.backward(3000);
}
tedlasai:
I edited my code to do what you were saying for me to do.
your code is unreadable without using code tags. correct that.
Advice: create your class inside your .ino file (like the example I gave you) until you get it working the way you want... then put it into header and implementation files.
My classes do work in the header files if I use the extern keyword for my servo objects. All the functions work. The issue is how the Servo object is getting accessed when object is a part of the class(encapsulated). Should I still move it it?
I am attaching my setup and loop code below.
Drive drive;
void setup() {
Serial.begin(115200); // connect serial
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
drive.init(9,10);
drive.straight();
drive.stop(1000);
}
void loop() {
drive.backward(3000);
}
Notice the extern variables that were commented. My program works if those are uncommented and my servos are created in my test file. This is the .cpp file below.
#ifndef _DRIVE_H_
#define _DRIVE_H_
#include <Servo.h> //Servo library, included with the Arduino IDE
#include <Arduino.h>
//extern Servo steer;
//extern Servo motor;
#define GO 1600 //PPM speed for forward motion on motor servo, 1665-1695 in long grass (like
//the west lawn) 1600 is preferable for solid ground (cement, gravel, etc)
#define BACK 1350 //PPM speed for reverse motion on motor servo,
//1000 in long grass, 1200 for solid ground
#define STOP 1500 //PPM speed for idle on the motor servo
#define STRAIGHT 90 //Steering servo straight command
#define LEFT 120 //Steering servo left turn command
#define RIGHT 0 //Steering servo right turn command
class Drive
{
public:
void left();
void right();
void straight();
void init(int steerPin, int drivePin);
void forward(int delayTime);
void backward(int delayTime);
void stop(int delayTime);
private:
Servo steer, motor;
//Servo *steer, *motor;
};
#endif
The .h file is below
#include "Drive.h"
void Drive::init(int steerPin, int drivePin){
steer.attach(steerPin);
motor.attach(drivePin);
}
void Drive::backward(int delayTime){
motor.write(BACK);
delay(25);
motor.write(STOP);
delay(25);
motor.write(BACK);
delay(delayTime);
}
void Drive::forward(int delayTime){
motor.write(GO);
delay(delayTime);
}
void Drive::left(){
steer.write(LEFT);
}
void Drive::straight(){
steer.write(STRAIGHT);
}
void Drive::right(){
steer.write(RIGHT);
}
void Drive::stop(int delayTime){
motor.write(STOP);
delay(delayTime);
}
tedlasai:
The .h file is below
the class definition belongs in the header, the implementation of the class members goes in the cpp.
¿you have them reversed?
again, the best advice is to get a class working in your ino file. Once you know it works, move it off to the header/implementation files.
I tried moving the class into the .ino file. However the same issue. It works when I call the individual methods on a servo object created outside the class. Essentially the issue seems to be that when I make the servos a part of the class everything stops.
Here is my updated code. Sorry on the last post, I just labeled my code wrong. Ooops. The .h file and .cpp file were not switched.
#include <Servo.h> //Servo library, included with the Arduino IDE
#include <LiquidCrystal_I2C.h>
//#include "Drive.h"
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
//Servo steer;
//Servo motor;
#define GO 1600 //PPM speed for forward motion on motor servo, 1665-1695 in long grass (like
//the west lawn) 1600 is preferable for solid ground (cement, gravel, etc)
#define BACK 1350 //PPM speed for reverse motion on motor servo,
//1000 in long grass, 1200 for solid ground
#define STOP 1500 //PPM speed for idle on the motor servo
#define STRAIGHT 90 //Steering servo straight command
#define LEFT 120 //Steering servo left turn command
#define RIGHT 50 //Steering servo right turn command
class Drive {
public:
Drive(uint8_t steer, uint8_t motor) : steerPin(steer), motorPin(motor) {}
void init(){
steer.attach(steerPin);
motor.attach(motorPin);
}
void backward(int delayTime){
motor.write(BACK);
delay(25);
motor.write(STOP);
delay(25);
motor.write(BACK);
delay(delayTime);
}
void forward(int delayTime){
motor.write(GO);
delay(delayTime);
}
void left(){
steer.write(LEFT);
}
void straight(){
steer.write(STRAIGHT);
}
void right(){
steer.write(RIGHT);
}
void stopCar(int delayTime){
motor.write(STOP);
delay(delayTime);
}
private:
Servo steer, motor;
uint8_t steerPin;
uint8_t motorPin;
//Servo *steer, *motor;
};
Drive drive(9,10);
void setup() {
Serial.begin(115200); // connect serial
drive.init();
drive.straight();
drive.stopCar(1000);
// put your setup code here, to run once:
//attach the steering and motor servos to pins 9 and 10 respectively
//steer.attach(9);
//motor.attach(10);
/*
steer.write(STRAIGHT);
delay(1000);
motor.write(STOP);
delay(2000);
Serial.println();
*/
/*
pinMode(2, INPUT);
attachInterrupt(digitalPinToInterrupt(2), touchthis, RISING);
pinMode(3, INPUT);
attachInterrupt(digitalPinToInterrupt(3), touchthis, RISING);
*/
//drive.stop(1000);
}
/*
void back(int delayTime){
motor.write(BACK);
delay(25);
motor.write(STOP);
delay(25);
motor.write(BACK);
delay(delayTime);
}
void forward(int delayTime){
motor.write(GO);
delay(delayTime);
}
void left(){
steer.write(LEFT);
}
void right(){
steer.write(RIGHT);
}
void stop(int delayTime){
motor.write(STOP);
delay(delayTime);
}
*/
void loop() {
drive.backward(3000);
/*drive.left();
delay(1000);
drive.straight();
delay(1000);
//drive.backward(4000);
drive.right();
delay(1000);*/
//drive.forward(1000);
//left();
//back(2000);
}
/*//function for touch sensor interrupt service routine
void touchthis()
{
endlessLoop();
//touch = 1;
}
/*
//loop to stop all functionality at the end
void endlessLoop(void)
{
while (1)
{
motor.write(STOP);
//Serial.println("done!");
lcd.clear();
lcd.print("DONE!");
delay(1500);
}
}*/
tedlasai:
I tried moving the class into the .ino file. However the same issue. It works when I call the individual methods on a servo object created outside the class. Essentially the issue seems to be that when I make the servos a part of the class everything stops.
Here is my updated code. Sorry on the last post, I just labeled my code wrong. Ooops. The .h file and .cpp file were not switched.
Clean up your code!! get all of the non-class nonsense out of there, Just focus on your class and getting member functions working the way you expect.
Also use all your debugging tools!
Try this:
#include <Servo.h> //Servo library, included with the Arduino IDE
#define GO 1600 //PPM speed for forward motion on motor servo, 1665-1695 in long grass (like
//the west lawn) 1600 is preferable for solid ground (cement, gravel, etc)
#define BACK 1350 //PPM speed for reverse motion on motor servo,
//1000 in long grass, 1200 for solid ground
#define STOP 1500 //PPM speed for idle on the motor servo
#define STRAIGHT 90 //Steering servo straight command
#define LEFT 120 //Steering servo left turn command
#define RIGHT 50 //Steering servo right turn command
class Drive {
public:
Drive(uint8_t steer, uint8_t motor) : steerPin(steer), motorPin(motor) {}
void init() {
Serial.println(F("Init"));
steer.attach(steerPin);
motor.attach(motorPin);
}
void backward(int delayTime) {
Serial.println(F("Backward"));
motor.write(BACK);
delay(25);
motor.write(STOP);
delay(25);
motor.write(BACK);
delay(delayTime);
}
void forward(int delayTime) {
motor.write(GO);
delay(delayTime);
}
void left() {
steer.write(LEFT);
}
void straight() {
Serial.println(F("Straight"));
steer.write(STRAIGHT);
}
void right() {
steer.write(RIGHT);
}
void stopCar(int delayTime) {
Serial.println(F("Stop Car"));
motor.write(STOP);
delay(delayTime);
}
private:
Servo steer, motor;
uint8_t steerPin;
uint8_t motorPin;
};
Drive drive(9, 10);
void setup() {
Serial.begin(9600); // connect serial
drive.init();
drive.straight();
drive.stopCar(1000);
}
void loop() {
drive.backward(3000);
}
I am doing a little bit better but it still won't work. The steer servo works but not the motor servo. I have control over the steering but no control over the drive(motor servo).
I have some code that doesn't use the class and just uses the functions. That code works for both servos. I am copying the class and the non-class versions. I can't figure out why one is working and the other is not.
Class Code:(Doesn't Work)
#include <Servo.h> //Servo library, included with the Arduino IDE
#define GO 1600 //PPM speed for forward motion on motor servo, 1665-1695 in long grass (like
//the west lawn) 1600 is preferable for solid ground (cement, gravel, etc)
#define BACK 1350 //PPM speed for reverse motion on motor servo,
//1000 in long grass, 1200 for solid ground
#define STOP 1500 //PPM speed for idle on the motor servo
#define STRAIGHT 90 //Steering servo straight command
#define LEFT 120 //Steering servo left turn command
#define RIGHT 50 //Steering servo right turn command
class Drive {
public:
Drive(uint8_t steer, uint8_t motor) : steerPin(steer), motorPin(motor) {}
void init() {
Serial.println(F("Init"));
steer.attach(steerPin);
motor.attach(motorPin);
}
void backward(int delayTime) {
Serial.println(F("Backward"));
motor.write(BACK);
delay(1000);
motor.write(STOP);
delay(3000);
motor.write(BACK);
delay(delayTime);
}
void forward(int delayTime) {
Serial.println(F("Forward"));
motor.write(GO);
delay(delayTime);
}
void left() {
Serial.println(F("Left"));
steer.write(LEFT);
}
void straight() {
Serial.println(F("Straight"));
steer.write(STRAIGHT);
}
void right() {
Serial.println(F("Right"));
steer.write(RIGHT);
}
void stopCar(int delayTime) {
Serial.println(F("Stop Car"));
motor.write(STOP);
delay(delayTime);
}
private:
Servo steer, motor;
uint8_t steerPin;
uint8_t motorPin;
};
Drive drive(9, 10);
void setup() {
Serial.begin(115200); // connect serial
drive.init();
drive.straight();
drive.stopCar(1000);
}
void loop() {
drive.forward(3000);
drive.left();
drive.stopCar(3000);
drive.backward(3000);
drive.stopCar(3000);
drive.right();
}
Code that works(Just functions no classes):
#include <Servo.h> //Servo library, included with the Arduino IDE
#include <LiquidCrystal_I2C.h>
//#include "Drive.h"
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
Servo steer;
Servo motor;
#define GO 1600 //PPM speed for forward motion on motor servo, 1665-1695 in long grass (like
//the west lawn) 1600 is preferable for solid ground (cement, gravel, etc)
#define BACK 1350 //PPM speed for reverse motion on motor servo,
//1000 in long grass, 1200 for solid ground
#define STOP 1500 //PPM speed for idle on the motor servo
#define STRAIGHT 90 //Steering servo straight command
#define LEFT 120 //Steering servo left turn command
#define RIGHT 50 //Steering servo right turn command
void setup() {
Serial.begin(115200); // connect serial
// put your setup code here, to run once:
//attach the steering and motor servos to pins 9 and 10 respectively
steer.attach(9);
motor.attach(10);
steer.write(STRAIGHT);
delay(1000);
motor.write(STOP);
delay(2000);
Serial.println();
pinMode(2, INPUT);
attachInterrupt(digitalPinToInterrupt(2), touchthis, RISING);
pinMode(3, INPUT);
attachInterrupt(digitalPinToInterrupt(3), touchthis, RISING);
}
void back(int delayTime){
motor.write(BACK);
delay(50);
motor.write(STOP);
delay(50);
motor.write(BACK);
delay(delayTime);
}
void forward(int delayTime){
motor.write(GO);
delay(delayTime);
}
void left(){
steer.write(LEFT);
}
void right(){
steer.write(RIGHT);
}
void stop(int delayTime){
motor.write(STOP);
delay(delayTime);
}
void loop() {
forward(3000);
left();
stop(3000);
back(3000);
stop(3000);
right();
}
//function for touch sensor interrupt service routine
void touchthis()
{
endlessLoop();
//touch = 1;
}
//loop to stop all functionality at the end
void endlessLoop(void)
{
while (1)
{
motor.write(STOP);
//Serial.println("done!");
lcd.clear();
lcd.print("DONE!");
delay(1500);
}
}
tedlasai:
I am doing a little bit better but it still won't work. The steer servo works but not the motor servo. I have control over the steering but no control over the drive(motor servo).
that says to me that your member functions may not be properly defined.
¿you are using the standard Servo.h libRARY? ¿these are what kind of servo?
On a continuous rotation servo, this will set the speed of the servo (with 0 being full-speed in one direction, 180 being full speed in the other, and a value near 90 being no movement).
I am using the standard Servo.h library.
I have an ESC(Electronic Speed Controller) and a normal servo for rotation. This would work fine for me when I didn't have a class. I don't think my member functions are wrong because they worked perfectly fine when I wasn't trying to use a class. I hope this makes sense. If you look at the code from the last post, I have the same functions. However, one the functions are put into the class they don't seem to work.
tedlasai:
I am using the standard Servo.h library.
I have an ESC(Electronic Speed Controller) and a normal servo for rotation. This would work fine for me when I didn't have a class. I don't think my member functions are wrong because they worked perfectly fine when I wasn't trying to use a class. I hope this makes sense. If you look at the code from the last post, I have the same functions. However, one the functions are put into the class they don't seem to work.
but you said you can move the steer servo inside the class?
saying "it doesn't work" isn't helpful... what happens on the output pin (can you scope it)? does the servo even jitter?
do you have a link to the servo?
My code just started working. The same code that I posted recently. I have no idea why but thank you for the help.