查看完整版本: 有關Arduino的問題
頁: [1]

xznm0215 發表於 2017-5-3 11:42 PM

有關Arduino的問題

目前有點小問題,目的是要讓超音波感測到障礙物時會馬達會停止,沒有障礙物時馬達會動作,但現在因為有加進PWM去控制速度,但是這LOOP裡的速度會影響到SWITCH的速度,比方說當啟動FORWARD時速度是127但維持時間只維持很短,delay完就回到LOOP的速度191去,但拿掉那段後,速度維持的時間是持續的,但有點缺陷是感測到障礙物時停止,但當障礙物移走後就不會自行啟動了,請問要如何修正?


#include <SoftwareSerial.h>
#include <Wire.h>  
#include <stdio.h>
int enablePin = 6;
int motorPin1 = 3;
int motorPin2 = 5;
int trig = 9 , echo = 8 ;
int beep = 12;
char x;
byte dis;  //distance package
SoftwareSerial BT(10, 11); // RX, TX
float distance = 0;
char dischar;
int i=0;


float Length()
{
  float duration, distancetmp;
  digitalWrite(trig, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trig, LOW);
  duration = pulseIn (echo, HIGH);
  distancetmp = (duration / 2) / 29;
  return distancetmp;
}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  BT.begin(9600);
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(beep, OUTPUT);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(enablePin, LOW);
  delay(1000);
}

void loop()
{
  {
  distance = Length();
  if (distance < 20)
  {   
    Serial.print("WARNING!");
    Serial.print("Obstacle!!");
    digitalWrite(beep,HIGH);
    delay(500);
    digitalWrite(beep,LOW);
    analogWrite(enablePin, 0);
  }
  else
  {
    Serial.print("OK!");
    digitalWrite(beep,LOW);
    delay(500);
    analogWrite(enablePin, 191);
  }
  Serial.print("distance = ");
  Serial.print(distance);
  Serial.println("cm");
  delay(500);
  }
  int sendData = (int) (distance * 100); //times 100 and convert disance to integer
  byte packet;
  packet = 97;
  packet = sendData / 256; //divides sendData to two 1 byte packets
  packet = sendData % 256;
  if ( BT.available()>0)
  {
    if (BT.read() == 97)
    {
    for(int i = 0; i < 3; i++)
    BT.write(packet);
    }
    val = BT.read();
      
  }
  switch(x)
    {
      case 'F':   // car forward
                forward();
                break;
      case 'B':   // car back
                back();
                break;
      case 'S':   // car stop
                motorstop();
                break;      
      case 'H':   // speed high
                motorhigh();
                break;
      case 'M':   // speed mid
                motormedian();
                break;      
      case 'L':   // speed low
                motorlow();
                break;                              
    }   
}

void motorstop()
{
  Serial.println("Stop!");
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  analogWrite(enablePin, 0);
  delay(500);
}

void forward()
{
  Serial.println("Forward!");
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  analogWrite(enablePin, 127);
  delay(500);
}
void back()
{
  Serial.println("Back!");
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  analogWrite(enablePin, 127);
  delay(500);
}
void motorhigh()
{
  Serial.println("High!");
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  analogWrite(enablePin, 255);
  delay(500);
}
void motormedian()
{
  Serial.println("Median!");
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  analogWrite(enablePin, 150);
  delay(500);
}
void motorlow()
{
  Serial.println("Low!");
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  analogWrite(enablePin, 64);
  delay(500);
}
...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><div></div>

johnwanz 發表於 2017-5-4 08:52 AM

你的switch按照狀態給定了行動. 但是狀態X的遷移控制, 並沒有看到呢. 是code沒有po上來? 你提到對應狀態的行動是正常的, 那問題就在於狀態與狀態間的變換不正常.

chevylin0802 發表於 2017-5-4 10:21 AM

本帖最後由 chevylin0802 於 2017-5-4 10:30 AM 編輯

