Skip to main content

A simple Python API that interacts with Arduino devices for USB mouse and keyboard emulation.

Project description

<h1 id="pyduino-mk">PyDuino-MK</h1>
<p>A simple Python API that interacts (via serial communication) with Arduino devices for USB mouse and keyboard emulation. It is compatible with all Arduino devices (Leonardo, Micro, etc.) that support the Arduino Mouse/Keyboard libraries.</p>
<h1 id="features">Features</h1>
<ul>
<li>Simple Python 2.7 API</li>
<li>Absolute Mouse Positioning</li>
<li>Vanilla Arduino (w/o HID modifications)</li>
<li>Extended mouse and keyboard functions</li>
<li>Bezier curve mouse movement</li>
<li>Human-like keyboard typing</li>
</ul>
<h1 id="requirements">Requirements</h1>
<ul>
<li><a href="https://www.python.org/">Python 2.7.x</a> (does not currently work with Python 3.x)</li>
<li><a href="http://pyserial.sourceforge.net/">PySerial 2.7</a></li>
<li><a href="http://www.arduino.cc/en/Main/Software">Arduino IDE 1.6+</a></li>
<li>A compatible Arduino device</li>
</ul>
<h1 id="installation">Installation</h1>
<p>To install PyDuino-MK from the PyPI repository, run the following from a command line:</p>
<pre><code>pip install pyduino_mk
</code></pre><p>To install PyDuino-MK locally from the source directory, <code>cd</code> to the <code>python</code> directory containing <code>setup.py</code> and run:</p>
<pre><code>python setup.py build install
</code></pre><h1 id="setup">Setup</h1>
<ol>
<li>Plug your Arduino device into a computer via USB.</li>
<li><code>cd</code> to the <code>arduino</code> folder and open the <code>arduino.ino</code> file in the Arduino IDE.</li>
<li>Upload the sketch to the Arduino device.</li>
</ol>
<p>After the Arduino sketch has been uploaded, the Arduino device is now ready to accept serial messages from the Python API.</p>
<h1 id="usage">Usage</h1>
<p>To use PyDuino-MK, you must first import the Arduino-MK mouse/keyboard constants and the <code>Arduino</code> class encapsulating the Arduino commands. The mouse/keyboard constants are used to designate mouse buttons (i.e. <code>MOUSE_LEFT</code>, <code>MOUSE_RIGHT</code>) and keyboard keys (i.e. <code>F1</code>, <code>CTRL</code>, <code>INSERT</code>).</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> arduino_mk.constants <span class="hljs-keyword">import</span> *
<span class="hljs-keyword">from</span> arduino_mk <span class="hljs-keyword">import</span> Arduino
</code></pre>
<p>Instantiating the <code>Arduino</code> class is simple and easy.</p>
<pre><code class="lang-python">arduino = Arduino()
</code></pre>
<p>PyDuino-MK automatically detects and establishes a connection with the serial port that the Arduino device resides on. But if for any reason PyDuino-MK is unable to do so, a port can be explicitly provided as an optional parameter.</p>
<pre><code class="lang-python">arduino = Arduino(port=<span class="hljs-string">'COM5'</span>) <span class="hljs-comment"># Windows example</span>
</code></pre>
<pre><code class="lang-python">arduino = Arduino(port=<span class="hljs-string">'/dev/tty.usbmodemfa141'</span>) <span class="hljs-comment"># OSX example</span>
</code></pre>
<pre><code class="lang-python">arduino = Arduino(port=<span class="hljs-string">'/dev/ttyS2'</span>) <span class="hljs-comment"># Linux example</span>
</code></pre>
<h2 id="moving-the-mouse">Moving the Mouse</h2>
<p>PyDuino-MK provides a couple of modules for moving the mouse from one location to another. These modules take two arguments that represent a Cartesian coordinate. A coordinate system where the top-left of the screen represents the origin, <code>(0, 0)</code>, such that pixel coordinates increase in the right and down directions is assumed.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Calling this module will move the mouse from the current mouse position to </span>
<span class="hljs-comment"># a specified mouse position in a linear motion.</span>
arduino.move(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>)
</code></pre>
<p><img src="https://cloud.githubusercontent.com/assets/10904556/8178406/a19b4b9c-13c2-11e5-847e-b364a73d7445.gif" alt="besenham"></p>
<pre><code class="lang-python"><span class="hljs-comment"># Calling this module will move the mouse from the current mouse position to </span>
<span class="hljs-comment"># a specified mouse position in a cubic bezier motion. This module generates</span>
<span class="hljs-comment"># two random control points every call to vary the mouse paths.</span>
arduino.bezier_move(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>)
</code></pre>
<p><img src="https://cloud.githubusercontent.com/assets/10904556/8178416/b67bfdae-13c2-11e5-9a39-234df8d34675.gif" alt="bezier"></p>
<h2 id="clicking-the-mouse">Clicking the Mouse</h2>
<p>To click using the mouse, call the <code>click(button)</code> module. This module holds down the designated button for a random interval between 50-100ms and then releases the button to resemble a human-like click motion.</p>
<p>All of the click modules have the default parameter value, <code>MOUSE_LEFT</code>.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Left-click (2 ways)</span>
arduino.click()
arduino.click(MOUSE_LEFT)
</code></pre>
<pre><code class="lang-python"><span class="hljs-comment"># Middle-click</span>
arduino.click(MOUSE_MIDDLE)
</code></pre>
<pre><code class="lang-python"><span class="hljs-comment"># Right-click</span>
arduino.click(MOUSE_RIGHT)
</code></pre>
<p>To click without briefly holding the mouse button down, use the <code>fast_click(button)</code> module.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Auto-click very quickly</span>
<span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
arduino.fast_click(MOUSE_LEFT)
</code></pre>
<p>Use the <code>press(button)</code> and <code>release(button)</code> modules to hold down a mouse button and release it on command.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> time

<span class="hljs-comment"># Hold the right mouse button for 5 seconds</span>
arduino.press(MOUSE_RIGHT)
time.sleep(<span class="hljs-number">5</span>)
arduino.release(MOUSE_RIGHT)
</code></pre>
<pre><code class="lang-python"><span class="hljs-comment"># Drag the left mouse button to (500, 500)</span>
arduino.press()
arduino.bezier_move(<span class="hljs-number">500</span>, <span class="hljs-number">500</span>)
arduino.release()
</code></pre>
<h2 id="using-the-keyboard">Using the Keyboard</h2>
<p>To send a character or a string <strong>as a single keystroke</strong>, use the <code>write(character)</code> or <code>write(string)</code> module.</p>
<p>All keyboard modules will work <strong>only</strong> with ASCII characters that correspond to a key on the keyboard. With the exception of backspace, passing the ASCII codes for non-printable characters as arguments will produce undefined results.</p>
<p>However, modifier keys (such as Ctrl, Shift, Alt) may be passed as arguments. The modifier key constants are available and can be imported from <code>pyduino_mk.constants</code>. The names of the constants are almost identical to the <a href="http://www.arduino.cc/en/Reference/KeyboardModifiers">Arduino keyboard modifiers</a>. The only difference is that the constants omit the <code>KEY_</code> prefix. <code>KEY_LEFT_CTRL</code> becomes <code>LEFT_CTRL</code>, <code>KEY_CAPS_LOCK</code> becomes <code>CAPS_LOCK</code>, and so on.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Write the letter 'A' in two ways. A character or an integer ordinal </span>
<span class="hljs-comment"># representing the character can be used as an argument.</span>
arduino.write(<span class="hljs-string">'A'</span>)
arduino.write(<span class="hljs-number">65</span>)
</code></pre>
<pre><code class="lang-python"><span class="hljs-comment"># Write 'Hello world!' through the Arduino keyboard as a single keystroke.</span>
arduino.write(<span class="hljs-string">'Hello world!'</span>)
</code></pre>
<p>Like the mouse, keyboard keys can also be held down and released. The <code>press(button)</code> and <code>release(button)</code> modules are overloaded for the keyboard. <code>releaseAll()</code> can be used to release all keys that are held down.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Hit Ctrl+Alt+Delete</span>
arduino.press(LEFT_CTRL)
arduino.press(LEFT_ALT)
arduino.press(DELETE)
arduino.releaseAll()
</code></pre>
<h2 id="realistic-human-typing">Realistic Human Typing</h2>
<p>Instead of writing messages as a single keystroke, messages may also be sent as a series of keystrokes. One of the extended keyboard functionality provided by PyDuino-MK is human typing emulation. This is available through the <code>type(string)</code> module. By default, the module will type at a rate of 80 wpm at 96% accuracy. If mistakes occur, the Arduino will pause for a brief moment and correct the mistake. Mistakes may be disabled for 100% accuracy if desired.</p>
<pre><code class="lang-python"><span class="hljs-comment"># 80 wpm with 85% accuracy</span>
arduino.type(<span class="hljs-string">'https://github.com/nelsontran/PyDuino-MK/'</span>, accuracy=<span class="hljs-number">85</span>)
</code></pre>
<p><img src="https://cloud.githubusercontent.com/assets/10904556/8180364/ffa5fd22-13d1-11e5-9b7b-0b76537b862f.gif" alt="typing"></p>
<h3 id="optional-parameters">Optional parameters</h3>
<ul>
<li><code>wpm</code> (int) - words per minute (assuming 5 characters per word) <strong>without</strong> taking mistakes into account.</li>
<li><code>mistakes</code> (bool) - True/False value that determines whether to make mistakes or not.</li>
<li><code>accuracy</code> (int) - Value between 1 and 100, representing a percentage, that determines typing accuracy.</li>
</ul>
<h1 id="notes">Notes</h1>
<p>Keep in mind that all of the Arduino modules are blocking until the Arduino device has completed the action. For example, calling <code>move(destination)</code> will cause the Python script to hang until the Arduino has finished moving the cursor to the destination. If you call <code>type()</code> with a long message and a slow WPM with low accuracy, expect to wait a while for the call to finish.</p>
<h1 id="license">License</h1>
<p>PyDuino-MK is licensed under the MIT License (see <code>LICENSE</code> for details).</p>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyduino_mk-0.0.2.zip (7.9 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page