cordovarduino

Want a module for your Arduino board that provides:

  • Power
  • High-res Touch Interface
  • Storage
  • AND connectivity? (WiFi + 3G + Bluetooth)

Hey, why not just use your Android phone/tablet?

This Cordova/Phonegap plugin allows two-way serial communication using USB On-The-Go (OTG) from your Android device to your Arduino board or other USB-powered serial IO device.

And that means that ability to give your Arduino project a mobile app (web-view) interface as well as powering it using the rechargeable battery on your phone!

Install it

From the root folder of your cordova project, run :

cordova plugin add cordovarduino

How to use it

Your first need to understand how to create and upload a simple Cordova Project. Here is some info on how to get started with Cordova on Android, and here is a simple Cordova plugin you can use to get familiar with the plugin system.

The plugin API for this behaves as follows:

Because you're polite, first request the permission to use the serial port to the system:

serial.requestPermission(function success(), function error());

You can now open the serial port:

serial.open(opts, function success(), function error());

opts is a JSON object with the following properties:

  • baudRate: defaults to 9600
  • dataBits: defaults to 8
  • stopBits: defaults to 1
  • parity: defaults to 0
  • dtr: defaults to false (it may be needed to be true for some arduino)
  • rts: defaults to false (it may be needed to be true for some modules, including the monkeyboard dab module)
  • sleepOnPause: defaults to true. If false, the the OTG port will remain open when the app goes to the background (or the screen turns off). Otherwise, the port with automatically close, and resume once the app is brought back to foreground.

You're now able to read and write:

serial.write(data, function success(), function error());
serial.read(function success(buffer), function error());

data is the string representation to be written to the serial port. buffer is a JavaScript ArrayBuffer containing the data that was just read.

Apart from using serial.write, you can also use serial.writeHex to have an easy way to work with RS232 protocol driven hardware from your javascript by using hex-strings.

In a nutshell, serial.writeHex('ff') would write just a single byte where serial.write('ff') would let java write 2 bytes to the serial port.

Apart from that, serial.writeHex works the same way as serial.write does.

Register a callback that will be invoked when the driver reads incoming data from your serial device. The success callback function will recieve an ArrayBuffer filled with the data read from serial:

serial.registerReadCallback(
    function success(data){
        var view = new Uint8Array(data);
        console.log(view);
    },
    function error(){
        new Error("Failed to register read callback");
    });

And finally close the port:

serial.close(function success(), function error())

A Simple Example

A callback-ish example.

var errorCallback = function(message) {
    alert('Error: ' + message);
};

serial.requestPermission(
    function(successMessage) {
        serial.open(
            {baudRate: 9600},
            function(successMessage) {
                serial.write(
                    '1',
                    function(successMessage) {
                        alert(successMessage);
                    },
                    errorCallback
                );
            },
            errorCallback
        );
    },
    errorCallback
);

A Complete Example

Here is your index.html:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Hello World</title>
    </head>
    <body>
        <div class="app">
            <h1>Potentiometer value</h1>
            <p>Value <span id="pot">...</span></p>
            <p id="delta">...</p>
            <button id="on">On</button>
            <button id="off">Off</button>
        </div>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>
</html>

Here is the index.js file:

var app = {
    initialize: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    onDeviceReady: function() {
        var potText = document.getElementById('pot');
        var delta = document.getElementById('delta');
        var on = document.getElementById('on');
        var off = document.getElementById('off');
        var open = false;
        var str = '';
        var lastRead = new Date();

        var errorCallback = function(message) {
            alert('Error: ' + message);
        };
        // request permission first
        serial.requestPermission(
            // if user grants permission
            function(successMessage) {
                // open serial port
                serial.open(
                    {baudRate: 9600},
                    // if port is succesfuly opened
                    function(successMessage) {
                        open = true;
                        // register the read callback
                        serial.registerReadCallback(
                            function success(data){
                                // decode the received message
                                var view = new Uint8Array(data);
                                if(view.length >= 1) {
                                    for(var i=0; i < view.length; i++) {
                                        // if we received a \n, the message is complete, display it
                                        if(view[i] == 13) {
                                            // check if the read rate correspond to the arduino serial print rate
                                            var now = new Date();
                                            delta.innerText = now - lastRead;
                                            lastRead = now;
                                            // display the message
                                            var value = parseInt(str);
                                            pot.innerText = value;
                                            str = '';
                                        }
                                        // if not, concatenate with the begening of the message
                                        else {
                                            var temp_str = String.fromCharCode(view[i]);
                                            var str_esc = escape(temp_str);
                                            str += unescape(str_esc);
                                        }
                                    }
                                }
                            },
                            // error attaching the callback
                            errorCallback
                        );
                    },
                    // error opening the port
                    errorCallback
                );
            },
            // user does not grant permission
            errorCallback
        );

        on.onclick = function() {
            console.log('click');
            if (open) serial.write('1');
        };
        off.onclick = function() {
            if (open) serial.write('0');
        }
    }
};

