Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of PAT9125_OTS_L476RG by
This section highlights the setup and operating guide to integrating PAT9125EL with the Nucleo L476RG.
Setup
Hardware:
- 1. PC with Windows Operating System
- 2. Nucleo L476RG Dev Kit Board from ST
- 3. PAT9125EL Arduino Enabled Board
- 4. USB Cable (one end with miniUSB)
Connection:
Please connect the board as show below.

Supplying Power
Connect the one end of the USB to the PC USB and the other to the Nucleo L476RG miniUSB as shown in the figure below.

I am assuming that you already know and are able to download the code at this point. Once programmed with the latest compiled .bin file, the LED should turn Green, as illustrated below.

Next, we will test to see if the sensor (PAT9125EL) is indeed functional, and able to display the rotational displacement, on the on-board LCD Display.
While you rotate the Rotational Shaft clockwise, you should see an increment in the digital count for "SHAFT" on the LCD Display, also showing "Up" as you rotate the shaft in the clockwise direction.
While you rotate the Rotational Shaft counter-clockwise, you should see decrease in the digital counts under "SHAFT"on the LCD Display, also showing "Down" as you rotate the shaft in the counter-clockwise direction.
While you push the shaft inward, you should see an increment in digital counts under SPRING. While pushed inward, it will show as "Pre" for Press on the LCD Display.
Conversely, once you release the shaft, the LCD Display should show "Rel" for "Release".
To RESET the digital count, press on the button on the bottom left side of the board. This should reset the digital count on "SHAFT" and "SPRING" to "+0000".
Have fun with this and should you have any questions, please do not hesitate to contact us.
Revision 4:1cd61816c013, committed 2017-10-18
- Comitter:
- pixus_mbed
- Date:
- Wed Oct 18 10:01:44 2017 +0000
- Branch:
- Branch_nRF51
- Parent:
- 2:4fb710ae08dd
- Child:
- 11:29053223499c
- Child:
- 13:1efc192be0f5
- Commit message:
- Support UART command mode.
Changed in this revision
| pat9125_mbed/pat9125_mbed.cpp | Show annotated file Show diff for this revision Revisions of this file |
| pixart_lcm/pixart_lcm.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 4fb710ae08dd -r 1cd61816c013 pat9125_mbed/pat9125_mbed.cpp
--- a/pat9125_mbed/pat9125_mbed.cpp Tue Oct 17 09:31:37 2017 +0000
+++ b/pat9125_mbed/pat9125_mbed.cpp Wed Oct 18 10:01:44 2017 +0000
@@ -41,7 +41,10 @@
#define LCM_DisplayString(a,b,c) gp_state->pLCM->LCM_DisplayString(a,b,c)
#define I2C_RESET gp_state->p_i2c = gp_state->p_i2c->reset(); //workaround for nRF51 mbed
-
+
+
+unsigned char xy2uart_enh=0;
+
//for OTS
signed int deltaX16;
signed int deltaY16;
@@ -113,13 +116,6 @@
OTS_WriteRead_Reg(0x0E, 0xFF); // set Y-axis resolution (depends on application)
OTS_WriteRead_Reg(0x19, 0x04); // set 12-bit X/Y data format (depends on application)
//OTS_WriteRead_Reg(0x4B, 0x04); // ONLY for VDD=VDDA=1.7~1.9V: for power saving
-
- if(OTS_Read_Reg(0x5E) == 0x04)
- {
- OTS_WriteRead_Reg(0x5E, 0x08);
- if(OTS_Read_Reg(0x5D) == 0x10)
- OTS_WriteRead_Reg(0x5D, 0x19);
- }
OTS_WriteRead_Reg(0x09, 0x00); // enable write protect
}
@@ -259,6 +255,260 @@
}
//-----------------------------------------------------------------------
+
+/*
+ SerialEvent occurs whenever a new data comes in the hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response.
+ Multiple bytes of data may be available.
+
+ Host Command Supported:
+ Read and write sensor register
+ Sensor read = "r aa", aa must be hex value, example "r 0f" means read register 0x0f.
+ Sensor write = "w aa bb", aa and bb must be hex value, example "w 02 00" means write register 0x02 with value 0x00.
+*/
+#include <string>
+#include <algorithm>
+#include <cctype>
+#include <locale>
+
+#define String string
+#define VERSRION "2.40" //PAT9125 FW version
+
+
+void serialProcess(String input);
+bool IsParamValid(char *param, String str_pre, bool hex =false);
+void PrintHex8(uint8_t data);
+bool IsDigit(char *p, bool hex);
+typedef unsigned char byte ;
+String strRead;
+char hexChar[3];
+
+void println()
+{
+ gp_state->p_pc->printf("\n");
+}
+
+void println(String str)
+{
+ const char * c = str.c_str();
+ gp_state->p_pc->printf(c);
+ gp_state->p_pc->printf("\n");
+}
+void print(String str)
+{
+ const char * c = str.c_str();
+ gp_state->p_pc->printf(c);
+}
+void print(signed int value)
+{
+ gp_state->p_pc->printf("%d",value);
+}
+
+
+string trim(const string& src, const string& c)
+{
+ int p2 = src.find_last_not_of(c);
+ if (p2 == string::npos) {
+ return string();
+ }
+ int p1 = src.find_first_not_of(c);
+ if (p1 == string::npos) {
+ p1 = 0;
+ }
+
+ return src.substr(p1, (p2-p1)+1);
+}
+
+void toCharArray(char *buffer, string s)
+{
+ strcpy(buffer, s.c_str());
+}
+
+void serialEvent()
+{
+ while (gp_state->p_pc->readable())
+ {
+ // get the new byte:
+ char inChar = (char)gp_state->p_pc->getc() ; //Serial.read();
+ // if the incoming character is a newline, set a flag
+ // so the main loop can do something about it:
+ if ((inChar == '\n') || (inChar == '\r'))
+ {
+ //strRead.trim();
+ strRead = trim(strRead, " ");
+ strRead += " "; // for tokenizing
+ serialProcess(strRead);
+ strRead = "";
+ }
+ else if (inChar != 0xf0)
+ {
+ // add it to the inputString:
+ strRead += inChar;
+ }
+ }
+}
+
+void serialProcess(String input)
+{
+ int val;
+ int i, j;
+ String output;
+ unsigned char Address,Value;
+
+ // ====================================================
+ // Single command goes here
+ // NOTE: All command compare must have " " at the back
+ // ====================================================
+ if (input == "pxi ")
+ {
+ println("PixArt-PAT9125");
+ }
+ else if (input == "ver ")
+ {
+ println(VERSRION);
+ }
+ else if (input == "xy2uart_on ")
+ {
+ xy2uart_enh=1;
+ println("Sensor XY Output Enable");
+ }
+ else if (input == "xy2uart_off ")
+ {
+ xy2uart_enh=0;
+ println("Sensor XY Output Disable");
+ }
+ // ====================================================
+ // Command with parameters goes here, like r 00, w 48 00
+ // ====================================================
+ else if (input != " ") // not empty string, then proceed to decode the command
+ {
+ char buff[50];
+ //input.toCharArray(buff, input.length());
+ toCharArray(buff, input);
+
+ // Get the command
+ char *tok = strtok(buff, " ");
+ if (!tok)
+ {
+ println("empty command");
+ return;
+ }
+
+ // Get parameters, up to 4 parameters, if more than that, individual command will need to extract it on their own
+ char *param[4];
+ for (val = 0; val < 4; val++)
+ {
+ param[val] = strtok(NULL, " ");
+ if (!param[val]) // break if we reach the end
+ break;
+ }
+
+ // switch for command
+ String str = String(tok);
+ if ((str == "r") || (str == "w"))
+ {
+ // Address is the first byte
+ if (!IsParamValid(param[0], "Error (r/w): address"))
+ {
+ return;
+ }
+ // convert to integer
+ Address = strtol(param[0], NULL, 16);
+ if (Address > 0x7F)
+ {
+ println("Error (r/w): address > 0x7F");
+ return;
+ }
+
+ if (str == "w")
+ {
+ // Value is second byte
+ if (!IsParamValid(param[1], "Error (w): value"))
+ {
+ return;
+ }
+ // convert to integer
+ Value = strtol(param[1], NULL, 16);
+ if (Value > 0xFF)
+ {
+ println("Error (w): value > 0xFF");
+ return;
+ }
+
+ OTS_Write_Reg(Address, Value);
+ }
+
+ print("ADDR ");
+ PrintHex8(Address);
+ print(" ");
+ PrintHex8(OTS_Read_Reg(Address));
+ println();
+ }
+ else
+ {
+ println("Bad command");
+ }
+ }
+}
+
+// Check if param is not given or not hexa, print the error as well
+bool IsParamValid(char *param, String str_pre, bool hex)
+{
+ if (!param)
+ {
+ print(str_pre);
+ println(" not given");
+ return false;
+ }
+ if (!IsDigit(param, hex))
+ {
+ print(str_pre);
+ if (hex)
+ println(" not hex");
+ else
+ println(" not digit");
+ return false;
+ }
+ return true;
+}
+
+// Check whether is hexa for given char
+bool IsDigit(char *p, bool hex)
+{
+ for (int i; i < strlen(p); i++)
+ {
+ if (hex)
+ {
+ if (!isxdigit(p[i]))
+ return false;
+ }
+ else if (!isdigit(p[i]))
+ return false;
+ }
+ return true;
+}
+
+void Hex8(uint8_t data)
+{
+ byte first ;
+ first = (data >> 4) | 48;
+ if (first > 57) hexChar[0] = first + (byte)39;
+ else hexChar[0] = first ;
+
+ first = (data & 0x0F) | 48;
+ if (first > 57) hexChar[1] = first + (byte)39;
+ else hexChar[1] = first;
+}
+
+// Print in hex with leading zero
+void PrintHex8(uint8_t data)
+{
+ Hex8(data);
+
+ print(hexChar);
+}
+
+
+//-----------------------------------------------------------------------
void loop()
{
@@ -304,6 +554,14 @@
}
}
+ if(xy2uart_enh == 1)
+ {
+ //output to UART
+ print("DX:\t");print(deltaX16);print("\t");
+ print("DY:\t");print(deltaY16);print("\t");
+ print("\n");
+ }
+
//re-enable interrupt for MOTION pin
attachInterrupt(digitalPinToInterrupt(PIN_SEN_MOTION), OTS_MotionPin_ISR, LOW);
diff -r 4fb710ae08dd -r 1cd61816c013 pixart_lcm/pixart_lcm.cpp
--- a/pixart_lcm/pixart_lcm.cpp Tue Oct 17 09:31:37 2017 +0000
+++ b/pixart_lcm/pixart_lcm.cpp Wed Oct 18 10:01:44 2017 +0000
@@ -185,7 +185,7 @@
void LCM_DisplayString_Boot(boolean sen_status)
{
LCM_DisplayString(1,1,"PixArt Shaft EVK");
- LCM_DisplayString(2,1,"PAT9125 FW V2.30");
+ LCM_DisplayString(2,1,"PAT9125 FW V2.40");
delay(2000);
LCM_ClearLine(1);
@@ -198,6 +198,7 @@
else
{
LCM_DisplayString(2,1,"Read Sensor Fail");
+ while(1);//stop here if read sensor fail as a warning.
}
}

PAT9125EL - Miniature Optical Navigation for Surface Tracking