Arduinos en BT

De Bajas Temperaturas
Revisión del 13:25 16 mar 2016 de Renex (discusión | contribuciones) (Comunicacion basica Arduino python)
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Ir a la navegaciónIr a la búsqueda

Tacómetro "spiner"

Horno "flash"

Baño termostático

<syntaxhighlight lang="php"> <?php

   $v = "string";    // sample initialization

?> html text <?

   echo $v;         // end of php code

?> </syntaxhighlight>

<syntaxhighlight lang="c">

/*** PROGAMA DE CONTROL DE LA PLANCHA CALEFACTORA ***/ /*** por Juan Zarate & Ignacio Artola ***/ /*** Laboratorio de Bajas Temperaturas ***/ /*** Noviembre de 2011 ***/

/*** Version 5 por Nadim Morhell & Leonardo Salazar ***/ /*** (Agregando dos termometros DS18B20 y dos circuitos OptoTriac-Triac para emular Reles) ***/ /*** Setiembre de 2014 ***/

/*** TO DO:

* .- Cambiar las direcciones de los termometros
* .- Cambiar los pines ReleyPin para las planchas
.- Conectar y probar  */

// LIBRERIAS

  1. include <avr/pgmspace.h>
  2. include <LiquidCrystal.h>
  3. include "constante_planchas_v5.h"
  4. include <MAX6675.h>
  1. include <OneWire.h> // Nadim Sep '14
  2. include <DallasTemperature.h> // Nadim Sep '14
  3. define TEMPERATURE_PRECISION 9 // 9 bits de resolucion. Para 1 grado de precision es suficiente
  4. define ONE_WIRE_BUS 3

// DEFINICION DE FUNCIONES void read_button(); void ch_MENU(); int add_setpoint(int setpoint, int max_setpoint); int sub_setpoint(int setpoint); int add_setpoint_f(int setpoint, int max_setpoint); int sub_setpoint_f(int setpoint); boolean button_long(unsigned long tiempo0, int buttonPin); void disp_MENU(); void disp_block_s (int columna, char string1[16], char string2[16]); void disp_block_n (int columna, float valor1, float valor2); void disp_encendido(int planchas); void control0_on_off(); void control_tau_on_off(); void calc_control_P(); void calc_control_PID(); //Cristal Líquido LiquidCrystal lcd(13, 12, 11, 10, 9, 8); //Lectura de termocupla void read_temp(); //Inicializacion del lector de termocupla

MAX6675 temp0(CS0,SO,SCK1,units);



// DEFINICION DE VARIABLES

int buttonStateMENU = LOW; int buttonStateUP = LOW; int buttonStateDOWN = LOW;

boolean b_state = false; boolean b_MENU = false; boolean b_UP = false; boolean b_DOWN = false; boolean b_long_MENU = false; boolean b_long_UP = false; boolean b_long_DOWN = false;

boolean plancha1 = false; boolean plancha2 = false; boolean plancha3 = false;

unsigned long time_button = 0; unsigned long time_disp = 0; unsigned long time_per1 = 0; unsigned long time_per2 = 0; unsigned long time_per3 = 0; unsigned long time_ctrl_ant = 0;

int Dtime_ctrl = 0;

float err1 = 0; float err1_ant = 0; float int1 = 0; float int1_next = 0; float der1 = 0; float Pot1 = 0; int t_on1 = 0;

float err2 = 0; float err2_ant = 0; float int2 = 0; float int2_next = 0; float der2 = 0; float Pot2 = 0; int t_on2 = 0;

float err3 = 0; float err3_ant = 0; float int3 = 0; float int3_next = 0; float der3 = 0; float Pot3 = 0; int t_on3 = 0;

int state_MENU = 0; int SetPoint1 = 100; int SetPoint2 = 100; int SetPoint3 = 100;

int Temp1 = 0; float Temp2 = 0; float Temp3 = 0;

int temp1_read = 0; int temp2_read = 0; int temp3_read = 0;

/* Para medir con los termometros onewire (Nadim Sep '14)*/ OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature. DeviceAddress termometro1={

 0x28, 0x56, 0x00, 0x7F, 0x03, 0x00, 0x00, 0x54 };

DeviceAddress termometro2={

 0x28, 0x6C, 0xE7, 0x7E, 0x03, 0x00, 0x00, 0x72 };   //Con estas variables vamos a identificar los termometros

////