#include <SoftwareSerial.h>
#include <Wire.h>  
#include <stdio.h>
int enablePin = 6;
int motorPin1 = 3;
int motorPin2 = 5;
int trig = 9 , echo = 8 ;
int beep = 12;
char x;
byte dis;  //distance package
SoftwareSerial BT(10, 11); // RX, TX
float distance = 0;
char dischar;
int speed = 0; // speed control value
int i=0;


float Length()
{
  float duration, distancetmp;
  digitalWrite(trig, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trig, LOW);
  duration = pulseIn (echo, HIGH);
  distancetmp = (duration / 2) / 29;
  return distancetmp;
}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  BT.begin(9600);
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(beep, OUTPUT);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(enablePin, LOW);
  delay(1000);
}

void loop()
{
  
  distance = Length();
  if (distance < 20) {   
    Serial.print("WARNING!");
    Serial.print("Obstacle!!");
    digitalWrite(beep,HIGH);
    // delay(500);     
    // cancelled because too many delay code
    digitalWrite(beep,LOW);
    speed = 0;
    analogWrite(enablePin, speed);
  } else {
    Serial.print("OK!");
    digitalWrite(beep,LOW);
    // delay(500);     
    // cancelled because too many delay code
    if( speed == 0 ) {
        speed = 191; // 191 or 127 ?
        analogWrite(enablePin, speed);
    }
  }
  Serial.print("distance = ");
  Serial.print(distance);
  Serial.println("cm");
  delay(500);
  
  int sendData = (int) (distance * 100); //times 100 and convert disance to integer
  byte packet;
  packet = 97;
  packet = sendData / 256; //divides sendData to two 1 byte packets
  packet = sendData % 256;
  if ( BT.available() > 0 ) {
    if (BT.read() == 97) {
       for(int i = 0; i < 3; i++)
           BT.write(packet);
    }
    val = BT.read();
      
    switch(x) {
      case 'F':   // car forward
                forward();
                break;
      case 'B':   // car back
                back();
                break;
      case 'S':   // car stop
                motorstop();
                break;      
      case 'H':   // speed high
                motorhigh();
                break;
      case 'M':   // speed mid
                motormedian();
                break;      
      case 'L':   // speed low
                motorlow();
                break;                              
    }   
    delay(500);  // if bluetooth command transmitted, the delay is need
  }

}

void motorstop()
{
  speed = 0;
  Serial.println("Stop!");
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  analogWrite(enablePin, speed);
}

void forward()
{
  Serial.println("Forward!");
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  if(speed == 0) {
     speed = 127;
     analogWrite(enablePin, speed);
  }
}

void back()
{
  Serial.println("Back!");
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  if(speed == 0) {
     speed = 127;
     analogWrite(enablePin, speed);
  }
}

void motorhigh()
{
  Serial.println("High!");
  if( speed != 255 ) { // if is 255 then no more need repeat the output
      speed = 255;
      analogWrite(enablePin, speed);
  }
}

void motormedian()
{
  speed = 127;
  Serial.println("Median!");
  if( speed != 127 ) { // if is 127 then no more need repeat the output
      speed =127;
      analogWrite(enablePin, speed);
  }
}

void motorlow()
{
  speed = 63;
  Serial.println("Low!");
  if( speed != 63 ) { // if is 63 then no more need repeat the output
      speed = 63;
      analogWrite(enablePin, speed);
  }
}這是修改後的代碼
你可以試試...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

xznm0215 發表於 2017-5-4 02:20 PM

本帖最後由 xznm0215 於 2017-5-4 02:35 PM 編輯

chevylin0802 發表於 2017-5-4 10:21 AM static/image/common/back.gif
這是修改後的代碼
你可以試試
謝謝,這問題有解決了,原來是要這樣修正,真的謝謝了

xznm0215 發表於 2017-5-5 02:50 PM

chevylin0802 發表於 2017-5-4 10:21 AM static/image/common/back.gif
這是修改後的代碼
你可以試試

您好,我現在有個問題,當我用的ai2作的app藍芽連線後會發生傳遞延遲
請問是我藍芽那邊程式設錯嗎?<br><br><br><br><br><div></div>

chevylin0802 發表於 2017-5-5 03:40 PM

