diff --git a/README.md b/README.md index 6df47a6..187d156 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,12 @@ 0 - Температура включения реле (если ниже, включится) (в 0.01 градуса) 1 - Температура выключения реле (если выше, выключится) (в 0.01 градуса) -2 - Режим работы (0 - авто, 1 - принудительно включено, 2 - принудительно выключено) +2 - Режим работы (0 - авто, 1 - вручную) 3 - Текущая температура (в 0.01 градуса) -4 - Текущее состояние реле (0 - выключено, 1 - включено) \ No newline at end of file +4 - Текущее состояние реле (0 - выключено, 1 - включено) +5 - Дополнительная температура (второй датчик) + +Используется вот такой термистор +https://files.amperka.ru/datasheets/B57164.pdf +Из них тот у которого 10кОм при 25градусах + diff --git a/defrost.service b/defrost.service new file mode 100644 index 0000000..ef56aee --- /dev/null +++ b/defrost.service @@ -0,0 +1,13 @@ +[Unit] +Description=Defrost service +After=network.target + +[Service] +ExecStart=/home/root/bin/defrost /home/root/bin/defrost.cfg +User=root +Group=root +RuntimeDirectory=/home/root/bin +RuntimeDirectoryMode=0755 + +[Install] +WantedBy=multi-user.target diff --git a/src/ModbusServiceWorker.cpp b/src/ModbusServiceWorker.cpp index d904606..a7f2c34 100644 --- a/src/ModbusServiceWorker.cpp +++ b/src/ModbusServiceWorker.cpp @@ -1,5 +1,6 @@ #include "ModbusServiceWorker.h" #include "libdiff.h" +#include "globals.h" #include @@ -15,7 +16,55 @@ void ModbusServiceWorker::Run() try { while (true) { - + string header = s.Receive(7); + string transaction_id = header.substr(0, 2); + string protocol_id = header.substr(2, 2); + int length = ((int)(unsigned char)header[5]) | (((int)(unsigned char)header[4]) << 8); + string unit_identifier = header.substr(6, 1); + log->LogString("Receiving modbus frame of length " + ToString(length)); + string data = s.Receive(length - 1); + log->LogString("Received modbus frame of length " + ToString(length)); + string answer_data = ""; + int function = data[0]; + log->LogString("Processing function " + ToString(function)); + if (function == 3) + { + LockMutex(register_mutex); + int address = GetInt(data.substr(1, 2)); + int amount = GetInt(data.substr(3, 2)); + string result = ""; + for (int a = address; a < address + amount; a++) + { + int val = 0; + if (a >= 0 && a <= 65535) val = registers[a]; + result += (char)((val >> 8) & 0xFF); + result += (char)(val & 0xFF); + } + ReleaseMutex(register_mutex); + answer_data += (char)3; + answer_data += (char)result.length(); + answer_data += result; + } + else if (function == 6) + { + LockMutex(register_mutex); + int address = GetInt(data.substr(1, 2)); + int value = GetInt(data.substr(3, 2)); + if (address >= 0 && address <= 65535) + { + registers[address] = value; + } + ReleaseMutex(register_mutex); + answer_data = data; + } + else throw (string)("Unknown function " + ToString(function)); + answer_data = unit_identifier + answer_data; + string length_str = ""; + length_str += (char)((answer_data.length() >> 8) & 0xFF); + length_str += (char)((answer_data.length()) & 0xFF); + log->LogString("Sending answer"); + s.Send(transaction_id + protocol_id + length_str + answer_data); + log->LogString("Answer sent"); } } catch (string s) @@ -34,6 +83,17 @@ void ModbusServiceWorker::Run() s.Disconnect(); } +int ModbusServiceWorker::GetInt(const string &s) +{ + int res = 0; + for (int i = 0; i < (int)s.length(); i++) + { + res <<= 8; + res += (int)(unsigned char)s[i]; + } + return res; +} + ModbusServiceWorker::~ModbusServiceWorker() { s.Disconnect(); diff --git a/src/ModbusServiceWorker.h b/src/ModbusServiceWorker.h index c1d8dab..7739885 100644 --- a/src/ModbusServiceWorker.h +++ b/src/ModbusServiceWorker.h @@ -12,6 +12,8 @@ class ModbusServiceWorker : public Thread int socket; SynchronousSocket s; LogFile *log; + + int GetInt(const std::string &s); protected: virtual void Run(); public: diff --git a/src/defrost.cpp b/src/defrost.cpp index 39a3169..63b6769 100644 --- a/src/defrost.cpp +++ b/src/defrost.cpp @@ -3,6 +3,7 @@ #include "jhd1313m1.h" #include "mraa/common.hpp" #include "mraa/gpio.hpp" +#include "mraa/aio.hpp" #include "globals.h" #include "ModbusServiceListenThread.h" #include "libdiff.h" @@ -13,23 +14,32 @@ #include #include #include +#include #define GPIO_PIN_1 2 +const int AIO_PIN = 1; -void temperature_update(upm::GroveTemp* temperature_sensor, upm::Jhd1313m1 *lcd) +void temperature_update(upm::GroveTemp* temperature_sensor, upm::Jhd1313m1 *lcd, mraa::Aio* additional_t_sensor) { // other helper variables - int temperature; // temperature sensor value in degrees Celsius + float temperature; // temperature sensor value in degrees Celsius float fade; // fade value [0.0 .. 1.0] uint8_t r, g, b; // resulting LCD backlight color components [0 .. 255] std::stringstream row_1, row_2; // LCD rows // update the min and max temperature values - temperature = temperature_sensor->value() * 100; + float voltage = additional_t_sensor->read(); + voltage = voltage * 5 / 1023.0; + temperature = 1.0 / (log(voltage / 2.5) / 4300.0 + 1.0 / 298.0) - 273.0; + temperature *= 100; + temperature = (int)temperature; + registers[REGISTER_CUR_TEMP] = temperature; + float additional_temperature = temperature_sensor->value() * 100; + registers[REGISTER_SECONDARY_TEMP] = additional_temperature; // display the temperature values on the LCD - row_1 << "T " << temperature / 100 << " Mode: "; + row_1 << "T " << temperature / 100 << " M: "; int mode = registers[REGISTER_MODE]; if (mode == 0) row_1 << "auto"; else if (mode == 1) row_1 << "on"; @@ -59,11 +69,11 @@ void temperature_update(upm::GroveTemp* temperature_sensor, upm::Jhd1313m1 *lcd) lcd->setColor(r, g, b); } -int main() +int main(int argc, char *argv[]) { try { // ����� lock-file, ����� ���������� ������ ���� ��������� ������� - int lockfile = open("defrost.lock", O_RDWR | O_CREAT, 0777); + int lockfile = open("/tmp/defrost.lock", O_RDWR | O_CREAT, 0777); if (lockfile == -1) { cout << "Unable to open file for locking, errno = " << errno << "\n"; @@ -90,6 +100,7 @@ int main() { return EXIT_FAILURE; } + mraa::Aio additional_t(AIO_PIN); // temperature sensor connected to A0 (analog in) upm::GroveTemp* temp_sensor = new upm::GroveTemp(0); @@ -105,8 +116,8 @@ int main() } // load config ConfigParser cfg; - cfg.Load("defrost.cfg"); - mainlog.InitLogging(cfg.GetParam("LogPath"), LIBLOGSINGLEFILE); + cfg.Load(argv[1]); + mainlog.InitLogging(cfg.GetParam("LogPath"), LIBLOGSINGLEFILE, "defrost", true); mainlog.LogString("Defrost service started"); if (pthread_mutex_init(®ister_mutex, NULL) != 0) @@ -127,9 +138,18 @@ int main() while (true) { LockMutex(register_mutex); - temperature_update(temp_sensor, lcd); - if (registers[REGISTER_CUR_TEMP] < registers[REGISTER_ON_TEMP]) io_value = 1; - else if (registers[REGISTER_CUR_TEMP] > registers[REGISTER_OFF_TEMP]) io_value = 0; + temperature_update(temp_sensor, lcd, &additional_t); + int mode = registers[REGISTER_MODE]; + if (mode == 0) + { + if (registers[REGISTER_CUR_TEMP] < registers[REGISTER_ON_TEMP]) io_value = 1; + else if (registers[REGISTER_CUR_TEMP] > registers[REGISTER_OFF_TEMP]) io_value = 0; + } + else if (mode == 1) + { + io_value = registers[REGISTER_CUR_STATE]; + } + registers[REGISTER_CUR_STATE] = io_value; gpio.write(io_value); ReleaseMutex(register_mutex); sleep(1); diff --git a/src/globals.h b/src/globals.h index 06d2fba..e60f90b 100644 --- a/src/globals.h +++ b/src/globals.h @@ -8,6 +8,7 @@ const int REGISTER_OFF_TEMP = 1; const int REGISTER_MODE = 2; const int REGISTER_CUR_TEMP = 3; const int REGISTER_CUR_STATE = 4; +const int REGISTER_SECONDARY_TEMP = 5; extern int registers[65536]; extern pthread_mutex_t register_mutex;