Go Down

Topic: Problemino sketch PID (Read 14115 times) previous topic - next topic

enomis10

Ciao a tutti, mi ritrovo di nuovo a chiedermi di aiutarmi nel giro di pochi giorni.
Stavolta però il problema non è hardware ma software.
Spiego meglio, sto creando una serra automatizzata e ho creato uno sketch PID per il controllo di una striscia led 12V (che quindi alimento tramite mosfet) e funziona tutto bene, risposta rapida e luce stabile anche a media intensità.
Il problema sorge quando vado ad aggiungere questo sketch con PID ad un altro sketch che avevo già creato per far funzionare tutto il resto...(pompa acqua, un servo per un pannello solare, ventilatore, ecc..). Infatti ora la striscia LED ha una risposta molta più lenta e ad una intensità media la luce ha un leggero sfarfallio (poco stabile).  Non riesco veramente a capire perchè!!!
Credevo fosse colpa dei delay dello sketch senza PID ma anche dopo averli eliminati il risultato non è cambiato.
vi aggiungo i 2 sketch separati e quello finale che unisce questi 2.

Se può essere di aiuto dico che controllo i LED con un sensore con fotoresistenza che ho posto sotto la striscia LED e quando la luce ha quel leggero sfarfallio ne risente anche il sensore(lo vedo dal lampeggio che fa il led del sensore).

codice PID LED
Code: [Select]
#include <PID_v1.h>
const int photores = A2; // Photo resistor input
const int pot = A1; // Potentiometer input
const int led = 5; // LED output
double lightLevel; // variable that stores the incoming light level
// Tuning parameters
float Kp=0; //Initial Proportional Gain
float Ki=10; //Initial Integral Gain
float Kd=0; //Initial Differential Gain
double Setpoint, Input, Output; //These are just variables for storingvalues
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// This sets up our PDID Loop
//Input is our PV
//Output is our u(t)
//Setpoint is our SP
const int sampleRate = 1; // Variable that determines how fast our PID loop runs
// Communication setup
const long serialPing = 500; //This determines how often we ping our loop
// Serial pingback interval in milliseconds
unsigned long now = 0; //This variable is used to keep track of time
// placehodler for current timestamp
unsigned long lastMessage = 0; //This keeps track of when our loop last spoke to serial
// last message timestamp.
void setup(){
 lightLevel = analogRead(photores); //Read in light level
 Input = map(lightLevel, 1024, 0, 0, 255); //Change read scale to analog out scale
 Setpoint = map(analogRead(pot), 0, 1024, 0, 255);
//get our setpoint from our pot
 Serial.begin(9600); //Start a serial session
 myPID.SetMode(AUTOMATIC); //Turn on the PID loop
 myPID.SetSampleTime(sampleRate); //Sets the sample rate

 Serial.println("Begin"); // Hello World!
 lastMessage = millis(); // timestamp
}
void loop(){
 Setpoint = map(analogRead(pot), 0, 1024, 0, 255); //Read our setpoint
 lightLevel = analogRead(photores); //Get the light level
 Input = map(lightLevel, 1024, 0, 0, 255); //Map it to the right scale
 myPID.Compute(); //Run the PID loop
 analogWrite(led, Output); //Write out the output from the PID loop to our LED pin

 now = millis(); //Keep track of time
 if(now - lastMessage > serialPing) { //If it has been long enough give us some info on serial
 // this should execute less frequently
 // send a message back to the mother ship
 Serial.print("Setpoint = ");
 Serial.print(Setpoint);
 Serial.print(" Input = ");
 Serial.print(Input);
 Serial.print(" Output = ");
 Serial.print(Output);
 Serial.print("\n");
 if (Serial.available() > 0) { //If we sent the program a command deal with it
 for (int x = 0; x < 4; x++) {
 switch (x) {
 case 0:
 Kp = Serial.parseFloat();
 break;
 case 1:
 Ki = Serial.parseFloat();
 break;
 case 2:
 Kd = Serial.parseFloat();
 break;
 case 3:
 for (int y = Serial.available(); y == 0; y--) {
 Serial.read(); //Clear out any residual junk
 }
 break;
 }
 }
 Serial.print(" Kp,Ki,Kd = ");
 Serial.print(Kp);
 Serial.print(",");
 Serial.print(Ki);
 Serial.print(",");
 Serial.println(Kd); //Let us know what we just received
 myPID.SetTunings(Kp, Ki, Kd); //Set the PID gain constants and start running
 }

 lastMessage = now;
 //update the time stamp.
 }

}


CODICE SERRA
Code: [Select]
#include <Servo.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN A3
 
