The CJMCU-3901 is a compact optical flow sensor module that integrates the PixArt PMW3901 chip. It is mainly designed for X-Y motion detection and precise positioning in drones and robotics, particularly in indoor or GPS-denied settings.
If you'd like to support the development of the site with the price of a coffee — or a few — please do so here.
Here's a handy tip: you can quickly save this page as a PDF by clicking “export to PDF” in the menu on the right side of the screen.
| Pin Name | Function | Description |
|---|---|---|
| 3V3 | Power Supply | Typically 3.3V (range: 1.8V – 3.6V) |
| GND | Ground | Connect to the common ground of your system |
| MOS | SPI Data In | Master Out Slave In; receives commands from the controller |
| CLK | SPI Clock | Serial clock signal generated by the master |
| MIS | SPI Data Out | Master In Slave Out; sends motion data to the controller |
| CS | Chip Select | Active-low signal to enable the sensor for communication |
| RST | Reset | Optional active-low hardware reset pin |
| MOT | Interrupt | Motion detection output; triggers when new motion is detected |
| VRE | reference voltage output | It provides access to the sensor's internal regulated voltage, which is used as a reference for its internal optoelectronic operations |
Connection Requirements
Since the CJMCU-3901 operates on 3.3V logic, you must use a 3.3V Arduino (e.g., Nano 33 IoT) or a level shifter if using a 5V Arduino (e.g., Uno).
| CJMCU-3901 Pin | Arduino Pin (Uno/Nano) | Function |
|---|---|---|
| VCC | 3.3V | Power Supply |
| GND | GND | Ground |
| CS | D10 (or any Digital Pin) | Chip Select |
| MOSI | D11 | SPI Data In |
| MISO | D12 | SPI Data Out |
| SCLK | D13 | SPI Clock |
Need to install the Bitcraze_PMW3901 library via the Arduino Library Manager.
#include "Bitcraze_PMW3901.h" // Using digital pin 10 for chip select Bitcraze_PMW3901 flow(10); void setup() { Serial.begin(9600); // Initialize the sensor if (!flow.begin()) { Serial.println("Initialization of the flow sensor failed"); while(1); // Halt if sensor not found } } int16_t deltaX, deltaY; void loop() { // Get motion count since the last call flow.readMotionCount(&deltaX, &deltaY); Serial.print("X: "); Serial.print(deltaX); Serial.print(" | Y: "); Serial.println(deltaY); delay(100); // Small delay for readability }Operational Notes
This page has been accessed for: Today: 2, Until now: 3