Hola a todos después de buscar por la web los molesto con el siguiente problema: estoy armando un aparato para derretir cera. Consta de una resistencia de 220 v / 1000 watts, un sensor de temperatura ds18b20 y un display lcd 16x2.
Básicamente el programa lo que hace es leer las interrupciones (de un optoacoplador, cruce por cero) y luego disparar un triac para manejar los 220v de la resistencia a través de un PID. El problema surge cuando enchufo los 220v: se disparan la interrupciones y sucede que la pantalla corre muy lenta. Cuando hago lecturas de millis o micros veo que no corren como corresponde y todo anda muy lento.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 11
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Termometro;
float temp = 0.0;
const byte rojo = 7;
const byte verde = 8;
bool estadoledv = true;
bool estadoledr = true;
const byte buzzer = 12;
bool estadobuzzer = false;
const byte interruptPin = 2;
const byte dimmer = 6;
int valor = 0;
byte setpoint = 38;
unsigned long elapsedTime = 0;
unsigned long Time = 0;
unsigned long timePrev = 0;
unsigned long tiempoactual = 0;
unsigned long tiempoanterior = 0;
unsigned long tiempoanterior2 = 0;
unsigned long tiempoanterior3 = 0;
unsigned long tiempoanterior4 = 0;
const byte boton = 9;
bool pressed_1 = false;
volatile bool encender = true;
byte a = 1;
byte n = 0;
float PID_error = 0.0;
float previous_error = 0.0;
volatile int PID_value = 0;
// ORIGINAL!!! : byte kp = 203; byte ki = 7.2; byte kd = 1.04;
int kp = 1000; byte ki = 0; byte kd = 25;
byte PID_p = 0; byte PID_i = 0; byte PID_d = 0;
void setup() {
lcd.begin();
Wire.setClock(100000L);
lcd.backlight();
pinMode(rojo, OUTPUT);
pinMode(verde, OUTPUT);
inicio();
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), resistencia, RISING);
pinMode(dimmer, OUTPUT);
digitalWrite(dimmer, LOW);
pinMode (boton, INPUT_PULLUP);
pinMode (buzzer, OUTPUT);
PCIFR |= (1 << PCIF0);
PCICR |= (1 << PCIE0);
PCMSK0 |= (1 << PCINT1);
Serial.begin(9600);
sensors.begin();
sensors.getAddress(Termometro, 0);
sensors.setResolution(Termometro, 9);
}
void loop() {
tiempoactual = micros() / 1000L;
if (tiempoactual - tiempoanterior2 >= 800 && a == 0) {
a = 1;
}
if (tiempoactual - tiempoanterior3 >= 3000) {
tiempoanterior3 = tiempoactual;
n++;
lcd.clear();
if (n == 2) {
n = 0;
}
}
switch (n) {
case 0:
estado();
break;
case 1:
temperatura();
break;
}
if (tiempoactual - tiempoanterior >= 500) {
tiempoanterior = tiempoactual;
// sensors.requestTemperatures();
// temp = sensors.getTempC(Termometro);
temp = 20.5;
if (encender) {
previous_error = PID_error;
PID_error = setpoint - temp;
if (PID_error > 30) //integral constant will only affect errors below 30ºC
{
PID_i = 0;
}
PID_p = kp * PID_error; //Calculate the P value
PID_i = PID_i + (ki * PID_error); //Calculate the I value
PID_d = kd * ((PID_error - previous_error) / 0.5); //Calculate the D value
PID_value = 9200.0 - (PID_p + PID_i + PID_d); //Calculate total PID value
//We define firing delay range between 0 and 7400. Read above why 7400!!!!!!!
if (PID_value < 0) {
PID_value = 0;
}
if (PID_value > 9200) {
PID_value = 9200;
}
Serial.println(tiempoactual);
// PID_value = 3000;
// LOW VERDE
PORTB &= B11111110;
if (!estadoledr) {
PORTD |= B10000000;
//ROJO HIGH
}
else {
//LOW ROJO
PORTD &= B01111111;
}
estadoledr = !estadoledr;
}
else {
// triac LOW
PORTD &= B10111111;
//LOW ROJO
PORTD &= B01111111;
if (!estadoledv) {
PORTB |= B11000001;
//VERDE HIGH
}
else {
// LOW VERDE
PORTB &= B11111110;
}
estadoledv = !estadoledv;
}
if (temp >= 30) {
if (!estadobuzzer) {
PORTB |= B11010000;
//BUZZER HIGH
}
else {
//BUZZER LOW
PORTB &= B11101111;
}
}
else {
//BUZZER LOW
PORTB &= B11101111;
}
estadobuzzer = !estadobuzzer;
}
}
void resistencia() {
// if (encender) {
delayMicroseconds(PID_value);
// triac high
PORTD |= B01000000;
delayMicroseconds(100);
// triac LOW
PORTD &= B10111111;
// }
}
ISR(PCINT0_vect) {
if (PINB & B00000010) {
if (a == 1) {
encender = !encender;
//Serial.println(encender);
tiempoanterior2 = tiempoactual;
a = 0;
}
}
}
void estado() {
lcd.setCursor(4, 0);
lcd.print("Estado:");
if (!encender) {
lcd.setCursor(3, 1);
lcd.print(" Detenido ");
}
else {
lcd.setCursor(3, 1);
lcd.print("Calentando");
}
}
void temperatura() {
lcd.setCursor(0, 0);
lcd.print("Temp.:");
lcd.setCursor(7, 0);
lcd.print(temp);
lcd.setCursor(13, 0);
lcd.print((char)223);
lcd.setCursor(14, 0);
lcd.print("C");
lcd.setCursor(3, 1);
lcd.print("Set:");
lcd.setCursor(8, 1);
lcd.print(valor);
lcd.setCursor(11, 1);
lcd.print((char)223);
lcd.setCursor(12, 1);
lcd.print("C");
if (tiempoactual - tiempoanterior4 >= 150) {
tiempoanterior4 = tiempoactual;
valor = analogRead(A0);
valor = map(valor, 0, 1023, 27 , 31);
}
}
void inicio() {
PORTD |= B10000000;
//ROJO HIGH
PORTB |= B11000001;
//VERDE HIGH
lcd.setCursor(4, 0);
lcd.print("INTRONIC");
delay(1000);
lcd.setCursor(0, 1);
lcd.print("Iniciando...");
delay(2000);
lcd.clear();
//LOW ROJO
PORTD &= B01111111;
// LOW VERDE
PORTB &= B11111110;
}
El arranque y parada del sistema es con un pulsador. La verdad no me doy cuenta donde meto la pata...
gracias!!!