Virtual Comport reading
Posted: Sat Feb 24, 2024 2:51 pm
I'm attempting to display a weight measurement on the KMotionCNC UI screen using a scale connected to the PC, which also connects to my Kogna board.Due to encoding issues, the scale cannot be directly programmed by KMotion so I've managed to read the scale's output to a specific COM port using C++ code. I believe one way to display a specific value on the KMotionCNC screen is by saving the variable in KMotion and assigning it to a DRO button. Consequently, I'm trying to have the board read this value via the virtual COM port. The C++ code writes the read data to a specific file, and then the KMotion code opens that file to save the data to a variable. The challenge arises because the file cannot be opened by both programs simultaneously. To address this, I'm considering implementing a lock mechanism to lock the file while data is being written to it. The writing process will pause for a moment, during which the file will be unlocked, allowing the board to access and record the data.
The C++ code functions perfectly, handling file writing, printing, and pausing at the set moments. However, the KMotion code only reads the correct data once before causing the C++ code to crash, as if it can no longer access the file.
These are the code I am currently using :
*C++:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define INTERVAL 5000 // Interval in milliseconds for reading/pausing
bool CreateLockFile(const char* lockFilePath) {
FILE* lockFile = NULL;
errno_t err = fopen_s(&lockFile, lockFilePath, "w");
if (err == 0) {
fclose(lockFile);
return true;
}
return false;
}
bool IsLockFileExists(const char* lockFilePath) {
FILE* lockFile = NULL;
errno_t err = fopen_s(&lockFile, lockFilePath, "r");
if (err == 0) {
fclose(lockFile);
return true;
}
return false;
}
void DeleteLockFile(const char* lockFilePath) {
remove(lockFilePath);
}
int main() {
HANDLE hSerial;
DCB dcbSerialParams = { 0 };
DWORD bytesRead, lastSwitchTime = GetTickCount();
FILE* file = NULL;
char buffer[2560];
const char* lockFilePath = "C:\\Users\\user\\Desktop\\readcomport\\readcomport\\lockfile.txt";
const char* dataFilePath = "C:\\Users\\user\\Desktop\\readcomport\\readcomport\\weight.txt";
bool readingPhase = true;
// Open the serial port
hSerial = CreateFile(TEXT("\\\\.\\COM7"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Error opening serial port\n");
return 1;
}
// Set up the serial port parameters
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
fprintf(stderr, "Error getting serial port state\n");
CloseHandle(hSerial);
return 1;
}
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams)) {
fprintf(stderr, "Error setting serial port state\n");
CloseHandle(hSerial);
return 1;
}
while (1) {
DWORD currentTime = GetTickCount();
if (currentTime - lastSwitchTime >= INTERVAL) {
readingPhase = !readingPhase;
lastSwitchTime = currentTime;
if (!readingPhase) {
// End reading phase: Close file and delete lock file
if (file) {
fclose(file);
file = NULL;
}
DeleteLockFile(lockFilePath);
printf("Pausing...\n");
}
else {
// Begin reading phase: Create lock file
CreateLockFile(lockFilePath);
printf("Reading...\n");
}
}
if (readingPhase && !file) {
errno_t err = fopen_s(&file, dataFilePath, "a");
if (err != 0) {
fprintf(stderr, "Error opening data file for writing\n");
continue;
}
}
if (readingPhase && file) {
if (ReadFile(hSerial, buffer, sizeof(buffer) - 1, &bytesRead, NULL) && bytesRead > 0) {
buffer[bytesRead] = '\0'; // Ensure null-terminated string
// Assuming buffer contains a string representation of the weight in kg
double weightInKg;
if (sscanf_s(buffer, "%lf", &weightInKg) == 1) { // Successfully parsed the weight
double weightInG = weightInKg * 1000; // Convert kg to g
fprintf(file, "%f g\n", weightInG); // Write the weight in grams to the file
printf("Data: %f g\n", weightInG); // Also print the weight in grams to the console
}
else {
fprintf(stderr, "Error parsing weight data\n");
}
}
}
}
// Cleanup
CloseHandle(hSerial);
if (file) {
fclose(file);
}
return 0;
}
*Kmotion:
#include "KMotionDef.h"
// Define the paths to your data and lock files
char *dataFilePath = "C:\\Users\\user\\Desktop\\readcomport\\readcomport\\weight.txt";
char *lockFilePath = "C:\\Users\\user\\Desktop\\readcomport\\readcomport\\lockfile.txt";
FILE *dataFile, *lockFile;
char line[1024]; // Buffer to hold each line read from the file
int main() {
while (1) {
// Attempt to open the lock file to check if it exists
lockFile = fopen(lockFilePath, "rt");
if (lockFile == NULL) {
// Lock file does not exist, proceed to read the weight file
dataFile = fopen(dataFilePath, "rt");
if (dataFile != NULL) {
// Successfully opened the weight file, read and print each line
while (fgets(line, sizeof(line), dataFile) != NULL) {
Print(line); // Print each line read from the file
}
fclose(dataFile); // Close the file after reading
} else {
Print("Error opening weight file.\n");
}
Delay_sec(1);
} else {
// Lock file exists, close it and wait before trying again
//fclose(lockFile);
Delay_sec(1); // Delay for 1 second
}
}
return 0; // This line is technically unreachable
}
Thank you.
The C++ code functions perfectly, handling file writing, printing, and pausing at the set moments. However, the KMotion code only reads the correct data once before causing the C++ code to crash, as if it can no longer access the file.
These are the code I am currently using :
*C++:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define INTERVAL 5000 // Interval in milliseconds for reading/pausing
bool CreateLockFile(const char* lockFilePath) {
FILE* lockFile = NULL;
errno_t err = fopen_s(&lockFile, lockFilePath, "w");
if (err == 0) {
fclose(lockFile);
return true;
}
return false;
}
bool IsLockFileExists(const char* lockFilePath) {
FILE* lockFile = NULL;
errno_t err = fopen_s(&lockFile, lockFilePath, "r");
if (err == 0) {
fclose(lockFile);
return true;
}
return false;
}
void DeleteLockFile(const char* lockFilePath) {
remove(lockFilePath);
}
int main() {
HANDLE hSerial;
DCB dcbSerialParams = { 0 };
DWORD bytesRead, lastSwitchTime = GetTickCount();
FILE* file = NULL;
char buffer[2560];
const char* lockFilePath = "C:\\Users\\user\\Desktop\\readcomport\\readcomport\\lockfile.txt";
const char* dataFilePath = "C:\\Users\\user\\Desktop\\readcomport\\readcomport\\weight.txt";
bool readingPhase = true;
// Open the serial port
hSerial = CreateFile(TEXT("\\\\.\\COM7"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Error opening serial port\n");
return 1;
}
// Set up the serial port parameters
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
fprintf(stderr, "Error getting serial port state\n");
CloseHandle(hSerial);
return 1;
}
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams)) {
fprintf(stderr, "Error setting serial port state\n");
CloseHandle(hSerial);
return 1;
}
while (1) {
DWORD currentTime = GetTickCount();
if (currentTime - lastSwitchTime >= INTERVAL) {
readingPhase = !readingPhase;
lastSwitchTime = currentTime;
if (!readingPhase) {
// End reading phase: Close file and delete lock file
if (file) {
fclose(file);
file = NULL;
}
DeleteLockFile(lockFilePath);
printf("Pausing...\n");
}
else {
// Begin reading phase: Create lock file
CreateLockFile(lockFilePath);
printf("Reading...\n");
}
}
if (readingPhase && !file) {
errno_t err = fopen_s(&file, dataFilePath, "a");
if (err != 0) {
fprintf(stderr, "Error opening data file for writing\n");
continue;
}
}
if (readingPhase && file) {
if (ReadFile(hSerial, buffer, sizeof(buffer) - 1, &bytesRead, NULL) && bytesRead > 0) {
buffer[bytesRead] = '\0'; // Ensure null-terminated string
// Assuming buffer contains a string representation of the weight in kg
double weightInKg;
if (sscanf_s(buffer, "%lf", &weightInKg) == 1) { // Successfully parsed the weight
double weightInG = weightInKg * 1000; // Convert kg to g
fprintf(file, "%f g\n", weightInG); // Write the weight in grams to the file
printf("Data: %f g\n", weightInG); // Also print the weight in grams to the console
}
else {
fprintf(stderr, "Error parsing weight data\n");
}
}
}
}
// Cleanup
CloseHandle(hSerial);
if (file) {
fclose(file);
}
return 0;
}
*Kmotion:
#include "KMotionDef.h"
// Define the paths to your data and lock files
char *dataFilePath = "C:\\Users\\user\\Desktop\\readcomport\\readcomport\\weight.txt";
char *lockFilePath = "C:\\Users\\user\\Desktop\\readcomport\\readcomport\\lockfile.txt";
FILE *dataFile, *lockFile;
char line[1024]; // Buffer to hold each line read from the file
int main() {
while (1) {
// Attempt to open the lock file to check if it exists
lockFile = fopen(lockFilePath, "rt");
if (lockFile == NULL) {
// Lock file does not exist, proceed to read the weight file
dataFile = fopen(dataFilePath, "rt");
if (dataFile != NULL) {
// Successfully opened the weight file, read and print each line
while (fgets(line, sizeof(line), dataFile) != NULL) {
Print(line); // Print each line read from the file
}
fclose(dataFile); // Close the file after reading
} else {
Print("Error opening weight file.\n");
}
Delay_sec(1);
} else {
// Lock file exists, close it and wait before trying again
//fclose(lockFile);
Delay_sec(1); // Delay for 1 second
}
}
return 0; // This line is technically unreachable
}
Thank you.