Last active
November 28, 2018 12:36
-
-
Save satakagi/dd6d9a83764529be368b9a73a2ce9f85 to your computer and use it in GitHub Desktop.
PWM H-Bridhe Motor Driver for CHIRIMEN RPi3 using L298N and PCA9685 CASE-1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// サーボではなく、純粋にPWM出力装置としてPCA9685を使います | |
// based on http://www.geocities.jp/zattouka/GarageHouse/micon/Motor/PCA9685/shield1.htm | |
// Programmed by Satoru Takagi | |
var PCA9685_PWM = function(i2cPort,slaveAddress){ | |
this.i2cPort = i2cPort; | |
this.i2cSlave = null; | |
this.slaveAddress = slaveAddress; | |
this.frequency=null; | |
}; | |
PCA9685_PWM.prototype = { | |
sleep: function(ms){ | |
return new Promise((resolve)=>{setTimeout(resolve,ms);}); | |
}, | |
init: async function(frequency,noSetZero){ | |
// frequency : in Hz | |
// angleRange : -angleRange to +angleRange degrees | |
if(this.frequency){ | |
console.log("alredy initialised"); | |
} | |
if ( frequency ){ | |
this.frequency = frequency; | |
} else { | |
this.frequency = 60; // default: 60Hz | |
} | |
var freq = Math.floor((25000000/(4096*this.frequency))-1); | |
if ( freq < 0x03 || freq > 0xff ){ | |
throw Error("Frequency should be between 24Hz to 1526Hz"); | |
} | |
var i2cSlave = await this.i2cPort.open(this.slaveAddress); | |
this.i2cSlave = i2cSlave; | |
await this.i2cSlave.write8(0x00,0x00); | |
await this.i2cSlave.write8(0x01,0x04); | |
await this.i2cSlave.write8(0x00,0x10); | |
await this.i2cSlave.write8(0xfe,freq); | |
await this.i2cSlave.write8(0x00,0x00); | |
await this.i2cSlave.write8(0x06,0x00); | |
await this.i2cSlave.write8(0x07,0x00); | |
await this.sleep(300); | |
if ( !noSetZero ){ | |
for ( var pwmPort = 0 ; pwmPort < 16 ; pwmPort ++ ){ | |
await this.setPWM(pwmPort , 0 ); | |
} | |
} | |
}, | |
setPWM: async function(pwmPort,dutyRatio){ | |
// dutyRatio : 0.0(OFF) .. 1.0(ON) | |
// console.log(pwmPort,angle) | |
const portStart = 8; | |
const portInterval = 4; | |
if(this.i2cSlave == null){ | |
throw Error("i2cSlave Address does'nt yet open!"); | |
} | |
if ( pwmPort < 0 || pwmPort > 15 ){ | |
throw Error("PWM Port should be between 0 to 15"); | |
} | |
if ( dutyRatio < 0 || dutyRatio > 1 ){ | |
throw Error("dutyRatio should be between 0.0 to 1.0"); | |
} | |
var ticks = Math.floor(4095 * dutyRatio); | |
var tickH = (( ticks >> 8 ) & 0x0f); | |
var tickL = (ticks & 0xff); | |
var pwm = Math.round(portStart + pwmPort * portInterval); | |
await this.i2cSlave.write8( pwm + 1, tickH); | |
await this.i2cSlave.write8( pwm, tickL); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>GPIO-I2C-PWMHBridge</title> | |
</head> | |
<body> | |
<script src="../../../polyfill/polyfill.js"></script> | |
<script src="../../drivers/i2c-PCA9685_PWM.js"></script> | |
<script src="pwhb.js"></script> | |
<h1>GPIO H-Bridge Motor drive (with PWM)</h1> | |
<input type="button" onclick="free()" value="BRAKE"></input> | |
<input type="button" onclick="fwd()" value="FOWARD"></input> | |
<input type="button" onclick="rev()" value="REVERSE"></input> | |
<!-- <input type="button" onclick="brake()" value="BRAKE"></input> L298NではGPIO 0,0でもブレーキモードになるらしい --> | |
<br> | |
<input type="button" onclick="pwm(0)" value="0%(FREE)"></input> <!-- PWM 0%を指定することでフリーになるらしい --> | |
<input type="button" onclick="pwm(0.2)" value="20%"></input> | |
<input type="button" onclick="pwm(0.4)" value="40%"></input> | |
<input type="button" onclick="pwm(0.6)" value="60%"></input> | |
<input type="button" onclick="pwm(0.8)" value="80%"></input> | |
<input type="button" onclick="pwm(1.0)" value="100%"></input> | |
<div> | |
<img src="PWMHBridge.png" height="500"> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Hブリッジモータードライバは正転[1,0]・逆転[0,1]・ブレーキ[1,1]・フリー[0,0]の4状態を | |
// GPIOの2つの信号線を使って指示します | |
// さらにPCA9685のPWMをEnableラインに入力して速度をコントロールします。 | |
var portAddrs = [20,21]; // HブリッジコントローラをつなぐGPIOポート番号 | |
var portPromise; | |
var pca9685pwmPromise; | |
onload =async function(){ // ポートを初期化するための非同期関数 | |
try{ | |
console.log("onload"); | |
var gpioAccess = await navigator.requestGPIOAccess(); // thenの前の関数をawait接頭辞をつけて呼び出します。 | |
var ports = []; | |
var i2cAccess = await navigator.requestI2CAccess(); | |
var i2cPort = i2cAccess.ports.get(1); | |
var pca9685pwm = new PCA9685_PWM(i2cPort, 0x40); | |
await pca9685pwm.init(100); | |
for ( var i = 0 ; i < 2 ; i++ ){ | |
ports[i] = gpioAccess.ports.get(portAddrs[i]); | |
await ports[i].export("out"); | |
} | |
for ( var i = 0 ; i < 2 ; i++ ){ | |
ports[i].write(0); | |
} | |
portPromise = ports; | |
pca9685pwmPromise = pca9685pwm; | |
} catch (error) { | |
console.error("error", error); | |
} | |
} | |
async function pwm(ratio){ | |
var pca9685pwm = await pca9685pwmPromise; | |
await pca9685pwm.setPWM(0,ratio); | |
} | |
async function free(){ | |
var ports = await portPromise; | |
ports[0].write(0); | |
ports[1].write(0); | |
} | |
async function brake(){ | |
var ports = await portPromise; | |
ports[0].write(1); | |
ports[1].write(1); | |
await sleep(300); // 300ms待機してフリー状態にします | |
ports[0].write(0); | |
ports[1].write(0); | |
} | |
async function fwd(){ | |
var ports = await portPromise; | |
ports[0].write(1); | |
ports[1].write(0); | |
} | |
async function rev(){ | |
var ports = await portPromise; | |
ports[0].write(0); | |
ports[1].write(1); | |
} | |
// 単に指定したms秒スリープするだけの非同期処理関数 | |
// この関数の定義方法はとりあえず気にしなくて良いです。コピペしてください。 | |
function sleep(ms){ | |
return new Promise( function(resolve) { | |
setTimeout(resolve, ms); | |
}); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
このコードの実体配線図はこちら