Forum
Issue regarding the use of Fanuc Focas cnc_rdparam function.
Quote from Santosh Naidu on July 11, 2023, 9:56 amHello, I've tried to use the fwlib32 cnc_readparam function and encountered some issues. I have attached the output of code as well as the parameters visible on the fanuc HMI. It would be helpful if someone finds where I am going wrong.#include <stdio.h>#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "fwlib32.h"int main() {
unsigned short handle;
short ret;
IODBPSD param;if (cnc_startupprocess(0, "focas.log") != EW_OK){
fprintf(stderr, "Failed to create log file \n");
return 1;
}
// Connect to CNC
ret = cnc_allclibhndl3("192.168.0.11", 8193, 10, &handle);if (ret == EW_OK) {
// Read parameter number 6711 for all axes
ret = cnc_rdparam3(handle, 6711, 0, sizeof(param), 0, ¶m);if (ret == EW_OK) {
printf("Part count: %ld\n", param.u.rdata.prm_val);
printf("Dec count: %ld\n", param.u.rdata.dec_val);
printf("data no: %hd\n", param.datano);
printf("type: %ld\n", param.type);
printf("Char data: %c\n", param.u.cdata);
printf("idata: %hd\n", param.u.idata);
printf("long data: %ld\n", param.u.ldata);} else {
printf("Failed to read part count. Error code: %d\n", ret);
}// Release CNC handle
cnc_freelibhndl(handle);
} else {
printf("Failed to connect to CNC. Error code: %d\n", ret);
}return 0;
}
#include <stdlib.h>
#include <string.h>
#include "fwlib32.h"
int main() {
unsigned short handle;
short ret;
IODBPSD param;
if (cnc_startupprocess(0, "focas.log") != EW_OK){
fprintf(stderr, "Failed to create log file \n");
return 1;
}
// Connect to CNC
ret = cnc_allclibhndl3("192.168.0.11", 8193, 10, &handle);
if (ret == EW_OK) {
// Read parameter number 6711 for all axes
ret = cnc_rdparam3(handle, 6711, 0, sizeof(param), 0, ¶m);
if (ret == EW_OK) {
printf("Part count: %ld\n", param.u.rdata.prm_val);
printf("Dec count: %ld\n", param.u.rdata.dec_val);
printf("data no: %hd\n", param.datano);
printf("type: %ld\n", param.type);
printf("Char data: %c\n", param.u.cdata);
printf("idata: %hd\n", param.u.idata);
printf("long data: %ld\n", param.u.ldata);
} else {
printf("Failed to read part count. Error code: %d\n", ret);
}
// Release CNC handle
cnc_freelibhndl(handle);
} else {
printf("Failed to connect to CNC. Error code: %d\n", ret);
}
return 0;
}
Uploaded files:
- You need to login to have access to uploads.
Quote from Kenneth Porter on July 11, 2023, 9:30 pmLook here at how to interpret the rdata type. It's a fixed-point decimal number.
https://www.inventcom.net/fanuc-focas-library/ncdata/cnc_rdparam3
I suggest adding a helper function that renders a REALPRM type to either a string or a long double.
Look here at how to interpret the rdata type. It's a fixed-point decimal number.
https://www.inventcom.net/fanuc-focas-library/ncdata/cnc_rdparam3
I suggest adding a helper function that renders a REALPRM type to either a string or a long double.
Quote from Santosh Naidu on July 17, 2023, 11:38 pmHi, thank you for the reply. I created a function that renders the structure as a long double. But sadly it still gives me incorrect values.
Hi, thank you for the reply. I created a function that renders the structure as a long double. But sadly it still gives me incorrect values.
Quote from Kenneth Porter on July 18, 2023, 12:56 amCan you post your code? (Alas, I don't see a markup type in the editor here for pre-formatted text to preserve indentation. You could use a pastebin for that, though.)
Can you post your code? (Alas, I don't see a markup type in the editor here for pre-formatted text to preserve indentation. You could use a pastebin for that, though.)
Quote from Kenneth Porter on July 18, 2023, 1:07 amBased on the doc link above, this C++ should work. (Untested.)
long double realprmToLongDouble(const REALPRM& rp) { return static_cast<long double>(rp.prm_val) * std::pow(10.0L, -rp.dec_val); }
Based on the doc link above, this C++ should work. (Untested.)
long double realprmToLongDouble(const REALPRM& rp) { return static_cast<long double>(rp.prm_val) * std::pow(10.0L, -rp.dec_val); }
Quote from Kenneth Porter on July 18, 2023, 1:25 amI think I see your problem. What compiler and platform are you using? I see Kali in the screenshot so I assume some flavor of Linux. But I'm guessing it's 64-bit and the compiler is using 64-bit longs. The Focas header assumes that longs are 32-bit, so it's misinterpreting the contents of the returned structure. That huge number is actually two 32-bit longs glued together into a 48-bit number, which is wrong. (I fed it to Windows Calculator in programming mode to see what the hex equivalent is.)
I think I see your problem. What compiler and platform are you using? I see Kali in the screenshot so I assume some flavor of Linux. But I'm guessing it's 64-bit and the compiler is using 64-bit longs. The Focas header assumes that longs are 32-bit, so it's misinterpreting the contents of the returned structure. That huge number is actually two 32-bit longs glued together into a 48-bit number, which is wrong. (I fed it to Windows Calculator in programming mode to see what the hex equivalent is.)
Quote from Santosh Naidu on July 18, 2023, 1:36 amYou are right. I am running a linux. And it is a x86_64. Can you suggest the best possible approach to resolve the issue ?
You are right. I am running a linux. And it is a x86_64. Can you suggest the best possible approach to resolve the issue ?
Quote from Kenneth Porter on July 18, 2023, 3:04 amI think your compiler is completely misinterpreting the structures in the Focas header. What compiler are you using? I'm guessing gcc, but what version? There are probably settings to force it to interpret the types in the Focas header properly, since it's also used to compile the kernel, and the kernel is quite sensitive to this.
Fanuc should change its types to the C99 ones that specify the desired word size, like int32_t to enhance portability.
I think your compiler is completely misinterpreting the structures in the Focas header. What compiler are you using? I'm guessing gcc, but what version? There are probably settings to force it to interpret the types in the Focas header properly, since it's also used to compile the kernel, and the kernel is quite sensitive to this.
Fanuc should change its types to the C99 ones that specify the desired word size, like int32_t to enhance portability.
Quote from Kenneth Porter on July 18, 2023, 3:13 amI think you're going to need to build the app as 32-bit. At least until Fanuc fixes its headers to use int32_t for those members. Windows compilers assume long is 32-bit, so this is a basic incompatibility between gcc and Visual Studio.
I think you're going to need to build the app as 32-bit. At least until Fanuc fixes its headers to use int32_t for those members. Windows compilers assume long is 32-bit, so this is a basic incompatibility between gcc and Visual Studio.
Quote from Versex on July 18, 2023, 8:49 amSorry I did not see this sooner. I am not sure why I am not getting all the email notifications for new topics. I'll have to check my settings to make sure everything is set correctly. Anyway, I wanted to note that Fanuc no longer supports the Linux libs and won't be making anymore updates/fixes for it.
In order to compile for 32-bit you will need to install gcc-multilib and pass the -m32 flag when compiling.
On a side note, after reading this thread, I added the ability to add code blocks.
Sorry I did not see this sooner. I am not sure why I am not getting all the email notifications for new topics. I'll have to check my settings to make sure everything is set correctly. Anyway, I wanted to note that Fanuc no longer supports the Linux libs and won't be making anymore updates/fixes for it.
In order to compile for 32-bit you will need to install gcc-multilib and pass the -m32 flag when compiling.
On a side note, after reading this thread, I added the ability to add code blocks.