Closed stepandr47 closed 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.
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?
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.
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.
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
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.
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
Connect to the Flame-T: self.spectrometer = Spectrometer.from_serial_number(serial_number)
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')
Write the register address (lamp enable): self.spectrometer.f.raw_usb_bus_access.raw_usb_write(data=struct.pack('<B', 0x40), endpoint='primary_out')
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?