2016年8月28日 星期日

Arduino專案_LED矩陣顯示器3

前面練習過了用LED矩陣顯示靜態和動態圖像,這次要做的是捲動字元,

也是一種動態圖像的呈現。利用 fonts.h 程式檔,可以快速取得電腦中

ASCII編碼中的127個字元圖像定義。

要讓字元產生向左捲動的效果,就是讓後一行的LED資料複製給前一行,

第1行←第2行,第2行←第3行,……第7行←第8行,那第8行的資料呢?

就要去抓下一個字元的第1行資料複製到第8行來。跑完一輪後,就能發現

字元圖像向左移動了1行,如此不斷地循環,便能產生捲動效果。但第2輪

的第8行是去抓下一個字元的第2行喔!

實際的程式碼是利用陣列、迴圈和自定函數來完成字元捲動效果。這裡就

不詳細說明程式碼的內容,可上網查閱資料或看相關書籍便能更清楚瞭解。

fonts.h 沒有內建,因此要將它複製到程式庫中,編譯時才不會出現錯誤。

程式碼:

#include <SPI.h>
#include <fonts.h>

byte buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};

char msg[] = { 'L', 'Y', 'C', 'D', 'I', 'Y', '!', ' ' };  //想要顯示的字元
int msgSize = sizeof(msg);  //計算字串陣列的元素數量

const byte NOOP = 0x0;    //定義暫存器常數
const byte DECODEMODE = 0x9;
const byte INTENSITY = 0xA;
const byte SCANLIMIT = 0xB;
const byte SHUTDOWN = 0xC;
const byte DISPLAYTEST = 0xF;

void max7219(byte reg, byte data) {   //傳輸資料自定函數
  digitalWrite(SS, LOW);
  SPI.transfer(reg);
  SPI.transfer(data);
  digitalWrite(SS, HIGH);
}

void scroll(byte chr) {             //捲動字元自定函數
  for (byte j = 0; j < 8; j++) {
    for (byte i = 0; i < 7; i++) {
    buf[i] = buf[i+1];
    max7219 (i + 1, buf[i]);
   }
  buf[7] = fonts[chr][j];
  max7219 (8, buf[7]);
  delay(300);
 }
}


void setup() {
  pinMode(SS, OUTPUT);
  digitalWrite(SS, HIGH);

  SPI.begin();
  max7219 (SCANLIMIT, 7);
  max7219 (DECODEMODE, 0);
  max7219 (INTENSITY, 8);
  max7219 (DISPLAYTEST, 0);
  max7219 (SHUTDOWN, 1);

  for (byte i = 0; i < 8; i++) {
    max7219 (i + 1, 0);
  }
}

void loop() {
  byte chr;
    for (int i = 0; i < msgSize; i++) {
    chr = msg[i];
    scroll(chr);
  }
}




完成影片:


Arduino專案_LED矩陣顯示器2

先前的LED矩陣顯示器呈現了一張靜態的圖像,接下來要做的是呈現

出動態的影像,同樣利用陣列方式來記錄各LED的狀態。但此次陣列

要改用二維陣列,就是陣列中再包含陣列。

先構思一下想要呈現出的圖像,利用word畫一個8*8表格,配合底色

來展現想要的圖像,再算出16進位格式的數值資料。這次我想要呈現

出「 D I Y」三個字的圖像,利用word完成三張圖的16進位格式資料。

word空白表格:



構思圖像並計算16進位數值:















程式碼不同之處:

二維陣列:pic[3][8] { {第1個圖像8行資料}, {第2個圖像8行資料},
                                   {第3個圖像8行資料} };




迴圈:因為要呈現二維陣列資料,因此迴圈要使用雙重迴圈。














完成影片:



2016年8月27日 星期六

Arduino專案_LED矩陣顯示器

由於LED技術發展快速,應用層面也越來越廣。將多顆 LED封裝起來,

便可組成LED矩陣,常見的廣告看板、各式各樣的顯示面板,都採用

LED矩陣型式來完成的。

手邊有二個大小不同的LED矩陣,一個是8*8,一個是5*8。最大的差

異是,8*8的LED矩陣已焊接一顆MAX7219 LED驅動 IC ,只需要三條

數位腳接線即可控制LED矩陣,在使用上方便很多。不然,在麵包板上

要自行連接一堆線材、電容和電阻。















MAX7219 採用一種 Serial Peripheral Interface (序列周邊介面),簡稱

SPI介面。SPI採用四條線連接主機和周邊設備(SS, MOSI, MISO, SCK)。

