-
Notifications
You must be signed in to change notification settings - Fork 63
Return ReportID being read from the sensor #55
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
Conversation
Ping |
Hi @ya-mouse, |
Hi, I had a similar need of knowing which data was really updated and forked the code there guihomework@905084e . I was in the process of providing a PR, but saw this one which aims to a similar goal. Would be nice to get some comments if one or the other idea (or both) should be prepared as a PR, and which feature seem worth keeping. thanks |
Hi @guihomework & @ya-mouse , |
That consumes a lot of memory while could be stored in simple bit vector:
With such a code: on each packet receive you should call all of the routines that you have expected to be supported instead of handling the current packet type (like my PR do). |
@PaulZC, I've updated the base. |
You are right about the memory consumption. I was not processing the latest packet in my mainloop, because I want to adjust the speed at which I process (=send to the PC) the new data in a regular timed interrupt. The mainloop was just calling the library data extraction (with dataAvailable) fast enough and in this interrupt I check if all data I need are there and create a frame (acc, gyro, quat for instance) to send the latest of all of them together to the PC. With your code, I need to store a boolean vector (or if I optimize memory, a bit array) in my main loop and poll this "external" boolean vector in my code. Will work as well, but I wanted to provide this newData state to every user of the lib because in my opinion the state of the data of the sub-functions of the chip should be available on request from the lib. Maybe a compromise could be to store a bit array in the lib (in you reworked dataAvailable it will be easy with the return value of getReadings to update the bit array), for later use, and still have your direct answer when doing getReadings. I would be fine to provide a PR on top of your changes, and I am preparing a different PR regarding the helper functions to retrieve x,y,z values in one call (unrelated to new data available then) |
The sample code is:
What is important:
After each If you have a 10 milliseconds reading period or less? I'm not counting on SPI interface that requires an exact reaction on the packet (by interrupt pin) within a strict deadline, otherwise BNO080 will be reset by its watchdog (BNO088 has ability to re-try sending the data, but still requires a real-time operation). In case of sending frame to PC just keep a Ring Buffer long enough (you can have separate RingBuffers that stores different kind of data with timestamps) with several data series and poll them periodically from PC. Or even push to PC. Having one routine to get all values at once might be a good idea. Keep this change in separate PR. The boolean vector stuff, IMO, is an implementation details for the specific project. I would keep it within it. Not a big deal :) PS. I had another change that returns TimeStamp with current local system's microseconds right at the time of parsing the packet minus the packet's measuring microseconds time. The code is naive and didn't account on microseconds wrap, so, incomplete =) |
Hi @ya-mouse thank you for taking the time to demonstrate your idea and compare it to mine. I repeat your idea is fine. I am trying to see if some additional stuff could help others. I was not using getTimeStamp at my side (more on that lower) so I missed your very good point about knowing when the data was acquired. Your idea of my usage is a little bit off. For my system I need a full frame (lin acc, gyro, and quat), and the frame speed is limited to the slowest data. Hence, at the time I did 3 getOnNewXXX for a full new frame, maybe some the fastest data had already been missed but it was replaced by fresher ones, and my newData was then true for all 3 types. This way I was sure I had the most fresh data possible for the combination of 3 types of data. For me the timestamp could not really be combined for my frame, even if I had stored it for each type, so I decided to not use it. here is the code that is currently running in one of our device. The interrupt is at 1ms (for our tactile sensors through external ADCs overs SPI), so faster than the refresh rate of the BNO08x set to 2 ms. While re-reading my code, I realize I am not doing what I thought I had coded and reported earlier. I apologize. I am not calling dataAvailable in the mainloop as fast as possible. Hence, for 3 new data types to be "new" at the same time, the shortest period would be 3 times calling the dataAvailable, which means 3ms in my case. This explains my slower rate that I was seeing (but sufficient for the IMU). A rework is necessary it seems. In the best case, the SPI handling in my code should be with interrupts on new data of the BNO08x, and take care to store the data locally, until all data are the "most fresh" to create a full frame. Your code permits that. I think providing an example based on the code you shared in the conversion as part of the PR could be good. Ideally a second example for SPI with interrupt, and handling the storage at user code side could be nice as well (I can do that later as this would be required for my code anyway). Regarding the timestamp storage for different data types, if you concur, this could be a new PR too if need be thanks, |
Let's keep the library simple. The only purpose of the library is to:
Calls to That's why |
Yes to all you wrote about my code, I noticed exactly what you commented on my code when I myself read it again. Currently only one "if" is valid at a time and makes no sense (but at least the data was stored once in my variables and no further memory copy would be done) The thing is, the current lib does not do only 1. and 2. that you suggest, it also does because there is a 3. existing, I thought augmenting it with the "state" of the data (= was it "consumed" or not...) Your solution is keeping the lib simple and not storing the state of the data (needs to be consumed when it is there to store the state at the mainloop side), so my discussion is only about a choice what should the library store. If I follow you, 3. would have to be removed as well from the lib and the mainloop would necessarily have to process the data when it is there, including storing, keeping track of flags after each getReadings (which you do) and then remove all those memory usage about storing all data types in the lib. The choice of what to store in the lib is a question that the maintainer should decide on. @PaulZC do you want to comment on your vision of what should be stored in the lib ? (newdata state , data type individual timestamp ?) I suppose for backward compatibility 3. will stay, and the additional getReadings of your PR is just in order to bypass the internals that do not store all info yet, while my 'clumsy' idea was to add some kind of info about the state. thanks for your kind answers and comments. |
Don't excuse :)) The precise interrupt-driven handling is another story and perhaps might lead to different design of the library. My opinion, that the lib is not a silver bullet, but to demonstrate how to interact with the sensor using either i2c or spi. You probably might want to skip the Q-numbers conversion to float and just store original values from the sensor. Later you can convert them to doubles (e.g.on PC) For the high rate application it might be worth just to consume parts from the library code to efficiently handle new data packets. In your case you just handle getReadings in interrupt handler, store data for the new frame and tracks completeness by bit flags. Once all type of data is collected, then release the frame (e.g.store in data collection/ringbuffer/whereever), reset the bit flag and re-init the frame for the new data. This will keep the interrupt handler short. It would be great to have a one routine per sensors type to copy measurements. |
@PaulZC , ping :) |
Are you guys finished?! |
Hi, |
Hi @ya-mouse , |
Hi @ya-mouse , |
Hi @guihomework , |
@PaulZC FYI, working on that right now. I found an arduino I can use too for my tests. |
Current function dataAvailable initiates data read and returns boolean without respect to which kind of data being read.
If the sensor being configured to report different sensors, then dataAvailable() wouldn't provide essential info which sensor were updated.