Go Down

Topic: libraries and servo motor (Read 1 time) previous topic - next topic

araresty

I thought I had this working, but since I had fried my servo motor I wasn't able to test it until now. I'm not sure if the problem I'm having is with using libraries inside of a custom library, or if I just did something very wrong along the way...In any case, thanks for your help...I'm new to this, and very confused, at the moment!

The idea is to have a motor scan 180 degrees in 10 degree increments, reading in an analog value each time.  At the end of the cycle, it repeats itself, if the average of the array containing the analog input is below a given threshold.  If it is above the threshold, the motor goes to the index of its maximum value and stays there, (also it writes an output to another pin that is mapped from the analog in) .

Everything that is printing in the serial monitor makes it look as if the code is working properly, but the servo motor is not moving, except to reset itself to 0 once at the very beginning.  I tested the motor with some basic code and it is working fine.

Here is the header:
Code: [Select]
/* library to make motor scan and look for and go to greatest source of meaningful input*/

#ifndef MotorScan_h
#define MotorScan_h

#include "WProgram.h"
#include "Servo.h"
#include "Array.h"

class MotorScan
{
 public:
   MotorScan(int servoPin, int sensorPin, int outPutPin); //declare sensorPin, add semicolon
    //not sure if this should be void...in original code it is declared as int
   int ReadSens_and_Condition();
   int getIndexOfMaximumValue(int* array, int size);
   void scanAndGetSerialValues();
 private:
   Servo _servo1; //not sure where to put this...should it even be in library?
   int _servoPin;
   int _sensorPin;
   int _sensorVal;
   int _arrSize; //eventually would be nice to make this public, so that you can choose how many values to take from sensor
   int _sensorDistance[19]; //how to declare arrays in header file
   int _servoAngle[19];
   int _a;
   int _arrayAverage;
   int _outPutPin;
   int _pInput;
   int _outPut;
   Array<int> _array();
};

#endif


Here is the source file
Code: [Select]
/* library to make motor scan and look for and go to greatest source of meaningful input*/

#include "WProgram.h"
#include "motorandfeedback.h"
#include "Servo.h"
#include "Array.h"

MotorScan::MotorScan(int servoPin, int sensorPin, int outPutPin) //declare sensorPin
{
 _servoPin = servoPin;
 _sensorPin = sensorPin;
 _outPutPin = outPutPin;
 _sensorVal = 0;
 _pInput = 0;
 _outPut = 0;
 _arrSize = 19;
 _a;
 _servo1.attach(_servoPin);

}


void MotorScan::scanAndGetSerialValues()
{
 Array<int>_array(_sensorDistance, _arrSize);
 int _servoAngle[19] = {0,10,20,30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180};
 
 _sensorVal = analogRead(_sensorPin);
  Serial.print("sensorVal =");
 Serial.print(_sensorVal);
 Serial.println();
 
 _pInput = _sensorVal;

 
 
 if(_sensorVal < 200){
   
   _outPut = 0;
   analogWrite(_outPutPin, _outPut);
   
   for(int x = 0; x <= 18; x++)
    {
     _servo1.write(_servoAngle[x]); //tell servo to go to the angle assigned to the index x of the array we are iterating through
     _sensorDistance[x] = ReadSens_and_Condition(); //store serial values in distance array
     Serial.println(_servoAngle[x]); //print the servo angle array
     Serial.println(_sensorDistance[x]);  //print the distance array
     Serial.println();
     delay(500);    
   }  

   _a=getIndexOfMaximumValue(_sensorDistance, _arrSize); //distance is the array, arrSize = 18, and is the size of the array
   Serial.print("Max index is------");
   Serial.print(_a);
   Serial.print("------");
   Serial.println(_sensorDistance[_a]); //prints the value at the index of the max value
   Serial.print("\tAverage value:");
   _arrayAverage = _array.getAverage();
   Serial.print(_arrayAverage);
   Serial.println();
 }
 
 
 if(_sensorVal >= 200){
   

 if(_arrayAverage > 200 && _pInput >= 200){
               _servo1.write(_servoAngle[_a]);
                Serial.print("I'm going to the location of my greatest input value: ");  
                Serial.print(_servoAngle[_a]);
                Serial.print(" ");
                Serial.print("degrees ");
                Serial.println();
                delay(500);  
               
                 _outPut = map(_pInput, 0, 1023, 0, 255);
                 analogWrite(_outPutPin, _outPut);
}
     
  else{
    _outPut = 0;
   analogWrite(_outPutPin, _outPut);  
   
    for(int x = 0; x <= 18; x++)
    {
     _servo1.write(_servoAngle[x]); //tell servo to go to the angle assigned to the index x of the array we are iterating through
     _sensorDistance[x] = ReadSens_and_Condition(); //store serial values in distance array
     Serial.println(_servoAngle[x]); //print the servo angle array
     Serial.println(_sensorDistance[x]);  //print the distance array
     Serial.println();
     delay(500);    
   }  

   _a=getIndexOfMaximumValue(_sensorDistance, _arrSize); //distance is the array, arrSize = 18, and is the size of the array
   Serial.print("Max index is------");
   Serial.print(_a);
   Serial.print("------");
   Serial.println(_sensorDistance[_a]); //prints the value at the index of the max value
   Serial.print("\tAverage value:");
   _arrayAverage = _array.getAverage();
   Serial.print(_arrayAverage);
   Serial.println();
 }
}
}
int MotorScan:: ReadSens_and_Condition() //will this work as int?  also, do I need to declare the other ints, below?
{
 int i;
 int sval;
 for (i = 0; i < 5; i++)
    {
      sval = sval + analogRead(_sensorPin);  
    }

 sval = sval / 5;    
 return sval;
}

int MotorScan:: getIndexOfMaximumValue(int* array, int size)
{
int maxIndex = 0;
int max = array[maxIndex];
  for (int i=1; i<size; i++)
  {
      if (max<array[i])
      {
          max = array[i];
          maxIndex = i;
      }
  }
return maxIndex;
}


And here I'm trying to use the library:

Code: [Select]

#include <motorandfeedback.h>
#include <Servo.h>
#include <Array.h>


MotorScan firstMotor(9, 2, 4); //servo motor pin, read sensor from pin, write output to pin

void setup()
{
  Serial.begin(9600);          
Serial.println("Servo test!");
}


void loop()
{
 firstMotor.scanAndGetSerialValues();
 delay(500);
}



PaulS

Do you know WHEN your constructor gets called? Is the servo pin ready to be attached to when the constructor is called?

Perhaps you've noticed that classes like Serial have a begin() method that actually does the work, and that that method is called from within setup(), after all the hardware initialization is complete, and all constructors have been called.

Try adding a begin() method to your class, and move everything that depends on other constructors and initialization operations into that method (just the attach method call).

In the sketch, add a call to the begin method() using the instance of your class.

Why is the array of sensor readings a dynamic array while the array to take the readings at is a fixed size array?

Why are you doing analogWrite() to a non-PWM pin?
The art of getting good answers lies in asking good questions.

Go Up