app.initialize();

And here is your Arduino project .ino file, with a potentiometer on A0 and a led on 13:

#define POT A0
#define LED 13

unsigned long previousMillis;
int interval = 50;

void setup() {
    Serial.begin(9600);
    pinMode(POT, INPUT);
    pinMode(LED, OUTPUT);
}

void loop() {
    if (Serial.available() > 0) {
        char i = Serial.read();
        switch (i) {
            case '0':
                digitalWrite(LED, LOW);
                break;
            case '1':
                digitalWrite(LED, HIGH);
                break;
        }
    }
    if (millis() - previousMillis >= interval) {
        previousMillis = millis();
        int value = analogRead(POT);
        Serial.println(value);
    }
}

Your Device is not (yet) known?

Thanks to usb-serial-for-android library, you can communicate with CDC, FTDI, Arduino and other devices.

Your device might not be listed over at https://github.com/mik3y/usb-serial-for-android . If you know your devices VID (Vendor ID) and PID (Product ID) you could however try

serial.requestPermission({vid: '1d50', pid: '607d'}, function success(), function error()); //hex strings
or
serial.requestPermission({vid: 7504, pid: 24701}, function success(), function error()); //integers

You can also choose the driver to use. Options are:

  • CdcAcmSerialDriver
  • Ch34xSerialDriver
  • Cp21xxSerialDriver
  • FtdiSerialDriver
  • ProlificSerialDriver

It defaults to CdcAcmSerialDriver if empty or not one of these (please feel free to add a PR to support more).

serial.requestPermission({
        vid: '1d50',
        pid: '607d',
        driver: 'FtdiSerialDriver' // or any other
    },
    function success(),
    function error()
);

You can find your devices VID and PID on linux or android using "lsusb" (returning VID:PID in hex) or by looking at your dmesg log.

Change log

2015.10: Ed. Lafargue: Implemented "sleepOnPause" flag in the 'open' options to prevent closing the OTG port when app goes to background.

2014.08: Zevero: Option to find device by VID and PID, that let you use "unrecognized" devices.

2014.07: Hendrik Maus: Implemented writeHex for working with RS232 protocol, i.e. javascript can now pass "ff", java turns it into a 1 byte array and writes to the serial port - naturally, java, and the existing write method here, would create a 2 byte array from the input string.

2014.04: Derek K: Implemented registerReadCallback for evented reading and Android onPause/onResume

2014.03: Ed. Lafargue: Implemented read(). The success callback returns a Javascript ArrayBuffer which is the best way to handle binary data in Javascript. It is straightforward to convert this to a string if required - a utility function could be implemented in this plugin.

2013.11: Xavier Seignard: First implementation



cordovarduino

想要为您的Arduino板提供:

的模块
  • 电源
  • 高分辨率触摸界面
  • 存储
  • 和连接? (WiFi + 3G +蓝牙)

嘿,为什么不使用你的Android手机/平板电脑?

此Cordova / Phonegap插件允许使用Android设备上的On-The-Go(OTG)到Arduino板或其他USB供电的串行IO设备进行双向串行通信。 p> 这意味着,您可以通过手机上的充电电池为您的Arduino项目提供移动应用程序(网络浏览)界面以及为其供电。

安装

从您的cordova项目的根文件夹运行:

cordova plugin add cordovarduino

如何使用它

您首先需要了解如何创建和上传一个简单的Cordova项目。以下是有关Android上的Cordova的如何开始的信息,这是一个简单的Cordova插件,您可以使用它来熟悉插件系统。

此插件API的行为如下:

由于您很有礼貌,请先向系统请求使用串行端口的权限:

serial.requestPermission(function success(), function error());

现在可以打开串行端口:

serial.open(opts, function success(), function error());

opts 是具有以下属性的JSON对象:

  • baudRate:默认为9600
  • dataBits:默认为8
  • stopBits:默认为1
  • 奇偶校验:默认为0
  • dtr:默认为false(某些arduino可能需要为true)
  • rts:默认为false(某些模块可能需要使用,包括monkeyboard dab模块)
  • sleepOnPause:默认为true。如果为false,当应用程序进入后台(或屏幕关闭)时,OTG端口将保持打开状态。否则,端口将自动关闭,并将应用程序恢复到前台后恢复。

您现在可以读写:

serial.write(data, function success(), function error());
serial.read(function success(buffer), function error());

data 是要写入串行端口的字符串表示形式。 buffer 是一个包含刚刚读取的数据的JavaScript ArrayBuffer。