本帖最後由 chevylin0802 於 2017-5-5 04:00 PM 編輯

xznm0215 發表於 2017-5-5 02:50 PM static/image/common/back.gif
您好,我現在有個問題,當我用的ai2作的app藍芽連線後會發生傳遞延遲
請問是我藍芽那邊程式設錯嗎? ...
你是從電腦使用App Inventor
它本身就是一套採用java運行的伺服器
你要靠瀏覽器去跟它連線才能工作
所以本身一定會有延遲
一般我們不會這樣子做
因為多了一道http的傳輸過程
採用HTTP的方式進行的時候它的延遲速度是必然存在的
所以我們通常都是直接採用寫APP的方式放到手機裏
直接採用手機與板子溝通的方式做

我有試過採用Bluno的板子
它的效能會比較好一些
因為它所使用的藍芽晶片是TI的CC254x系列的Bluetooth 4.0晶片
手機端程式可以採用Bluetooth 3.0+HS的Serial Communication的方式來溝通
反應速度也比較快

而Arduino官方所介紹的HC-05或HC-06
都只是Bluetooth 2.1+EDR的規格
傳輸方式以及傳輸速度上與Bluetooth 3.0所規範的硬體規格差一大截

...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

xznm0215 發表於 2017-5-5 04:10 PM

chevylin0802 發表於 2017-5-5 03:40 PM static/image/common/back.gif
你是從電腦使用App Inventor
它本身就是一套採用java運行的伺服器
你要靠瀏覽器去跟它連線才能工作


但當我把紅字這段拿掉,綠字改成if ( BT.available()) ,等於是把超音波傳遞的值給拿掉,單作控制反而沒有延遲問題
,範例次參考雙A計畫的PART7做的
  int sendData = (int) (distance * 100); //times 100 and convert disance to integer   byte packet;
  packet = 97;
  packet = sendData / 256; //divides sendData to two 1 byte packets
  packet = sendData % 256;
  if ( BT.available() >...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

chevylin0802 發表於 2017-5-5 04:54 PM

xznm0215 發表於 2017-5-5 04:10 PM static/image/common/back.gif
但當我把紅字這段拿掉,綠字改成if ( BT.available()) ,等於是把超音波傳遞的值給拿掉,單作控制反而沒 ...

不能直接拿掉
否則你的read()會一直傳回97
你再試試看在BT.write(packet);之後再加一行BT.flush();
或許就可以了

xznm0215 發表於 2017-5-22 05:32 PM

chevylin0802 發表於 2017-5-5 04:54 PM static/image/common/back.gif
不能直接拿掉
否則你的read()會一直傳回97
你再試試看在BT.write(packet);之後再加一行BT.flush();


我想請問一下,如果說造成傳遞延遲的話是什麼情況

chevylin0802 發表於 2017-5-22 06:01 PM

本帖最後由 chevylin0802 於 2017-5-22 06:06 PM 編輯

xznm0215 發表於 2017-5-22 05:32 PM static/image/common/back.gif
我想請問一下,如果說造成傳遞延遲的話是什麼情況
因為網路傳輸跟串列傳輸都會開一塊記憶體暫存區
不管是傳送還是接收都各有一段暫存區在記憶體上
當write()的函式執行時
並沒有碼上就把資料傳送出去
而是需要等到flush()被呼叫的時候才會真正的執行
flush還有一個重要的功能就是清除暫存區的資料
當然它是必需要等到傳送資料已經完成才會真正進行清空的動作
所以傳送之所以會延遲都跟資料是否有真正的傳出去有關
由於Arduino只是單晶片
而這個單晶片只能夠透過串列介面來連結到藍芽晶片上
所以串列介面只要傳送資料就必需要在之後加上一行flush()的動作
來確保資料可以在第一時間發送出去

至於available()這個函式是在檢查串列介面讀取資料的暫存區裏有沒有新的資料進來
如果你沒有去檢查的話
那麼它就會造成你的write不斷的重複執行

...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div><br><br><br><br><br><div></div>
頁: [1]