tobias
Bitcraze
Posts: 1722
Joined: Mon Jan 28, 2013 7:17 pm
Location: Sweden

Difficult to know but I think you are on to something. To make sure the DELTA registers are consistent this should be followed:
1. Read the Motion register. This will freeze the Delta_X_L, Delta_X_H, Delta_Y_L and Delta_Y_H
register values.
2. If Bit 7 is set, Delta_X_L, Delta_X_H, Delta_Y_L, Delta_Y_H, SQUAL and Shutter_Upper registers
should be read in sequence to get the accumulated motion.
Note: If Delta_X_L, Delta_X_H, Delta_Y_L and Delta_Y_H registers are not read before the motion
register is read for the second time, the data in Delta_X_L, Delta_X_H, Delta_Y_L and Delta_Y_H
will be lost.
3. To suppress false motion reports, discard Delta_X and Delta Y values if the SQUAL value < 0x19
and Shutter_Upper = 0x1F.
4. To read a new set of motion data (Delta_X_L, Delta_X_H, Delta_Y_L and Delta_Y_H), repeat from
Step (1).

Sailorjoe
Beginner
Posts: 10
Joined: Thu Mar 22, 2018 5:30 am

Thank you. I'll follow those instructions and let you know. Question: how does the chip decide to update the data registers after the read sequence is complete? Is there just a time delay, or some other logic? Thanks.

Sailorjoe
Beginner
Posts: 10
Joined: Thu Mar 22, 2018 5:30 am

OK, I think I have it. Following your suggestions, I modified the Arduino library Bitcraze_PMW3901 to do things a little differently. First, I added two additional parameters to the readMotionCount function, so now it looks like this: readMotionCount(int16_t *deltaX, int16_t *deltaY, uint8_t *squal, uint8_t *shutterU). That let me read the squal and shutter_Upper and check their values in the main program. As it happens, I never once got a reading that needed to be thrown out. The second thing was to rearrange how the deltaX and Y registers are read. In the original program, they aren't read sequentially, so I modified the code to cause that to happen. Lo and behold, the strange spikes I was getting went away. Now I just get what I consider normal noise. With a little filtering I think it will be OK.

Someone asked if my counts were consistent over a fixed distance. After fixing the library as described above, I ran a series of tests, where I moved the sensor a fixed distance, and (without filtering), accumulated counts. I ran twenty tests, and plotted the results. Here is a plot of the results for the X axis.
PMW3901Tests.xls
Over a fixed distance of 8-9/16 inches, the count ranged from 828 to 1084, and the number of readings ranged from 26 (fast motion) to 195 (slow motion). The main program has a 20 msec delay between readings. There is a slight negative correlation between count and speed. All of this translates to an average of about 112 counts per inch, which is far more than I need on the robot. So in practical terms we should be able to make this work.

By the way, I ran the same tests for the Y axis, and got essentially the exact same results. No surprises there.

I wonder if the squal and shutter values can be explained, or if that is proprietary information. Same for the other registers that are available.

Thank you for your suggestions. They put me on the right path. Now I need to take what I've learned and translate it all to Java to use on the actual robot. In another post, I'll compare the Arduino and the Crazyflie PMW3901 initialization code, and highlight the differences.

Joe

Sailorjoe
Beginner
Posts: 10
Joined: Thu Mar 22, 2018 5:30 am