Dear Forum
Can you please check my code because the ouput value shows 0. I connect pin 3 output for dc motor and pin 2 for the opto sensor.
/*
Adafruit Arduino - Lesson 15. Bi-directional Motor
*/
//#include <LiquidCrystal.h>
#include <PID_v1.h>
double Setpoint, Input, Output;
const double Kp=0.1;
const double Ki=0;
const double Kd=0.3;
PID myPID(&Input, & Output, &Setpoint, Kp, Ki, Kd, DIRECT);
int inputPin=0, outputPin=3;
unsigned long serialTime;
//LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
volatile int rpmcount = 0;//see http://arduino.cc/en/Reference/Volatile
int rpm = 0;
unsigned long lastmillis = 0;
int enablePin = 11;
int in1Pin = 10;
int in2Pin = 9;
int switchPin = 8;
int potPin = 1;
void setup()
{
Serial.begin(9600);
pinMode(in1Pin, OUTPUT);
pinMode(in2Pin, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(switchPin, INPUT_PULLUP);
//lcd.begin(16, 2);
//lcd.print("rpm!");
Serial.begin(9600);
Input = analogRead(0);
Setpoint = 100;
attachInterrupt(0, rpm_fan, FALLING);//interrupt cero (0) is on pin two(2).
myPID.SetMode(AUTOMATIC);
//}
//union { // This Data structure lets
//byte asBytes[24]; // us take the byte array
//float asFloat[6]; // sent from processing and
//} // easily convert it to a
//foo; // float array
}
void SerialReceive()
{
//read the bytes sent from Processing
int index=0;
byte Auto_Man = -1;
byte Direct_Reverse = -1;
while(Serial.available()&&index<26)
{
if(index==0) Auto_Man = Serial.read();
else if(index==1) Direct_Reverse = Serial.read();
//else foo.asBytes[index-2] = Serial.read();
index++;
}
}
// if the information we got was in the correct format,
// read it into the system
//if(index==26 && (Auto_Man==0 || Auto_Man==1)&& (Direct_Reverse==0 || Direct_Reverse==1))
// {
// Setpoint=double(foo.asFloat[0]);
//Input=double(foo.asFloat[1]); // * the user has the ability to send the
// value of "Input" in most cases (as
// in this one) this is not needed.
// if(Auto_Man==0) // * only change the output if we are in
// { // manual mode. otherwise we'll get an
// Output=double(foo.asFloat[2]); // output blip, then the controller will
// /} // overwrite.
void loop()
{
Input = analogRead(0);
myPID.Compute();
analogWrite(3,Output);
int speed = analogRead(potPin) / 4;
myPID.Compute();
boolean reverse = digitalRead(switchPin);
setMotor(speed, reverse);
if (millis() - lastmillis >= 1000){ //Uptade every one second, this will be equal to reading frecuency (Hz).
detachInterrupt(0); //Disable interrupt when calculating
rpm = rpmcount * 60; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.
Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.print(rpm); // print the rpm value.
Serial.print("\t Hz=\t"); //print the word "Hz".
Serial.println(rpmcount); //print revolutions per second or Hz. And print new line or enter.
rpmcount = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
if(millis()>serialTime)
{
SerialReceive();
SerialSend();
serialTime+=500;
}
}
}
void SerialSend()
{
Serial.print("PID ");
Serial.print(Setpoint);
Serial.print(" ");
Serial.print(Input);
Serial.print(" ");
Serial.print(Output);
Serial.print(" ");
Serial.print(myPID.GetKp());
Serial.print(" ");
Serial.print(myPID.GetKi());
Serial.print(" ");
Serial.print(myPID.GetKd());
Serial.print(" ");
if(myPID.GetMode()==AUTOMATIC) Serial.print("Automatic");
else Serial.print("Manual");
Serial.print(" ");
if(myPID.GetDirection()==DIRECT) Serial.println("Direct");
else Serial.println("Reverse");
}
void setMotor(int speed, boolean reverse)
{
analogWrite(enablePin, speed);
digitalWrite(in1Pin, ! reverse);
digitalWrite(in2Pin, reverse);
}
void rpm_fan(){ // this code will be executed every time the interrupt 0 (pin2) gets low.
rpmcount++;
}