Components and supplies
MLX90614
Real Time Clock (RTC)
Arduino Mega 2560
Arduino Proto Shield
Tools and machines
FUSION 360
Cura By DAGOMA
Project description
Code
celio_full_sketch.ino
arduino
1// IDE ADRUINO V1.8.7 2// BOARD ARDUINO MEGA 2560 (no enough memory with UNO board) 3//______________________________ SERVO 4#include <Servo.h> 5#define UPDATE_TIME 10 6#define MAX_POS 180 7#define MIN_POS 0 8int servoPin = 9; 9int pulse = 1900; 10char s="1.5"; 11Servo HS64WP; 12int pos=0; 13int ServoPwr_pin = 8; 14int ServoPwr_led = 22; 15//______________________________ THERMOCOUPLE 16#include <Adafruit_MAX31855.h> 17Adafruit_MAX31855 *thermocouples[1]; 18float Tc_HSU_start, Tc_HSU_end; 19volatile float Tc_Heater; 20float Tc_MAX31855; 21//______________________________ IR SENSORs 22#include <Wire.h> 23#include <Adafruit_MLX90614.h> 24float TA90H,TO90H,TA10H,TO10H,TA90R,TO90R,RO90; 25Adafruit_MLX90614 mlx_fov10_Head = Adafruit_MLX90614(0x1B); // Head FOV90 26Adafruit_MLX90614 mlx_fov90_Head = Adafruit_MLX90614(0x5A); // Head FOV10 27Adafruit_MLX90614 mlx_fov90_Ref = Adafruit_MLX90614(0x3A); // Ref FOV90 28//______________________________ SD-CARD 29#include <SPI.h> 30#include <SD.h> 31const int chipSelect = 53; 32//______________________________ REAL TIME CLOCK DS1307 33#define DS1307_I2C_ADDRESS 0x68 34volatile int top, top60, top10, topD,Heat_cnt; 35byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 36int SQW_RTC_led = 2; 37//______________________________ RF433 MHZ 38//#include <RH_ASK.h> => can't be used simutaneously with another SPI component. => should be externalyzed 39// try to use RCSwitch or VirtualWire 40//______________________________ HEATER 12V-4W 41int HeaterPwr_pin = 7; 42int HeaterPwr_led = 23; 43//______________________________ GLOBAL VARIABLEs 44boolean HeaterPwr_cmd, Heater_break, Idle_mode; 45float voltage, MinTamb, Alt_ref_raw, Alt_head_raw, Alt_head_corr, Alt_dyn_raw, Alt_dyn_corr, KDG90, KDG10; 46String File_record = "Celio_A1"; 47volatile int Idle_cnt, Break_cnt, Clean_cnt; 48 49////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 50volatile float TPL_HH = 55; // (C) Thermal Protection Level High-High <> risk for PLA, absolute threshold to stop completely the main program. 51volatile float TPL_H = 45; // (C) Thermal Protection Level High <> permission to launch Start_up sequence in cas of several Power restart 52volatile float PwrSupply_ref = 7.45;// (V) Power Supply Volatege Reference <> shoudl be control due to risk of deviation +/- 53volatile float PwrSupply_db = 0.40; // (V) Dead band power supply for accessories <> below 7V the servo don't work correctly. 54volatile int HS64_offset = -12; // (step) aligne the deflector with the MLX axle. 55volatile float TMNICE = 2.0; // (C) thermal threshold to define the risk of ice and activate the Heater. Hysteresis is handle at +3C on pick-Up 56volatile float KHTO = 120; // (second) Heat TimeOut running => permit a safety break during heating. A n Breaker time is associated at the half 57////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 58////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 59////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 60void setup() { 61 62pinMode(HeaterPwr_pin, OUTPUT); 63pinMode(HeaterPwr_led, OUTPUT); 64pinMode(ServoPwr_pin, OUTPUT); 65pinMode(ServoPwr_led, OUTPUT); 66pinMode(SQW_RTC_led,OUTPUT); 67pinMode(3,INPUT_PULLUP); 68 69thermocouples[0] = new Adafruit_MAX31855(4, 5, 6); 70attachInterrupt (digitalPinToInterrupt(3), Flash_RTC , RISING ); 71 72Serial.begin(9600); 73 74mlx_fov10_Head.begin(); 75mlx_fov90_Head.begin(); 76mlx_fov90_Ref.begin(); 77 78Wire.begin(); 79Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0x07); Wire.write(0x10); 80Wire.endTransmission(); 81 82if (!SD.begin(chipSelect)) 83 {Serial.println("Card failed, or not present");return;} 84else 85 {Serial.println("card initialized."); 86 File dataFile = SD.open(File_record, FILE_WRITE); 87 if (dataFile) 88 { 89 dataFile.print("Date") ;dataFile.print(" ; "); 90 dataFile.print("Hour") ;dataFile.print(" ; "); 91 dataFile.print("Tamb_FOV90_Head") ;dataFile.print(" ; "); 92 dataFile.print("Tamb_FOV10_Head") ;dataFile.print(" ; "); 93 dataFile.print("Tamb_FOV90_Ref") ;dataFile.print(" ; "); 94 dataFile.print("Tobj_FOV90_Head") ;dataFile.print(" ; "); 95 dataFile.print("Tobj_FOV10_Head") ;dataFile.print(" ; "); 96 dataFile.print("Tobj_FOV90_Ref") ;dataFile.print(" ; "); 97 dataFile.print("Tc_Heater") ;dataFile.print(" ; "); 98 dataFile.print("Tc_MAX31855") ;dataFile.print(" ; "); 99 dataFile.print("Voltage") ;dataFile.print(" ; "); 100 dataFile.print("Rate_FOV90") ;dataFile.print(" ; "); 101 dataFile.print("Rate_FOV10") ;dataFile.print(" ; "); 102 dataFile.print("Altitude_raw") ;dataFile.print(" ; "); 103 dataFile.print("Altitude_corr") ;dataFile.print(" ; "); 104 dataFile.print("Idle_mode") ;dataFile.print(" ; "); 105 dataFile.print("HeaterPwr_cmd") ;dataFile.print(" ; "); 106 dataFile.print("Heater_break") ;dataFile.print(" ; "); 107 dataFile.print("Heat_count") ;dataFile.print(" ; "); 108 dataFile.println("File name") ;dataFile.close(); 109 }} 110 111StartUp(); 112 113HS64WP.attach(servoPin); 114for (pos = MIN_POS; pos <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); } 115delay(UPDATE_TIME);Serial.println("Configuration Corrected Measurment");delay(1000); 116top60 = 0; 117 118} 119 120////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 121////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 122////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 123void loop() { 124 125Tc_Heater = thermocouples[0]->readCelsius(); 126Thermal_Prot(); 127 128Tc_MAX31855 = thermocouples[0]->readInternal(); 129TA90H = mlx_fov90_Head.readAmbientTempC(); 130TA10H = mlx_fov10_Head.readAmbientTempC(); 131TA90R = mlx_fov90_Ref.readAmbientTempC(); 132voltage = analogRead(A0) * (5.0 / 1023.0) * (1680.0/680.0); // (R1 = 1 kOhm , R2 = 680 Ohms) 133TO90H = mlx_fov90_Head.readObjectTempC(); 134TO10H = mlx_fov10_Head.readObjectTempC(); 135TO90R = mlx_fov90_Ref.readObjectTempC(); 136 137KDG90 = TO90H / TO90R; 138KDG10 = TO10H / TO90R; 139 140MinTamb = min(TA90H,TA10H); // Mini Tambe sensor and not outdoor 141Alt_ref_raw = max(0,(( TA90R - TO90R) / 0.6) * 100); 142Alt_head_raw = max(0,(( TA90H - TO90H) / 0.6) * 100); 143Alt_head_corr = Alt_head_raw * KDG90; 144Alt_dyn_raw = max(0,(( TA10H - TO10H) / 0.6) * 100); 145Alt_dyn_corr = Alt_dyn_raw * KDG10; 146 147//[1] HEATING MANAGMENT___________________________________ 148if (MinTamb <= TMNICE && HeaterPwr_cmd == false && Heater_break == false) {HeaterPwr_cmd = true; } 149else if (MinTamb >= TMNICE + 3 or Heat_cnt >= KHTO) {HeaterPwr_cmd = false; Heat_cnt = 0; Heater_break = true;} 150 151//[2] CLEANING MANAGMENT__________________________________ 152 153if ( ((TA90H - TO90H) <= 2.0) && ((TA10H - TO10H) <= 2.0) && ((TA90R - TO90R) <= 2.0) && (Idle_mode == false) ) 154 {Monitor(); CleanUp(); Clean_cnt = Clean_cnt + 1;} 155else 156 {Clean_cnt = 0;} 157 158if (Clean_cnt >= 3) 159 {Serial.println("IDLE");for (pos = MAX_POS + HS64_offset; pos <= MIN_POS; pos -= 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 160 Idle_mode = true; 161 Alt_ref_raw = 0; 162 Alt_head_raw = 0; 163 Alt_head_corr = 0; 164 Alt_dyn_raw = 0; 165 Alt_dyn_corr = 0; 166 } 167 168 169//[3] RECORDING___________________________________________ 170if (top60 >= 10) { Record(); Monitor(); top60 = 0;} 171 172 173//[4] ACTUATORS CONTROL __________________________________ 174if (HeaterPwr_cmd == true) {digitalWrite(HeaterPwr_pin, HIGH); digitalWrite(HeaterPwr_led, HIGH); } else {digitalWrite(HeaterPwr_pin, LOW); digitalWrite(HeaterPwr_led, LOW); } 175 176} 177 178 179//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 180 181void CleanUp() 182{ 183 184Serial.println("Clean-Up"); 185for (pos = MIN_POS; pos <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 186delay(2000); 187 188} 189 190//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 191 192byte bcdToDec(byte val) 193{ return ( (val/16*10) + (val%16) );} 194 195void getDateDs1307(byte *second,byte *minute,byte *hour,byte *dayOfWeek,byte *dayOfMonth,byte *month,byte *year) //--- 196{ 197 Wire.beginTransmission(DS1307_I2C_ADDRESS); 198 Wire.write(0); 199 Wire.endTransmission(); 200 Wire.requestFrom(DS1307_I2C_ADDRESS, 7); 201 202 *second = (bcdToDec(Wire.read() & 0x7f)); 203 *minute = (bcdToDec(Wire.read())); 204 *hour = (bcdToDec(Wire.read() & 0x3f)); // Need to change this if 12 hour am/pm 205 *dayOfWeek = bcdToDec(Wire.read()); 206 *dayOfMonth = bcdToDec(Wire.read()); 207 *month = bcdToDec(Wire.read()); 208 *year = bcdToDec(Wire.read()); 209} 210 211//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 212 213void Flash_RTC () 214{ 215 216 top = top + 1; 217 top60 = top60 + 1; 218 219 digitalWrite(SQW_RTC_led,HIGH); 220 delay(500); 221 digitalWrite(SQW_RTC_led, LOW); 222 223if (HeaterPwr_cmd == true) {Heat_cnt = Heat_cnt + 1;} 224 225 switch(Heat_cnt) 226 { 227 case 30: CleanUp(); break; 228 case 60: CleanUp(); break; 229 case 90: CleanUp(); break; 230 case 120: CleanUp(); break; 231 } 232 233if (Heater_break == true) {Break_cnt = Break_cnt + 1;} 234if (Break_cnt >= KHTO / 2) {Heater_break = false; Break_cnt = 0;} 235 236if (Idle_mode == true) {Idle_cnt = Idle_cnt + 1;} 237if (Idle_cnt >= 600) {Idle_mode = false; Idle_cnt = 0;Clean_cnt = 0;} // cleanUp reset required to permit a new cycle of Cleaning and avoid looping 238} 239 240//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 241 242void Record() { 243 244 getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); 245 246 File dataFile = SD.open(File_record, FILE_WRITE); 247 248 if (dataFile) 249 { 250 dataFile.print(dayOfMonth);dataFile.print("/");dataFile.print(month);dataFile.print("/");dataFile.print(year);dataFile.print(" ; "); 251 dataFile.print(hour);dataFile.print(":");dataFile.print(minute);dataFile.print(":");dataFile.print(second);dataFile.print(" ; "); 252 dataFile.print(TA90H,2) ;dataFile.print(" ; "); 253 dataFile.print(TA10H,2) ;dataFile.print(" ; "); 254 dataFile.print(TA90R,2) ;dataFile.print(" ; "); 255 dataFile.print(TO90H,2) ;dataFile.print(" ; "); 256 dataFile.print(TO10H,2) ;dataFile.print(" ; "); 257 dataFile.print(TO90R,2) ;dataFile.print(" ; "); 258 dataFile.print(Tc_Heater,1) ;dataFile.print(" ; "); 259 dataFile.print(Tc_MAX31855,1) ;dataFile.print(" ; "); 260 dataFile.print(voltage,2) ;dataFile.print(" ; "); 261 dataFile.print(KDG90,3) ;dataFile.print(" ; "); 262 dataFile.print(KDG10,3) ;dataFile.print(" ; "); 263 dataFile.print(Alt_ref_raw,1) ;dataFile.print(" ; "); 264 dataFile.print(Alt_head_raw,1) ;dataFile.print(" ; "); 265 dataFile.print(Alt_head_corr,1) ;dataFile.print(" ; "); 266 dataFile.print(Alt_dyn_raw,1) ;dataFile.print(" ; "); 267 dataFile.print(Alt_dyn_corr,1) ;dataFile.print(" ; "); 268 dataFile.print(Idle_mode) ;dataFile.print(" ; "); 269 dataFile.print(HeaterPwr_cmd) ;dataFile.print(" ; "); 270 dataFile.print(Heater_break) ;dataFile.print(" ; "); 271 dataFile.print(Heat_cnt) ;dataFile.print(" ; "); 272 dataFile.println(File_record ) ;dataFile.close(); 273 } 274 275} 276 277//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 278 279 280void Monitor() { 281 282Serial.print(TA90H);Serial.print("C : "); 283Serial.print(TA10H);Serial.print("C : "); 284Serial.print(TA90R);Serial.print("C : >> "); 285Serial.print(Tc_Heater);Serial.print("C << : "); 286Serial.print(Tc_MAX31855);Serial.print("C : "); 287Serial.print(top);Serial.print("- : "); 288Serial.print(HeaterPwr_cmd);Serial.print(" : "); 289Serial.print(voltage);Serial.print("V : "); 290Serial.print(TO90H);Serial.print("C : "); 291Serial.print(TO10H);Serial.print("C : "); 292Serial.print(TO90R);Serial.print("C : "); 293Serial.print(Alt_ref_raw);Serial.print("m : "); 294Serial.print(Alt_head_raw);Serial.print("m : "); 295Serial.print(Alt_head_corr);Serial.print("m : "); 296Serial.print(Alt_dyn_raw);Serial.print("m : "); 297Serial.print(Alt_dyn_corr);Serial.print("m : "); 298Serial.print(KDG90);Serial.print("- : "); 299Serial.print(KDG10);Serial.print("- : "); 300Serial.print(top60);Serial.println("- : "); 301 302} 303 304//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 305 306int laps, SUHT_STOP; 307float deltat, volt_max, volt_min; 308 309void StartUp() { 310 311Tc_Heater = thermocouples[0]->readCelsius(); 312 313if (Tc_Heater <= TPL_H) { 314 315digitalWrite(HeaterPwr_pin, LOW);digitalWrite(HeaterPwr_led, LOW); 316digitalWrite(ServoPwr_pin, LOW);digitalWrite(HeaterPwr_led, LOW); 317 318Serial.println(">>>>>>>>>START-UP<<<<<<<<<<"); 319 320Serial.println("(1) HEATER TEST ______________"); 321 322Serial.print("Temp Tc Heater:"); 323Tc_HSU_start = thermocouples[0]->readCelsius(); 324volt_max = Tc_HSU_start; 325volt_min = Tc_HSU_start; 326Serial.print(Tc_HSU_start);Serial.println(" C"); 327delay(1000); 328laps = 0; 329Serial.println("-->HEATER ON"); 330 do {digitalWrite(HeaterPwr_pin, HIGH);digitalWrite(HeaterPwr_led, HIGH); 331 laps = laps + 1 ; 332 deltat=thermocouples[0]->readCelsius()-Tc_HSU_start; 333 voltage = analogRead(A0) * (5.0 / 1023.0) * (1680.0/680.0); 334 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 335 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;} 336 Serial.print(laps);Serial.print(" : "); 337 Serial.print(voltage);Serial.print(" : "); 338 Serial.print(deltat);Serial.println(" : "); 339 if (volt_max - volt_min > (2 * PwrSupply_db)) {Serial.println("TRIP BOARD - POWER SUPPLY ISSUE"); delay(250); exit(0);} 340 if (voltage < (PwrSupply_ref-PwrSupply_db)) {Serial.println("TRIP BOARD - POWER SUPPLY TOO LOW"); delay(250); exit(0);} 341 if (laps == 40 && deltat <= 5.0) {Serial.println("TRIP BOARD - NO HEATING"); delay(250); exit(0);} 342 if (thermocouples[0]->readCelsius() > TPL_HH) {Serial.println("TRIP BOARD - Too HOT"); delay(250); exit(0);} 343 if (laps >=40 || deltat >= 5.0) {SUHT_STOP = 1;} else {SUHT_STOP = 0;} 344 delay(1000); } while ( SUHT_STOP == 0); 345 346digitalWrite(HeaterPwr_pin, LOW); digitalWrite(HeaterPwr_led, LOW);Serial.println("-->HEATER OFF");} else {Serial.println("TRIP BOARD - Too HOT"); delay(250); exit(0);} 347 348Serial.println("(2) SERVO TEST ______________"); 349HS64WP.attach(servoPin); 350digitalWrite(ServoPwr_pin, HIGH); digitalWrite(ServoPwr_led, HIGH); Serial.println("SERVO ON"); 351delay(1000); 352 353 354for (pos = MIN_POS; pos <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME); 355 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 356 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;}} 357 Serial.println("Configuration Corrected Measurment");delay(2000); 358for (pos = MAX_POS+HS64_offset; pos >= 85+HS64_offset; pos -= 1) { HS64WP.write(pos); delay(UPDATE_TIME); 359 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 360 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;}} 361 Serial.println("Configuration Head Measurment only");delay(2000); 362for (pos = 90+HS64_offset; pos >= MIN_POS; pos -= 1) { HS64WP.write(pos); delay(UPDATE_TIME); 363 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 364 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;}} 365 Serial.println("Safe location - Measurment OFF");delay(2000); 366 367 368Serial.println("END START-UP ______________"); 369 370} 371 372//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 373 374void Thermal_Prot() {if (Tc_Heater > TPL_HH) {Serial.println("TRIP BOARD - OVERHEAT");delay(250);exit(0);}} 375
Main Program
arduino
Updated Revision with several improvements
1// IDE ADRUINO V1.8.7 2// BOARD ARDUINO MEGA 2560 (no enough memory with UNO board) 3//______________________________ SERVO 4#include <Servo.h> 5#define UPDATE_TIME 10 6#define MAX_POS 180 7#define MIN_POS 0 8int servoPin = 9; 9int pulse = 1900; 10char s="1.5"; 11Servo HS64WP; 12int pos=0; 13int ServoPwr_pin = 8; 14int ServoPwr_led = 23; 15//______________________________ THERMOCOUPLE 16#include <Adafruit_MAX31855.h> 17Adafruit_MAX31855 *thermocouples[1]; 18float Tc_HSU_start, Tc_HSU_end; 19volatile float Tc_Heater; 20float Tc_MAX31855; 21//______________________________ IR SENSORs 22#include <Wire.h> 23#include <Adafruit_MLX90614.h> 24volatile float TA90H,TO90H,TA10H,TO10H,TA90R,TO90R,Text; 25volatile float TA90H_int,TO90H_int,TA10H_int,TO10H_int,TA90R_int,TO90R_int; 26Adafruit_MLX90614 mlx_fov10_Head = Adafruit_MLX90614(0x1B); // Head FOV90 27Adafruit_MLX90614 mlx_fov90_Head = Adafruit_MLX90614(0x5A); // Head FOV10 28Adafruit_MLX90614 mlx_fov90_Ref = Adafruit_MLX90614(0x3A); // Ref FOV90 29//______________________________ SD-CARD 30#include <SPI.h> 31#include <SD.h> 32const int chipSelect = 53; 33//______________________________ REAL TIME CLOCK DS1307 34#define DS1307_I2C_ADDRESS 0x68 35volatile int top,Heat_cnt; 36byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 37int SQW_RTC_led = 24; 38//______________________________ RF433 MHZ 39//#include <RH_ASK.h> => can't be used simutaneously with another SPI component. => should be externalyzed 40// try to use RCSwitch or VirtualWire 41//______________________________ HEATER 12V-4W 42int HeaterPwr_pin = 7; 43int HeaterPwr_led = 22; 44//______________________________ GLOBAL VARIABLEs 45boolean HeaterPwr_cmd, Heater_break, Idle_mode; 46float MinTamb, Alt_ref_raw, Alt_head_raw, Alt_head_corr, Alt_dyn_raw, Alt_dyn_corr, KDG90, KDG10; 47volatile float voltage, voltage_int; 48String File_record = "Celio_A3"; 49volatile int Idle_cnt, Break_cnt, Clean_cnt; 50 51////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 52volatile float TPL_HH = 55; // (C) Thermal Protection Level High-High <> risk for PLA, absolute threshold to stop completely the main program. 53volatile float TPL_H = 45; // (C) Thermal Protection Level High <> permission to launch Start_up sequence in cas of several Power restart 54volatile float PwrSupply_ref = 7.45;// (V) Power Supply Volatege Reference <> shoudl be control due to risk of deviation +/- 55volatile float PwrSupply_db = 0.40; // (V) Dead band power supply for accessories <> below 7V the servo don't work correctly. 56volatile int HS64_offset = -2; // (step) aligne the deflector with the MLX axle. 57volatile float TMNICE = 2.0; // (C) thermal threshold to define the risk of ice and activate the Heater. Hysteresis is handle at +3C on pick-Up 58volatile float KHTO = 120; // (second) Heat TimeOut running => permit a safety break during heating. A n Breaker time is associated at the half 59volatile float KIdle_dly = 30; // (second) time delay to maintain the Idle mode 60int NBS = 10.0; // (Numbers of top-1Hz <> NB seconds) define the recording frequency 61////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 62////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 63////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 64void setup() { 65 66pinMode(HeaterPwr_pin, OUTPUT); 67pinMode(HeaterPwr_led, OUTPUT); 68pinMode(ServoPwr_pin, OUTPUT); 69pinMode(ServoPwr_led, OUTPUT); 70pinMode(SQW_RTC_led,OUTPUT); 71pinMode(3,INPUT_PULLUP); 72 73thermocouples[0] = new Adafruit_MAX31855(4, 5, 6); 74attachInterrupt (digitalPinToInterrupt(3), Flash_RTC , RISING ); 75 76Serial.begin(9600); 77 78mlx_fov10_Head.begin(); 79mlx_fov90_Head.begin(); 80mlx_fov90_Ref.begin(); 81 82Wire.begin(); 83Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0x07); Wire.write(0x10); 84Wire.endTransmission(); 85 86if (!SD.begin(chipSelect)) 87 {Serial.println("Card failed, or not present"); exit(0);} 88else 89 {Serial.println("card initialized."); 90 File dataFile = SD.open(File_record, FILE_WRITE); 91 if (dataFile) 92 { 93 dataFile.print("Date") ;dataFile.print(" ; "); 94 dataFile.print("Hour") ;dataFile.print(" ; "); 95 dataFile.print("Tamb_FOV90_Head") ;dataFile.print(" ; "); 96 dataFile.print("Tamb_FOV10_Head") ;dataFile.print(" ; "); 97 dataFile.print("Tamb_FOV90_Ref") ;dataFile.print(" ; "); 98 dataFile.print("Tobj_FOV90_Head") ;dataFile.print(" ; "); 99 dataFile.print("Tobj_FOV10_Head") ;dataFile.print(" ; "); 100 dataFile.print("Tobj_FOV90_Ref") ;dataFile.print(" ; "); 101 dataFile.print("Tc_Heater") ;dataFile.print(" ; "); 102 dataFile.print("Tc_MAX31855") ;dataFile.print(" ; "); 103 dataFile.print("Voltage") ;dataFile.print(" ; "); 104 dataFile.print("Rate_FOV90") ;dataFile.print(" ; "); 105 dataFile.print("Rate_FOV10") ;dataFile.print(" ; "); 106 dataFile.print("Alt_ref_raw") ;dataFile.print(" ; "); 107 dataFile.print("Alt_head_raw") ;dataFile.print(" ; "); 108 dataFile.print("Alt_head_corr") ;dataFile.print(" ; "); 109 dataFile.print("Alt_dyn_raw") ;dataFile.print(" ; "); 110 dataFile.print("Alt_dyn_corr") ;dataFile.print(" ; "); 111 dataFile.print("Idle_mode") ;dataFile.print(" ; "); 112 dataFile.print("HeaterPwr_cmd") ;dataFile.print(" ; "); 113 dataFile.print("Heater_break") ;dataFile.print(" ; "); 114 dataFile.print("Heat_count") ;dataFile.print(" ; "); 115 dataFile.println("File name") ;dataFile.close(); 116 }} 117 118StartUp(); 119Run(); 120top = 0; 121 122} 123 124////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 125////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 126////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 127void loop() { 128 129Tc_Heater = thermocouples[0]->readCelsius(); 130Thermal_Prot(); 131 132HS64WP.attach(servoPin); 133 134Tc_MAX31855 = thermocouples[0]->readInternal(); 135TA90H = mlx_fov90_Head.readAmbientTempC(); 136TA10H = mlx_fov10_Head.readAmbientTempC(); 137TA90R = mlx_fov90_Ref.readAmbientTempC(); 138voltage = analogRead(A0) * (5.0 / 1023.0) * (1680.0/680.0); // (R1 = 1 kOhm , R2 = 680 Ohms) 139TO90H = mlx_fov90_Head.readObjectTempC(); 140TO10H = mlx_fov10_Head.readObjectTempC(); 141TO90R = mlx_fov90_Ref.readObjectTempC(); 142Text = TA90R; 143 144//[1] HEATING MANAGMENT___________________________________ 145MinTamb = min(TA90H,TA10H); // Mini Tambe sensor and not outdoor 146if (MinTamb <= TMNICE && HeaterPwr_cmd == false && Heater_break == false) 147 {HeaterPwr_cmd = true; } 148else if ((MinTamb >= TMNICE + 3) or (Heat_cnt >= KHTO)) 149 {HeaterPwr_cmd = false; Heat_cnt = 0; Heater_break = true;} 150 151switch(Heat_cnt) 152{ 153 case 30: CleanUp(); Serial.println("CleanUp during Heating");break; 154 case 60: CleanUp(); Serial.println("CleanUp during Heating");break; 155 case 90: CleanUp(); Serial.println("CleanUp during Heating");break; 156 case 120: CleanUp(); Serial.println("CleanUp during Heating");break; 157} 158 159//[2] CLEANING MANAGMENT__________________________________ 160 161if ( (((TA90H - TO90H) <= 2.0) || ((TA10H - TO10H) <= 2.0) ) && (Idle_mode == false) ) 162 {Monitor(); Clean_cnt = Clean_cnt + 1;Serial.println(Clean_cnt);CleanUp();} 163else 164 {Clean_cnt = constrain((Clean_cnt -1),0,10000);} 165 166 167if ((Clean_cnt >= 3) && (Idle_mode == false)) 168 {Serial.println("IDLE"); 169 Idle(); 170 Idle_mode = true; 171 Alt_ref_raw = 0; Alt_head_raw = 0; Alt_head_corr = 0; Alt_dyn_raw = 0; Alt_dyn_corr = 0; 172 } 173 174 175 176//[3] ACTUATORS CONTROL __________________________________ 177if (HeaterPwr_cmd == true) {digitalWrite(HeaterPwr_pin, HIGH); digitalWrite(HeaterPwr_led, HIGH); } else {digitalWrite(HeaterPwr_pin, LOW); digitalWrite(HeaterPwr_led, LOW); } 178 179 180//[4] RECORDING___________________________________________ 181if (top >= NBS) 182{ 183 184TA90H = TA90H_int / NBS; 185TO90H = TO90H_int / NBS; 186TA10H = TA10H_int / NBS; 187TO10H = TO10H_int / NBS; 188TA90R = TA90R_int / NBS; 189TO90R = TO90R_int / NBS; 190voltage = voltage_int / NBS; 191 192KDG90 = TO90H / TO90R; 193KDG10 = TO10H / TO90R; 194 195if (Idle_mode == true) 196{ 197 Alt_ref_raw = 0; 198 Alt_head_raw = 0; 199 Alt_head_corr = 0; 200 Alt_dyn_raw = 0; 201 Alt_dyn_corr = 0; 202} 203else 204{ 205 Alt_ref_raw = constrain(((( Text - TO90R) / 0.6) * 100),0,10000); 206 Alt_head_raw = constrain(((( Text - TO90H) / 0.6) * 100),0,10000); 207 Alt_head_corr = constrain(Alt_head_raw * KDG90,0,10000); 208 Alt_dyn_raw = constrain(((( Text - TO10H) / 0.6) * 100),0,10000); 209 Alt_dyn_corr = constrain(Alt_dyn_raw * KDG10,0,10000); 210} 211 212Record(); Monitor(); 213 214top = 0; 215 216TA90H_int = 0; 217TO90H_int = 0; 218TA10H_int = 0; 219TO10H_int = 0; 220TA90R_int = 0; 221TO90R_int = 0; 222voltage_int = 0; 223 224} 225 226} 227 228void CleanUp() 229{ 230 231Serial.println("Clean-Up on run"); 232digitalWrite(ServoPwr_pin, HIGH); digitalWrite(ServoPwr_led, HIGH); 233delay(500); 234for (pos = MIN_POS; pos <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 235delay(1000); 236//digitalWrite(ServoPwr_pin, LOW); digitalWrite(ServoPwr_led, LOW); 237} 238 239byte bcdToDec(byte val) 240{ return ( (val/16*10) + (val%16) );} 241 242void getDateDs1307(byte *second,byte *minute,byte *hour,byte *dayOfWeek,byte *dayOfMonth,byte *month,byte *year) //--- 243{ 244 Wire.beginTransmission(DS1307_I2C_ADDRESS); 245 Wire.write(0); 246 Wire.endTransmission(); 247 Wire.requestFrom(DS1307_I2C_ADDRESS, 7); 248 249 *second = (bcdToDec(Wire.read() & 0x7f)); 250 *minute = (bcdToDec(Wire.read())); 251 *hour = (bcdToDec(Wire.read() & 0x3f)); // Need to change this if 12 hour am/pm 252 *dayOfWeek = bcdToDec(Wire.read()); 253 *dayOfMonth = bcdToDec(Wire.read()); 254 *month = bcdToDec(Wire.read()); 255 *year = bcdToDec(Wire.read()); 256} 257 258void Flash_RTC () 259{ 260 261 Thermal_Prot(); // already activated by the main loop , this crutial function is recall here to avoid infite loop condition in the main program. 262 263 top = top + 1; 264 265 266 digitalWrite(SQW_RTC_led,HIGH); 267 delay(500); 268 269 270if (HeaterPwr_cmd == true) {Heat_cnt = Heat_cnt + 1;} 271 272if (Heater_break == true) {Break_cnt = Break_cnt + 1;} 273if (Break_cnt >= KHTO / 2) {Heater_break = false; Break_cnt = 0;} 274 275if (Idle_mode == true) {Idle_cnt = Idle_cnt + 1;Serial.println(Idle_cnt);} 276if (Idle_cnt >= KIdle_dly) {Idle_mode = false; Idle_cnt = 0;Clean_cnt = 0;} // cleanUp reset required to permit a new cycle of Cleaning and avoid looping 277 278TA90H_int = TA90H_int + TA90H; 279TO90H_int = TO90H_int + TO90H; 280TA10H_int = TA10H_int + TA10H; 281TO10H_int = TO10H_int + TO10H; 282TA90R_int = TA90R_int + TA90R; 283TO90R_int = TO90R_int + TO90R; 284voltage_int = voltage_int + voltage; 285 286 287 288 digitalWrite(SQW_RTC_led, LOW); 289} 290 291void Idle() 292{ 293 294Serial.println("Return on idle"); 295digitalWrite(ServoPwr_pin, HIGH); digitalWrite(ServoPwr_led, HIGH); 296delay(500); 297for (pos = MAX_POS+HS64_offset; pos >= 0; pos -= 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 298delay(1000); 299digitalWrite(ServoPwr_pin, LOW); digitalWrite(ServoPwr_led, LOW); 300 301} 302 303void Record() { 304 305 getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); 306 307 File dataFile = SD.open(File_record, FILE_WRITE); 308 309 if (dataFile) 310 { 311 dataFile.print(dayOfMonth);dataFile.print("/");dataFile.print(month);dataFile.print("/");dataFile.print(year);dataFile.print(" ; "); 312 dataFile.print(hour);dataFile.print(":");dataFile.print(minute);dataFile.print(":");dataFile.print(second);dataFile.print(" ; "); 313 dataFile.print(TA90H,2) ;dataFile.print(" ; "); 314 dataFile.print(TA10H,2) ;dataFile.print(" ; "); 315 dataFile.print(TA90R,2) ;dataFile.print(" ; "); 316 dataFile.print(TO90H,2) ;dataFile.print(" ; "); 317 dataFile.print(TO10H,2) ;dataFile.print(" ; "); 318 dataFile.print(TO90R,2) ;dataFile.print(" ; "); 319 dataFile.print(Tc_Heater,1) ;dataFile.print(" ; "); 320 dataFile.print(Tc_MAX31855,1) ;dataFile.print(" ; "); 321 dataFile.print(voltage,2) ;dataFile.print(" ; "); 322 dataFile.print(KDG90,3) ;dataFile.print(" ; "); 323 dataFile.print(KDG10,3) ;dataFile.print(" ; "); 324 dataFile.print(Alt_ref_raw,1) ;dataFile.print(" ; "); 325 dataFile.print(Alt_head_raw,1) ;dataFile.print(" ; "); 326 dataFile.print(Alt_head_corr,1) ;dataFile.print(" ; "); 327 dataFile.print(Alt_dyn_raw,1) ;dataFile.print(" ; "); 328 dataFile.print(Alt_dyn_corr,1) ;dataFile.print(" ; "); 329 dataFile.print(Idle_mode) ;dataFile.print(" ; "); 330 dataFile.print(HeaterPwr_cmd) ;dataFile.print(" ; "); 331 dataFile.print(Heater_break) ;dataFile.print(" ; "); 332 dataFile.print(Heat_cnt) ;dataFile.print(" ; "); 333 dataFile.println(File_record ) ;dataFile.close(); 334 } 335 336} 337 338void Run() 339 340{ 341 342Serial.println("Run"); 343 344digitalWrite(ServoPwr_pin, HIGH); digitalWrite(ServoPwr_led, HIGH); 345delay(500); 346for (pos = MIN_POS; pos <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 347delay(1000); 348//digitalWrite(ServoPwr_pin, LOW); digitalWrite(ServoPwr_led, LOW); 349 350} 351 352void Monitor() { 353 354Serial.print(TA90H);Serial.print("C : "); 355Serial.print(TA10H);Serial.print("C : "); 356Serial.print(TA90R);Serial.print("C : >> "); 357Serial.print(Tc_Heater);Serial.print("C << : "); 358Serial.print(Tc_MAX31855);Serial.print("C : "); 359Serial.print(top);Serial.print("- : "); 360Serial.print(HeaterPwr_cmd);Serial.print(" : "); 361Serial.print(voltage);Serial.print("V : "); 362Serial.print(TO90H);Serial.print("C : "); 363Serial.print(TO10H);Serial.print("C : "); 364Serial.print(TO90R);Serial.print("C : "); 365Serial.print(Alt_ref_raw);Serial.print("m : "); 366Serial.print(Alt_head_raw);Serial.print("m : "); 367Serial.print(Alt_head_corr);Serial.print("m : "); 368Serial.print(Alt_dyn_raw);Serial.print("m : "); 369Serial.print(Alt_dyn_corr);Serial.print("m : "); 370Serial.print(KDG90);Serial.print("- : "); 371Serial.println(KDG10); 372 373 374} 375 376int laps, SUHT_STOP; 377float deltat, volt_max, volt_min; 378 379void StartUp() { 380 381Tc_Heater = thermocouples[0]->readCelsius(); 382 383if (Tc_Heater <= TPL_H) { 384 385digitalWrite(HeaterPwr_pin, LOW);digitalWrite(HeaterPwr_led, LOW); 386digitalWrite(ServoPwr_pin, LOW);digitalWrite(HeaterPwr_led, LOW); 387 388Serial.println(">>>>>>>>>START-UP<<<<<<<<<<"); 389 390Serial.println("(1) HEATER TEST ______________"); 391 392Serial.print("Temp Tc Heater:"); 393Tc_HSU_start = thermocouples[0]->readCelsius(); 394volt_max = Tc_HSU_start; 395volt_min = Tc_HSU_start; 396Serial.print(Tc_HSU_start);Serial.println(" C"); 397delay(1000); 398laps = 0; 399Serial.println("-->HEATER ON"); 400 do {digitalWrite(HeaterPwr_pin, HIGH);digitalWrite(HeaterPwr_led, HIGH); 401 laps = laps + 1 ; 402 deltat=thermocouples[0]->readCelsius()-Tc_HSU_start; 403 voltage = analogRead(A0) * (5.0 / 1023.0) * (1680.0/680.0); 404 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 405 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;} 406 Serial.print(laps);Serial.print(" : "); 407 Serial.print(voltage);Serial.print(" : "); 408 Serial.print(deltat);Serial.println(" : "); 409 if (volt_max - volt_min > (2 * PwrSupply_db)) {Serial.println("TRIP BOARD - POWER SUPPLY ISSUE"); delay(250); exit(0);} 410 if (voltage < (PwrSupply_ref-PwrSupply_db)) {Serial.println("TRIP BOARD - POWER SUPPLY TOO LOW"); delay(250); exit(0);} 411 if (laps == 40 && deltat <= 5.0) {Serial.println("TRIP BOARD - NO HEATING"); delay(250); exit(0);} 412 if (thermocouples[0]->readCelsius() > TPL_HH) {Serial.println("TRIP BOARD - Too HOT"); delay(250); exit(0);} 413 if (laps >=40 || deltat >= 5.0) {SUHT_STOP = 1;} else {SUHT_STOP = 0;} 414 delay(1000); } while ( SUHT_STOP == 0); 415 416digitalWrite(HeaterPwr_pin, LOW); digitalWrite(HeaterPwr_led, LOW);Serial.println("-->HEATER OFF");} else {Serial.println("TRIP BOARD - Too HOT"); delay(500); exit(0);} 417 418Serial.println("(2) SERVO TEST ______________"); 419HS64WP.attach(servoPin); 420digitalWrite(ServoPwr_pin, HIGH); digitalWrite(ServoPwr_led, HIGH); Serial.println("SERVO ON"); 421delay(1000); 422 423 424for (pos = MIN_POS; pos <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME); 425 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 426 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;}} 427 Serial.println("Configuration Corrected Measurment");delay(2000); 428for (pos = MAX_POS+HS64_offset; pos >= 85+HS64_offset; pos -= 1) { HS64WP.write(pos); delay(UPDATE_TIME); 429 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 430 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;}} 431 Serial.println("Configuration Head Measurment only");delay(2000); 432for (pos = 90+HS64_offset; pos >= MIN_POS; pos -= 1) { HS64WP.write(pos); delay(UPDATE_TIME); 433 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 434 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;}} 435 Serial.println("Safe location - Measurment OFF");delay(2000); 436 437 438Serial.println("END START-UP ______________"); 439digitalWrite(ServoPwr_pin, LOW); digitalWrite(ServoPwr_led, LOW); 440 441} 442 443void Thermal_Prot() 444 445{ 446 447 448//if ((Tc_Heater > TPL_HH) || (voltage < (PwrSupply_ref-PwrSupply_db))) 449if (Tc_Heater > TPL_HH) 450 {Serial.println("TRIP BOARD - OVERHEAT or LOW-VOLTAGE");delay(500);exit(0);} 451 452} 453 454/* 455Version Celio_A2 456############################################################################################################################################################## 457>manage Heater only with external temperature <> that mean Ambient temp from Reference MLX90614 458>keep 2C of lower lever hysteresis and increase upper level from 3 to 5C 459>recalculate altitudes from each sensors with raw and corrected result. 460>re adjust Deflector's offset 461>shutdown servo powersupply if not required = on idle 462>gain reactivity by calling the Thermal protection from the loop Flash RTC which is still workingat 1Hz (The main Loop can cumulate several delays) 463>Change conditions for Clean Up replace AND between IR sensors by OR 464 465Note: we temporaly remove de flash Led RTC which created disturbance with the Servo Signal pin. 466The servo is hold powered on on High position (measurment) and just shutdonw on idle. 467In all cases we withdrew the unstabilities 468 469 470Version Celio_A3 471############################################################################################################################################################## 472>Voltage recording unavailable... bad definition 473>correct Altitude calculation an declare a new variable to avoid confusion TA90R=Text 474>upgrade head name on record file 475 476For next step 477...>add voltage control in thermal loop... if no power supply => no protection = stop the main program (Exit0) 478 */ 479
celio_full_sketch.ino
arduino
1// IDE ADRUINO V1.8.7 2// BOARD ARDUINO MEGA 2560 (no enough memory 3 with UNO board) 4//______________________________ SERVO 5#include <Servo.h> 6#define 7 UPDATE_TIME 10 8#define MAX_POS 180 9#define MIN_POS 0 10int servoPin = 9; 11int 12 pulse = 1900; 13char s="1.5"; 14Servo HS64WP; 15int pos=0; 16int ServoPwr_pin 17 = 8; 18int ServoPwr_led = 22; 19//______________________________ THERMOCOUPLE 20#include 21 <Adafruit_MAX31855.h> 22Adafruit_MAX31855 *thermocouples[1]; 23float Tc_HSU_start, 24 Tc_HSU_end; 25volatile float Tc_Heater; 26float Tc_MAX31855; 27//______________________________ 28 IR SENSORs 29#include <Wire.h> 30#include <Adafruit_MLX90614.h> 31float TA90H,TO90H,TA10H,TO10H,TA90R,TO90R,RO90; 32Adafruit_MLX90614 33 mlx_fov10_Head = Adafruit_MLX90614(0x1B); // Head FOV90 34Adafruit_MLX90614 mlx_fov90_Head 35 = Adafruit_MLX90614(0x5A); // Head FOV10 36Adafruit_MLX90614 mlx_fov90_Ref = Adafruit_MLX90614(0x3A); 37 // Ref FOV90 38//______________________________ SD-CARD 39#include <SPI.h> 40#include 41 <SD.h> 42const int chipSelect = 53; 43//______________________________ REAL TIME 44 CLOCK DS1307 45#define DS1307_I2C_ADDRESS 0x68 46volatile int top, top60, top10, 47 topD,Heat_cnt; 48byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 49int 50 SQW_RTC_led = 2; 51//______________________________ RF433 MHZ 52//#include <RH_ASK.h> 53 => can't be used simutaneously with another SPI component. => should be externalyzed 54// 55 try to use RCSwitch or VirtualWire 56//______________________________ HEATER 12V-4W 57int 58 HeaterPwr_pin = 7; 59int HeaterPwr_led = 23; 60//______________________________ 61 GLOBAL VARIABLEs 62boolean HeaterPwr_cmd, Heater_break, Idle_mode; 63float voltage, 64 MinTamb, Alt_ref_raw, Alt_head_raw, Alt_head_corr, Alt_dyn_raw, Alt_dyn_corr, KDG90, 65 KDG10; 66String File_record = "Celio_A1"; 67volatile int Idle_cnt, Break_cnt, 68 Clean_cnt; 69 70////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 71volatile 72 float TPL_HH = 55; // (C) Thermal Protection Level High-High <> risk for 73 PLA, absolute threshold to stop completely the main program. 74volatile float TPL_H 75 = 45; // (C) Thermal Protection Level High <> permission to launch Start_up 76 sequence in cas of several Power restart 77volatile float PwrSupply_ref = 7.45;// 78 (V) Power Supply Volatege Reference <> shoudl be control due to risk of deviation 79 +/- 80volatile float PwrSupply_db = 0.40; // (V) Dead band power supply for accessories 81 <> below 7V the servo don't work correctly. 82volatile int HS64_offset = -12; 83 // (step) aligne the deflector with the MLX axle. 84volatile float TMNICE = 85 2.0; // (C) thermal threshold to define the risk of ice and activate the 86 Heater. Hysteresis is handle at +3C on pick-Up 87volatile float KHTO = 120; // 88 (second) Heat TimeOut running => permit a safety break during heating. A n Breaker 89 time is associated at the half 90////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 91////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 92////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 93void 94 setup() { 95 96pinMode(HeaterPwr_pin, OUTPUT); 97pinMode(HeaterPwr_led, OUTPUT); 98pinMode(ServoPwr_pin, 99 OUTPUT); 100pinMode(ServoPwr_led, OUTPUT); 101pinMode(SQW_RTC_led,OUTPUT); 102pinMode(3,INPUT_PULLUP); 103 104thermocouples[0] 105 = new Adafruit_MAX31855(4, 5, 6); 106attachInterrupt (digitalPinToInterrupt(3), 107 Flash_RTC , RISING ); 108 109Serial.begin(9600); 110 111mlx_fov10_Head.begin(); 112 113mlx_fov90_Head.begin(); 114mlx_fov90_Ref.begin(); 115 116Wire.begin(); 117Wire.beginTransmission(DS1307_I2C_ADDRESS); 118 Wire.write(0x07); Wire.write(0x10); 119Wire.endTransmission(); 120 121if (!SD.begin(chipSelect)) 122 123 {Serial.println("Card failed, or not present");return;} 124else 125 {Serial.println("card 126 initialized."); 127 File dataFile = SD.open(File_record, FILE_WRITE); 128 if 129 (dataFile) 130 { 131 dataFile.print("Date") ;dataFile.print(" 132 ; "); 133 dataFile.print("Hour") ;dataFile.print(" 134 ; "); 135 dataFile.print("Tamb_FOV90_Head") ;dataFile.print(" ; "); 136 137 dataFile.print("Tamb_FOV10_Head") ;dataFile.print(" ; "); 138 139 dataFile.print("Tamb_FOV90_Ref") ;dataFile.print(" ; "); 140 dataFile.print("Tobj_FOV90_Head") 141 ;dataFile.print(" ; "); 142 dataFile.print("Tobj_FOV10_Head") ;dataFile.print(" 143 ; "); 144 dataFile.print("Tobj_FOV90_Ref") ;dataFile.print(" ; "); 145 146 dataFile.print("Tc_Heater") ;dataFile.print(" ; "); 147 dataFile.print("Tc_MAX31855") 148 ;dataFile.print(" ; "); 149 dataFile.print("Voltage") ;dataFile.print(" 150 ; "); 151 dataFile.print("Rate_FOV90") ;dataFile.print(" ; "); 152 153 dataFile.print("Rate_FOV10") ;dataFile.print(" ; "); 154 155 dataFile.print("Altitude_raw") ;dataFile.print(" ; "); 156 dataFile.print("Altitude_corr") 157 ;dataFile.print(" ; "); 158 dataFile.print("Idle_mode") ;dataFile.print(" 159 ; "); 160 dataFile.print("HeaterPwr_cmd") ;dataFile.print(" ; "); 161 162 dataFile.print("Heater_break") ;dataFile.print(" ; "); 163 dataFile.print("Heat_count") 164 ;dataFile.print(" ; "); 165 dataFile.println("File name") ;dataFile.close(); 166 167 }} 168 169StartUp(); 170 171HS64WP.attach(servoPin); 172for (pos = MIN_POS; 173 pos <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); } 174delay(UPDATE_TIME);Serial.println("Configuration 175 Corrected Measurment");delay(1000); 176top60 = 0; 177 178} 179 180////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 181////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 182////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 183void 184 loop() { 185 186Tc_Heater = thermocouples[0]->readCelsius(); 187Thermal_Prot(); 188 189Tc_MAX31855 190 = thermocouples[0]->readInternal(); 191TA90H = mlx_fov90_Head.readAmbientTempC(); 192TA10H 193 = mlx_fov10_Head.readAmbientTempC(); 194TA90R = mlx_fov90_Ref.readAmbientTempC(); 195voltage 196 = analogRead(A0) * (5.0 / 1023.0) * (1680.0/680.0); // (R1 = 1 kOhm , R2 = 680 Ohms) 197TO90H 198 = mlx_fov90_Head.readObjectTempC(); 199TO10H = mlx_fov10_Head.readObjectTempC(); 200TO90R 201 = mlx_fov90_Ref.readObjectTempC(); 202 203KDG90 = TO90H / TO90R; 204KDG10 = TO10H 205 / TO90R; 206 207MinTamb = min(TA90H,TA10H); // Mini Tambe sensor and not outdoor 208Alt_ref_raw 209 = max(0,(( TA90R - TO90R) / 0.6) * 100); 210Alt_head_raw = max(0,(( TA90H - TO90H) 211 / 0.6) * 100); 212Alt_head_corr = Alt_head_raw * KDG90; 213Alt_dyn_raw = max(0,(( 214 TA10H - TO10H) / 0.6) * 100); 215Alt_dyn_corr = Alt_dyn_raw * KDG10; 216 217//[1] 218 HEATING MANAGMENT___________________________________ 219if (MinTamb <= TMNICE && 220 HeaterPwr_cmd == false && Heater_break == false) {HeaterPwr_cmd = true; } 221else 222 if (MinTamb >= TMNICE + 3 or Heat_cnt >= KHTO) {HeaterPwr_cmd = false; Heat_cnt 223 = 0; Heater_break = true;} 224 225//[2] CLEANING MANAGMENT__________________________________ 226 227if 228 ( ((TA90H - TO90H) <= 2.0) && ((TA10H - TO10H) <= 2.0) && ((TA90R - TO90R) <= 2.0) 229 && (Idle_mode == false) ) 230 {Monitor(); CleanUp(); Clean_cnt = Clean_cnt + 1;} 231else 232 233 {Clean_cnt = 0;} 234 235if (Clean_cnt >= 3) 236 {Serial.println("IDLE");for 237 (pos = MAX_POS + HS64_offset; pos <= MIN_POS; pos -= 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 238 239 Idle_mode = true; 240 Alt_ref_raw = 0; 241 Alt_head_raw = 0; 242 Alt_head_corr 243 = 0; 244 Alt_dyn_raw = 0; 245 Alt_dyn_corr = 0; 246 } 247 248 249//[3] 250 RECORDING___________________________________________ 251if (top60 >= 10) { Record(); 252 Monitor(); top60 = 0;} 253 254 255//[4] ACTUATORS CONTROL __________________________________ 256if 257 (HeaterPwr_cmd == true) {digitalWrite(HeaterPwr_pin, HIGH); digitalWrite(HeaterPwr_led, 258 HIGH); } else {digitalWrite(HeaterPwr_pin, LOW); digitalWrite(HeaterPwr_led, LOW); 259 } 260 261} 262 263 264//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 265 266void 267 CleanUp() 268{ 269 270Serial.println("Clean-Up"); 271for (pos = MIN_POS; pos <= 272 MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 273delay(2000); 274 275 276} 277 278//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 279 280byte 281 bcdToDec(byte val) 282{ return ( (val/16*10) + (val%16) );} 283 284void getDateDs1307(byte 285 *second,byte *minute,byte *hour,byte *dayOfWeek,byte *dayOfMonth,byte *month,byte 286 *year) //--- 287{ 288 Wire.beginTransmission(DS1307_I2C_ADDRESS); 289 Wire.write(0); 290 291 Wire.endTransmission(); 292 Wire.requestFrom(DS1307_I2C_ADDRESS, 7); 293 294 295 *second = (bcdToDec(Wire.read() & 0x7f)); 296 *minute = (bcdToDec(Wire.read())); 297 298 *hour = (bcdToDec(Wire.read() & 0x3f)); // Need to change this if 12 hour 299 am/pm 300 *dayOfWeek = bcdToDec(Wire.read()); 301 *dayOfMonth = bcdToDec(Wire.read()); 302 303 *month = bcdToDec(Wire.read()); 304 *year = bcdToDec(Wire.read()); 305} 306 307//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 308 309void 310 Flash_RTC () 311{ 312 313 top = top + 1; 314 top60 = top60 + 1; 315 316 digitalWrite(SQW_RTC_led,HIGH); 317 318 delay(500); 319 digitalWrite(SQW_RTC_led, LOW); 320 321if (HeaterPwr_cmd == 322 true) {Heat_cnt = Heat_cnt + 1;} 323 324 switch(Heat_cnt) 325 { 326 case 327 30: CleanUp(); break; 328 case 60: CleanUp(); break; 329 case 90: CleanUp(); 330 break; 331 case 120: CleanUp(); break; 332 } 333 334if (Heater_break == 335 true) {Break_cnt = Break_cnt + 1;} 336if (Break_cnt >= KHTO / 2) {Heater_break = 337 false; Break_cnt = 0;} 338 339if (Idle_mode == true) {Idle_cnt = Idle_cnt + 1;} 340if 341 (Idle_cnt >= 600) {Idle_mode = false; Idle_cnt = 0;Clean_cnt = 0;} // cleanUp reset 342 required to permit a new cycle of Cleaning and avoid looping 343} 344 345//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 346 347void 348 Record() { 349 350 getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, 351 &month, &year); 352 353 File dataFile = SD.open(File_record, FILE_WRITE); 354 355 356 if (dataFile) 357 { 358 dataFile.print(dayOfMonth);dataFile.print("/");dataFile.print(month);dataFile.print("/");dataFile.print(year);dataFile.print(" 359 ; "); 360 dataFile.print(hour);dataFile.print(":");dataFile.print(minute);dataFile.print(":");dataFile.print(second);dataFile.print(" 361 ; "); 362 dataFile.print(TA90H,2) ;dataFile.print(" ; "); 363 364 dataFile.print(TA10H,2) ;dataFile.print(" ; "); 365 dataFile.print(TA90R,2) 366 ;dataFile.print(" ; "); 367 dataFile.print(TO90H,2) ;dataFile.print(" 368 ; "); 369 dataFile.print(TO10H,2) ;dataFile.print(" ; "); 370 dataFile.print(TO90R,2) 371 ;dataFile.print(" ; "); 372 dataFile.print(Tc_Heater,1) ;dataFile.print(" 373 ; "); 374 dataFile.print(Tc_MAX31855,1) ;dataFile.print(" ; "); 375 dataFile.print(voltage,2) 376 ;dataFile.print(" ; "); 377 dataFile.print(KDG90,3) ;dataFile.print(" 378 ; "); 379 dataFile.print(KDG10,3) ;dataFile.print(" ; "); 380 381 dataFile.print(Alt_ref_raw,1) ;dataFile.print(" ; "); 382 dataFile.print(Alt_head_raw,1) 383 ;dataFile.print(" ; "); 384 dataFile.print(Alt_head_corr,1) ;dataFile.print(" 385 ; "); 386 dataFile.print(Alt_dyn_raw,1) ;dataFile.print(" ; "); 387 388 dataFile.print(Alt_dyn_corr,1) ;dataFile.print(" ; "); 389 dataFile.print(Idle_mode) 390 ;dataFile.print(" ; "); 391 dataFile.print(HeaterPwr_cmd) ;dataFile.print(" 392 ; "); 393 dataFile.print(Heater_break) ;dataFile.print(" ; "); 394 395 dataFile.print(Heat_cnt) ;dataFile.print(" ; "); 396 dataFile.println(File_record 397 ) ;dataFile.close(); 398 } 399 400} 401 402//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 403 404 405void 406 Monitor() { 407 408Serial.print(TA90H);Serial.print("C : "); 409Serial.print(TA10H);Serial.print("C 410 : "); 411Serial.print(TA90R);Serial.print("C : >> "); 412Serial.print(Tc_Heater);Serial.print("C 413 << : "); 414Serial.print(Tc_MAX31855);Serial.print("C : "); 415Serial.print(top);Serial.print("- 416 : "); 417Serial.print(HeaterPwr_cmd);Serial.print(" : "); 418Serial.print(voltage);Serial.print("V 419 : "); 420Serial.print(TO90H);Serial.print("C : "); 421Serial.print(TO10H);Serial.print("C 422 : "); 423Serial.print(TO90R);Serial.print("C : "); 424Serial.print(Alt_ref_raw);Serial.print("m 425 : "); 426Serial.print(Alt_head_raw);Serial.print("m : "); 427Serial.print(Alt_head_corr);Serial.print("m 428 : "); 429Serial.print(Alt_dyn_raw);Serial.print("m : "); 430Serial.print(Alt_dyn_corr);Serial.print("m 431 : "); 432Serial.print(KDG90);Serial.print("- : "); 433Serial.print(KDG10);Serial.print("- 434 : "); 435Serial.print(top60);Serial.println("- : "); 436 437} 438 439//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 440 441int 442 laps, SUHT_STOP; 443float deltat, volt_max, volt_min; 444 445void StartUp() { 446 447Tc_Heater 448 = thermocouples[0]->readCelsius(); 449 450if (Tc_Heater <= TPL_H) { 451 452digitalWrite(HeaterPwr_pin, 453 LOW);digitalWrite(HeaterPwr_led, LOW); 454digitalWrite(ServoPwr_pin, LOW);digitalWrite(HeaterPwr_led, 455 LOW); 456 457Serial.println(">>>>>>>>>START-UP<<<<<<<<<<"); 458 459Serial.println("(1) 460 HEATER TEST ______________"); 461 462Serial.print("Temp Tc Heater:"); 463Tc_HSU_start 464 = thermocouples[0]->readCelsius(); 465volt_max = Tc_HSU_start; 466volt_min = Tc_HSU_start; 467Serial.print(Tc_HSU_start);Serial.println(" 468 C"); 469delay(1000); 470laps = 0; 471Serial.println("-->HEATER ON"); 472 do 473 {digitalWrite(HeaterPwr_pin, HIGH);digitalWrite(HeaterPwr_led, HIGH); 474 laps 475 = laps + 1 ; 476 deltat=thermocouples[0]->readCelsius()-Tc_HSU_start; 477 voltage 478 = analogRead(A0) * (5.0 / 1023.0) * (1680.0/680.0); 479 if (voltage > volt_max) 480 {volt_max = voltage;} else {volt_max = volt_max;} 481 if (voltage > volt_min) 482 {volt_min = voltage;} else {volt_min = volt_min;} 483 Serial.print(laps);Serial.print(" 484 : "); 485 Serial.print(voltage);Serial.print(" : "); 486 Serial.print(deltat);Serial.println(" 487 : "); 488 if (volt_max - volt_min > (2 * PwrSupply_db)) {Serial.println("TRIP 489 BOARD - POWER SUPPLY ISSUE"); delay(250); exit(0);} 490 if (voltage < (PwrSupply_ref-PwrSupply_db)) 491 {Serial.println("TRIP BOARD - POWER SUPPLY TOO LOW"); delay(250); exit(0);} 492 493 if (laps == 40 && deltat <= 5.0) {Serial.println("TRIP BOARD - NO HEATING"); 494 delay(250); exit(0);} 495 if (thermocouples[0]->readCelsius() > TPL_HH) {Serial.println("TRIP 496 BOARD - Too HOT"); delay(250); exit(0);} 497 if (laps >=40 || deltat >= 5.0) 498 {SUHT_STOP = 1;} else {SUHT_STOP = 0;} 499 delay(1000); } while ( SUHT_STOP 500 == 0); 501 502digitalWrite(HeaterPwr_pin, LOW); digitalWrite(HeaterPwr_led, LOW);Serial.println("-->HEATER 503 OFF");} else {Serial.println("TRIP BOARD - Too HOT"); delay(250); exit(0);} 504 505Serial.println("(2) 506 SERVO TEST ______________"); 507HS64WP.attach(servoPin); 508digitalWrite(ServoPwr_pin, 509 HIGH); digitalWrite(ServoPwr_led, HIGH); Serial.println("SERVO ON"); 510delay(1000); 511 512 513for 514 (pos = MIN_POS; pos <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME); 515 516 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 517 518 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;}} 519 520 Serial.println("Configuration Corrected Measurment");delay(2000); 521for 522 (pos = MAX_POS+HS64_offset; pos >= 85+HS64_offset; pos -= 1) { HS64WP.write(pos); 523 delay(UPDATE_TIME); 524 if (voltage > volt_max) {volt_max = voltage;} else 525 {volt_max = volt_max;} 526 if (voltage > volt_min) {volt_min = voltage;} else 527 {volt_min = volt_min;}} 528 Serial.println("Configuration Head Measurment 529 only");delay(2000); 530for (pos = 90+HS64_offset; pos >= MIN_POS; pos -= 1) { HS64WP.write(pos); 531 delay(UPDATE_TIME); 532 if (voltage > volt_max) {volt_max = voltage;} else 533 {volt_max = volt_max;} 534 if (voltage > volt_min) {volt_min = voltage;} else 535 {volt_min = volt_min;}} 536 Serial.println("Safe location - Measurment OFF");delay(2000); 537 538 539Serial.println("END 540 START-UP ______________"); 541 542} 543 544//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 545 546void 547 Thermal_Prot() {if (Tc_Heater > TPL_HH) {Serial.println("TRIP BOARD - OVERHEAT");delay(250);exit(0);}} 548
Main Program
arduino
Updated Revision with several improvements
1// IDE ADRUINO V1.8.7 2// BOARD ARDUINO MEGA 2560 (no enough memory 3 with UNO board) 4//______________________________ SERVO 5#include <Servo.h> 6#define 7 UPDATE_TIME 10 8#define MAX_POS 180 9#define MIN_POS 0 10int servoPin = 9; 11int 12 pulse = 1900; 13char s="1.5"; 14Servo HS64WP; 15int pos=0; 16int ServoPwr_pin 17 = 8; 18int ServoPwr_led = 23; 19//______________________________ THERMOCOUPLE 20#include 21 <Adafruit_MAX31855.h> 22Adafruit_MAX31855 *thermocouples[1]; 23float Tc_HSU_start, 24 Tc_HSU_end; 25volatile float Tc_Heater; 26float Tc_MAX31855; 27//______________________________ 28 IR SENSORs 29#include <Wire.h> 30#include <Adafruit_MLX90614.h> 31volatile float 32 TA90H,TO90H,TA10H,TO10H,TA90R,TO90R,Text; 33volatile float TA90H_int,TO90H_int,TA10H_int,TO10H_int,TA90R_int,TO90R_int; 34Adafruit_MLX90614 35 mlx_fov10_Head = Adafruit_MLX90614(0x1B); // Head FOV90 36Adafruit_MLX90614 mlx_fov90_Head 37 = Adafruit_MLX90614(0x5A); // Head FOV10 38Adafruit_MLX90614 mlx_fov90_Ref = Adafruit_MLX90614(0x3A); 39 // Ref FOV90 40//______________________________ SD-CARD 41#include <SPI.h> 42#include 43 <SD.h> 44const int chipSelect = 53; 45//______________________________ REAL TIME 46 CLOCK DS1307 47#define DS1307_I2C_ADDRESS 0x68 48volatile int top,Heat_cnt; 49byte 50 second, minute, hour, dayOfWeek, dayOfMonth, month, year; 51int SQW_RTC_led = 24; 52//______________________________ 53 RF433 MHZ 54//#include <RH_ASK.h> => can't be used simutaneously with another SPI 55 component. => should be externalyzed 56// try to use RCSwitch or VirtualWire 57//______________________________ 58 HEATER 12V-4W 59int HeaterPwr_pin = 7; 60int HeaterPwr_led = 22; 61//______________________________ 62 GLOBAL VARIABLEs 63boolean HeaterPwr_cmd, Heater_break, Idle_mode; 64float MinTamb, 65 Alt_ref_raw, Alt_head_raw, Alt_head_corr, Alt_dyn_raw, Alt_dyn_corr, KDG90, KDG10; 66volatile 67 float voltage, voltage_int; 68String File_record = "Celio_A3"; 69volatile int 70 Idle_cnt, Break_cnt, Clean_cnt; 71 72////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 73volatile 74 float TPL_HH = 55; // (C) Thermal Protection Level High-High <> risk for 75 PLA, absolute threshold to stop completely the main program. 76volatile float TPL_H 77 = 45; // (C) Thermal Protection Level High <> permission to launch Start_up 78 sequence in cas of several Power restart 79volatile float PwrSupply_ref = 7.45;// 80 (V) Power Supply Volatege Reference <> shoudl be control due to risk of deviation 81 +/- 82volatile float PwrSupply_db = 0.40; // (V) Dead band power supply for accessories 83 <> below 7V the servo don't work correctly. 84volatile int HS64_offset = -2; 85 // (step) aligne the deflector with the MLX axle. 86volatile float TMNICE = 87 2.0; // (C) thermal threshold to define the risk of ice and activate the 88 Heater. Hysteresis is handle at +3C on pick-Up 89volatile float KHTO = 120; // 90 (second) Heat TimeOut running => permit a safety break during heating. A n Breaker 91 time is associated at the half 92volatile float KIdle_dly = 30; // (second) 93 time delay to maintain the Idle mode 94int NBS = 10.0; // 95 (Numbers of top-1Hz <> NB seconds) define the recording frequency 96////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 97////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 98////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 99void 100 setup() { 101 102pinMode(HeaterPwr_pin, OUTPUT); 103pinMode(HeaterPwr_led, OUTPUT); 104pinMode(ServoPwr_pin, 105 OUTPUT); 106pinMode(ServoPwr_led, OUTPUT); 107pinMode(SQW_RTC_led,OUTPUT); 108pinMode(3,INPUT_PULLUP); 109 110thermocouples[0] 111 = new Adafruit_MAX31855(4, 5, 6); 112attachInterrupt (digitalPinToInterrupt(3), 113 Flash_RTC , RISING ); 114 115Serial.begin(9600); 116 117mlx_fov10_Head.begin(); 118 119mlx_fov90_Head.begin(); 120mlx_fov90_Ref.begin(); 121 122Wire.begin(); 123Wire.beginTransmission(DS1307_I2C_ADDRESS); 124 Wire.write(0x07); Wire.write(0x10); 125Wire.endTransmission(); 126 127if (!SD.begin(chipSelect)) 128 129 {Serial.println("Card failed, or not present"); exit(0);} 130else 131 {Serial.println("card 132 initialized."); 133 File dataFile = SD.open(File_record, FILE_WRITE); 134 if 135 (dataFile) 136 { 137 dataFile.print("Date") ;dataFile.print(" 138 ; "); 139 dataFile.print("Hour") ;dataFile.print(" 140 ; "); 141 dataFile.print("Tamb_FOV90_Head") ;dataFile.print(" ; "); 142 143 dataFile.print("Tamb_FOV10_Head") ;dataFile.print(" ; "); 144 145 dataFile.print("Tamb_FOV90_Ref") ;dataFile.print(" ; "); 146 dataFile.print("Tobj_FOV90_Head") 147 ;dataFile.print(" ; "); 148 dataFile.print("Tobj_FOV10_Head") ;dataFile.print(" 149 ; "); 150 dataFile.print("Tobj_FOV90_Ref") ;dataFile.print(" ; "); 151 152 dataFile.print("Tc_Heater") ;dataFile.print(" ; "); 153 dataFile.print("Tc_MAX31855") 154 ;dataFile.print(" ; "); 155 dataFile.print("Voltage") ;dataFile.print(" 156 ; "); 157 dataFile.print("Rate_FOV90") ;dataFile.print(" ; "); 158 159 dataFile.print("Rate_FOV10") ;dataFile.print(" ; "); 160 161 dataFile.print("Alt_ref_raw") ;dataFile.print(" ; "); 162 dataFile.print("Alt_head_raw") 163 ;dataFile.print(" ; "); 164 dataFile.print("Alt_head_corr") ;dataFile.print(" 165 ; "); 166 dataFile.print("Alt_dyn_raw") ;dataFile.print(" ; "); 167 168 dataFile.print("Alt_dyn_corr") ;dataFile.print(" ; "); 169 dataFile.print("Idle_mode") 170 ;dataFile.print(" ; "); 171 dataFile.print("HeaterPwr_cmd") ;dataFile.print(" 172 ; "); 173 dataFile.print("Heater_break") ;dataFile.print(" ; "); 174 175 dataFile.print("Heat_count") ;dataFile.print(" ; "); 176 dataFile.println("File 177 name") ;dataFile.close(); 178 }} 179 180StartUp(); 181Run(); 182top = 0; 183 184} 185 186////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 187////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 188////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 189void 190 loop() { 191 192Tc_Heater = thermocouples[0]->readCelsius(); 193Thermal_Prot(); 194 195HS64WP.attach(servoPin); 196 197 198Tc_MAX31855 = thermocouples[0]->readInternal(); 199TA90H = mlx_fov90_Head.readAmbientTempC(); 200TA10H 201 = mlx_fov10_Head.readAmbientTempC(); 202TA90R = mlx_fov90_Ref.readAmbientTempC(); 203voltage 204 = analogRead(A0) * (5.0 / 1023.0) * (1680.0/680.0); // (R1 = 1 kOhm , R2 = 680 Ohms) 205TO90H 206 = mlx_fov90_Head.readObjectTempC(); 207TO10H = mlx_fov10_Head.readObjectTempC(); 208TO90R 209 = mlx_fov90_Ref.readObjectTempC(); 210Text = TA90R; 211 212//[1] HEATING MANAGMENT___________________________________ 213MinTamb 214 = min(TA90H,TA10H); // Mini Tambe sensor and not outdoor 215if (MinTamb <= TMNICE 216 && HeaterPwr_cmd == false && Heater_break == false) 217 {HeaterPwr_cmd = true; 218 } 219else if ((MinTamb >= TMNICE + 3) or (Heat_cnt >= KHTO)) 220 {HeaterPwr_cmd 221 = false; Heat_cnt = 0; Heater_break = true;} 222 223switch(Heat_cnt) 224{ 225 case 226 30: CleanUp(); Serial.println("CleanUp during Heating");break; 227 case 60: 228 CleanUp(); Serial.println("CleanUp during Heating");break; 229 case 90: CleanUp(); 230 Serial.println("CleanUp during Heating");break; 231 case 120: CleanUp(); Serial.println("CleanUp 232 during Heating");break; 233} 234 235//[2] CLEANING MANAGMENT__________________________________ 236 237if 238 ( (((TA90H - TO90H) <= 2.0) || ((TA10H - TO10H) <= 2.0) ) && (Idle_mode == false) 239 ) 240 {Monitor(); Clean_cnt = Clean_cnt + 1;Serial.println(Clean_cnt);CleanUp();} 241else 242 243 {Clean_cnt = constrain((Clean_cnt -1),0,10000);} 244 245 246if ((Clean_cnt >= 247 3) && (Idle_mode == false)) 248 {Serial.println("IDLE"); 249 Idle(); 250 Idle_mode 251 = true; 252 Alt_ref_raw = 0; Alt_head_raw = 0; Alt_head_corr = 0; Alt_dyn_raw = 253 0; Alt_dyn_corr = 0; 254 } 255 256 257 258//[3] ACTUATORS CONTROL __________________________________ 259if 260 (HeaterPwr_cmd == true) {digitalWrite(HeaterPwr_pin, HIGH); digitalWrite(HeaterPwr_led, 261 HIGH); } else {digitalWrite(HeaterPwr_pin, LOW); digitalWrite(HeaterPwr_led, LOW); 262 } 263 264 265//[4] RECORDING___________________________________________ 266if (top 267 >= NBS) 268{ 269 270TA90H = TA90H_int / NBS; 271TO90H = TO90H_int / NBS; 272TA10H 273 = TA10H_int / NBS; 274TO10H = TO10H_int / NBS; 275TA90R = TA90R_int / NBS; 276TO90R 277 = TO90R_int / NBS; 278voltage = voltage_int / NBS; 279 280KDG90 = TO90H / TO90R; 281KDG10 282 = TO10H / TO90R; 283 284if (Idle_mode == true) 285{ 286 Alt_ref_raw = 0; 287 Alt_head_raw 288 = 0; 289 Alt_head_corr = 0; 290 Alt_dyn_raw = 0; 291 Alt_dyn_corr = 0; 292} 293else 294{ 295 296 Alt_ref_raw = constrain(((( Text - TO90R) / 0.6) * 100),0,10000); 297 Alt_head_raw 298 = constrain(((( Text - TO90H) / 0.6) * 100),0,10000); 299 Alt_head_corr = constrain(Alt_head_raw 300 * KDG90,0,10000); 301 Alt_dyn_raw = constrain(((( Text - TO10H) / 0.6) * 100),0,10000); 302 303 Alt_dyn_corr = constrain(Alt_dyn_raw * KDG10,0,10000); 304} 305 306Record(); Monitor(); 307 308 309top = 0; 310 311TA90H_int = 0; 312TO90H_int = 0; 313TA10H_int = 0; 314TO10H_int 315 = 0; 316TA90R_int = 0; 317TO90R_int = 0; 318voltage_int = 0; 319 320} 321 322} 323 324void 325 CleanUp() 326{ 327 328Serial.println("Clean-Up on run"); 329digitalWrite(ServoPwr_pin, 330 HIGH); digitalWrite(ServoPwr_led, HIGH); 331delay(500); 332for (pos = MIN_POS; pos 333 <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 334delay(1000); 335//digitalWrite(ServoPwr_pin, 336 LOW); digitalWrite(ServoPwr_led, LOW); 337} 338 339byte bcdToDec(byte val) 340{ 341 return ( (val/16*10) + (val%16) );} 342 343void getDateDs1307(byte *second,byte 344 *minute,byte *hour,byte *dayOfWeek,byte *dayOfMonth,byte *month,byte *year) //--- 345{ 346 347 Wire.beginTransmission(DS1307_I2C_ADDRESS); 348 Wire.write(0); 349 Wire.endTransmission(); 350 351 Wire.requestFrom(DS1307_I2C_ADDRESS, 7); 352 353 *second = (bcdToDec(Wire.read() 354 & 0x7f)); 355 *minute = (bcdToDec(Wire.read())); 356 *hour = (bcdToDec(Wire.read() 357 & 0x3f)); // Need to change this if 12 hour am/pm 358 *dayOfWeek = bcdToDec(Wire.read()); 359 360 *dayOfMonth = bcdToDec(Wire.read()); 361 *month = bcdToDec(Wire.read()); 362 363 *year = bcdToDec(Wire.read()); 364} 365 366void Flash_RTC () 367{ 368 369 370 Thermal_Prot(); // already activated by the main loop , this crutial function 371 is recall here to avoid infite loop condition in the main program. 372 373 top 374 = top + 1; 375 376 377 digitalWrite(SQW_RTC_led,HIGH); 378 delay(500); 379 380 381if 382 (HeaterPwr_cmd == true) {Heat_cnt = Heat_cnt + 1;} 383 384if (Heater_break == 385 true) {Break_cnt = Break_cnt + 1;} 386if (Break_cnt >= KHTO / 2) {Heater_break = 387 false; Break_cnt = 0;} 388 389if (Idle_mode == true) {Idle_cnt = Idle_cnt + 1;Serial.println(Idle_cnt);} 390if 391 (Idle_cnt >= KIdle_dly) {Idle_mode = false; Idle_cnt = 0;Clean_cnt = 0;} // cleanUp 392 reset required to permit a new cycle of Cleaning and avoid looping 393 394TA90H_int 395 = TA90H_int + TA90H; 396TO90H_int = TO90H_int + TO90H; 397TA10H_int = TA10H_int 398 + TA10H; 399TO10H_int = TO10H_int + TO10H; 400TA90R_int = TA90R_int + TA90R; 401TO90R_int 402 = TO90R_int + TO90R; 403voltage_int = voltage_int + voltage; 404 405 406 407 digitalWrite(SQW_RTC_led, 408 LOW); 409} 410 411void Idle() 412{ 413 414Serial.println("Return on idle"); 415digitalWrite(ServoPwr_pin, 416 HIGH); digitalWrite(ServoPwr_led, HIGH); 417delay(500); 418for (pos = MAX_POS+HS64_offset; 419 pos >= 0; pos -= 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 420delay(1000); 421digitalWrite(ServoPwr_pin, 422 LOW); digitalWrite(ServoPwr_led, LOW); 423 424} 425 426void Record() { 427 428 429 getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); 430 431 432 File dataFile = SD.open(File_record, FILE_WRITE); 433 434 if (dataFile) 435 436 { 437 dataFile.print(dayOfMonth);dataFile.print("/");dataFile.print(month);dataFile.print("/");dataFile.print(year);dataFile.print(" 438 ; "); 439 dataFile.print(hour);dataFile.print(":");dataFile.print(minute);dataFile.print(":");dataFile.print(second);dataFile.print(" 440 ; "); 441 dataFile.print(TA90H,2) ;dataFile.print(" ; "); 442 443 dataFile.print(TA10H,2) ;dataFile.print(" ; "); 444 dataFile.print(TA90R,2) 445 ;dataFile.print(" ; "); 446 dataFile.print(TO90H,2) ;dataFile.print(" 447 ; "); 448 dataFile.print(TO10H,2) ;dataFile.print(" ; "); 449 dataFile.print(TO90R,2) 450 ;dataFile.print(" ; "); 451 dataFile.print(Tc_Heater,1) ;dataFile.print(" 452 ; "); 453 dataFile.print(Tc_MAX31855,1) ;dataFile.print(" ; "); 454 dataFile.print(voltage,2) 455 ;dataFile.print(" ; "); 456 dataFile.print(KDG90,3) ;dataFile.print(" 457 ; "); 458 dataFile.print(KDG10,3) ;dataFile.print(" ; "); 459 460 dataFile.print(Alt_ref_raw,1) ;dataFile.print(" ; "); 461 dataFile.print(Alt_head_raw,1) 462 ;dataFile.print(" ; "); 463 dataFile.print(Alt_head_corr,1) ;dataFile.print(" 464 ; "); 465 dataFile.print(Alt_dyn_raw,1) ;dataFile.print(" ; "); 466 467 dataFile.print(Alt_dyn_corr,1) ;dataFile.print(" ; "); 468 dataFile.print(Idle_mode) 469 ;dataFile.print(" ; "); 470 dataFile.print(HeaterPwr_cmd) ;dataFile.print(" 471 ; "); 472 dataFile.print(Heater_break) ;dataFile.print(" ; "); 473 474 dataFile.print(Heat_cnt) ;dataFile.print(" ; "); 475 dataFile.println(File_record 476 ) ;dataFile.close(); 477 } 478 479} 480 481void Run() 482 483{ 484 485Serial.println("Run"); 486 487digitalWrite(ServoPwr_pin, 488 HIGH); digitalWrite(ServoPwr_led, HIGH); 489delay(500); 490for (pos = MIN_POS; pos 491 <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME);} 492delay(1000); 493//digitalWrite(ServoPwr_pin, 494 LOW); digitalWrite(ServoPwr_led, LOW); 495 496} 497 498void Monitor() { 499 500Serial.print(TA90H);Serial.print("C 501 : "); 502Serial.print(TA10H);Serial.print("C : "); 503Serial.print(TA90R);Serial.print("C 504 : >> "); 505Serial.print(Tc_Heater);Serial.print("C << : "); 506Serial.print(Tc_MAX31855);Serial.print("C 507 : "); 508Serial.print(top);Serial.print("- : "); 509Serial.print(HeaterPwr_cmd);Serial.print(" 510 : "); 511Serial.print(voltage);Serial.print("V : "); 512Serial.print(TO90H);Serial.print("C 513 : "); 514Serial.print(TO10H);Serial.print("C : "); 515Serial.print(TO90R);Serial.print("C 516 : "); 517Serial.print(Alt_ref_raw);Serial.print("m : "); 518Serial.print(Alt_head_raw);Serial.print("m 519 : "); 520Serial.print(Alt_head_corr);Serial.print("m : "); 521Serial.print(Alt_dyn_raw);Serial.print("m 522 : "); 523Serial.print(Alt_dyn_corr);Serial.print("m : "); 524Serial.print(KDG90);Serial.print("- 525 : "); 526Serial.println(KDG10); 527 528 529} 530 531int laps, SUHT_STOP; 532float 533 deltat, volt_max, volt_min; 534 535void StartUp() { 536 537Tc_Heater = thermocouples[0]->readCelsius(); 538 539if 540 (Tc_Heater <= TPL_H) { 541 542digitalWrite(HeaterPwr_pin, LOW);digitalWrite(HeaterPwr_led, 543 LOW); 544digitalWrite(ServoPwr_pin, LOW);digitalWrite(HeaterPwr_led, LOW); 545 546Serial.println(">>>>>>>>>START-UP<<<<<<<<<<"); 547 548Serial.println("(1) 549 HEATER TEST ______________"); 550 551Serial.print("Temp Tc Heater:"); 552Tc_HSU_start 553 = thermocouples[0]->readCelsius(); 554volt_max = Tc_HSU_start; 555volt_min = Tc_HSU_start; 556Serial.print(Tc_HSU_start);Serial.println(" 557 C"); 558delay(1000); 559laps = 0; 560Serial.println("-->HEATER ON"); 561 do 562 {digitalWrite(HeaterPwr_pin, HIGH);digitalWrite(HeaterPwr_led, HIGH); 563 laps 564 = laps + 1 ; 565 deltat=thermocouples[0]->readCelsius()-Tc_HSU_start; 566 voltage 567 = analogRead(A0) * (5.0 / 1023.0) * (1680.0/680.0); 568 if (voltage > volt_max) 569 {volt_max = voltage;} else {volt_max = volt_max;} 570 if (voltage > volt_min) 571 {volt_min = voltage;} else {volt_min = volt_min;} 572 Serial.print(laps);Serial.print(" 573 : "); 574 Serial.print(voltage);Serial.print(" : "); 575 Serial.print(deltat);Serial.println(" 576 : "); 577 if (volt_max - volt_min > (2 * PwrSupply_db)) {Serial.println("TRIP 578 BOARD - POWER SUPPLY ISSUE"); delay(250); exit(0);} 579 if (voltage < (PwrSupply_ref-PwrSupply_db)) 580 {Serial.println("TRIP BOARD - POWER SUPPLY TOO LOW"); delay(250); exit(0);} 581 582 if (laps == 40 && deltat <= 5.0) {Serial.println("TRIP BOARD - NO HEATING"); 583 delay(250); exit(0);} 584 if (thermocouples[0]->readCelsius() > TPL_HH) {Serial.println("TRIP 585 BOARD - Too HOT"); delay(250); exit(0);} 586 if (laps >=40 || deltat >= 5.0) 587 {SUHT_STOP = 1;} else {SUHT_STOP = 0;} 588 delay(1000); } while ( SUHT_STOP 589 == 0); 590 591digitalWrite(HeaterPwr_pin, LOW); digitalWrite(HeaterPwr_led, LOW);Serial.println("-->HEATER 592 OFF");} else {Serial.println("TRIP BOARD - Too HOT"); delay(500); exit(0);} 593 594Serial.println("(2) 595 SERVO TEST ______________"); 596HS64WP.attach(servoPin); 597digitalWrite(ServoPwr_pin, 598 HIGH); digitalWrite(ServoPwr_led, HIGH); Serial.println("SERVO ON"); 599delay(1000); 600 601 602for 603 (pos = MIN_POS; pos <= MAX_POS+HS64_offset; pos += 1) { HS64WP.write(pos); delay(UPDATE_TIME); 604 605 if (voltage > volt_max) {volt_max = voltage;} else {volt_max = volt_max;} 606 607 if (voltage > volt_min) {volt_min = voltage;} else {volt_min = volt_min;}} 608 609 Serial.println("Configuration Corrected Measurment");delay(2000); 610for 611 (pos = MAX_POS+HS64_offset; pos >= 85+HS64_offset; pos -= 1) { HS64WP.write(pos); 612 delay(UPDATE_TIME); 613 if (voltage > volt_max) {volt_max = voltage;} else 614 {volt_max = volt_max;} 615 if (voltage > volt_min) {volt_min = voltage;} else 616 {volt_min = volt_min;}} 617 Serial.println("Configuration Head Measurment 618 only");delay(2000); 619for (pos = 90+HS64_offset; pos >= MIN_POS; pos -= 1) { HS64WP.write(pos); 620 delay(UPDATE_TIME); 621 if (voltage > volt_max) {volt_max = voltage;} else 622 {volt_max = volt_max;} 623 if (voltage > volt_min) {volt_min = voltage;} else 624 {volt_min = volt_min;}} 625 Serial.println("Safe location - Measurment OFF");delay(2000); 626 627 628Serial.println("END 629 START-UP ______________"); 630digitalWrite(ServoPwr_pin, LOW); digitalWrite(ServoPwr_led, 631 LOW); 632 633} 634 635void Thermal_Prot() 636 637{ 638 639 640//if ((Tc_Heater 641 > TPL_HH) || (voltage < (PwrSupply_ref-PwrSupply_db))) 642if (Tc_Heater > TPL_HH) 643 644 {Serial.println("TRIP BOARD - OVERHEAT or LOW-VOLTAGE");delay(500);exit(0);} 645 646} 647 648/* 649Version 650 Celio_A2 651############################################################################################################################################################## 652>manage 653 Heater only with external temperature <> that mean Ambient temp from Reference MLX90614 654>keep 655 2C of lower lever hysteresis and increase upper level from 3 to 5C 656>recalculate 657 altitudes from each sensors with raw and corrected result. 658>re adjust Deflector's 659 offset 660>shutdown servo powersupply if not required = on idle 661>gain reactivity 662 by calling the Thermal protection from the loop Flash RTC which is still workingat 663 1Hz (The main Loop can cumulate several delays) 664>Change conditions for Clean 665 Up replace AND between IR sensors by OR 666 667Note: we temporaly remove de flash 668 Led RTC which created disturbance with the Servo Signal pin. 669The servo is hold 670 powered on on High position (measurment) and just shutdonw on idle. 671In all cases 672 we withdrew the unstabilities 673 674 675Version Celio_A3 676############################################################################################################################################################## 677>Voltage 678 recording unavailable... bad definition 679>correct Altitude calculation an declare 680 a new variable to avoid confusion TA90R=Text 681>upgrade head name on record file 682 683For 684 next step 685...>add voltage control in thermal loop... if no power supply => no 686 protection = stop the main program (Exit0) 687 */ 688
Documentation
3D STL File
Servo Bearing Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL File
Technical Drawings
Electronic is not complicated, but the outdoor constraints required a really good conception of casing. These drawings define the several parts which constitute the full sensor.
Technical Drawings
3D STL Files
Deflector Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL Files
3D STL Files
Deflector Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL Files
3D STL File
Main Body Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL File
3D STL File
Ref Bottom Plug Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL File
3D STL File
Main Body Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL File
3D STL Files
Controller Bearing Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL Files
3D STL Files
Deflector Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL Files
3D STL File
Main Body Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL File
3D STL Files
Bottom Plug Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL Files
Technical Drawings
Electronic is not complicated, but the outdoor constraints required a really good conception of casing. These drawings define the several parts which constitute the full sensor.
Technical Drawings
3D STL File
Servo Bearing Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL File
3D STL File
Controller Cover Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL File
3D STL File
Ref Bottom Plug Printed on Dagoma Disco Easy 200 PLA White 1.75mm / 0.1mm
3D STL File
Comments
Only logged in users can leave comments
KFMAKR
0 Followers
•0 Projects
Table of contents
Intro
8
0