2018年5月15日 星期二

8051 (6) 紅外線避障模組控制LED七段顯示器。



這篇要做的Project就是感測器測到訊號時,LED七段顯示器會開始計算偵測次數,

到第5次時會讓紅色LED燈發光。



程式如下:

#include <reg52.h>

unsigned char seg[5]={0xf9,0xa4,0xb0,0x99,0x92}; //七段顯示器0~4。
sbit Sensor=P2^0;
sbit LED=P2^1;
void delay(unsigned int);
int seven_count=0;//LED7計數器。
void main()
{
 while(1)
 {
  if(Sensor==0){  //感測器是觸發給低電位。
P1=~seg[seven_count];//一開始是"0",所以LED7會先顯示"0"。
delay(20000);
seven_count++;//計數器先加1,再度觸發時就會顯示+1後的數值。。
}
if(seven_count>=5){
LED=0;//計數器為5的時候亮紅色燈泡。
delay(30000);
seven_count=0;//清除計數器。
if(seven_count<5){//計數器小於5的時候紅色燈泡不亮。
LED=1;
  delay(5000);
}
}
  }
 }   

void delay( unsigned int count)
{
 unsigned int i;
 for(i=0;i<count;i++);
}

我本來想再加一些功能,就是如果數到5以下時過了5秒會自動清除計數器,

這我還在試...

2018年5月10日 星期四

8051 (5) 外部中斷實驗。

使用5顆燈泡和1個按鈕,

按鈕按下後燈泡換切換觸發I/O埠低電位。




程式如下 :

#include <reg52.h>
unsigned char LED_P1=0x15;//P1二進制10101。
unsigned char LED_P2=0x06;//P2二進制110。
void delay(unsigned int);
char a;

void main()
{
 SP=0x60;
 EA=1;//打開中斷功能。
 EX0=1;//外部中斷0。
 IT0=1;//負緣觸發。
 a=1;//按鈕預設1,功能等同Boolean。

 while(1)
 {
  if(a==1){//按下次數雙數狀態。
   P1=~LED_P1;
   P2=LED_P2;
  }
  if(a==0){//按下次數單數狀態。
   P1=LED_P1;
   P2=~LED_P2;
  }
delay(10000);
 } 
}


void delay( unsigned int count)
{
 unsigned int i;
 for(i=0;i<count;i++);
}

void EX0_INT(void) interrupt 0 //外部中斷0的function,按鈕狀態切換。
{
 a=!a;
}

8051 (4) 七段顯示器。(TIMER)

這篇也沒什麼重點,就簡單的顯示1~0,做個紀錄囉。


程式如下 :

#include "reg52.h"


void main(){
int count=0;
int i=0;
unsigned char seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//定義1~0陣列。
TMOD=0x01;
TH0=0xB8;
TL0=0x00;
TR0=1;
while(1){
if(TF0==1){
TF0=0;
TH0=0xB8;
      TL0=0x00;
count++;
if(count>=20){
count=0;
P1=~seg[i];
i++;
if(i>=10){
i=0;
}
}
}
}
}
後面整段"TIMER"就跟第2篇的51很像,這邊就不另外標註了。

8051 (3) 霹靂燈。


霹靂燈,就像是小時候看的霹靂遊俠車頭的排序燈。

這篇沒什麼重點,只是Arduino沒有去寫霹靂燈,用51補上囉。

程式如下 :

#include <reg52.h>

void delay(int );//Delay寫成function。

main()
{
    char code led[]={0x01,0x02,0x04,0x08,0x10};//一樣是P1.0~P1.4。
    int i;
    P1=0xff;
    while(1)
    {
        for(i=0;i<4;i++)
        {
        P1=~led[i];//陣列0~4負電位觸發。
        delay(50);
        }
for(i=4;i>0;i--)
        {
        P1=~led[i];//陣列4~0負電位觸發。
        delay(50);
        }
       
    }
}

void delay(int x)
{
    int i,j;
    for(i=0;i<x;i++)
        for(j=0;j<600;j++);}

2018年5月8日 星期二

8051 (2) 單向跑馬燈。(TIMER版本)

影片範例跟上一篇差不多,故不另行貼上了。

程式如下 :

#include "reg52.h"


void main(){
int count=0;
int i=0;
unsigned char seg[]={0x01,0x02,0x04,0x08,0x10};  //I/O輸出陣列P1.0~P1.4。
TMOD=0x01;  //模式選擇16位元計時器。
TH0=0xB8;  //設高低8位(20ms)。
TL0=0x00;
TR0=1; //啟動計時器。
while(1){
if(TF0==1){  //溢位旗標。
TF0=0;  //清除旗標。
TH0=0xB8;//重設高低8位。
                        TL0=0x00;
count++; //溢位1次計數+1。
if(count>=20){//20X20ms=400,400ms執行如下。
count=0;  //計數計清除。
P1=~seg[i];//低電位觸發,"i"從0開始每400ms增加。
i++;
if(i>=5){//第5顆燈點亮後"i"清0。
i=0;
}
}
}
}
}

看起來有點複雜,但是不難,整合進計時器功能而已,說是會比較準,我倒沒什麼感覺。

8051 (1) 單向跑馬燈。(Shift版本)


玩過 Arduino後再回頭寫8051,感覺Arduino人性化非常多,而且我手上這組8051,不是開發板,只能玩數位訊號,並沒有加AD轉換器,因為功能有限,就簡單寫幾篇囉。

上面這張板子是跟同事借的,單純只有I/O,而且這Layout有問題,怎麼I/O是沒規則的亂跳呢??

最大的好處是這張有ISP轉USB,這樣燒錄就很方便了!!

這篇就先來寫個最簡單的跑馬燈吧!!!

因為我這張8051最好是用低電位觸發,所以我都寫成低電為觸發囉。

就這樣,慢慢依序亮滅亮滅。

程式如下 :


#include "reg51.h"

unsigned int i;
unsigned char count=0; //計數器預設0。
void main()
{
while(1)   //Arduino的Loop,無限迴圈。
{
  P1=~(0X01<<count); //P1埠(00000001),P1.0為HIGH,"~"反向低電位觸發,位移1位。
                                      
for(i=0;i<20000;i++);//延遲。
count++;//每次延遲後位移+1。
if(count>=5){//如果位移達5次清除計數器。
count=0;
    }
  }
}

沒難度,超簡單跑馬燈完成!!

如果你要0X01、0X02、0X04、0X08..........輪者亮也可以,不過這樣的程式會很長,用位移是最理想的。



2018年3月5日 星期一

Arduino (26) 主、從端HC-05藍芽互相連通+二輪智能車系統。


智能車搭配藍芽序列阜操控,

如果已經玩到現在這種程度的話就知道只是想充充版面而已,

沒什麼難度,只想試看看而已,順便也寫一下。



搭配一個Master。




因為要同時看螢幕和車子,只好讓他懸空轉。

程式如下 :

就只附上Slave端的就好了。

#include <SoftwareSerial.h>
SoftwareSerial BT(3, 4);
char val;
const byte IN1 = 10;  
const byte IN2 = 9;
const byte IN3 = 8;
const byte IN4 = 7;

void setup() {
  BT.begin(38400);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
}
void forward()
{
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
}
//前進的函式。

void backward()
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
}
//後退的函式。

void turnLeft()
{
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
}
//左轉的函式。

void turnRight()
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
}
//右轉的函式。

void stop()
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
}
//停止的函式。
void loop() {
  if (BT.available()) {
    val = BT.read();
    if (val == '1') {
      forward();
      delay(100);
      BT.println("forward");
    } else if (val == '2') {
      backward();
      delay(100);
      BT.println("backward");
    }else if (val == '3') {
       turnLeft();
       delay(100);
      BT.println("turnLeft");
    }
    else if (val == '4') {
       turnRight(); 
       delay(100);
      BT.println("turnRight");
    }
    else if (val == '5') {
       stop();
       delay(100);
      BT.println("stop");
    }
    //輸入數字對應輪子轉動方式。

    delay(100);
  }
}




2018年3月4日 星期日

Arduino (25) 循跡辨識模組TCRT5000+二輪智能車系統。


智能車專案的第三種系統,辨識黑白線軌道,感應模組就是萬向輪左右那兩根。



循跡辨識模組TCRT5000,上面有一顆LED,觸發才會亮,基本原理是紅外線反射。

安裝位置愈低愈好,我一開始安裝太高反應很遲鈍。




意外的強,還以為這東西會有跟超聲波一樣反應遲鈍的問題。


程式如下:

const int SRight = 2;    
const int SLeft = 3;      
//右、左輪感測器宣告。

const int motorIn1 = 10;
const int motorIn2 = 9;
const int motorIn3 = 8;     
const int motorIn4 = 7;      
char val; 
int SRR;    
int SLL;    
byte byteSensorStatus=0;

void setup() 
{
  pinMode(SLeft, INPUT);
  pinMode(SRight, INPUT);
  pinMode(motorIn1, OUTPUT);
  pinMode(motorIn2, OUTPUT);
  pinMode(motorIn3, OUTPUT);
  pinMode(motorIn4, OUTPUT);  
}


void loop(){
 byteSensorStatus = 0;
  SRR = digitalRead(SRight);
  if(SRR == 1)
     byteSensorStatus = (byteSensorStatus | (0x01 << 1));

  SLL = digitalRead(SLeft);
  if(SLL == 1)
     byteSensorStatus = (byteSensorStatus | 0x01);
   //辨識循跡狀態的公式。

  switch(byteSensorStatus)
  {             
    case 0: 
           motorstop();
            break;
    //0、0(黑、黑,停止)。

    case 1: 
             left();  
            break;
   //1、0(白、黑,左轉)。

    case 2: 
             right(); 
            break;
   //0、1(黑、白,右轉)。

    case 3: 
           forward() ;
            break;
   //1、1(白、白,前進)。

  } 

}

void motorstop()
{
  digitalWrite(motorIn1, LOW);
  digitalWrite(motorIn2, LOW);
  digitalWrite(motorIn3, LOW);
  digitalWrite(motorIn4, LOW);
}

void forward()
{
  digitalWrite(motorIn1, HIGH);
  digitalWrite(motorIn2, LOW);
  digitalWrite(motorIn3, HIGH);
  digitalWrite(motorIn4, LOW);
}

void backward()
{
  digitalWrite(motorIn1, LOW);
  digitalWrite(motorIn2, HIGH);
  digitalWrite(motorIn3, LOW);
  digitalWrite(motorIn4, HIGH);

}

void right()
{
  digitalWrite(motorIn1, LOW);
  digitalWrite(motorIn2, LOW);
  digitalWrite(motorIn3, HIGH);
  digitalWrite(motorIn4, LOW);

}

void left()
{
  digitalWrite(motorIn1, HIGH);
  digitalWrite(motorIn2, LOW);
  digitalWrite(motorIn3, LOW);
  digitalWrite(motorIn4, LOW);
}





2018年3月1日 星期四

Arduino (24) 超聲波模組HC-SR01+二輪智能車系統。


和前一篇的差別就是將紅外線拆除,裝上了超聲波模組HC-SR01,

這看起來挺像瓦力的,兩個眼睛。

模式就是前進後,前方距離只有20CM時停止0.25秒,然後轉向,再前進。





程式如下 :

const int trigPin=11;
const int echoPin=12;
unsigned long data;
const byte IN1 = 10;   
const byte IN2 = 9;
const byte IN3 = 8;  
const byte IN4 = 7;

unsigned long ping(){
  digitalWrite(trigPin,HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin,LOW);
  return pulseIn(echoPin,HIGH);
//超聲波函式。

}
byte dir = 0;
void setup() {
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
  Serial.begin(9600);

}
void forward()
{
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW); 
}
void backward()
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);  
}
void turnLeft()
{
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW); 
}
void turnRight()
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
}
void stop()
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
}
void loop() {
   data=ping()/58;
  int A=abs(data);
 //A就是距離,單位公分。

  if (A>20) { 
  if (dir != 0) {  // 如果目前的行進狀態不是「前進」
     dir = 0;        // 設定成「前進」
     stop();         // 暫停馬達0.25秒
     delay(250);
      }
    forward();    // 前進
     } else {
   if (dir != 1) { // 如果目前的狀態不是「右轉」
      dir = 1;       // 設定成「右轉」
      stop();        // 暫停馬達0.25秒
      delay(250); 
      }
     turnRight(); // 向右轉
      }
   //上面這一坨是抄書本的,比較穩定。

   delay(500); 
}



2018年2月28日 星期三

Arduino (23) 紅外線收發器+二輪智能車系統。



Arduino 玩到最後都要碰一下智能車才行。

兩輪智能車的結構大概就是兩顆減速直流馬達和一個L298N直流馬達驅動模組。

減速直流馬達是什麼??就是內建齒輪比讓輸出轉速降低,

就像是以前玩的軌道車,都會搭配1比3和1比4的齒輪比來降低輸出轉速。

而這台車送來發現兩顆輪子顏色不太一樣= =。


第一篇智能車專案就來搭配紅外線收發來控制前進、後退和方向。



程式如下 :

#include <IRremote.h>
#include <LedControl.h>
const int irReceiverPin = 2;
IRrecv irrecv(irReceiverPin);
decode_results results;

const byte IN1 = 3; 
const byte IN2 = 4;
const byte IN3 = 5;
const byte IN4 = 6;
//L298N的接腳宣告,控制兩顆馬達正反轉的輸出。 

void setup() {
  Serial.begin(115200);
  irrecv.enableIRIn();
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
}
void forward()
{
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
}
//前進的函式。

void backward()
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
}
//後退的函式。

void turnLeft()
{
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
}
//左轉的函式。

void turnRight()
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
}
//右轉的函式。

void stop()
{
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
}
//停止的函式。

void loop() {
  if (irrecv.decode(&results)){
            Serial.print("Protocol: "); 

            switch(results.decode_type) {
        case NEC:
          Serial.print("NEC");
          break;
        case SONY:
          Serial.print("SONY");
          break;
        case RC5:
          Serial.print("RC5");
          break;
        case RC6:
          Serial.print("RC6");
          break;
        default:
          Serial.print("Unknown encoding");
    }
  Serial.print("  irCode: ");         
  Serial.print(results.value);
//紅外線我直接沿用我前面之前寫的,我懶的在重新對編碼。

   if (results.value == 16753245) {
    forward();
    delay(100); }
   if (results.value == 16736925) {
    backward(); 
    delay(100); }
   if (results.value == 16738455) {
     turnLeft(); 
    delay(100); }
   if (results.value == 16724175) {
     turnRight(); 
    delay(100); }
   if (results.value == 16730805) {
      stop();
      }
    delay(1000);
    irrecv.resume();     
   }
}

遙控車不過就這樣而已嘛....













2018年2月21日 星期三

Arduino (22) 主、從端HC-05藍芽互相連通+PS類比搖桿+雙軸伺服馬達SG-90。


沒想到弄好一組對收藍芽後就可以變出很多種配置,

這次就來玩,主-PS搖桿,從-兩顆伺服馬達。

模組就之前介紹過了,這邊不多贅述。



至於跟(21)篇的主要差異在於這篇是傳遞類比訊號,而(21)篇是傳遞數位訊號。





上圖是Master配置。


上圖是Slave 配置。





成果感覺還行。

底座沒有固定,所以倒了,不管。


程式如下 :

Master--

#include <SoftwareSerial.h>
#include<Servo.h > 
SoftwareSerial BT(8, 9);
int valX, posX;
int valY, posY;
const byte pinX = A0;
const byte pinY = A1;

void setup() {
  Serial.begin(9600);
  Serial.println("BT is ready!");
  BT.begin(38400);
}

void loop() {
  valX = analogRead(pinX);
  valY = analogRead(pinY);
  posX = map(valX, 0, 1023, 0, 179);
  posY = map(valY, 0, 1023, 0, 179);

  BT.write(posX);
  BT.write(posY);
//從這裡將類比訊號傳到藍芽。

  delay(100);
}



Slave--
#include <SoftwareSerial.h>
#include<Servo.h > 
SoftwareSerial BT(8, 9);
Servo servo1;
Servo servo2;
int val1,val2;
void setup() {
  servo1.attach(3);
  servo2.attach(4);
  Serial.begin(9600);
  Serial.println("BT is ready!");
  BT.begin(38400);
}
void loop() {
  if (BT.available()>0) {
    val1 = BT.read(); 
    servo1.write(val1);
    delay(15);
  }
//接收類比訊號一,啟動一號馬達。

  if (BT.available()>0) {
    val2 = BT.read(); 
    servo2.write(val2);
    delay(15);
//接收類比訊號二,啟動二號馬達。
}
delay(15);
}


其實馬達還是有點抖動,delay這邊還可以再多試一下。





8051 (6) 紅外線避障模組控制LED七段顯示器。

這篇要做的Project就是感測器測到訊號時,LED七段顯示器會開始計算偵測次數, 到第5次時會讓紅色LED燈發光。 程式如下: #include <reg52.h> unsigned char seg[5]={0xf9,...