ap-- / python-seabreeze

Python module for OceanOptics spectrometers
https://python-seabreeze.readthedocs.io
MIT License
204 stars 81 forks source link

Unable to read register from Flame-T #134

Closed stepandr47 closed 2 years ago

stepandr47 commented 2 years ago

spectrometer and system information

current problem

Trying to complete a register read using raw_usb_write and raw_usb_read. The functionality works for other ep1 commands. I tested it with a temperature read command and got the expected result returned. For the register read the second byte returned is always 0x0c. I have tried it two different ways. One with sending each byte in separate commands and the other sending them combined.

steps to reproduce

  1. Connect to the Flame-T: self.spectrometer = Spectrometer.from_serial_number(serial_number)

  2. Write the endpoint 1 command (read register command): self.spectrometer.f.raw_usb_bus_access.raw_usb_write(data=struct.pack('<B', 0x6B), endpoint='primary_out')

  3. Write the register address (lamp enable): self.spectrometer.f.raw_usb_bus_access.raw_usb_write(data=struct.pack('<B', 0x40), endpoint='primary_out')

  4. Read back the returned value: self.spectrometer.f.raw_usb_bus_access.raw_usb_read(endpoint='primary_in', buffer_length=4)

Result: '@\x0c\x00\x00' The expected return would be @ = 0x40 which is the correct register value for the first byte, followed by the LSB of the value. For lamp enable this can only be a 1 or a 0. This result is the same for all register reads with the correct register value in the first byte and 0x0c as the second byte.

The other way I have tried it is doing the raw_usb_write as one command shown below. Using this returns a value of all zero: self.spectrometer.f.raw_usb_bus_access.raw_usb_write(b'\x6B\x40', endpoint='primary_out')

Is there something wrong with how I am using the raw_usb_write and read commands or is the way I am trying to read a register incorrect?

ap-- commented 2 years ago

Hi @stepandr47,

So sending the raw usb command in one go is correct. What is weird is that you're able to read 4 bytes back when you send each byte individually. According to the flame-t datasheet the command returns 3 bytes. weirdly enough as ">BH" Byte MSB LSB. My guess is that that's a print error in the datasheet and it'll be small endian in the end. Also it doesn't specify if it's an unsigned short or a signed short. So you might have to determine that from testing.

...
read_register_cmd = 0x6B
register_addr = 0x40  # Lamp Enable

# Flame-T datasheet page 113
spectrometer.f.raw_usb_bus_access.raw_usb_write(struct.pack("<BB", read_register_cmd, register_addr), endpoint='primary_out')
raw = spectrometer.f.raw_usb_bus_access.raw_usb_read(endpoint='primary_in', buffer_length=3)
returned_register_addr, register_value = struct.unpack("<BH", raw)  # note: the datasheet claims big endian, but I doubt.

Let me know if that helps.

stepandr47 commented 2 years ago

I have switched my implementation to mimic yours. I am still unsure how to interpret the result I am getting. Below are the results for a firmware version read followed by a lamp enable read. I would have expected the address for the firmware version to be 0x04 = 4 and for the lamp enable to be 0x40 = 64. Is my understanding of the returned values incorrect? image

ap-- commented 2 years ago

Hmm. I agree it seems something is off. Interestingly it looks like I ran into a similar issue when I read the firmware version https://github.com/ap--/python-seabreeze/blob/b3b6c61e649df7134b456f471b849652a6914dc1/src/seabreeze/pyseabreeze/features/fpga.py#L27

It very much possible that your spectrometer runs a firmware that doesn't match with what's written in the datasheet. Try reconstructing the firmware version from the returned value and see if it matches with what the Oceanview software reports.

Then try to repeatedly read the firmware version to check if we read the correct number of return bytes.

Also try setting lamp enable and read back the register value. I think it defaults to 0. So at least the return value is consistent here.

stepandr47 commented 2 years ago

I was able to get the correct firmware version using this command structure. Seems like my device just doesn't follow what is written in the datasheet. I was also able to write and read the lamp enable value using this.

Thanks for the help on figuring out that the first byte was different than expected.

ap-- commented 2 years ago

You're welcome :smiley:

Do you think the docs could be improved by adding a section about the raw_usb feature, maybe with an example? And would you want to contribute such an example?

Cheers, Andreas

stepandr47 commented 2 years ago

I would say the code example already makes sense it was more the disconnect between the Ocean Insight documentation that caused me confusion. Maybe just adding a comment to the raw_usb_read function saying that the first byte returned for a register read may not match the first byte in their documentation.