2016年9月5日月曜日

ブラウザからDCモータを制御

というわけで、せっかくのESP-WROOM-02なので、ブラウザから(というかhttpで)モータを制御するようにプログラム書き換えました。

配線は前回のままです。起動するとIPアドレスが表示されますので、そのIPアドレスにパラメータをつけると制御できます。

http://<ip-address>?brake=0 : ブレーキがかかります
http://<ip-address>?r=40:速度指令40でモータを正転させます
http://<ip-address>?r=-40:速度指令40でモータを逆転させます。

ま、rじゃなくてもbrake以外なら何でも良いんですが。

ソース乗っけておきます。


// DRV8830 control over http / ESP-WROOM-02
//
// Thanks :
// HelloServer : a Sample program for ESP8266
//
const int LED = 13;
const int kMaxSpeed = 0x3f;
//
// Wifi
//
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include "private_ssid.h"
//const char *ssid = "******************";
//const char *password = "******************";
ESP8266WebServer server(80);
//
// Wire / DRV8830
//
#include <Wire.h>
const int kDrv8830Address = 0x64;
const int kBitClear = 0x80;
const int kBitILimit = 0x10;
const int kBitOTS = 0x08;
const int kBitUVLO = 0x04;
const int kBitOCP = 0x02;
const int kBitFault = 0x01;
//
// Setup
//
void setup() {
Serial.begin(115200);
Wire.begin();
//
// Wifi Server
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/inline", []() {
server.send(200, "text/plain", "this works as well");
});
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
//
// Loop
//
float r = 0;
void loop() {
//
// http server
server.handleClient();
}
//
// WebServer
//
void handleRoot() {
digitalWrite(LED, HIGH);
for (int i = 0; i < server.args(); i++) {
char *cStr = (char *)server.argName(i).c_str();
Serial.print("received=");
Serial.print((char *)server.argName(i).c_str());
Serial.print("=");
Serial.println(server.arg(i).c_str());
if (strcmp(cStr, "brake") == 0) {
brakeMotor();
} else {
int value = atoi(server.arg(i).c_str());
if (value > kMaxSpeed) value = kMaxSpeed;
if (value < -kMaxSpeed) value = -kMaxSpeed;
Serial.println(value);
runMotor(value);
}
}
int status = readMotorStatus();
char buf[100];
sprintf(buf, "drv8830 result = %02x", status);
if (status != 0) {
resetMotorStatus();
}
server.send(200, "text/plain", buf);
digitalWrite(LED, LOW);
}
void handleNotFound() {
digitalWrite(LED, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(LED, 0);
}
//
// DRV8830
//
uint8_t readMotorStatus() {
uint8_t result = 0x00;
Wire.beginTransmission(kDrv8830Address);
Wire.write(0x01); // read register 0x01
Wire.endTransmission();
Wire.requestFrom(kDrv8830Address, 1);
if (Wire.available()) {
result = Wire.read();
} else {
Serial.println("No status data");
}
return result;
}
void resetMotorStatus() {
Wire.beginTransmission(kDrv8830Address);
Wire.write(0x01); // fault
Wire.write(0x80); // clear
Wire.endTransmission(true);
}
void runMotor(int inVector) {
int direction;
int voltage;
if (inVector > 0) {
direction = 0x01;
voltage = inVector;
} else if (inVector == 0) {
direction = 0x00;
voltage = 0;
} else {
direction = 0x02;
voltage = -inVector;
}
writeToDriver(direction, voltage);
}
void brakeMotor() {
writeToDriver(0x03, 0x00);
}
void writeToDriver(byte inDirection, byte inVoltage) {
if (inVoltage <= 0x05) inVoltage = 0x06; // minimum voltage valu is 0x06.
int outData = (inVoltage & 0x3f) << 2 | (inDirection & 0x03);
Wire.beginTransmission(kDrv8830Address);
Wire.write(0x00); // control
Wire.write(outData); //
Wire.endTransmission(true);
delay(12);
}

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。