Arduino的ATmega系列處理器內建了SPI介面,數位10~13腳位即是

SPI介面使用。

MAX7219 LED矩陣模組有5個針腳與Arduino連接,分別是VCC(電源)、

 GNC(接地)、DIN(資料輸入)、CS(晶片選擇)、CLK(時脈)。將DIN接

D11,CS接D10,CLK接D13。

MAX7219有多個暫存器的設定,這裡就不詳述了。它每次接收16位元

資訊,分2區塊包含[ 沒有使用(4位元)、位址(4位元 )]和[ 資料(8位元) ]。

使用陣列來記錄LED的狀態,每1行的8個LED使用一個陣列的元素呈現,

可以用2進位或16進位來表示每1行的數值。

電路連接圖:



程式碼:

#include <SPI.h>  //引用SPI函式庫

byte symbol[8] = {0xFC, 0xA1, 0xBF, 0xA1, 0x9E, 0xA0, 0x20, 0x1E};  //16進位格式

const byte NOOP = 0x0;        //各項暫存器設定
const byte DECODEMODE = 0x9;
const byte INTENSITY = 0xA;
const byte SCANLIMIT = 0xB;
const byte SHUTDOWN = 0xC;
const byte DISPLAYTEST = 0xF;

void max7219(byte reg, byte data) {          //自定函數,寫入資料的4個步驟
  digitalWrite(SS, LOW);
  SPI.transfer(reg);
  SPI.transfer(data);
  digitalWrite(SS, HIGH);
}

void setup() {
  pinMode(SS, OUTPUT);
  digitalWrite(SS, HIGH);

  SPI.begin();
  max7219 (SCANLIMIT, 7);
  max7219 (DECODEMODE, 0);
  max7219 (INTENSITY, 8);
  max7219 (DISPLAYTEST, 0);
  max7219 (SHUTDOWN, 1);

  for (byte i = 0; i < 8; i++) {
    max7219 (i + 1, 0);
  }
}

void loop() {
  for (byte i = 0; i < 8; i++) {
    max7219 (i + 1, symbol[i]);
  }
}


完成圖1:




完成圖2:













Arduino專案_LED 7段顯示器+按鈕

先前練習了LED七段顯示器,製作了一個倒數計時裝置。這次想要加上一個按鈕,

讓數字不停的快速轉換時,當按下按鈕,就使數字暫停一段時間,如同抽號碼機

器一樣。利用原本的程式碼進行修改。在顯示完一個數字後進行按鈕是否按壓的

偵測,如果第11腳位收到HIGH,即表示按鈕有按壓,利用delay暫停顯示數字。

電路連接圖:



 程式碼:

//Arduino七段顯示器範例程式
//此為共陰極設定,若是共陽極,0與1互換即可
//1 = 開啟,0 = 關閉LED
//Arduino 腳位; 2,3,4,5,6,7,8
//設定11腳位為輸入,讀取按鈕數值

//二維陣列,儲存每個數字的LED電壓狀態
byte seven_seg_digits[10][7] = {
   {1,1,1,1,0,1,1},  // = 0
   {0,0,1,1,0,0,0},  // = 1
   {1,1,0,1,1,0,1},  // = 2
   {0,1,1,1,1,0,1},  // = 3
   {0,0,1,1,1,1,0},  // = 4
   {0,1,1,0,1,1,1},  // = 5
   {1,1,1,0,1,1,1},  // = 6
   {0,0,1,1,0,1,1},  // = 7
   {1,1,1,1,1,1,1},  // = 8
   {0,1,1,1,1,1,1}   // = 9
};

int buttonPin = 11;
int buttonState = 0;

void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(buttonPin, INPUT);
  writeDot(0); //程式開始時,小數點熄滅
}

//自訂函式,控制小數點亮滅狀態
void writeDot(byte dot) {
  digitalWrite(9, dot);
}

//自訂函式,控制3個變數值,讓數字倒數
void sevenSegWrite(byte digit) {
  byte pin = 2;
    for (byte segCount = 0; segCount < 7; ++segCount) {
        digitalWrite(pin, seven_seg_digits[digit][segCount]);
          ++pin;
    }
}

void loop() {
  for (byte count = 10; count > 0; --count) {
    delay(50);
        sevenSegWrite(count - 1);
        buttonState = digitalRead(buttonPin);       //設定按鈕變數值,偵測按鈕是否被按壓
        if (buttonState == HIGH) {
              Serial.println(buttonState);
              delay(5000);
    }
  }
}


完成影片:













2016年8月20日 星期六

Arduino專案_LED 7段顯示器

當我們需要顯示數字時,LED 7段顯示器就是一個相當實用的元件。

它是由7段LED所組成,外加一個小數點,可以顯示出0~9的數字。

它具有10根針腳,購買時要注意一下是共陰極還是共陽極,接線時

會有所不同。共陰極的共同針腳要接地,控制LED的針腳輸出高電

位時,LED便會亮起。反之,共陽極接電源,控制LED的針腳輸出

低電位才會亮。

這次要做的是倒數計時器,從9倒數至0。


 腳位編號:
 

 電路接線圖:


程式碼:
//Arduino七段顯示器範例程式
//此為共陰極設定,若是共陽極,0與1互換即可
//1 = 開啟,0 = 關閉LED
//Arduino 腳位; 2,3,4,5,6,7,8

//二維陣列,儲存每個數字的LED電壓狀態
byte seven_seg_digits[10][7] = {
   {1,1,1,1,0,1,1},  // = 0
   {0,0,1,1,0,0,0},  // = 1
   {1,1,0,1,1,0,1},  // = 2
   {0,1,1,1,1,0,1},  // = 3
   {0,0,1,1,1,1,0},  // = 4
   {0,1,1,0,1,1,1},  // = 5
   {1,1,1,0,1,1,1},  // = 6
   {0,0,1,1,0,1,1},  // = 7
   {1,1,1,1,1,1,1},  // = 8
   {0,1,1,1,1,1,1}   // = 9
};

void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  writeDot(0); //程式開始時,小數點熄滅
}

//自訂函式,控制小數點亮滅狀態
void writeDot(byte dot) {
  digitalWrite(9, dot);
}

//自訂函式,控制3個變數值,讓數字倒數
void sevenSegWrite(byte digit) {
  byte pin = 2;
    for (byte segCount = 0; segCount < 7; ++segCount) {
        digitalWrite(pin, seven_seg_digits[digit][segCount]);
          ++pin;
    }
}

void loop() {
  for (byte count = 10; count > 0; --count) {
    delay(1000);
        sevenSegWrite(count - 1);
    }
    delay(4000);
}

完成相片:




2016年8月15日 星期一

免費的遊戲學習平台_Kahoo!

最近看到一個免費的遊戲學習平台_Kahoo,它是一套可以出題,

然後讓參予者透過手機、平板或電腦進行答題的系統,以前的flash,

或是利用moodle的出題功能、google表單也可以做到相似的功能。

這一套系統可以立即讓使用者知道答題結果,並累積分數,答完後

也可以看到整個答題正確率的統計資料,掌握每個參予者的回答情形。

重點是,我覺得這套系統設計題目的方式相當簡易,結合行動裝置或

電腦,能在很多地方進行應用。

在教學現場,老師不用花費很多時間、心力就能完成題目,也可以在

一小段教學進度後,進行一次小評量,瞭解學生們的學習狀況,做為

調整教學內容的參考依據。只是硬體方面還需要配合,要先準備相當數

量的平板電腦,無線網路的設置也是一個問題。不然,就是要到電腦教

室來進行活動。

首先要先進行註冊(免費),接著就可以開始設計題目了,而參予者可以

透過網址,連結到答題網頁,輸入完遊戲密碼後,便能進入到答題的

網頁內,進行答題活動了。

Kahoo官網:https://getkahoot.com/

答題網頁:https://kahoot.it

呂聰賢老師有製作教學影片,相當的實用。

Youtube教學影片

2016年8月14日 星期日

Arduino專案_LED循環閃燈

小時候曾流行過霹靂遊俠李麥克的影集,令人印象深刻的地方,

就是霹靂車前方不斷來回閃爍的燈,就像賦予車子生命力一般。

因此,就用LED循環閃燈來回味一下吧!

配置相當簡單,用了8個LED燈和8個電阻,接到2-9號腳位,設定

依序亮起、熄滅,就能呈現出循環閃燈的效果了。

電路連接圖:



程式碼:

//設定2-9腳位為輸出模式//
void setup() {
 for (int i = 2; i < 10; i++) {
    pinMode(i, OUTPUT);
 }
}

//設定關閉LED的副程式//
void allLEDsOff(void)
{
  for (int i = 2; i < 10; i++) {
  digitalWrite(i, LOW);
  }
}

//從2號到8號腳位,依序開啟LED200毫秒,接著關閉//
void loop() {
  for (int i = 2; i < 9; i++) {
    allLEDsOff();
    digitalWrite(i, HIGH);
    delay(200);
  }
//從9號到3號腳位,依序開啟LED200毫秒,接著關閉// 
  for (int i = 9; i > 2; i--) {
    allLEDsOff();
    digitalWrite(i, HIGH);
    delay(200);
  }
}


完成影片:

















Arduino專案_按鈕開關控制LED

這個專案是在練習按鈕開關的連接,當按下按鈕,LED燈就會亮起,

放開手後,LED燈就熄滅。就如同家裡的電燈也是用開關控制一樣,

但家裡的開關叫搖頭開關,而這裡用的是瞬時開關。

要注意的是,LED和開關都要接上電阻。

電路連接圖:



程式碼:
const int ledPin = 13;
const int btnPin = 2;

void setup() {
 pinMode(ledPin, OUTPUT);
 pinMode(btnPin, INPUT);
}

void loop() {
  int val = digitalRead(btnPin);
  delay(100);
  if (val == HIGH) {
  digitalWrite(ledPin, HIGH);
  } else {
  digitalWrite(ledPin, LOW);   
  } 
}

這裡要注意到的是,書中有提到按下按鈕會產生彈跳的情形,

因此設了delay,來消除彈跳情形。


完成圖:







2016年8月13日 星期六

App inventor 2_刮刮卡

前面做了一個圖片刮刮樂,可以刮除整張卡片而看到後面的圖片,

接著,就想到能否用這個效果來做一個類似刮刮卡的功能。和前面

不同的地方是要設好幾個刮除區域讓人可以刮,也就是要設多個畫

布元件剛好遮住金額區域。

首先,準備一張設計好獎金金額和刮除金額的圖片,並將它設為

Screen1的背景圖案,然後加入多個畫布元件,並配合水平布局,

將畫布元布排列好,利用高度及寬度像素設定,讓它能剛好遮住

金額區域,調整這些畫布的元件位置是最傷腦筋的地方,要不斷

調整、測試,才勉強成功。

至於程式部份,和圖片刮刮樂差不多,只是要多複製幾個畫布元件

程式。

設計畫面:

























元件清單:


程式碼:




完成圖:































2016年8月12日 星期五

App inventor 2_圖片刮刮樂

8月8日~10日去研習了App inventor 2,雖然之前有玩過App inventor,但有

一段時間沒摸了,因為玩Arduino之後,以後可能會需要用手機操控一些專題

,因此想再去學習一下。

經過3天的練習,已有了基本的概念,其實它非常類似Scratch的操作,有了

Scratch的經驗,更容易上手App inventor 2了。

這個專案是想要設計一個類似刮刮樂的效果,刮一刮之後就能看見圖片。

關鍵在於圖案的上面塗上一層顏色,然後將畫筆設成透明的顏色,再將原

本的顏色抹除,就能看見圖片了。

用到的元件:畫布、按鈕(重置鍵、清除鍵)。

設計說明:上傳一張圖片,設為Screen1的背景圖片,然後在Screen1初

始化的時候,設定畫筆為灰色,畫一個大圓塗滿畫布元件,也就是遮住

圖片,然後立刻設定畫筆為透明色。拖動或點按畫面時,就能消除灰色。













程式碼如下:


效果就如下:










Arduino專案_亮度調節器

最近在研究Arduino,稍微做一下記錄,以免老是忘記了。

電路接線圖可以使用 Fritzing 這套軟體來畫。

這個專案是相當簡單的範例,利用1個可變電阻來控制led燈的明亮度。

led燈應接1個470Ω限流電阻,正極腳位必需接在板子上pwm腳位才行。














程式碼如下:

/*
  此專案為led燈配合可變電阻(50K)pwm脈衝頻寬調變,來調整
  led燈的亮度。
 */
int potPin = 0; // 此變數為設定讀取可變電阻的訊號腳位
int potValue = 0; // 此變數為設定讀取可變電阻的訊號數值
int led = 9; //此變數為設定led燈輸出電壓的腳位

// 這個 setup 函式會在接通電源或按重置鍵後,率先被執行
void setup() {
  // 設定9號腳位為輸出模式
  pinMode(led, OUTPUT);
}

// 這個 loop 函式將會不斷重覆執行
void loop() {
  potValue = analogRead(potPin);   // 讀取類比訊號A0的值,並設定給變數potValue
  analogWrite(led, potValue/4);    // 輸出類比訊號至led正極接的9號腳位,值要除以4
  delay(10);              // 等待10毫秒
}

完成照片:旋轉可變電阻,便能調整led燈的亮度了