/****************************************************************************/ /** MAIN SETUP **/ /****************************************************************************/

void setup() {

 /*pinMode(buttonPinMENU, INPUT);
  pinMode(buttonPinUP, INPUT);
  pinMode(buttonPinDOWN, INPUT);
  */
 pinMode(releyPlancha1Pin, OUTPUT);
 pinMode(releyPlancha2Pin, OUTPUT);
 pinMode(releyPlancha3Pin, OUTPUT);
 //  Serial.begin(9600);
 sensors.begin();    // Arranca los termometros OneWire (Nadim Sep '14)
 sensors.setResolution(termometro1, TEMPERATURE_PRECISION);
 sensors.setResolution(termometro2, TEMPERATURE_PRECISION);
 lcd.begin(16, 2);
 lcd.print("Planchita TEAM");
 disp_block_s(0,"Planchita TEAM","BT - CAB - BARIL");
 delay(2000);
 lcd.autoscroll();


}

/****************************************************************************/ /** MAIN LOOP **/ /****************************************************************************/

void loop(){

 //digitalWrite(releyPlancha1Pin, HIGH); 
 control_tau_on_off(); //Se controlan los relays, para apagarlos o encenderlos según t_onX
 if (millis()-time_button > ESP_BUTTON) read_button(); //Me fijo si se apreta boton, si pasó más de ESP_BUTTON desde el último evento
 if (b_state) ch_MENU(); //Si se apreto un boton, voy al control de Menus
 if (millis()-time_disp > ESP_DISP){ //Cada ESP_DISP ms, actualizo el valor de temperatura, los valores de t_onX y el display
   read_temp();
   control_max_temp();
   calc_control_PID();
   disp_MENU();
   //if(state_MENU == 1) imprime_seria();
 }

}

/****************************************************************************/ /** FUNCIONES DE CONTROL DE RELAY**/ /****************************************************************************/

void control_tau_on_off(){

 if (plancha1){
   if(millis()-time_per1 > TAU){
     time_per1 = millis();
     if(t_on1 > 0) digitalWrite(releyPlancha1Pin, HIGH);  
   }
   if(millis()-time_per1 > t_on1) digitalWrite(releyPlancha1Pin, LOW);     
 }
 else digitalWrite(releyPlancha1Pin, LOW);
 if (plancha2){
   if(millis()-time_per2 > TAU){
     time_per2 = millis();
     if(t_on2 > 0) digitalWrite(releyPlancha2Pin, HIGH);  
   }
   if(millis()-time_per2 > t_on2) digitalWrite(releyPlancha2Pin, LOW);     
 }
 else digitalWrite(releyPlancha2Pin, LOW);
 if (plancha3){
   if(millis()-time_per3 > TAU){
     time_per3 = millis();
     if(t_on3 > 0) digitalWrite(releyPlancha3Pin, HIGH);  
   }
   if(millis()-time_per3 > t_on3) digitalWrite(releyPlancha3Pin, LOW);     
 }
 else digitalWrite(releyPlancha3Pin, LOW);

}

void calc_control_P(){

 SetPoint1=SetPoint1/10;  // Agregado Nadim Sep '14 para solucionar la temp/10
 SetPoint2=SetPoint2/10;
 if(Temp1 > SetPoint1) t_on1 = 0;
 else if (SetPoint1 - Temp1 > MAX_ERR) t_on1 = TAU;
 else t_on1 = TAU * (SetPoint1 - Temp1) / MAX_ERR;
 if(Temp2 > SetPoint2) t_on2 = 0;
 else if (SetPoint2 - Temp2 > MAX_ERR) t_on2 = TAU;
 else t_on2 = TAU * (SetPoint2 - Temp2) / MAX_ERR;
 if(Temp3 > SetPoint3) t_on3 = 0;
 else if (SetPoint3 - Temp3 > MAX_ERR) t_on3 = TAU;
 else t_on3 = TAU * (SetPoint3 - Temp3) / MAX_ERR;

}

