'Issue communicating with USB instrument (AlphaLab Gaussmeter) with serial via Python

I am trying to communicate with a AlphaLabs GM-2 Gaussmeter (https://www.alphalabinc.com/product/gm2/) via its USB port with serial in python. The gaussmeter is a pretty straightforward device that only displays a digial value of the measured magnetic field on the front panel. We hope to get to the point were we can read the measurement and plot it versus time.

For now, we are having issues communicating with the device and would love some help! I've been trying to follow their Data Acquisition Manual for their systems (https://www.alphalabinc.com/wp-content/uploads/2018/02/alphaapp_comm_protocol.pdf)... but alas, we are definitely hitting a big road block.

According to the manual, if I would like to send the device the ID_METER_PROP command, i need to feed the device the command byte: 0x01 followed by 'five bytes whose contents doesn't matter'. This should give us an ASCII block followed by either a terminate byte or a byte signaling there is more data.

From our code we can get one ASCII block followed by this 'acknowledgement byte' (indicating their is more data to be sent from the gaussmeter...) but we can't seem to get out program to receive said data. Once we call this program it freezes the gaussmeter... like it's trying to send more data but just can't.

Thanks for any advice!

I've tried contacting tech support at Alpha Labs, but sadly they couldn't offer any coding help outside of their premade GUI.

'''python

# Define the command to send to the device
command = serial.to_bytes([0x01, 0x03, 0x03, 0x03, 0x03, 0x03])
#print(command)

# Send command to device and save its return
ret=gaussmeter.getIdentification(command)
print(ret) # print return variable


#-----
#Defined Function getIdentification for reference
#-----
    def getIdentification(self, command):
        time.sleep(self.DEFAULT_SLEEP_TIME)
        self.port.write(command)
        identification = self.port.read(self.DEFAULT_READ_SIZE)
        test = self.port.read(self.DEFAULT_READ_SIZE)
        return identification, test

'''

The code above outputs: (b':METER_NAME=GM2_GAUS\x08', b'')

the '\x08 is the 'acknowledgement byte' defined above and in the manual. Calling this code freezes the gaussmeter device and the only way to reset it is to unplug it and plug it back in.

We'd expect to see more device ASCII settings as defined in the manual and we definitely do not expect the device to freak out



Solution 1:[1]

First of all, I believe you should call sleep after calling write.

And the documentation says you should repeat the process if you get that 'acknowledgement byte'.

So you send command, read and if acknowledgement byte is received repeat.

Solution 2:[2]

Your code is missing sending ACKNOWLEDGE (0x08) back to the gaussmeter when an ACKNOWLEDGE (0x08) is in byte 21. Thus gaussmeter freezes waiting to receive an ACKNOWLEDGE before sending more information.

This code worked for me:

   def getIdentification(self):
        time.sleep(self.DEFAULT_SLEEP_TIME)
        self.send_cmd(self.ID_METER_PROP)
        identification = self.port.read(self.DEFAULT_READ_SIZE)
        if (len(identification) == 21):
            print(identification[0:20])
            more_to_read = (identification[20] == self.ACKNOWLEDGE)
            while(more_to_read):
                self.send_cmd( self.ACKNOWLEDGE)
                identification = self.port.read(self.DEFAULT_READ_SIZE)
                print(identification[0:20])
                more_to_read = (identification[20] == 0x08)
        else:
            print("Error reading from gaussmeter port")

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ipaleka
Solution 2