Maker.io main logo

Mouse Painter: Emulate Mice with MakeCode

2024-11-19 | By Adafruit Industries

License: See Original Project Circuit Playground

Courtesy of Adafruit

Guide by John Park

Overview

 

drawing_1

Drawing beautiful curves and perfect circles with a mouse is hard! ‎It's been likened to trying to paint with a bar of soap. You can enlist ‎your Circuit Playground Express coded with MakeCode to be your ‎Mouse Painter assistant. Loaded with pre-programmed shapes, the ‎CPX can "click" your mouse buttons and move your cursor for you to ‎create gorgeous shape in your favorite digital paint program.‎

This guide will show you how to code it in MakeCode, and then you ‎can expand on your palette of available shapes to make your own ‎masterpiece.‎

Text editor powered by tinymce.‎

Code the Mouse Painter in MakeCode

painter_2

Getting Started with MakeCode

If you're new to MakeCode, head to this guide to get started. Once ‎you're familiar with MakeCode on your Circuit Playground Express, ‎return here.‎

makecode_3

Load the Code

Let's start by downloading the code so we can take a look at it in the ‎MakeCode editor, as well as load it on the Circuit Playground Express ‎to use it.‎

Load the code by heading to this share link. Then, click ‎the Edit button to open it into the MakeCode editor.‎

Alternately, you can download the .uf2 file linked below and import it ‎into MakeCode by dragging it onto the MakeCode browser window.‎

download_4

circuitplayground-Mouse_Painter.uf2‎

Let's have a look now at how it works.‎

Add Extension

For the CPX to act as a mouse emulator, we need to add the HID ‎Mouse (Human Interface Device) extension to MakeCode. First, click ‎on the Advanced button and then click Extensions.‎

Then, click on the mouse extension and it will be added to your ‎project.‎

You'll now see the Mouse category and associated blocks available.‎

You can now emulate three different things -- clicking the mouse ‎buttons, moving the mouse horizontally and vertically, and turning ‎the mouse wheel.‎

add_5

add_6

add_7

Mouse emulation can be used for more... nefarious uses, too! Check ‎out the Phantom Mouse Jiggler project to see how to prank ‎someone with a mysterious cursor that has a mind of its own.‎

Setup

NeoPixels

In the on start block we'll turn on a few NeoPixels as indicators. ‎These are the ones nearest the cap touch pads we'll be using to ‎adjust parameters later, such as radius and amplitude of our shapes.‎

Note how we use the HSV (hue, saturation, value) color model rather ‎than the default RGB (red, green, blue) for the three pixels that will ‎be changing color to indicate parameter values. The HSV model is ‎simpler to deal with when changing colors, as only a single number -‎‎- the hue -- needs to change in order to cycle through the color ‎wheel.‎

The magenta pixel at the bottom will be flipped between NeoPixel 4 ‎and 5 to indicate the position of the slide switch, and thus, which ‎shape set we're accessing with the A & B buttons.‎

setup_8

setup_9

Variables

We also set up a large number of different variables that are used ‎throughout the rest of the program. This is a convenient place to do ‎so, allowing you to tweak values in a single place as you experiment ‎with what shapes you like most!‎

Switch and Buttons

While Switch & Buttons would make a great title for an animated ‎buddy cop film about an unlikely crime fighting duo of a fast-talking ‎lizard (Switch) and a highly educated cat (Buttons), that's not what's ‎going on here. No, we are literally talking about the slide switch and ‎two momentary buttons on the CPX.‎

We'll use the switch to flip between two different sets of shapes that ‎can be drawn by toggling the style variable between 0 and 1. We'll ‎also flip the magenta NeoPixel to the corresponding position of the ‎physical switch.‎

When button A is pressed, we call either the sineWave function or ‎the cosineWave function, depending on the switch position.‎

Button B calls either the circle function or the diamond function.‎

‎ ‎buttons_10‎ ‎

Cap Touch

We can use the capacitive touch pads as inputs to adjust the ‎parameters of our drawn shapes. The A3 and A2 pads are used to ‎increase or decrease the radius variable that we'll use in a moment ‎when drawing the circle and diamond shapes.‎

When the on touch A3 click block runs, first we light the on-board ‎red LED, then we increment the radius variable by 5 * ‎the radScrnMlt variable. That variable was on we set in the on start loop, and it gives us a convenient place to multiply our radius ‎values broadly in case we use the mouse painter on a system with a ‎different screen resolution. I found that moving between computers ‎all of my shapes seemed too small on the larger resolution monitor, ‎so a quick tweak to the radScrnMlt is the ‎answer.‎

cap_11

cap_12

Next, we adjust the hue of the nearby NeoPixel 8. This changes ‎along with the change in the radius variable, and by using ‎the remainder of __ / 255 block, we can constrain all values to within ‎the 0-255 range of the hue parameter. In other words, the colors will ‎cycle as we increase the radius.‎

