Smoothing problem

Hello,

I tried to build an PID controller, the program works flawless. Except for the senor value smoothing. I took 10 samples for the average, but it only returns a value of 1.0 bit (range 0, 1023).

#include <PID_v1.h>
#include <Smoothed.h>

const byte SetpointAIPin = A0;
const byte InputAIPin = A1;
const byte MotorEnablePin = 8;
const byte MotorDirectionPin = 12;
const byte MotorPWMPin = 3;
const byte MotorUpperDIPin = 4;
const byte MotorLowerDIPin = 7;
const byte XPVDIPin = 2;
const byte controlManual = 10;

//Define Variables
double Setpoint, Input, Output;
int motormax, motormin, XPV, manual, smoothedSensorValueAvg;

Smoothed mySensor;

//Specify the links and initial tuning parameters
double Kp = 1, Ki = 2, Kd = 1;

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

unsigned long serialTime; //this will help us know when to talk with processing

void setup()
{

//initialize the serial link with processing
Serial.begin(9600);

pinMode(MotorPWMPin, OUTPUT);
pinMode(MotorEnablePin, OUTPUT);
pinMode(MotorUpperDIPin, INPUT);
pinMode(MotorLowerDIPin, INPUT);
pinMode(XPVDIPin, INPUT);
pinMode(controlManual, INPUT);

digitalWrite(MotorEnablePin, HIGH);

mySensor.begin(SMOOTHED_AVERAGE, 10);

//turn the PID on
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(-100, 100);
}

void loop()
{

Input = mySensor.add(analogRead(InputAIPin));
Setpoint = analogRead(SetpointAIPin) /4;
motormax = digitalRead(MotorUpperDIPin);
motormin = digitalRead(MotorLowerDIPin);
XPV = digitalRead(XPVDIPin);
manual = digitalRead(controlManual);

myPID.Compute();

if (Output >= 0 && motormax == LOW && XPV == HIGH && manual == LOW)
{
myPID.SetMode(AUTOMATIC);
digitalWrite(MotorDirectionPin, HIGH);
analogWrite(3, Output);
}
else if (motormax == HIGH || XPV == LOW)
{
myPID.SetMode(MANUAL);
analogWrite(3, 0);
}
else if (Output <= 0 && motormin == LOW && XPV == HIGH && manual == LOW)
{
myPID.SetMode(AUTOMATIC);
digitalWrite(MotorDirectionPin, LOW);
analogWrite(3, -Output);
}
else if (motormin == HIGH || XPV == LOW)
{
myPID.SetMode(MANUAL);
analogWrite(3, 0);
}
else if (manual = HIGH && Setpoint >= 127 && motormax == LOW)
{
myPID.SetMode(MANUAL);
digitalWrite(MotorDirectionPin, LOW);
analogWrite(3, analogRead(SetpointAIPin));
}
else if (manual = HIGH && Setpoint < 127 && motormin == LOW)
{
myPID.SetMode(MANUAL);
digitalWrite(MotorDirectionPin, HIGH);
analogWrite(3, analogRead(SetpointAIPin));
}
else
{
delay(100);
}

@Servo1984 Why do users choose to ignore the advice on posting code ?

The easier you make it to read and copy your code the more likely it is that you will get help

Please follow the advice given in the link below when posting code , use code tags and post the code here

Can I ask if mySensor.add() returns the value (as you assume) or does it return a boolean (true/false)? or something else (void?). "1" feels like a boolean.
Alan

1 Like

Hello
Use severval Serial.println() to see what happens wihin your sketch.

Nice catch. This is from the .h file:

bool Smoothed<T>::add (T newReading) {

Line 81

Bool is used for switching the mode between average and exponentional

#include <PID_v1.h>
#include <Smoothed.h>

const byte SetpointAIPin = A0;
const byte InputAIPin = A1;
const byte MotorEnablePin = 8;
const byte MotorDirectionPin = 12;
const byte MotorPWMPin = 3;
const byte MotorUpperDIPin = 4;
const byte MotorLowerDIPin = 7;
const byte XPVDIPin = 2;
const byte controlManual = 10;

//Define Variables
double Setpoint, Input, Output;
int motormax, motormin, XPV, manual, smoothedSensorValueAvg;

Smoothed mySensor;

//Specify the links and initial tuning parameters
double Kp = 1, Ki = 2, Kd = 1;

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

unsigned long serialTime; //this will help us know when to talk with processing

void setup()
{

//initialize the serial link with processing
Serial.begin(9600);

pinMode(MotorPWMPin, OUTPUT);
pinMode(MotorEnablePin, OUTPUT);
pinMode(MotorUpperDIPin, INPUT);
pinMode(MotorLowerDIPin, INPUT);
pinMode(XPVDIPin, INPUT);
pinMode(controlManual, INPUT);

digitalWrite(MotorEnablePin, HIGH);

mySensor.begin(SMOOTHED_AVERAGE, 10);

//turn the PID on
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(-100, 100);
}

void loop()
{

Input = mySensor.add(analogRead(InputAIPin));
Setpoint = analogRead(SetpointAIPin) /4;
motormax = digitalRead(MotorUpperDIPin);
motormin = digitalRead(MotorLowerDIPin);
XPV = digitalRead(XPVDIPin);
manual = digitalRead(controlManual);

myPID.Compute();

if (Output >= 0 && motormax == LOW && XPV == HIGH && manual == LOW)
{
myPID.SetMode(AUTOMATIC);
digitalWrite(MotorDirectionPin, HIGH);
analogWrite(3, Output);
}
else if (motormax == HIGH || XPV == LOW)
{
myPID.SetMode(MANUAL);
analogWrite(3, 0);
}
else if (Output <= 0 && motormin == LOW && XPV == HIGH && manual == LOW)
{
myPID.SetMode(AUTOMATIC);
digitalWrite(MotorDirectionPin, LOW);
analogWrite(3, -Output);
}
else if (motormin == HIGH || XPV == LOW)
{
myPID.SetMode(MANUAL);
analogWrite(3, 0);
}
else if (manual = HIGH && Setpoint >= 127 && motormax == LOW)
{
myPID.SetMode(MANUAL);
digitalWrite(MotorDirectionPin, LOW);
analogWrite(3, analogRead(SetpointAIPin));
}
else if (manual = HIGH && Setpoint < 127 && motormin == LOW)
{
myPID.SetMode(MANUAL);
digitalWrite(MotorDirectionPin, HIGH);
analogWrite(3, analogRead(SetpointAIPin));
}
else
{
delay(100);
}

with the code tags now...

You miss the point. Smoothed returns a boolean. Itll return true if run for average or exponential, and false if neither is chosen. You don't want to store that output in your 'int input'.

Ah yes i understand.. but i don't grasp whcich function returns the average value.

Call 'get()'. See header file starting at line 118.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.