訊號與系統報告

題目 - 光敏電阻或光感應器之應用

  • 設計一個轉速計並以之控制馬達轉速

Developer:

倪祺婷 林建宏 楊宗凱

實驗器材

RPI3 :

L298N :

其他器材 :

項目 數量 項目 數量
麵包版供電模組 一個 L298N 一個
18650電池 二個 電池盒 一個
馬達 一個 測速盤 一個
RPI3 一台 7697 一個
光柵 二個 手機 一台

實驗步驟(流程圖)

  • server利用Rpi來架設(MQTT),並提供wifi熱點,讓手機、7697得以接收及發送訊息

  • 手機App連接Terminal 來接收、控制轉速 / 7967連接Terminal 來接收控制、回傳轉速

  • 7697輸出pwm訊號來控制馬達轉速 (0-255)

  • 7697利用測速盤(20格)和光柵回傳的資料來測得實際轉速並反饋

資料處理的方式 - 光閘測轉速

  • 如圖所示,利用兩個光閘去測轉速,會得出三個數據,分別是
    1. 兩個光閘本身的數據,
    2. 光閘之間的數據

Miles若不易擺放則只使用一個光柵

  • 測轉速資料處理方式
    1. 利用impulse去測馬達,藉此得到系統的全貌,從光柵得到數位資料及類比資料

    2. 將光柵視為開關,利用7697的 Timer 及 外部中斷來測量轉速

    3. 再利用7697的wifi傳給手機端

Miles 1.轉盤20孔 每18度 Timer每1ms 計數一次
2.可以試試BLE
3. 類比模式只能測量透明度及調整感測器靈敏度

  • 控制轉速資料處理方式
    1. 若從手機端發出參考速度給7697
    2. 7697將速度轉成pwm訊號給l298N模組去控制轉速
    3. 對比接收的轉速和實際測得的轉速來處理誤差(反饋)

資料處理的方式 - 反饋

預計結果

  • 可利用手機與7697溝通,且7697可將測得的轉速送給手機端來顯示,
    手機端也可將所想要的轉速傳給7697去控制馬達轉速

參考資料

  1. L298N 介紹 :
    web.htjh.tp.edu.tw/B4/105-2robot/L298N馬達驅動模組介紹.pdf
  2. 光柵 :
    https://www.openimpulse.com/blog/products-page/product-category/motor-speed-encoder-sensor/
  3. 穩壓模組, 馬達, L298N :
    https://hackmd.io/s/HJkSu1FoZ
  4. Timer :
    https://docs.labs.mediatek.com/resource/linkit7697-arduino/en/developer-guide/timer

結果呈現

利用

  • 一個TT馬達
  • 兩個光閘
  • arduino
  • 7697
  • 手機APP

完成馬達轉速計

完成圖

流程圖

使用器材

項目 數量 項目 數量
麵包版供電模組 一個 L298N 一個
18650電池 二個 電池盒 一個
馬達 一個 測速盤 一個
arduino 一台 7697 一個
光柵 二個 手機 一台

系統架構

  • 利用arduino mega 來測轉速 (原先是打算由7697來測量)
    因 7697 的interrupt 處理速度不夠快,導致光柵無法測量
    所以將原本由7697測量的轉速交給arduino
  • Arduino 利用Rx Tx將量測到的轉速傳給7697
  • 7697 利用 BLE 傳現在的轉速給手機端
  • 手機端可將想達到的轉速傳給7697,7697利用arduino量到的轉速來調整pwm

程式碼

7697程式碼

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 11); // RX, TX

#include <LBLE.h>
#include <LBLEPeriphral.h>
LBLEService ledService("19B10010-E8F2-537E-4F6C-D104768A1214");
LBLECharacteristicString switchCharacteristic("19B10011-E8F2-537E-4F6C-D104768A1214", LBLE_READ | LBLE_WRITE);
String text="";


const int motorin1 = 16;
const int motorin2 = 17;

const int mul[4] = {1000,100,10,1};
int count = 3;
bool flag=false;
// speed is rpm
int required_speed = 810;
int now_speed = 0;
bool at_range=false;
int now_pwm = 160;
 int boundarylarge = 100;
 int boundarymid = 50;
 int boundarysmall = 10;
int pwm_count=0;
void setup() {
  Serial.begin(9600);           //設定baud rate
  pinMode(motorin1,OUTPUT);
  pinMode(motorin2,OUTPUT);
  analogWrite(motorin1,now_pwm);
  analogWrite(motorin2,0);

  while (!Serial) {
    ;
  }
  Serial.println("Goodnight moon!");
  mySerial.begin(4800);
  
  LBLE.begin();
  while (!LBLE.ready()) {
    delay(100);
  }
  Serial.println("BLE ready");
  detect_bound();
  Serial.print("Device Address = [");
  Serial.print(LBLE.getDeviceAddress());
  Serial.println("]");
  LBLEAdvertisementData advertisement;
  advertisement.configAsConnectableDevice("BLE MOTOR");
  LBLEPeripheral.setName("BLE MOTOR");
  ledService.addAttribute(switchCharacteristic);
  LBLEPeripheral.addService(ledService);
  LBLEPeripheral.begin();
  LBLEPeripheral.advertise(advertisement);
}

void loop() {
  
  if(mySerial.available() ) {     // 有收到數值時,會回傳>0的值
    char i = mySerial.read();

    if(i=='.')
    {
      flag=true;
    }
    else
    {
      if(flag)
      {
        if(i<='9'&&i>='0')
        {
          now_speed += (int)(i-'0')*mul[count] ;
          count--;
        if(count==-1) 
        {
          pwm_set();
          send_data(now_speed);
          // 傳送data給手機
          count = 3; now_speed = 0;
          flag=false;
        }

        }
    }
    }
  }
  LBLEPeripheral.connected();
  //Serial.print("conected=");
  //Serial.println(LBLEPeripheral.connected());
  /*if (digitalRead(6))   // 斷線
  {
    Serial.println("disconnect all!");
    LBLEPeripheral.disconnectAll();
  }*/
  if (switchCharacteristic.isWritten()) {   // 接收到手機資料
    text = switchCharacteristic.getValue();
    required_speed = text.toInt();
     at_range=false;
    Serial.println(required_speed);
      detect_bound();
  }
}

//傳資料
void send_data(int data) {
  switchCharacteristic.setValue(String(data));
  LBLEPeripheral.notifyAll(switchCharacteristic);
  }


void pwm_set() { 
  if(at_range)
  {
     if(abs(now_speed-required_speed)>boundarysmall)
     {
       ++pwm_count;
     }
     else
     {
      pwm_count=0;
     }
     if(pwm_count>=3)
     {
      at_range=false;
     }
  }
  else
  {
    int x=now_speed-required_speed;
    int y = abs(x);
    if(x>=0)
    {
      if(y>=boundarylarge)
      {
        now_pwm-=5;
      }
      else if (y>=boundarymid)
      {
        now_pwm-=2;
      }
      else if (y>=boundarysmall)
      {
        now_pwm-=1;
      }
      else
      {
        at_range=true;
      }
    }
    else
    {     
      if(y>=boundarylarge)
      {
        now_pwm+=5;
      }
      else if (y>=boundarymid)
      {
        now_pwm+=2;
      }
      else if (y>=boundarysmall)
      {
        now_pwm+=1;
      }
      else
      {
        at_range=true;
      }
    }
  }
  if(now_pwm<100)
    now_pwm=100;
  if(now_pwm>210)
    now_pwm=210;
  analogWrite(motorin1,now_pwm);
  analogWrite(motorin2,0);
  Serial.print("now_pwm : ");
  Serial.println(now_pwm);
}
void detect_bound()
{
  boundarysmall=(int)(5+(required_speed-700)/28\\\\\\\\
  3.20);
  boundarylarge=boundarysmall+100;
  boundarymid=boundarysmall+50;
}


Arduino程式碼

#include <SoftwareSerial.h>
SoftwareSerial mySerial(15,14);//RX TX
unsigned long count=0;
int counterPin = 2;
unsigned long time2;
unsigned long rpm;      
unsigned int grid_num = 16;

void counter() {
   count++;
}

void setup() {
   Serial.begin(9600);
   mySerial.begin(4800);
  // pinMode(counterPin, INPUT);
   attachInterrupt(0, counter, RISING);
   count = 0;
   rpm = 0;
   time2 = 0;
}

void loop() {

 if (millis() - time2 >= 1000){   /* 每秒更新 */
 
     // 計算 rpm 時,停止計時
     detachInterrupt(0);

     // 偵測的格數count * (60 * 1000 / 一圈網格數20)/ 時間差) 
     rpm=60000*count/grid_num;
     rpm = rpm/ (millis() - time2);
     
     count = 0;
    
     // 輸出至Console
     Serial.print("RPM = ");
     Serial.println(rpm,DEC);
         for(int i=0;i<4;i++) { 
        int data = rpm%10;
        mySerial.print(data);
        rpm /= 10;
     }
      mySerial.print('.');;
     //Restart the interrupt processing
     time2 = millis();
     attachInterrupt(0, counter, RISING);
  }
}

APP程式碼

package org.hopto.pipe.ble_motor;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ArrayAdapter;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter mBluetoothAdapter;
    private static final int REQUEST_ENABLE_BT = 2;
    private BluetoothManager mBluetoothManager;
    private Handler mHandler;
    private ArrayList<String> deviceName;
    private ArrayList<BluetoothDevice> mBluetoothDevices=new ArrayList<BluetoothDevice>();
    private static final int REQUEST_CODE_ACCESS_COARSE_LOCATION = 1;
    private ListAdapter adapter;
    private BluetoothLeScanner scanner;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ListView listview = (ListView) findViewById(R.id.list);
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        deviceName=new ArrayList<String>();
        adapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1,deviceName) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View view = super.getView(position, convertView, parent);
                TextView text = (TextView) view.findViewById(android.R.id.text1);
                text.setTextColor(Color.WHITE);
                return view;
            }
        };
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                        Manifest.permission.ACCESS_COARSE_LOCATION)) {

                }
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                        REQUEST_CODE_ACCESS_COARSE_LOCATION);
            }
        }
        listview.setAdapter(adapter);
        listview.setOnItemClickListener(onClickListView);
        mHandler=new Handler();
        scanner = mBluetoothAdapter.getBluetoothLeScanner();
    }
    public void startScanning(){
        deviceName.clear();
        mBluetoothDevices.clear();
        ((BaseAdapter)adapter).notifyDataSetChanged();
        scanner = mBluetoothAdapter.getBluetoothLeScanner();
        scanner.startScan(new MyScanCallback());

    }
    public void stopScanning()
    {
        scanner = mBluetoothAdapter.getBluetoothLeScanner();
        scanner.stopScan(new MyScanCallback());

    }
    private AdapterView.OnItemClickListener onClickListView = new AdapterView.OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // Toast 快顯功能 第三個參數 Toast.LENGTH_SHORT 2秒  LENGTH_LONG 5秒
            Toast.makeText(MainActivity.this,"點選第 "+(position +1) +" 個 \n內容:"+parent.getAdapter().getItem(position), Toast.LENGTH_SHORT).show();
            final BluetoothDevice mBluetoothDevice=mBluetoothDevices.get(position);
            Log.d("device choose",mBluetoothDevice.toString());
            Intent goControlIntent=new Intent(MainActivity.this,control.class);
            //將device Name與address存到ControlActivity的DEVICE_NAME與ADDRESS,以供ControlActivity使用
            goControlIntent.putExtra("name",mBluetoothDevice.getName());
            goControlIntent.putExtra("address",mBluetoothDevice.getAddress());
            stopScanning();
            startActivity(goControlIntent);
        }
    };
    public void scan_click(View view){
        Toast.makeText(MainActivity.this,"Begin scan", Toast.LENGTH_SHORT).show();
        startScanning();
    }
    public void stop_click(View view){
        Toast.makeText(MainActivity.this,"Stop scan", Toast.LENGTH_SHORT).show();
        stopScanning();

    }
    @Override
    protected void onResume() {
        super.onResume();
        if(!mBluetoothAdapter.isEnabled()){
            Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent,REQUEST_ENABLE_BT);
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(REQUEST_ENABLE_BT==2 && resultCode== Activity.RESULT_CANCELED){
            finish();
            return;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    public class MyScanCallback extends ScanCallback {

        @Override
        public void onScanResult(int callbackType, final ScanResult result) {

            BluetoothDevice device = result.getDevice();
            if(mBluetoothDevices.contains(device))
                return;
            mBluetoothDevices.add(device);
            String deviceInfo = device.getName() + " - " + device.getAddress();
            ScanRecord scanRecord = result.getScanRecord();
            List<ParcelUuid> uuids = scanRecord.getServiceUuids();

            if(uuids != null) {
                for(int i = 0; i < uuids.size(); i++) {
                    deviceInfo += "\n" + uuids.get(i).toString();
                }
            }
            final String text = deviceInfo;
            Log.d("res",text );
            deviceName.add(text);
            ((BaseAdapter)adapter).notifyDataSetChanged();
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            //Do something with batch of results
        }

        @Override
        public void onScanFailed(int errorCode) {
            Log.d("error","Cannot scan");
            Toast.makeText(MainActivity.this,"Cannot scan", Toast.LENGTH_SHORT).show();
        }
    }

}


APP程式碼

package org.hopto.pipe.ble_motor;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextPaint;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class control extends AppCompatActivity {
    private String name;
    private String address;
    private  BluetoothGatt mGatt =  null ;
    private BluetoothDevice device;
    private BluetoothAdapter adapter;
    private ArrayList< BluetoothGattService> service_list=new ArrayList< BluetoothGattService>();
    private int state;
    private ListAdapter listadapter;
    private ArrayList<String> serviceName;
    private boolean done;
    private Handler mHandler ;
    private ListView listview;
     private TextInputLayout Input;
     private Button returnlist;
     private Button send;
     private EditText textfield;
     private BluetoothGattCharacteristic characteristic=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_control);
        listview= (ListView) findViewById(R.id.list1);
        Intent intent = getIntent();
        name=intent.getStringExtra("name");
        address=intent.getStringExtra("address");
        Input=( TextInputLayout) findViewById(R.id.motorinput);
        returnlist=(Button) findViewById(R.id.re);
        send=(Button)findViewById(R.id.send);
        textfield=(EditText) findViewById(R.id.text_dis);
        Input.setVisibility(View.INVISIBLE);
        returnlist.setVisibility(View.INVISIBLE);
        send.setVisibility(View.INVISIBLE);
        textfield.setVisibility(View.INVISIBLE);
        textfield.setKeyListener(null);
        Log.d("name",name);
        Log.d("address",address);
        serviceName=new ArrayList<String>();
        final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
        adapter = bluetoothManager.getAdapter();
        listadapter = new ArrayAdapter(this,
                android.R.layout.simple_list_item_1,serviceName);
        device=adapter.getRemoteDevice(address);
        listview.setAdapter(listadapter);
        listview.setOnItemClickListener(onClickListView);
        done=false;
        connect_BLE();
       mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                switch(msg.what){
                    case 1:
                        ((BaseAdapter)listadapter).notifyDataSetChanged();
                        break;
                    case 2:
                        textfield.append(msg.getData().getString("text"));
                        break;
                }
            }
        };
    }
    private void connect_BLE() {
        ParcelUuid[] uuids = (ParcelUuid[]) device.getUuids();
        mGatt = device.connectGatt( this ,  true , mGattCallback);
        textfield.setText("");
        Log.d("a",mGatt.toString());
    }
    private AdapterView.OnItemClickListener onClickListView = new AdapterView.OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // Toast 快顯功能 第三個參數 Toast.LENGTH_SHORT 2秒  LENGTH_LONG 5秒
            Toast.makeText(control.this,"點選第 "+(position +1) +" 個 \n內容:"+parent.getAdapter().getItem(position), Toast.LENGTH_SHORT).show();
            characteristic=service_list.get(position).getCharacteristics().get(0);
            mGatt.setCharacteristicNotification( characteristic,true);
            mGatt.readCharacteristic(characteristic);
            Input.setVisibility(View.VISIBLE);
            returnlist.setVisibility(View.VISIBLE);
            send.setVisibility(View.VISIBLE);
            textfield.setVisibility(View.VISIBLE);
            listview.setVisibility(View.INVISIBLE);
        }
    };
    public void reclick(View view)
    {
        textfield.setText("");
        mGatt.setCharacteristicNotification( characteristic,false);
        Input.setVisibility(View.INVISIBLE);
        returnlist.setVisibility(View.INVISIBLE);
        send.setVisibility(View.INVISIBLE);
        textfield.setVisibility(View.INVISIBLE);
        listview.setVisibility(View.VISIBLE);
    }
    public void sendclick(View view) {
        byte[] send1=null;
        try{
            send1 = Input.getEditText().getText().toString().getBytes("UTF-8");
        }catch (Exception e)
        {

        }

        if(send1!=null) {
            Log.e("dataSend", new String(send1));
            characteristic.setValue(send1);
            boolean status = mGatt.writeCharacteristic(characteristic);
            Log.e("dataSend", status + "");
            mGatt.writeCharacteristic(characteristic);
        }
    }
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            Log.i("t", "Connected to GATT server.");
            // Attempts to discover services after successful connection.
            Log.i("t", "Attempting to start service discovery:" + gatt.discoverServices());
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            Log.i("t", "Disconnected from GATT server.");

            String address = gatt.getDevice().getAddress();
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            boolean isGood = true;
            for (int i = 0; i < gatt.getServices().size(); i++) {
                BluetoothGattService bgs = gatt.getServices().get(i);
                Log.w("t", "found service " + bgs.getUuid().toString());
                Log.w("t", bgs.getCharacteristics().toString());
                service_list.add(bgs);
                String text = "found service " + Integer.toString(i + 1) + "\n" + bgs.getUuid().toString();
                serviceName.add(text);
                if (bgs.getCharacteristics().size() == 0)
                    isGood = false;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Message msg = new Message();
            msg.what = 1;
            mHandler.sendMessage(msg);
        } else {
            Log.w("t", "onServicesDiscovered received: " + status);
        }
        if(characteristic!=null)
        mGatt.setCharacteristicNotification( characteristic,true);
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic, int status) {
        Log.e("onCharacteristicRead中", "recieve" + new String(characteristic.getValue()));
        Message msg = new Message();
        msg.what = 2;
        Bundle b=new Bundle();
        b.putString("text","now speed  "+new String(characteristic.getValue())+" (rmp) "+"\n");
        msg.setData(b);
        mHandler.sendMessage(msg);
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,
                                      BluetoothGattCharacteristic characteristic, int status) {//发送数据时调用
        if (status == BluetoothGatt.GATT_SUCCESS) {//写入成功
            Message msg = new Message();
            msg.what = 2;
            Bundle b=new Bundle();
            b.putString("text","寫入成功\n");
            msg.setData(b);
            mHandler.sendMessage(msg);
        } else if (status == BluetoothGatt.GATT_FAILURE) {
            Log.e("onCharacteristicWrite中", "fail");
        } else if (status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED) {
            Log.e("onCharacteristicWrite中", "no permission");
        }

    }
    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {// Characteristic 改变,数据接收会调用
        Log.e("onCharacteristicChange中", "recieve" + new String(characteristic.getValue()));
        Message msg = new Message();
        msg.what = 2;
        Bundle b=new Bundle();
        b.putString("text","now speed  "+new String(characteristic.getValue())+" (rmp) "+"\n");
        msg.setData(b);
        mHandler.sendMessage(msg);
    }
};


}


改進項目

  • 更換測速盤格數(4格)
  • 將TT馬達換成12V直流馬達
  • 根據需求的速度去調整容許的誤差範圍
  • 在速度的調整上增加誤差容許,以防速度不斷變化
  • 獲得資料的方法

遇到的難題

  • 網購測速盤未送達
  • 光柵訊號問題 - 馬達沒轉arduino卻產生interrupt
  • interrupt處理問題 - 測速盤格數過多、轉速過快

解決方法

  1. 網購測速盤未送達
    透過自製轉速盤,在解決該問題下,還可自行設定測速盤格數 (難題3)
  2. 光柵訊號問題
    礙於使用arduino和7697導致線路有些複雜,經確認後發現是共地的參考點所導致
  3. interrupt處理問題
    12V直流馬達的轉速比TT馬達還要快許多,所以在使用相同測速盤下,處理速度無法跟上,所以我們調低測速盤的格數,來降低interrupt產生的時間間隔
  4. 馬達架設問題
    馬達沒地方可以裝支架,只好利用L型支架把它夾住,然後架起來。

改進後的成品

Select a repo