我是19级同学,给大家先介绍一下我们的项目:智能垃圾分类垃圾桶。
因为学校发的硬件只是颜色传感器,所以垃圾分类其实就是颜色分类,颜色传感器是必用的器件。
你们要注意有几个点:1.首先是学院发的器件都要用上,没有会扣分。
2. 大家有什么创新的东西都可以加上去,比如我们组就用摄像头去识别垃圾,这算是创新点,不过因为忘记了学院要求,没用颜色传感器被老师扣分但是在后面的专家会上展示效果不错,拿到了一等奖。
3.上位机大部分同学都是旧板子,个别小组拿到的新板子不是很好用,版本太高(就是不会用)可以和老师沟通。
我把自己小组的操作流程放在下面方便大家理解上位机与mcu的通信部分
我新建的是activity,把新建的步骤贴在下面:
project→app→src→main→java然后根据你们文件名不同 右键选择新建Empty Activity就好了,java文件对应的layout就直接一起生成了,如图:
layout在main文件下的res中的layout里,就是选中的xml文件。
根据项目要求,上位机实现的功能代码主要分为:?
1.界面的跳转
2.与mcu的通信(用户模式与维护模式)
我是先看B站swc010学长的视频,有了样例,然后修改里面的内容,来满足我们组的通信,大家一定要先看视频,跟着一步一步做,把样例复制到需要通信的java文件里,然后根据下面的注释,理解自己该怎么改动代码来达到通信要求。
视频链接:https://www.bilibili.com/video/BV1Xb41177wR
我修改后代码如下:
package com.example.teamworks;//这个是大家新建的project名字可以不管
import android.content.Intent;
import android.content.res.Configuration;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.friendlyarm.FriendlyThings.HardwareControler;
import java.util.Timer;
import java.util.TimerTask;//上面所有的import大家不用动
//绿色的是java文件名,大家要把样例里的改为自己的
public class UseChinese1Activity extends AppCompatActivity implements View.OnClickListener {
private Button btn_back;
private Button btn_call;
private Button btn_put, btn_radio;
private TextView t1, t2, t3, t4;
public static int a = 100, b = 100, c = 100, d = 100;
private MediaPlayer mp = new MediaPlayer();
private MediaPlayer mp1 = new MediaPlayer();
private Button play;
????//以上的private变量需要自行定义
private final int MAXLINES = 200;
private StringBuilder remoteData = new StringBuilder(256 * MAXLINES);
private String devName = "/dev/ttyAMA3"; //ttyAMA3-->UART3
private int speed = 115200;
private int dataBits = 8;
private int stopBits = 1;
private int devfd = -1;
private String str = "";//这部分有波特率,数据位,校验位,停止位的定义,这个和负责mcu的同学对应就好了
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_use_chinese1);
String winTitle = devName + "," + speed + "," + dataBits + "," + stopBits;
setTitle(winTitle);
btn_back = (Button) findViewById(R.id.back2);
btn_back.setOnClickListener(this);
btn_call = (Button) findViewById(R.id.call_btn2);
btn_call.setOnClickListener(this);
btn_put = (Button) findViewById(R.id.put_btn2);
btn_put.setOnClickListener(this);
btn_radio = (Button) findViewById(R.id.shuoming2);
btn_radio.setOnClickListener(this);
//把java文件里的变量与layout中的控件通过ID链接
devfd = HardwareControler.openSerialPort(devName, speed, dataBits, stopBits);
if (devfd >= 0) {
timer.schedule(task, 0, 100);
} else {
devfd = -1;
}
}
//if语句判断控件是否被点击,触发响应
@Override
public void onClick(View v) {
if (v.getId() == R.id.back2) {
//跳转到主界面
Intent intent = new Intent(UseChinese1Activity.this,LoadingChineseActivity.class);
startActivity(intent);
}
//界面跳转,Intent 是跳转指令,XXX.this,XXX.calss指的是从this的界面跳到class的界面,XXX是java文件名
if (v.getId() == R.id.put_btn2) {
String str_0 = "b";
if (str_0.length() > 0) {
int ret = HardwareControler.write(devfd, str_0.getBytes());
if (ret > 0) {
remoteData.append(str_0);
}
}
remoteData.append(str_0);
}
//点击按钮,发送数据给mcu,示例里发送的是“b”
if (v.getId() == R.id.shuoming2) {
Button play = findViewById(R.id.shuoming2);
final MediaPlayer mp = MediaPlayer.create(this, R.raw.help);
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { mp.start(); }
});
}
}
//点击按钮,播放语音
//下面是上位机接收mcu发送的数据并做出相应回应
private final int BUFSIZE = 512;
private byte[] buf = new byte[BUFSIZE];
private Timer timer = new Timer();
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
if (HardwareControler.select(devfd, 0, 0) == 1) {
int retSize = HardwareControler.read(devfd, buf, BUFSIZE);
if (retSize > 0) {
String str = new String(buf, 0, retSize);
remoteData.append(str);//这些不用变动,意思是把从mcu接收到的数据存入str这个变量名里
??????????????????????????switch (str) {
case "k"://如果接收的是K执行下面的指令
Toast.makeText(UseEnglishActivity.this, "recyclable garbage", Toast.LENGTH_SHORT).show();
????????????????????????????????//Toast是弹窗,会将"recyclable garbage"显示
break;
case "i":
Toast.makeText(UseEnglishActivity.this, "hazardous waste", Toast.LENGTH_SHORT).show();
break;
case "o":
Toast.makeText(UseEnglishActivity.this, "other rubbish", Toast.LENGTH_SHORT).show();
break;
case "v":
Toast.makeText(UseEnglishActivity.this, "kitchen rubbish", Toast.LENGTH_SHORT).show();
break;
case "l":
Toast.makeText(UseEnglishActivity.this, "Please keep a distance over 10 cm!", ????????????????????????????????????????????????Toast.LENGTH_SHORT).show();
break;
}
}
}
break;
}
super.handleMessage(msg);
}
};
private TimerTask task = new TimerTask() {
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
public void onDestroy() {
timer.cancel();
if (devfd != -1) {
HardwareControler.close(devfd);
devfd = -1;
}
super.onDestroy();
if (mp != null) {
mp.stop();
mp.release();
}
super.onDestroy();
if (mp1 != null) {
mp1.stop();
mp1.release();
}
}
public void onPause(){
if (devfd != -1) {
HardwareControler.close(devfd);
devfd = -1;
}
super.onPause();
}
public void onStop(){
if (devfd != -1) {
HardwareControler.close(devfd);
devfd = -1;
}
super.onStop();
}
}//这些复制就行
有一点要注意,我的通信都是收发字母,之前试过数字,不知道为什么不太行,你们可以试试,不行的话老老实实用字母。
package com.example.teamworks;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class RepairLoadingEnglishActivity extends AppCompatActivity implements View.OnClickListener {
private Button tv_back;
private EditText et_user_name;
private EditText et_psw;
private Button btn_login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_repair_loading_english);
tv_back = findViewById(R.id.tv_back2);
tv_back.setOnClickListener(this);
btn_login = findViewById(R.id.btn_login2);
et_user_name = findViewById(R.id.et_user_name);
et_psw = findViewById(R.id.et_psw);
btn_login.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.btn_login2){
String username = et_user_name.getText().toString();
String password = et_psw.getText().toString();
Intent intent = null;
//弹出内容
String ok = "successfully";
String fail = "please try it again";
if(username.equals("089")&&password.equals("1")){
Intent intent1 = new Intent(RepairLoadingEnglishActivity.this, RepairActivity.class);
startActivity(intent1);
//弹出
Toast.makeText(getApplicationContext(),ok,Toast.LENGTH_SHORT).show();
}else{
//不正确toast
Toast.makeText(getApplicationContext(),fail,Toast.LENGTH_SHORT).show();
}
}
???????????????//登录主要是用户名和密码的设置
if (v.getId()==R.id.tv_back2){
Intent intent2 = new Intent(RepairLoadingEnglishActivity.this, LoadingEnglishActivity.class);
startActivity(intent2);
}
}
}
|