Just wrote my first library. A driver for the L298 chip

So while there are many drivers for various motor shields I noticed that there wasn't one for just the L298 chip itself or the various single chip modules such as this https://www.sparkfun.com/products/9670

I know it's not really.necessary to have a library for this usage but I wrote it so that my students can get started on the meaty bits of robotics nice and quickly after learning the basics of the arduino IDE.

Let me.know what you think. Feel free to submit issues if you see them.

Why are the pin numbers to use hard-coded?

pinMode() assumes that the hardware is ready. When your constructor is run, that is NOT a valid assumption. Your class needs a begin() method where the hardware diddling happens.

Perhaps I'm missing something, but BRAKE and RELEASE seem to do the same thing.

BRAKE and release do the same thing yes.

I realised to RELEASE I just needed to set the speed to 0.

OK so you are saying that I should have a method that I would call like this:

MS.begin(3, 4, 5, 6, 9, 10)

Which would set up the pinMode()

OK so you are saying that I should have a method that I would call like this:

MS.begin(3, 4, 5, 6, 9, 10)

Which would set up the pinMode()

Not exactly. The pins to use should be input to the constructor. The calls to pinMode() do belong in the begin() method.

OK you have lost me a bit there.

Where would I enter the pin numbers if not when calling either begin method or motorsetup method?

spacedementia87:
OK you have lost me a bit there.

Where would I enter the pin numbers if not when calling either begin method or motorsetup method?

The constructor should take 3 pin numbers:

class DCMotor
{
  public:
    DCMotor(uint8_t motorNum, uint8_t aPin, uint8_t bPin, uint8_t dirPin);
    void begin();

The class should have three arrays of pin numbers:

  private:
    int aPins[2];
    int bPins[2];
    int dirPins[2];

In the implementation of the constructor, set the 0th element of each array, or the 1th element of each array, to aPin, bPin, and dirPin, respectively, based on the value in motorNum. camelCase is better than flatcase for names.

Then, your sketch would have:

DCMotor motorOne(1, 2, 3, 9);
DCMotor motorTwo(2, 4, 5, 10);

And, in setup():

void setup()
{
    motorOne.begin();
    motorTwo.begin();

Ahh OK!

Thank you

I have never had any formal lessons in c++. All I know from it is me fiddling with arduino and looking at other libraries and the such.

I get what you mean now. I just wasn't sure what you meant by constructor.

Right I had a go at fixing it to allow for the user to select pins.

I think I have it working I would really appreciate it if you cast an eye over my new branch with these changes.

I have also made some changes to the names of various variables to match conventions.

I think I have it working I would really appreciate it if you cast an eye over my new branch with these changes.

When I create an instance of your class, like so:

DCMotor motorOne(114, 2, 3, 9);

Where is your constructor going to store the pin numbers?

[ rant ]I REALLY hate variable names that have IN in the name being set to OUTPUT. It does not make sense. That the pin is connected to an INput to the motor driver is NOT a reason to use IN in the name. [ /rant ]

Well as it is a driver for a dual H bridge they should.only define two motors.

I guess I should have a check in the constructor that checks the num = 1 or 2 and throw an error if not.

Out of interest though how do I make a list/array "expandanle" so that it will grow to whatever is needed?

Well as it is a driver for a dual H bridge they should.only define two motors.

Well, as its your library, you should check for sane input before using it.

Out of interest though how do I make a list/array "expandanle" so that it will grow to whatever is needed?

You shouldn't. You could use malloc(), realloc(), etc. to make dynamic arrays. But, you really shouldn't. There is no chance that the number of motors that one instance of your class, being based on hardware, can handle will change while the Arduino is running.

PaulS:
Well, as its your library, you should check for sane input before using it.

OK I thought so,

I am struggling with this though. I have included an if statement:

 if (num == 1 || num == 2) {
//do stuff
}
else {
//bad input
}

however I am sure sure what to put in my else block.

Googling to how to throw an error just gets me lots of people asking about the errors they have!

Thanks for all the help you have given me, really appreciate it. I can see on this forum you spend a lot of time helping people like me and it looks quite frustrating ins some instances!

Well now I have done a bit more research and made these adjustments:

DCMotor::DCMotor(uint8_t num, uint8_t Pin1, uint8_t Pin2, uint8_t enPin) {
  #if (num == 1 || num == 2)
    _motorNum = num;
    _Pin1s[_motorNum - 1] = Pin1;
    _Pin2s[_motorNum - 1] = Pin2;
    _enPins[_motorNum - 1] = enPin;
  #else
    #error "This chip is not supported!"
  #endif
}

however the error comes up whenever I try to compile regardless of the value of num.

I think I can see why, when compiling num has not yet been assigned a value and so it drops to the #else block.

in that case though, how do I make it through the error only when appropriate?

however the error comes up whenever I try to compile regardless of the value of num.

The syntax for preprocessor statements is not the same as the syntax for if statements.

The "chip" part of the message is going to confuse the hell out of people.

I know, the error message is just a random one at the moment as I am focusing on getting the syntax for throwing this error correctly.

I would appreciate it if you could show me how to get this problem handled properly.

At least point me in a relevant direction. I can't find anything to have it work.

At least point me in a relevant direction. I can't find anything to have it work.

You are trying to get the preprocessor to do something that it is not designed to do. It can not tell what value is stored in variables in the code. That approach will never work.

All that you can do is use any valid data that is supplied, and quietly ignore any bad data.

OK, why did you bring it up then? It was only at your suggestion that I went down the rabbit hole.

The code already ignores any I put for num > 2.

Also I spied your suggestion of:

private:
int aPins[2];
int bPins[2];
int dirPins[2];

Is a bit pointless, as they are private variables for the instance of the class they don't need to be arrays.

It was only at your suggestion that I went down the rabbit hole.

I suggested that you check the user input. I did NOT suggest that you try to get the pre-processor or compiler to that checking for you.

Is a bit pointless, as they are private variables for the instance of the class they don't need to be arrays.

The code is simpler for using the data when you use arrays. You are welcome to write code that is more complicated than needed.