온도 센서와 PH센서, 전기 전도도 센서를 한꺼번에 다룰 수 있는 라이브러리 제작 | O |
---|---|
온도 센서로부터 값을 읽어 시리얼 모니터로 출력 | O |
전기 전도도 센서로부터 값을 읽어 시리얼 모니터로 출력 | O |
PH센서로부터 값을 읽어 시리얼 모니터로 출력 | O |
코딩을 처음하는 사람들이 쉽게 쓸 수 있도록 제작 | O |
https://github.com/KiRist-code/PTELibrary
전체 코드는 위 깃허브 링크에 올려두었다.
EC센서를 동작시키는 소스 파일, PH센서를 동작시키는 소스 파일, 온도 센서를 동작시키는 소스 파일, 센세 셋을 묶어서 라이브러리로 만들어주는 소스파일로 구성되어 있다.
#ifndef ECSensor_h
#define ECSensor_h
#include <OneWire.h>
#include "Arduino.h"
#include <stdint.h>
#define StartConvert 0
#define ReadTemperature 1
class EC
{
public:
// arduino class basically set-up
EC() {}
EC(uint8_t EC_pin, uint8_t DS18B20_pin) { begin(EC_pin, DS18B20_pin); };
void begin(uint8_t EC_pin, uint8_t DS18B20_pin);
// personal set-up
void initSensor();
void EC_read();
void DS18B20_read();
float TempProcess(bool ch);
// getter
float getDSTemp();
unsigned int getAnalogAverage();
unsigned int getAverageVoltage();
void setPrintTime();
unsigned long getPrintTime();
float getECcurrent();
private:
uint8_t _EC_pin;
uint8_t _DS18D20_pin;
byte customChar[8];
float ECcurrent;
unsigned int AnalogSampleInterval;
unsigned long AnalogValueTotal;
unsigned int AnalogAverage, averageVoltage;
unsigned long AnalogSampleTime, printTime, tempSampleTime;
unsigned int readings[20];
byte index;
float temperature;
unsigned int tempSampleInterval;
byte numReadings;
OneWire ds;
};
#endif
헤더파일에서 EC 센서를 다루는 클래스를 다음 코드와 같이 생성해주었다. 클래스 내에서 EC센서를 초기화 및 센서값 읽기 함수를 미리 선언해, 소스 파일 내에서 구현할 수 있도록 제작하였다.
#include "ECSensor.h"
#include "Arduino.h"
void EC::begin(uint8_t EC_pin, uint8_t DS18B20_pin)
{
this->_EC_pin = EC_pin;
this->_DS18D20_pin = DS18B20_pin;
this->AnalogSampleInterval = 25;
this->AnalogValueTotal = 0;
this->AnalogAverage = 0;
this->averageVoltage = 0;
this->index = 0;
this->tempSampleInterval = 850;
this->numReadings = 20;
byte inputCustomChar[] = {B11000, B11000, B00111, B01000, B01000, B01000, B00111, B00000};
for (int i = 0; i < 8; i++)
{
this->customChar[i] = inputCustomChar[i];
}
this->ds = OneWire(_DS18D20_pin);
// initLCD();
EC::initSensor();
}
void EC::initSensor()
{
for (byte thisReading = 0; thisReading < numReadings; thisReading++)
{
readings[thisReading] = 0;
}
TempProcess(StartConvert);
AnalogSampleTime = millis();
setPrintTime();
tempSampleTime = millis();
}
void EC::EC_read()
{
if (millis() - AnalogSampleTime >= AnalogSampleInterval)
{
AnalogSampleTime = millis();
AnalogValueTotal = AnalogValueTotal - readings[index];
readings[index] = analogRead(_EC_pin);
AnalogValueTotal = AnalogValueTotal + readings[index];
index = index + 1;
if (index >= numReadings)
{
index = 0;
}
AnalogAverage = AnalogValueTotal / numReadings;
}
}
void EC::DS18B20_read()
{
if (millis() - tempSampleTime >= tempSampleInterval)
{
tempSampleTime = millis();
temperature = TempProcess(ReadTemperature);
TempProcess(StartConvert);
}
}
float EC::TempProcess(bool ch)
{
static byte data[12];
static byte addr[8];
static float TemperatureSum;
if (!ch)
{
if (!ds.search(addr))
{
Serial.println("no more sensors on chain, reset search!");
ds.reset_search();
return 0;
}
if (OneWire::crc8(addr, 7) != addr[7])
{
Serial.println("CRC is not vaild!");
return 0;
}
if (addr[0] != 0x10 && addr[0] != 0x28)
{
Serial.print("Device is not recognized!");
return 0;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1);
}
else
{
byte present = ds.reset();
ds.select(addr);
ds.write(0xBE);
for (int i = 0; i < 9; i++)
{
data[i] = ds.read();
}
ds.reset_search();
byte MSB = data[1];
byte LSB = data[0];
float tempRead = ((MSB << 8) | LSB);
TemperatureSum = tempRead / 16;
}
return TemperatureSum;
}
// getter
float EC::getDSTemp()
{
return temperature;
}
unsigned int EC::getAnalogAverage()
{
return AnalogAverage;
}
unsigned int EC::getAverageVoltage()
{
averageVoltage = AnalogAverage * (float)5000 / 1024;
return averageVoltage;
}
unsigned long EC::getPrintTime()
{
return printTime;
}
void EC::setPrintTime()
{
printTime = millis();
}
float EC::getECcurrent()
{
float TempCoefficient = 1.0 + 0.0185 * (temperature - 25.0);
float CoefficientVoltage = (float)averageVoltage / TempCoefficient;
if (CoefficientVoltage < 150)
{
return -1; // No Solution
}
else if (CoefficientVoltage > 3300)
{
return -2; // Out of Range
}
else
{
if (CoefficientVoltage <= 448)
{
ECcurrent = 6.84 * CoefficientVoltage - 64.32;
}
else if (CoefficientVoltage <= 1457)
{
ECcurrent = 6.98 * CoefficientVoltage - 127;
}
else
{
ECcurrent = 5.3 * CoefficientVoltage + 2278;
}
ECcurrent /= 1000;
return ECcurrent;
}
}