int sensorPin = A5;
int servoPin  = 9;
 
int sensorValue = 0;
int servoGrad = 90;
int tolleranza = 20;
 
Servo myservo;
  
int umidita=A0;
int luce=A2;
const int POMPA=3;
const int VENTOLE=2;
const int LUCE=5;
int val_Adc = 0;
float temp = 0;
 
void setup(){  
  Serial.begin(9600);
  pinMode(umidita, INPUT);
  pinMode(POMPA, OUTPUT);
  pinMode(VENTOLE, OUTPUT);
  pinMode(LUCE, OUTPUT);
  pinMode( sensorPin, INPUT);
  myservo.attach( servoPin );
  myservo.write( servoGrad );
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}
 
void loop(){
   sensorValue = analogRead(sensorPin);
  if ( sensorValue < (512-tolleranza) )
  {
    if (servoGrad < 180) servoGrad++;
  }
 
  if ( sensorValue > (512+tolleranza) )
  {
    if (servoGrad > 0) servoGrad--;
  }
 
  myservo.write( servoGrad );
 
  delay(100);      
int chk;
  Serial.print("DHT11, \t");
  chk = DHT.read(DHT11_PIN);    // READ DATA
  switch (chk){
    case DHTLIB_OK:  
                Serial.print("OK,\t");
                break;
    case DHTLIB_ERROR_CHECKSUM:
                Serial.print("Checksum error,\t");
                break;
    case DHTLIB_ERROR_TIMEOUT:
                Serial.print("Time out error,\t");
                break;
    default:
                Serial.print("Unknown error,\t");
                break;


                                                                      
  }
 // DISPLAT DATA
   Serial.print("\t");
    Serial.print(DHT.humidity,1);
  Serial.print("\t"); Serial.print("\t");
  Serial.println(DHT.temperature,1);
                                                              
  
delay(100);
  
   if ((DHT.temperature)<23)
       { digitalWrite (VENTOLE, LOW);   }
    if ((DHT.temperature)>24)
      { digitalWrite(VENTOLE, HIGH);     }                                    
                                        
    
    if (analogRead(A0)>100) {
    digitalWrite (POMPA, HIGH);
   if (analogRead(A0)<700)
    digitalWrite(POMPA, LOW);
    
    
   if (analogRead(A2)<800)
   { digitalWrite(LUCE, LOW);}
   else { digitalWrite(LUCE, HIGH);
    

}  
}
}



grazie mille in anticipo a chiunque voglia aiutarmi!!

enomis10

mancava il codice finale che posto di seguito, chiedo scusa ma avevo ecceduto i caratteri max...


E  infine il CODICE FINALE dove ho eliminato i delay del codice serra
Code: [Select]


#include <PID_v1.h>
#include <Servo.h>
#include <dht11.h>
dht11 DHT;
#define DHT11_PIN A3

int sensorPin = A5;
int servoPin  = 9;
 
int sensorValue = 0;
int servoGrad = 90;
int tolleranza = 20;
 
Servo myservo;
  
int umidita=A0;
int luce=A2;
const int POMPA=3;
const int VENTOLE=2;
const int LUCE=5;
int val_Adc = 0;
float temp = 0;



//parte relativa a PID
const int photores = A2; // Photo resistor input
const int pot = A1; // Potentiometer input
const int led = 5; // LED output
double lightLevel; // variable that stores the incoming light level
// Tuning parameters
float Kp=0; //Initial Proportional Gain
float Ki=10; //Initial Integral Gain
float Kd=0; //Initial Differential Gain
double Setpoint, Input, Output; //These are just variables for storingvalues
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// This sets up our PDID Loop
//Input is our PV
//Output is our u(t)
//Setpoint is our SP
const int sampleRate = 1; // Variable that determines how fast our PID loop runs
// Communication setup
const long serialPing = 500; //This determines how often we ping our loop
// Serial pingback interval in milliseconds
unsigned long now = 0; //This variable is used to keep track of time
// placehodler for current timestamp
unsigned long lastMessage = 0; //This keeps track of when our loop last spoke to serial
// last message timestamp.


void setup(){
  Serial.begin(9600); //Start a serial session
 lightLevel = analogRead(photores); //Read in light level
 Input = map(lightLevel, 1024, 0, 0, 255); //Change read scale to analog out scale
 Setpoint = map(analogRead(pot), 0, 1024, 0, 255);
//get our setpoint from our pot
 
 myPID.SetMode(AUTOMATIC); //Turn on the PID loop
 myPID.SetSampleTime(sampleRate); //Sets the sample rate

 Serial.println("Begin"); // Hello World!
 lastMessage = millis(); // timestamp

 
  pinMode(umidita, INPUT);
  pinMode(POMPA, OUTPUT);
  pinMode(VENTOLE, OUTPUT);
  pinMode(LUCE, OUTPUT);
  pinMode( sensorPin, INPUT);
  myservo.attach( servoPin );
  myservo.write( servoGrad );
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}


void loop(){

   sensorValue = analogRead(sensorPin);
  if ( sensorValue < (512-tolleranza) )
  {
    if (servoGrad < 180) servoGrad++;
  }
 
  if ( sensorValue > (512+tolleranza) )
  {
    if (servoGrad > 0) servoGrad--;
  }
 
  myservo.write( servoGrad );
 
  delay(0);      
int chk;
  Serial.print("DHT11, \t");
  chk = DHT.read(DHT11_PIN);    // READ DATA
  switch (chk){
    case DHTLIB_OK:  
                Serial.print("OK,\t");
                break;
    case DHTLIB_ERROR_CHECKSUM:
                Serial.print("Checksum error,\t");
                break;
    case DHTLIB_ERROR_TIMEOUT:
                Serial.print("Time out error,\t");
                break;
    default:
                Serial.print("Unknown error,\t");
                break;


                                                                      
  }
 // DISPLAT DATA
   Serial.print("\t");
    Serial.print(DHT.humidity,1);
  Serial.print("\t"); Serial.print("\t");
  Serial.println(DHT.temperature,1);
                                                              
  
delay(0);
  
   if ((DHT.temperature)<23)
       { digitalWrite (VENTOLE, LOW);   }
    if ((DHT.temperature)>23)
      { digitalWrite(VENTOLE, HIGH);     }                                    
                                        
    
    if (analogRead(A0)>100) {
    digitalWrite (POMPA, HIGH);
   if (analogRead(A0)<700)
    digitalWrite(POMPA, LOW);
    
    
   if (analogRead(A2)<800)
   { digitalWrite(LUCE, LOW);}
   else { digitalWrite(LUCE, HIGH);
    

}  
}



//parte relativa a PID


 Setpoint = map(analogRead(pot), 0, 1024, 0, 255); //Read our setpoint
 lightLevel = analogRead(photores); //Get the light level
 Input = map(lightLevel, 1024, 0, 0, 255); //Map it to the right scale
 myPID.Compute(); //Run the PID loop
 analogWrite(led, Output); //Write out the output from the PID loop to our LED pin

 now = millis(); //Keep track of time
 if(now - lastMessage > serialPing) { //If it has been long enough give us some info on serial
 // this should execute less frequently
 // send a message back to the mother ship
 Serial.print("Setpoint = ");
 Serial.print(Setpoint);
 Serial.print(" Input = ");
 Serial.print(Input);
 Serial.print(" Output = ");
 Serial.print(Output);
 Serial.print("\n");
 if (Serial.available() > 0) { //If we sent the program a command deal with it
 for (int x = 0; x < 4; x++) {
 switch (x) {
 case 0:
 Kp = Serial.parseFloat();
 break;
 case 1:
 Ki = Serial.parseFloat();
 break;
 case 2:
 Kd = Serial.parseFloat();
 break;
 case 3:
 for (int y = Serial.available(); y == 0; y--) {
 Serial.read(); //Clear out any residual junk
 }
 break;
 }
 }
 Serial.print(" Kp,Ki,Kd = ");
 Serial.print(Kp);
 Serial.print(",");
 Serial.print(Ki);
 Serial.print(",");
 Serial.println(Kd); //Let us know what we just received
 myPID.SetTunings(Kp, Ki, Kd); //Set the PID gain constants and start running
 }

 lastMessage = now;
 //update the time stamp.
 }

}

gpb01

#2
Jan 30, 2016, 11:44 pm Last Edit: Jan 30, 2016, 11:45 pm by gpb01
Nella sezione dove hai messo il post c'è chiaramente scritto, in grassetto, di non postare nulla ... quindi, per favore, la prossima volta presta più attenzione e posta nella sezione giusta. Grazie.

Guglielmo
Search is Your friend ... or I am Your enemy !

enomis10

ops, chiedo scusa. Ma adesso cosa devo fare? Devo postare in un'altra zona?

gpb01

#4
Jan 31, 2016, 08:19 am Last Edit: Jan 31, 2016, 08:20 am by gpb01
ops, chiedo scusa. Ma adesso cosa devo fare? Devo postare in un'altra zona?
... se noti ho già spostato io il thread nella sezione giusta (Software) ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

Go Up