Then we turn off the red LED. This all happens very quickly, so the ‎LED appears to blink rapidly with each touch of the pad, a nice ‎indicator that the input has been received.‎

The A2 pad is used in the same way as A3, but to decrease the ‎radius instead.‎

The A4 and A6 pads will be used in much the same way, but instead ‎of incrementing values, they each cycle through an array of numbers ‎we created in the on start loop. This gives five different amplitudes ‎and five different wave periods to choose from when creating sine ‎waves and cosine waves.‎

Diamond Drawing

This one is the simplest one -- when the diamond function is called, ‎first, the mouse button is pressed. NOTE: there is a bug currently that ‎requires us to call the mouse button right when we want to click ‎the left mouse button.‎

Next, we move the mouse to the right on x and up on y. Rather than ‎hard-code a value, we use the radius variable (which we can change ‎by tapping the A3 pad) multiplied by the radScrnMlt number, ‎multiplied by positive 4 on x and negative 4 on y.‎

We then pause half a second to allow the brush to catch up, and ‎then repeat the process until we have drawn the diamond pattern.‎

Depending on brush tool settings, in some software, such as the ‎excellent, free Sketch.io Sketchpad, this will result in a rounded ‎diamond, while others, such as Photoshop, will create a straight ‎sided one.‎

Also note how different brush tip profiles will create interesting ‎angled/calligraphic effects. We can tap the A3 button to change the ‎radius for some variety as well.‎

drawing_13

drawing_14

drawing_15

drawing_16

drawing_17

Circles

Drawing a smooth circle can be very tricky by hand, particularly ‎when using a mouse instead of a pencil! Thankfully, we can use a ‎formula to draw one for us. Most drawing programs can create a ‎circle, sure, and you can then pick a color to outline it. But the ‎advantage to drawing it in real time is that we can use ‎angled/calligraphy brushes and other stamping/tip effects that only ‎work when the stroke is painted in real-time.‎

Many circle calculation formulas are for plotting the points in an ‎absolute set. We, however, need to calculate the relative offset of the ‎mouse position from step to step of the plotting process.‎

circles_18

circles_19

After looking at some online reference and consulting with the much ‎more mathematically competent Jan Goolsbey, here's the formula I ‎used in pseudocode, you can see the block implementation in ‎MakeCode in the image to the left:‎

Download File

Copy Code
theta = 0 // starting angle (in radians) and the variable that increases with each loop
lastX = (cos(theta) * radius) // a temporary variable that stores the previous X value; used to calculate the difference between the current position and the previous
lastY = (sin(theta) * radius)  // a temporary variable that stores the previous Y value; used to calculate the difference between the current position and the previous
step = 0.1  // amount in radians added to theta angle variable for each loop; "walks" around the circle in a clockwise direction
repeat until theta is less than or equal to ((2 * pi) + step) { // loops from the starting value of theta until it reaches a full circle plus one step (to close the circle completely)
    set x to (radius * (cos)theta)) // the cosine function produces a value between -1 and 1; multiplying by the radius scales the circle to the selected size
    set y to (radius * (sin)theta)) // the sine function...
    move mouse x to (x - lastX) // calculate the difference between the new position's absolute x value and the previous; move the mouse incrementally from the old position to the new position
    move mouse y to (y - lastY) // ... absolute y value ...
    pause (stepDelay / 2)ms // wait a while for the drawing application to respond to the mouse movement
    change theta by step // get ready to plot the next point on the circle by incrementing the theta angle value
    set lastX to x // record the new position's x value so it can be used as the previous value during the next loop cycle
    set lastY to y // ..... y value ...

Note: in order to use pi we can either approximate it as 3.14159 in the ‎Blocks mode, or head to JavaScript mode and use the built-in ‎constant 'Math.PI' See the reference for more ‎info: https://makecode.adafruit.com/blocks/math

Waves

A beautiful, undulating sine or cosine wave is another wonderful, yet ‎difficult-to-draw shape.‎

Our formula here is a bit more simple than the circle. We loop ‎through a certain number of times defined by the length variable ‎divided by the wavePeriod (width) variable, and do the following:‎

waves_20

waves_21

Download File

Copy Code
set x to wavePeriod // plots the first x position
set y to (amplitude * sin((index + 1) / 4))
move mouse.x to x
move mouse.y to y
pause the stepDelay amount // allow the brush to catch up to the cursor

By tapping the A4 and A6 pads on the CPX, the amplitude and wave ‎period may be adjusted respectively, thus creating different sine ‎wave patterns.‎

Currently, the style 1 mode with the slide switch in the right position ‎creates a cosine wave when the A button is pressed. It is very similar ‎to the sine wave -- for extra credit, what other shape could you ‎create instead?‎

Enjoy making your CPX Mouse Painter assisted digital art!‎

 

Text editor powered by tinymce.

制造商零件编号 3333
CIRCUIT PLAYGROUND EXPRESS
Adafruit Industries LLC
¥203.09
Details
Add all DigiKey Parts to Cart
TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum