【概要】
PC(Processing)からLAN(TCP)通信でコマンドを受けて、mbed側でRCサーボモータを制御する。
ベースボードにはStarBoard Orangeを使用した。
RCサーボモータの電源+5VはUSBからは取らずに、ACアダプターから供給する。
Processing側のプログラムは(その2)を参照してください。
【配線】(サーボ1個分のみ示す)
mbed側 RCサーボモータ側(メーカによって色が異なるので注意)
P21 ―――――――― 白(黄)
VIN ―――――――― 赤
GND ―――――――― 黒
【通信コマンドのフォーマット】
【mbed側のプログラム】
以下のライブラリをインポートしておく。
・EthernetNetIf
・Servo
・TextLCD (必要に応じて)
//---- ここから --------------------------------------------
// 異常処理は手抜きしているので必要に応じて追加してください。
#include "mbed.h"
#include "EthernetNetIf.h"
#include "TCPSocket.h"
#include "TextLCD.h"
#include "Servo.h"
TextLCD lcd(p24, p26, p27, p28, p29, p30); // rs, e, d0-d3
Servo servo1(p21);
Servo servo2(p22);
Servo servo3(p23);
//EthernetNetIf eth; // <-DHCPを使うときはこちらを使う
EthernetNetIf eth( // ここは自分の環境に合わせて変更する
IpAddr(192,168,0,100), // mbedに割り当てるIPアドレス
IpAddr(255,255,255,0), // MASK
IpAddr(192,168,0,200), // GATEWAY
IpAddr(192,168,0,200) // DNS
);
TCPSocket listensock;
TCPSocket *sock;
Serial pc(USBTX, USBRX);
unsigned char buff[30];
int RecvCount = 0;
int ParamLen = 0;
int ParamCount = 0;
void Recv(unsigned char data);
void ServoCmdExec();
void onTCPSocketEvent (TCPSocketEvent e) {
switch (e) {
case TCPSOCKET_CONNECTED: //
break;
case TCPSOCKET_WRITEABLE: //
break;
case TCPSOCKET_READABLE: { //
char buf[300];
int len;
len = sock->recv(buf, sizeof(buf));
for (int i = 0; i < len; i++) {
Recv((unsigned char)buf[i]);
}
}
break;
case TCPSOCKET_DISCONNECTED:
case TCPSOCKET_CONTIMEOUT:
case TCPSOCKET_CONRST:
case TCPSOCKET_CONABRT:
case TCPSOCKET_ERROR:
sock->close();
break;
}
}
void onTCPListenSocketEvent (TCPSocketEvent e) {
if (e == TCPSOCKET_ACCEPT) {
Host client;
if (listensock.accept(&client, &sock) != TCPSOCKET_OK) {
return;
}
printf("Connected from %d.%d.%d.%d\r\n", (unsigned char)client.getIp()[0], (unsigned char)client.getIp()[1], (unsigned char)client.getIp()[2], (unsigned char)client.getIp()[3]);
sock->setOnEvent(&onTCPSocketEvent);
}
}
int main () {
pc.baud(115200);
Host local(IpAddr(), 10002);
RecvCount = 0;
ParamLen = 0;
ParamCount = 0;
servo1 = 0.5f;
servo2 = 0.5f;
servo3 = 0.5f;
lcd.printf("OK");
if (eth.setup()) {
return -1;
}
listensock.setOnEvent(&onTCPListenSocketEvent);
if (listensock.bind(local) != TCPSOCKET_OK) {
return -1;
}
if (listensock.listen() != TCPSOCKET_OK) {
return -1;
}
while (1) {
Net::poll();
}
}
void Recv(unsigned char data) {
switch (RecvCount) {
case 0:
ParamLen = 0;
ParamCount = 0;
if (data == 0xff) { // Headder
buff[RecvCount++] = data;
}
break;
case 1:
if (data == 0) { // ID
buff[RecvCount++] = data;
}
break;
case 2: // LENGTH
buff[RecvCount++] = data;
ParamLen = data;
break;
default:
if (ParamLen > 0) {
buff[RecvCount++] = data;
ParamCount++;
if (ParamCount >= ParamLen) {
ServoCmdExec();
RecvCount = 0;
}
} else {
RecvCount = 0;
}
break;
}
}
void ServoCmdExec() {
float tmp1 = (float)buff[4]/255.0f;
float tmp2 = (float)buff[5]/255.0f;
servo1 = tmp1;
servo2 = tmp2;
servo3 = (float)buff[6]/255.0f;
lcd.locate(0,0);
lcd.printf("servo1 = %02Xh %.1f",buff[4],tmp1);
lcd.locate(0,1);
lcd.printf("servo2 = %02Xh %.1f",buff[5],tmp2);
}
//---- ここまで --------------------------------------------
動画はこちら。
mbedにTCPで接続してRCサーボモータを動かしてみた。
―【Processing編】につづく...―
ここを参考にさせていただいた。
・mbedで初めてのマイコン開発 その3パソコンからmbedを遠隔制御してみよう!