Creating A Library

Hello, i want to transform my code i wrote to a library. This Is The Code

int sensorleft = 4;
int sensorright = 5;
int motor1pin1 = 8; //LEFT
int motor1pin2 = 7;
int motor2pin1 = 10; //RIGHT
int motor2pin2 = 9;
int sensval = 0;
int sensval2 = 0;
int counter=0;


void setup() {
  pinMode(sensorleft, INPUT);
  pinMode(sensorright, INPUT);
  pinMode(motor1pin1, OUTPUT);
  pinMode(motor1pin2, OUTPUT);
  pinMode(motor2pin1, OUTPUT);
  pinMode(motor2pin2, OUTPUT);
  
}
void loop() {
  
  sensval = analogRead(sensorleft);
  sensval2 = analogRead(sensorright);
  //both white
if(sensval <=450 && sensval2 <=450){
digitalWrite(motor1pin1, HIGH);
digitalWrite(motor1pin2, LOW);
digitalWrite(motor2pin1, LOW);
digitalWrite(motor2pin2, HIGH);
}
//turn right
if(sensval2 >=450 && sensval <=450){
  digitalWrite(motor1pin1, LOW );
  digitalWrite(motor1pin2, HIGH);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2,HIGH);
  delay(50);
  
}
  //turn left
if(sensval >=450 && sensval2 <=450){
  digitalWrite(motor2pin1, HIGH);
  digitalWrite(motor2pin2, LOW);
  digitalWrite(motor1pin1, HIGH);
  digitalWrite(motor1pin2, LOW);
  delay(50);
  
  
}
//intersection
if(sensval >=450 && sensval2 >=450){
  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, LOW);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, LOW);
  counter ++;
  delay(500);
  digitalWrite(motor1pin1, HIGH);
  digitalWrite(motor1pin2, LOW);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, HIGH);
  delay(500);
  
  if (counter>3)
  {digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, LOW);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, LOW);
  delay(10000000);
  
  }
  
  
  
}
}

I know the basics of creating a .cpp and .h file for each of my 4 motors and 2 sensors .
How do you write .cpp and .h files ? Where would I write the counters - in the .cpp or the .h file ?
Thanks

first step is to derive the basic functions from your code. Put these in a class e.g. robot
You get something like this

void robot::forward()
{
  digitalWrite(motor1pin1, HIGH);
  digitalWrite(motor1pin2, LOW);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, HIGH);
}
void  robot::right()
{
  digitalWrite(motor1pin1, LOW );
  digitalWrite(motor1pin2, HIGH);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2,HIGH);
}
void  robot::left()
{
  digitalWrite(motor2pin1, HIGH);
  digitalWrite(motor2pin2, LOW);
  digitalWrite(motor1pin1, HIGH);
  digitalWrite(motor1pin2, LOW);
}
void  robot::stop()
{
  digitalWrite(motor1pin1, LOW);
  digitalWrite(motor1pin2, LOW);
  digitalWrite(motor2pin1, LOW);
  digitalWrite(motor2pin2, LOW);
}

Now don't you have to create a seperate class for each of the seperate functions for the 1st 2nd 3rd and 4th motor as well as the 2 sensors?

I have wrote my .h file for the left sensor which i called Lsensor. I have attached it to this post.
Is it correct?

Lsensor.h (184 Bytes)

Pretty good start, I added some elements

//
//    FILE: lsensor.h
//  AUTHOR: 
// VERSION: 0.1.00
// PURPOSE: 
//    DATE: 
//     URL:
//
// Released to the public domain
//

#ifndef LSENSOR_H
#define LSENSOR_H

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#define LSENSOR_LIB_VERSION "0.1.00"

class Lsensor
{
public:
    Lsensor (int ls);
    int getCounter();
    void resetCounter();

private:
    int _ls;
    int _counter;
}

#endif
// -- END OF FILE --

you should also write a minimal test sketch for the library that tries every exposed function. That can be included with the examples in the lib and when you improve your code it is easy to test.

begin_to_program:
Now don't you have to create a seperate class for each of the seperate functions for the 1st 2nd 3rd and 4th motor as well as the 2 sensors?

The idea with using classes (in general) is to abstract the details enough that it can be re-used. You shouldn't have to make separate left and right classes. Instead, have private variables for the motor pins which are set by the constructor, or a specific setMotorPins() method. Then, in your sketch, you create instances of the motor class with the parameters set to define which motor is being controlled. E.g.:

// EDIT: Fixed this line (mixed up the type declaration and object name)
MyMotor  MotorL;

void setup() {
  MotorL.setMotorPins(PIN_ML1, PIN_ML2);
}
...

To expand on what SirNickity said:

You should create your class/object structure such that your main program looks something like this:

Motor rightMotor(PIN_R1, PIN_R2);
Motor leftMotor(PIN_L1, PIN_L2);
LightSensor lightSensor(PIN_LIGHT);

LineFollower lineFollower(lightSensor, rightMotor, leftMotor);

void setup()
{
}

void loop()
{
    lineFollower.follow();
}

Based on your code and questions, I am not sure you're ready to get there yet though. I suggest you look at a bunch of C++ and C++ object model tutorials to understand the basics of C++, including functions, header files, classes etc. before you dive into the deep end.

Can your #ifndef statement along with your #define statement have the same name as your class ?

Let me quickly explain what that part does.... Pull up a chair. :stuck_out_tongue:

In C (but not so much in the Arduino IDE), you're supposed to declare your functions, constants, and things of that nature in a header file. Only the function bodies (and any globals, but don't do that!) go in the .c file itself. This is useful because when your program gets large enough, you'll want to split it into multiple files. It helps keep the length of any given C file within reasonable limits (easier to edit and keep track of what's in there), and allows you to section off your code into reusable modules. Afterall, once you write a couple handy functions, you'll find they're useful elsewhere, too. So when you do this, you'll have somelibrary.c with all your code, and somelibrary.h with the function declarations and stuff.

Later on, you might decide those functions in somelibrary.c are useful to your new project. Well, rather than maintaining a copy of that file for project 1 and another copy for project 2, you can just compile it into a library file (like a .so in Linux, or a .dll in Windows) and reference those functions from your new project. But, since the file is compiled, you're not using the source file (.c) anymore... so how does the compiler know what functions are available, what inputs they require, and what constants were defined? For that matter, how do YOU know a year from now when you've forgotten? Well, that's where the header file comes in.

You just #include "yourheader.h" from your new project's source code file, and all the function definitions are available again, without having to include the function code itself. (This is also useful if you want to keep your source code private, but distribute the library for others to use.)

But, there's a snag... if your project gets big, and you have, e.g., two source code files called file1.c and file2.c, both of which include that library header file, the header will be included twice by the compiler. It's not smart enough to know that the content has already been compiled once and this is just a repeat... so it complains about a ton of conflicting (really, duplicate) declarations.

The way to stop that is to set a flag that is picked up by the C pre-processor before the compiler gets to touch the code. Then, when that flag is already set (which it will be the first time the header gets compiled), the pre-processor skips everything within that flagged section. It goes like this...

// If this flag hasn't been defined already, include everything until the #endif
#ifndef __SOME_ARBITRARY_FLAG__
// Define the flag now, so the next time this file is parsed, the check above will skip this section
#define __SOME_ARBITRARY_FLAG__

(code that must not be included more than once)

// The end of the flagged section
#endif

That flag is not special -- it's any arbitrary (legal) name you want to use, but convention is to name it the same as the header file itself. I use "filename_h" myself.

Obviously, all this applies to .cpp/.h files just the same. Hope that helps!

Thank You :slight_smile: