Control tempertura PID no funciona

Hola, estoy haciendo un proyecto de electronoods de un control de temperatura PID, aunque me he informado sobre pid no logro aplicar lo que entiendo al código, sobre el código no sé hacer prácticamente nada, pero estoy trabajando bajo un tutorial.
Este es el tutorial: [Temperature PID Arduino controller tutorial]
He conseguido que la pantalla y el termopar funcionen correctamente, utilizo otra pantalla, pero eso no fue problema.
Lo que no consigo es que la resistencia se caliente.
este es mi codigo:

/*    Max6675 Module  ==>   Arduino
 *    CS              ==>     D10
 *    SO              ==>     D12
 *    SCK             ==>     D13
 *    Vcc             ==>     Vcc (5v)
 *    Gnd             ==>     Gnd      */

//LCD config (i2c LCD screen, you need to install the LiquidCrystal_I2C if you don't have it )
#include <Wire.h> 
#include <LiquidCrystal_PCF8574.h>    //If you don't have the LiquidCrystal_I2C library, download it and install it
LiquidCrystal_PCF8574 lcd(0x27);  //sometimes the adress is not 0x3f. Change to 0x27 if it dosn't work.

/*    i2c LCD Module  ==>   Arduino
 *    SCL             ==>     A5
 *    SDA             ==>     A4
 *    Vcc             ==>     Vcc (5v)
 *    Gnd             ==>     Gnd      */

#include <SPI.h>
//We define the SPI pìns
#define MAX6675_CS   10
#define MAX6675_SO   12
#define MAX6675_SCK  13

//Pins
int PWM_pin = 3;


//Variables
float temperature_read = 0.0;
float set_temperature = 100;
float PID_error = 0;
float previous_error = 0;
unsigned long elapsedTime, Time, timePrev;
float PID_value = 0;



//PID constants
const float kp = 9.1; 
const float ki = 0.3; 
const float kd = 1.8; 

float PID_p = 0; 
float PID_i = 0; 
float PID_d = 0; 


void setup() {
  pinMode(PWM_pin,OUTPUT);
  TCCR2B = TCCR2B & B11111000 | 0x03;    // pin 3 and 11 PWM frequency of 980.39 Hz
  Time = millis(); 
 int error;

  Serial.begin(115200);
  Serial.println("LCD...");

  // wait on Serial to be available on Leonardo
  while (!Serial)
    ;

  Serial.println("Dose: check for LCD");

  // See http://playground.arduino.cc/Main/I2cScanner how to test for a I2C device.
  Wire.begin();
  Wire.beginTransmission(0x27);
  error = Wire.endTransmission();
  Serial.print("Error: ");
  Serial.print(error);

  if (error == 0) {
    Serial.println(": LCD found.");
    lcd.begin(16, 2); // initialize the lcd

  } else {
    Serial.println(": LCD not found.");
  } // if;
}


void loop() {
 // First we read the real value of temperature
  temperature_read = readThermocouple();
  //Next we calculate the error between the setpoint and the real value
  PID_error = set_temperature - temperature_read;
  //Calculate the P value
  PID_p = kp * PID_error;
  //Calculate the I value in a range on +-3
  if(-3 < PID_error <3)
  {
    PID_i = PID_i + (ki * PID_error);
  }

  //For derivative we need real time to calculate speed change rate
  timePrev = Time;                            // the previous time is stored before the actual time read
  Time = millis();                            // actual time read
  elapsedTime = (Time - timePrev) / 1000; 
  //Now we can calculate the D calue
  PID_d = kd*((PID_error - previous_error)/elapsedTime);
  //Final total PID value is the sum of P + I + D
  PID_value = PID_p + PID_i + PID_d;

  //We define PWM range between 0 and 255
  if(PID_value < 0.0) 
  {    PID_value = 0;    }
  if(PID_value > 255.0)  
  {    PID_value = 255;  }
  //Now we can write the PWM signal to the mosfet on digital pin D3
  analogWrite(PWM_pin,255-PID_value);
  previous_error = PID_error;     //Remember to store the previous error for next loop.

  delay(300);
  //lcd.clear();
  
  lcd.setBacklight(255);
  lcd.setCursor(0,0);
  lcd.print("PID TEMP control");
  lcd.setCursor(0,1);
  lcd.print("S:");
  lcd.setCursor(2,1);
  lcd.print(set_temperature,1);
  lcd.setCursor(9,1);
  lcd.print("R:");
  lcd.setCursor(11,1);
  lcd.print(temperature_read,1);
}



double readThermocouple() {

  uint16_t v;
  pinMode(MAX6675_CS, OUTPUT);
  pinMode(MAX6675_SO, INPUT);
  pinMode(MAX6675_SCK, OUTPUT);
  
  digitalWrite(MAX6675_CS, LOW);
  delay(1);

  // Read in 16 bits,
  //  15    = 0 always
  //  14..2 = 0.25 degree counts MSB First
  //  2     = 1 if thermocouple is open circuit  
  //  1..0  = uninteresting status
  
  v = shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST);
  v <<= 8;
  v |= shiftIn(MAX6675_SO, MAX6675_SCK, MSBFIRST);
  
  digitalWrite(MAX6675_CS, HIGH);
  if (v & 0x4) 
  {    
    // Bit 2 indicates if the thermocouple is disconnected
    return NAN;     
  }

  // The lower three bits (0,1,2) are discarded status bits
  v >>= 3;

  // The remaining bits are the number of 0.25 degree (C) counts
  return v*0.25;
}


Alguien puede hacerse a la idea que puedo estar haciendo mal.
Muchas gracias de antemano

Coloca un LED en el pin 3 y mira a ver si cambia su brillo.
Has revisado la salida del termopar? Mide correctamente la temperatura?

Hola.
He puesto el led en positivo pwm de y el negativo en gnd, el led no se enciende.
He puesto el pin d3 pwm en el negativo del led y el positivo en 3.3v del Arduino y el led prende, coloco el setpoint en 10, ósea por debajo de consigna el led se apaga.



eso significa que mi placa funciona bien?
video explicativo
la resistencia en el video la conecto yo directa manualmente
Puede que el conexionado en el s8050 está mal hecho?

Muchas gracias por tu respuesta, esto es parte de un proyecto ms grande y si no me funciona esto el proyecto completo queda inútil, así que agradezco mucho tu aportación

El patillaje del s8050 es
imagen

imagen

Y el delIRFZ44n es
imagen

En la foto no se ve si estan bien conectados o no.

float elapsedTime, Time, timePrev;

Está mal, deben ser unsigned long, entonces

unsigned long elapsedTime, Time, timePrev;

Saludos

hol, gracias por tu respuesta, he hecho un esquema basándome en lo que tengo hecho.


s cambio el gnd del Arduino al de l fuente de 12 v, la resistencia no deja de calentarse, queda como conectado directo.
Muchísimas gracias

¿viendo la manera que tengo hecho el esquema, si cambio eso debería funcionar?

No, hay más errores.
Ya te digo...

Agrego:

//PID constants 
int kp = 9.1; int ki = 0.3; int kd = 1.8; 
int PID_p = 0; int PID_i = 0; int PID_d = 0; 

Si kp es entera no puede nunca almacenar el valor 9.1 que es float entonces lo trunca a 9.
Lo mismo para ki que queda en 0 y kd en 1.
Además si nunca cambian su valor deberías declararlas como constantes
Y si PID_p debe almacenar el resultado de una operación entre float's no puede ser int, lo mismo para las otras 2.
Entonces

//PID constants
const float kp = 9.1; 
const float ki = 0.3; 
const float kd = 1.8; 

float PID_p = 0; 
float PID_i = 0; 
float PID_d = 0; 

Lamento mucho mi ignorancia, es un copipaste y he modificado lo de la pantalla y funciona de chiripa.

Fijate en el post anterior que te marqué otros errores.

PID_value también debe ser float

En las comparaciones como

if(PID_value < 0) {

debes usar

if(PID_value < 0.0) {

Lo mismo

if(PID_value > 255.0) {

porque la variable a comparar es float.

Saludos

Esta es la parte dos del proyecto, después debo añadir un encoder para seleccionar las pid y la temperatura de consigna. ¿Aun con esas debo modificar estos valores?
https://electronoobs.com/eng_arduino_tut24_2.php

te parece correcto mi esquema?

me pareceis heroes saviendo hacer estas cosas :face_holding_back_tears:

Si, las variables igual deben ser float (las bananas siguen siendo babanas las elijas de la forma que las elijas, ¿no?).

El esquema parece igual al del tutorial, está bien (creo).

Saludos

Ya he modificado los valores tal y como dijiste. Sigue sin funcionar, pero imagino que lo que hiciste es mejorar el pid. No entiendo nada de lo que he hecho. :sweat_smile:
muchas gracias por tu atención :blush:

No hace falta hacer

pinMode(MAX6675_CS, OUTPUT); pinMode(MAX6675_SO, INPUT); pinMode(MAX6675_SCK, OUTPUT);

cada vez que llama a la función porque el modo de los pines no cambia durante la ejecución.
Eso hay que ponerlo en setup().

Mirá, creo que elegiste el peor tutorial, ese código (el del tutorial), tal como está, es un desastre.

Saludos

PD: En 2 hs salgo de viaje, ya no te puedo seguir ayudando por hoy. Lo siento.

Muchas gracias por tu ayuda, te agradezco muchísimo.
Sabes de algún otro tuto que pueda hacer, aunque tenga que descartar todo lo que hice.
Por ahí leí que demoa.manera que está puesto el s8050 tarde o temprano quemaría al atmega.
Sabes de algún otro tutorial?
Gracias

He estado haciendo unos pruebas sun simple led y el s8050, y con la salida pwm d3 no activa el transistor como para que pase la corriente. ¿Esto no debería ser así no? de hecho he vjado el setpoint a 10 y es cuando me lo enciende.
¿deveria de ser al reves no?

Que no se entere el de ELECTRONOOBS porque sus videos son buenos pero evidentemente tienen errores.

Necesito un control de temperatura PID que funcione bien.
Sabéis dónde puedo encontrar uno, como el de electronoods pero que funcione. Necesito temperaturas de 218 grados.
La verdad es que miro mucho a electronoods me parece un tío genial. Este proyecto me viene genial para lo que necesito hacer. Pero, no me funciona . Para una vez que me pongo a hacer algo :joy:

A ver... funcionar tiene que funcionar.
Prueba como te dije un led en el pin 3 con una Resistencia limitadora. Nunca conectes el led directo al pin.
Haz un código simple donde varies el brillo usando

analogWrite(pin, valor);

De cuento debería ser la resistencia, discúlpame, pero no sé nada de esto. Únicamente necesite un control de temperatura y después no me funcionó. Disculpa mi total ignorancia.
He colocado un led que pasa a través de s8050 y cuando el setpoin está por encima el led no brilla, cuando está por debajo sí. ¿Creo que debería ir al revés?




he buscado un pelin y he hecho esto

byte n;
void setup(){
   pinMode(3, OUTPUT);
}
void loop(){
   analogWrite(3, n);
   n++;
   delay(10);
}

el led va variando su intensidad, le puse una resistencia de 330 ohm.
Al final me he tirado 20 minutos jugando con 4 leds unos cuentos s8050 y el Arduino. Alimentos me divierto jejej