void calc_control_PID(){

 Dtime_ctrl = millis() - time_ctrl_ant;
 time_ctrl_ant = millis();
 if(plancha1){
   //err1 = SetPoint1 - Temp1;   
   err1 = SetPoint1/10 - Temp1;  //Modificado para que compare el setpoint contra el valor de temperatura sin dividir por 10
   int1_next = int1 + err1 * Dtime_ctrl;
   if(0 < (int1_next / Kint1) &&  (int1_next / Kint1) < MAX_INT) int1 = int1_next;
   der1 = err1/Dtime_ctrl;
   Pot1 = Kprop1 * (err1 + int1 / Kint1 - Kder1 * der1);
   if(Pot1 < 0) t_on1 = 0;
   else if (Pot1 > MAX_POT) t_on1 = TAU;
   else t_on1 = TAU * Pot1 / MAX_POT;
 }
 if(plancha2){
   //   err2 = SetPoint2 - Temp2;
   err2 = SetPoint2/10 - Temp2;
   int2_next = int2 + err2 * Dtime_ctrl;
   if(0 < (int2_next / Kint2) &&  (int2_next / Kint2) < MAX_INT) int2 = int2_next;
   der2 = err2/Dtime_ctrl;
   Pot2 = Kprop2 * (err2 + int2 / Kint2 - Kder2 * der2);
   if(Pot2 < 0) t_on2 = 0;
   else if (Pot2 > MAX_POT) t_on2 = TAU;
   else t_on2 = TAU * Pot2 / MAX_POT;
 }
 if(plancha3){
   err3 = SetPoint3 - Temp3;
   int3_next = int3 + err3 * Dtime_ctrl;
   if(0 < (int3_next / Kint3) &&  (int3_next / Kint3) < MAX_INT) int3 = int3_next;
   der3 = err3/Dtime_ctrl;
   Pot3 = Kprop3 * (err3 + int3 / Kint3 - Kder3 * der3);
   if(Pot3 < 0) t_on3 = 0;
   else if (Pot3 > MAX_POT) t_on3 = TAU;
   else t_on3 = TAU * Pot3 / MAX_POT;
 }

}

void control_max_temp(){

 if (Temp1 > MAX_TEMP) if(plancha1){
   plancha1 = false;
   disp_mex_temp(1);
 }
 if (Temp2 > MAX_TEMP) if(plancha2){
   plancha2 = false;
   disp_mex_temp(2);
 }
 if (Temp3 > MAX_TEMP) if(plancha3){
   plancha1 = false;
   disp_mex_temp(3);
 }

}

/****************************************************************************/ /** FUNCIONES DE LEER BOTONES **/ /****************************************************************************/

void read_button(){


 /*buttonStateMENU = digitalRead(buttonPinMENU);
  buttonStateUP   = digitalRead(buttonPinUP);
  buttonStateDOWN = digitalRead(buttonPinDOWN);
  */
 buttonStateMENU = analogRead(an_buttonPinMENU);
 buttonStateUP   = analogRead(an_buttonPinUP);
 buttonStateDOWN = analogRead(an_buttonPinDOWN);
 b_MENU = false;
 b_UP = false;
 b_DOWN = false;
 if(buttonStateMENU > AN_READ_ERR){
   b_MENU = true;
   b_state = true;   
 }
 if(buttonStateUP > AN_READ_ERR){
   b_UP = true;
   b_state = true;
 }
 if(buttonStateDOWN > AN_READ_ERR){
   b_DOWN = true;
   b_state = true;
 } 
 if(b_state == true) time_button = millis();
 if (b_MENU){
   if(!b_long_MENU) if( button_long(time_button, an_buttonPinMENU)) b_long_MENU = true;
 }
 else b_long_MENU = false;
 if (b_UP){
   if(!b_long_UP) if( button_long(time_button, an_buttonPinUP)) b_long_UP = true;
 }
 else b_long_UP = false;
 if (b_DOWN){
   if(!b_long_DOWN) if( button_long(time_button, an_buttonPinDOWN)) b_long_DOWN = true;
 }
 else b_long_DOWN = false;
 return;

}

/****************************************************************************/ /** FUNCIONES DEL MENU **/ /****************************************************************************/

