2015年11月9日 星期一

Arduino 9:超聲波測距離

超聲波感測器 HCSR04



  1. const byte trigPin = 10;  // 超音波模組的觸發腳
  2. const int  echoPin = 9;    // 超音波模組的接收腳
  3. unsigned long d;          // 儲存高脈衝的持續時間

  4. unsigned long ping() {
  5.   digitalWrite(trigPin, HIGH);   // 觸發腳設定成高電位
  6.   delayMicroseconds(5);             // 持續 5 微秒
  7.   digitalWrite(trigPin, LOW);    // 觸發腳設定成低電位
  8.  
  9.   return pulseIn(echoPin, HIGH); // 傳回高脈衝的持續時間
  10. }

  11. void setup() {
  12.   pinMode(trigPin, OUTPUT);  // 觸發腳設定成「輸出」
  13.   pinMode(echoPin, INPUT);   // 接收腳設定成「輸入」
  14.    Serial.begin(9600);                // 初始化序列埠
  15. }

  16. void loop(){
  17.   d = ping() / 58;       // 把高脈衝時間值換算成公分單位
  18.   Serial.print(d);       // 顯示距離
  19.   Serial.print("cm");
  20.   Serial.println();
  21.   delay(1000);          // 等待一秒鐘(每隔一秒測量一次)
  22. }


顯示在LCD上



  1. //-------------------------   LCD 
  2. //Library version:1.1
  3.  #include <Wire.h>
  4.  #include <LiquidCrystal_I2C.h>
  5.  #if defined(ARDUINO) && ARDUINO >= 100
  6.  #define printByte(args)  write(args);
  7.  #else
  8.  #define printByte(args)  print(args,BYTE);
  9.  #endif
  10.  LiquidCrystal_I2C lcd(0x20,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line
  11. //-------------------------

  12. //+ + + + + + + + + + +   超音波模組
  13.  const byte trigPin = 13;  // 超音波模組的觸發腳
  14.  const int echoPin = 12;    // 超音波模組的接收腳
  15.  unsigned long d;          // 儲存高脈衝的持續時間

  16.   unsigned long ping() {
  17.    digitalWrite(trigPin, HIGH);   // 觸發腳設定成高電位
  18.    delayMicroseconds(5);          // 持續 5 微秒
  19.    digitalWrite(trigPin, LOW);    // 觸發腳設定成低電位
  20.  
  21.    return pulseIn(echoPin, HIGH); // 傳回高脈衝的持續時間
  22.  }
  23. //+ + + + + + + + + + +  

  24. void setup() {
  25.     //-------------------------   LCD  
  26.      lcd.init();                      // initialize the lcd 
  27.      lcd.backlight();

  28.      lcd.setCursor(0, 0);
  29.      lcd.print   ("Distance= ");
  30.     //-------------------------   LCD  
  31.     
  32.     //+ + + + + + + + + + +   超音波模組
  33.     pinMode(trigPin, OUTPUT);  // 觸發腳設定成「輸出」
  34.     pinMode(echoPin, INPUT);   // 接收腳設定成「輸入」
  35.           //Serial.begin(9600);        // 初始化序列埠
  36.     //+ + + + + + + + + + +
  37. }


  38. void loop(){
  39.     //+ + + + + + + + + + +   超音波模組
  40.      d = ping() / 58;       // 把高脈衝時間值換算成公分單位
  41.           //Serial.print(d);       // 顯示距離
  42.           //Serial.print("cm");
  43.           //Serial.println();
  44.     //-------------------------   LCD
  45.      lcd.setCursor(9, 1);
  46.      lcd.print((unsigned long)  d  );
  47.       //  lcd.setCursor(14, 1);
  48.      lcd.print   ("cm");
  49.     //-------------------------   LCD
  50.   delay(1000);          // 等待一秒鐘(每隔一秒測量一次)
  51. }



Arduino 8:溫度量測,來個LCD顯示

DS18B20

需要引入函式庫


  1. #include <OneWire.h>

  2. int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2

  3. //Temperature chip i/o
  4. OneWire ds(DS18S20_Pin);  // on digital pin 2

  5. void setup(void) {
  6.   Serial.begin(9600);     //從螢幕上監測
  7. }

  8. void loop(void) {
  9.   float temperature = getTemp();
  10.   Serial.println(temperature);
  11.   
  12.   delay(100); //just here to slow down the output so it is easier to read
  13. }



  14. float getTemp(){
  15.                             //returns the temperature from one DS18S20 in DEG Celsius
  16.   byte data[12];
  17.   byte addr[8];

  18.   if ( !ds.search(addr)) {
  19.       //no more sensors on chain, reset search
  20.       ds.reset_search();
  21.       return -1000;
  22.   }

  23.   if ( OneWire::crc8( addr, 7) != addr[7]) {
  24.       Serial.println("CRC is not valid!");
  25.       return -1000;
  26.   }

  27.   if ( addr[0] != 0x10 && addr[0] != 0x28) {
  28.       Serial.print("Device is not recognized");
  29.       return -1000;
  30.   }

  31.   ds.reset();
  32.   ds.select(addr);
  33.   ds.write(0x44,1); // start conversion, with parasite power on at the end

  34.   byte present = ds.reset();
  35.   ds.select(addr);    
  36.   ds.write(0xBE); // Read Scratchpad

  37.   
  38.   for (int i = 0; i < 9; i++) { // we need 9 bytes
  39.     data[i] = ds.read();
  40.   }
  41.   
  42.   ds.reset_search();
  43.   
  44.   byte MSB = data[1];
  45.   byte LSB = data[0];

  46.   float tempRead = ((MSB << 8) | LSB); //using two's compliment
  47.   float TemperatureSum = tempRead / 16;
  48.   return TemperatureSum;
  49. }

改成將結果輸出到LCD

  1. //-------------------------   LCD 
  2.                                              //Library version:1.1
  3.  #include <OneWire.h>      // DS18S20 waterproof溫度模組
  4.  #include <Wire.h>
  5.  #include <LiquidCrystal_I2C.h>
  6.  #if defined(ARDUINO) && ARDUINO >= 100
  7.  #define printByte(args)  write(args);
  8.  #else
  9.  #define printByte(args)  print(args,BYTE);
  10.  #endif
  11.  LiquidCrystal_I2C lcd(0x20,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line
  12. //-------------------------

  13.  int DS18S20_Pin = 2;     //DS18S20 溫度Signal pin on digital 2
  14.                                          //Temperature chip i/o
  15.  OneWire ds(DS18S20_Pin);  // on digital pin 2
  16.  
  17. void setup() {
  18.     //-------------------------   LCD  
  19.      lcd.init();                      // initialize the lcd 
  20.      lcd.backlight();

  21.      lcd.setCursor(0, 0);
  22.      lcd.print   ("Temp.=");
  23.     //-------------------------   LCD 
  24. }


  25. void loop(){       
  26.         float temperature = getTemp();
  27.                                    //Serial.println(temperature);
  28.        //-------------------------   LCD  
  29.          lcd.setCursor(6, 0);
  30.          lcd.print(temperature, 3  );
  31.          lcd.print((char)223);            //度
  32.          lcd.print("C");
  33.        //-------------------------   LCD 
  34.  
  35.   delay(100);   //just here to slow down the output so it is easier to read
  36.                                 // delay(1000);          // 等待一秒鐘(每隔一秒測量一次)
  37. }



  38. float getTemp(){
  39.                             //returns the temperature from one DS18S20 in DEG Celsius
  40.   byte data[12];
  41.   byte addr[8];
  42.   if ( !ds.search(addr)) {
  43.       //no more sensors on chain, reset search
  44.       ds.reset_search();
  45.       return -1000;
  46.   }

  47.   if ( OneWire::crc8( addr, 7) != addr[7]) {
  48.       Serial.println("CRC is not valid!");
  49.       return -1000;
  50.   }

  51.   if ( addr[0] != 0x10 && addr[0] != 0x28) {
  52.       Serial.print("Device is not recognized");
  53.       return -1000;
  54.   }

  55.   ds.reset();
  56.   ds.select(addr);
  57.   ds.write(0x44,1); // start conversion, with parasite power on at the end

  58.   byte present = ds.reset();
  59.   ds.select(addr);    
  60.   ds.write(0xBE); // Read Scratchpad

  61.   
  62.   for (int i = 0; i < 9; i++) { // we need 9 bytes
  63.     data[i] = ds.read();
  64.   }
  65.   
  66.   ds.reset_search();
  67.   
  68.   byte MSB = data[1];
  69.   byte LSB = data[0];

  70.   float tempRead = ((MSB << 8) | LSB); //using two's compliment
  71.   float TemperatureSum = tempRead / 16;
  72.   return TemperatureSum;
  73. }


Arduino 7: LCD--將數值輸出到LCD

LCD


  • Arduino控制器的控制埠數量實在是有限,連接幾個感測器,通訊設備什麼的,你就會發現埠不夠用了,還想擴展一個液晶顯示器,怎麼辦?
  • 為了解決上述問題,我們開發的I2C介面的LCD顯示器,I2C只需兩根線就可以實現資料顯示,還可以串聯多個I2C設備。標準IIC介面,除了Arduino可以使用之外,其他單片機同樣可以進行驅動控制。
  • I2C LCD1602液晶模組,可以顯示2,每行16個字元。對於Arduino初學者來說,不必為繁瑣複雜液晶驅動電路連線而頭疼了,這款LCD擴展板將電路簡化,使用相關文檔中的庫檔,您只需使用幾行簡單的Arduino控制代碼便能完成LCD控制顯示的功能。
  • I2C LCD1602液晶模組背面的電位器還能提供你調節液晶顯示器對比度的功能。
  • 新版的IIC LCD模組支援gadgeteer介面,並且具有位址設置功能,可以通過跳線設置位址(0x20-0x27)。


需引入函式庫


  1. //-------------------------   LCD
  2.                                //Library version:1.1
  3. #include <Wire.h>
  4. #include <LiquidCrystal_I2C.h>
  5. #if defined(ARDUINO) && ARDUINO >= 100
  6. #define printByte(args)  write(args);
  7. #else
  8. #define printByte(args)  print(args,BYTE);
  9. #endif
  10. LiquidCrystal_I2C lcd(0x20,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
  11. //-------------------------

  12. void setup(){ 
  13.     //-------------------------   LCD
  14.      lcd.init();                            // initialize the lcd 
  15.      lcd.backlight();
  16.      lcd.home();  
  17.      lcd.print   ("Hello world...");
  18.      lcd.setCursor(0, 1);                //設定游標位置
  19.      lcd.print   ("CTJH");
  20.     //-------------------------   LCD
  21. }

  22.       //-------------------------    LCD 每隔 interval 閃爍,測試用
  23.        int    backlightState = LOW;
  24.        long previousMillis = 0;
  25.        long interval = 1000;
  26.       //------------------------- 

  27. void loop(){
  28.      //-------------------------    LCD 每隔 interval 閃爍,測試用
  29.        unsigned long currentMillis = millis(); 
  30.        if(currentMillis - previousMillis > interval) {
  31.          previousMillis = currentMillis;   
  32.        if (backlightState == LOW)
  33.          backlightState = HIGH;
  34.        else
  35.          backlightState = LOW;
  36.        if(backlightState == HIGH)  lcd.backlight();
  37.        else lcd.noBacklight();
  38.       } 
  39.      //-------------------------
  40. }





2015年11月8日 星期日

Arduino 6:光學特雷明-- 聲音與光學的樂器

Light Theremin
光學特雷明




  1.                           // variable to hold sensor value
  2. int sensorValue;
  3.                           // variable to calibrate low value
  4. int sensorLow = 1023;
  5.                           // variable to calibrate high value
  6. int sensorHigh = 0;
  7.                           // LED pin
  8. const int ledPin = 13;

  9. void setup() {
  10.                            // Make the LED pin an output and turn it on
  11.   pinMode(ledPin, OUTPUT);
  12.   digitalWrite(ledPin, HIGH);
  13.                             // calibrate for the first five seconds after program runs
  14.   while (millis() < 5000) {
  15.                             //keep record of the maximum sensor value
  16.     sensorValue = analogRead(A0);
  17.     if (sensorValue > sensorHigh) {
  18.       sensorHigh = sensorValue;
  19.     }
  20.                              // record the minimum sensor value
  21.     if (sensorValue < sensorLow) {
  22.       sensorLow = sensorValue;
  23.     }
  24.   }
  25.                            // turn the LED off, signaling the end of the calibration period
  26.   digitalWrite(ledPin, LOW);
  27. }

  28. void loop() {
  29.                            //read the input from A0 and store it in a variable
  30.   sensorValue = analogRead(A0);

  31.                            // map the sensor values to a wide range of pitches
  32.   int pitch = map(sensorValue, sensorLow, sensorHigh, 50, 4000);

  33.                            // play the tone for 20 ms on   pin 8
  34.   tone(8, pitch, 20);
  35.                            // wait for a moment
  36.   delay(10);
  37. }


Arduino 5:馬達控制--使用IRF520控制轉速

延續上一篇的利用IRF520控制1W的LED,並且加上[可變電阻]直接控制轉速




  1.                                        // named constants for the switch and motor pins
  2. const int motorPin =  9; // the number of the motor pin
  3. const int potentialPin= 0;  // potential meter
  4. int   value = 0;

  5. void setup() {
  6.                         // initialize the motor pin as an output:
  7.   pinMode(motorPin, OUTPUT);      
  8.                         // initialize the switch pin as an input:
  9.      // pinMode(potentialPin, INPUT);  No need declare Analog
  10. }

  11. void loop(){
  12.    
  13.   value = analogRead(potentialPin);
  14.   int intensity = map(value, 0, 1023, 0, 255);
  15.   
  16.   analogWrite( motorPin , intensity);  
  17. }
多加個[開關],只有在按下[開關]時,馬達才會運轉
  1.                                        // named constants for the switch and motor pins
  2. const int switchPin = 2; // the number of the switch pin
  3. const int motorPin =  9; // the number of the motor pin
  4. const int potentialPin= 0;  // potential meter

  5. int switchState = 0;  // variable for reading the switch's status

  6. void setup() {
  7.                         // initialize the motor pin as an output:
  8.   pinMode(motorPin, OUTPUT);      
  9.                         // initialize the switch pin as an input:
  10.   pinMode(switchPin, INPUT);
  11.                        // pinMode(potentialPin, INPUT);  No need declare Analog
  12. }

  13. void loop(){
  14.                         // read the state of the switch value:
  15.   switchState = digitalRead(switchPin);
  16.   
  17.   int value = analogRead(potentialPin);
  18.   int intensity= map(value, 0, 1023, 0,255);

  19.             // check if the switch is pressed.
  20.   if (switchState == HIGH) {     
  21.             // turn motor on:    
  22.             // digitalWrite(motorPin, HIGH);
  23.     analogWrite(motorPin, intensity);
  24.   } 
  25.   else {
  26.              // turn motor off:
  27.     digitalWrite(motorPin, LOW); 
  28.   }
  29. }




Arduino 4:LED 1W

要控制1W的LED必須要有足夠的電流:





Arduino 可利用[IRF520]當作開關,控制1W LED:

加上按鈕開關,控制LED是否亮起:




加入[可變電阻]當作輸入,控制1W LED的閃爍頻率:


  1. const int motorPin =  9;      // the number of the motor pin
  2. const int potentialPin= 0;  // potential meter
  3. int   value = 0;
  4. void setup() {
  5.                                    // initialize the motor pin as an output:
  6.   pinMode(motorPin, OUTPUT);      
  7.                                         // initialize the switch pin as an input:
  8.                                         // pinMode(potentialPin, INPUT);  No need declare Analog
  9.   Serial.begin(9600);       //顯示在螢幕上
  10. }
  11. void loop(){
  12.    
  13.   value = analogRead(potentialPin);
  14.               // Serial.print("value=");
  15.               // Serial.println(value);            
  16.   if(value == 0){      
  17.           digitalWrite(motorPin, LOW);   
  18.     delay(1000);
  19.    }
  20.   else{
  21.      int frequency = map(value, 0, 1023, 0,30);  //控制頻率
  22.                // Serial.print("freq=");
  23.                // Serial.println(frequency);
  24.        //int interval  = (1/ frequency) *1000* 0.5;  //週期的一半  (毫秒)
  25.      int interval  = 500/ frequency;
  26.              // Serial.print("interval=");
  27.              // Serial.println(interval);    
  28.      digitalWrite(motorPin, HIGH);
  29.        delay(interval);
  30.      digitalWrite(motorPin, LOW);
  31.        delay(interval);
  32.     }
  33.  }

將閃爍的頻率,顯示在LCD上:


  1. //-------------------------   LCD 
  2. //Library version:1.1
  3. #include <Wire.h>
  4. #include <LiquidCrystal_I2C.h>
  5. #if defined(ARDUINO) && ARDUINO >= 100
  6. #define printByte(args)  write(args);
  7. #else
  8. #define printByte(args)  print(args,BYTE);
  9. #endif
  10. LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
  11.                   //    ^'20'改成"27"  ,for "PCF8574"
  12.                   //    SDA  -->   "A4"
  13.                   //    SCL  -->   "A5"
  14. //-------------------------

  15. // named constants for the switch and motor pins
  16. const int motorPin =  9; // the number of the motor pin
  17. const int potentialPin= 0;  // potential meter
  18. int   value = 0;

  19. void setup() {
  20.      // initialize the motor pin as an output:
  21.   pinMode(motorPin, OUTPUT);      
  22.      // initialize the switch pin as an input:
  23.   // pinMode(potentialPin, INPUT);  No need declare Analog
  24.   Serial.begin(9600);
  25.      //-------------------------   LCD  
  26.       lcd.init();                      // initialize the lcd 
  27.       lcd.backlight();

  28.      //   lcd.setCursor(0, 0);
  29.      //   lcd.print ("freq. =");
  30.      // lcd.setCursor(0, 1);
  31.      // lcd.print   ("period=");
  32.      //-------------------------   LCD 
  33. }

  34. void loop(){
  35.    
  36.   value = analogRead(potentialPin);
  37.           //  Serial.print("value=");
  38.           //  Serial.println(value);            
  39.   if(value == 0){      
  40.           digitalWrite(motorPin, LOW);   
  41.     delay(1000);
  42.          //-------------------------   LCD
  43.         lcd.clear(); 
  44.             lcd.setCursor(0, 0);
  45.             lcd.print ("freq. =");
  46.           lcd.setCursor(0, 1);
  47.           lcd.print   ("period=");
  48.                 lcd.setCursor(8, 0);
  49.                 lcd.print(0);

  50.               lcd.setCursor(8, 1);
  51.               lcd.print(0);
  52.          //-------------------------   LCD
  53.    }
  54.   else{
  55.      int frequency = map(value, 0, 1023, 0,30);  //控制頻率
  56.              // Serial.print("freq=");
  57.              // Serial.println(frequency);
  58.      //int interval  = (1/ frequency) *1000* 0.5;  //週期的一半  (毫秒)
  59.      int interval  = 500/ frequency;
  60.              // Serial.print("interval=");
  61.              // Serial.println(interval);       
  62.         //-------------------------   LCD
  63.         lcd.clear(); 
  64.             lcd.setCursor(0, 0);
  65.             lcd.print ("freq. =");
  66.           lcd.setCursor(0, 1);
  67.           lcd.print   ("period=");
  68.         
  69.                 lcd.setCursor(8, 0);
  70.                 lcd.print(frequency);

  71.               lcd.setCursor(8, 1);
  72.               lcd.print(2*interval);
  73.                lcd.setCursor(13, 1);
  74.               lcd.print("ms");
  75.               //-------------------------   LCD
  76.      digitalWrite(motorPin, HIGH);
  77.        delay(interval);
  78.      digitalWrite(motorPin, LOW);
  79.        delay(interval);
  80.   }
  81.     
  82. }

POV_視覺暫留


Arduino 3: LED - - RGB

共陰極 RGB LED

使用random()來隨機產生數值:


  1. #define LEDR 9
  2. #define LEDG 10
  3. #define LEDB 11

  4. void setup() {               
  5.   pinMode(LEDR, OUTPUT);
  6.   pinMode(LEDG, OUTPUT);
  7.   pinMode(LEDB, OUTPUT);
  8. }

  9. int r = 0;
  10. int g = 0;
  11. int b = 0;
  12. void loop() {
  13.   r = random(0, 255);
  14.   g = random(0, 255);
  15.   b = random(0, 255);
  16.   analogWrite(LEDR, r);
  17.   analogWrite(LEDG, g);
  18.   analogWrite(LEDB, b);
  19.   delay(1000);
  20.  }

改用[可變電阻]改變不同的R、G、B數值:

  1. #define LEDR 9
  2. #define LEDG 10
  3. #define LEDB 11

  4. void setup() {               
  5.   pinMode(LEDR, OUTPUT);
  6.   pinMode(LEDG, OUTPUT);
  7.   pinMode(LEDB, OUTPUT);

  8.   Serial.begin(9600);
  9. }

  10. int r = 0;
  11. int g = 0;
  12. int b = 0;

  13. void loop() {
  14.   int rREAD=analogRead(0);
  15.   int gREAD=analogRead(1);
  16.   int bREAD=analogRead(2);
  17.      //r = random(0, 255);
  18.      //g = random(0, 255);
  19.      //b = random(0, 255);
  20.   r = map(rREAD, 0,1023, 0,255);  
  21.   g = map(gREAD, 0,1023, 0,255);
  22.   b = map(bREAD, 0,1023, 0,255); 
  23.   
  24. Serial.println(r);
  25. Serial.println(g);
  26. Serial.println(b);
  27.   
  28.    analogWrite(LEDR, r);
  29.    analogWrite(LEDG, g);
  30.    analogWrite(LEDB, b);
  31.  delay(100);
  32. }

Attiny85

  1. // This program is in the public domain.
  2. // This sketch waits for an IR pulse from a remote control
  3. // and then randomly changes the color of an RGB LED

  4. int ledPinRED = 2;    // LED on digital pin 2
  5. int ledPinGREEN = 1;  // LED on digital pin 1
  6. int ledPinBLUE = 4;   // LED on  digital pin 0
  7. int inPin = 0;               // the input pin for the IR phototransistor
  8. int randRED = 0;
  9. int randGREEN = 0;
  10. int randBLUE = 0;

  11. void setup() {
  12.   pinMode(inPin, INPUT);    // declare IR phototransistor as input
  13. }

  14. void loop(){
  15.   while(digitalRead(inPin) != LOW) {};  // read input value
  16.   
  17.     randRED = random(255); // picking a random number
  18.     randGREEN = random(255); // between 1 and 255
  19.     randBLUE = random(255);
  20.    
  21.     analogWrite(ledPinRED, randRED);        
  22.     analogWrite(ledPinGREEN, randGREEN);        
  23.     analogWrite(ledPinBLUE, randBLUE);        
  24.     delay(100);  // de-bounces the input so it does not zoom
  25.                  // through a zillion colors with every button click   
  26.   }

Arduino 2: 使用不同方式控制LED

RC


555


2N6027



光敏電阻控制亮度


Arduino 1: LED

Arduino 板



首先,來[寫]一個簡單的arduino程式:



可以利用 delay() 調整不同頻率。

再來看一個[改寫版]:


現在,實際接上一個LED:

再使用[開關]控制 LED是否要亮起來:

  1. void setup(){
  2.     // declare the LED pins as outputs 
  3.   pinMode(3,OUTPUT);
  4.     // declare the switch pin as an input   
  5.   pinMode(2,INPUT);
  6. }

  7. void loop(){
  8.     // read the value of the switch
  9.     // digitalRead() checks to see if there is voltage
  10.     // on the pin or not  
  11.   switchstate = digitalRead(2);

  12.     // if the button is not pressed
  13.     // blink the red LEDs  
  14.   if (switchstate == LOW) {
  15.     digitalWrite(3, LOW); // turn the green LED on pin 3 off
  16.   }
  17.       // this else is part of the above if() statement. 
  18.       // if the switch is not LOW (the button is pressed)
  19.       // the code below will run  
  20.   else {
  21.     digitalWrite(3, HIGH); // turn the red LED on pin 5 on
  22.       // wait for a quarter second before changing the light
  23.     delay(250);
  24.   }
  25. }