Integration of Pixracer with Optical Flow PMW 3901

@anbello, thanks for that info. A serial interface is pretty easy to write actually.

@Ryan_Ho, if you’re interested in writing a serial driver for the cheerson optical flow we have this on the wiki which gives some advice on how to write new drivers.

@rmackay9 I am ready to test, as I have one sitting on my shelves since a couple of months…:wink:

The issue was not really with the driver but with the implementation of the EKF and how to make it as efficient as the PX4FLOW

Btw @anbello I am reading a signal data structure different than this one https://github.com/iNavFlight/inav/blob/master/src/main/io/opflow_cxof.c#L50

my little plan to sneak that into the build didn’t work unfortunately, so no point testing. It will need to be a compile time option, with a big caveat: this flow sensor needs to be the only device on the SPI bus (so if your FC has one SPI bus with multiple chip selects for the IMU and external, don’t use it as you’ll probably crash).
I’ll work on putting a hook into OpticalFlow.cpp so that if PIXARTFLOW_SPI is defined, it will build for it. I’ll need to add instructions to the wiki as well.

James, if you map a new SPI device with the hardware definition file on the PixRacer this would be ok then?

@ppoirier with my CX-OF sensor I read data coherent with inav driver, I wrote this Arduino sketch to test:

#include <SoftwareSerial.h>

SoftwareSerial ofSerial(10, 11); // RX, TX

uint8_t chr;
uint8_t buf[9];
uint8_t index = 0;
int X, Y;

void setup() {
  Serial.begin(19200);
  ofSerial.begin(19200);

  Serial.println("CX-OF");
}

void loop() {
  while (ofSerial.available() > 0) {
    chr = ofSerial.read();

    if (index == 0) {
      if (chr != 0xFE) {
        break;
      }
    }

    buf[index++] = chr;
    
    if (index == 9) {
      if (buf[0] == 0xFE && buf[8] == 0xAA) {
        X = (int8_t)buf[2] * 256 + (int8_t)buf[3];
        Y = (int8_t)buf[4] * 256 + (int8_t)buf[5];
  
        Serial.print(X);
        Serial.print(",");
        Serial.print(Y);
        Serial.println();
      }
      
      index = 0;
    }
  }
}

and I obtain X and Y form OF. Follows an image from Arduino Serial Plotter, I was moving the sensor over my desktop in circle by hand

Cool Thanks @anbello ,
I will compare with my own test code tonight, and update here.
Thinking out loud for a moment; What about using an arrduino to emulate a PX4FLOW on I2C like a did for the TFMINI How to make the TFMINI rangefinder talk I2C? This way I am pretty sure that the EKF integration would be optimal…

With this type of board this is about the same footprint as the CX-OF

@anbello ok LOL now I remember why my code was different :slight_smile:https://www.banggood.com/AOSENMA-CG035-Optical-Positioning-Version-RC-Drone-Quadcopter-Spare-Parts-Optical-Positioning-Moudel-p-1211574.html

image

So I just ordered a Cheerson CX-OF because the above model is just 8 bit x-y values

The driver still needs to call it. The Skyviper F412 implementation is representative.
The key thing is that we have no means to configure the spi bus at runtime, so which is why the hwdef needs changing.

arducopter.apj (845.8 KB)
This is an fmu-v3 build with the pixartflow enabled on external SPI. Testing welcome please. It will only work for Pixhawk (and probably the mRo X2.1?), but not Cube, because the extra IMU on the Cube consumes that SPI bus (which is why there isn’t an external SPI port on the Cube carrier). I don’t have an fmu-v4 but will build a firmware so others can test. It turns out Revo-mini has an SPI port too, if that’s of interest to anyone.
Remember that you need a rangefinder as well, not just the flow sensor.
I’m still trying to decide the best way to push this, as it isn’t really desirable to consume the external SPI with a specific device. For fmu-v5 there is another problem, as the exposed SPI shares a timer for DMA with pwm 5 & 6, so you lose two DShot outputs if you enable the SPI (which is why its disabled by default).
The end state of all that is that at the moment I think it makes sense to have the hooks in OpticalFlow.cpp so that if the hwdef.dat defines the pixartflow, it will build for it, but not change the hwdef files in master: at least not until/unless the external SPI assignments get parameterised.

1 Like

arducopter-fmuv4.apj (806.1 KB)

This should work for Pixracer. Apart from adding in the defines for the device, SPI4 has been set up on the wifi port GPIO pins as below. The UART remains intact, so whilst the esp8266 that comes with the pixracer won’t fit if you have other cables in the connector, you could run a lead to it and it should still work. As above, I don’t have a pixracer, so this is untested.

define the 8266 port GPIOs as SPI4

PE2 SPI4_SCK SPI4
PE5 SPI4_MISO SPI4
PE6 SPI4_MOSI SPI4
PB4 FLOW_CS CS

1 Like

So others can see what I’ve done here, have a look at the following PR’s:

https://github.com/ArduPilot/ardupilot/pull/9753 - this adds a check for whether the board has HAL_HAVE_PIXARTFLOW_SPI defined, and if it does, builds in the driver.

https://github.com/ArduPilot/ardupilot/pull/9754 - this disables GPIO and adds in the SPI pin assignments on the wifi port, adds the device to the SPIDEV table and adds the HAL_HAVE_PIXARTFLOW_SPI define. Those changes are commented out, so that this doesn’t effect standard builds.

1 Like

Hi, i just wanted to ask, how do i edit and add codes? I am new here. Do I use a certain software for it?

Hi James, thank you for all the help you have given me so far, but how do i edit the CHibiOs programme

Ok.

Start here to get the code:
http://ardupilot.org/dev/docs/where-to-get-the-code.html

Then follow the guide for your operating system to set up a build environment. I use Ubuntu.

When you’ve got all that sorted out and working, you need to find this file in your local copy of the source:

https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_HAL_ChibiOS/hwdef/fmuv4/hwdef.dat

And make the changes I linked above.

The change to OpticalFlow.cpp is now in master, so you only need to change the hwdef.dat to set up the spi device and define HAL_HAVE_PIXARTFLOW_SPI

Regards,

James

Hi James,
I wanted to ask… how to you read on write codes on the pixracer? Ive done the first two steps of your previous post.
And, i just wanted to say that I am very thankful for your time and help

Regards,
Ryan

It’s in the wiki, but once you’ve made the changes to the hwdef, from the top ArduPilot directory: “./waf configure —board fmuv4”, then “./waf copter —upload”, with the board connected on USB.
The dashes are double dashes (this forum doesn’t display them well).

The changes to set up the spi isnt as simple as adding
"
PE2 SPI4_SCK SPI4
PE5 SPI4_MISO SPI4
PE6 SPI4_MOSI SPI4
PB4 FLOW_CS CS

"
right? just to clariy

regards,
Ryan

Like that,
from

to

Have a look here: https://github.com/ArduPilot/ardupilot/pull/9754/files

1 Like

Would uploading the .apj file above via missionplanner (load custom firmware) suffice? Or must I make changes. As i cannot open the .apj file, but i can click on the file via mission planner (load custom firmware)