void ch_MENU(){

 b_state = false;
 switch (state_MENU) {
 case 0:
   if(b_MENU){ 
     if (b_long_MENU){ 
       plancha1 = !plancha1;
       disp_encendido(1);
     }    
     else state_MENU = 1;
     break;
   }
   if(b_UP){
     if (b_long_UP){ 
       plancha2 = !plancha2;
       disp_encendido(2);
     }  
     break;
   }
   if(b_DOWN){
     if (b_long_DOWN){ 
       plancha3 = !plancha3;
       disp_encendido(3);
     }  
     break;
   }
 case 1:
   if(b_MENU){ 
     if (b_long_MENU){
       plancha1 = !plancha1;
       disp_encendido(1);
     }    
     else state_MENU = 2;
     break;
   }
   if(b_UP){
     if (b_long_UP) SetPoint1 = add_setpoint_f(SetPoint1, MAX_SETPOINT1);
     else SetPoint1 = add_setpoint(SetPoint1, MAX_SETPOINT1);
     break;
   }
   if(b_DOWN){
     if (b_long_DOWN) SetPoint1 = sub_setpoint_f(SetPoint1);
     else SetPoint1 = sub_setpoint(SetPoint1);
     break;
   }
 case 2:
   if(b_MENU){ 
     if (b_long_MENU){
       plancha2 = !plancha2;
       disp_encendido(2);
     }    
     else state_MENU = 3;
     break;
   }
   if(b_UP){
     if (b_long_UP) SetPoint2 = add_setpoint_f(SetPoint2, MAX_SETPOINT2);
     else SetPoint2 = add_setpoint(SetPoint2, MAX_SETPOINT2);
     break;
   }
   if(b_DOWN){
     if (b_long_DOWN) SetPoint2 = sub_setpoint_f(SetPoint2);
     else SetPoint2 = sub_setpoint(SetPoint2);
     break;
   }
 case 3:
   if(b_MENU){ 
     if (b_long_MENU){
       plancha3 = !plancha3;
       disp_encendido(3);
     }    
     else state_MENU = 0;
     break;
   }
   if(b_UP){
     if (b_long_UP) SetPoint3 = add_setpoint_f(SetPoint3, MAX_SETPOINT3);
     else SetPoint3 = add_setpoint(SetPoint3, MAX_SETPOINT3);
     break;
   }
   if(b_DOWN){
     if (b_long_DOWN) SetPoint3 = sub_setpoint_f(SetPoint3);
     else SetPoint3 = sub_setpoint(SetPoint3);
     break;
   }
 }
 return;

}


int add_setpoint(int setpoint, int max_setpoint){

 int old_setpoint;
 old_setpoint = setpoint;
 setpoint += 10;
 if (setpoint > max_setpoint) return old_setpoint;
 else return setpoint;

}

int sub_setpoint(int setpoint){

 int old_setpoint;
 old_setpoint = setpoint;
 setpoint -= 10;
 if (setpoint < MIN_SETPOINT) return old_setpoint;
 else return setpoint;

}

int add_setpoint_f(int setpoint, int max_setpoint){

 int old_setpoint;
 old_setpoint = setpoint;
 setpoint += 100;
 if (setpoint > max_setpoint) return old_setpoint;
 else return setpoint;

}

int sub_setpoint_f(int setpoint){

 int old_setpoint;
 old_setpoint = setpoint;
 setpoint -= 100;
 if (setpoint < MIN_SETPOINT) return old_setpoint;
 else return setpoint;

}


boolean button_long(unsigned long tiempo0, int an_buttonPin){

 while(analogRead(an_buttonPin) > AN_READ_ERR){
   if(millis()-tiempo0 > ESP_APAGADO){
     return true;
   }  
 }
 return false; 

}

/****************************************************************************/ /** FUNCIONES DE LECTURA ANALOGICA/ /****************************************************************************/ /** EDIT: En esta funcion agrego la lectura de los termometros ONEWIRE DS18B20 - Termometros1Wire.h - (Nadim SEP '14) */

void read_temp(){

 //  temp1_read = 10 * temp0.read_temp(NUM_RED_TEMP);
 temp1_read = 10 * temp0.read_temp();
 //temp2_read = 0;
 //temp3_read = 0;
 //  sensors.requestTemperatures();
 sensors.requestTemperaturesByAddress(termometro2);
 sensors.requestTemperaturesByAddress(termometro1);
 //Temp1 = (-2.5181 + 0.9829 * temp1_read);    //Calibración con fecha 31/10/2011.
 Temp1 =  sensors.getTempC(termometro2); // Address del termometro 2   
 Temp2 =  sensors.getTempC(termometro1); // Address del termometro 1  - Si no se la conoce, correr el ejemplo Multiple de la libreria Dallas Temperature 
 Temp3 = (-2.5181 + 0.9829 * temp1_read);    //Calibración con fecha 31/10/2011.
 //   Serial.println(Temp2);
 //  Device Address: 286CE77E03000072   Cable Amarillo
 //  Device Address: 2856007F03000054  Cable Violeta

}

