Energia - Bài 1: Điều khiển LED và nút nhấn qua các ví dụ

Điều khiển LED là bài cơ bản khi mới bắt đầu, nhưng nếu chỉ điều khiển bật tắt LED không thì cũng hơi buồn chán một chút, thôi thì thay đổi không khí riêng về LED và nút nhấn mình làm một loạt ví dụ luôn cho dễ làm quen.

Trước khi bắt đầu thì mình post lại hình ảnh pinout của TIVA cho các bạn tiện theo dõi chân cẳng

Cấu trúc chung của một chương trình Energia thường có dạng

void setup()
{
  // put your setup code here, to run once:
  // Đây là nơi bạn cấu hình chân IO, tốc độ baud, khai báo,...
}

void loop()
{
  // put your main code here, to run repeatedly:
  // Đây là phần để viết chương trình chính.
  
}

Trước khi bắt đầu các bạn nên dành thời gian khoảng 30ph để xem và làm theo các ví dụ trong video lập trình ARM TIVA với Energia để khởi động làm quen.Trong các ví dụ dưới mình tổng hợp và thay đổi lại từ các ví dụ của Energia cho phù hợp với kit TIVA kèm theo giải thích bằng comment bên cạnh dòng lệnh luôn cho các bạn tiện theo dõi

Fade LED

Ví dụ cơ bản đầu tiên để bắt đầu là làm một LED sáng dần và tắt dần.

// Chuong trinh sang dan tat dan 1 LED
// Khai bao bien
int brightness = 0;  //Bien do sang LED
int fadeAmount = 5;  //So diem LED sang dan tat dan
void setup()
{
  // put your setup code here, to run once:
  pinMode(GREEN_LED, OUTPUT);   //Cau hinh LED xanh la output
}

void loop()
{
  // put your main code here, to run repeatedly:
  //Dieu chinh do sang cua LED xanh
  analogWrite(GREEN_LED, brightness);
  //Thay doi do sang trong vong lap tiep theo
  brightness = brightness + fadeAmount;
  //Dao chieu,thay doi tu sang dan sang tat dan
  if(brightness == 0 || brightness == 255)
  {
    fadeAmount = -fadeAmount;
  }
  delay(30);
}

Fade 3 LED

Tiếp tục với việc làm sáng 3 LED lần lượt với các độ sáng khác nhau, hàm analogWrite ở đây tương ứng với PWM nếu bạn dùng nó để điều khiển động cơ.

//Chuong trinh chop tat thu tu 3 LED sang dan, tat dan
const int analogWritePin[] = {30, 39, 40}; //Su dung LED co san RED,GREEN,BLUE tren kit tuong ung voi chan 30,39,40
//Tuong ung voi chan PC4 PC5 PC6
void setup()
{
  // put your setup code here, to run once:
  //Cau hinh cac chan PC4=6 la output
  for (int thisPin = 0; thisPin <=3; thisPin++)
  {
    pinMode(analogWritePin[thisPin], OUTPUT);
  }
  
}

void loop()
{
  // put your main code here, to run repeatedly:
  //Chuong trinh chinh
  for (int thisPin = 0; thisPin <=3; thisPin++)
  {
    //Thuc hien sang dan
  for(int brightness = 0; brightness<255; brightness++)
  {
    analogWrite(analogWritePin[thisPin], brightness);
    delay(2);
  }
  //Thuc hien tat dan
  for(int brightness = 255; brightness>=0; brightness--)
  {
    analogWrite(analogWritePin[thisPin], brightness);
    delay(2);
  }
  delay(100);
  }
}

Với ví dụ này ta có thể điều khiển truy xuất, điều khiển từng LED riêng biệt. Ở đây mình tận dụng 2 LED có sẵn là xanh lá và xanh lam, bạn có thể nối LED riêng ở ngoài và khai báo 5-10 chân (ví dụ chân từ 30-40) để điều khiển tăng độ khó

/*
  Sử dụng mảng để khai báo và điều khiển nhiều LED
 
  created 2006
  by David A. Mellis
  modified 16 Apr 2013
  by Adrian Fernandez 
  
  Hardware Required:
  * TIVA LaunchPad
  * 2 LEDs
*/

int timer_ms = 100;           // Thời gian timer 100ms
int ledPins[] = {39,40};      // Mảng 2 phần tử lưu chân LED xanh lá và xanh da trời
int pinCount = 2;             // Chiều dài của mảng tương ứng với số chân lựa chọn

void setup() {
  // Sử dụng vòng lặp for để khai báo chân
  for (int thisPin = 0; thisPin < pinCount; thisPin++)  {
    pinMode(ledPins[thisPin], OUTPUT);      
  }
}

void loop() {
  // Vòng lặp cho chân nhỏ nhất tới chân lớn nhất
  for (int thisPin = 0; thisPin < pinCount; thisPin++) { 
    // Bật từng chân ON
    digitalWrite(ledPins[thisPin], HIGH);   
    delay(timer_ms);                  
    // Tắt từng chân OFF
    digitalWrite(ledPins[thisPin], LOW);    

  }

  // Đảo lại từ chân lớn về chân nhỏ
  for (int thisPin = pinCount - 1; thisPin >= 0; thisPin--) { 
    // Bật
    digitalWrite(ledPins[thisPin], HIGH);
    delay(timer_ms);
    // Tắt
    digitalWrite(ledPins[thisPin], LOW);
  }
}

Ngoài việc sử dụng hàm delay() có sẵn của Energia thì còn một cách khác là dùng millis(), có thể xem cách này tương tự như lập trình timer 🙂

/* 
 Chương trình chớp LED không sử dụng hàm delay
 
 The circuit:
 * Sử dụng kit TIVA Launchpad
 * Sử dụng LED xanh có sẵn trên kit
 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen
 modified 27 Apr 2012
 by Robert Wessels
 
 This example code is in the public domain.
 
 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 */

const int ledPin =  GREEN_LED;      //Khai báo chân LED xanh lá

int ledState = LOW;             // Biến trạng thái LED
long previousMillis = 0;        // biến thời gian cuối cùng update LED

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // Thời gian để blink LED (milliseconds)

void setup() {
  // Cấu hình chân output
  pinMode(ledPin, OUTPUT);      
}

void loop()
{
 // Hàm millis trả về giá trị thời gian hiện tại (ms) từ lúc cấp nguồn cho kit
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {

    previousMillis = currentMillis;   

    // Nếu LED off thì đảo trạng thái LED qua biến trạng thái
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // Bật tắt led
    digitalWrite(ledPin, ledState);
  }
}

Ấn nút chớp LED

Sau khi qua vài bài về LED thì chúng ta sẽ thử thao tác giữa nút nhấn và LED, ở đây mình tận dụng luôn nút nhấn có trên kit, đỡ phải nối dây thêm phức tạp. Nếu bạn muốn nối nút nhấn ở ngoài thì tham khảo thêm về cách kết nối nút nhấn dạng pull up nhé.

//Chuong trinh an nut sang LED
void setup()
{
  // put your setup code here, to run once:
  //Cau hinh uart
  Serial.begin(9600);
  pinMode(31, INPUT_PULLUP); //Cau hinh chan 31 noi voi nut nhan,tro keo len
  pinMode(40,OUTPUT);  //Cau hinh LED xanh (tren kit) la output
}

void loop()
{
  // put your main code here, to run repeatedly:
  //Chuong trinh chinh
  int buttonVal = digitalRead(31);
  //In gia tri cua nut nhan
  Serial.println(buttonVal);
  //Kiem tra neu nut chua duoc nhan thi tat LED
  if (buttonVal == HIGH)
  {
    digitalWrite(40, LOW);
  }else{
    digitalWrite(40,HIGH); //Nguoc lai thi bat LED
  }   
}

Bật tắt LED

Sau khi thử nghiệm nhấn nút điều khiển LED rồi thì mình thử sang bài điều khiển bật tắt LED từ máy tính xem sao, ấn chữ H sau đó enter thì LED sáng, ngược lại chữ L thì LED tắt.

/*
  Bật tắt LED thông qua máy tính
  Khi gõ kí tự H từ máy tính để bật LED và L để tắt LED
  Phần cứng:
  * TIVA C LaunchPad
  * Sử dụng LED xanh nối với chân 40
  created 2006
  by David A. Mellis
  modified 30 Aug 2011
  by Tom Igoe and Scott Fitzgerald
  Modified 15 April 2013
  By Sean Alvarado
  This example code is in the public domain.
*/

const int ledPin = 40;  // LED xanh
int incomingByte;       // Biến lưu dữ liệu gửi từ máy tính
void setup() {
  // Cấu hình serial với baud 9600
  Serial.begin(9600);
  // Cấu hình LED là output
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // Kiểm tra nếu có dữ liệu tới
  if (Serial.available() > 0) {
    // Đọc dữ liệu trong buffer
    incomingByte = Serial.read();
    // Nếu là H (ASCII 72),bật LED:
    if (incomingByte == 'H') {
      digitalWrite(ledPin, HIGH);
    } 
    // Nếu là L (ASCII 76) tắt LED:
    if (incomingByte == 'L') {
      digitalWrite(ledPin, LOW);
    }
  }
}

Điều khiển màu

Điều khiển được 1 LED rồi, giờ chúng ta thử với 3LED phối hợp, tạo mã màu điều khiển màu sắc của LED RGB xem sao. Bài này có thể ứng dụng được cho điều khiển LED RGB thông qua máy tính.

/*
  Điều khiển led RGB qua máy tính
  Sau khi nạp chương trình ấn mã màu tương ứng ví dụ 0,255,123 sau đó enter
  Mạch điện: 
  * Sử dụng kit TIVA Launchpad và 3 LED có sẵn trên kit
  * LED đỏ nối với chân 30
  * LED xanh lá nối với chân 39
  * LED lam nối với chân 40
  created 13 Apr 2012
  by Tom Igoe
  Modified 12 Apr 2013
  by Sean Alvarado
  
  This example code is in the public domain.
*/

// pins for the LEDs:
const int redPin = 30;
const int greenPin = 39;
const int bluePin = 40;

void setup() {
 // Cấu hình serial với baud 9600
 Serial.begin(9600);
 // Cấu hình LED output
 pinMode(redPin, OUTPUT); 
 pinMode(greenPin, OUTPUT); 
 pinMode(bluePin, OUTPUT); 

}

void loop() {
// Kiểm tra khi có tín hiệu từ serial
while (Serial.available() > 0) {

  // Lưu các giá trị nhận được vào từng biến
  int red = Serial.parseInt(); 
  // thực hiện lại
  int green = Serial.parseInt(); 
  // thực hiện lại
  int blue = Serial.parseInt(); 

  // Kiểm tra khi ấn enter thì dừng nhận dữ liệu
  if (Serial.read() == '\n') {
  // Giá trị bắt buộc nằm trong khoảng từ 0-255
  red = constrain(red, 0, 255);
  green = constrain(green, 0, 255);
  blue = constrain(blue, 0, 255);

  // Thực hiện PWM theo giá trị nhận được để thay đổi màu sắc LED
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);

  // IN các giá trị ra dưới dạng hex
  Serial.print(red, HEX);
  Serial.print(green, HEX);
  Serial.println(blue, HEX);
  }
 }
}

Đọc nút nhấn

Nút nhấn điều khiển LED đã ổn rồi, giờ làm thế nào để biết là nút đã ấn hay chưa nhỉ, thử lập trình xem trạng thái nút xem thế nào ? Nếu có ấn thì hiển thị số 1, không ấn thì số 0

/*
  Đọc trạng thái nút nhấn và in trạng thái này ra terminal
 
  Phần cứng:
  * Tiva LaunchPad
  * Sử dụng nút nhấn PB1 chân 31
  
  This example code is in the public domain.
 */

// Nút nhấn nối với chân 31 (PB1)
int pushButton = 31;


void setup() {
  // Cấu hình serial baud 9600:
  Serial.begin(9600); 
  // Cấu hình nút nhấn là INPUT pullup
  pinMode(pushButton, INPUT_PULLUP);
}

void loop() {
  // Đọc chân input:
  int buttonState = digitalRead(pushButton);
  // In trạng thái nút nhấn:
  Serial.println(buttonState);
  delay(1);        // delay
}

Đếm số lần ấn nút

Tiếp tục cải tiến ví dụ trước đếm xem nút nhấn được ấn bao nhiêu lần

/*
  Chương trình đếm số lần nhấn nút và hiển thị trạng thái hiện tại của nút nhấn là on hay off
 
 Mạch điện:
 * Sử dụng kit TIVA Launchpad
 * Sử dụng nút nhấn sẵn có trên kit kết nối với chân 31
 * LED sử dụng LED đỏ có trên kit
 
 created  27 Sep 2005
 modified 30 Aug 2011
 by Tom Igoe
 modified 27 Apr 2012
 Robert Wessels
This example code is in the public domain.
 	
 http://arduino.cc/en/Tutorial/ButtonStateChange
 
 */

const int  buttonPin = 31;        // Chân nối với nút nhấn
const int ledPin = RED_LED;       // Chân nối với LED


int buttonPushCounter = 0;        // biến đếm số lần ấn nút
int buttonState = 0;              // biến trạng thái nút nhấn
int lastButtonState = 0;          //biến trạng thái trước đó của nút nhấn

void setup() {
  // Cấu hình nút nhấn là input
  pinMode(buttonPin, INPUT_PULLUP);
  // Cấu hình LED là output
  pinMode(ledPin, OUTPUT);
  // Cấu hình in dữ liệu với tốc độ 9600
  Serial.begin(9600);
}


void loop() {
  // Đọc trạng thái nút nhấn
  buttonState = digitalRead(buttonPin);

  // So sánh trạng thái này với trạng thái trước đó
  if (buttonState != lastButtonState) {
    // Nếu khác thì tăng biến đếm lên
    if (buttonState == HIGH) {
      // Nếu trạng thái hiện tại là HIGH thì in trạng thái
      // nút nhấn là on
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } 
    else {
      // Nếu trạng thái hiện tại là LOW thì in off
      Serial.println("off"); 
    }
  }
  // Lưu trạng thái hiện tại lại để so sánh trong các
  // vòng lặp tiếp theo
  lastButtonState = buttonState;

  
  // Thực hiện bật LED sau mỗi 4 lần nhấn để kiểm tra biến đếm nút nhấn
  if (buttonPushCounter % 4 == 0) {
    digitalWrite(ledPin, HIGH);
  } else {
   digitalWrite(ledPin, LOW);
  }
  
}

Tạm kết

Coi như chúng ta đã đi qua một cơ số bài về LED, nút nhấn, hiển thị thông tin qua terminal, các bài phối hợp giữa 3 cái trên, đọc hiển thị trạng thái, quá nhanh quá nguy hiểm. Hi vọng sẽ giúp được các bạn làm quen nhanh chóng và có thể ứng dụng được vào các bài toán của riêng mình.