Hello everyone after searching the web I bother you with the following problem: I am putting together a device to melt wax. It consists of a 220 v / 1000 watt resistor, a ds18b20 temperature sensor and a 16x2 lcd display.
Basically the program what it does is to read the interruptions (of an optocoupler, zero crossing ) and then to fire a triac to handle the 220v of the resistance through a PID controller. The problem arises when I plug in the 220v: the interrupts are triggered and the screen runs very slowly. When I read millis or micros, I see that they do not run properly and everything is very slow.
#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 = 0;
unsigned long tiempoactual = 0;
unsigned long tiempoanterior = 0;
unsigned long tiempoanterior2 = 0;
unsigned long tiempoanterior3 = 0;
unsigned long tiempoanterior4 = 0;
unsigned long tiempoanterior5 = 0;
const byte boton = 9;
bool pressed_1 = false;
volatile bool encender = false;
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), interrupcion, 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(115200);
sensors.begin();
sensors.getAddress(Termometro, 0);
sensors.setResolution(Termometro, 9);
}
void loop() {
tiempoactual = millis();
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);
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;
}
PID_value = 7000;
// 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 interrupcion() {
resistencia();
}
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() {
if (tiempoactual - tiempoanterior4 >= 150) {
tiempoanterior4 = tiempoactual;
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() {
if (tiempoactual - tiempoanterior4 >= 100) {
tiempoanterior4 = tiempoactual;
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");
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;
}
The start and stop of the system is with a push button. The truth is I do not realize where I screw up ...
Thank you!!! (sorry for my bad english)