main
rane 2025-04-14 17:36:33 +07:00
parent e171dcc37a
commit 1ee9c67179
12 changed files with 198 additions and 147 deletions

114
README.md
View File

@ -1,115 +1 @@
# Eva-Pro_Test-stend
Стенд для проверки и колибровки датчиков.
# Подготовка
## Настройка raspi-config
1. Открыть настройки
```
sudo raspi-config
```
2. Меню Interface Options
3. Выбрать пункт SPI
4. Yes/Да
## Включить IPv4
Изначально советую включить IPv4 Инструкция:
Создать файл:
```
sudo nano /etc/apt/apt.conf.d/99force-ipv4
```
Вставить в него
```
Acquire::ForceIPv4 "true";
```
Либо при установки пакетов установить флаг `-o Acquire::ForceIPv4=true`
Пример:
```
sudo apt update -o Acquire::ForceIPv4=true
```
Без этого пакеты будут пытаться скачиваться через IPv6, поэтому ни один пакет не будет установлен.
## Установка VS Code
```
sudo apt update
sudo apt upgrade
sudo apt install -y wget gpg
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo install -o root -g root -m 644 microsoft.gpg /usr/share/keyrings/
sudo sh -c 'echo "deb [arch=armhf signed-by=/usr/share/keyrings/microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list'
rm -f microsoft.gpg
sudo apt update
sudo apt install code
```
## Установка cURL
```
sudo apt update
sudo apt install -y libcurl4-openssl-dev
```
## Установка GTK
### Установка библиотеки
```
sudo apt install -y libcairo2-dev libpango1.0-dev libatk1.0-dev libgdk-pixbuf2.0-dev
sudo apt install -y libgtk-3-dev
```
### Использование для vscode
Будет работать и без этого, но VS code будет выводить ошибку что не может найти файл в библиотеки.
В папке `.vscode\` в файле `c_cpp_properties.json` указать пути до gtk пример.
```json
{
    "configurations": [
      {
        "name": "Linux",
        "includePath": [
          "${workspaceFolder}/**",
          "/usr/include/gtk-3.0",
          "/usr/include/glib-2.0",
          "/usr/lib/arm-linux-gnueabihf/glib-2.0/include",
          "/usr/include/cairo",
          "/usr/include/pango-1.0",
          "/usr/include/gdk-pixbuf-2.0",
          "/usr/include/atk-1.0",
          "/usr/include/harfbuzz/"
        ],
        "defines": [],
        "compilerPath": "/usr/bin/gcc",
        "cStandard": "c11",
        "cppStandard": "c++17",
        "intelliSenseMode": "linux-gcc-x64"
      }
    ],
    "version": 4
}
```
Если путь подчёркивается (не существует). После поиска заменить путь на существующий.
```
find /usr -name <Имя файла который нужно найти>.h
```
## Установка WiringPi
```
sudo apt install git
git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
./build
cd ..
```
### Проверка
```
gpio readall
```
# Usage
Для компиляции и запуска программы
```
make
```

View File

@ -12,5 +12,7 @@
char* concat_strings(const char *str1, const char *str2);
cJSON *cJSON_GetObject(cJSON *object, uint8_t *key);
uint8_t InitializationProject(uint8_t* api_url, uint8_t pin_nss, uint8_t pin_rst, uint8_t pin_dio0, uint8_t pin_koncevik, uint8_t pin_air_input, uint8_t pin_air_output, int8_t* serial_port, uint8_t* serial_device);
const char* NumToHexString(uint32_t Num);
void print_bytes(SxResive* ptr, size_t size);
void packSxTransmit(SxTransmit* data, uint8_t* buffer);
void packSxTransmit(SxTransmit* data, uint8_t* buffer);
void get_current_time(char *datetime);

View File

@ -1,4 +1,5 @@
#include "../Inc/curl2.h"
#include "../../Logger/Inc/logger.h"
size_t write_callback_size(void *ptr, size_t size, size_t nmemb, char *data) {
return size * nmemb;
}
@ -35,12 +36,24 @@ void CURL_POST_Request(uint8_t *URL, uint8_t *post_data){
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, URL);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// curl_easy_setopt(curl, CURLOPT_POST, 1L);
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
// curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
// char response[4096] = {0};
// curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
// printf("%s\n", response);
printf("%s\n", post_data);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {

View File

@ -0,0 +1,24 @@
CC = gcc
CFLAGS = -Wall -g
LDFLAGS = -lusb-1.0
TARGET = print_label
SRCS = stend_logic.c
OBJS = $(SRCS:.c=.o)
# Цель по умолчанию
all: $(TARGET) clean launch
# Правило для создания исполняемого файла
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS)
# Правило для компиляции .c файлов в .o файлы
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# Чистка проекта от скомпилированных файлов
clean:
rm -f $(OBJS)
launch:
./$(TARGET)

View File

@ -1,5 +1,5 @@
#include "../Inc/Godex500.h"
const int OFFSET = 131;
int GODEX500_setup_serial(const char* device) {
int serial_port = open(device, O_RDWR);
if (serial_port < 0) {
@ -58,12 +58,14 @@ void GODEX500_print_label(int serial_port, const char* id, const char* model) {
"^O0\n^D0\n^E30\n~R255\n"
"^L\n"
"Dy2-me-dd\nTh:m:s\n"
"AB,5,10,1,1,0,0E,%s\n"
"AB,40,45,1,1,0,0E,%s\n"
"XRB130,14,4,0,%d\n"
"AB,%d,10,1,1,0,0E,%s\n"
"AB,%d,45,1,1,0,0E,%s\n"
"XRB%d,14,4,0,%d\n"
"%s\n"
"E\n",
id, model, datamatrix_length, datamatrix_data);
5 + OFFSET, id,
40 + OFFSET, model,
130 + OFFSET, datamatrix_length, datamatrix_data);
GODEX500_send_to_printer(serial_port, buffer);
}

View File

@ -0,0 +1,25 @@
# Переменные
CC = gcc
CFLAGS = -Wall -g
LDFLAGS = -lwiringPi # Добавляем линковку с wiringPi
TARGET = program
SRCS = stend_logic.c sx1278.c
OBJS = $(SRCS:.c=.o)
# Цель по умолчанию
all: $(TARGET) clean launch
# Правило для создания исполняемого файла
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS)
# Правило для компиляции .c файлов в .o файлы
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# Чистка проекта от скомпилированных файлов
clean:
rm -f $(OBJS)
launch:
./$(TARGET)

View File

@ -0,0 +1,51 @@
#include "sx1278.h"
#define PinNSS 8
#define PinRST 22
#define PinDIO0 4
int main(void) {
SX1278_Init(PinNSS, PinRST, PinDIO0);
SX1278_load();
uint8_t verstion = SX1278_ReadRegister(REG_VERSION);
printf("Версия модуля: 0x%X\n", verstion);
// // Пример отправки данных
uint8_t txBuffer[SX1278_PAYLOAD] = {0x16, 0xF0, 0xDD, 0xD0, 0xD0, 0x0, 0xF1, 0x1D, 0x36, 0x6, 0x80, 0xC4, 0xBC, 0xF, 0x1E, 0xFF, 0xFF, 0x3, 0x3, 0x1, 0x0, 0x0, 0xA1};
SX1278_SetMode(SX1278_MODE_TRANSMITTER);
while (1)
{
SX1278_FIFO_SendData(&txBuffer);
delay(100);
}
// Пример приема данных
uint8_t rxBuffer[SX1278_PAYLOAD];
SX1278_SetMode(SX1278_MODE_RECEIVER);
while (1)
{
if(digitalRead(PinDIO0) == 1)
{
SX1278_FIFO_ReadData(&rxBuffer);
for(int i = 0; i < SX1278_PAYLOAD; i++)
{
printf("0x%X, ", rxBuffer[i]);
}
printf("\n");
}
delay(100);
}
return 0;
}

View File

@ -7,7 +7,7 @@
#define PRESSURE_MEASUREMENTS_DURATION 3000 // Время для измерений давления (в миллисекундах)
#define PRESSURE_NUMBER_OF_CHECKS 10 // Количество проверок давления
#define SEND_FRAME_NUMBER_OF_ATTEMPTS 3 // Количество попыток для отправки кадра калибровки
#define MAX_PRESSURE_THRESHOLD 700 // Максимальное давление в контуре для проверки (7.00 бар)
#define MAX_PRESSURE_THRESHOLD 500 // Максимальное давление в контуре для проверки (5.00 бар)
#define PRESSURE_DROP_TOLERANCE 5 // Допустимое падение давления (0.05 бар)
#define SENSOR_RESPONSE_TIMEOUT 5000 // Таймаут ожидания ответа от датчика (в миллисекундах)
@ -23,7 +23,10 @@ static SxResive sxResive_data;
static uint8_t rxBuffer[SX1278_PAYLOAD];
static uint8_t txBuffer[SX1278_PAYLOAD];
static char LabelText[100];
static char datetime[64];
static char post_data[512];
static char jsonDataBuffer[1024*50];
static int8_t serial_port;
void reset_pressure_data() {
pressure_data.min_pressure = UINT16_MAX; // Устанавливаем максимальное значение
pressure_data.max_pressure = 0;
@ -86,6 +89,10 @@ void release_pressure() {
delay(1000); // Подождать 1 секунду
digitalWrite(PIN_AIR_OUTPUT, LOW);
}
void close_Serial(){
close(serial_port);
log_info("Порт закрыт");
}
void read_sx1278_data() {
if (digitalRead(PIN_DIO0) == HIGH) {
@ -112,7 +119,7 @@ void set_etalonSensor_data(){
}
void* stend_logic() {
int8_t serial_port;
log_set_level(LOG_DEBUG);
// Инициализация проекта
uint8_t init = InitializationProject(API_URL, PIN_NSS, PIN_RST, PIN_DIO0, PIN_KONCEVIK,
@ -181,27 +188,31 @@ void* stend_logic() {
log_trace("Состояние: ACTION_GET_SENSOR_ID");
Set_New_ButtonMain_Label("Поиск датчика...");
SX1278_SetMode(SX1278_MODE_RECEIVER);
bool sensor_response = false;
uint32_t start_time = millis();
while ((millis() - start_time) < SENSOR_RESPONSE_TIMEOUT * 2) {
while ((millis() - start_time) < SENSOR_RESPONSE_TIMEOUT * 3) {
read_sx1278_data();
if (sxResive_data.type == 0x41) {
set_testSensor_data();
current_action = ACTION_CHECK_PRESSURE;
snprintf(LabelText, sizeof(LabelText), "Датчик найден ID: %X", testSensor.id_sensor);
Set_New_LableSensorPressure(LabelText);
log_debug("ID тестового датчика получен %X, переходим к ACTION_CHECK_PRESSURE", testSensor.id_sensor);
sensor_response = true;
break;
}
delay(100);
delay(10);
}
if (current_action != ACTION_CHECK_PRESSURE) {
if (!sensor_response) {
log_error("Не удалось получить ID датчика в течение таймаута");
current_action = ACTION_WAIT_SENSOR_RELEASE;
Set_New_LableSensorPressure("Датчик не найден");
release_pressure();
}
else{
current_action = ACTION_CHECK_PRESSURE;
log_debug("ID тестового датчика получен %X, переходим к ACTION_CHECK_PRESSURE", testSensor.id_sensor);
}
break;
case ACTION_CHECK_PRESSURE: {
@ -248,6 +259,7 @@ void* stend_logic() {
if (pressure_data.max_pressure < MAX_PRESSURE_THRESHOLD) {
error_data.compressor_pressure_error = 1; // Устанавливаем бит ошибки
log_error("Недостаточное давление компрессора");
current_action = ACTION_RELEASE_PRESSURE;
}
// Проверка падения давления
@ -297,7 +309,7 @@ void* stend_logic() {
// Ожидание ответа
uint32_t start_time = millis();
while ((millis() - start_time) < SENSOR_RESPONSE_TIMEOUT) {
while ((millis() - start_time) < SENSOR_RESPONSE_TIMEOUT * 2) {
read_sx1278_data();
if (sxResive_data.type == 0x92) {
@ -337,13 +349,28 @@ void* stend_logic() {
case ACTION_PRINT_RESULTS:
log_trace("Состояние: ACTION_PRINT_RESULTS");
// Обработка результатов и вывод информации
// Здесь можно добавить функции для печати наклеек и записи в БД
static uint8_t* id_sensor_str;
uint8_t error_code = *(uint8_t*)&error_data;
memset(&jsonDataBuffer, 0, sizeof(jsonDataBuffer));
CURL_GET_Request(concat_strings(API_URL, concat_strings("get-serial-data/", NumToHexString(testSensor.id_sensor))), &jsonDataBuffer);
cJSON *json = cJSON_Parse(jsonDataBuffer);
log_debug("result: %s", jsonDataBuffer);
cJSON *dataJSON = cJSON_GetObject(json, "data");
log_debug("Model id: %s\n", cJSON_GetObject(dataJSON, "model_id")->valuestring);
id_sensor_str = cJSON_GetObject(dataJSON, "serial_num")->valuestring;
log_info("%s", id_sensor_str);
log_info("Код ошибки: %u", error_code);
if (error_code == 0) {
log_info("Тест пройден, датчик соответствует спецификациям");
memset(&jsonDataBuffer, 0, sizeof(jsonDataBuffer));
CURL_GET_Request(concat_strings(API_URL, concat_strings("get-data/device_model/", cJSON_GetObject(dataJSON, "model_id")->valuestring)), &jsonDataBuffer);
json = cJSON_Parse(jsonDataBuffer);
dataJSON = cJSON_GetObject(json, "data");
log_debug("Model name: %s\n", cJSON_GetObject(dataJSON, "name")->valuestring);
GODEX500_print_label(serial_port, NumToHexString(testSensor.id_sensor), cJSON_GetObject(dataJSON, "name")->valuestring);
Set_Color_ButtonMain_green();
} else {
log_error("Тест не пройден, датчик не прошёл все проверки");
@ -352,6 +379,10 @@ void* stend_logic() {
Set_New_LableSensorPressure(LabelText);
Update_Error_Table(error_code);
}
get_current_time(datetime);
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);
current_action = ACTION_WAIT_SENSOR_RELEASE;
break;

View File

@ -1,6 +1,5 @@
#include "../Inc/utils.h"
char* concat_strings(const char *str1, const char *str2) {
size_t len = strlen(str1) + strlen(str2) + 1;
char *result = (char*) malloc(len);
@ -14,6 +13,13 @@ char* concat_strings(const char *str1, const char *str2) {
return result;
}
void get_current_time(char *datetime){
time_t t = time(NULL);
struct tm tm = *localtime(&t);
log_debug("sn");
sprintf(datetime, "%d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
}
cJSON *cJSON_GetObject(cJSON *object, uint8_t *key){
cJSON *objectJSON = cJSON_GetObjectItemCaseSensitive(object, key);
if (objectJSON == NULL) {
@ -27,11 +33,11 @@ uint8_t InitializationProject(uint8_t* api_url, uint8_t pin_nss, uint8_t pin_rst
log_info("Initialization...");
Set_New_ButtonMain_Label("Initialization...");
// int connection_init = CURL_Check_connection(api_url);
// if(connection_init < 0){
// log_error("Conncection ERROR");
// return 1;
// }
int connection_init = CURL_Check_connection(api_url);
if(connection_init < 0){
log_error("Conncection ERROR");
return 1;
}
log_info("SX1278Init...");
Set_New_ButtonMain_Label("SX1278Init...");
int sx_init = SX1278_Init(pin_nss, pin_rst, pin_dio0);
@ -45,18 +51,24 @@ uint8_t InitializationProject(uint8_t* api_url, uint8_t pin_nss, uint8_t pin_rst
log_info("SX1278_load...");
Set_New_ButtonMain_Label("SX1278_load...");
SX1278_load();
// delay(500);
// *serial_port = GODEX500_setup_serial(&serial_device);
// if (*serial_port < 0) {
// log_error("GODEX500 Initialization ERROR");
// return 1;
// }
*serial_port = GODEX500_setup_serial(serial_device);
if (*serial_port < 0) {
log_error("GODEX500 Initialization ERROR");
return 1;
}
log_info("Initialization completed!");
Set_New_ButtonMain_Label("Initialization completed!");
return 0;
}
const char* NumToHexString(uint32_t Num){
static char HexString[9];
sprintf(HexString, "%08X", Num);
return HexString;
}
void print_bytes(SxResive* ptr, size_t size){
uint8_t* byte_ptr = (uint8_t*)ptr;
for(size_t i = 0; i < size; i++){

View File

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

View File

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

View File

@ -6,6 +6,7 @@
void close_main_window(void){
_ResetPressure();
_CloseSerial();
gtk_main_quit();
}