Skip to content

Commit

Permalink
v1.1.0 commit
Browse files Browse the repository at this point in the history
- Raw Image (=Camera) read support
  • Loading branch information
SunjunKim committed Apr 23, 2019
1 parent 9d73b2e commit 35e7e13
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 7 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ For the most basic example, please take look at [basic_polling] example.
* Write register value to the module.


Disclaimer: some part of the code is based on https://github.com/mrjohnk/PMW3360DM-T2QU
Notice: some part of the code is based on https://github.com/mrjohnk/PMW3360DM-T2QU
Disclaimer: This is not a PixArt official library. USE AT YOUR OWN RISK.

# License

Expand All @@ -58,6 +59,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* v1.0.0
* Initial release

# v1.0.1
* v1.0.1
* Bug fix on register reading (timing stabilized)
* Sensor initialization check routine added. (begin() will return false if failed)

* v1.1.0
* Raw frame capture functions are updated (prepareImage, readImagePixel, endImage).
* 'Camera' example is added

131 changes: 131 additions & 0 deletions examples/Camera/Camera.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include <PMW3360.h>
/*
Frame capture (=Camera) mode:
This mode disables navigation and overwrites any downloaded firmware.
A hardware reset is required to restore navigation, and the firmware must be reloaded.
# PIN CONNECTION
* MI = MISO
* MO = MOSI
* SS = Slave Select / Chip Select
* SC = SPI Clock
* MT = Motion (active low interrupt line)
* RS = Reset
* GD = Ground
* VI = Voltage in up to +5.5V
Module Arduino
RS --- (NONE)
GD --- GND
MT --- (NONE)
SS --- Pin_10 (use this pin to initialize a PMW3360 instance)
SC --- SCK
MO --- MOSI
MI --- MISO
VI --- 5V
*/

#define SS 10 // Slave Select pin. Connect this to SS on the module.

PMW3360 sensor;

void setup() {
Serial.begin(9600);
while(!Serial);

if(sensor.begin(SS)) // 10 is the pin connected to SS of the module.
Serial.println("Sensor initialization successed");
else
Serial.println("Sensor initialization failed");

// wait for 250 ms for frame capture.
delay(250);
}

void loop() {
// The following routine shoud be alwyas performed together.
// BEGIN -------------------------------------------------
sensor.prepareImage();
for(int i=0;i<36*36;i++)
{
byte pixel = sensor.readImagePixel();
Serial.print(pixel, DEC);
Serial.print(' ');
}
sensor.endImage();
// END ----------------------------------------------------

delay(50);

// optional: Surface quality report
int squal = sensor.readReg(REG_SQUAL);
Serial.println(squal);

delay(10);
}

/* Processing code for visualization (http://processing.org to downlaod)
import processing.serial.*;
Serial myPort;
int[] val = null;
boolean sync = false;
int lf = 10;
void setup()
{
size(360, 380);
String[] sList = Serial.list();
String portName = sList[sList.length - 1];
myPort = new Serial(this, portName, 9600);
}
void draw()
{
if(myPort.available() > 0)
{
String s = myPort.readStringUntil(lf);
if(s != null)
{
int[] nums = int(split(trim(s), ' '));
if(nums.length == 36*36+1)
{
val = nums;
}
}
}
if(val == null)
{
background(0);
return;
}
background(0);
noStroke();
for(int i=0;i<36;i++)
{
for(int j=0;j<36;j++)
{
int pixel = val[i*36+j];
fill(pixel);
rect(i*10, (35-j)*10, 10, 10);
}
}
int squal = val[36*36];
fill(255);
text("SQUAL = "+squal, 10, 375);
}
void keyPressed()
{
if(key == 's')
save("frame.png");
}
*/
2 changes: 1 addition & 1 deletion examples/basic_interrupt/basic_interrupt.ino
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Module Arduino
#define SS 10 // Slave Select pin. Connect this to SS on the module.

PMW3360 sensor;
bool motion = false;
volatile bool motion = false;

void setup() {
Serial.begin(9600);
Expand Down
3 changes: 3 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ getCPI KEYWORD2
readBurst KEYWORD2
readReg KEYWORD2
writeReg KEYWORD2
prepareImage KEYWORD2
readImagePixel KEYWORD2
endImage KEYWORD2

#######################################
# Constants (LITERAL1)
Expand Down
6 changes: 3 additions & 3 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name=PMW3360 Module
version=1.0.1
version=1.1.0
author=Sunjun Kim
maintainer=Sunjun Kim <kuaa.net@gmail.com>
sentence=This library allows an Arduino/Genuino board to interface with PixArt PMW3360 module
paragraph=Set parameters and get motion data from PMW3360 motion sensor module
sentence=This library allows an Arduino/Genuino board to interface with PixArt PMW3360 motion sensor module.
paragraph=You can set/get parameters, get motion data, get raw camer image from PMW3360 module.
category=Sensors
url=https://github.com/SunjunKim/PMW3360
architectures=*
90 changes: 90 additions & 0 deletions src/PMW3360.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,11 +304,19 @@ const unsigned char firmware_data[] PROGMEM = { // SROM 0x04
//================================================================================
// PMW3360 Motion Sensor Module

// bascially do nothing here
PMW3360::PMW3360()
{
}

// public
/*
begin: initalize variables, prepare the sensor to be init.
# parameter
ss_pin: The arduino pin that is connected to slave select on the module.
CPI: initial CPI. optional.
*/
bool PMW3360::begin(unsigned int ss_pin, unsigned int CPI)
{
_ss = ss_pin;
Expand Down Expand Up @@ -357,6 +365,12 @@ bool PMW3360::begin(unsigned int ss_pin, unsigned int CPI)
}

// public
/*
setCPI: set CPI level of the motion sensor.
# parameter
cpi: Count per Inch value
*/
void PMW3360::setCPI(unsigned int cpi)
{
int cpival = constrain((cpi/100)-1, 0, 0x77); // limits to 0--119
Expand All @@ -368,6 +382,12 @@ void PMW3360::setCPI(unsigned int cpi)
}

// public
/*
getCPI: get CPI level of the motion sensor.
# retrun
cpi: Count per Inch value
*/
unsigned int PMW3360::getCPI()
{
SPI_BEGIN;
Expand All @@ -378,6 +398,12 @@ unsigned int PMW3360::getCPI()
}

// public
/*
readBurst: get one frame of motion data.
# retrun
type: PMW3360_DATA
*/
PMW3360_DATA PMW3360::readBurst()
{
unsigned long fromLast = micros() - _lastBurst;
Expand Down Expand Up @@ -438,6 +464,14 @@ PMW3360_DATA PMW3360::readBurst()
}

// public
/*
readReg: get one byte value from the given reg_addr.
# parameter
reg_addr: the register address
# retrun
byte value on the register.
*/
byte PMW3360::readReg(byte reg_addr)
{
SPI_BEGIN;
Expand All @@ -447,13 +481,23 @@ byte PMW3360::readReg(byte reg_addr)
}

// public
/*
writeReg: write one byte value to the given reg_addr.
# parameter
reg_addr: the register address
data: byte value to be pass to the register.
*/
void PMW3360::writeReg(byte reg_addr, byte data)
{
SPI_BEGIN;
adns_write_reg(reg_addr, data);
SPI_END;
}

/*
adns_read_reg: write one byte value to the given reg_addr.
*/
byte PMW3360::adns_read_reg(byte reg_addr) {
if(reg_addr != REG_Motion_Burst)
{
Expand All @@ -473,6 +517,9 @@ byte PMW3360::adns_read_reg(byte reg_addr) {
return data;
}

/*
adns_write_reg: write one byte value to the given reg_addr
*/
void PMW3360::adns_write_reg(byte reg_addr, byte data) {
if(reg_addr != REG_Motion_Burst)
{
Expand All @@ -490,6 +537,9 @@ void PMW3360::adns_write_reg(byte reg_addr, byte data) {
delayMicroseconds(100); // tSWW/tSWR (=120us) minus tSCLK-NCS. Could be shortened, but is looks like a safe lower bound
}

/*
adns_upload_firmware: load SROM content to the motion sensor
*/
void PMW3360::adns_upload_firmware() {
//Write 0 to Rest_En bit of Config2 register to disable Rest mode.
adns_write_reg(REG_Config2, 0x00);
Expand Down Expand Up @@ -526,6 +576,11 @@ void PMW3360::adns_upload_firmware() {
END_COM;
}

/*
check_signature: check whether SROM is successfully loaded
return: true if the rom is loaded correctly.
*/
bool PMW3360::check_signature() {
SPI_BEGIN;

Expand All @@ -536,4 +591,39 @@ bool PMW3360::check_signature() {
SPI_END;

return (pid==0x42 && iv_pid == 0xBD && SROM_ver == 0x04); // signature for SROM 0x04
}

/*
prepareImage: prepare a raw image capture from the snesor
*/
void PMW3360::prepareImage()
{
SPI_BEGIN;

adns_write_reg(REG_Config2, 0x00);

adns_write_reg(REG_Frame_Capture, 0x83);
adns_write_reg(REG_Frame_Capture, 0xc5);

delay(20);

BEGIN_COM;
SPI.transfer(REG_Raw_Data_Burst & 0x7f);
delayMicroseconds(20);
}
/*
readImagePixel: prepare a raw image capture from the snesor
*/
byte PMW3360::readImagePixel()
{
byte pixel = SPI.transfer(0);
delayMicroseconds(20);

return pixel;
}

void PMW3360::endImage()
{
END_COM;
SPI_END;
}
8 changes: 7 additions & 1 deletion src/PMW3360.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,18 @@ class PMW3360
{
public:
PMW3360(); // set CPI to 800 by default.
bool begin(unsigned int ss_pin, unsigned int CPI = 800);
// begin: initialize the module, ss_pin: slave select pin, CPI: initial Count Per Inch
bool begin(unsigned int ss_pin, unsigned int CPI = 800);
// setCPI: set Count Per Inch value
void setCPI(unsigned int newCPI);
// setCPI: get CPI value (it does read CPI register from the module)
unsigned int getCPI();
PMW3360_DATA readBurst();
byte readReg(byte reg_addr);
void writeReg(byte reg_addr, byte data);
void prepareImage();
byte readImagePixel();
void endImage();

private:
unsigned int _ss;
Expand Down

0 comments on commit 35e7e13

Please sign in to comment.