基本的には、こちらにあるサンプルの流用となりますが、Galileo側で WinSock Server プログラムを動かして、Windows PC からWinSock Client プログラムで接続して、文字を送信、Galileo 側が受信文字によってAnalogRead()の値をClient側に返すというシンプルなものです。また、ついでに、前回のLCDシールドも使って、応答文字列をLCDにも表示しています。
今回は GroveシールドとLCDシールドをスタックしています。Grove も DigitalWrite() や DigitalRead() などで使える簡単なものは動きますが、超音波距離センサを使おうと思ったところ pulseIn()関数が使えないようでした。
PCのクライアントソフトで接続して、x とか y とか送信すると、AnalogRead() でジョイスティックの値を読み込んで、LCDに表示しつつ、クライアント側に応答送信します。
Galileo側の WinSock Server のソースはこちら、PC側のテスト用クライアントのソースはこちら にあります。
一応、Galileo側のコードだけ以下に掲載。
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
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <WinSock2.h> | |
#include <WS2tcpip.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include "stdafx.h" | |
#include "arduino.h" | |
#include "LiquidCrystal.h" | |
// Ws2_32.lib のリンクが必要。 | |
#pragma comment (lib, "Ws2_32.lib") | |
#define DEFAULT_BUFLEN 512 | |
#define DEFAULT_PORT "27015" | |
// LCD pin <=> Arduino pin | |
int RS = 12; | |
int ENABLE = 11; | |
int DB4 = 5, DB5 = 4, DB6 = 3, DB7 = 2; | |
LiquidCrystal lcd = LiquidCrystal(RS, ENABLE, DB4, DB5, DB6, DB7); | |
int __cdecl main(void) | |
{ | |
WSADATA wsaData; | |
int iResult; | |
SOCKET listenSocket = INVALID_SOCKET; | |
SOCKET clientSocket = INVALID_SOCKET; | |
struct addrinfo *result = NULL; | |
struct addrinfo hints; | |
int iSendResult; | |
char rcvBuf[DEFAULT_BUFLEN]; | |
int rcvBufLen = DEFAULT_BUFLEN; | |
// LCDの初期化。16文字×2行。 | |
lcd.begin(16, 2); | |
lcd.setCursor(0, 0); | |
lcd.print("Hello,WinIoT !"); | |
// WinSockの初期化。WinSock Ver.2.2、MAKEWORD(メジャVer, マイナVer)。 | |
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); | |
if (iResult != 0) | |
{ | |
printf("WSAStartup failed with error: %d\n", iResult); | |
return 1; | |
} | |
// 変数の初期化。 | |
ZeroMemory(&hints, sizeof(hints)); | |
hints.ai_family = AF_INET; | |
hints.ai_socktype = SOCK_STREAM; | |
hints.ai_protocol = IPPROTO_TCP; | |
hints.ai_flags = AI_PASSIVE; | |
// Serverのアドレスとポートの解決。 | |
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); | |
if (iResult != 0) | |
{ | |
printf("getaddrinfo failed with error: %d\n", iResult); | |
// Winsockのリソース解放。 | |
WSACleanup(); | |
return 1; | |
} | |
// Server接続のためのSocketの生成。 | |
listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); | |
if (listenSocket == INVALID_SOCKET) | |
{ | |
printf("socket failed with error: %ld\n", WSAGetLastError()); | |
// getaddrinfo()で確保したメモリの解放。 | |
freeaddrinfo(result); | |
// Winsockのリソース解放。 | |
WSACleanup(); | |
return 1; | |
} | |
// TCP リスナソケットの設定。ソケットをアドレス・ポートに結びつける。 | |
iResult = bind(listenSocket, result->ai_addr, (int)result->ai_addrlen); | |
if (iResult == SOCKET_ERROR) | |
{ | |
printf("bind failed with error: %d\n", WSAGetLastError()); | |
// getaddrinfo()で確保したメモリの解放。 | |
freeaddrinfo(result); | |
// ソケットを閉じる。 | |
closesocket(listenSocket); | |
// Winsockのリソース解放。 | |
WSACleanup(); | |
return 1; | |
} | |
// getaddrinfo()で確保したメモリの解放。 | |
freeaddrinfo(result); | |
// ソケットリスナを接続待ちにする。 | |
iResult = listen(listenSocket, SOMAXCONN); | |
if (iResult == SOCKET_ERROR) | |
{ | |
printf("listen failed with error: %d\n", WSAGetLastError()); | |
// ソケットを閉じる。 | |
closesocket(listenSocket); | |
// Winsockのリソース解放。 | |
WSACleanup(); | |
return 1; | |
} | |
// クライアントソケット受け入れ。 | |
clientSocket = accept(listenSocket, NULL, NULL); | |
if (clientSocket == INVALID_SOCKET) | |
{ | |
printf("accept failed with error: %d\n", WSAGetLastError()); | |
// ソケットを閉じる。 | |
closesocket(listenSocket); | |
// Winsockのリソース解放。 | |
WSACleanup(); | |
return 1; | |
} | |
// 不要なソケットを閉じる。 | |
closesocket(listenSocket); | |
// 相手が接続を閉じるまで、受信する。 | |
do | |
{ | |
// ソケット受信。 | |
iResult = recv(clientSocket, rcvBuf, rcvBufLen, 0); | |
if (iResult > 0) | |
{ | |
printf("Bytes received: %d\n", iResult); | |
// 受信文字によって、バッファをAnalogRead()値で書き換え。 | |
switch (rcvBuf[0]) | |
{ | |
case 'x': | |
case 'X': | |
{ | |
int val = analogRead(A0); | |
iResult = sprintf(rcvBuf, "X: %d\n", val); | |
break; | |
} | |
case 'y': | |
case 'Y': | |
{ | |
int val = analogRead(A1); | |
iResult = sprintf(rcvBuf, "Y: %d\n", val); | |
break; | |
} | |
default: | |
break; | |
} | |
// 送信側に受信したバッファの内容を返す。 | |
iSendResult = send(clientSocket, rcvBuf, iResult, 0); | |
if (iSendResult == SOCKET_ERROR) | |
{ | |
printf("send failed with error: %d\n", WSAGetLastError()); | |
// ソケットを閉じる。 | |
closesocket(clientSocket); | |
// Winsockのリソース解放。 | |
WSACleanup(); | |
return 1; | |
} | |
printf("Bytes sent: %d\n", iSendResult); | |
// LCDに表示。 | |
if (iResult <= 16) | |
{ | |
rcvBuf[iResult] = '\0'; | |
} | |
else | |
{ | |
rcvBuf[16] = '\0'; | |
} | |
lcd.setCursor(0, 1); | |
lcd.print(rcvBuf); | |
} | |
else if (iResult == 0) | |
printf("Connection closeing...\n"); | |
else | |
{ | |
printf("recv failed with error: %d\n", WSAGetLastError()); | |
// ソケットを閉じる。 | |
closesocket(clientSocket); | |
// Winsockのリソース解放。 | |
WSACleanup(); | |
return 1; | |
} | |
} while (iResult > 0); | |
// ソケット送受信の無効化。 | |
iResult = shutdown(clientSocket, SD_SEND); | |
if (iResult == SOCKET_ERROR) | |
{ | |
printf("shutdown failed with error: %d\n", WSAGetLastError()); | |
// ソケットを閉じる。 | |
closesocket(clientSocket); | |
// Winsockのリソース解放。 | |
WSACleanup(); | |
return 1; | |
} | |
// ソケットを閉じる。 | |
closesocket(clientSocket); | |
// Winsockのリソース解放。 | |
WSACleanup(); | |
return 0; | |
} |
0 件のコメント:
コメントを投稿