除了使用 serial.write 之外,您还可以使用 serial.writeHex 轻松地使用 RS232协议驱动的硬件通过使用十六进制字符串从您的javascript。

简单来说, serial.writeHex(’ff’)将只写一个字节,其中 serial.write(’ff’)将让java写入2个字节到串行端口。

除此之外, serial.writeHex 的工作方式与 serial.write 相同。

注册当驱动程序从串行设备读取传入数据时将被调用的回调。成功回调函数将收到一个填充了从串行数据读取的数据的ArrayBuffer:

serial.registerReadCallback(
    function success(data){
        var view = new Uint8Array(data);
        console.log(view);
    },
    function error(){
        new Error("Failed to register read callback");
    });

最后关闭端口:

serial.close(function success(), function error())

一个简单的例子

一个callback-ish示例。

var errorCallback = function(message) {
    alert('Error: ' + message);
};

serial.requestPermission( function(successMessage) { serial.open( {baudRate: 9600}, function(successMessage) { serial.write( '1', function(successMessage) { alert(successMessage); }, errorCallback ); }, errorCallback ); }, errorCallback );

一个完整的例子

这是您的 index.html

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Hello World</title>
    </head>
    <body>
        <div class="app">
            <h1>Potentiometer value</h1>
            <p>Value <span id="pot">…</span></p>
            <p id="delta">…</p>
            <button id="on">On</button>
            <button id="off">Off</button>
        </div>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>
</html>

这是 index.js 文件:

var app = {
    initialize: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    onDeviceReady: function() {
        var potText = document.getElementById('pot');
        var delta = document.getElementById('delta');
        var on = document.getElementById('on');
        var off = document.getElementById('off');
        var open = false;
        var str = '';
        var lastRead = new Date();

    <span class="pl-k">var</span> <span class="pl-en">errorCallback</span> <span class="pl-k">=</span> <span class="pl-k">function</span>(<span class="pl-smi">message</span>) {
        <span class="pl-en">alert</span>(<span class="pl-s"><span class="pl-pds">&#39;</span>Error: <span class="pl-pds">&#39;</span></span> <span class="pl-k">+</span> message);
    };
    <span class="pl-c"><span class="pl-c">//</span> request permission first</span>
    <span class="pl-smi">serial</span>.<span class="pl-en">requestPermission</span>(
        <span class="pl-c"><span class="pl-c">//</span> if user grants permission</span>
        <span class="pl-k">function</span>(<span class="pl-smi">successMessage</span>) {
            <span class="pl-c"><span class="pl-c">//</span> open serial port</span>
            <span class="pl-smi">serial</span>.<span class="pl-c1">open</span>(
                {baudRate<span class="pl-k">:</span> <span class="pl-c1">9600</span>},
                <span class="pl-c"><span class="pl-c">//</span> if port is succesfuly opened</span>
                <span class="pl-k">function</span>(<span class="pl-smi">successMessage</span>) {
                    open <span class="pl-k">=</span> <span class="pl-c1">true</span>;
                    <span class="pl-c"><span class="pl-c">//</span> register the read callback</span>
                    <span class="pl-smi">serial</span>.<span class="pl-en">registerReadCallback</span>(
                        <span class="pl-k">function</span> <span class="pl-en">success</span>(<span class="pl-smi">data</span>){
                            <span class="pl-c"><span class="pl-c">//</span> decode the received message</span>
                            <span class="pl-k">var</span> view <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Uint8Array</span>(data);
                            <span class="pl-k">if</span>(<span class="pl-smi">view</span>.<span class="pl-c1">length</span> <span class="pl-k">&gt;=</span> <span class="pl-c1">1</span>) {
                                <span class="pl-k">for</span>(<span class="pl-k">var</span> i<span class="pl-k">=</span><span class="pl-c1">0</span>; i <span class="pl-k">&lt;</span> <span class="pl-smi">view</span>.<span class="pl-c1">length</span>; i<span class="pl-k">++</span>) {
                                    <span class="pl-c"><span class="pl-c">//</span> if we received a \n, the message is complete, display it</span>
                                    <span class="pl-k">if</span>(view[i] <span class="pl-k">==</span> <span class="pl-c1">13</span>) {
                                        <span class="pl-c"><span class="pl-c">//</span> check if the read rate correspond to the arduino serial print rate</span>
                                        <span class="pl-k">var</span> now <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-en">Date</span>();
                                        <span class="pl-smi">delta</span>.<span class="pl-smi">innerText</span> <span class="pl-k">=</span> now <span class="pl-k">-</span> lastRead;
                                        lastRead <span class="pl-k">=</span> now;
                                        <span class="pl-c"><span class="pl-c">//</span> display the message</span>
                                        <span class="pl-k">var</span> value <span class="pl-k">=</span> <span class="pl-c1">parseInt</span>(str);
                                        <span class="pl-smi">pot</span>.<span class="pl-smi">innerText</span> <span class="pl-k">=</span> value;
                                        str <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">&#39;</span><span class="pl-pds">&#39;</span></span>;
                                    }
                                    <span class="pl-c"><span class="pl-c">//</span> if not, concatenate with the begening of the message</span>
                                    <span class="pl-k">else</span> {
                                        <span class="pl-k">var</span> temp_str <span class="pl-k">=</span> <span class="pl-c1">String</span>.<span class="pl-c1">fromCharCode</span>(view[i]);
                                        <span class="pl-k">var</span> str_esc <span class="pl-k">=</span> <span class="pl-c1">escape</span>(temp_str);
                                        str <span class="pl-k">+=</span> <span class="pl-c1">unescape</span>(str_esc);
                                    }
                                }
                            }
                        },
                        <span class="pl-c"><span class="pl-c">//</span> error attaching the callback</span>
                        errorCallback
                    );
                },
                <span class="pl-c"><span class="pl-c">//</span> error opening the port</span>
                errorCallback
            );
        },
        <span class="pl-c"><span class="pl-c">//</span> user does not grant permission</span>
        errorCallback
    );

    <span class="pl-smi">on</span>.<span class="pl-en">onclick</span> <span class="pl-k">=</span> <span class="pl-k">function</span>() {
        <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">&#39;</span>click<span class="pl-pds">&#39;</span></span>);
        <span class="pl-k">if</span> (open) <span class="pl-smi">serial</span>.<span class="pl-c1">write</span>(<span class="pl-s"><span class="pl-pds">&#39;</span>1<span class="pl-pds">&#39;</span></span>);
    };
    <span class="pl-smi">off</span>.<span class="pl-en">onclick</span> <span class="pl-k">=</span> <span class="pl-k">function</span>() {
        <span class="pl-k">if</span> (open) <span class="pl-smi">serial</span>.<span class="pl-c1">write</span>(<span class="pl-s"><span class="pl-pds">&#39;</span>0<span class="pl-pds">&#39;</span></span>);
    }
}

};

app.initialize();

这里是您的Arduino项目 .ino 文件,A0上有一个电位器,13:

#define POT A0
#define LED 13

unsigned long previousMillis; int interval = 50;

void setup() { Serial.begin(9600); pinMode(POT, INPUT); pinMode(LED, OUTPUT); }

void loop() { if (Serial.available() > 0) { char i = Serial.read(); switch (i) { case '0': digitalWrite(LED, LOW); break; case '1': digitalWrite(LED, HIGH); break; } } if (millis() - previousMillis >= interval) { previousMillis = millis(); int value = analogRead(POT); Serial.println(value); } }

您的设备尚未知道?

感谢 usb-serial-for-android 库,您可以与CDC,FTDI, Arduino等设备。

您的设备可能没有列在 https://github.com/mik3y/usb-serial-for -android 。 如果您知道您的设备VID(供应商ID)和PID(产品编号),您可以尝试

serial.requestPermission({vid: '1d50', pid: '607d'}, function success(), function error()); //hex strings
or
serial.requestPermission({vid: 7504, pid: 24701}, function success(), function error()); //integers

您也可以选择要使用的驱动程序。选项是:

  • CdcAcmSerialDriver
  • Ch34xSerialDriver
  • Cp21xxSerialDriver
  • FtdiSerialDriver
  • ProlificSerialDriver

如果空白或不是其中之一,则默认为 CdcAcmSerialDriver (请随时添加PR以支持更多)。

serial.requestPermission({
        vid: '1d50',
        pid: '607d',
        driver: 'FtdiSerialDriver' // or any other
    },
    function success(),
    function error()
);

您可以使用lsusb(以十六进制形式返回VID:PID)或查看dmesg日志,在linux或android上找到您的设备VID和PID。

更改日志

2015.10: Ed Lafargue :在打开选项中实现了sleepOnPause标志,以防止在应用程序进入后台时关闭OTG端口。

2014.08: Zevero :通过VID和PID查找设备的选项,可让您使用无法识别的设备。

2014.07: Hendrik Maus :实现了使用RS232协议的writeHex,即javascript现在可以通过ff,java将其转换为1字节数组并写入串行端口 - 自然地,java和现有的写入方法在这里将从输入字符串创建一个2字节的数组。

2014.04: Derek K :实现了registerReadCallback,用于事件读取和Android onPause / onResume

2014.03: Ed。 Lafargue :已实现read()。成功回调返回一个Javascript ArrayBuffer,它是处理Javascript中二进制数据的最佳方式。如果需要,将其转换为字符串是很直接的 - 可以在此插件中实现一个实用程序函数。

2013.11: Xavier Seignard :首次实施




相关问题推荐