Skip to content
Snippets Groups Projects
Commit 3dbfd928 authored by Benedikt Burger's avatar Benedikt Burger
Browse files

Merge branch 'master' of git.rwth-aachen.de:nloqo/arduino-sketches

parents e01b97f8 48433439
No related branches found
No related tags found
No related merge requests found
const String version = "ReadFlow 1.3"; // Version of this script
//-----------------------------------------Define variables and pins-----------
const int flowChannelC15 = 0;
const int tempChannelC15 = 2;
float rateC15 = 1.0;
float startTimeC15 = 0.0;
float endTimeC15 = 0.0;
float resistance = 20000.0;
float tempResistanceC15 = 0;
float tempValueC15 = 0;
float tempC15 = 0.0;
float rotationValueC15 = 0.0;
float lastValueC15 = 0.0;
// sensor parameters
const int averaging = 50; // Number of times for the running average
int precision = 5; // Number of digits to print.
const int highVoltage = 500;
float timeC15 = 0.0;
#include "RunningAverage.h"
RunningAverage average0(averaging); //generate running average variable
RunningAverage average2(averaging); //generate running average variable
//---------------------------------------Start loop----------------------------
void sendSensorDataLast(){
// Send the last sensor values.
Serial.print(rateC15, precision);
Serial.print("\t");
Serial.print(tempC15, precision);
Serial.println();
};
void sendSensorDataAverage(){
// Send the running average sensor values.
Serial.print(average0.getAverage(), precision);
Serial.print("\t");
Serial.print(average2.getAverage(), precision);
Serial.println();
};
void sendSensorDataRaw(){
// Send raw analouge input values.
Serial.print(rotationValueC15);
Serial.print("\t");
Serial.print(tempValueC15);
Serial.println();
};
void setup()
{
Serial.begin(9600);
}
void loop()
{
rotationValueC15 = analogRead(flowChannelC15);
tempValueC15 = analogRead(tempChannelC15);
endTimeC15 = millis();
if(lastValueC15 < highVoltage && rotationValueC15 > highVoltage)
{
timeC15 = endTimeC15 - startTimeC15;
rateC15 = 1 / timeC15 * 1000 / 8.8936;
startTimeC15 = millis();
};
lastValueC15 = rotationValueC15;
tempResistanceC15 = resistance * ((1024 / tempValueC15) - 1); // Calculate the temperature dependent resistance in case the voltage is measured with a total voltage of 5 V between a reference point and ground over the constant resistor.
tempC15 = 1 / (log(tempResistanceC15 / 50000) / 3642 + 1 / 298.15) - 273.15;
average0.addValue(rateC15);
average2.addValue(tempC15);
if (Serial.available()){
char input[20];
int len;
len = Serial.readBytesUntil('\n', input, 20);
input[len] = '\0'; // Null terminating the array to interpret it as a string
switch (input[0]){
case 'p': // Ping
Serial.println("pong");
break;
case 'l': // Send last sensor data
sendSensorDataLast();
break;
case 'q': // Send read average sensor data
sendSensorDataAverage();
break;
case 'f': //Set the precision
precision = atoi(&input[1]);
break;
case 'd': // debug
Serial.println("debug");
break;
case 'v': // Send Version
Serial.println(version);
break;
case 't': // Send time
Serial.println(timeC15);
break;
};
};
}
/*
***************************
* Read sensor values and calculate a PID value from sensor 0.
* Depending on this PID value, a relay is switched.
***************************
*/
const String version = "TemperatureController 1.0.1"; // Version of this script
//** CONSTANTS **//
const int cyclePeriod = 30000; //program cycle period in ms
// I/O-pins
const int sensor0Pin = 0; //Channel to which the sensor 0 is connected
const int sensor1Pin = 1; //Channel to which the sensor 1 is connected
const int sensorWater = 2;
const int waterThreshold = 341;
const int relayPin = 11; //Pin by which the relay unit is controlled (11 or 12)
const int indicatorPin = 3; //Pin sending a control signal, indicating if the relay is closed
const int tooColdPin = 2; //Pin being set high, if the temperature is too low
const int tooHotPin = 4; //Pin being set high, if the temperature is too high
const int powerPin = 13; //Pin for indicating device is on; also used to indicate errors
#include <EEPROM.h>
const int floatsize = sizeof(float);
// sensor parameters
long measurements = 100; //How many times should the sensor be read for a single readout?
const int averaging = 50; // Number of times for the running average
int precision = 5; // Number of digits to print.
// MISC
const long rolloverThreshold = 4294965000; //After how many milliseconds should we suspend normal operation to await millis()-rollover? (Should be at least cyclePeriod+digitalPinSetDelay below the maximum value of an unsigned long of 4.294.967.295)
// ********************************************************************************
// ***********************************VARIABLES************************************
// Sensor values.
float sensor0Value = 0; //Define sensor value variable
float sensor1Value = 0; //Define sensor value variable
int waterSensorValue = 0;
#include "RunningAverage.h"
RunningAverage average0(averaging); //generate running average variable
RunningAverage average1(averaging); //generate running average variable
// As we only want to do one measurement per second, we need to know, when we last ran.
unsigned long nextCycle = 3000; //set starting values for an initial delay of 5s to prevent racing conditions on start
unsigned long nextOff = 0; // When to switch off the heater the next time
//******************************PID-CONTROL*****************************************
// Werte werden aus EEPROM gelesen
float setpoint; // setpoint for the temperature = 36°C
float PIDKp; //Wert für die PID Regelung (Proportional-Teil)
float PIDKi; //Wert für die PID Regelung (Integral-Teil)
float integral; //Wert für die PID Integralteil
int controller = 2; // controller mode: 0 = off, 1 = control cooling only, 2 = full control
boolean autoData=false;
//******************************************************************************
void setup() {
//Setup the serial connection and the pins
Serial.begin(9600);
pinMode(tooColdPin,OUTPUT);
pinMode(tooHotPin,OUTPUT);
pinMode(indicatorPin, OUTPUT);
pinMode(relayPin, OUTPUT);
pinMode(powerPin, OUTPUT);
digitalWrite(powerPin, HIGH);
digitalWrite(indicatorPin, HIGH);
// Read PID values
EEPROM.get(0 * floatsize, setpoint);
if ( isnan(setpoint)){
setpoint = 400;
}
EEPROM.get(1 * floatsize, PIDKp);
if ( isnan(PIDKp)){
PIDKp = -1000;
}
EEPROM.get(2 * floatsize, PIDKi);
if ( isnan(PIDKi)){
PIDKi = -1;
}
EEPROM.get(3 * floatsize, integral);
if ( isnan(integral) || integral < 0 || integral > 1000 ){
integral = 100;
}
}
void loop(){
// Read the sensor many times and calculate the average
sensor0Value = 0;
sensor1Value = 0;
for(int x=1; x <= measurements; x++){
sensor0Value += analogRead(sensor0Pin);
sensor1Value += analogRead(sensor1Pin);
}
sensor0Value /= measurements;
sensor1Value /= measurements;
average0.addValue(sensor0Value);
average1.addValue(sensor1Value);
int waterSensorValue = analogRead(sensorWater)
if (waterSensorValue > waterthreshold){
controller = 0
controlRelay(false)
}
//Serial communication
if(autoData){
sendSensorDataLast();
}
if ( Serial.available() ){
char input[20];
int len;
len = Serial.readBytesUntil('\n', input, 20);
input[len] = '\0'; // Null terminating the array to interpret it as a string
switch (input[0]){
case 'p': // Ping
Serial.println("Pong");
break;
case 'r': // Send read average sensor data
sendSensorDataAverage();
break;
case 'l': // Send sensor data
sendSensorDataLast();
break;
case 'm': //Set number of measurements
measurements = atoi(&input[1]);
break;
case 'f': //Set the precision
precision = atoi(&input[1]);
break;
case 'a': // Automatically send sensor data
if ( input[1] <= '0' ){
autoData= false;
Serial.println("ACK autoOff");
}
else {
autoData=true;
Serial.println("ACK autoOn");
}
break;
case 'c': // Configure the controller
controller = input[1]-'0';
Serial.println("ACK-controller");
break;
case 'k'://Einstellen der PID Parameter
if ( input[1] == 'p'){
PIDKp=atof(&input[2]);
Serial.println("ACK-Kp");
}
else if ( input[1] == 'i'){
PIDKi=atof(&input[2]);
Serial.println("ACK-Ki");
}
else if ( input[1] == 'x'){
integral=atof(&input[2]);
Serial.println("ACK-integral");
}
else if ( input[1] == 's'){
setpoint = atof(&input[2]);
Serial.println("ACK-setpoint");
}
break;
case 'o': // control the relay itself
if ( input[1] <= '0' ){
controlRelay( false );
Serial.println("ACK openRelay");
}
else {
controlRelay( true );
Serial.println("ACK closeRelay");
}
break;
case 'd': // debug
Serial.print(integral);
Serial.print(", p:");
Serial.print(PIDKp);
Serial.print(", i:");
Serial.print(PIDKi);
Serial.print(", setpoint: ");
Serial.print(setpoint);
Serial.println();
break;
case 'v': // Send Version
Serial.println(version);
break;
case 'e': // Store values in EEPROM
EEPROM.put(0 * floatsize, setpoint);
EEPROM.put(1 * floatsize, PIDKp);
EEPROM.put(2 * floatsize, PIDKi);
EEPROM.put(3 * floatsize, integral);
Serial.println("ACK EEPROM saved.");
break;
}
}
// Control temperature, if desired
if ( millis() >= nextCycle ){
if (controller & 2){
calculatePID();
}
nextCycle += cyclePeriod;
}
if ( millis() >= nextOff && nextOff > 0){
controlRelay(false);
}
//if we are within 2300ms of rollover of millis counter suspend normal operation
if (millis() > rolloverThreshold){
nextCycle = cyclePeriod; //set everything for continuing normal operation after rollover
while (millis() > rolloverThreshold){}; //wait for rollover to happen
};
}
void sendSensorDataLast(){
// Send the last sensor values.
Serial.print(sensor0Value, precision);
Serial.print("\t");
Serial.print(sensor1Value, precision);
Serial.print("\t");
Serial.print(setpoint, precision);
Serial.println();
}
void sendSensorDataAverage(){
// Send the running average sensor values.
Serial.print(average0.getAverage(), precision);
Serial.print("\t");
Serial.print(average1.getAverage(), precision);
Serial.println();
}
void calculatePID(){
// Calculate the PID signal
float error = setpoint - average0.getAverage();
integral += PIDKi * error;
if (integral > cyclePeriod){
integral = cyclePeriod;
}
else if (integral < 0){
integral = 0;
}
float pid = PIDKp * error + integral;
if (pid < 0){
nextOff = 0;
}
else {
nextOff = millis() + pid;
controlRelay( true );
}
}
void controlRelay(const boolean close){
//Open or close the relay
if ( close ){
digitalWrite(relayPin, HIGH);
digitalWrite(indicatorPin, HIGH);
}
else {
digitalWrite(relayPin, LOW);
digitalWrite(indicatorPin, LOW);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment