refactor: 删除 ESP Config WeChat 项目
@@ -1,2 +0,0 @@
|
||||
node_modules/
|
||||
miniprogram_npm/
|
||||
@@ -1,5 +0,0 @@
|
||||
# ESP Config WeChat
|
||||
A WeChat application for provisioning ESP smart devices.
|
||||
|
||||
## Implemented modules
|
||||
[BluFi](https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/blufi)
|
||||
@@ -1,22 +0,0 @@
|
||||
//app.js
|
||||
App({
|
||||
data: {
|
||||
service_uuid: "0000FFFF-0000-1000-8000-00805F9B34FB",
|
||||
characteristic_write_uuid: "0000FF01-0000-1000-8000-00805F9B34FB",
|
||||
characteristic_read_uuid: "0000FF02-0000-1000-8000-00805F9B34FB",
|
||||
name: "BLUFI",
|
||||
mtu: 19,
|
||||
constMtu: 128,
|
||||
md5Key: "",
|
||||
platform: '',
|
||||
sequenceControl: -1,
|
||||
sequenceNumber: -1
|
||||
},
|
||||
|
||||
onLaunch: function () {
|
||||
|
||||
},
|
||||
globalData: {
|
||||
userInfo: null
|
||||
}
|
||||
})
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/index",
|
||||
"pages/blueDevices/blueDevices",
|
||||
"pages/blueWifi/blueWifi",
|
||||
"pages/blueConnect/blueConnect"
|
||||
],
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#4d9efb",
|
||||
"navigationBarTitleText": "WeChat",
|
||||
"navigationBarTextStyle": "white"
|
||||
},
|
||||
"sitemapLocation": "sitemap.json"
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/**app.wxss**/
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
padding: 0 10px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.item {
|
||||
display: flex;
|
||||
height: 130rpx;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.item-img {
|
||||
flex: 0 0 100rpx;
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 100%;
|
||||
}
|
||||
.bluetooth-img {
|
||||
height: 80rpx;
|
||||
width: 80rpx;
|
||||
}
|
||||
.item-name {
|
||||
flex: 1;
|
||||
padding-left: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.text-rssi {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
.btn {
|
||||
width: 100%;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
background: #4d9efb;
|
||||
border: none;
|
||||
margin-bottom: 30rpx;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
}
|
||||
.font14 {
|
||||
font-size: 14px;
|
||||
}
|
||||
.font16 {
|
||||
font-size: 16px;
|
||||
}
|
||||
.textcenter {
|
||||
text-align: center;
|
||||
}
|
||||
.width100 {
|
||||
width: 100%;
|
||||
}
|
||||
.margintop20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.margintop10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.modal-mask{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(0,0,0,.7);
|
||||
overflow: hidden;
|
||||
color: #ffffff;
|
||||
z-index:900;
|
||||
}
|
||||
.modal-dialog{
|
||||
background-color: #f9f9f9;
|
||||
/*background: rgba(0,0,0,.7);*/
|
||||
opacity: 0.95;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
top: 20%;
|
||||
left: 10%;
|
||||
overflow: hidden;
|
||||
width: 80%;
|
||||
color: #000;
|
||||
border-radius: 26rpx;
|
||||
}
|
||||
.modal-dialog input{
|
||||
margin: 15px 0;
|
||||
padding: 0 20px;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.modal-btn-wrapper{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100rpx;
|
||||
line-height:90rpx;
|
||||
border-top: 2rpx solid rgba(7,17,27,0.1);
|
||||
}
|
||||
.cancel-btn, .confirm-btn{
|
||||
flex: 1;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.cancel-btn{
|
||||
border-right: 2rpx solid rgba(7,17,27,0.1);
|
||||
}
|
||||
.modal-title{
|
||||
text-align: center;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
var generatePrime = require('./lib/generatePrime')
|
||||
|
||||
var DH = require('./lib/dh')
|
||||
var Buffer = require('./lib/safe-buffer').Buffer
|
||||
|
||||
function getDiffieHellman(mod) {
|
||||
var prime = new Buffer(primes[mod].prime, 'hex')
|
||||
var gen = new Buffer(primes[mod].gen, 'hex')
|
||||
|
||||
return new DH(prime, gen)
|
||||
}
|
||||
|
||||
var ENCODINGS = {
|
||||
'binary': true, 'hex': true, 'base64': true
|
||||
}
|
||||
|
||||
function createDiffieHellman(prime, enc, generator, genc) {
|
||||
if (Buffer.isBuffer(enc) || ENCODINGS[enc] === undefined) {
|
||||
return createDiffieHellman(prime, 'binary', enc, generator)
|
||||
}
|
||||
|
||||
enc = enc || 'binary'
|
||||
genc = genc || 'binary'
|
||||
generator = generator || new Buffer([2])
|
||||
|
||||
if (!Buffer.isBuffer(generator)) {
|
||||
generator = new Buffer(generator, genc)
|
||||
}
|
||||
|
||||
if (typeof prime === 'number') {
|
||||
return new DH(generatePrime(prime, generator), generator, true)
|
||||
}
|
||||
|
||||
if (!Buffer.isBuffer(prime)) {
|
||||
prime = new Buffer(prime, enc)
|
||||
}
|
||||
|
||||
return new DH(prime, generator, true)
|
||||
}
|
||||
|
||||
exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman
|
||||
exports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman
|
||||
@@ -1,151 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
exports.byteLength = byteLength
|
||||
exports.toByteArray = toByteArray
|
||||
exports.fromByteArray = fromByteArray
|
||||
|
||||
var lookup = []
|
||||
var revLookup = []
|
||||
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
|
||||
|
||||
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
for (var i = 0, len = code.length; i < len; ++i) {
|
||||
lookup[i] = code[i]
|
||||
revLookup[code.charCodeAt(i)] = i
|
||||
}
|
||||
|
||||
// Support decoding URL-safe base64 strings, as Node.js does.
|
||||
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
|
||||
revLookup['-'.charCodeAt(0)] = 62
|
||||
revLookup['_'.charCodeAt(0)] = 63
|
||||
|
||||
function getLens (b64) {
|
||||
var len = b64.length
|
||||
|
||||
if (len % 4 > 0) {
|
||||
throw new Error('Invalid string. Length must be a multiple of 4')
|
||||
}
|
||||
|
||||
// Trim off extra bytes after placeholder bytes are found
|
||||
// See: https://github.com/beatgammit/base64-js/issues/42
|
||||
var validLen = b64.indexOf('=')
|
||||
if (validLen === -1) validLen = len
|
||||
|
||||
var placeHoldersLen = validLen === len
|
||||
? 0
|
||||
: 4 - (validLen % 4)
|
||||
|
||||
return [validLen, placeHoldersLen]
|
||||
}
|
||||
|
||||
// base64 is 4/3 + up to two characters of the original data
|
||||
function byteLength (b64) {
|
||||
var lens = getLens(b64)
|
||||
var validLen = lens[0]
|
||||
var placeHoldersLen = lens[1]
|
||||
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
||||
}
|
||||
|
||||
function _byteLength (b64, validLen, placeHoldersLen) {
|
||||
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
|
||||
}
|
||||
|
||||
function toByteArray (b64) {
|
||||
var tmp
|
||||
var lens = getLens(b64)
|
||||
var validLen = lens[0]
|
||||
var placeHoldersLen = lens[1]
|
||||
|
||||
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
|
||||
|
||||
var curByte = 0
|
||||
|
||||
// if there are placeholders, only get up to the last complete 4 chars
|
||||
var len = placeHoldersLen > 0
|
||||
? validLen - 4
|
||||
: validLen
|
||||
|
||||
for (var i = 0; i < len; i += 4) {
|
||||
tmp =
|
||||
(revLookup[b64.charCodeAt(i)] << 18) |
|
||||
(revLookup[b64.charCodeAt(i + 1)] << 12) |
|
||||
(revLookup[b64.charCodeAt(i + 2)] << 6) |
|
||||
revLookup[b64.charCodeAt(i + 3)]
|
||||
arr[curByte++] = (tmp >> 16) & 0xFF
|
||||
arr[curByte++] = (tmp >> 8) & 0xFF
|
||||
arr[curByte++] = tmp & 0xFF
|
||||
}
|
||||
|
||||
if (placeHoldersLen === 2) {
|
||||
tmp =
|
||||
(revLookup[b64.charCodeAt(i)] << 2) |
|
||||
(revLookup[b64.charCodeAt(i + 1)] >> 4)
|
||||
arr[curByte++] = tmp & 0xFF
|
||||
}
|
||||
|
||||
if (placeHoldersLen === 1) {
|
||||
tmp =
|
||||
(revLookup[b64.charCodeAt(i)] << 10) |
|
||||
(revLookup[b64.charCodeAt(i + 1)] << 4) |
|
||||
(revLookup[b64.charCodeAt(i + 2)] >> 2)
|
||||
arr[curByte++] = (tmp >> 8) & 0xFF
|
||||
arr[curByte++] = tmp & 0xFF
|
||||
}
|
||||
|
||||
return arr
|
||||
}
|
||||
|
||||
function tripletToBase64 (num) {
|
||||
return lookup[num >> 18 & 0x3F] +
|
||||
lookup[num >> 12 & 0x3F] +
|
||||
lookup[num >> 6 & 0x3F] +
|
||||
lookup[num & 0x3F]
|
||||
}
|
||||
|
||||
function encodeChunk (uint8, start, end) {
|
||||
var tmp
|
||||
var output = []
|
||||
for (var i = start; i < end; i += 3) {
|
||||
tmp =
|
||||
((uint8[i] << 16) & 0xFF0000) +
|
||||
((uint8[i + 1] << 8) & 0xFF00) +
|
||||
(uint8[i + 2] & 0xFF)
|
||||
output.push(tripletToBase64(tmp))
|
||||
}
|
||||
return output.join('')
|
||||
}
|
||||
|
||||
function fromByteArray (uint8) {
|
||||
var tmp
|
||||
var len = uint8.length
|
||||
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
|
||||
var parts = []
|
||||
var maxChunkLength = 16383 // must be multiple of 3
|
||||
|
||||
// go through the array every three bytes, we'll deal with trailing stuff later
|
||||
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
|
||||
parts.push(encodeChunk(
|
||||
uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
|
||||
))
|
||||
}
|
||||
|
||||
// pad the end with zeros, but make sure to not forget the extra bytes
|
||||
if (extraBytes === 1) {
|
||||
tmp = uint8[len - 1]
|
||||
parts.push(
|
||||
lookup[tmp >> 2] +
|
||||
lookup[(tmp << 4) & 0x3F] +
|
||||
'=='
|
||||
)
|
||||
} else if (extraBytes === 2) {
|
||||
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
|
||||
parts.push(
|
||||
lookup[tmp >> 10] +
|
||||
lookup[(tmp >> 4) & 0x3F] +
|
||||
lookup[(tmp << 2) & 0x3F] +
|
||||
'='
|
||||
)
|
||||
}
|
||||
|
||||
return parts.join('')
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
var r;
|
||||
|
||||
module.exports = function rand(len) {
|
||||
if (!r)
|
||||
r = new Rand(null);
|
||||
|
||||
return r.generate(len);
|
||||
};
|
||||
|
||||
function Rand(rand) {
|
||||
this.rand = rand;
|
||||
}
|
||||
module.exports.Rand = Rand;
|
||||
|
||||
Rand.prototype.generate = function generate(len) {
|
||||
return this._rand(len);
|
||||
};
|
||||
|
||||
// Emulate crypto API using randy
|
||||
Rand.prototype._rand = function _rand(n) {
|
||||
console.log(this);
|
||||
if (this.rand.getBytes)
|
||||
return this.rand.getBytes(n);
|
||||
|
||||
var res = new Uint8Array(n);
|
||||
for (var i = 0; i < res.length; i++)
|
||||
res[i] = this.rand.getByte();
|
||||
return res;
|
||||
};
|
||||
|
||||
if (typeof self === 'object') {
|
||||
Rand.prototype._rand = function _rand(n) {
|
||||
var list = [];
|
||||
for (var i = 0; i < n; i++) {
|
||||
list.push(Math.ceil(Math.random() * 255))
|
||||
}
|
||||
var arr = new Uint8Array(list);
|
||||
return arr;
|
||||
};
|
||||
} else {
|
||||
// Node.js or Web worker with no crypto support
|
||||
try {
|
||||
var crypto = require('crypto');
|
||||
if (typeof crypto.randomBytes !== 'function')
|
||||
throw new Error('Not supported');
|
||||
|
||||
Rand.prototype._rand = function _rand(n) {
|
||||
return crypto.randomBytes(n);
|
||||
};
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
var BN = require('bn');
|
||||
var MillerRabin = require('miller-rabin');
|
||||
var millerRabin = new MillerRabin();
|
||||
var TWENTYFOUR = new BN(24);
|
||||
var ELEVEN = new BN(11);
|
||||
var TEN = new BN(10);
|
||||
var THREE = new BN(3);
|
||||
var SEVEN = new BN(7);
|
||||
var Buffer = require('safe-buffer').Buffer
|
||||
var primes = require('./generatePrime');
|
||||
var randomBytes = require('randombytes');
|
||||
module.exports = DH;
|
||||
|
||||
function setPublicKey(pub, enc) {
|
||||
enc = enc || 'utf8';
|
||||
if (!Buffer.isBuffer(pub)) {
|
||||
pub = new Buffer(pub, enc);
|
||||
}
|
||||
this._pub = new BN(pub);
|
||||
return this;
|
||||
}
|
||||
|
||||
function setPrivateKey(priv, enc) {
|
||||
enc = enc || 'utf8';
|
||||
if (!Buffer.isBuffer(priv)) {
|
||||
priv = new Buffer(priv, enc);
|
||||
}
|
||||
this._priv = new BN(priv);
|
||||
return this;
|
||||
}
|
||||
|
||||
var primeCache = {};
|
||||
function checkPrime(prime, generator) {
|
||||
var gen = generator.toString('hex');
|
||||
var hex = [gen, prime.toString(16)].join('_');
|
||||
if (hex in primeCache) {
|
||||
return primeCache[hex];
|
||||
}
|
||||
var error = 0;
|
||||
|
||||
if (prime.isEven() ||
|
||||
!primes.simpleSieve ||
|
||||
!primes.fermatTest(prime) ||
|
||||
!millerRabin.test(prime)) {
|
||||
//not a prime so +1
|
||||
error += 1;
|
||||
|
||||
if (gen === '02' || gen === '05') {
|
||||
// we'd be able to check the generator
|
||||
// it would fail so +8
|
||||
error += 8;
|
||||
} else {
|
||||
//we wouldn't be able to test the generator
|
||||
// so +4
|
||||
error += 4;
|
||||
}
|
||||
primeCache[hex] = error;
|
||||
return error;
|
||||
}
|
||||
if (!millerRabin.test(prime.shrn(1))) {
|
||||
//not a safe prime
|
||||
error += 2;
|
||||
}
|
||||
var rem;
|
||||
switch (gen) {
|
||||
case '02':
|
||||
if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) {
|
||||
// unsuidable generator
|
||||
error += 8;
|
||||
}
|
||||
break;
|
||||
case '05':
|
||||
rem = prime.mod(TEN);
|
||||
if (rem.cmp(THREE) && rem.cmp(SEVEN)) {
|
||||
// prime mod 10 needs to equal 3 or 7
|
||||
error += 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error += 4;
|
||||
}
|
||||
primeCache[hex] = error;
|
||||
return error;
|
||||
}
|
||||
|
||||
function DH(prime, generator, malleable) {
|
||||
this.setGenerator(generator);
|
||||
this.__prime = new BN(prime);
|
||||
this._prime = BN.mont(this.__prime);
|
||||
this._primeLen = 128;
|
||||
this._pub = undefined;
|
||||
this._priv = undefined;
|
||||
this._primeCode = undefined;
|
||||
if (malleable) {
|
||||
this.setPublicKey = setPublicKey;
|
||||
this.setPrivateKey = setPrivateKey;
|
||||
} else {
|
||||
this._primeCode = 8;
|
||||
}
|
||||
}
|
||||
Object.defineProperty(DH.prototype, 'verifyError', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
if (typeof this._primeCode !== 'number') {
|
||||
this._primeCode = checkPrime(this.__prime, this.__gen);
|
||||
}
|
||||
return this._primeCode;
|
||||
}
|
||||
});
|
||||
DH.prototype.generateKeys = function () {
|
||||
if (!this._priv) {
|
||||
this._priv = new BN(randomBytes(this._primeLen));
|
||||
}
|
||||
this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed();
|
||||
return this.getPublicKey();
|
||||
};
|
||||
|
||||
DH.prototype.computeSecret = function (other) {
|
||||
other = new BN(other);
|
||||
other = other.toRed(this._prime);
|
||||
var secret = other.redPow(this._priv).fromRed();
|
||||
var out = new Buffer(secret.toArray());
|
||||
var prime = this.getPrime();
|
||||
if (out.length < prime.length) {
|
||||
var front = new Buffer(prime.length - out.length);
|
||||
front.fill(0);
|
||||
out = Buffer.concat([front, out]);
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
DH.prototype.getPublicKey = function getPublicKey(enc) {
|
||||
return formatReturnValue(this._pub, enc);
|
||||
};
|
||||
|
||||
DH.prototype.getPrivateKey = function getPrivateKey(enc) {
|
||||
return formatReturnValue(this._priv, enc);
|
||||
};
|
||||
|
||||
DH.prototype.getPrime = function (enc) {
|
||||
return formatReturnValue(this.__prime, enc);
|
||||
};
|
||||
|
||||
DH.prototype.getGenerator = function (enc) {
|
||||
return formatReturnValue(this._gen, enc);
|
||||
};
|
||||
|
||||
DH.prototype.setGenerator = function (gen, enc) {
|
||||
enc = enc || 'utf8';
|
||||
if (!Buffer.isBuffer(gen)) {
|
||||
gen = new Buffer(gen, enc);
|
||||
}
|
||||
this.__gen = gen;
|
||||
this._gen = new BN(gen);
|
||||
return this;
|
||||
};
|
||||
|
||||
function formatReturnValue(bn, enc) {
|
||||
var buf = new Buffer(bn.toArray());
|
||||
if (!enc) {
|
||||
return buf;
|
||||
} else {
|
||||
return buf.toString(enc);
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
var randomBytes = require('randombytes');
|
||||
module.exports = findPrime;
|
||||
findPrime.simpleSieve = simpleSieve;
|
||||
findPrime.fermatTest = fermatTest;
|
||||
var BN = require('bn.js');
|
||||
var TWENTYFOUR = new BN(24);
|
||||
var MillerRabin = require('miller-rabin');
|
||||
var millerRabin = new MillerRabin();
|
||||
var ONE = new BN(1);
|
||||
var TWO = new BN(2);
|
||||
var FIVE = new BN(5);
|
||||
var SIXTEEN = new BN(16);
|
||||
var EIGHT = new BN(8);
|
||||
var TEN = new BN(10);
|
||||
var THREE = new BN(3);
|
||||
var SEVEN = new BN(7);
|
||||
var ELEVEN = new BN(11);
|
||||
var FOUR = new BN(4);
|
||||
var TWELVE = new BN(12);
|
||||
var primes = null;
|
||||
|
||||
function _getPrimes() {
|
||||
if (primes !== null)
|
||||
return primes;
|
||||
|
||||
var limit = 0x100000;
|
||||
var res = [];
|
||||
res[0] = 2;
|
||||
for (var i = 1, k = 3; k < limit; k += 2) {
|
||||
var sqrt = Math.ceil(Math.sqrt(k));
|
||||
for (var j = 0; j < i && res[j] <= sqrt; j++)
|
||||
if (k % res[j] === 0)
|
||||
break;
|
||||
|
||||
if (i !== j && res[j] <= sqrt)
|
||||
continue;
|
||||
|
||||
res[i++] = k;
|
||||
}
|
||||
primes = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
function simpleSieve(p) {
|
||||
var primes = _getPrimes();
|
||||
|
||||
for (var i = 0; i < primes.length; i++)
|
||||
if (p.modn(primes[i]) === 0) {
|
||||
if (p.cmpn(primes[i]) === 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function fermatTest(p) {
|
||||
var red = BN.mont(p);
|
||||
return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;
|
||||
}
|
||||
|
||||
function findPrime(bits, gen) {
|
||||
if (bits < 16) {
|
||||
// this is what openssl does
|
||||
if (gen === 2 || gen === 5) {
|
||||
return new BN([0x8c, 0x7b]);
|
||||
} else {
|
||||
return new BN([0x8c, 0x27]);
|
||||
}
|
||||
}
|
||||
gen = new BN(gen);
|
||||
|
||||
var num, n2;
|
||||
|
||||
while (true) {
|
||||
num = new BN(randomBytes(Math.ceil(bits / 8)));
|
||||
while (num.bitLength() > bits) {
|
||||
num.ishrn(1);
|
||||
}
|
||||
if (num.isEven()) {
|
||||
num.iadd(ONE);
|
||||
}
|
||||
if (!num.testn(1)) {
|
||||
num.iadd(TWO);
|
||||
}
|
||||
if (!gen.cmp(TWO)) {
|
||||
while (num.mod(TWENTYFOUR).cmp(ELEVEN)) {
|
||||
num.iadd(FOUR);
|
||||
}
|
||||
} else if (!gen.cmp(FIVE)) {
|
||||
while (num.mod(TEN).cmp(THREE)) {
|
||||
num.iadd(FOUR);
|
||||
}
|
||||
}
|
||||
n2 = num.shrn(1);
|
||||
if (simpleSieve(n2) && simpleSieve(num) &&
|
||||
fermatTest(n2) && fermatTest(num) &&
|
||||
millerRabin.test(n2) && millerRabin.test(num)) {
|
||||
return num;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
|
||||
var e, m
|
||||
var eLen = (nBytes * 8) - mLen - 1
|
||||
var eMax = (1 << eLen) - 1
|
||||
var eBias = eMax >> 1
|
||||
var nBits = -7
|
||||
var i = isLE ? (nBytes - 1) : 0
|
||||
var d = isLE ? -1 : 1
|
||||
var s = buffer[offset + i]
|
||||
|
||||
i += d
|
||||
|
||||
e = s & ((1 << (-nBits)) - 1)
|
||||
s >>= (-nBits)
|
||||
nBits += eLen
|
||||
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
||||
|
||||
m = e & ((1 << (-nBits)) - 1)
|
||||
e >>= (-nBits)
|
||||
nBits += mLen
|
||||
for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
|
||||
|
||||
if (e === 0) {
|
||||
e = 1 - eBias
|
||||
} else if (e === eMax) {
|
||||
return m ? NaN : ((s ? -1 : 1) * Infinity)
|
||||
} else {
|
||||
m = m + Math.pow(2, mLen)
|
||||
e = e - eBias
|
||||
}
|
||||
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
|
||||
}
|
||||
|
||||
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
|
||||
var e, m, c
|
||||
var eLen = (nBytes * 8) - mLen - 1
|
||||
var eMax = (1 << eLen) - 1
|
||||
var eBias = eMax >> 1
|
||||
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
|
||||
var i = isLE ? 0 : (nBytes - 1)
|
||||
var d = isLE ? 1 : -1
|
||||
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
|
||||
|
||||
value = Math.abs(value)
|
||||
|
||||
if (isNaN(value) || value === Infinity) {
|
||||
m = isNaN(value) ? 1 : 0
|
||||
e = eMax
|
||||
} else {
|
||||
e = Math.floor(Math.log(value) / Math.LN2)
|
||||
if (value * (c = Math.pow(2, -e)) < 1) {
|
||||
e--
|
||||
c *= 2
|
||||
}
|
||||
if (e + eBias >= 1) {
|
||||
value += rt / c
|
||||
} else {
|
||||
value += rt * Math.pow(2, 1 - eBias)
|
||||
}
|
||||
if (value * c >= 2) {
|
||||
e++
|
||||
c /= 2
|
||||
}
|
||||
|
||||
if (e + eBias >= eMax) {
|
||||
m = 0
|
||||
e = eMax
|
||||
} else if (e + eBias >= 1) {
|
||||
m = ((value * c) - 1) * Math.pow(2, mLen)
|
||||
e = e + eBias
|
||||
} else {
|
||||
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
|
||||
e = 0
|
||||
}
|
||||
}
|
||||
|
||||
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
|
||||
|
||||
e = (e << mLen) | m
|
||||
eLen += mLen
|
||||
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
|
||||
|
||||
buffer[offset + i - d] |= s * 128
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
var bn = require('bn.js');
|
||||
var brorand = require('brorand');
|
||||
|
||||
function MillerRabin(rand) {
|
||||
this.rand = rand || new brorand.Rand();
|
||||
}
|
||||
module.exports = MillerRabin;
|
||||
|
||||
MillerRabin.create = function create(rand) {
|
||||
return new MillerRabin(rand);
|
||||
};
|
||||
|
||||
MillerRabin.prototype._randbelow = function _randbelow(n) {
|
||||
var len = n.bitLength();
|
||||
var min_bytes = Math.ceil(len / 8);
|
||||
|
||||
// Generage random bytes until a number less than n is found.
|
||||
// This ensures that 0..n-1 have an equal probability of being selected.
|
||||
do
|
||||
var a = new bn(this.rand.generate(min_bytes));
|
||||
while (a.cmp(n) >= 0);
|
||||
|
||||
return a;
|
||||
};
|
||||
|
||||
MillerRabin.prototype._randrange = function _randrange(start, stop) {
|
||||
// Generate a random number greater than or equal to start and less than stop.
|
||||
var size = stop.sub(start);
|
||||
return start.add(this._randbelow(size));
|
||||
};
|
||||
|
||||
MillerRabin.prototype.test = function test(n, k, cb) {
|
||||
var len = n.bitLength();
|
||||
var red = bn.mont(n);
|
||||
var rone = new bn(1).toRed(red);
|
||||
|
||||
if (!k)
|
||||
k = Math.max(1, (len / 48) | 0);
|
||||
|
||||
// Find d and s, (n - 1) = (2 ^ s) * d;
|
||||
var n1 = n.subn(1);
|
||||
for (var s = 0; !n1.testn(s); s++) {}
|
||||
var d = n.shrn(s);
|
||||
|
||||
var rn1 = n1.toRed(red);
|
||||
|
||||
var prime = true;
|
||||
for (; k > 0; k--) {
|
||||
var a = this._randrange(new bn(2), n1);
|
||||
if (cb)
|
||||
cb(a);
|
||||
|
||||
var x = a.toRed(red).redPow(d);
|
||||
if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
|
||||
continue;
|
||||
|
||||
for (var i = 1; i < s; i++) {
|
||||
x = x.redSqr();
|
||||
|
||||
if (x.cmp(rone) === 0)
|
||||
return false;
|
||||
if (x.cmp(rn1) === 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i === s)
|
||||
return false;
|
||||
}
|
||||
|
||||
return prime;
|
||||
};
|
||||
|
||||
MillerRabin.prototype.getDivisor = function getDivisor(n, k) {
|
||||
var len = n.bitLength();
|
||||
var red = bn.mont(n);
|
||||
var rone = new bn(1).toRed(red);
|
||||
|
||||
if (!k)
|
||||
k = Math.max(1, (len / 48) | 0);
|
||||
|
||||
// Find d and s, (n - 1) = (2 ^ s) * d;
|
||||
var n1 = n.subn(1);
|
||||
for (var s = 0; !n1.testn(s); s++) {}
|
||||
var d = n.shrn(s);
|
||||
|
||||
var rn1 = n1.toRed(red);
|
||||
|
||||
for (; k > 0; k--) {
|
||||
var a = this._randrange(new bn(2), n1);
|
||||
|
||||
var g = n.gcd(a);
|
||||
if (g.cmpn(1) !== 0)
|
||||
return g;
|
||||
|
||||
var x = a.toRed(red).redPow(d);
|
||||
if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)
|
||||
continue;
|
||||
|
||||
for (var i = 1; i < s; i++) {
|
||||
x = x.redSqr();
|
||||
|
||||
if (x.cmp(rone) === 0)
|
||||
return x.fromRed().subn(1).gcd(n);
|
||||
if (x.cmp(rn1) === 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i === s) {
|
||||
x = x.redSqr();
|
||||
return x.fromRed().subn(1).gcd(n);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
function oldBrowser() {
|
||||
throw new Error('Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11')
|
||||
}
|
||||
|
||||
var Buffer = require('safe-buffer').Buffer
|
||||
|
||||
module.exports = randomBytes
|
||||
|
||||
function randomBytes(size, cb) {
|
||||
// phantomjs needs to throw
|
||||
if (size > 65536) throw new Error('requested too many random bytes')
|
||||
// in case browserify isn't using the Uint8Array version
|
||||
var arr = [];
|
||||
for (var i = 0; i < size; i++) {
|
||||
arr.push(Math.ceil(Math.random() * 255))
|
||||
}
|
||||
var rawBytes = new Uint8Array(arr)
|
||||
|
||||
// XXX: phantomjs doesn't like a buffer being passed here
|
||||
var bytes = Buffer.from(rawBytes.buffer)
|
||||
|
||||
if (typeof cb === 'function') {
|
||||
return process.nextTick(function () {
|
||||
cb(null, bytes)
|
||||
})
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/* eslint-disable node/no-deprecated-api */
|
||||
var buffer = require('buffer')
|
||||
var Buffer = buffer.Buffer
|
||||
|
||||
// alternative to using Object.keys for old browsers
|
||||
function copyProps (src, dst) {
|
||||
for (var key in src) {
|
||||
dst[key] = src[key]
|
||||
}
|
||||
}
|
||||
if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
|
||||
module.exports = buffer
|
||||
} else {
|
||||
// Copy properties from require('buffer')
|
||||
copyProps(buffer, exports)
|
||||
exports.Buffer = SafeBuffer
|
||||
}
|
||||
|
||||
function SafeBuffer (arg, encodingOrOffset, length) {
|
||||
return Buffer(arg, encodingOrOffset, length)
|
||||
}
|
||||
|
||||
// Copy static methods from Buffer
|
||||
copyProps(Buffer, SafeBuffer)
|
||||
|
||||
SafeBuffer.from = function (arg, encodingOrOffset, length) {
|
||||
if (typeof arg === 'number') {
|
||||
throw new TypeError('Argument must not be a number')
|
||||
}
|
||||
return Buffer(arg, encodingOrOffset, length)
|
||||
}
|
||||
|
||||
SafeBuffer.alloc = function (size, fill, encoding) {
|
||||
if (typeof size !== 'number') {
|
||||
throw new TypeError('Argument must be a number')
|
||||
}
|
||||
var buf = Buffer(size)
|
||||
if (fill !== undefined) {
|
||||
if (typeof encoding === 'string') {
|
||||
buf.fill(fill, encoding)
|
||||
} else {
|
||||
buf.fill(fill)
|
||||
}
|
||||
} else {
|
||||
buf.fill(0)
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
SafeBuffer.allocUnsafe = function (size) {
|
||||
if (typeof size !== 'number') {
|
||||
throw new TypeError('Argument must be a number')
|
||||
}
|
||||
return Buffer(size)
|
||||
}
|
||||
|
||||
SafeBuffer.allocUnsafeSlow = function (size) {
|
||||
if (typeof size !== 'number') {
|
||||
throw new TypeError('Argument must be a number')
|
||||
}
|
||||
return buffer.SlowBuffer(size)
|
||||
}
|
||||
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 259 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "ESP-Config-WeChat",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ESP-Config-WeChat",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"crypto-js": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
|
||||
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"crypto-js": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
|
||||
"integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "ESP-Config-WeChat",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/EspressifApps/ESP-Config-WeChat.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/EspressifApps/ESP-Config-WeChat/issues"
|
||||
},
|
||||
"homepage": "https://github.com/EspressifApps/ESP-Config-WeChat#readme",
|
||||
"dependencies": {
|
||||
"crypto-js": "^4.0.0"
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1,29 +0,0 @@
|
||||
<!--pages/blueConnect/blueConnect.wxml-->
|
||||
<view class="container">
|
||||
<block wx:if="{{!failure}}">
|
||||
<view class="schedule">
|
||||
<view class="schedule-result schedule-success">
|
||||
<image class='schedule-img' mode='aspectFit' src='../../images/round.gif'></image>
|
||||
<view class="desc-wrapper">
|
||||
<view class="text-value"><text>{{value}}</text><text class="text-samll">%</text></view>
|
||||
<view class="text-desc">{{desc}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<view class="schedule fail">
|
||||
<view class="schedule-result schedule-fail">
|
||||
<image class='schedule-img' mode='aspectFit' src='../../images/failure.png'></image>
|
||||
<view class="desc-wrapper">
|
||||
<view class="text-sigh"><text>!</text></view>
|
||||
<view class="text-desc">{{desc}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="process-wrapper">
|
||||
<text class="text-process" wx:for="{{processList}}" wx:key="*this">{{item}}</text>
|
||||
<text>{{vConsoleV}}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -1,68 +0,0 @@
|
||||
/* pages/blueConnect/blueConnect.wxss */
|
||||
.container {
|
||||
padding: 0;
|
||||
}
|
||||
.schedule {
|
||||
background: #4d9efb;
|
||||
height: 46vh;
|
||||
width: 100%;
|
||||
padding: 50rpx;
|
||||
}
|
||||
.schedule-result {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 100%;
|
||||
background: transparent;
|
||||
height: 55vw;
|
||||
width: 55vw;
|
||||
margin: 0 auto;
|
||||
color: #fff;
|
||||
}
|
||||
.schedule-img {
|
||||
height: 55vw;
|
||||
width: 55vw;
|
||||
}
|
||||
.fail{
|
||||
background: #737d89;
|
||||
}
|
||||
.desc-wrapper {
|
||||
position: absolute;
|
||||
}
|
||||
.text-value {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
.text-desc {
|
||||
font-size: 14px;
|
||||
}
|
||||
.text-samll {
|
||||
font-size: 16px;
|
||||
}
|
||||
.text-sigh {
|
||||
height: 80rpx;
|
||||
width: 80rpx;
|
||||
background: #fff;
|
||||
border-radius: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #737d89;
|
||||
margin: 0 auto 10px;
|
||||
}
|
||||
.process-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
margin-top: 20px;
|
||||
padding-left: 30px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
.text-process {
|
||||
margin: 3px 0;
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
|
||||
//获取应用实例
|
||||
const app = getApp();
|
||||
const util = require('../../utils/util.js');
|
||||
Page({
|
||||
data: {
|
||||
deviceList: [],
|
||||
deviceId: "",
|
||||
},
|
||||
bindViewConnect: function (event) {
|
||||
var self = this,
|
||||
deviceId = event.currentTarget.dataset.value;
|
||||
self.setData({
|
||||
deviceId: deviceId
|
||||
});
|
||||
wx.navigateTo({
|
||||
url: '/pages/blueWifi/blueWifi?deviceId=' + deviceId,
|
||||
})
|
||||
},
|
||||
|
||||
getBluDevice: function () {
|
||||
var self = this;
|
||||
wx.getBluetoothDevices({
|
||||
success: function (res) {
|
||||
var list = util.filterDevice(res.devices, "name");
|
||||
if (list.length > 0) {
|
||||
wx.hideLoading();
|
||||
}
|
||||
self.setData({
|
||||
deviceList: list
|
||||
})
|
||||
}
|
||||
})
|
||||
wx.onBluetoothDeviceFound(function (res) {
|
||||
console.log(res.devices[0].name);
|
||||
var list = util.filterDevice(res.devices, "name");
|
||||
if (list.length > 0) {
|
||||
wx.hideLoading();
|
||||
}
|
||||
self.setData({
|
||||
deviceList: self.data.deviceList.concat(list)
|
||||
})
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
onLoad: function () {
|
||||
var self = this;
|
||||
wx.setNavigationBarTitle({
|
||||
title: 'BluFi扫描'
|
||||
});
|
||||
wx.showLoading({
|
||||
title: '设备扫描中...',
|
||||
})
|
||||
self.getBluDevice();
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
var self = this,
|
||||
deviceId = self.data.deviceId;
|
||||
if (!util._isEmpty(deviceId)) {
|
||||
wx.closeBLEConnection({
|
||||
deviceId: deviceId,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1,13 +0,0 @@
|
||||
<!--index.wxml-->
|
||||
<view class="container">
|
||||
<view data-value="{{item.deviceId}}" bindtap="bindViewConnect" wx:for="{{deviceList}}" class="item" wx:key="*this">
|
||||
<view class="item-img">
|
||||
<image class='bluetooth-img' mode='aspectFit' src='../../images/bluetooth.png'></image>
|
||||
</view>
|
||||
<view class="item-name">
|
||||
<text class="text-name">{{item.name}}</text>
|
||||
<text class="text-rssi">Rssi: {{item.RSSI}}</text>
|
||||
<text class="text-rssi">deviceId: {{item.deviceId}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -1,11 +0,0 @@
|
||||
/* pages/blueDevices/blueDevices.wxss */
|
||||
.prompt-title {
|
||||
height: 50rpx;
|
||||
border-top: 1px solid #999;
|
||||
border-bottom: 1px solid #999;
|
||||
width: 100%;
|
||||
}
|
||||
.item {
|
||||
height: auto;
|
||||
padding: 8rpx 0;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"backgroundTextStyle": "dark",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<view class="container">
|
||||
<view data-bssid="" data-ssid="{{item.SSID}}" bindtap="bindViewWifi" wx:for="{{wifiList}}" class="item" wx:key="*this">
|
||||
<view class="item-name">
|
||||
<text class="text-name">{{item.SSID}}</text>
|
||||
</view>
|
||||
<view class="item-icon">
|
||||
<image class='wifi-img' mode='aspectFit' src='../../images/wifi.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class='modal-mask' hidden="{{hiddenModal}}"></view>
|
||||
<view class='modal-dialog' hidden="{{hiddenModal}}">
|
||||
<view class='modal-title'>{{ssid}}</view>
|
||||
<input type='text' password='true' bindinput='bindViewInput' placeholder="请输入密码"/>
|
||||
<view class='modal-btn-wrapper'>
|
||||
<view class='cancel-btn' style='color:rgba(7,17,27,0.6)' bindtap='bindViewCancel'>取消</view>
|
||||
<view class='confirm-btn' style='color:#4d9efb' bindtap='bindViewConfirm'>开始配网</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -1,12 +0,0 @@
|
||||
/* pages/blueWifi/blueWifi.wxss */
|
||||
.item-icon {
|
||||
flex: 0 0 80rpx;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
.wifi-img {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
//index.js
|
||||
//获取应用实例
|
||||
const app = getApp();
|
||||
const util = require('../../utils/util.js');
|
||||
Page({
|
||||
data: {
|
||||
|
||||
},
|
||||
//事件处理函数
|
||||
bindViewBlue: function() {
|
||||
wx.closeBluetoothAdapter({
|
||||
success: function () {
|
||||
}
|
||||
});
|
||||
wx.openBluetoothAdapter({
|
||||
success: function (res) {
|
||||
wx.startBluetoothDevicesDiscovery({
|
||||
success: function (res) {
|
||||
wx.navigateTo({
|
||||
url: '/pages/blueDevices/blueDevices',
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: function (res) {
|
||||
wx.showToast({
|
||||
title: '请打开蓝牙',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
bindViewWifi: function () {
|
||||
wx.navigateTo({
|
||||
url: '/pages/wifiDevices/wifiDevices',
|
||||
})
|
||||
},
|
||||
onLoad: function () {
|
||||
wx.setNavigationBarTitle({
|
||||
title: '配网方式'
|
||||
})
|
||||
wx.getSystemInfo({
|
||||
success (res) {
|
||||
try {
|
||||
app.data.platform = res.platform.toLocaleLowerCase()
|
||||
} catch(e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getUserInfo: function(e) {
|
||||
}
|
||||
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1,19 +0,0 @@
|
||||
<!--index.wxml-->
|
||||
<view class="container">
|
||||
<view class='header-wrapper'>
|
||||
<image class="header-image" src="../../images/network.png"></image>
|
||||
</view>
|
||||
<view class='content-wrapper'>
|
||||
<view class="title">配网方式</view>
|
||||
<view class="btn-info">
|
||||
<view bindtap="bindViewBlue" class="select-way">
|
||||
<image class="btn-image" src="../../images/bluetooth-way.png"></image>
|
||||
<text class="name">BluFi 配网</text>
|
||||
</view>
|
||||
<!-- <view bindtap="bindViewWifi" class="select-way">
|
||||
<image class="btn-image" src="../../images/wifi-way.png"></image>
|
||||
<text class="name">WiFi配网</text>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -1,60 +0,0 @@
|
||||
.container {
|
||||
display: block;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
background: #eee;
|
||||
}
|
||||
.header-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 45vh;
|
||||
width: 100%;
|
||||
background: #4d9efb;
|
||||
border-bottom-right-radius: 40px;
|
||||
border-bottom-left-radius: 40px;
|
||||
}
|
||||
.header-image {
|
||||
width: 29vh;
|
||||
height: 29vh;
|
||||
position: relative;
|
||||
top: -5vh;
|
||||
}
|
||||
.content-wrapper {
|
||||
position: absolute;
|
||||
top: 38vh;
|
||||
left: 15px;
|
||||
height: 50vh;
|
||||
width: calc(100% - 30px);
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0px 0px 3px #fff;
|
||||
color: #818181;
|
||||
}
|
||||
.title {
|
||||
margin: 10px 0;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
.btn-info {
|
||||
display: flex;
|
||||
margin-top: 10vh;
|
||||
}
|
||||
.btn-image {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.select-way {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.name {
|
||||
margin: 10px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
// pages/wifiConfig/wifiConfig.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
next: function () {
|
||||
wx.navigateTo({
|
||||
url: "/pages/wifiList/wifiList"
|
||||
})
|
||||
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
wx.setNavigationBarTitle({
|
||||
title: 'WiFi配网'
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1,20 +0,0 @@
|
||||
<!--pages/wifi3/wifi3.wxml-->
|
||||
<view class='container'>
|
||||
<view class='textcenter'>
|
||||
<view><text class='font14'>第二步</text></view>
|
||||
<view class="margintop10"><text class='font16'>将手机连接设备,请前往手机设置,进入无线局域网</text></view>
|
||||
</view>
|
||||
|
||||
<!-- wifi -->
|
||||
|
||||
<view>
|
||||
<image class="wifi-img" src="../../images/wifi.jpg"></image>
|
||||
</view>
|
||||
<view class="width100 margintop20">
|
||||
<button class="btn" bindtap='setWifi'>去设置 </button>
|
||||
</view>
|
||||
<view class="width100" bindtap='next'>
|
||||
<button class="btn" > 下一步 </button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/* pages/wifiConfig/wifiConfig.wxss */
|
||||
.container{
|
||||
padding-top: 50rpx;
|
||||
}
|
||||
.wifi-img {
|
||||
width:300px;
|
||||
height:234px;
|
||||
margin-top:20px;
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
// pages/wifiConnect/wifiConnect.js
|
||||
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
failStatus: false,
|
||||
sucStatus: false,
|
||||
progress: 0,
|
||||
},
|
||||
getStatus: function() {
|
||||
var self = this;
|
||||
|
||||
wx.request({
|
||||
url: 'https://www.alavening.com/wifi/connstatus.cgi',
|
||||
data: {
|
||||
},
|
||||
header: {
|
||||
'content-type': 'application/json' // 默认值
|
||||
},
|
||||
success: function (res) {
|
||||
console.log(res.data);
|
||||
var data = res.data;
|
||||
console.log(data.status);
|
||||
if (data.status == "success") {
|
||||
self.setData({
|
||||
progress: 100,
|
||||
failStatus: false,
|
||||
sucStatus: true,
|
||||
})
|
||||
self.setResult("success");
|
||||
} else if (data.status == "fail") {
|
||||
self.setData({
|
||||
failStatus: true,
|
||||
sucStatus: false,
|
||||
})
|
||||
self.setResult("fail");
|
||||
} else {
|
||||
if (self.data.progress <= 90) {
|
||||
self.setData({
|
||||
progress: (self.data.progress + 5),
|
||||
failStatus: false,
|
||||
sucStatus: false,
|
||||
})
|
||||
}
|
||||
self.getStatus();
|
||||
}
|
||||
},
|
||||
fail: function (res) {
|
||||
self.setData({
|
||||
failStatus: true,
|
||||
sucStatus: false,
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
setResult: function(result) {
|
||||
var self = this;
|
||||
wx.request({
|
||||
url: 'https://www.alavening.com/wifi/configsuccess.cgi',
|
||||
method: "post",
|
||||
data: {
|
||||
configstatus: result
|
||||
},
|
||||
header: {
|
||||
'content-type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
success: function (res) {
|
||||
},
|
||||
fail: function () {
|
||||
}
|
||||
})
|
||||
},
|
||||
setConnect: function(ssid, password) {
|
||||
var self = this;
|
||||
wx.request({
|
||||
url: 'https://alavening.com/wifi/connect.cgi',
|
||||
method: "post",
|
||||
data: {
|
||||
essid: ssid,
|
||||
password: password
|
||||
},
|
||||
header: {
|
||||
'content-type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
success: function (res) {
|
||||
|
||||
},
|
||||
fail: function () {
|
||||
}
|
||||
})
|
||||
self.getStatus();
|
||||
},
|
||||
successwifi: function() {
|
||||
wx.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
},
|
||||
failwifi: function() {
|
||||
wx.navigateBack({
|
||||
delta: 2
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
var self = this;
|
||||
wx.setNavigationBarTitle({
|
||||
title: 'WiFi配网'
|
||||
});
|
||||
self.setConnect(options.ssid, options.password);
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1,13 +0,0 @@
|
||||
<!--pages/wifi4/wifi4.wxml-->
|
||||
<view class='container'>
|
||||
<view class='textcenter'>
|
||||
<view><text class='font16'>配网中...</text></view>
|
||||
</view>
|
||||
<view class="progress-wrapper">
|
||||
<progress percent="{{progress}}" stroke-width="12" activeColor="#4d9efb"/>
|
||||
</view>
|
||||
<view class='width100 margintop20'>
|
||||
<button hidden='{{failStatus || !sucStatus}}' class="btn" bindtap='successwifi'>配网成功 </button>
|
||||
<button hidden='{{!failStatus || sucStatus}}' class="btn" bindtap='failwifi'>配网失败 </button>
|
||||
</view>
|
||||
</view>
|
||||
@@ -1,13 +0,0 @@
|
||||
/* pages/wifiConnect/wifiConnect.wxss */
|
||||
.container {
|
||||
padding-top: 50rpx;
|
||||
}
|
||||
.progress-wrapper {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
progress {
|
||||
flex: 1;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
// pages/wifiDevices/wifiDevices.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
next: function () {
|
||||
wx.navigateTo({
|
||||
url: "/pages/wifiConfig/wifiConfig"
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
wx.setNavigationBarTitle({
|
||||
title: 'WiFi配网'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1,23 +0,0 @@
|
||||
<!--pages/wifi/wifi.wxml-->
|
||||
<view class='container'>
|
||||
<view class='textcenter'>
|
||||
<view><text class='font14'>第一步</text></view>
|
||||
<view class="margintop10"><text class='font16'>双击设备按键</text></view>
|
||||
</view>
|
||||
<!-- 图片 -->
|
||||
<view>
|
||||
<image></image>
|
||||
</view>
|
||||
<view class='textcenter font14'>
|
||||
<checkbox-group>
|
||||
<label class="checkbox">
|
||||
<checkbox color="#4d9efb" value=""/>我已双击设备按钮
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
<view class='width100 margintop20' bindtap='next'>
|
||||
<button class="btn" >下一步</button>
|
||||
</view>
|
||||
<!-- <button class='font14 back' >返回上一步</button> -->
|
||||
|
||||
</view>
|
||||
@@ -1,20 +0,0 @@
|
||||
/* pages/wifi/wifi.wxss */
|
||||
.container {
|
||||
padding-top: 50rpx;
|
||||
}
|
||||
.checkbox{
|
||||
color: #333
|
||||
}
|
||||
.back{
|
||||
width: 40%;
|
||||
margin: 0 auto
|
||||
}
|
||||
.colored{
|
||||
color: red;
|
||||
}
|
||||
.hide{
|
||||
display: none;
|
||||
}
|
||||
.show{
|
||||
display: block;
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
// pages/wifiList/wifiList.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
password: '',
|
||||
hiddenmodal: true,//可以通过hidden是否掩藏弹出框的属性,来指定那个弹出框
|
||||
wifiList: [],
|
||||
ssid: '',
|
||||
},
|
||||
//点击按钮弹出指定的hiddenmodalput弹出框
|
||||
bindViewWifi: function (e) {
|
||||
var list = this.data.wifiList;
|
||||
var index = e.currentTarget.dataset.index;
|
||||
//console.log(list[index])
|
||||
this.setData({
|
||||
ssid: list[index].essid,
|
||||
hiddenmodal: !this.data.hiddenmodal,
|
||||
|
||||
})
|
||||
|
||||
},
|
||||
bindViewInput: function (e) {
|
||||
this.setData({ password: e.detail.value })
|
||||
},
|
||||
getWifiList: function() {
|
||||
var self = this;
|
||||
wx.request({
|
||||
url: 'https://www.alavening.com/wifi/wifiscan.cgi',
|
||||
data: {
|
||||
},
|
||||
header: {
|
||||
'content-type': 'application/json' // 默认值
|
||||
},
|
||||
success: function (res) {
|
||||
console.log(res);
|
||||
var data = res.data.result;
|
||||
console.log(data);
|
||||
if (data.inProgress == "0") {
|
||||
wx.hideLoading();
|
||||
self.setData({
|
||||
wifiList: data.APs
|
||||
})
|
||||
} else {
|
||||
self.getWifiList();
|
||||
}
|
||||
},
|
||||
fail: function(res) {
|
||||
console.log(res);
|
||||
wx.hideLoading();
|
||||
}
|
||||
})
|
||||
},
|
||||
//取消按钮
|
||||
cancel: function () {
|
||||
this.setData({
|
||||
hiddenmodal: true
|
||||
});
|
||||
},
|
||||
//确认
|
||||
confirm: function () {
|
||||
var self = this;
|
||||
// this.setData({
|
||||
// hiddenmodal: true
|
||||
// })
|
||||
if (!self.data.password.length < 8) {
|
||||
// 这里修改成跳转的页面
|
||||
wx.redirectTo({
|
||||
url: '/pages/wifiConnect/wifiConnect?password=' + self.data.password + "&ssid=" + self.data.ssid
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
var self = this;
|
||||
wx.setNavigationBarTitle({
|
||||
title: 'WiFi配网'
|
||||
});
|
||||
setTimeout(function() {
|
||||
wx.showLoading({
|
||||
title: 'WiFi加载中...',
|
||||
});
|
||||
self.getWifiList();
|
||||
console.log("WiFi加载中...");
|
||||
}, 500);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1,35 +0,0 @@
|
||||
<!--pages/wifi2/wifi2.wxml-->
|
||||
<view class='container'>
|
||||
<view class='textcenter'>
|
||||
<view><text class='font14'>第三步</text></view>
|
||||
<view class="margintop10"><text class='font16'>请选择您的WiFi</text></view>
|
||||
</view>
|
||||
<!-- wifi -->
|
||||
<view class="width100 margintop20">
|
||||
<view data-index="{{index}}" bindtap="bindViewWifi" wx:for="{{wifiList}}" class="item" wx:key="*this">
|
||||
<view class="item-name">
|
||||
<text class="text-name">{{item.essid}}</text>
|
||||
</view>
|
||||
<view class="item-icon">
|
||||
<image class='wifi-img' mode='aspectFit' src='../../images/wifi.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
<view class='modal-mask' hidden="{{hiddenmodal}}"></view>
|
||||
<!-- 弹窗 -->
|
||||
<view class='modal-dialog' hidden="{{hiddenmodal}}" data-index="{{index}}">
|
||||
<view class='modal-title'>{{ssid}}</view>
|
||||
<input type='text' password='true' bindinput='bindViewInput' placeholder="请输入密码"/>
|
||||
<view class='modal-btn-wrapper'>
|
||||
<view class='cancel-btn' style='color:rgba(7,17,27,0.6)' bindtap='cancel'>取消</view>
|
||||
<view class='confirm-btn' style='color:#4d9efb' bindtap='confirm'>确定</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
@@ -1,35 +0,0 @@
|
||||
.container{
|
||||
position: relative;
|
||||
padding-top: 50rpx;
|
||||
}
|
||||
.weui-cell__bd{
|
||||
padding: 0 20px;
|
||||
}
|
||||
.wifi-list{
|
||||
margin-top: 30px;
|
||||
}
|
||||
.main-content{
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.item-wifi{
|
||||
border-bottom:2rpx solid #eee;
|
||||
height:100rpx;
|
||||
line-height:100rpx;
|
||||
margin-top:0;
|
||||
padding: 0 20px;
|
||||
|
||||
}
|
||||
|
||||
.item-icon {
|
||||
flex: 0 0 80rpx;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
.wifi-img {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
{
|
||||
"description": "项目配置文件",
|
||||
"packOptions": {
|
||||
"ignore": [],
|
||||
"include": []
|
||||
},
|
||||
"setting": {
|
||||
"urlCheck": true,
|
||||
"es6": true,
|
||||
"enhance": false,
|
||||
"postcss": true,
|
||||
"preloadBackgroundData": false,
|
||||
"minified": true,
|
||||
"newFeature": true,
|
||||
"coverView": true,
|
||||
"nodeModules": true,
|
||||
"autoAudits": false,
|
||||
"showShadowRootInWxmlPanel": true,
|
||||
"scopeDataCheck": false,
|
||||
"uglifyFileName": false,
|
||||
"checkInvalidKey": true,
|
||||
"checkSiteMap": true,
|
||||
"uploadWithSourceMap": true,
|
||||
"compileHotReLoad": false,
|
||||
"useMultiFrameRuntime": false,
|
||||
"useApiHook": false,
|
||||
"useApiHostProcess": false,
|
||||
"babelSetting": {
|
||||
"ignore": [],
|
||||
"disablePlugins": [],
|
||||
"outputPath": ""
|
||||
},
|
||||
"useIsolateContext": false,
|
||||
"userConfirmedBundleSwitch": false,
|
||||
"packNpmManually": false,
|
||||
"packNpmRelationList": [],
|
||||
"minifyWXSS": true,
|
||||
"disableUseStrict": false,
|
||||
"minifyWXML": true,
|
||||
"showES6CompileOption": false,
|
||||
"useCompilerPlugins": false
|
||||
},
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "2.3.0",
|
||||
"appid": "wx3ff81ef68814b084",
|
||||
"projectname": "ESPConfig",
|
||||
"simulatorType": "wechat",
|
||||
"simulatorPluginLibVersion": {},
|
||||
"condition": {},
|
||||
"editorSetting": {
|
||||
"tabIndent": "insertSpaces",
|
||||
"tabSize": 2
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
|
||||
"projectname": "ESPConfig",
|
||||
"setting": {
|
||||
"compileHotReLoad": true
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(blufi_demo)
|
||||
@@ -1,84 +0,0 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-IDF Blufi Example
|
||||
|
||||
This demo shows how to use the *Blufi* to configurate the Wi-Fi connection to AP.
|
||||
|
||||
The BluFi for ESP32 is a Wi-Fi network configuration function via Bluetooth channel. It provides a secure protocol to pass Wi-Fi configuration and credentials to the ESP32.
|
||||
|
||||
## How to Use Example
|
||||
|
||||
Before project configuration and build, be sure to set the correct chip target using:
|
||||
|
||||
```bash
|
||||
idf.py set-target <chip_name>
|
||||
```
|
||||
|
||||
To test this demo, you need to prepare a mobile phone with blufi application installed. You can download the blufi application from [Android version](https://github.com/EspressifApp/EspBlufi) and [iOS version](https://itunes.apple.com/cn/app/espblufi/id1450614082?mt=8).
|
||||
|
||||
Blufi is completely open source, here is the download link:
|
||||
|
||||
* [Blufi source code](https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/blufi)
|
||||
* [BluFi protocol](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ble/blufi.html)
|
||||
* [iOS source code](https://github.com/EspressifApp/EspBlufiForiOS)
|
||||
* [Android source code](https://github.com/EspressifApp/EspBlufi)
|
||||
* [Bluetooth Network User Guide CN](https://www.espressif.com/sites/default/files/documentation/esp32_bluetooth_networking_user_guide_cn.pdf)
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* A development board with ESP32/ESP32-C3/ESP32-S3/ESP32-C2 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
|
||||
* A USB cable for Power supply and programming
|
||||
|
||||
See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it.
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
```
|
||||
I (0) cpu_start: Starting scheduler on APP CPU.
|
||||
I (708) wifi:wifi driver task: 3ffbb118, prio:23, stack:6656, core=0
|
||||
I (708) system_api: Base MAC address is not set
|
||||
I (708) system_api: read default base MAC address from EFUSE
|
||||
I (718) wifi:wifi firmware version: 44799ff
|
||||
I (718) wifi:wifi certification version: v7.0
|
||||
I (718) wifi:config NVS flash: enabled
|
||||
I (718) wifi:config nano formatting: disabled
|
||||
I (728) wifi:Init data frame dynamic rx buffer num: 32
|
||||
I (728) wifi:Init management frame dynamic rx buffer num: 32
|
||||
I (738) wifi:Init management short buffer num: 32
|
||||
I (738) wifi:Init dynamic tx buffer num: 32
|
||||
I (748) wifi:Init static rx buffer size: 1600
|
||||
I (748) wifi:Init static rx buffer num: 10
|
||||
I (748) wifi:Init dynamic rx buffer num: 32
|
||||
I (758) wifi_init: rx ba win: 6
|
||||
I (758) wifi_init: tcpip mbox: 32
|
||||
I (768) wifi_init: udp mbox: 6
|
||||
I (768) wifi_init: tcp mbox: 6
|
||||
I (768) wifi_init: tcp tx win: 5744
|
||||
I (778) wifi_init: tcp rx win: 5744
|
||||
I (778) wifi_init: tcp mss: 1440
|
||||
I (788) wifi_init: WiFi IRAM OP enabled
|
||||
I (788) wifi_init: WiFi RX IRAM OP enabled
|
||||
I (798) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07
|
||||
I (908) wifi:mode : sta (fc:f5:c4:3c:62:90)
|
||||
I (908) wifi:enable tsf
|
||||
I (908) BTDM_INIT: BT controller compile version [1342a48]
|
||||
I (1198) BLUFI_EXAMPLE: BD ADDR: fc:f5:c4:3c:62:92
|
||||
|
||||
I (1198) BLUFI_EXAMPLE: BLUFI VERSION 0102
|
||||
|
||||
I (1198) BLUFI_EXAMPLE: BLUFI init finish
|
||||
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
|
||||
@@ -1,4 +0,0 @@
|
||||
idf_component_register(SRCS "blufi_example_main.c"
|
||||
"blufi_security.c"
|
||||
"blufi_init.c"
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -1,10 +0,0 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY
|
||||
int "WiFi connection maximum retry"
|
||||
range 0 255
|
||||
default 2
|
||||
help
|
||||
WiFi connection maximum retry, from 0 to 255.
|
||||
|
||||
endmenu
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#define BLUFI_EXAMPLE_TAG "BLUFI_EXAMPLE"
|
||||
#define BLUFI_INFO(fmt, ...) ESP_LOGI(BLUFI_EXAMPLE_TAG, fmt, ##__VA_ARGS__)
|
||||
#define BLUFI_ERROR(fmt, ...) ESP_LOGE(BLUFI_EXAMPLE_TAG, fmt, ##__VA_ARGS__)
|
||||
|
||||
void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free);
|
||||
int blufi_aes_encrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
int blufi_aes_decrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
uint16_t blufi_crc_checksum(uint8_t iv8, uint8_t *data, int len);
|
||||
|
||||
int blufi_security_init(void);
|
||||
void blufi_security_deinit(void);
|
||||
int esp_blufi_gap_register_callback(void);
|
||||
esp_err_t esp_blufi_host_init(void);
|
||||
esp_err_t esp_blufi_host_and_cb_init(esp_blufi_callbacks_t *callbacks);
|
||||
esp_err_t esp_blufi_host_deinit(void);
|
||||
esp_err_t esp_blufi_controller_init(void);
|
||||
esp_err_t esp_blufi_controller_deinit(void);
|
||||
@@ -1,18 +0,0 @@
|
||||
# Override some defaults so BT stack is enabled
|
||||
# in this example
|
||||
|
||||
#
|
||||
# Partition Table
|
||||
# (It's possible to fit Blufi in 1MB app partition size with some other optimizations, but
|
||||
# default config is close to 1MB.)
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
|
||||
|
||||
#
|
||||
# BT config
|
||||
#
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_GATTC_ENABLE=n
|
||||
CONFIG_BT_BLE_SMP_ENABLE=n
|
||||
CONFIG_BT_BLE_BLUFI_ENABLE=y
|
||||
CONFIG_MBEDTLS_HARDWARE_MPI=n
|
||||
CONFIG_MBEDTLS_DHM_C=y
|
||||
@@ -1,7 +0,0 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
CONFIG_IDF_TARGET="esp32"
|
||||
CONFIG_BT_ENABLED=y
|
||||
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
|
||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
||||
@@ -1,18 +0,0 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_NIMBLE_BLUFI_ENABLE=y
|
||||
# CONFIG_BT_GATTC_ENABLE is not set
|
||||
# CONFIG_BT_BLE_SMP_ENABLE is not set
|
||||
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
|
||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
||||
CONFIG_MBEDTLS_DHM_C=y
|
||||
# The config items for NIMBLE HOST
|
||||
CONFIG_BT_NIMBLE_ENABLED=y
|
||||
CONFIG_BT_NIMBLE_ROLE_CENTRAL=n
|
||||
CONFIG_BT_NIMBLE_ROLE_OBSERVER=n
|
||||
CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n
|
||||
CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
|
||||
CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=n
|
||||
@@ -1,7 +0,0 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
CONFIG_IDF_TARGET="esp32c3"
|
||||
CONFIG_BT_ENABLED=y
|
||||
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
|
||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
||||
@@ -1,18 +0,0 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_NIMBLE_BLUFI_ENABLE=y
|
||||
# CONFIG_BT_GATTC_ENABLE is not set
|
||||
# CONFIG_BT_BLE_SMP_ENABLE is not set
|
||||
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
|
||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
||||
CONFIG_MBEDTLS_DHM_C=y
|
||||
# The config items for NIMBLE HOST
|
||||
CONFIG_BT_NIMBLE_ENABLED=y
|
||||
CONFIG_BT_NIMBLE_ROLE_CENTRAL=n
|
||||
CONFIG_BT_NIMBLE_ROLE_OBSERVER=n
|
||||
CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n
|
||||
CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
|
||||
CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=n
|
||||
@@ -1,7 +0,0 @@
|
||||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
CONFIG_IDF_TARGET="esp32s3"
|
||||
CONFIG_BT_ENABLED=y
|
||||
# CONFIG_BT_BLE_50_FEATURES_SUPPORTED is not set
|
||||
CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y
|
||||
@@ -4,22 +4,22 @@
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "dbcfd28f34b2a13b",
|
||||
"id": "8ff7430257e8e5f4",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "ba89e06e4ba5dcbd",
|
||||
"id": "c787cb3c2720eaca",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
|
||||
"file": "10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/42步进电机.md",
|
||||
"mode": "source",
|
||||
"source": false,
|
||||
"backlinks": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "SG90舵机"
|
||||
"title": "42步进电机"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -69,7 +69,7 @@
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300
|
||||
"width": 240.5
|
||||
},
|
||||
"right": {
|
||||
"id": "5efe8913089ec8d6",
|
||||
@@ -85,13 +85,13 @@
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
|
||||
"file": "10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/42步进电机.md",
|
||||
"followCursor": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-list",
|
||||
"title": "SG90舵机 的大纲"
|
||||
"title": "42步进电机 的大纲"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -107,23 +107,39 @@
|
||||
"templates:插入模板": false
|
||||
}
|
||||
},
|
||||
"active": "ba89e06e4ba5dcbd",
|
||||
"active": "70853e127a5d7008",
|
||||
"lastOpenFiles": [
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/28BYJ-48步进电机.md",
|
||||
"04.外设学习/4.1-基础外设/4.1.6-LED_PWM/LED_PWM控制.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments/Pasted image 20250528152414.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments/Pasted image 20250528152307.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527165130.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527163637.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527163522.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527162100.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments/Pasted image 20250527161829.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.4-rc522模块/rc522模块.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/42步进电机.md",
|
||||
"目录.md",
|
||||
"04.外设学习/4.1-基础外设/4.1.1-GPIO/GPIO入门.md",
|
||||
"attachments/Templates.md",
|
||||
"attachments/20250202192226.png",
|
||||
"04.外设学习/4.3-其他外设/4.3.3-RMT/RMT.md",
|
||||
"04.外设学习/4.3-其他外设/4.3.2-TWAI/TWAI.md",
|
||||
"04.外设学习/4.3-其他外设/4.3.3-RMT",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.4-rc522模块/attachments/Pasted image 20250624174842.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.4-rc522模块/attachments/Pasted image 20250624174733.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.4-rc522模块/attachments/Pasted image 20250624165127.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.4-rc522模块/attachments",
|
||||
"04.外设学习/4.1-基础外设/4.1.9-I2S/I2S入门.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.4-rc522模块",
|
||||
"04.外设学习/4.1-基础外设/4.1.7-I2C/I2C通信.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/28BYJ-48步进电机.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/SG90舵机.md",
|
||||
"04.外设学习/4.3-其他外设/4.3.1-MCPWM/MCPWM.md",
|
||||
"04.外设学习/4.3-其他外设/4.3.2-TWAI",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/attachments/Pasted image 20250604165352.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/attachments/Pasted image 20250604164929.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/attachments/Pasted image 20250604164852.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/attachments/Pasted image 20250604162407.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/attachments/Pasted image 20250604162227.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/attachments/Pasted image 20250604162038.png",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机/attachments",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.3-42步进电机",
|
||||
"04.外设学习/4.1-基础外设/4.1.6-LED_PWM/LED_PWM控制.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.2-SG90舵机/attachments",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机/attachments",
|
||||
"04.外设学习/4.1-基础外设/4.1.1-GPIO/GPIO入门.md",
|
||||
"04.外设学习/4.1-基础外设/4.1.4-ADC/ADC模数转换.md",
|
||||
"01.认识ESP32/1.1-ESP32介绍/ESP32介绍.md",
|
||||
"00.常见问题及解决方案/常见问题及解决方案.md",
|
||||
@@ -131,12 +147,7 @@
|
||||
"10.项目实战/10.1-模块驱动案例/未命名.md",
|
||||
"10.项目实战/10.1-模块驱动案例/10.1.1-28BYJ-48步进电机",
|
||||
"04.外设学习/4.4-外设使用案例/未命名.md",
|
||||
"04.外设学习/4.4-外设使用案例/未命名",
|
||||
"10.项目实战/10.1-模块驱动案例",
|
||||
"00.常见问题及解决方案/attachments/20250210094506.png",
|
||||
"attachments/20250202192226.png",
|
||||
"01.认识ESP32/1.2-ESP32开发环境搭建/1.环境搭建-Windows.md",
|
||||
"03.FreeRTOS基础/3.4-FreeRTOS软件定时器/FreeRTOS软件定时器.md",
|
||||
"00.常见问题及解决方案/attachments/20250506154522.png"
|
||||
"03.FreeRTOS基础/3.4-FreeRTOS软件定时器/FreeRTOS软件定时器.md"
|
||||
]
|
||||
}
|
||||
@@ -29,10 +29,8 @@ Inter-IC Sount Bus(I2S)是飞利浦半导体公司(现为恩智浦半导体公
|
||||
|
||||
**SCK: (continuous serial clock) 串行时钟**:标准名称为“连续串列主频”
|
||||
|
||||
|
||||
**WS: (word select) 字段(声道)选择:** 也称为“帧同步线”
|
||||
|
||||
|
||||
**SD: (serial data) 串行数据 :** 也可称为SDATA,SDIN,SDOUT,DACDAT,ADCDAT等
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
# 双线汽车接口 (TWAI) -(CAN)
|
||||
|
||||
> [!TIP] 🚀 ESP32 外设之双线汽车接口 (TWAI) |
|
||||
> - 💡 **碎碎念**😎:本节将介绍 ESP32 的双线汽车接口 (TWAI) ,他是是一种适用于汽车和工业应用的实时串行通信协议。
|
||||
> - 📺 **视频教程**:🚧 *开发中*
|
||||
> - 💾 **示例代码**:🚧 *开发中*
|
||||
|
||||
双线汽车接口 (TWAI) 是一种适用于汽车和工业应用的实时串行通信协议。它兼容 ISO11898-1 经典帧,因此可以支持标准帧格式(11 位 ID)和扩展帧格式(29 位 ID)。ESP32 包含 1 个 TWAI 控制器,经配置可以在 TWAI 总线上使用外部收发器通信。
|
||||
|
||||
注意:TWAI 控制器不兼容 ISO11898-1 FD 格式帧,并会将这些帧解析为错误。
|
||||
|
||||
## 一、前言简介
|
||||
|
||||
- 简介:TWAI(Two-Wire Automotive Interface)是 ESP32 提供的 CAN 协议兼容实现。
|
||||
- 协议兼容性:支持 ISO11898-1 标准帧和扩展帧格式,不支持 CAN-FD。
|
||||
- 应用场景:
|
||||
- 车载设备通信
|
||||
- 工业自动化系统
|
||||
- 多主多从嵌入式网络
|
||||
|
||||
---
|
||||
|
||||
## 二、协议基础
|
||||
|
||||
- TWAI = Classic CAN(兼容)
|
||||
- 帧格式:
|
||||
- 标准帧(11 位 ID)
|
||||
- 扩展帧(29 位 ID)
|
||||
- 数据帧、远程帧、错误帧
|
||||
- 仲裁机制与优先级
|
||||
- 位定时与波特率选择(如 500kbps)
|
||||
|
||||
---
|
||||
|
||||
## 三、硬件准备
|
||||
|
||||
- ESP32 模块(推荐 WROOM/WROVER 系列)
|
||||
- CAN 收发器(如 SN65HVD230、TJA1050)
|
||||
- 接线说明:
|
||||
- ESP32 TX ➝ 收发器 TXD
|
||||
- ESP32 RX ➝ 收发器 RXD
|
||||
- CANH、CANL ➝ 总线
|
||||
- 加 120Ω 终端电阻于总线两端
|
||||
- 电源要求与隔离建议(如长距离通信建议使用隔离型收发器)
|
||||
|
||||
---
|
||||
|
||||
## 四、软件环境配置(ESP-IDF)
|
||||
|
||||
- 驱动初始化步骤:
|
||||
- `twai_driver_install()`
|
||||
- `twai_start()`
|
||||
- 主要结构体:
|
||||
- `twai_message_t`:数据帧定义
|
||||
- `twai_general_config_t`、`twai_timing_config_t`、`twai_filter_config_t`
|
||||
- 示例配置波特率、引脚、模式等参数
|
||||
- 使用 FreeRTOS 任务接收数据(推荐)
|
||||
|
||||
---
|
||||
|
||||
## 五、发送与接收示例
|
||||
|
||||
- ✅ 发送帧示例(标准帧、扩展帧)
|
||||
- ✅ 接收帧示例(阻塞与非阻塞)
|
||||
- 🔁 循环发送测试数据
|
||||
- 🛑 超时处理和帧校验
|
||||
- 🚦 使用中断或轮询方式收发
|
||||
|
||||
---
|
||||
|
||||
## 六、调试与验证
|
||||
|
||||
- 使用逻辑分析仪/示波器查看 CANH/CANL 波形
|
||||
- 多设备组网互通验证(例如连接另一个 STM32/开发板)
|
||||
- 常见问题排查:
|
||||
- 没有数据 ➝ 检查终端电阻、电压、接线
|
||||
- 接收错误 ➝ 检查帧格式、波特率一致性
|
||||
- 控制器状态 ➝ 使用 `twai_get_status_info()` 查看错误码
|
||||
|
||||
---
|
||||
|
||||
## 七、高级应用(可选)
|
||||
|
||||
- 设置 ID 过滤器(精确匹配 / 范围匹配)
|
||||
- 发送优先级控制(低 ID = 高优先级)
|
||||
- 状态监测:总线关闭、错误计数
|
||||
- 灵活切换正常模式 / 回环模式 / 监听模式
|
||||
|
||||
---
|
||||
|
||||
## 八、总结与资料
|
||||
|
||||
- 官方文档:
|
||||
- [ESP-IDF TWAI 文档](https://docs.espressif.com/projects/esp-idf/zh/latest/esp32/api-reference/peripherals/twai.html)
|
||||
- 推荐资料:
|
||||
- CAN 协议详解(推荐阅读 Bosch CAN spec)
|
||||
- 收发器芯片选型参考
|
||||
- 视频教程:🚧 *开发中*
|
||||
- 示例代码:🚧 *开发中*
|
||||
@@ -0,0 +1,4 @@
|
||||
# 红外遥控 (RMT)
|
||||
|
||||
|
||||
红外遥控 (RMT) 外设是一个红外发射和接收控制器。其数据格式灵活,可进一步扩展为多功能的通用收发器,发送或接收多种类型的信号。就网络分层而言,RMT 硬件包含物理层和数据链路层。物理层定义通信介质和比特信号的表示方式,数据链路层定义 RMT 帧的格式。
|
||||
@@ -0,0 +1,108 @@
|
||||
|
||||
# ESP32驱动42步进电机
|
||||
|
||||
> [!TIP] 🚀 ESP32驱动42步进电机 | XXXXX
|
||||
> - 💡 **碎碎念**😎:本节将介绍XXXXXXXXXXXXXXXXXXX
|
||||
> - 📺 **视频教程**:🚧 *开发中*
|
||||
> - 💾 **示例代码**:🚧 *开发中*
|
||||
>
|
||||
|
||||
## 一、介绍
|
||||
|
||||
### 1.1 什么是42步进电机?
|
||||
|
||||
42步进电机是一种常见的小型两相步进电机,因其电机外壳边长为 42mm 而得名(即 NEMA 17 尺寸标准)。该类电机广泛应用于 3D打印机、激光雕刻机、CNC加工设备、机器人 等对位置控制要求较高的场景。
|
||||
|
||||
常见参数如下:
|
||||
|
||||
- 步距角:1.8°(每转200步)或 0.9°(每转400步)
|
||||
- 工作电压:一般为 12V 或 24V
|
||||
- 峰值电流:0.8A ~ 2A
|
||||
|
||||
### 1.2 步进电机工作原理
|
||||
|
||||
步进电机是一种将电脉冲信号转换为角位移的电机。当控制器发出一个脉冲信号,电机就按照设定角度旋转一步。通过调节脉冲频率,可以控制电机的转速;通过控制脉冲数量,可以精准控制角位移。
|
||||
|
||||
具体的工作原理在此不再赘述,大家可自行上网查阅。由于其不需要编码器即可进行位置控制,特别适合需要开环控制的系统。
|
||||
|
||||
下面简单对比步进电机与直流电机 / 伺服电机的区别:
|
||||
|
||||
| 特性 | 步进电机 | 直流电机 | 伺服电机 |
|
||||
| ---- | --------------- | --------- | ---------- |
|
||||
| 控制方式 | 开环(可闭环) | 电压/电流控制 | 闭环(带编码器) |
|
||||
| 精度 | 高(0.9°\~1.8°/步) | 低 | 非常高(编码器支持) |
|
||||
| 启停性能 | 好 | 中 | 非常好 |
|
||||
| 振动噪音 | 较大(尤其低速) | 小 | 极小 |
|
||||
| 价格 | 便宜 | 更便宜 | 昂贵 |
|
||||
| 适合应用 | 中低速定位控制 | 普通旋转/风扇/泵 | 高速高精定位控制 |
|
||||
|
||||
值得注意的是,我们需要了解一下细分技术:
|
||||
|
||||
传统步进电机的步距角通常为 1.8°(每圈 200 步),在一些对平稳性和精度要求更高的场合,1.8° 的步进角可能仍然过大,运行过程中会出现抖动、不平滑等问题。为此,引入了 细分驱动(Microstepping) 技术。
|
||||
|
||||
细分驱动器不是简单地控制电机绕组全电流通断,而是通过 PWM 控制 或 电流恒流分级控制,将每个完整步细分为若干个微小步。比如:
|
||||
|
||||
- 半步细分:每步 0.9°,一圈 400 步;
|
||||
- 1/8 细分:每步 0.225°,一圈 1600 步;
|
||||
- 1/16 细分:每步 0.1125°,一圈 3200 步;
|
||||
|
||||
细分的优势在于提高分辨率和控制精度,运行更平滑、减少共振,降低噪音和震动和改善电机低速运行性能。虽然细分技术能提高控制平滑度,但并不能无限提高“实际定位精度”,因为电机本身的机械和磁滞误差仍然存在。高细分主要用于改善运动特性,而不是绝对定位精度。并且市面上常见的步进电机驱动器基本都支持细分。
|
||||
### 1.3 常用驱动器
|
||||
|
||||
步进电机无法直接由电源驱动,必须通过驱动器精确控制线圈的电流方向与大小。以下是几种常用驱动器及其特点:
|
||||
#### 1. A4988 驱动芯片
|
||||
|
||||
A4988 是一种体积小、成本低的双极步进电机驱动模块,广泛应用于 3D 打印机、桌面级 CNC 等入门级设备。它支持全步、半步、1/4、1/8 和 1/16 微步细分,并带有可调电流限制功能。模块自带过热保护和欠压保护,接口简单、体积小巧,适合面包板快速开发。但需要注意的是,该模块在高电流下易发热,接线错误或通电顺序错误容易烧毁,因此在使用时要特别注意接线安全与散热。
|
||||
|
||||

|
||||
#### 2. tb6600 驱动器
|
||||
|
||||
TB6600 驱动器是面向工业级场景设计的中功率步进电机驱动器,支持工作电压 9V 到 42V,最大输出电流可达 4.5A,常用于控制较大扭矩的 42、57、86 步进电机。它支持的细分模式从全步到 32步,用户可通过拨码开关手动配置。TB6600 驱动器通常带有铝合金壳体和散热片,接口清晰,安装方便,适用于 CNC 雕刻机、激光切割、机械臂等中大型场合。相比 A4988,TB6600 功率更大、稳定性更好,但体积较大,不适合空间受限的设计,且价格略高。
|
||||
|
||||

|
||||
|
||||
#### 3.DRV8825驱动芯片
|
||||
|
||||
DRV8825 是德州仪器推出的一款高性能步进电机驱动器,与 A4988 引脚兼容但性能更强。其支持最多 1/32 步细分。相比 A4988,它支持更高的工作电压,能够在更高速度下提供更大的扭矩,同时运行更安静,抖动更小。它适用于对噪音和稳定性有更高要求的项目,如中高端 3D 打印机或机器人项目。不过也需注意散热问题,可以在模块上添加散热片。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 二、使用
|
||||
|
||||
下面简单介绍一下使用ESP32配合DRV8825驱动芯片驱动42步进电机:
|
||||
|
||||
首先介绍DRV8825驱动模块,我们买到的DRV8825步进驱动模块一般如下图:
|
||||
|
||||

|
||||
|
||||
DRV8825 是德州仪器设计的集成电机驱动芯片。 芯片内部集成了2个H桥电路和1/32微步进分度器, 可以驱动一个双极型电机或两个直流有刷电机。主要有如下特点:
|
||||
|
||||
1. 适合驱动8.2V~45V2.5A以下的步进电机:
|
||||
2. 只有简单的步进和方向控制接口;
|
||||
3. 六个不同的步进模式:全、半、1/4、1/8、1/16、1/32;
|
||||
4. 可调电位器可以调节最大电流输出,从而获得更高的步进率;
|
||||
5. 自动电流衰减模式检测/选择;
|
||||
6. 过热关闭电路、欠压锁定、交叉电流保护;
|
||||
|
||||
它的引脚定义是这样的:
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
这是芯片手册中的简化控制示意图:
|
||||
|
||||

|
||||
|
||||
## 三、示例
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 参考链接
|
||||
|
||||
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 234 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 342 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 128 KiB |
@@ -0,0 +1,140 @@
|
||||
# ESP32驱动RC522模块与 RFID / NFC 卡通信
|
||||
|
||||
> [!TIP] 🚀 ESP32驱动RC522射频IC卡识别模块 | 轻松实现 RFID / NFC 卡通信
|
||||
>
|
||||
> * 💡 **碎碎念**😎:本节将介绍如何使用 ESP32 驱动 RC522 模块,快速实现 RFID/NFC 卡片的检测和读取。
|
||||
> * 📺 **视频教程**:🚧 *开发中*
|
||||
> * 💾 **示例代码**:🚧 *开发中*
|
||||
|
||||
## 一、介绍
|
||||
|
||||

|
||||
|
||||
RC522 是一款常见的 RFID 读卡器模块,工作在 **13.56MHz** 频段,支持对标准 NFC / IC 卡片进行检测和通信。结合 ESP32 可快速构建:
|
||||
|
||||
* 门禁控制器
|
||||
* NFC 标签检测器
|
||||
* RFID 学生证管理器
|
||||
* 简单的考勤、登录、支付等应用场景
|
||||
|
||||
RC522 通常通过 **SPI 接口** 与 ESP32 通信,库和示例代码完善,适合入门和快速验证。
|
||||
|
||||
## 二、使用
|
||||
|
||||
### 1️⃣ 硬件连接
|
||||
|
||||
| ESP32引脚 | RC522引脚 | 功能 |
|
||||
| ------- | ------- | -------- |
|
||||
| 3V3 | 3.3V | 供电 |
|
||||
| GND | GND | 地线 |
|
||||
| GPIO18 | SCK | SPI时钟 |
|
||||
| GPIO19 | MISO | SPI MISO |
|
||||
| GPIO23 | MOSI | SPI MOSI |
|
||||
| GPIO5 | RST | 重置 |
|
||||
| GPIO4 | SDA | SPI片选 |
|
||||
|
||||
### 2️⃣ 配套库
|
||||
|
||||
* ESP-IDF: https://components.espressif.com/components/abobija/rc522/versions/3.3.2/versions?language=en
|
||||
|
||||
### 3️⃣ 通信流程
|
||||
|
||||
1. ESP32 通过 SPI 与 RC522 通信。
|
||||
2. 检测是否有 RFID/NFC 标签进入。
|
||||
3. 获取 UID。
|
||||
4. 可选:读取或写入 IC 卡数据。
|
||||
|
||||
## 三、示例
|
||||
|
||||
接线:
|
||||
|
||||
``` c
|
||||
#define RC522_SPI_BUS_GPIO_MISO (25)
|
||||
#define RC522_SPI_BUS_GPIO_MOSI (23)
|
||||
#define RC522_SPI_BUS_GPIO_SCLK (19)
|
||||
#define RC522_SPI_SCANNER_GPIO_SDA (22)
|
||||
```
|
||||
|
||||

|
||||
|
||||
代码:
|
||||
|
||||
```cpp
|
||||
#include <esp_log.h>
|
||||
#include "rc522.h"
|
||||
#include "driver/rc522_spi.h"
|
||||
#include "rc522_picc.h"
|
||||
|
||||
static const char *TAG = "rc522-basic-example";
|
||||
|
||||
#define RC522_SPI_BUS_GPIO_MISO (25)
|
||||
#define RC522_SPI_BUS_GPIO_MOSI (23)
|
||||
#define RC522_SPI_BUS_GPIO_SCLK (19)
|
||||
#define RC522_SPI_SCANNER_GPIO_SDA (22)
|
||||
#define RC522_SCANNER_GPIO_RST (-1)
|
||||
|
||||
static rc522_spi_config_t driver_config = {
|
||||
.host_id = SPI2_HOST,
|
||||
.bus_config = &(spi_bus_config_t){
|
||||
.miso_io_num = RC522_SPI_BUS_GPIO_MISO,
|
||||
.mosi_io_num = RC522_SPI_BUS_GPIO_MOSI,
|
||||
.sclk_io_num = RC522_SPI_BUS_GPIO_SCLK,
|
||||
},
|
||||
.dev_config = {
|
||||
.spics_io_num = RC522_SPI_SCANNER_GPIO_SDA,
|
||||
},
|
||||
.rst_io_num = RC522_SCANNER_GPIO_RST,
|
||||
};
|
||||
|
||||
static rc522_driver_handle_t driver;
|
||||
static rc522_handle_t scanner;
|
||||
|
||||
static void on_picc_state_changed(void *arg, esp_event_base_t base, int32_t event_id, void *data)
|
||||
{
|
||||
rc522_picc_state_changed_event_t *event = (rc522_picc_state_changed_event_t *)data;
|
||||
rc522_picc_t *picc = event->picc;
|
||||
|
||||
if (picc->state == RC522_PICC_STATE_ACTIVE) {
|
||||
rc522_picc_print(picc);
|
||||
}
|
||||
else if (picc->state == RC522_PICC_STATE_IDLE && event->old_state >= RC522_PICC_STATE_ACTIVE) {
|
||||
ESP_LOGI(TAG, "Card has been removed");
|
||||
}
|
||||
}
|
||||
|
||||
void app_main()
|
||||
{
|
||||
rc522_spi_create(&driver_config, &driver);
|
||||
rc522_driver_install(driver);
|
||||
|
||||
rc522_config_t scanner_config = {
|
||||
.driver = driver,
|
||||
};
|
||||
|
||||
rc522_create(&scanner_config, &scanner);
|
||||
rc522_register_events(scanner, RC522_EVENT_PICC_STATE_CHANGED, on_picc_state_changed, NULL);
|
||||
rc522_start(scanner);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
效果:
|
||||
|
||||

|
||||
|
||||
|
||||
### 其他
|
||||
|
||||
在使用esp-idf-rc522这个库时,发现通信引脚不能随意配置
|
||||
|
||||
对于ESP32来说,能够正常使用的配置如下:
|
||||
|
||||
```
|
||||
#define RC522_SPI_BUS_GPIO_MISO (25)
|
||||
#define RC522_SPI_BUS_GPIO_MOSI (23)
|
||||
#define RC522_SPI_BUS_GPIO_SCLK (19)
|
||||
#define RC522_SPI_SCANNER_GPIO_SDA (22)
|
||||
#define RC522_SCANNER_GPIO_RST (-1)
|
||||
```
|
||||
|
||||
具体见: https://github.com/abobija/esp-idf-rc522/issues/71
|
||||