Compare commits

..

No commits in common. "8ef70c197c69d2c4986ab75b7f0791c64b9c9906" and "1ee9c671790fdbea8e7387b66518ff862c9d19b2" have entirely different histories.

15 changed files with 620 additions and 639 deletions

View File

@ -1,24 +1,24 @@
{ {
"configurations": [ "configurations": [
{ {
"name": "Linux", "name": "Linux",
"includePath": [ "includePath": [
"${workspaceFolder}/**", "${workspaceFolder}/**",
"/usr/include/gtk-3.0", "/usr/include/gtk-3.0",
"/usr/include/glib-2.0", "/usr/include/glib-2.0",
"/usr/lib/arm-linux-gnueabihf/glib-2.0/include", "/usr/lib/arm-linux-gnueabihf/glib-2.0/include",
"/usr/include/cairo", "/usr/include/cairo",
"/usr/include/pango-1.0", "/usr/include/pango-1.0",
"/usr/include/gdk-pixbuf-2.0", "/usr/include/gdk-pixbuf-2.0",
"/usr/include/atk-1.0", "/usr/include/atk-1.0",
"/usr/include/harfbuzz/" "/usr/include/harfbuzz/"
], ],
"defines": [], "defines": [],
"compilerPath": "/usr/bin/gcc", "compilerPath": "/usr/bin/gcc",
"cStandard": "c11", "cStandard": "c11",
"cppStandard": "c++17", "cppStandard": "c++17",
"intelliSenseMode": "linux-gcc-x64" "intelliSenseMode": "linux-gcc-x64"
} }
], ],
"version": 4 "version": 4
} }

36
.vscode/settings.json vendored
View File

@ -1,19 +1,19 @@
{ {
"files.associations": { "files.associations": {
"sx1278.h": "c", "sx1278.h": "c",
"godex500.h": "c", "godex500.h": "c",
"curl2.h": "c", "curl2.h": "c",
"utils.h": "c", "utils.h": "c",
"main.h": "c", "main.h": "c",
"gtk.h": "c", "gtk.h": "c",
"stend_logic.h": "c", "stend_logic.h": "c",
"mainform.h": "c", "mainform.h": "c",
"button_handlers.h": "c", "button_handlers.h": "c",
"ui.h": "c", "ui.h": "c",
"widgets.h": "c", "widgets.h": "c",
"ui_controller.h": "c", "ui_controller.h": "c",
"constants.h": "c", "constants.h": "c",
"stend_controller.h": "c", "stend_controller.h": "c",
"error.h": "c" "error.h": "c"
} }
} }

View File

@ -11,4 +11,4 @@
#define PIN_Speaker 26 #define PIN_Speaker 26
#define SerialDevice "/dev/ttyUSB0" #define SerialDevice "/dev/ttyUSB0"
#define API_URL "http://192.168.122.161:8000/api/" #define API_URL "http://192.168.122.120:3000/api/"

View File

@ -1,5 +1,5 @@
#include "../Inc/Godex500.h" #include "../Inc/Godex500.h"
const int OFFSET = 0; const int OFFSET = 131;
int GODEX500_setup_serial(const char* device) { int GODEX500_setup_serial(const char* device) {
int serial_port = open(device, O_RDWR); int serial_port = open(device, O_RDWR);
if (serial_port < 0) { if (serial_port < 0) {
@ -49,8 +49,7 @@ void GODEX500_print_label(int serial_port, const char* id, const char* model) {
snprintf(buffer, sizeof(buffer), snprintf(buffer, sizeof(buffer),
"^Q10,2\n" "^Q10,2\n"
"^W25\n" "^W25^H14\n"
"^H14\n"
"^P1\n" "^P1\n"
"^S2\n" "^S2\n"
"^AT\n" "^AT\n"

View File

@ -1,419 +1,405 @@
#include "../Inc/stend_logic.h" #include "../Inc/stend_logic.h"
#include "../../controllers/Inc/ui_controller.h" #include "../../controllers/Inc/ui_controller.h"
// Макросы для различных пороговых значений и констант // Макросы для различных пороговых значений и констант
#define THRESHOLD_TIME 500 // Время для проверки концевика (в миллисекундах) #define THRESHOLD_TIME 500 // Время для проверки концевика (в миллисекундах)
#define PRESSURE_TOLERANCE 5 // Допустимая погрешность давления #define PRESSURE_TOLERANCE 5 // Допустимая погрешность давления
#define PRESSURE_MEASUREMENTS_DURATION 3000 // Время для измерений давления (в миллисекундах) #define PRESSURE_MEASUREMENTS_DURATION 3000 // Время для измерений давления (в миллисекундах)
#define PRESSURE_NUMBER_OF_CHECKS 10 // Количество проверок давления #define PRESSURE_NUMBER_OF_CHECKS 10 // Количество проверок давления
#define SEND_FRAME_NUMBER_OF_ATTEMPTS 3 // Количество попыток для отправки кадра калибровки #define SEND_FRAME_NUMBER_OF_ATTEMPTS 3 // Количество попыток для отправки кадра калибровки
#define MAX_PRESSURE_THRESHOLD 500 // Максимальное давление в контуре для проверки (5.00 бар) #define MAX_PRESSURE_THRESHOLD 500 // Максимальное давление в контуре для проверки (5.00 бар)
#define PRESSURE_DROP_TOLERANCE 5 // Допустимое падение давления (0.05 бар) #define PRESSURE_DROP_TOLERANCE 5 // Допустимое падение давления (0.05 бар)
#define SENSOR_RESPONSE_TIMEOUT 5000 // Таймаут ожидания ответа от датчика (в миллисекундах) #define SENSOR_RESPONSE_TIMEOUT 5000 // Таймаут ожидания ответа от датчика (в миллисекундах)
// Глобальные переменные // Глобальные переменные
static PressureData pressure_data; static PressureData pressure_data;
static ErrorData error_data; static ErrorData error_data;
static ActionState current_action = ACTION_WAIT_SENSOR; static ActionState current_action = ACTION_WAIT_SENSOR;
static EtalonSensor etalonSensor; static EtalonSensor etalonSensor;
static TestSensor testSensor; static TestSensor testSensor;
static SxTransmit sxTransmit_data; static SxTransmit sxTransmit_data;
static SxResive sxResive_data; static SxResive sxResive_data;
static uint8_t rxBuffer[SX1278_PAYLOAD]; static uint8_t rxBuffer[SX1278_PAYLOAD];
static uint8_t txBuffer[SX1278_PAYLOAD]; static uint8_t txBuffer[SX1278_PAYLOAD];
static char LabelText[100]; static char LabelText[100];
static char datetime[64]; static char datetime[64];
static char post_data[512]; static char post_data[512];
static char jsonDataBuffer[1024*50]; static char jsonDataBuffer[1024*50];
static int8_t serial_port; static int8_t serial_port;
void reset_pressure_data() { void reset_pressure_data() {
pressure_data.min_pressure = UINT16_MAX; // Устанавливаем максимальное значение pressure_data.min_pressure = UINT16_MAX; // Устанавливаем максимальное значение
pressure_data.max_pressure = 0; pressure_data.max_pressure = 0;
pressure_data.counter_pressure = 0; pressure_data.counter_pressure = 0;
pressure_data.sum_pressure = 0; pressure_data.sum_pressure = 0;
pressure_data.avg_pressure = 0; pressure_data.avg_pressure = 0;
log_debug("Данные давления сброшены"); log_debug("Данные давления сброшены");
} }
void reset_sxResive_data() { void reset_sxResive_data() {
memset(&sxResive_data, 0, sizeof(SxResive)); memset(&sxResive_data, 0, sizeof(SxResive));
log_debug("Данные приёма SX1278 сброшены"); log_debug("Данные приёма SX1278 сброшены");
} }
void reset_sxTransmit_data() { void reset_sxTransmit_data() {
memset(&sxTransmit_data, 0, sizeof(SxTransmit)); memset(&sxTransmit_data, 0, sizeof(SxTransmit));
log_debug("Данные передачи SX1278 сброшены"); log_debug("Данные передачи SX1278 сброшены");
} }
void reset_error_data() { void reset_error_data() {
*(uint8_t*)&error_data = 0; // Сбрасываем все биты в 0 *(uint8_t*)&error_data = 0; // Сбрасываем все биты в 0
log_debug("Данные ошибок сброшены"); log_debug("Данные ошибок сброшены");
} }
void reset_test_data() { void reset_test_data() {
memset(&testSensor, 0, sizeof(TestSensor)); memset(&testSensor, 0, sizeof(TestSensor));
log_debug("Данные тестового датчика сброшены"); log_debug("Данные тестового датчика сброшены");
} }
void reset_all_data() { void reset_all_data() {
reset_pressure_data(); reset_pressure_data();
reset_error_data(); reset_error_data();
reset_test_data(); reset_test_data();
reset_sxTransmit_data(); reset_sxTransmit_data();
reset_sxResive_data(); reset_sxResive_data();
log_info("Все данные сброшены"); log_info("Все данные сброшены");
} }
bool check_gpio() { bool check_gpio() {
// Проверка сработки концевика в течение THRESHOLD_TIME // Проверка сработки концевика в течение THRESHOLD_TIME
uint32_t start_time = millis(); uint32_t start_time = millis();
log_trace("Проверка состояния GPIO"); log_trace("Проверка состояния GPIO");
while ((millis() - start_time) < THRESHOLD_TIME) { while ((millis() - start_time) < THRESHOLD_TIME) {
if (!digitalRead(PIN_KONCEVIK)) { if (!digitalRead(PIN_KONCEVIK)) {
// Концевик сработал // Концевик сработал
log_debug("Концевой выключатель активирован"); log_debug("Концевой выключатель активирован");
return true; return true;
} }
delay(100); // Задержка 100 миллисекунд delay(100); // Задержка 100 миллисекунд
} }
// Концевик не сработал // Концевик не сработал
log_warn("Концевой выключатель не активирован в течение порогового времени"); log_warn("Концевой выключатель не активирован в течение порогового времени");
return false; return false;
} }
void release_pressure() { void release_pressure() {
log_info("Спуск давления"); log_info("Спуск давления");
digitalWrite(PIN_AIR_INPUT, LOW); digitalWrite(PIN_AIR_INPUT, LOW);
digitalWrite(PIN_AIR_OUTPUT, HIGH); digitalWrite(PIN_AIR_OUTPUT, HIGH);
delay(1000); // Подождать 1 секунду delay(1000); // Подождать 1 секунду
digitalWrite(PIN_AIR_OUTPUT, LOW); digitalWrite(PIN_AIR_OUTPUT, LOW);
} }
void close_Serial(){ void close_Serial(){
close(serial_port); close(serial_port);
log_info("Порт закрыт"); log_info("Порт закрыт");
} }
void read_sx1278_data() { void read_sx1278_data() {
if (digitalRead(PIN_DIO0) == HIGH) { if (digitalRead(PIN_DIO0) == HIGH) {
SX1278_FIFO_ReadData(rxBuffer); SX1278_FIFO_ReadData(rxBuffer);
memcpy(&sxResive_data, rxBuffer, sizeof(SxResive)); memcpy(&sxResive_data, rxBuffer, sizeof(SxResive));
log_trace("Данные получены от SX1278"); log_trace("Данные получены от SX1278");
if (sxResive_data.type == 0x90) { if (sxResive_data.type == 0x90) {
set_etalonSensor_data(); set_etalonSensor_data();
} }
} }
} }
void set_testSensor_data(){ void set_testSensor_data(){
memcpy(&testSensor, &sxResive_data.data, sizeof(TestSensor)); memcpy(&testSensor, &sxResive_data.data, sizeof(TestSensor));
testSensor.rssi = SX1278_ReadRegister(REG_RSSIVALUE) >> 1; testSensor.rssi = SX1278_ReadRegister(REG_RSSIVALUE) >> 1;
log_debug("Обновлены данные тестового датчика: ID = %X, Давление = %u", testSensor.id_sensor, testSensor.pressure); log_debug("Обновлены данные тестового датчика: ID = %X, Давление = %u", testSensor.id_sensor, testSensor.pressure);
} }
void set_etalonSensor_data(){ void set_etalonSensor_data(){
memcpy(&etalonSensor, &sxResive_data.data, sizeof(EtalonSensor)); memcpy(&etalonSensor, &sxResive_data.data, sizeof(EtalonSensor));
snprintf(LabelText, sizeof(LabelText), "Текущее давление: %d.%02d", etalonSensor.pressure / 100, etalonSensor.pressure % 100); snprintf(LabelText, sizeof(LabelText), "Текущее давление: %d.%02d", etalonSensor.pressure / 100, etalonSensor.pressure % 100);
Set_New_LableCurrentPressure(LabelText); Set_New_LableCurrentPressure(LabelText);
log_trace("Обновлены данные эталонного датчика: Давление = %u", etalonSensor.pressure); log_trace("Обновлены данные эталонного датчика: Давление = %u", etalonSensor.pressure);
} }
char* lastModelName = ""; void* stend_logic() {
void reprintSticker(){
if(testSensor.id_sensor > 0){ log_set_level(LOG_DEBUG);
GODEX500_print_label(serial_port, NumToHexString(testSensor.id_sensor), lastModelName); // Инициализация проекта
} uint8_t init = InitializationProject(API_URL, PIN_NSS, PIN_RST, PIN_DIO0, PIN_KONCEVIK,
} PIN_AIR_INPUT, PIN_AIR_OUTPUT, &serial_port, SerialDevice);
if (init != 0) {
void* stend_logic() { log_fatal("Ошибка инициализации проекта");
return NULL;
log_set_level(LOG_DEBUG); }
// Инициализация проекта log_info("Проект успешно инициализирован");
uint8_t init = InitializationProject(API_URL, PIN_NSS, PIN_RST, PIN_DIO0, PIN_KONCEVIK,
PIN_AIR_INPUT, PIN_AIR_OUTPUT, &serial_port, SerialDevice); SX1278_SetMode(SX1278_MODE_RECEIVER);
if (init != 0) { log_info("SX1278 установлен в режим приёма");
log_fatal("Ошибка инициализации проекта");
return NULL; while (1) {
} // Чтение данных из модуля
log_info("Проект успешно инициализирован"); read_sx1278_data();
SX1278_SetMode(SX1278_MODE_RECEIVER); // Проверка состояния концевика
log_info("SX1278 установлен в режим приёма"); if (digitalRead(PIN_KONCEVIK)) {
current_action = ACTION_WAIT_SENSOR;
while (1) { log_trace("Состояние концевого выключателя изменилось, возвращаемся к ACTION_WAIT_SENSOR");
// Чтение данных из модуля }
read_sx1278_data();
switch (current_action) {
// Проверка состояния концевика case ACTION_WAIT_SENSOR:
if (digitalRead(PIN_KONCEVIK)) { Set_New_ButtonMain_Label("Ожидание установки датчика...");
current_action = ACTION_WAIT_SENSOR; log_trace("Состояние: ACTION_WAIT_SENSOR");
log_trace("Состояние концевого выключателя изменилось, возвращаемся к ACTION_WAIT_SENSOR"); if (!digitalRead(PIN_KONCEVIK)) {
} delay(500); // Подождать полсекунды
if (!digitalRead(PIN_KONCEVIK)) {
switch (current_action) { current_action = ACTION_CHECK_SENSOR_ACTIVATION;
case ACTION_WAIT_SENSOR: log_debug("Датчик обнаружен, переходим к ACTION_CHECK_SENSOR_ACTIVATION");
Set_New_ButtonMain_Label("Ожидание установки датчика..."); }
log_trace("Состояние: ACTION_WAIT_SENSOR"); }
if (!digitalRead(PIN_KONCEVIK)) { break;
delay(500); // Подождать полсекунды
if (!digitalRead(PIN_KONCEVIK)) { case ACTION_CHECK_SENSOR_ACTIVATION:
current_action = ACTION_CHECK_SENSOR_ACTIVATION; log_trace("Состояние: ACTION_CHECK_SENSOR_ACTIVATION");
log_debug("Датчик обнаружен, переходим к ACTION_CHECK_SENSOR_ACTIVATION"); if (check_gpio()) {
} Set_New_ButtonMain_Label("Начало цикла проверки...");
} Set_New_LableSensorPressure("Поиск датчика...");
break; Set_Color_ButtonMain_white();
Update_Error_Table(0);
case ACTION_CHECK_SENSOR_ACTIVATION: reset_all_data();
log_trace("Состояние: ACTION_CHECK_SENSOR_ACTIVATION"); current_action = ACTION_SET_PRESSURE;
if (check_gpio()) { log_debug("Проверка GPIO пройдена, переходим к ACTION_SET_PRESSURE");
Set_New_ButtonMain_Label("Начало цикла проверки..."); } else {
Set_New_LableSensorPressure("Поиск датчика..."); // Если концевик не активен, возвращаемся к ожиданию
Set_Color_ButtonMain_white(); current_action = ACTION_WAIT_SENSOR;
Update_Error_Table(0); log_warn("Проверка GPIO не пройдена, возвращаемся к ACTION_WAIT_SENSOR");
reset_all_data(); }
current_action = ACTION_SET_PRESSURE; break;
log_debug("Проверка GPIO пройдена, переходим к ACTION_SET_PRESSURE");
} else { case ACTION_SET_PRESSURE:
// Если концевик не активен, возвращаемся к ожиданию log_trace("Состояние: ACTION_SET_PRESSURE");
current_action = ACTION_WAIT_SENSOR; Set_New_ButtonMain_Label("Установка давления...");
log_warn("Проверка GPIO не пройдена, возвращаемся к ACTION_WAIT_SENSOR"); digitalWrite(PIN_AIR_INPUT, HIGH);
} log_debug("Вход воздуха активирован");
break; delay(2000); // Подождать 2 секунды
digitalWrite(PIN_AIR_INPUT, LOW);
case ACTION_SET_PRESSURE: log_debug("Вход воздуха деактивирован");
log_trace("Состояние: ACTION_SET_PRESSURE"); current_action = ACTION_GET_SENSOR_ID;
Set_New_ButtonMain_Label("Установка давления..."); break;
digitalWrite(PIN_AIR_INPUT, HIGH);
log_debug("Вход воздуха активирован"); case ACTION_GET_SENSOR_ID:
delay(2000); // Подождать 2 секунды log_trace("Состояние: ACTION_GET_SENSOR_ID");
digitalWrite(PIN_AIR_INPUT, LOW); Set_New_ButtonMain_Label("Поиск датчика...");
log_debug("Вход воздуха деактивирован"); SX1278_SetMode(SX1278_MODE_RECEIVER);
current_action = ACTION_GET_SENSOR_ID; bool sensor_response = false;
break; uint32_t start_time = millis();
while ((millis() - start_time) < SENSOR_RESPONSE_TIMEOUT * 3) {
case ACTION_GET_SENSOR_ID: read_sx1278_data();
log_trace("Состояние: ACTION_GET_SENSOR_ID");
Set_New_ButtonMain_Label("Поиск датчика..."); if (sxResive_data.type == 0x41) {
SX1278_SetMode(SX1278_MODE_RECEIVER); set_testSensor_data();
bool sensor_response = false; snprintf(LabelText, sizeof(LabelText), "Датчик найден ID: %X", testSensor.id_sensor);
uint32_t start_time = millis(); Set_New_LableSensorPressure(LabelText);
while ((millis() - start_time) < SENSOR_RESPONSE_TIMEOUT * 3) { sensor_response = true;
read_sx1278_data(); break;
}
if (sxResive_data.type == 0x41) {
set_testSensor_data(); delay(10);
snprintf(LabelText, sizeof(LabelText), "Датчик найден ID: %X", testSensor.id_sensor); }
Set_New_LableSensorPressure(LabelText); if (!sensor_response) {
sensor_response = true; log_error("Не удалось получить ID датчика в течение таймаута");
break; current_action = ACTION_WAIT_SENSOR_RELEASE;
} Set_New_LableSensorPressure("Датчик не найден");
release_pressure();
delay(10); }
} else{
if (!sensor_response) { current_action = ACTION_CHECK_PRESSURE;
log_error("Не удалось получить ID датчика в течение таймаута"); log_debug("ID тестового датчика получен %X, переходим к ACTION_CHECK_PRESSURE", testSensor.id_sensor);
current_action = ACTION_WAIT_SENSOR_RELEASE; }
Set_New_LableSensorPressure("Датчик не найден"); break;
release_pressure();
} case ACTION_CHECK_PRESSURE: {
else{ log_trace("Состояние: ACTION_CHECK_PRESSURE");
current_action = ACTION_CHECK_PRESSURE; Set_New_ButtonMain_Label("Проверка давления...");
log_debug("ID тестового датчика получен %X, переходим к ACTION_CHECK_PRESSURE", testSensor.id_sensor); delay(2000);
} bool received_data = false;
break;
for (int i = 0; i < PRESSURE_NUMBER_OF_CHECKS; i++) {
case ACTION_CHECK_PRESSURE: { // Чтение данных из модуля
log_trace("Состояние: ACTION_CHECK_PRESSURE"); read_sx1278_data();
Set_New_ButtonMain_Label("Проверка давления...");
delay(2000); if (sxResive_data.type == 0x90) {
bool received_data = false; uint16_t pressure = etalonSensor.pressure;
pressure_data.sum_pressure += pressure;
for (int i = 0; i < PRESSURE_NUMBER_OF_CHECKS; i++) { pressure_data.counter_pressure++;
// Чтение данных из модуля
read_sx1278_data(); if (pressure < pressure_data.min_pressure)
pressure_data.min_pressure = pressure;
if (sxResive_data.type == 0x90) {
uint16_t pressure = etalonSensor.pressure; if (pressure > pressure_data.max_pressure)
pressure_data.sum_pressure += pressure; pressure_data.max_pressure = pressure;
pressure_data.counter_pressure++;
received_data = true;
if (pressure < pressure_data.min_pressure) log_trace("Данные давления собраны: %u", pressure);
pressure_data.min_pressure = pressure; }
if (pressure > pressure_data.max_pressure) delay(500);
pressure_data.max_pressure = pressure; }
received_data = true; current_action = ACTION_SEND_DATA;
log_trace("Данные давления собраны: %u", pressure); if (!received_data) {
} // Не получили данных от эталонного датчика
error_data.reference_sensor_error = 1; // Устанавливаем бит ошибки
delay(500); log_error("Нет данных от эталонного датчика");
} current_action = ACTION_RELEASE_PRESSURE;
break;
current_action = ACTION_SEND_DATA; }
if (!received_data) {
// Не получили данных от эталонного датчика // Расчет среднего значения давления
error_data.reference_sensor_error = 1; // Устанавливаем бит ошибки pressure_data.avg_pressure = pressure_data.sum_pressure / pressure_data.counter_pressure;
log_error("Нет данных от эталонного датчика");
current_action = ACTION_RELEASE_PRESSURE; // Проверка максимального давления
break; if (pressure_data.max_pressure < MAX_PRESSURE_THRESHOLD) {
} error_data.compressor_pressure_error = 1; // Устанавливаем бит ошибки
log_error("Недостаточное давление компрессора");
// Расчет среднего значения давления current_action = ACTION_RELEASE_PRESSURE;
pressure_data.avg_pressure = pressure_data.sum_pressure / pressure_data.counter_pressure; }
// Проверка максимального давления // Проверка падения давления
if (pressure_data.max_pressure < MAX_PRESSURE_THRESHOLD) { if ((pressure_data.max_pressure - pressure_data.min_pressure) > PRESSURE_DROP_TOLERANCE) {
error_data.compressor_pressure_error = 1; // Устанавливаем бит ошибки error_data.pressure_leak_error = 1; // Устанавливаем бит ошибки
log_error("Недостаточное давление компрессора"); log_error("Травит датчик");
current_action = ACTION_RELEASE_PRESSURE; current_action = ACTION_RELEASE_PRESSURE;
} }
// Проверка падения давления log_info("Данные давления рассчитаны: MIN = %u, MAX = %u, AVG = %u",
if ((pressure_data.max_pressure - pressure_data.min_pressure) > PRESSURE_DROP_TOLERANCE) { pressure_data.min_pressure,
error_data.pressure_leak_error = 1; // Устанавливаем бит ошибки pressure_data.max_pressure,
log_error("Травит датчик"); pressure_data.avg_pressure);
current_action = ACTION_RELEASE_PRESSURE;
} break;
}
log_info("Данные давления рассчитаны: MIN = %u, MAX = %u, AVG = %u",
pressure_data.min_pressure, case ACTION_SEND_DATA: {
pressure_data.max_pressure, log_trace("Состояние: ACTION_SEND_DATA");
pressure_data.avg_pressure); // Отправка кадра на датчик, несколько попыток
bool sensor_response = false;
break; for (int i = 0; i < SEND_FRAME_NUMBER_OF_ATTEMPTS; i++) {
} log_info("Попытка отправки данных №%d", i + 1);
snprintf(LabelText, sizeof(LabelText), "Отправка данных на датчик...%d/%d", i + 1, SEND_FRAME_NUMBER_OF_ATTEMPTS);
case ACTION_SEND_DATA: { Set_New_ButtonMain_Label(LabelText);
log_trace("Состояние: ACTION_SEND_DATA");
// Отправка кадра на датчик, несколько попыток // Формирование кадра для отправки
bool sensor_response = false; sxTransmit_data.payload = 0x16;
for (int i = 0; i < SEND_FRAME_NUMBER_OF_ATTEMPTS; i++) { sxTransmit_data.type = 0x91;
log_info("Попытка отправки данных №%d", i + 1); sxTransmit_data.id_sensor = testSensor.id_sensor;
snprintf(LabelText, sizeof(LabelText), "Отправка данных на датчик...%d/%d", i + 1, SEND_FRAME_NUMBER_OF_ATTEMPTS); sxTransmit_data.pressure = pressure_data.avg_pressure;
Set_New_ButtonMain_Label(LabelText); sxTransmit_data.temperature = 0x0000;
sxTransmit_data.timestamp = (int)time(NULL);
// Формирование кадра для отправки
sxTransmit_data.payload = 0x16; uint8_t array[9] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
sxTransmit_data.type = 0x91; memcpy(sxTransmit_data.otherData, array, sizeof(array));
sxTransmit_data.id_sensor = testSensor.id_sensor;
sxTransmit_data.pressure = pressure_data.avg_pressure; SX1278_SetMode(SX1278_MODE_TRANSMITTER);
sxTransmit_data.temperature = 0x0000; log_trace("SX1278 установлен в режим передачи");
sxTransmit_data.timestamp = (int)time(NULL); for (int j = 0; j < 2; j++) {
SX1278_FIFO_SendData(&sxTransmit_data);
uint8_t array[9] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}; log_debug("Калибровочный кадр отправлен (%d/2)", j + 1);
memcpy(sxTransmit_data.otherData, array, sizeof(array)); delay(100);
}
SX1278_SetMode(SX1278_MODE_TRANSMITTER); SX1278_SetMode(SX1278_MODE_RECEIVER);
log_trace("SX1278 установлен в режим передачи"); log_trace("SX1278 возвращён в режим приёма");
for (int j = 0; j < 2; j++) {
SX1278_FIFO_SendData(&sxTransmit_data); // Ожидание ответа
log_debug("Калибровочный кадр отправлен (%d/2)", j + 1); uint32_t start_time = millis();
delay(100); while ((millis() - start_time) < SENSOR_RESPONSE_TIMEOUT * 2) {
} read_sx1278_data();
SX1278_SetMode(SX1278_MODE_RECEIVER);
log_trace("SX1278 возвращён в режим приёма"); if (sxResive_data.type == 0x92) {
set_testSensor_data();
// Ожидание ответа snprintf(LabelText, sizeof(LabelText), "Давленние датчика: %d.%02d", testSensor.pressure / 100, testSensor.pressure % 100);
uint32_t start_time = millis(); Set_New_LableSensorPressure(LabelText);
while ((millis() - start_time) < SENSOR_RESPONSE_TIMEOUT * 2) { sensor_response = true;
read_sx1278_data(); log_info("Получен ответ от тестового датчика");
break;
if (sxResive_data.type == 0x92) { }
set_testSensor_data();
snprintf(LabelText, sizeof(LabelText), "Давленние датчика: %d.%02d", testSensor.pressure / 100, testSensor.pressure % 100); delay(100);
Set_New_LableSensorPressure(LabelText); }
sensor_response = true;
log_info("Получен ответ от тестового датчика"); if (sensor_response) {
break; break;
} } else {
log_warn("Нет ответа от тестового датчика на попытке %d", i + 1);
delay(100); }
} }
if (sensor_response) { if (!sensor_response) {
break; error_data.sensor_response_error = 1; // Устанавливаем бит ошибки
} else { log_error("Нет ответа от испытуемого датчика");
log_warn("Нет ответа от тестового датчика на попытке %d", i + 1); }
}
} current_action = ACTION_RELEASE_PRESSURE;
break;
if (!sensor_response) { }
error_data.sensor_response_error = 1; // Устанавливаем бит ошибки
log_error("Нет ответа от испытуемого датчика"); case ACTION_RELEASE_PRESSURE:
} log_trace("Состояние: ACTION_RELEASE_PRESSURE");
Set_New_ButtonMain_Label("Спуск давления...");
current_action = ACTION_RELEASE_PRESSURE; release_pressure();
break; current_action = ACTION_PRINT_RESULTS;
} break;
case ACTION_RELEASE_PRESSURE: case ACTION_PRINT_RESULTS:
log_trace("Состояние: ACTION_RELEASE_PRESSURE"); log_trace("Состояние: ACTION_PRINT_RESULTS");
Set_New_ButtonMain_Label("Спуск давления..."); static uint8_t* id_sensor_str;
release_pressure(); uint8_t error_code = *(uint8_t*)&error_data;
current_action = ACTION_PRINT_RESULTS;
break; memset(&jsonDataBuffer, 0, sizeof(jsonDataBuffer));
CURL_GET_Request(concat_strings(API_URL, concat_strings("get-serial-data/", NumToHexString(testSensor.id_sensor))), &jsonDataBuffer);
case ACTION_PRINT_RESULTS: cJSON *json = cJSON_Parse(jsonDataBuffer);
log_trace("Состояние: ACTION_PRINT_RESULTS"); log_debug("result: %s", jsonDataBuffer);
cJSON *json; cJSON *dataJSON = cJSON_GetObject(json, "data");
static char* id_sensor_str; log_debug("Model id: %s\n", cJSON_GetObject(dataJSON, "model_id")->valuestring);
id_sensor_str = NumToHexString(testSensor.id_sensor);
log_info("%s", id_sensor_str); id_sensor_str = cJSON_GetObject(dataJSON, "serial_num")->valuestring;
log_info("%s", id_sensor_str);
uint8_t error_code = *(uint8_t*)&error_data; log_info("Код ошибки: %u", error_code);
log_info("Код ошибки: %u", error_code); if (error_code == 0) {
uint32_t device_id; log_info("Тест пройден, датчик соответствует спецификациям");
if (error_code == 0) { memset(&jsonDataBuffer, 0, sizeof(jsonDataBuffer));
log_info("Тест пройден, датчик соответствует спецификациям"); CURL_GET_Request(concat_strings(API_URL, concat_strings("get-data/device_model/", cJSON_GetObject(dataJSON, "model_id")->valuestring)), &jsonDataBuffer);
char url[256]; json = cJSON_Parse(jsonDataBuffer);
snprintf(url, sizeof(url), "%sdevice_model/%d/device_serial_number/", API_URL, testSensor.id_sensor); dataJSON = cJSON_GetObject(json, "data");
memset(&jsonDataBuffer, 0, sizeof(jsonDataBuffer)); log_debug("Model name: %s\n", cJSON_GetObject(dataJSON, "name")->valuestring);
CURL_GET_Request((uint8_t *)url, &jsonDataBuffer);
json = cJSON_Parse(jsonDataBuffer); GODEX500_print_label(serial_port, NumToHexString(testSensor.id_sensor), cJSON_GetObject(dataJSON, "name")->valuestring);
log_debug("Model name: %s\n", cJSON_GetObject(json, "name")->valuestring); Set_Color_ButtonMain_green();
lastModelName = cJSON_GetObject(json, "name")->valuestring; } else {
GODEX500_print_label(serial_port, NumToHexString(testSensor.id_sensor), lastModelName); log_error("Тест не пройден, датчик не прошёл все проверки");
Set_Color_ButtonMain_red();
snprintf(url, sizeof(url), "%sdevice/%d/serial_number/", API_URL, testSensor.id_sensor); snprintf(LabelText, sizeof(LabelText), "Ошибка тестирования. Код: %u", error_code);
memset(&jsonDataBuffer, 0, sizeof(jsonDataBuffer)); Set_New_LableSensorPressure(LabelText);
CURL_GET_Request((uint8_t *)url, &jsonDataBuffer); Update_Error_Table(error_code);
json = cJSON_Parse(jsonDataBuffer); }
get_current_time(datetime);
device_id = cJSON_GetObject(json, "id")->valueint; snprintf(post_data, sizeof(post_data),
"{\"device_serial_num\": \"%s\", \"type\": \"calibrate\", \"date\": \"%s\", \"json_data\": {\"code\": %d}}", id_sensor_str, datetime, error_code);
CURL_POST_Request(concat_strings(API_URL, "insert-data/log"), (uint8_t *)post_data);
Set_Color_ButtonMain_green(); current_action = ACTION_WAIT_SENSOR_RELEASE;
} else { break;
log_error("Тест не пройден, датчик не прошёл все проверки");
Set_Color_ButtonMain_red(); case ACTION_WAIT_SENSOR_RELEASE:
snprintf(LabelText, sizeof(LabelText), "Ошибка тестирования. Код: %u", error_code); log_trace("Состояние: ACTION_WAIT_SENSOR_RELEASE");
Set_New_LableSensorPressure(LabelText); Set_New_ButtonMain_Label("Ожидание снятия датчика...");
Update_Error_Table(error_code); // Здесь можно добавить логику ожидания снятия датчика
} break;
get_current_time(datetime);
char url[256]; default:
snprintf(url, sizeof(url), "%sinsert-log/", API_URL); log_warn("Обнаружено неизвестное состояние, возвращаемся к ACTION_WAIT_SENSOR");
snprintf(post_data, sizeof(post_data), current_action = ACTION_WAIT_SENSOR;
"{\"device_id\": \"%d\", \"type\": \"calibrate\", \"date\": \"%s\", \"data\": {\"code\": %d}}", device_id, datetime, error_code); break;
CURL_POST_Request(url, (uint8_t *)post_data); }
current_action = ACTION_WAIT_SENSOR_RELEASE;
break; delay(30); // Задержка между циклами
}
case ACTION_WAIT_SENSOR_RELEASE:
log_trace("Состояние: ACTION_WAIT_SENSOR_RELEASE"); return NULL;
Set_New_ButtonMain_Label("Ожидание снятия датчика..."); }
// Здесь можно добавить логику ожидания снятия датчика
break;
default:
log_warn("Обнаружено неизвестное состояние, возвращаемся к ACTION_WAIT_SENSOR");
current_action = ACTION_WAIT_SENSOR;
break;
}
delay(30); // Задержка между циклами
}
return NULL;
}

View File

@ -34,7 +34,7 @@ uint8_t InitializationProject(uint8_t* api_url, uint8_t pin_nss, uint8_t pin_rst
Set_New_ButtonMain_Label("Initialization..."); Set_New_ButtonMain_Label("Initialization...");
int connection_init = CURL_Check_connection(api_url); int connection_init = CURL_Check_connection(api_url);
if(connection_init != 0){ if(connection_init < 0){
log_error("Conncection ERROR"); log_error("Conncection ERROR");
return 1; return 1;
} }

View File

@ -1,3 +1,2 @@
void _ResetPressure(); void _ResetPressure();
void _CloseSerial(); void _CloseSerial();
void _ReprintSticker();

View File

@ -7,7 +7,4 @@ void _ResetPressure(){
void _CloseSerial(){ void _CloseSerial(){
close_Serial(); close_Serial();
} }
void _ReprintSticker(){
reprintSticker();
}

View File

@ -1,6 +1,6 @@
#include <pthread.h> #include <pthread.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "../Inc/ui.h" #include "../Inc/ui.h"
#include "../Inc/button_handlers.h" #include "../Inc/button_handlers.h"
#include "../../controllers/Inc/stend_controller.h" #include "../../controllers/Inc/stend_controller.h"
#include "widgets.h" #include "widgets.h"

View File

@ -1,11 +1,11 @@
#ifndef BUTTON_HANDLERS_H #ifndef BUTTON_HANDLERS_H
#define BUTTON_HANDLERS_H #define BUTTON_HANDLERS_H
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "button_styles.h" #include "button_styles.h"
// Декларация функции для отключения кнопки // Декларация функции для отключения кнопки
void ButtonMain_Handler(GtkButton *button); void ButtonMain_Handler(GtkButton *button);
void ButtonReprint_Handler(GtkButton *button); void ButtonReprint_Handler(GtkButton *button);
#endif // BUTTON_HANDLERS_H #endif // BUTTON_HANDLERS_H

View File

@ -1,17 +1,17 @@
#ifndef UI_H #ifndef UI_H
#define UI_H #define UI_H
#include "../Inc/button_handlers.h" #include "../Inc/button_handlers.h"
#include "widgets.h" #include "widgets.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
gboolean update_ButtonMain_label(gpointer data); gboolean update_ButtonMain_label(gpointer data);
gboolean update_LableCurrentPressure(gpointer data); gboolean update_LableCurrentPressure(gpointer data);
gboolean update_LableSensorPressure(gpointer data); gboolean update_LableSensorPressure(gpointer data);
gboolean set_Color_ButtonMain_red(gpointer data); gboolean set_Color_ButtonMain_red(gpointer data);
gboolean set_Color_ButtonMain_green(gpointer data); gboolean set_Color_ButtonMain_green(gpointer data);
gboolean set_Color_ButtonMain_white(gpointer data); gboolean set_Color_ButtonMain_white(gpointer data);
gboolean update_Error_Table(gpointer data); gboolean update_Error_Table(gpointer data);
#endif // UI_H #endif // UI_H

View File

@ -1,27 +1,27 @@
#ifndef WIDGETS_H #ifndef WIDGETS_H
#define WIDGETS_H #define WIDGETS_H
#include <gtk/gtk.h> #include <gtk/gtk.h>
// Структура widgets должна быть объявлена глобально или передаваться между функциями // Структура widgets должна быть объявлена глобально или передаваться между функциями
typedef struct { typedef struct {
GtkWidget *GridBox; GtkWidget *GridBox;
GtkWidget *LabelCurrentPressure; GtkWidget *LabelCurrentPressure;
GtkWidget *LabelSensorPressure; GtkWidget *LabelSensorPressure;
GtkWidget *LabelRequiredPressure; GtkWidget *LabelRequiredPressure;
GtkWidget *ButtonMain; GtkWidget *ButtonMain;
GtkWidget *ButtonReprint; GtkWidget *ButtonReprint;
GtkWidget *ErrorTreeView; // Представление таблицы ошибок GtkWidget *ErrorTreeView; // Представление таблицы ошибок
GtkListStore *ErrorListStore; // Модель данных для таблицы ошибок GtkListStore *ErrorListStore; // Модель данных для таблицы ошибок
uint8_t gpio_triggered; uint8_t gpio_triggered;
} Widgets; } Widgets;
typedef struct { typedef struct {
GtkWidget *button; GtkWidget *button;
const char *label_text; const char *label_text;
} ButtonUpdateData; } ButtonUpdateData;
extern Widgets widgets; extern Widgets widgets;
#endif // WIDGETS_H #endif // WIDGETS_H

View File

@ -1,58 +1,58 @@
#include "../Inc/MainForm.h" #include "../Inc/MainForm.h"
#include <stdint.h> #include <stdint.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "../Inc/error.h" #include "../Inc/error.h"
void close_main_window(void){ void close_main_window(void){
_ResetPressure(); _ResetPressure();
_CloseSerial(); _CloseSerial();
gtk_main_quit(); gtk_main_quit();
} }
GtkWidget* create_main_window() { GtkWidget* create_main_window() {
GtkWidget *window; GtkWidget *window;
widgets.gpio_triggered = 0; widgets.gpio_triggered = 0;
widgets.ErrorTreeView = NULL; widgets.ErrorTreeView = NULL;
widgets.ErrorListStore = NULL; widgets.ErrorListStore = NULL;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL); window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Стенд проверки датчиков"); gtk_window_set_title(GTK_WINDOW(window), "Стенд проверки датчиков");
gtk_container_set_border_width(GTK_CONTAINER(window), 50); gtk_container_set_border_width(GTK_CONTAINER(window), 50);
gtk_window_set_default_size(GTK_WINDOW(window), 600, 400); gtk_window_set_default_size(GTK_WINDOW(window), 600, 400);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(close_main_window), NULL); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(close_main_window), NULL);
widgets.GridBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); widgets.GridBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add(GTK_CONTAINER(window), widgets.GridBox); gtk_container_add(GTK_CONTAINER(window), widgets.GridBox);
GtkWidget *label_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); GtkWidget *label_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_box_pack_start(GTK_BOX(widgets.GridBox), label_box, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(widgets.GridBox), label_box, FALSE, FALSE, 0);
widgets.LabelCurrentPressure = gtk_label_new("Текущее давление: 0.0"); widgets.LabelCurrentPressure = gtk_label_new("Текущее давление: 0.0");
gtk_box_pack_start(GTK_BOX(label_box), widgets.LabelCurrentPressure, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(label_box), widgets.LabelCurrentPressure, FALSE, FALSE, 0);
gtk_widget_set_valign(widgets.LabelCurrentPressure, GTK_ALIGN_START); gtk_widget_set_valign(widgets.LabelCurrentPressure, GTK_ALIGN_START);
widgets.LabelSensorPressure = gtk_label_new("Датчик не найден"); widgets.LabelSensorPressure = gtk_label_new("Датчик не найден");
gtk_box_pack_start(GTK_BOX(label_box), widgets.LabelSensorPressure, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(label_box), widgets.LabelSensorPressure, FALSE, FALSE, 0);
gtk_widget_set_valign(widgets.LabelSensorPressure, GTK_ALIGN_START); gtk_widget_set_valign(widgets.LabelSensorPressure, GTK_ALIGN_START);
// widgets.LabelRequiredPressure = gtk_label_new("Необходимое давление: 6.4"); // widgets.LabelRequiredPressure = gtk_label_new("Необходимое давление: 6.4");
// gtk_box_pack_start(GTK_BOX(label_box), widgets.LabelRequiredPressure, FALSE, FALSE, 0); // gtk_box_pack_start(GTK_BOX(label_box), widgets.LabelRequiredPressure, FALSE, FALSE, 0);
// gtk_widget_set_valign(widgets.LabelRequiredPressure, GTK_ALIGN_START); // gtk_widget_set_valign(widgets.LabelRequiredPressure, GTK_ALIGN_START);
widgets.ButtonMain = gtk_button_new_with_label("Начать работу"); widgets.ButtonMain = gtk_button_new_with_label("Начать работу");
gtk_box_pack_start(GTK_BOX(widgets.GridBox), widgets.ButtonMain, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(widgets.GridBox), widgets.ButtonMain, FALSE, FALSE, 0);
g_signal_connect(GTK_BUTTON(widgets.ButtonMain), "clicked", G_CALLBACK(ButtonMain_Handler), NULL); g_signal_connect(GTK_BUTTON(widgets.ButtonMain), "clicked", G_CALLBACK(ButtonMain_Handler), NULL);
widgets.ButtonReprint = gtk_button_new_with_label("Повторная печать"); widgets.ButtonReprint = gtk_button_new_with_label("Повторная печать");
gtk_box_pack_start(GTK_BOX(widgets.GridBox), widgets.ButtonReprint, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(widgets.GridBox), widgets.ButtonReprint, FALSE, FALSE, 0);
g_signal_connect(GTK_BUTTON(widgets.ButtonReprint), "clicked", G_CALLBACK(ButtonReprint_Handler), NULL); g_signal_connect(GTK_BUTTON(widgets.ButtonReprint), "clicked", G_CALLBACK(ButtonReprint_Handler), NULL);
// Создаем таблицу ошибок // Создаем таблицу ошибок
initialize_error_table(); initialize_error_table();
update_error_table(0); update_error_table(0);
set_button_color_white(widgets.ButtonMain); set_button_color_white(widgets.ButtonMain);
gtk_widget_show_all(window); gtk_widget_show_all(window);
return window; return window;
} }

View File

@ -1,11 +1,11 @@
#include "../Inc/button_handlers.h" #include "../Inc/button_handlers.h"
#include "../../controllers/Inc/stend_controller.h"
// Функция для изменения цвета кнопки и отключения её // Функция для изменения цвета кнопки и отключения её
void ButtonMain_Handler(GtkButton *button) { void ButtonMain_Handler(GtkButton *button) {
set_button_color_white(button); set_button_color_white(button);
} }
void ButtonReprint_Handler(GtkButton *button){ void ButtonReprint_Handler(GtkButton *button){
_ReprintSticker(); g_print("Button Reprint Pressed\n");
} }

View File

@ -1,42 +1,42 @@
#include "../Inc/ui.h" #include "../Inc/ui.h"
#include "../Inc/error.h" #include "../Inc/error.h"
gboolean update_ButtonMain_label(gpointer data) { gboolean update_ButtonMain_label(gpointer data) {
const char* new_label_text = (const char*)data; const char* new_label_text = (const char*)data;
gtk_button_set_label(GTK_BUTTON(widgets.ButtonMain), new_label_text); gtk_button_set_label(GTK_BUTTON(widgets.ButtonMain), new_label_text);
return FALSE; return FALSE;
} }
gboolean update_LableCurrentPressure(gpointer data){ gboolean update_LableCurrentPressure(gpointer data){
const char* new_label_text = (const char*)data; const char* new_label_text = (const char*)data;
gtk_label_set_text(GTK_LABEL(widgets.LabelCurrentPressure), new_label_text); gtk_label_set_text(GTK_LABEL(widgets.LabelCurrentPressure), new_label_text);
return FALSE; return FALSE;
} }
gboolean update_LableSensorPressure(gpointer data){ gboolean update_LableSensorPressure(gpointer data){
const char* new_label_text = (const char*)data; const char* new_label_text = (const char*)data;
gtk_label_set_text(GTK_LABEL(widgets.LabelSensorPressure), new_label_text); gtk_label_set_text(GTK_LABEL(widgets.LabelSensorPressure), new_label_text);
return FALSE; return FALSE;
} }
gboolean set_Color_ButtonMain_red(gpointer data){ gboolean set_Color_ButtonMain_red(gpointer data){
set_button_color_red(widgets.ButtonMain); set_button_color_red(widgets.ButtonMain);
return FALSE; return FALSE;
} }
gboolean set_Color_ButtonMain_green(gpointer data){ gboolean set_Color_ButtonMain_green(gpointer data){
set_button_color_green(widgets.ButtonMain); set_button_color_green(widgets.ButtonMain);
return FALSE; return FALSE;
} }
gboolean set_Color_ButtonMain_white(gpointer data){ gboolean set_Color_ButtonMain_white(gpointer data){
set_button_color_white(widgets.ButtonMain); set_button_color_white(widgets.ButtonMain);
return FALSE; return FALSE;
} }
gboolean update_Error_Table(gpointer data){ gboolean update_Error_Table(gpointer data){
uint8_t error_code = GPOINTER_TO_UINT(data); uint8_t error_code = GPOINTER_TO_UINT(data);
update_error_table(error_code); update_error_table(error_code);
// create_error_code_table(error_code); // create_error_code_table(error_code);
return FALSE; return FALSE;
} }