Skip to content

Instantly share code, notes, and snippets.

@pat1
Created March 18, 2020 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pat1/8eb665462fe3fc94b1c04d6ab0e0f943 to your computer and use it in GitHub Desktop.
Save pat1/8eb665462fe3fc94b1c04d6ab0e0f943 to your computer and use it in GitHub Desktop.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SensorDriverb.h>
#include <PID_v1.h>
// pin relè SSR
#define MR_PWM 13
#define MR_EN 12
// pin encoder
#define encoderPin1 2
#define encoderPin2 3
#define SENSORS_LEN 2 //numero di sensori 2
#define LENVALUES 2 //ogni sensore misura T e H
unsigned long starTime;
unsigned long Time;
const unsigned long period = 1000;
double Hambientale[SENSORS_LEN]; //alloco valori H e T
double Tambientale[SENSORS_LEN];
//encoder
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
int Tset;
//pad riscaldante
bool printed = true;
double Tambient;
double Hambient;
//pid
double Setpoint=23; // T desiderata
double Input=0; // Tambient
double Output=0; // PWMpad
double Kp=35; //32
double Ki=0.5; //0.01
double Kd=0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
LiquidCrystal_I2C lcd(0x27, 20, 4);
//inizializzo display
void init_lcd() {
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("PWMpad: ");
}
// funzione chiamata da interrupts encoder
void updateEncoder(){
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue --;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue ++;
lastEncoded = encoded; //store this value for next time
}
struct sensor_t
{
char driver[5]; // driver name
char type[5]; // driver name
int address; // i2c address
} sensors[SENSORS_LEN];
SensorDriver* sd[SENSORS_LEN]; // sensorDriver* pointer variable
void SensorConfiguration (){
strcpy(sensors[0].driver,"I2C"); //scrivo nella prima struct (sensors[0]) info sensore 1
strcpy(sensors[0].type,"HIH");
sensors[0].address=0x28; // sensore bianco
strcpy(sensors[1].driver,"I2C"); //scrivo nella seconda struct (sensors[1]) info sensore 2
strcpy(sensors[1].type,"HIH");
sensors[1].address=0x29; // sensore rosso
for (int i = 0; i < SENSORS_LEN; i++) {
sd[i]=SensorDriver::create(sensors[i].driver,sensors[i].type);
if (sd[i] == NULL){
Serial.print(sensors[i].driver);
Serial.println(": driver not created !");
}else{
sd[i]->setup(sensors[i].driver,sensors[i].address);
}
}
}
void SensorReady (){
long unsigned int waittime,maxwaittime=0;
// prepare sensors to measure
for (int i = 0; i < SENSORS_LEN; i++) {
if (!sd[i] == NULL){
if (sd[i]->prepare(waittime) == SD_SUCCESS){
// Serial.print(sensors[i].driver);
// Serial.print(" : ");
// Serial.print(sensors[i].type);
// Serial.println(" : Prepare OK");
maxwaittime=max(maxwaittime,waittime);
}else{
// Serial.print(sensors[i].driver);
// Serial.print(" : ");
// Serial.print(sensors[i].type);
// Serial.println(" : Prepare failed !");
}
}
}
//wait sensors to go ready
Serial.print("# wait sensors for ms:"); Serial.println(maxwaittime);
delay(maxwaittime); // 500 for tmp and 250 for adt and 2500 for davis
}
void setup() {
starTime= millis(); //start counting the time
init_lcd();
SensorConfiguration();
Serial.begin(115200);
Wire.begin();
pinMode(encoderPin1, INPUT_PULLUP); // encoder
pinMode(encoderPin2, INPUT_PULLUP);
pinMode(MR_PWM,OUTPUT); //relè
pinMode(MR_EN,OUTPUT);
digitalWrite(MR_EN, HIGH);
myPID.SetMode(AUTOMATIC);
attachInterrupt(0, updateEncoder, FALLING);
attachInterrupt(1, updateEncoder, FALLING);
}
void loop(){
Tset=23+encoderValue/2;
//Serial.print("Tsettata: ");
//Serial.println(Tset);
lcd.setCursor(0,3);
lcd.print("T set ");
lcd.setCursor(6,3);
lcd.print(Tset);
SensorReady();
for (int i = 0; i < SENSORS_LEN; i++) {
Serial.println(" ");
Serial.print("numero sensore: ");
Serial.println(i+1);
if (!sd[i] == NULL){
long values[LENVALUES]; // get integers value
size_t lenvalues=LENVALUES;
if (sd[i]->get(values,lenvalues) == SD_SUCCESS){
Hambientale[i] = (values[0]); // umidità
//
// Serial.print("Umidità: ");
// Serial.print(Hambientale[i]);
// Serial.println();
lcd.setCursor (9,i+1);
lcd.print("H");
lcd.setCursor(10,i+1);
lcd.print(i+1);
lcd.setCursor (12,i+1);
lcd.print(Hambientale[i]);
Tambientale[i] = (float(values[1])/100.)-273.15; // trasformazione temperatura
// Serial.print("Temperatura: ");
// Serial.print(cacca);
// Serial.println();
lcd.setCursor (0,i+1);
lcd.print("T");
lcd.setCursor(1,i+1);
lcd.print(i+1);
lcd.setCursor (3,i+1);
lcd.print(Tambientale[i]);
Time = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (Time - starTime >= period) //test whether the period has elapsed
{
starTime = Time; //IMPORTANT to save the start time of the current LED state.
}
}else{
Serial.println("Error");
}
}
}
Input = (Tambientale[0]+ Tambientale[1])/2;
lcd.setCursor(9,3);
lcd.print("Ta ");
lcd.setCursor(13,3);
lcd.print(int(Input));
Setpoint=Tset;
myPID.Compute();
lcd.setCursor(10,0);
lcd.print(Output);
analogWrite(MR_PWM, Output);
lcd.setCursor(12,3);
lcd.print(Input);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment