Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue reading structs containing BIT datatype #100

Open
isaac-nls opened this issue Dec 20, 2022 · 3 comments
Open

Issue reading structs containing BIT datatype #100

isaac-nls opened this issue Dec 20, 2022 · 3 comments
Labels
bug Something isn't working enhancement New feature or request

Comments

@isaac-nls
Copy link

Hi,

I'm having an issue where I cannot subscribe to structures containing BITs. I can subscribe to everything else just fine.

For example, I cannot subscribe to the struct below:

TYPE ST_SYSTEM_STATE :
STRUCT
	//all subsystems
	bStateMachineRunning					: BIT; 
	bMotorsPowered						: BIT; 	
	bInitComplete							: BIT; 	
	bIsHoming							: BIT;	
	bHasHomed							: BIT; 	
	bIsReady								: BIT; 	
	bIsBusy								: BIT; 
	bMotorsMoving						: BIT;	
	bHasStopped							: BIT; 
	bHasPaused							: BIT;
END_STRUCT
END_TYPE

Turning on debugging in ads-client, I receive the following message:

at async \node_modules\ads-client\src\ads-client.js:6325:35 { code: 'ERR_BUFFER_OUT_OF_BOUNDS' } +4ms
  ads-client:details IO in  <------ 68 bytes +494ms
  ads-client:details _parseAmsTcpHeader(): Starting to parse AMS/TCP header +1ms
  ads-client:details _parseAmsTcpHeader(): AMS/TCP header parsed: { command: 0, commandStr: 'AMS_TCP_PORT_AMS_CMD', dataLength: 62 } +0ms
  ads-client:details _parseAmsHeader(): Starting to parse AMS header +1ms
  ads-client:details _parseAmsHeader(): AMS header parsed: { targetAmsNetId: '192.168.200.1.1.1', targetAdsPort: 33242, sourceAmsNetId: '192.168.11.2.1.1', sourceAdsPort: 851, adsCommand: 8, adsCommandStr: 'Notification', stateFlags: 4, stateFlagsStr: 'AdsCommand, Tcp, Request', dataLength: 30, errorCode: 0, invokeId: 0, error: false, errorStr:
  ads-client:details _getDataTypeInfo(): Data type requested for BIT +0ms
  ads-client:details _getDataTypeInfo(): Data type info found from cache for BIT +0ms
  ads-client:details _getDataTypeInfo(): Data type requested for BIT +0ms  ads-client:details _getDataTypeInfo(): Data type info found from cache for BIT +1ms
  ads-client _onAdsCommandReceived(): Ads notification received but parsing Javascript object failed: RangeError [ERR_BUFFER_OUT_OF_BOUNDS]: Attempt to access memory outside buffer bounds

Any help would be greatly appreciated.

Thanks!
Isaac

@jisotalo
Copy link
Owner

jisotalo commented Dec 20, 2022

Hi!

Actually the BIT data type is not available/working at the moment. I thought that I had it in README but I didn't.. Basically it is in the code however handled like a BOOL and it would require some extra effort to be handled correctly.

So I would suggest to use BOOL instead if possible, or just a single WORD and then get the bits yourself. Personally I never use BITs with TwinCAT as the support is not that good.

Edit: I will keep this issue open as this certainly should work some day if it's technically doable.

@jisotalo jisotalo added bug Something isn't working enhancement New feature or request labels Dec 20, 2022
@isaac-nls
Copy link
Author

Hi jisotalo,

Thanks very much for the quick reply. Good to know I wasn't going crazy! We initially were using BITs instead of BOOLs to reduce the size of the overall packets over the network, but it's not a big deal for us to change over to using BOOLs instead. I'll keep it in mind for future development not to use BITs.

Once again, I very much appreciate the time and effort you've put into this library.

Thanks!
Isaac

@jisotalo
Copy link
Owner

If you really need to read struct with BITs it's possible but needs a little work. I tested the following and it works fine!

PLC side

TYPE ST_Bits:
STRUCT
  Bit_0 : BIT;
  Bit_1 : BIT;
  Bit_2 : BIT;
  Bit_3 : BIT;
  Bit_4 : BIT;
  Bit_5 : BIT;
  Bit_6 : BIT;
  Bit_7 : BIT;
END_STRUCT
END_TYPE
//GVL_BitTest
{attribute 'qualified_only'}
VAR_GLOBAL
  Bits : ST_Bits;
END_VAR

Node.js side

const ads = require('ads-client');
const client = new ads.Client({
  targetAmsNetId: 'localhost',
  targetAdsPort: 851
});

client.connect()
  .then(async res => {   
    console.log(`Connected to the ${res.targetAmsNetId}`);
    console.log(`Router assigned us AmsNetId ${res.localAmsNetId} and port ${res.localAdsPort}`);

    //First getting the symbol info for this variable
    const info = await client.getSymbolInfo('GVL_BitTest.Bits');

    //Using symbol info to subscribe to raw data
    const sub = await client.subscribeRaw(info.indexGroup, info.indexOffset, info.size, (data, sub) => {
      //Converting Buffer to byte
      const value = data.value.readUint8();
      
      const converted = {
        bit_0: !!(value & (0x01 << 0)),
        bit_1: !!(value & (0x01 << 1)),
        bit_2: !!(value & (0x01 << 2)),
        bit_3: !!(value & (0x01 << 3)),
        bit_4: !!(value & (0x01 << 4)),
        bit_5: !!(value & (0x01 << 5)),
        bit_6: !!(value & (0x01 << 6)),
        bit_7: !!(value & (0x01 << 7)),
      }
      console.log(converted);
      /* Should print something like:
      {
        bit_0: true,
        bit_1: false,
        bit_2: true,
        bit_3: false,
        bit_4: true,
        bit_5: false,
        bit_6: true,
        bit_7: false
      }
      */
    });
  })
  .catch(err => {
    console.log('Something failed:', err);
  })

Thanks again and have a nice christmas!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants