Design and implementation of smart housekeeping robot based on Android

1. Overview

Android is a free and open source operating system based on Linux. It is mainly used in mobile devices, such as smartphones and tablets. It is led and developed by Google and the Open Handset Alliance. The Android-based part of the system uses JAVA to complete development work. The entire system consists of an Android mobile phone control terminal and a robot execution terminal. The Android terminal completes user voice command recognition, interactive operation interface and Bluetooth wireless communication to transmit user commands; the robot terminal is responsible for responding to control commands and completing user requirements. The Android terminal is a set of control software running on Android phones. It completes speech recognition based on Google’s Google Voice Search. The recognition results are processed by the software to generate corresponding control instructions, which are sent to the robot terminal via Bluetooth. The robot receives control commands through the HC-05 Bluetooth module, and drives a set of CDS5500 servos under the control of STM32RBT6 to complete the user’s commands. During the test of the system, the system successfully realized speech recognition for non-specific people, and the robot was able to move to a designated location to execute specific commands more accurately. In order to reduce the error in the mechanical transmission part, I added the control functions of forward, backward, left turn, right turn and each degree of freedom of the manipulator to the Android terminal of the host computer.

2. Design indicators

(1) The robot is required to be a mobile body and have a manipulator;

(2) Implement simple speech recognition based on “Android”;

(3) Achieve simple operation of the robotic arm;

(4) Wireless control of robots by “Android” via Bluetooth;

(5) Realize automatic positioning.

3. Related codes

Robot side code:

#include "sys.h"
#include "usart.h"
#include "usart2.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "wdg.h"
#include "timer.h"
#include "lcd.h"
#include "hc05.h"
#include "string.h"
#include "cds5500.h"
char tt;
void delay_s(u8 t)
{
 u8tt;
 for(tt=0;tt<t;tt + + )
 {
  delay_ms(1000);
 }
}
int main(void)
{
u8 reclen=0;
unsigned short int distance=520;
unsigned short int height=750;
   Stm32_Clock_Init(9);
delay_init(72);
uart_init(72,1000000);
LED_Init();
SetMode(1,0,0);delay_ms(30);
SetMode(2,0,0);delay_ms(30);
SetMode(3,0,0);delay_ms(30);
SetMode(4,0,0);delay_ms(30);
SetMode(5,0,1023);delay_ms(30);
SetMode(6,0,1023);delay_ms(30);
SetMode(7,0,1023);delay_ms(30);
SetMode(8,0,1023);delay_ms(30);
SetMode(9,0,1023);delay_ms(30);
HC05_Init();
delay_ms(1000);
PostureInit();
 while(1)
{
if(USART2_RX_STA &0X8000)
{ reclen=USART2_RX_STA & amp;0X7FFF;
USART2_RX_BUF[reclen]=0;
USART2_RX_STA=0;
if(tt=='1')
{
Forward();
}
if(tt=='3')
{
Back();
}
if(tt=='0')
{
LED0=1;LED1=1;
Stop();
}
if(tt=='4')
{
TurnRight();
}
if(tt=='2')
{
TurnLeft();
}
if(tt=='5')
{
SetMode(9,0,1023);
delay_ms(30);
OpenPaw();
LED0=0;
}
if(tt=='6')
{
SetMode(9,0,1023);
delay_ms(30);
ClosePaw();
}
while(tt=='8')
{
USART2_RX_STA=0;
distance-=10; if(distance<=200)distance=200;
SetMode(7,0,1023);
delay_ms(30);
PawGoFar(distance);
delay_ms(75);
LED1=0;
}
while(tt=='7')
{
USART2_RX_STA=0;
distance + =10;
if(distance>=520)distance=520;
SetMode(7,0,1023);
delay_ms(30);
PawGoNear(distance);
delay_ms(75);
LED0=0;
}
while(tt=='9')
{
USART2_RX_STA=0;
height + =10;
if(height>=750)height=750;
SetMode(6,0,1023);
delay_ms(30);
ArmRaiseUp(height);
delay_ms(75);
LED0=0;
}
while(tt=='a')
{
USART2_RX_STA=0;
height-=10;
if(height<=500)height=500;
SetMode(6,0,1023);
delay_ms(30);
ArmSetDown(height);
delay_ms(75);
LED1=0;
}
}
}
}
#include <stm32f10x_lib.h>
#include "delay.h"
#include "cds5500.h"
void ControlBit_Init(void)
{
 RCC->APB2ENR|=1<<2;
 GPIOA->CRL &=0XF0FFFFFF;
 GPIOA->CRL|=0X03000000;
 GPIOA->ODR|=1<<6;

 GPIOA->CRL &=0X0FFFFFFF;
 GPIOA->CRL|=0X30000000;
 GPIOA->ODR|=1<<7;
}

void SetMode(unsigned char id, unsigned short int s_limit, unsigned short int n_limit)
{
 unsigned short int temp_n = 0;
 unsigned short int temp_s = 0;
 unsigned char temp_n_h = 0;
 unsigned char temp_n_l = 0;
 unsigned char temp_s_h = 0;
 unsigned char temp_s_l = 0;
 unsigned char temp_sum = 0;
 char len,t;
 char MODE[11];
 if (n_limit > 1023)
 temp_n = 1023;
 else
 temp_n = n_limit;
 if (s_limit > 1023)
temp_s = 1023;
 else
 temp_s = s_limit;
 temp_n_h = (unsigned char)(temp_n >> 8);
 temp_n_l = (unsigned char)temp_n;
 temp_s_h = (unsigned char)(temp_s >> 8);
 temp_s_l = (unsigned char)temp_s;
 TXEN=1;
 RXEN=0;
 MODE[0]=0XFF;
 MODE[1]=0XFF;
 MODE[2]=id; //ID
 MODE[3]=0X07;
 MODE[4]=0x03;
 MODE[5]=0x06;
 MODE[6]=temp_s_l;
 MODE[7]=temp_s_h;
 MODE[8]=temp_n_l;
 MODE[9]=temp_n_h;
 temp_sum = id + 7 + 0x03 + 0x06 + temp_s_l + temp_s_h + temp_n_l + temp_n_h;
 temp_sum = ~temp_sum;
 MODE[10]=temp_sum;
 len=11;
 for(t=0;t<len;t + + )
 {
  USART1->DR=MODE[t];
  while((USART1->SR & amp;0X40)==0);
 }
 TXEN=0;
 RXEN=1;
}
void SetServoPosition(unsigned char id, unsigned short int position, unsigned short int velocity)
{
 unsigned short int temp_velocity = 0;
 unsigned short int temp_position = 0;
 unsigned char temp_velocity_h = 0;
 unsigned char temp_velocity_l = 0;
 unsigned char temp_position_h = 0;
 unsigned char temp_position_l = 0;
 unsigned char temp_sum = 0;
 char t,len;
 char SERVO[11];
 if (velocity > 1023)
 temp_velocity = 1023;
 else
 temp_velocity = velocity;
 if (position > 1023)
 temp_position = 1023;
 else
 temp_position = position;
 temp_velocity_h = (unsigned char)(temp_velocity >> 8);
 temp_velocity_l = (unsigned char)temp_velocity;
 temp_position_h = (unsigned char)(temp_position >> 8);  8bit êy?Y
 temp_position_l = (unsigned char)temp_position;
 TXEN=1;
 RXEN=0;
 SERVO[0]=0XFF;
 SERVO[1]=0XFF;
 SERVO[2]=id; //ID
 SERVO[3]=0X07;
 SERVO[4]=0x03;
 SERVO[5]=0x1E;
 SERVO[6]=temp_position_l;
 SERVO[7]=temp_position_h;
 SERVO[8]=temp_velocity_l;
 SERVO[9]=temp_velocity_h;
 temp_sum = id + 7 + 0x03 + 0x1E + temp_position_l + temp_position_h + temp_velocity_l + temp_velocity_h;
 temp_sum = ~temp_sum;
 SERVO[10]=temp_sum;
 len=11;
 for(t=0;t<len;t + + )
 {
  USART1->DR=SERVO[t];
  while((USART1->SR & amp;0X40)==0);
 }
 TXEN=0;
 RXEN=1;
}
void SetVelocity(unsigned char id, signed short int velocity)
{
 unsigned char temp_sign = 0;
 unsigned short int temp_velocity = 0;
 unsigned char temp_value_h = 0;
 unsigned char temp_value_l = 0;
 unsigned char temp_sum = 0;
 char t,len;
 charVEL[9];
 if (velocity < 0)
 {
  temp_velocity = -velocity;
  temp_sign = 1; }
 else
 {
  temp_velocity = velocity;
  temp_sign = 0;
 }
 if (temp_velocity > 1023)
   temp_velocity = 1023;
 temp_velocity |= (temp_sign << 10);
 temp_value_h = (unsigned char)(temp_velocity >> 8);
 temp_value_l = (unsigned char)temp_velocity;
 TXEN=1;
 RXEN=0;
 VEL[0]=0XFF;
 VEL[1]=0XFF;
 VEL[2]=id;
 VEL[3]=5;
 VEL[4]=0x03;
 VEL[5]=0x20;
 VEL[6]=temp_value_l;
 VEL[7]=temp_value_h;
 temp_sum = id + 5 + 0x03 + 0x20 + temp_value_l + temp_value_h;
 temp_sum = ~temp_sum;
 VEL[8]=temp_sum;
 len=9;
 for(t=0;t<len;t + + )
 {
  USART1->DR=VEL[t];
  while((USART1->SR & amp;0X40)==0);
 }
 TXEN=0;
 RXEN=1;
}
void Forward(void)
{
 SetVelocity(1,1000);
 SetVelocity(2,1000);
 SetVelocity(3,-1000);
 SetVelocity(4,-1000);
}

void Back(void)
{
 SetVelocity(1,-1000);
 SetVelocity(2,-1000);
 SetVelocity(3,1000);
 SetVelocity(4,1000);
}
void Stop(void)
{
 SetVelocity(1,0);
 delay_ms(30);
 SetVelocity(2,0);
 delay_ms(30);
 SetVelocity(3,0);
 delay_ms(30);
 SetVelocity(4,0);
 delay_ms(30);
}
void TurnRight(void)
{
 SetVelocity(1,800);
 SetVelocity(2,800);
 SetVelocity(3,800);
 SetVelocity(4,800);
}
void TurnLeft(void)
{
 SetVelocity(1,-800);
 SetVelocity(2,-800);
 SetVelocity(3,-800);
 SetVelocity(4,-800);
}
void OpenPaw(void)
{
 SetServoPosition(9,300,700);
}
void ClosePaw(void)
{
 SetServoPosition(9,600,600);
}
void PawGoFar(unsigned short int dis)
{
 SetServoPosition(7,dis,500);
}

void PawGoNear(unsigned short int dis)
{
 SetServoPosition(7,dis,600);
}
void ArmRaiseUp(unsigned short int hei)
{
 SetServoPosition(6,hei,500);
}
void ArmSetDown(unsigned short int hei)
{
 SetServoPosition(6,hei,600);
}
void PostureInit(void)
{
 SetMode(6,0,1023);
 delay_ms(30);
 SetServoPosition(6,750,600);
 delay_ms(200);
 SetMode(6,0,1023);
 delay_ms(30);
 SetServoPosition(6,750,500);
 delay_ms(200);
 SetMode(5,0,1023);
 delay_ms(30);
 SetServoPosition(5,512,500);
 delay_ms(200);
 SetMode(7,0,1023);
 delay_ms(30);
 SetServoPosition(7,480,500);
 delay_ms(200);
 SetMode(5,0,1023);
 delay_ms(30);
 SetServoPosition(8,530,500);
 delay_ms(200);
 SetMode(9,0,1023);
 delay_ms(30);
 SetServoPosition(9,600,600);
}

Android code:

package com.example.voicerecognizer;

import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.view.View;
importandroid.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
importandroid.content.pm.PackageManage;
import android.content.pm.ResolveInfo;
import android.speech.RecognizerIntent;
import java.io.IOException;
import java.io.OutputStream;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothSocket;
import android.util.Log;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
importandroid.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class Main extends Activity {
private static final int UPTATE_INTERVAL_TIME = 120;
private static final String TAG = "MyBluetooth";
    private static final boolean D = true;
    private BluetoothAdapter mBluetoothAdapter = null;
    private BluetoothSocket btSocket = null;
    private OutputStream outStream = null;
private TextView textView1;
private Button button1;
private Button button2;
public static final int VOICE_RECOGNITION_REQUEST_CODE = 0x1008;
public String strRet;
public String strRet1;
private BluetoothData bluetoothData;
private BluetoothService mBluetoothService = null;
private long lastUpdateTime;
 private SensorManager sensorMag;
 private Sensor gravitySensor;
 //Save the last record
 float lastX = 0;
 float lastY = 0;
 float lastZ = 0;

private ServiceConnection connection=new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName arg0, IBinder service) {
bluetoothData = (BluetoothData)service;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
bluetoothData = null;
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
\t\t
sensorMag = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
gravitySensor = sensorMag.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
if (D)Log.e(TAG, " + + + ON CREATE + + + ");
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth device is not available, please turn on Bluetooth!", Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this, "Please turn on Bluetooth and rerun the program!", Toast.LENGTH_LONG).show();
finish();
return;
}
if (D)Log.e(TAG, " + + + DONE IN ON CREATE, GOT LOCAL BT ADAPTER + + + ");
try {
bindService(new Intent(Main.this,BluetoothService.class),
connection, Context.BIND_AUTO_CREATE);
} catch (Exception e) {
// TODO: handle exception
}
\t\t
textView1=(TextView)findViewById(R.id.textView1);
button1=(Button)findViewById(R.id.button1);
\t\t
button1.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
PackageManager pm = getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities
(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
//If Google voice search engine has been installed
if(activities.size() != 0){
try{
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);//Speech recognition Intent
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Jia Hanguang, School of Electronic Engineering and Automation, Guilin University of Electronic Science and Technology"); //Instructions for the appearance of the recognition screen
startActivityForResult(intent,VOICE_RECOGNITION_REQUEST_CODE); //Start speech recognition
}
catch (Exception e){
textView1.setText("" + e.getMessage());
Toast.makeText(Main.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
else{
textView1.setText("RecognizerIntent Not Found!!!");
Toast.makeText(Main.this, "RecognizerIntent Not Found!!!",
Toast.LENGTH_SHORT).show();
}
}
});
button2=(Button)findViewById(R.id.button2);
button2.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
try {
bluetoothData.SendMessage("0");
// bluetoothData.getACK();
}
catch (Exception e) {
// TODO: handle exception
}
}
}
);
\t\t
}
@Override
protected void onActivityResult(int requestcode, int resultcode, Intent data)
{
switch(requestcode)
{
case VOICE_RECOGNITION_REQUEST_CODE:
if(requestcode == VOICE_RECOGNITION_REQUEST_CODE
& amp; & amp; resultcode == RESULT_OK)
{
boolean flag=false;
strRet = "";
strRet1 ="Sending to robot!";
ArrayList<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
for(int i=0;i<1;i + + )
{
strRet + =results.get(i);
}
if(strRet.length()>0)
{
if(strRet.equals("forward"))
{
strRet="1";
}
if(strRet.equals("Turn right"))
{
strRet="4";
}
if(strRet.equals("Back"))
{
strRet="3";
}
if(strRet.equals("Turn left"))
{
strRet="2";
}
if(strRet.equals("open"))
{
strRet="5";
}
if(strRet.equals("grab"))
{
strRet="6";
}
if(strRet.equals("stretch"))
{
strRet="7";
}
if(strRet.equals("recover"))
{
strRet="8";
}
if(strRet.equals("lift"))
{
strRet="9";
}
if(strRet.equals("Put it down"))
{
strRet="a";
}
if(strRet.equals("Stop working"))
{
finish();
}
try {
flag=bluetoothData.SendMessage(strRet);
}
catch (Exception e) {
// TODO: handle exception
}
if(flag){
                    textView1.setText("Your command is:" + strRet);
Toast.makeText(Main.this, strRet + "\\
" + strRet1, Toast.LENGTH_SHORT).show();
}
}
}
}
}
\t
float tMax = 0.5f;
private SensorEventListener sensorLis = new SensorEventListener() {

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

public void onSensorChanged(SensorEvent event) {

if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
return;
}
// Detect time now
long currentUpdateTime = System.currentTimeMillis();
//The time interval between two detections
long timeInterval = currentUpdateTime - lastUpdateTime;
// Determine whether the detection time interval has been reached
if (timeInterval < UPTATE_INTERVAL_TIME)
return;
//The current time becomes the last time
lastUpdateTime = currentUpdateTime;
// Get the acceleration value. The following three values are the components of the gravity component in the device coordinates.
float x = event.values[SensorManager.DATA_X];

float y = event.values[SensorManager.DATA_Y];

float z = event.values[SensorManager.DATA_Z];

float absx = Math.abs(x);
float absy = Math.abs(y);
float absz = Math.abs(z);

if (absx > absy & amp; & amp; absx > absz) {

if (x > tMax) {
Log.e("origen", "turn left");
try {
bluetoothData.SendMessage("2");
// bluetoothData.getACK();
}
catch (Exception e) {
// TODO: handle exception
}

} else if (x < -tMax) {
Log.e("origen", "turn right");
try {
bluetoothData.SendMessage("4");
// bluetoothData.getACK();
}
catch (Exception e) {
// TODO: handle exception
}
}

} else if (absy > absx & amp; & amp; absy > absz) {

if (y < - tMax) {
Log.e("origen", "turn up");
try {
bluetoothData.SendMessage("1");
// bluetoothData.getACK();
}
catch (Exception e) {
// TODO: handle exception
}
\t\t\t\t\t
} else if (y > tMax) {
Log.e("origen", "turn down");
try {
bluetoothData.SendMessage("3");
// bluetoothData.getACK();
}
catch (Exception e) {
// TODO: handle exception
}
}
\t\t\t\t
}
else if (absx < tMax & amp; & amp; absy < tMax) {
Log.e("origen", "screen up");
try {
bluetoothData.SendMessage("0");
} catch (Exception e) {
// TODO: handle exception
}
}
}
};
\t
@Override
    public void onStart() {
    super.onStart();
    if (D) Log.e(TAG, " + + ON START + + ");
    sensorMag.registerListener(sensorLis, gravitySensor,
SensorManager.SENSOR_DELAY_UI);
    \t
    }
\t  
    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        if(D)
        {
            Log.e(TAG, " + + ON STOP + + ");
        }
    }
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        unbindService(connection);
        super.onDestroy();
        if(D)
        {
            Log.e(TAG, " + + ON DESTROY + + ");
        }
        try {
            if(btSocket != null)
              btSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "Close failed");
        }
    }