/****************************************************************************/ /** FUNCIONES DEL DISPLAY **/ /****************************************************************************/

void disp_MENU(){

 time_disp = millis();
 lcd.begin(16, 2);
 switch (state_MENU) {
 case 0:
   if(plancha1)
     if(fabs(err1)<1) disp_block_s_n(0," ON ",float(Temp1));
     else disp_block_s_n(0,"-on-",float(Temp1));
   else disp_block_s_n(0,"    ",float(Temp1));
   disp_block_s(5,"#","#");
   if(plancha2)
     if(fabs(err2)<1) disp_block_s_n(6," ON ",float(Temp2));
     else disp_block_s_n(6,"-on-",float(Temp2));
   else disp_block_s_n(6,"    ",float(Temp2));
   disp_block_s(11,"#","#");
   if(plancha3)
     if(fabs(err3)<10) disp_block_s_n(12," ON ",float(Temp3)/10);
     else disp_block_s_n(12,"-on-",float(Temp3)/10);
   else disp_block_s_n(12,"    ",float(Temp3)/10);
   break; 
 case 1:
   disp_block_n(7,float(SetPoint1)/10,float(Temp1));
   if(plancha1){
     disp_block_s(0,"SET1 :","TEM1 :");
     if(fabs(err1)<10) disp_block_s(12,"  ON","    ");
     else disp_block_s(12," -on","    ");
   }
   else{
     disp_block_s(0,"set1 :","tem1 :");
     disp_block_s(12,"    "," off");
   }
   break;
 case 2:
   disp_block_n(7,float(SetPoint2)/10,float(Temp2));
   if(plancha2){
     disp_block_s(0,"SET2 :","TEM2 :");
     if(fabs(err2)<10) disp_block_s(12,"  ON","    ");
     else disp_block_s(12," -on","    ");
   }
   else{
     disp_block_s(0,"set2 :","tem2 :");
     disp_block_s(12,"    "," off");
   }
   break;
 case 3:
   disp_block_n(7,float(SetPoint3)/10,float(Temp3)/10);
   if(plancha3){
     disp_block_s(0,"SET3 :","TEM3 :");
     if(fabs(err2)<10) disp_block_s(12,"  ON","    ");
     else disp_block_s(12," -on","    ");
   }
   else{
     disp_block_s(0,"set3 :","tem3 :");
     disp_block_s(12,"    "," off");
   }
   break;
 }

}

void disp_block_s (int columna, char string1[16], char string2[16]){

 lcd.setCursor(columna, 0);
 lcd.print(string1);
 lcd.setCursor(columna, 1);
 lcd.print(string2);

}

void disp_block_n (int columna, float valor1, float valor2){

 lcd.setCursor(columna, 0);
 lcd.print(valor1);
 lcd.setCursor(columna, 1);
 lcd.print(valor2);

}

void disp_block_s_n (int columna, char string1[16], float valor2){

 lcd.setCursor(columna, 0);
 lcd.print(string1);
 lcd.setCursor(columna, 1);
 lcd.print(valor2);

}

void disp_encendido(int planchas){

 lcd.begin(16, 2);
 lcd.print("Enc/Apa Plancha");
 lcd.println(planchas,DEC);
 delay(int(ESP_APAGADO));

}

void disp_mex_temp(int planchas){

 lcd.begin(16, 2);
 lcd.print("MaXIMA TEMP -> ");  
 lcd.println(planchas,DEC);
 delay(3*int(ESP_APAGADO));

}

/* void imprime_seria(){

Serial.print(millis(), DEC);
Serial.print(" ");
Serial.print(float(SetPoint1)/10, DEC);
Serial.print(" ");  
Serial.print(float(Temp1)/10, DEC);
Serial.print(" ");  
Serial.print(100*t_on1/TAU, DEC);
Serial.print(" ");
Serial.print(Pot1, DEC);
Serial.print(" ");
Serial.print(err1, DEC);
Serial.print(" ");
Serial.print(int1 / Kint1, DEC);
Serial.print(" ");  
Serial.println(Kder1 * der1, DEC);

}
*/

</syntaxhighlight>

Sistema de detección de incendio con sensores de oxígeno y temperatura

Respositorio actualizado o por línea de comando

   git clone https://renecode@bitbucket.org/renecode/alarmosv1.git

Comunicacion Arduino python basico

   git clone https://github.com/renexdev/arduinopyserialcommV1.git