之前以PWM製作會呼吸的LED、以揚聲器演奏青花瓷,這一篇要用16個LED,製作出左右來回跑的效果,也就是霹靂車燈。
夥計,我需要你!
我將先用Arduino的16個腳位,控制16個LED,然後再加入兩顆74HC595,就只需3個腳位即可。
電路圖(Fritzing格式)與程式原始碼,可在此下載。
電路圖:
16個220 ohm電阻,一端接地,另一端接到LED的短腳。
從Arduino板子的腳位A3、A2、A1、A0、2、3、4、5、6、7、8、9、10、11、12、13,分別接到LED的長腳。
程式碼:
#define NUM 16 // 首先定義LED的數目
// 然後是LED對應的腳位,請配合接線順序填寫。
int leds[NUM] = {
A3, A2, A1, A0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
};
// 將每個腳位模式設為OUTPUT
void setup() {
for(int i = 0; i < NUM; i++){
pinMode(leds[i], OUTPUT);
}
}
// 雖然A3、A2、A1、A0是類比腳位,
// 但也可以把它當做數位腳位使用。
// 然後是兩個迴圈,
// 第一個迴圈從這邊跑到那邊,
// 第二個迴圈跑回來。
void loop() {
for(int i = 0; i < NUM; i++){
digitalWrite(leds[i], HIGH);
delay(100);
digitalWrite(leds[i], LOW);
}
for(int i = NUM-1; i >= 0; i--){
digitalWrite(leds[i], HIGH);
delay(100);
digitalWrite(leds[i], LOW);
}
}
// 以degitalWrite點亮LED後,延遲100 milliseconds(0.1秒),
// 然後再滅掉,你可以修改延遲時間。
// 你可以把第二個迴圈改為 for(int i = NUM-2; i > 0; i--),
// 看看有何不同。
跑起來的效果,可以看看我上傳到YouTube的影片。(第二個迴圈為 for(int i = NUM-2; i > 0; i--)的情形。)
你可能覺得奇怪,左邊8個LED比較亮,右邊8個LED比較暗,其實也沒什麼道理,因為我買了兩組不同的LED,哈哈。
運用74HC595:
上面用了Arduino板的16個腳位,控制16個LED,感覺很浪費。接下來,我們將使用兩顆74HC595與函式shiftOut(),以3個腳位控制16個LED。
所謂74HC595,資料上寫著8-bit、serial-in、serial or parallel-out shift register、with output latches、3-state。
8-bit:它可以儲存8個bits的資料。
serial-in:以序列的方式,把資料傳給它,也就是一次傳一個bit給它。
serial or parallel-out:若是parallel-out並列輸出,就可控制8個LED。至於serial-out序列輸出,可用來接到下一顆74HC595,那麼,當你再傳入8個bits的資料時,先前的資料就會被送到下一顆74HC595,兩顆串起來後可控制16個LED。
shift register:移位暫存器,一次傳一個bit給它,前一個bit會被移位到下一個位置。
output latch:可以鎖住輸出腳位的狀態。
3-state:輸出可以有三種狀態HIGH、LOW、高阻抗(high impedance),本例不使用高阻抗狀態。
簡單講就是,我們將以三個腳位,將LED亮暗的資料存到74HC595,一顆74HC595有8個輸出、控制8個LED,兩顆就能控制16個LED。
595的腳位說明:
Pin 1~7(Q1~Q7)、Pin 15(Q0),8 bits的輸出。
Pin 8(GND)接地。
Pin 9(Q7" ),序列輸出。
Pin 10(MR),Master Reclear清除所有資料,active low低電位有效。
Pin 11(SH_CP),SHift register Clock Pin位移時脈腳位。又稱clock pin。
Pin 12(ST_CP),STorage register Clock Pin儲存時脈腳位,又稱latch pin鎖住腳位。
Pin 13(OE),Output enable允許輸出,active low低電位有效。
Pin 14(DS),Data Serial input序列資料輸入,又稱data pin資料腳位。
Pin 16(Vcc),供應正電壓。
電路圖:
先前從Arduino板子接到LED的16條線,全部拔掉。
從Arduino板的5V與GND腳位,接到麵包板上。
Pin 1~7(Q1~Q7)、Pin 15(Q0),依序接到8個LED,我把Q0接到最旁邊的LED。
Pin 8(GND),接地。
Pin 9(Q7" ),目前暫時未使用,之後會接到下一個74HC595。
Pin 10(MR) ,此例不使用此功能,所以接到5V。
Pin 11(SH_CP),接Arduino板子的腳位4。
Pin 12(ST_CP),接Arduino板子的腳位3。
Pin 13(OE),此例不使用此功能,所以接地。
Pin 14(DS),接Arduino板子的腳位2。
Pin 16(Vcc) ,接5V。
還有8個LED,目前暫時未使用。
P.S. 若有LED閃爍的現象,可在Pin 12(ST_CP)上接0.1 uF的電容,除去閃爍現象。
程式碼:
首先先寫個小程式,從右到左,輪流點亮每一個LED,一次只點亮一個LED,然後不斷循環。
// 首先定義腳位
#define DataPin 2 // 接到74HC595的DS
#define LatchPin 3 // 接到74HC595的ST_CP
#define ClockPin 4 // 接到74HC595的SH_CP
// 將三個腳位模式設定為OUTPUT
void setup() {
pinMode(DataPin, OUTPUT);
pinMode(LatchPin, OUTPUT);
pinMode(ClockPin, OUTPUT);
}
void loop() {
uint8_t number; // 這個變數裡的每一個bit,代表每一個LED亮不亮。
// 輪流點亮每一個LED,共有8個LED。
for (int i = 0; i < 8; i++) {
// 送出資料前,將LatchPin設為LOW,鎖定輸出的資料。
digitalWrite(LatchPin, LOW);
number = 0; // 所有bit清為0,代表全部LED都不亮。
bitSet(number, i); // 將某bit設為1,代表點亮該LED。
// 利用shiftOut()送出資料
shiftOut(DataPin, ClockPin, MSBFIRST, number);
// 送出資料結束,將LatchPin設為HIGH,更新輸出腳位。
digitalWrite(LatchPin, HIGH);
delay(500);
}
}
shiftOut()用起來很簡單,給它74HC595的DataPin與ClockPin,以及資料number,它就會把資料輸出給74HC595。至於MSBFIRST的意思是most significant bit first,也就是說,最先輸出的會是number(是個uint8_t,有8個bits,第7個bit是MSB,第0個bit是LSB)的第7個bit。如果改用LSBFIRST(least significant bit first),那麼最先輸出的會是第0個bit。
shiftOut()是Arduino內建的函式,有興趣的話可以到安裝目錄下的hardware\arduino\cores\arduino\wiring_shift.c看看原始碼。
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
uint8_t i;
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
digitalWrite(dataPin, !!(val & (1 << i)));
else
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}
可以得知,val接受大小為8 bits,所以shiftOut只能輸出8 bits的資料,根據參數bitOrder為LSBFIRST或MSBFIRST,依序輸出每一個bit,寫入dataPin;然後將clockPin拉上(從下到上),告知74HC595把資料吃進去,最後把clockPin拉下,準備給下一次的資料使用。
你可能會覺得奇怪,為什麼要用兩個驚嘆號(!!),這是一種慣用法。因為digitalWrite()的第二個參數應該是個布林值,如果直接丟個整數進去,會需要進行一些轉換,用了兩次驚嘆號後,就可確保得到一個型別為布林的值。(不過,在此例裡,digitalWrite()的第二個參數其實是個uint8_t。)
好,讓我們修改一下,改成霹靂車燈。
#define DataPin 2
#define LatchPin 3
#define ClockPin 4
void setup() {
pinMode(DataPin, OUTPUT);
pinMode(LatchPin, OUTPUT);
pinMode(ClockPin, OUTPUT);
}
void loop() {
uint8_t number;
for (int i = 0; i < 8; i++) {
digitalWrite(LatchPin, LOW);
number = 0;
bitSet(number, i);
shiftOut(DataPin, ClockPin, MSBFIRST, number);
digitalWrite(LatchPin, HIGH);
delay(300);
}
for (int i = 0; i < 8; i++) {
digitalWrite(LatchPin, LOW);
number = 0;
bitSet(number, i);
shiftOut(DataPin, ClockPin, LSBFIRST, number);
digitalWrite(LatchPin, HIGH);
delay(300);
}
}
東西都跟以前一樣,第一個迴圈從頭跑到尾後,利用新加入的第二個迴圈,讓LED從尾跑回頭。第二個迴圈有很多寫法,這裡我把MSBFIRST改成LSBFIRST就行了。
第二個迴圈也可以用底下這種寫法:
for (int i = 7; i >=0; i--) {
digitalWrite(LatchPin, LOW);
number = 0;
bitSet(number, i);
shiftOut(DataPin, ClockPin, MSBFIRST, number);
digitalWrite(LatchPin, HIGH);
delay(300);
}
好,接下來,就是加入第二顆74HC595,總共控制16個LED。
電路圖:延續之前的接線,然後,
第一顆74HC595:
Pin 9(Q7" ),接到第二顆74HC595的Pin 14(DS)。
Pin 11(ST_CP),接到第二顆74HC595的Pin 11(ST_CP)。
Pin 12(SH_CP),接到第二顆74HC595的Pin 12(SH_CP)。
第二顆74HC595:
Pin 1~7(Q1~Q7)、Pin 15(Q0),依序接到剩下來的8個LED,請注意順序,我的第二顆74HC595的Q0,接到上一顆74HC595的Q7的旁邊,我的第二顆74HC595的Q7,接到最旁邊的LED。
Pin 8(GND),接地。
Pin 9(Q7" ),不使用。
Pin 10(MR) ,此例不使用此功能,所以接到5V。
Pin 11(ST_CP),接到第一顆74HC595的Pin 11(ST_CP)。
Pin 12(SH_CP),接到第一顆74HC595的Pin 12(SH_CP)。
Pin 13(OE),此例不使用此功能,所以接地。
Pin 14(DS),接到第一顆74HC595的Pin 9(Q7")。
Pin 16(Vcc) ,接5V。
程式碼:
#define DataPin 2 // 接到74HC595的DS
#define LatchPin 3 // 接到74HC595的ST_CP
#define ClockPin 4 // 接到74HC595的SH_CP
void setup() {
pinMode(DataPin, OUTPUT);
pinMode(LatchPin, OUTPUT);
pinMode(ClockPin, OUTPUT);
}
void loop() {
uint16_t number;
uint8_t highbyte;
uint8_t lowbyte;
for (int i = 0; i < 16; i++) {
digitalWrite(LatchPin, LOW);
// 因為shiftOut()一次只能輸出8 bits的資料,
// 所以這裡分成highbyte與lowbyte,
// highbyte的第7個bit,代表最左邊的LED,
// lowbyte的第0個bit,代表最右邊的LED。
number = 0; // 先將全部bit清為0
bitSet(number, i); // 將某bit設為1
// 然後利用 >> 與 & 運算子,將資料取出來。
highbyte = (number >> 8) & 0xFF;
lowbyte = number & 0xFF;
shiftOut(DataPin, ClockPin, MSBFIRST, highbyte);
shiftOut(DataPin, ClockPin, MSBFIRST, lowbyte);
digitalWrite(LatchPin, HIGH);
delay(100);
}
for (int i = 0; i < 16; i++) {
digitalWrite(LatchPin, LOW);
number = 0;
bitSet(number, i);
highbyte = (number >> 8) & 0xFF;
lowbyte = number & 0xFF;
// 注意,這裡以LSBFIRST的順序寫出資料,
// 所以要先送出lowbyte,然後是highbyte。
// 你可以先highbyte再lowbyte,看看有何不同。
shiftOut(DataPin, ClockPin, LSBFIRST, lowbyte);
shiftOut(DataPin, ClockPin, LSBFIRST, highbyte);
digitalWrite(LatchPin, HIGH);
delay(100);
}
}
當然,第二個迴圈也可以有別種寫法,不過我就不列出來了。
跑起來的效果。跟之前以16個腳位控制的版本不太一樣,當跑到最左邊、最右邊時,感覺會停頓一下,因為那兩個LED亮的時間是其他的兩倍。想要改成不停頓效果的程式碼,我就不列出來了,改法就是去修改迴圈裡的i值。
參考資料:
- Arduino官方範例Examples > Display > LED Bar Graph,shiftOut()函式的說明文件。
- 74HC595,Arduino官方網站的Serial to Parallel Shifting-Out with a 74HC595,Arduino.TW樂園的手把手理解74HC595工作原理 & shiftOut指令。
- Cooper Maa的Lab5 LED Bar Graph、Lab11 使用 74HC595 和三支腳位控制 8 顆 LED、Lab12 使用兩顆 74HC595 和三支腳位控制 16 顆 LED。
您好
ReplyDelete我想請問
74HC595是讀完8個bits後才後一同輸出嗎?
是透過latchPin鎖住data嗎?
謝謝
另外我罩着範例程式(8*LED燈表示1~255數值)
Delete我用Serial print抓dataPin和clockPin
發現值是11 12 11 12...持續不斷
想請問這是爲何?
謝謝
74HC595是讀完8個bits後才後一同輸出嗎?
Delete是透過latchPin鎖住data嗎?
先呼叫digitalWrite(LatchPin, LOW),然後就可以
呼叫shiftOut把資料輸出到595,
最後呼叫digitalWrite(LatchPin, HIGH)鎖住。
用Serial print抓dataPin和clockPin
Delete什麼意思?不懂你想做什麼。
請問有將類型作品利用Persistence of Vision 產生圖案之範例嗎!? 感謝
ReplyDelete沒有。
DeletePOV可參考:
http://www.instructables.com/id/Arduino-LEDs-fan-POV-APPLAUSE-sign/
http://www.raspberrypi.org/mike-cooks-magic-wand/
http://www.ladyada.net/make/spokepov/
This comment has been removed by the author.
ReplyDelete葉老師您好,
ReplyDelete我是Arduino的初學者,這是我從書上學的霹靂燈程式,
想請教比較進階的問題是,如何使用兩個按鈕開關去控制這個霹靂燈的左右方向。
按下第一個按鈕開關時,霹靂燈向左跑
按下第二個按鈕開關時,霹靂燈向右跑
兩個按鈕沒有按時,就沒有動作。
小弟爬了些許文章,知道不可使用FOR迴圈,還有索引值得處理,卻不知從何下手。
想請葉老師幫忙指點,萬分感謝。
const byte NUM = 8;
const byte led[] = {11, 10, 9, 8, 7, 6, 5, 4};
int delaytime = 100;
int ii;
void setup() {
for (ii=0; ii0; ii--)
{ digitalWrite(led[ii], LOW);
delay(delaytime);
digitalWrite(led[ii], HIGH);
}
}
This comment has been removed by the author.
ReplyDelete葉老師您好,
ReplyDelete我是Arduino的初學者,這是我從書上學的霹靂燈程式,
想請教比較進階的問題是,如何使用兩個按鈕開關去控制這個霹靂燈的左右方向。
按下第一個按鈕開關時,霹靂燈向左跑
按下第二個按鈕開關時,霹靂燈向右跑
兩個按鈕沒有按時,就沒有動作。
小弟爬了些許文章,知道不可使用FOR迴圈,還有索引值得處理,卻不知從何下手。
想請葉老師幫忙指點,萬分感謝。
const byte NUM = 8;
const byte led[] = {11, 10, 9, 8, 7, 6, 5, 4};
int delaytime = 100;
int ii;
void setup() {
for (ii=0; ii0; ii--)
{ digitalWrite(led[ii], LOW);
delay(delaytime);
digitalWrite(led[ii], HIGH);
}
}
程式下半部有被砍掉 補上
ReplyDeletevoid loop() {
for (ii=0; ii0; ii--)
{ digitalWrite(led[ii], LOW);
delay(delaytime);
digitalWrite(led[ii], HIGH);
}
}
使用全域變數,儲存使用者按下了哪個按鈕。
Delete然後在loop()裡,以switch判斷該全域變數,執行相對應的函式。
例如
void run_left() { 向左跑的程式碼 }
void run_right { 向右跑的程式碼 }
int state;
void loop(){
讀取按鈕狀態,修改全域變數state。
switch(state){ 根據state,執行相對應的函式
case 0:
run_left();
break;
case 1:
run_right();
break;
}
}
感謝葉老師指點,我先來試試看。有問題再請教您
ReplyDelete您好,我想請問一下如果我使用三個74HC595,分別接上三顆RGB LED燈,第一顆74HC595都是接上三顆LED的RED腳,第二顆74HC595接上三顆LED的GREEN腳,第三顆接上三顆LED的BLUE腳,然後我想要這三顆LED分別為不同顏色(橘色,紫色,黃色),但是每一個74HC595他能給的類比值是固定的,所以變成最後顯示會是三顆LED都是同樣顏色,可能都是橘色或都是紫色,沒辦法做到三顆都是不同顏色,我想請問有辦法讓74HC595的Q0-Q7分別給不同的類比數值嗎?
ReplyDelete謝謝您
74HC595通常是用來擴充數位腳位的數量。
Delete你應該能做出LED 1為黃色(紅+綠),LED 2為洋紅色(紅+藍),LED 2為青綠色(藍+綠);也就是輸出高電位點亮LED 1的紅與綠,產生出黃色效果。
而作法就是從Arduino控制74HC595,讓它的腳位輸出你想要的值(高或低)。
至於類比值,一般來說會使用Arduino的類比腳位,輸出PWM訊號;若以三個類比腳位控制一個RGB LED的話,便可做出各種深淺色彩的效果。
至於你的問題,有辦法讓74HC595的Q0-Q7分別給不同的類比數值嗎?
雖然理論上可行,也就是很快速地控制74HC595,不斷切換,以數位訊號(高或低)模擬出類比數值,不過我沒做過。我只做過以Arduino的數位腳位模擬出類比數值,但那只是玩玩、做做實驗而已。
This comment has been removed by the author.
Delete有辦法讓74HC595的Q0-Q7分別給不同的類比數值嗎? 這個問題也是我想問的,怎麼讓shiftOut輸出不同的類比數值?
Delete另外一個74HC595可控制8個LED燈,如果有11個,共可接88個LED燈,對應鋼琴88個鍵,但是上面的程式是兩個74HC595當成一組控制16個LED燈,一共用到3個arduino port,如果11個74HC595,共要6組,共18個port,請問該如何解決arduino port不夠用的問題呢?
還是說把上面程式的number宣告為long(32 bits),把四個74HC595當成一組控制32個LED燈,共需要3組(4個一組、4個一組、3個一組,共控制88個LED燈),這樣就只需要3X3=9個port呢?
> 74HC595的Q0-Q7分別給不同的類比數值嗎?
Delete簡言之,不行。
你想要的,應該是4051吧 http://playground.arduino.cc/Learning/4051
74HC595可以串連,這篇文章用了兩個74HC595,但仍只使用3個Arduino腳位。
所以你若用11個75HC595,仍是3個腳位。
如果可以串連11個75HC595,請問上述的程式該怎麼改呢?
Deletefor (int i = 0; i < 88; i++) {
digitalWrite(LatchPin, LOW);
// 因為shiftOut()一次只能輸出8 bits的資料,
// 所以這裡分成highbyte與lowbyte,
// highbyte的第7個bit,代表最左邊的LED,
// lowbyte的第0個bit,代表最右邊的LED。
number = 0; // 先將全部bit清為0
bitSet(number, i); // 將某bit設為1 這個地方如果i=87的時候,number是2的87次方嗎? 如果是,
不就超過 int或long 的範圍嗎? 如果不是,number是多少呢?
// 然後利用 >> 與 & 運算子,將資料取出來。
byte_1 = (number >> 80) & 0xFF;
byte_2 = (number >> 72) & 0xFF;
byte_3 = (number >> 64) & 0xFF;
byte_4 = (number >> 56) & 0xFF;
byte_5 = (number >> 48) & 0xFF;
byte_6 = (number >> 40) & 0xFF;
byte_7 = (number >> 32) & 0xFF;
byte_8 = (number >> 24) & 0xFF;
byte_9 = (number >> 16) & 0xFF;
byte_10 = (number >> 8) & 0xFF;
byte_11 = number & 0xFF;
shiftOut(DataPin, ClockPin, MSBFIRST, byte_1 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_2 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_3 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_4 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_5 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_6 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_7 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_8 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_9 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_10 );
shiftOut(DataPin, ClockPin, MSBFIRST, byte_11 );
digitalWrite(LatchPin, HIGH);
delay(100);
}
請問是這樣寫嗎?
> 不就超過 int或long 的範圍嗎?
Delete對,超過了。long是4個位元組(32位元),但你需要88個位元。
可以改用3個unsigned long,共96個位元,但只用88個。
但程式也需要做相對應的修改,呵呵。
請問如果改用Analog Multiplexer/Demultiplexer - 4051,也是用11個4051去控制88個LED燈去對應鋼琴88個鍵嗎? 需要用到幾個及哪些arduino pin呢? 又請問電路圖和程式碼該如何寫呢?
Delete尊駕所言乃是需求,並非問題,無從回答。
Delete4051應該只有數位輸出/輸入。
Delete若要PWM的話,可試試TLC5940。
Arduino有很多PWM擴充板,
Delete譬如請參考拙作《Arduino輕鬆入門》第314頁介紹的Adafruit PWM/Servo擴充板,可輸出16個PWM訊號,解析度是12位元。
請教一下葉老師,若我用74164也可以嗎? 若不行CODE 要如何改?
ReplyDelete雖可,但74164沒有latch功能,
ReplyDelete所以當把一個個位元資料推進去74164時,會發生腳位輸出你不想要的值的現象。
老師您好,如果我用Uno板做
ReplyDelete是不是最高上限只能到64bit=64顆LED燈呢?
64 bit打哪來的?
Delete腳位不夠,可以擴充啊。
74HC595可以串接,你用3個腳位,就可以控制很多個595,也就可以控制很多個LED。
我已經串到8個595了
Delete不過在
uint16_t number;
uint8_t highbyte;
uint8_t lowbyte;
這個部分的uint16_t改成64
但是好像無法超過64以上的數字
還是說我定義錯誤?
以下是我定義部分的code
uint64_t number = 0x0000000000000001; //變數裡每個bit,代表亮不亮
uint8_t highbyte1;
uint8_t highbyte2;
uint8_t highbyte3;
uint8_t highbyte4;
uint8_t highbyte5;
uint8_t highbyte6;
uint8_t highbyte7;
uint8_t lowbyte;
//定義8顆暫存器
哇,8個,真厲害。
Delete有uint64_t,但應該沒有更大的了。
關於你想要的功能,嗯,暫時想到的簡單作法是:
使用多個uint32_t或uint64_t,然後要改寫其他部分的程式碼。
不過似乎很麻煩,你可以參考
http://playground.arduino.cc/Main/ShiftOutX
這套程式庫的寫法,裡頭有支函式shiftOut_X,使用的是uint64_t,
想辦法改寫,讓它能適用更多個595。
好的,感謝老師
Delete麻煩您了
已於另一篇回應。
ReplyDelete想請問,可以在這上述的霹靂登再加上開關嗎?
ReplyDelete譬如說,加上一個開關,開關沒按時 led 是左右一直跑,按下開關時,led就全部熄滅 再按一下又全部亮一直左右跑
可以這樣做嗎 程式又是如何寫呢?? 謝謝你
嗯,把這篇文章的loop()裡的東西,搬出來放進另一支新函式裡,例如取名為marquee。
Delete然後,增加全域變數,由開關控制其狀態,根據這個變數,決定要不要執行marquee。
int status = 0;
#define SWITCH_PIN 9 // 開關的腳位
void setup(){
// 其他東西
pinMode(SWITCH_PIN, INPUT);
}
void loop(){
int x = digitalRead(SWITCH_PIN); // 應該要debounce
if(x){
status = !status;
}
if(status){
marquee();
}
else{
// LED全部熄滅
}
}
大概是這樣吧,沒測試過;自己改改。
葉老師你好,那請問硬體線路我是直接參考你的文章的"以開關切換led明滅狀態"的這篇文章的作法,但線路是要接在595的接腳還是哪裡呢? void setup(){// 其他東西__這個其他東西 是要打上什麼呢? 葉老師不好意思 你的書已經有去買了但還沒到貨,所以有問題只能先在這裡請教你了
Delete> 但線路是要接在595的接腳還是哪裡呢?
Delete那篇文章不是就接到Arduino的某個數位腳位嗎。為何提到595。
> // 其他東西
就是你原本需要執行的東西。
多謝購買:D。
This comment has been removed by the author.
ReplyDelete葉老師你好 最後在請問一下"搬出來放進另一支新函式裡" 是在旁邊新增一個標籤然後取名為marquee嗎?
ReplyDelete新增函式,放進跑馬燈的程式。
ReplyDeletevoid marquee(){
// 跑馬燈的程式
}
老師你好,想請問一下
ReplyDeletehighbyte = (number >> 8) & 0xFF;
lowbyte = number & 0xFF;
你說這一段程式是將資料取出來
我還是搞不懂是如何運算的
number是個16個位元的整數,可當做由兩個byte(位元組)組成,現在我們想取出它的低位元組(第0個位元 到 第7個位元),以及高位元組(第8個位元 到 第15個位元),
Delete取出低位元組的方法是 number & 0xFF,
0xFF轉成二進位會是11111111,number與它做bitwise and運算的話,
高位元組的部份會變成0,保留低位元組的部份,
然後把結果放進lowbyte = number & 0xFF,
取出高位元組的方法是,
number >> 8,每個位元都向右位移8次,於是,原本低位元組的部份會被丟棄,
原本高位元組的部份,會跑到低位元組的位置,
然後再 & 0xFF,取得結果,放進highbyte。
老師你好 請問我接了4顆74H595接了28顆LED,想要每次輸出只亮我指定的某一顆燈就好這樣程式怎麼撰寫,網路上範例都是跑馬燈
ReplyDelete如果要隨機亮燈要怎麼寫
ReplyDelete