【android】USBセレクターの制御 ~wifi経由~
inkscapeを使って、ボタンのデザイン(( ..)φ)カキカキ
久々に触るのとバージョンがかなり前0.9台から1.4にしたこともあって、事前にクマを書いてしまった(チュートリアルをさらりとやって基本の操作を再度勉強)・・・https://inkscape.eksd.jp/
それなりにかっこいい?ボタンの画像イメージを作ってみた。PC1とPC2の2種類。
作成したファイルをPNGで保存。buttonpc1.pngとbuttonpc2.pngのファイル名で保存。
Android studioのimagebuttonの画像に割り当ててみる。新規プロジェクトを起こして、buttonpc1.pngとbuttonpc2.pn
のファイルをdrawableのフォルダーの下に移動させる。
その後、acrivity_main.xmlを編集、imagebuttonを2つ配置。
drawableにコピーした画像を割り当てる。普通に割り当てると、グレーの枠がついてしまう。
OC techNoteさんのHPに解決法があったので使わせていただく。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true"
android:drawable="@color/black" />
</selector>
各ボタンのbuckgoundにこのxmlファイルを指定してあげるとクリックしたときに一瞬バックグランドの色が変わる。画像を用意しておいて、それに入れ替えてもOKなはず。まずまずは簡単なバックグランドの色を変更で。
Wifi接続するためにAndroidManifest.xmlに
<uses-permission android:name="android.permission.INTERNET" />
を追加。
MainActivity.javaのファイルは以下のような感じ。
package com.example.myremocon1;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
private static Socket s;
private static PrintWriter printWriter;
String message="";
private static String ip="192.168.1.26";
private static int port=5000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
}
public void send_text1(View v)
{
message="1";
myTask mt =new myTask();
mt.execute();
CharSequence text = "Setting to PC1!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(this /* MyActivity */, text, duration);
toast.show();
}
public void send_text2(View v)
{
message="2";
myTask mt =new myTask();
mt.execute();
CharSequence text = "Setting to PC2!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(this /* MyActivity */, text, duration);
toast.show();
}
class myTask extends AsyncTask<Void,Void,Void> {
protected Void doInBackground(Void... voids) {
try {
s=new Socket(ip,5000);
printWriter=new PrintWriter(s.getOutputStream());
printWriter.write(message);
printWriter.flush();
printWriter.close();
s.close();
}catch (IOException e){
e.printStackTrace();
}
簡単に、
受信する側(サーバー側)はAruino IDEで以下のような簡単なものを作成。
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
const char *ssid = "ssid";
const char *password = "password";
int usb_state;
WiFiServer server(5000);
void connectToWiFi() {
WiFi.begin(ssid, password);
// WiFi.setSleep(false); // WiFiスリープを無効にする
// WiFi接続が確立されるまで待機
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// WiFi接続が確立した場合の処理
String ip = WiFi.localIP().toString().c_str();
Serial.println("");
Serial.println("WiFi connected");
Serial.printf("IP Address : ");
Serial.println(WiFi.localIP());
//サーバー立ち上げ
server.begin();
Serial.println("server.begin()");
Serial.println(WiFi.macAddress());
}
bool timeout(WiFiClient client){
int waitloops = 0;
while (!client.available()){
waitloops++;
delay(1); //delay 1 msec
if( 10000 < waitloops ){
return true;
}
}
return false;
}
void change_usb_channel(){
digitalWrite(LED_BUILTIN, HIGH); // push button on.
delay(100); // Wait for a second
digitalWrite(LED_BUILTIN, LOW);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
pinMode(10, INPUT); // readiing status of USB selector
connectToWiFi();
// Read status of USB selector
digitalWrite(LED_BUILTIN, LOW);
int usb_state = digitalRead(10);
if (usb_state==1){
Serial.println( "USB channel == 1" );
}else if (usb_state==0){
Serial.println( "USB channel == 2" );
}
}
void loop() {
// put your main code here, to run repeatedly:
WiFiClient client = server.available();
if (client) {
Serial.println("New Client.");
while (client.connected()) {
//if( timeout(client) ) break;
int size = client.available();
if (size) {
Serial.println();
Serial.print("size:");
Serial.println(size);
char cmd[size + 1]; // command
memset(cmd, 0, sizeof( cmd ));
client.read( ( uint8_t* )cmd, size);
cmd[size] = '\0'; // Add null terminator
Serial.println( cmd );
if( strcmp( cmd, "1" ) == 0 ){
Serial.println( "receive 1" );
if (usb_state==1){
change_usb_channel();
usb_state=1;
}
client.stop();
}
else if( strcmp( cmd, "2" ) == 0 ){
Serial.println( "receive 2" );
if (usb_state==0){
change_usb_channel();
usb_state=0;
}
client.stop();
//赤外線送信
}else if( strcmp( cmd, "3" ) == 0 ){
Serial.println( "receive 3" );
client.stop();
}
}
delay(1);
}
client.stop();
Serial.println();
Serial.println("client.stop()");
}
if (WiFi.status() != WL_CONNECTED) {
connectToWiFi();
}
delay(1);
}
コマンドとして単に数字を受け取るだけ。数字3は用意しているが今回は受信しても何もしない。
回路の方は、ブレッドボードに前に作ったのそのまま。https://funasover.blogspot.com/2025/02/iotusbiot.html
実機のタブレットで試してみる。
USBセレクタが初期状態で1の状態になっていて、タブレットのPC2のボタンを押すと、USBセレクタが2に変更。続けて、タブレットのPC1のボタンを押すと、再度USBセレクタが1に。
少しバグがまだあって、
Arduinoのシリアル通信の内容を見ている限り、クライアントが接続しに行っているので、ソケット接続ができている事がわかる。しかし、次のメッセージが受け取れず、ソケットをそのままクローズしている。
その場対処だが少し、ソケット接続してから、メッセージを送り込むまでSleepさせてやった。下の箇所にSleep(50);を挿入。(かかわるインポートも実施)
class myTask extends AsyncTask<Void,Void,Void> {
protected Void doInBackground(Void... voids) {
try {
s=new Socket(ip,5000);
printWriter=new PrintWriter(s.getOutputStream());
sleep(50);
printWriter.write(message);
printWriter.flush();
printWriter.close();
s.close();
}catch (IOException e){
e.printStackTrace();
}
return null;
}
}
これで様子を見ているが、欠損はしておらず、ボタンを押すたびに、USBセレクターが確実に切り替わるようになった。
次回は、PC1とPC2にそれぞれHDMIのセレクターを連動させる事を試みることにする。
コメント
コメントを投稿