AndroidとFonで自作ラジコンを動かす(Arduino)

概要

せっかくFonが余ってたので,タミヤのキットとArduino, eneloop mobile boosterを使って自作ラジコン作ってみました.
接続はAndroid → Wireless LAN(SSH) → Fon → Serial → Arduino → (DC moter, Servo motor)というふうな感じになってます.

FonDD-wrt化済み,JavaのJschライブラリを使ってSSHで接続しています.

動画

回路図

ソースコード

ラジコン側ソースコード
#include <Servo.h>
#include <MsTimer2.h>

#define MORTER_PIN1 4
#define MORTER_PIN2 5

#define SERVO_PIN 2

#define VOLUME_PIN 5

#define TIMER_TIME 3
#define PWM_MAX 10

int duty = 0;
int deg  = 0;
int pwm_count = 0;
int count = 0;
Servo myservo;

void pwm()
{
  count += TIMER_TIME;
  if(TIMER_TIME>1000){
    return;
  }
  pwm_count++;
  if(pwm_count >=  PWM_MAX){
    pwm_count = 0;
  }
  if(pwm_count < abs(duty)){
    if(duty>0){
      digitalWrite(MORTER_PIN1, LOW);
      digitalWrite(MORTER_PIN2, HIGH);
    }    
    else{
      digitalWrite(MORTER_PIN1, HIGH);
      digitalWrite(MORTER_PIN2, LOW);
    }
  }
  else{
    digitalWrite(MORTER_PIN1, LOW);
    digitalWrite(MORTER_PIN2, LOW);
  }
}

void setup(void)
{
  pinMode(MORTER_PIN1,OUTPUT);
  pinMode(MORTER_PIN2,OUTPUT);
  MsTimer2::set(TIMER_TIME, pwm);
  MsTimer2::start();

  myservo.attach(SERVO_PIN);
  Serial.begin(115200);
}

void loop(void)
{
  while(1){
    while(!Serial.available());
    if(Serial.read() == '\n')
      break;
  }

  int i;
  int val;

  for(val = 0, i = 0; i<2;i++){
    while(!Serial.available()){
    }
    val *= 10;
    val += Serial.read() - '0';
  }
  duty = val - 10;
  for(val = 0, i = 0; i<3;i++){
    while(!Serial.available()){
    }
    val *= 10;
    val += Serial.read() - '0';
  }
  count = 0;
  deg = map(val, 0, 180, 30, 150);
  myservo.write(deg);
}
スマートフォンソースコード
package com.miettal;

import java.util.Hashtable;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy;
import android.view.MotionEvent;
import android.view.Window;

import com.jcraft.jsch.*;

public class WifiradiconActivity extends Activity {
	private Session session = null;
	private final String hostname  = "192.168.2.1";
	private final String userid    = "root";
	private final String password  = "miettal";

	private double x = 0.5;
	private double y = 0.5;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		StrictMode.setThreadPolicy(new ThreadPolicy.Builder().permitNetwork().build());
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.main);

		/* SSH接続 */
		JSch jsch = new JSch();

		Hashtable<String, String> config = new Hashtable<String, String>();
		config.put("StrictHostKeyChecking", "no");
		JSch.setConfig(config);

		try {
			session = jsch.getSession(userid, hostname, 22);
			session.setPassword(password);
			session.connect();
		} catch (JSchException e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		/* 座標取得 */
		x = event.getX()/getWindowManager().getDefaultDisplay().getWidth();
		y = event.getY()/getWindowManager().getDefaultDisplay().getHeight();
		if(y<0.25){
			y = 0;
		}else if(y < 0.5){
			y = (y-0.25)*2;
		}
		String command = "";
		switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
			case MotionEvent.ACTION_MOVE:
			case MotionEvent.ACTION_CANCEL:
				command ="echo '"+String.format("%1$02d%2$03d", (int)(y*20), (int)(x*180))+"' > /dev/tts/0";
				break;
			case MotionEvent.ACTION_UP:
				command ="echo '"+String.format("%1$02d%2$03d", 10, (int)(x*180))+"' > /dev/tts/0";
				break;
		}
		/* 送信 */
		try {
			ChannelExec channel=(ChannelExec)session.openChannel("exec");
			channel.setCommand(command);
			channel.connect();
		} catch (JSchException e) {
			e.printStackTrace();
		}
		return super.onTouchEvent(event);
	}
}

その他

写真






部品

楽しい工作シリーズ No.172 ユニバーサルプレートL 210×160mm (70172)

楽しい工作シリーズ No.172 ユニバーサルプレートL 210×160mm (70172)


楽しい工作シリーズ No.112 バギー工作基本セット (70112)

楽しい工作シリーズ No.112 バギー工作基本セット (70112)



【永久保証付き】Arduino Uno

【永久保証付き】Arduino Uno