Introduction

The RP2040 Smartwatch is a customizable wearable device powered by the Raspberry Pi RP2040 microcontroller. This documentation provides information on how to flash the firmware, wire the required components, and utilize various input options in your projects.

Installation

To get started with the RP2040 Smartwatch, ensure you have the Arduino IDE installed along with the necessary libraries for the RP2040. Follow the steps below to install the required libraries:

  1. Download the Arduino IDE installation package from Arduino website
  2. Install Arduino-Pico Core on Arduino IDE.
    1. Open Arduino IDE, click the File on the left corner and choose "Preferences".
    2. Add the following link in "Additional boards manager URLs", then click OK.
    3. https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
    4. Click on Tools -> Board -> Board Manager -> Search for pico, and install Raspberry Pi Pico/RP2040 by Earle F. Philhower

To flash the firmware onto the RP2040 Smartwatch, follow these steps:

  1. Hold down the Reset button.
  2. While holding down Reset, also hold down the Boot button.
  3. Release the Reset button.

This will put the device into firmware flash mode, allowing you to upload the desired firmware.

Additional Steps

To customize the firmware, follow these additional steps:

  1. Go to the GitHub repository.
  2. Download the code from the repository.
  3. Locate the file named RP2040-Touch-LCD-1.28.ino.
  4. Add a new file named myApp.h in the same directory as RP2040-Touch-LCD-1.28.ino. This is where you would add the code for your app.
Firmware Files
  • UF2 File (RP2040): The UF2 file for the RP2040 microcontroller can be found in the Releases section. This file is used for flashing the RP2040.
  • Seeed.ino File (Seeed Xiao): This file is used for flashing the Seeed Xiao and can be found in the repository.

Apps

V1 Apps - Deprecated

Details on Version 1 Applications

Sample Layout

#ifndef MYAPP_H
#define MYAPP_H
extern bool inTransition;
extern bool pauseRender;
extern bool startup;
extern uint16_t deviceMainColorTheme;
extern uint16_t deviceSecondColorTheme;
extern uint16_t deviceThirdColorTheme;
extern UWORD* BlackImage;
#endif

void myApp() {
  if(startup){
    startup = false;
    //startup things
  }

  if (inTransition == false) {
    if (pauseRender == false) {
      LCD_1IN28_DisplayWindows(0, 0, 240, 240, BlackImage);
    }
  }
}
Overview of Version 1 Applications

In this example, the function myApp is called for each frame.

To ensure proper rendering of an application, all apps must adhere to the following structure:

if (inTransition == false) {
  if (pauseRender == false) {
    LCD_1IN28_DisplayWindows(0, 0, 240, 240, BlackImage);
  }
}

Application Launch

if(startup){
  startup = false;
  //startup things
}
Initialization During Launch

When the application is opened, a specific variable is set to true.

This initialization process occurs every time the application is launched, even if it is already running in the background.

Updates

void myApp() {
  //CODE HERE
}

Updates are called once per frame in the function with the same name as your app.

V2 Apps

Details on Version 2 Applications

Sample Layout

#ifndef MYAPP_H //Must Include Section:
#define MYAPP_H
#include "App.h"
extern bool inTransition;extern bool pauseRender;extern bool watchSwipe;extern bool otherSwipe;extern UWORD* BlackImage; //Other
extern std::list appPermissions;extern std::string appTitle;extern std::string appDesc;extern std::string appPub;extern std::string appOthInfo;extern float appVersion;extern int appDatePub;extern std::string appHash; //Config
extern uint16_t deviceMainColorTheme;extern uint16_t deviceSecondColorTheme;extern uint16_t deviceThirdColorTheme; // Device Customization Settings [Optional]

//Extra Libs
#include 

// Settings:
extern bool systemDisplayUpdates; // Default = True

class myApp : public App {
public:
  void sysConfig() override {                    // Triggers randomly when device needs info
    appPermissions = {};                                   //Permissions app needs in order to warn user about apps
    //Specify App Settings here

    appTitle = "Test App";                                 // Title
    appDesc = "Testing Reasons";                           // Description
    appPub = "Kaiyo";                                      // Publisher
    appOthInfo = "Website: kaiyo.dev";                     // Other Info
    appVersion = 1.0;                                      // Version
    appDatePub = 1716084259;                               // Unix Timestamp
    appHash = "6017612eb90d5b39b27a12e756a61be852971e8e";  // More Unique Identifier (SHA1)
  }

  void launch() override {  // Triggers upon first time opening app
    // ...
  }

  void update() override {  // Triggers on each frame
    Paint_DrawRectangle(0, 0, 100, 100, RED, DOT_PIXEL_1X1, DRAW_FILL_FULL);
  }
};

#endif

System Configuration

Available System Configuration Options
bool systemDisplayUpdates; //Default = True
Inclusion and Setting Configuration

At the beginning of the code, include extern followed by the type and variable name.

Setting the configuration option is done within void sysConfig() and can be assigned an appropriate value.

Application Information

Details about the Application
appTitle = "Test App";                                 // Title
appDesc = "Testing Reasons";                           // Description
appPub = "Kaiyo";                                      // Publisher
appOthInfo = "Website: kaiyo.dev";                     // Other Info
appVersion = 1.0;                                      // Version
appDatePub = 1716084259;                               // Unix Timestamp
appHash = "6017612eb90d5b39b27a12e756a61be852971e8e";  // More Unique Identifier (SHA1)

Application information such as Title, Publisher, and other details is set here. This information is used to identify the application and to help establish its credibility.

The appHash is a hash of all the code, used to uniquely identify different versions of the application more precisely than the version number.

Permissions

Currently, there are no specified permissions.

Application Launch

void launch() override {  // Triggers upon first time opening app
  // ...
}

This function is called upon the initial opening of the application and only triggers if the application is not already running in the background.

Update Function

void update() override {
  Paint_DrawRectangle(0, 0, 100, 100, RED, DOT_PIXEL_1X1, DRAW_FILL_FULL);
}

This function is called on each frame. It does not require manual rendering unless systemDisplayUpdates is set to false.

To render manually, similar to Version 1 applications, you can use the following code after setting systemDisplayUpdates to false:

if (inTransition == false) {
  if (pauseRender == false) {
    LCD_1IN28_DisplayWindows(0, 0, 240, 240, BlackImage);
  }
}

Like such:

void update() override {
  Paint_DrawRectangle(0, 0, 100, 100, RED, DOT_PIXEL_1X1, DRAW_FILL_FULL);

  if (inTransition == false) {
    if (pauseRender == false) {
      LCD_1IN28_DisplayWindows(0, 0, 240, 240, BlackImage);
    }
  }
}

Registering an App

In RP2040-Touch-LCD-1.28.ino include your app at the start of the code.

//Apps V1
#include "flappyBird.h"
#include "CountSteps.h"
//...

//Apps V2
#include "appVersTwo.h"
#include "appVersTwoTestTwo.h"
//...

#include "myApp.h" //ADD YOUR APP

Then find the following lines in setup

//Apps V1
apps["FindMyPhone"] = &findMyPhone;
apps["Alarms"] = &alarms;
//...

//Apps V2
apps["appVersTwo"] = &appV2;
appsV2["appVersTwo"] = new appVersTwo();
apps["appVersTwoTestTwo"] = &appV2;
appsV2["appVersTwoTestTwo"] = new appVersTwoTestTwo();
//...

and add your app

//Apps V1
apps["FindMyPhone"] = &findMyPhone;
apps["Alarms"] = &alarms;
//...

//Apps V2
apps["appVersTwo"] = &appV2;
appsV2["appVersTwo"] = new appVersTwo();
apps["appVersTwoTestTwo"] = &appV2;
appsV2["appVersTwoTestTwo"] = new appVersTwoTestTwo();
//...

apps["myApp"] = &appV2;
appsV2["myApp"] = new myApp();

Shapes

Rectangle

Syntax:

void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill);
Rectangle Arguments
  • UWORD Xstart, Ystart: Starting position of the rectangle.
  • UWORD Xend, Yend: Ending position of the rectangle.
  • UWORD Color: Color of the rectangle (e.g., RED, GREEN).
  • DOT_PIXEL Line_width: Thickness of the rectangle's border.
  • DRAW_FILL Draw_Fill: Specifies whether the rectangle is filled or empty.
Example
Paint_DrawRectangle(0, 0, 100, 100, RED, DOT_PIXEL_5X5, DRAW_FILL_EMPTY);

Transparent Rectangles

Syntax:

void Paint_DrawRectangleTrans(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, uint8_t transparency, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill);
Transparent Rectangle Arguments
  • UWORD Xstart, Ystart: Starting position of the rectangle.
  • UWORD Xend, Yend: Ending position of the rectangle.
  • uint8_t transparency: Transparency level (0 to 100).
  • DOT_PIXEL Line_width: Thickness of the rectangle's border.
  • DRAW_FILL Draw_Fill: Specifies whether the rectangle is filled or empty.

Transparency is a value from 0 to 100 and affects the shade or tint of what is below the rectangle.

Example
Paint_DrawRectangleTrans(0, 0, 100, 100, 50, DOT_PIXEL_1X1, DRAW_FILL_FULL);

Circle

Syntax:

void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill);
Circle Arguments
  • UWORD X_Center, Y_Center: Center position of the circle.
  • UWORD Radius: Radius of the circle.
  • UWORD Color: Color of the circle (e.g., RED, GREEN).
  • DOT_PIXEL Line_width: Thickness of the circle's border.
  • DRAW_FILL Draw_Fill: Specifies whether the circle is filled or empty.

Drawing circles requires more CPU time compared to other shapes.

Example
Paint_DrawCircle(120, 120, 50, RED, DOT_PIXEL_1X1, DRAW_FILL_FULL);

Transparent Circles

Syntax:

void Paint_DrawCircleTrans(UWORD Xcenter, UWORD Ycenter, UWORD Radius, uint8_t transparency, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill);
Transparent Circle Arguments
  • UWORD Xcenter, Ycenter: Center position of the circle.
  • UWORD Radius: Radius of the circle.
  • uint8_t transparency: Transparency level (0 to 100).
  • DOT_PIXEL Line_width: Thickness of the circle's border.
  • DRAW_FILL Draw_Fill: Specifies whether the circle is filled or empty.

Line

Syntax:

void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, LINE_STYLE Line_Style);
Line Arguments
  • UWORD Xstart, Ystart: Starting position of the line.
  • UWORD Xend, Yend: Ending position of the line.
  • UWORD Color: Color of the line (e.g., RED, GREEN).
  • DOT_PIXEL Line_width: Thickness of the line.
  • LINE_STYLE Line_Style: Style of the line (e.g., LINE_STYLE_SOLID).
Example
Paint_DrawLine(120, 120, 240, 240, 0x009688, DOT_PIXEL_2X2, LINE_STYLE_SOLID);

Point

Syntax:

void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_FillWay);
Point Arguments
  • UWORD Xpoint, Ypoint: Position of the point.
  • UWORD Color: Color of the point (e.g., RED, GREEN).
  • DOT_PIXEL Dot_Pixel: Size of the point.
  • DOT_STYLE Dot_FillWay: Style of the point (e.g., filled or not filled).
Example
Paint_DrawPoint(50, 50, BLUE, DOT_PIXEL_3X3, DOT_STYLE_FILL);

Inputs

Buttons

Syntax:

bool button(int x, int y, const char *text, sFONT *Font, UWORD Color_Foreground, UWORD Color_Background, int size);
Button Arguments
  • int x, y: The position coordinates of the button.
  • const char *text: The text displayed on the button.
  • sFONT *Font: The font used for the button text.
  • UWORD Color_Foreground: The color of the button text.
  • UWORD Color_Background: The color of the button background.
  • int size: The size of the button, where 0 represents small and 1 represents large (dynamic scaling will be available later).
Example
button(10, 20, "Click Me", &Font16, WHITE, BLUE, 1);

Checkboxes

Syntax:

bool checkBox(int x, int y, UWORD OutlineColor, UWORD XColor, std::string id, int size);
Checkbox Arguments
  • int x, y: The position coordinates of the checkbox.
  • UWORD OutlineColor: The color of the checkbox outline when unchecked.
  • UWORD XColor: The color of the checkmark when the checkbox is checked.
  • std::string id: A unique identifier for the checkbox.
  • int size: The size of the checkbox.
Example
checkBox(30, 40, BLACK, GREEN, "checkbox1", 30);

Radio Groups

Syntax:

bool radio(int x, int y, UWORD OutlineColor, UWORD XColor, std::string id, int size, std::string group);
Radio Button Arguments
  • int x, y: The position coordinates of the radio button.
  • UWORD OutlineColor: The base color of the radio button when not selected.
  • UWORD XColor: The color of the radio button when selected.
  • std::string id: A unique identifier for the radio button.
  • int size: The size of the radio button.
  • std::string group: The group name to which the radio button belongs.
Example
radio(50, 60, RED, BLUE, "radio1", 30, "group1");

Sliders

Syntax:

int slider(int x, int y, UWORD OutlineColor, UWORD InsideColor, std::string id, int width, int height);
Slider Arguments
  • int x, y: The position coordinates of the slider.
  • UWORD OutlineColor: The base color of the slider.
  • UWORD InsideColor: The color of the slider track that indicates progress.
  • std::string id: A unique identifier for the slider.
  • int width, height: The dimensions of the slider.
Example
slider(50, 150, GRAY, PURPLE, "slider1", 120, 20);

Switches

Syntax:

bool toggle(int x, int y, UWORD OutlineColor, UWORD ToggleColor, std::string id, int size);

Switches, also known as toggles, are used to represent on/off states.

Switch Arguments
  • int x, y: The position coordinates of the switch.
  • UWORD OutlineColor: The base color of the switch when it is off.
  • UWORD ToggleColor: The color of the switch when it is on.
  • std::string id: A unique identifier for the switch.
  • int size: The size of the switch.
Example
toggle(50, 10, GRAY, BLUE, "switch1", 30);

Other Visuals

Swipe

Syntax:

bool swipe(std::string dir, int thresh);

Returns whether or not the user swiped in a specified direction.

Swipe Arguments
  • std::string dir: The direction of the swipe. Valid values are "up", "down", "left", or "right". It indicates the direction your finger moves towards.
  • int thresh: The threshold value (0 to 240) that the user must swipe past to trigger the swipe event.
Example
if (swipe("down", 70)) {
  openApp("main", "UD", Touch_CTS816.y_point);
}

Scroll

Syntax:

std::list scrollFunction(int numberOfItems, std::string itemHeaders[], bool visible);

Manages a scroll bar for navigating through a list of items.

Scroll Arguments
  • int numberOfItems: The number of items to scroll through. Only needed if itemHeaders is used.
  • std::string itemHeaders[]: A list of names of items. Currently deprecated and may not function as expected, but intended for future use.
  • bool visible: Whether or not to show the circular scroll bar.
Returned Values

The returned values are a list of integers including:

  • scrollY: The scrollSlider value.
  • scrolling: 0 or 1, indicating if the user is scrolling or not.
  • hoverObject: Partially deprecated, but indicates the object the scroll wheel would be hovering over.
Example
std::list scrollValues = scrollFunction(10, itemHeaders, true);

Snack Bar

Syntax:

void snackBar(std::string text, UWORD BGC, UWORD TXCOLOR);

A snack bar is a small popup at the bottom of the screen displaying information.

Snack Bar Arguments
  • std::string text: The message to display in the snack bar.
  • UWORD BGC: The background color of the snack bar.
  • UWORD TXCOLOR: The text color of the snack bar.
Example
snackBar("Operation Successful", WHITE, BLACK);
Rendering the Snack Bar

Note: V2 apps auto render snack bar if systemDisplayUpdates is true.


In your code in order to render the snackBar you must include

renderSnack();

Example
renderSnack();
if (inTransition == false) {
  if (pauseRender == false) {
    LCD_1IN28_DisplayWindows(0, 0, 240, 240, BlackImage);
  }
}

Open Another App

Syntax:

void openApp(std::string app, std::string dir, int start);

Opens another application with optional animation.

openApp Arguments
  • std::string app: The name of the app to open.
  • std::string dir: The direction of the animation. Leave empty ("") if no animation is needed. Valid directions are "UD" (Up to Down), "DU" (Down to Up), "LR" (Left to Right), "RL" (Right to Left), and "RAND" (random pixels).
  • int start: The starting point for the animation. For "RL" and "LR", use 0 or 240 (from the edge) or Touch_CTS816.x_point (from the finger). For "DU" and "UD", use Touch_CTS816.y_point. If "RAND", use 0.

Note: Opening another app cannot be called in setup/startup of an App

Example
openApp("main", "RAND", 0);

Touch / Tap

Detects touch or tap events on the screen.

Touch/Tap Variables
  • Touch_CTS816.x_point: The x-coordinate of the touch point.
  • Touch_CTS816.y_point: The y-coordinate of the touch point.
  • extern bool tap: A boolean variable that is set to true when a tap is detected.
Usage

Use these variables and the tap boolean to detect and respond to touch events. Here is an example:

if (tap) {
    int x = Touch_CTS816.x_point;
    int y = Touch_CTS816.y_point;
    // Handle the tap event at (x, y)
}

Keyboard

To access the keyboard, you need to open the keyboard app:

openApp("keyboard", "RAND", 0);

When the user presses enter, the keyboardData variable will change from an empty string ("") to the input data. The keyboardData is a std::string. After processing the data, it is recommended to reset keyboardData to "" to prevent potential looping issues.

Keyboard Variables
  • std::string keyboardData: Stores the data entered by the user. Reset to "" after processing.
  • std::string keyboardTyped: Stores what is currently typed by the user, Resets after pressing Return.

Include the following extern declarations if needed:

extern std::string keyboardData;
extern std::string keyboardTyped;
Usage Example

Use the keyboardData variable to handle keyboard input:

if (keyboardData != "") {
    // Process the data
    std::string input = keyboardData;
    // Reset keyboardData to prevent looping
    keyboardData = "";
}

Fonts

The following fonts are available for use. Reference them by their variable names:

  • Font8
  • Font12
  • Font16
  • Font20
  • Font24

Colors

Here are the color codes available for use. Use these constants for consistency:

  • WHITE: 0xFFFF
  • BLACK: 0x0000
  • BLUE: 0x001F
  • BRED: 0xF81F
  • GRED: 0xFFE0
  • GBLUE: 0x07FF
  • RED: 0xF800
  • MAGENTA: 0xF81F
  • PINK: 0xfdff
  • GREEN: 0x07E0
  • CYAN: 0x7FFF
  • YELLOW: 0xFFE0
  • GOOD_YELLOW: 0xff6a
  • BROWN: 0xBC40
  • BRRED: 0xFC07
  • GRAY: 0x8430
  • DARKGRAY: 0x39c7
  • LIGHT_GRAY: 0xbdd7
  • ORANGE: 0xfc60
  • LIGHTPURPLE: 0xb5bd
  • LIGHTBLUE: 0xb69d
  • PURPLE: 0xa01a
  • SKYBLUE: 0x03ba
  • LIMEY: 0xafe0
  • AQUAGREEN: 0x07f1
  • DARKGREEN: 0x02a6
  • MIDGREEN: 0x050b
  • IJUSTWANTGRASS: 0x3cee
  • IGIVEUP: 0x4c29
  • MAROON: 0x40e5
  • BRIGHTPURPLE: 0x9274
  • PEACH: 0xf637
  • LIGHTBROWN: 0xbbed
  • DARKBROWN: 0x4963
  • REDTAN: 0xc42f
  • TAN: 0xf6ba
  • FRIEDYELLOW: 0xff96
  • YELLOWORANGE: 0xf6b2
  • PAPERGRAY: 0xb596
  • HOTPINK: 0xe1b1

DRAW_FILL

This attribute determines whether the graphical element is rendered as a solid fill or just an outline. It specifies the fill style for shapes such as rectangles, circles, and other polygons.

  • DRAW_FILL_FULL: The shape will be completely filled with the specified color.
  • DRAW_FILL_EMPTY: Only the outline of the shape will be drawn, leaving the inside empty.

LINE_STYLE

This parameter defines the style of lines used in drawing operations, indicating whether the line should be solid or dashed. This is applicable for drawing borders, shapes, and other line-based elements.

  • LINE_STYLE_SOLID: The line will be drawn as a continuous, unbroken line.
  • LINE_STYLE_DOTTED: The line will be rendered as a series of dots or short dashes.

DOT_PIXEL

This attribute defines the size of the point or pixel, typically used for outlining or marking specific coordinates on the display. The size can vary, allowing for different levels of visibility and emphasis.

  • DOT_PIXEL_1X1: A single pixel dot.
  • DOT_PIXEL_2X2: A dot with a 2x2 pixel size.
  • DOT_PIXEL_3X3: A dot with a 3x3 pixel size.
  • DOT_PIXEL_4X4: A dot with a 4x4 pixel size.
  • DOT_PIXEL_5X5: A dot with a 5x5 pixel size.
  • DOT_PIXEL_6X6: A dot with a 6x6 pixel size.
  • DOT_PIXEL_7X7: A dot with a 7x7 pixel size.
  • DOT_PIXEL_8X8: A dot with a 8x8 pixel size.

DOT_STYLE

This attribute specifies the fill style for individual points or pixels, often used in rendering operations that involve plotting points or drawing pixel-based shapes.

  • DOT_FILL_AROUND: The point will be filled in a circular manner around the specified coordinates.
  • DOT_FILL_RIGHTUP: I have no idea.

Networking

This section covers basic Bluetooth Low Energy (BTLE) and internet actions. Note that an active BTLE connection must be established with a mobile device using the companion app.

Note: Any data being sent between the device and a Mobile Smartphone has a max of roughly 16Bytes

Internet GET Request

Syntax:

std::string internet_get(std::string url);

This function sends an internet GET request to https://ptsv3.com and returns the response as a string.

GET Request Arguments
  • url: A string representing the endpoint for the GET request. Obtain a unique "toilet" URL at ptsv3.com. The request URL will be formatted as https://ptsv3.com/t/<toilet>/, where another service must handle the requests.
Example
std::string data = internet_get("myToilet");

Internet POST Request

Syntax:

void internet_post(std::string toilet, std::string data);

This function sends an internet POST request to https://ptsv3.com.

POST Request Arguments
  • toilet: A string representing the endpoint for the POST request. Obtain a unique "toilet" URL at ptsv3.com. The request URL will be formatted as https://ptsv3.com/t/<toilet>/, where another service must handle the requests.
  • data: A string containing the data to be posted. The maximum amount varies but is generally limited.
Example
internet_post("myToilet", "DATA");

BTLE Disconnect

Syntax:

void btleDiscon();

This function disconnects the current BTLE connection from the connected device.

Example
btleDiscon();