알아두면 유용한 아두이노 함수들

유용한 아두이노 함수 몇 가지를 여기에 소개합니다.

 

LED 깜박이기
LED를 요청한 빈도와 횟수만큼 깜박이는 함수입니다.


void blinkLED(byte targetPin, int numBlinks, int blinkRate) {
  for (int i=0; i < numBlinks; i++) {
    digitalWrite(targetPin, HIGH);
    delay(blinkRate);
    digitalWrite(targetPin, LOW);
    delay(blinkRate);
  }
}

 

숫자 깜박이기
과거 컴퓨터를 사용하기 시작한 지 얼마 안 된 시절에는 고장이 생겼을 때 사용자에게 오류가 발생했다는 것을 알릴 수 있는 유일한 수단이 불빛을 깜박이는 것밖에 없을 때도 있었습니다. 마이크로 컨트롤러 작업을 할 때에는 이 불빛이 유용할 때도 있습니다. 다음 함수는 LED를 연속적으로 깜박여서 숫자를 눈에 보이게 표현할 수 있지요.

void blinkNumber(char* numString) {
    int versLength = strlen(numString);
    delay(200);
    for (int i =0 ; i < versLength; i++) {
      int number = numString[i] -48;
      if (number == 0){
        blinkLED(LED_A,1,20);
        delay(160);
      }
      if (number > 0 && number < 10) blinkLED(LED_A,number,200);
      delay(400);
    }
}

 

버저 울리기
특정 주파수의 소리를 듣고 싶을 때마다 머리 아프게 수학 계산할 필요 없이 피에조 버저를 활용할 수 있게 도와주는 함수입니다. 여러분은 함수에 어떤 핀을 사용할 것인지, 어쩐 주파수의 소리를 듣고 싶은지, 그 주파수를 얼마나 길게 재생할 것인지 알려주기만 하면 된답니다.


void buzz(int targetPin, long frequency, long length) {
  long delayValue = 1000000/frequency/2;
  long numCycles = frequency * length/ 1000;
  for (long i=0; i < numCycles; i++){
    digitalWrite(targetPin,HIGH);
    delayMicroseconds(delayValue);
    digitalWrite(targetPin,LOW);
    delayMicroseconds(delayValue);
  }
}

 

사용 가능한 램 크기 확인하기
ATmega328의 프로그램 메모리는 32K지만 SRAM 크기는 2K밖에 되지 않습니다. 프로그램 메모리는 코드를 저장하는 공간이고 램은 코드가 사용하는 변수를 동적으로 저장하는 공간입니다. 실질적으로 사용할 수 있는 램의 용량은 2K보다 훨씬 적은데, 아두이노 라이브러리가 자체적으로 어느 정도의 메모리 공간을 차지하기 때문이지요.

설령 프로그램이 마이크로 컨트롤러의 SRAM 용량을 넘어서더라도 아두이노 개발 환경에서는 문제없이 컴파일이 가능합니다. 하지만 프로그램이 전혀 예측하지 못한 방향으로 동작하고, 코드가 이상하게 동작하거나 충돌할 수도 있습니다. 이 함수는 현재 사용 가능한 SRAM 용량을 반환할 것입니다.

int memoryTest() {
  int byteCounter = 0;
  byte *byteArray;
  while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL ) {
    byteCounter++;
    free(byteArray);
  }
  free(byteArray);
  return byteCounter;
}

 

큰 숫자 매핑하기
이 함수는 큰 양수에도 사용할 수 있는 map 함수라고 볼 수 있습니다. 음수는 사용할 수 없어요.

long mapBig(unsigned long x, unsigned long in_min, unsigned long in_max,
            unsigned long out_min, unsigned long out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

 

와이파이 연결하기
신형 아두이노 와이파이 실드는 아주 괜찮은 보드입니다. 그러나 여러 종류의 네트워크를 다루기는 까다로운 일이지요. 다음 코드는 SSID가 ssid 변수에 저장된 값과 같고, 암호가 pass 변수에 저장된 값과 일치하는 암호화된 WPA/WPA2 와이파이 네트워크에 접속을 시도할 것입니다. 그러나 만약 설정한 네트워크를 찾지 못하면, 공개 와아파이 네트워크를 찾기 시작하지요.

    if(WiFi.status() == WL_NO_SHIELD) {
      Serial.println("WiFi shield not present"); 
      while(true);
    }   

    if ( stringFromCharString(ssid) != "" ) {
       while ( status != WL_CONNECTED) { 
         timesWeTriedToConnect++;
         Serial.print(F("Attempting to connect to SSID (attempt "));
         Serial.print( timesWeTriedToConnect );
         Serial.print(F(" of 5): "));
         Serial.println(ssid);
         status = WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network. 
         delay(2000);
         if ( timesWeTriedToConnect >= 5 ) break;
       } 
    }    
    if ( status != WL_CONNECTED ) {
       Serial.print("Unable to connect to ssid '");
       Serial.print( ssid );
       Serial.println( "'");
       Serial.println("** Scanning for open networks **");
       byte numSsid = WiFi.scanNetworks();
       Serial.print("number of available networks:");
       Serial.println(numSsid);
       for (int thisNet = 0; thisNet<numSsid; thisNet++) {
          Serial.print(thisNet);
          Serial.print(") ");
          Serial.print(WiFi.SSID(thisNet));
          Serial.print("\tSignal: ");
          Serial.print(WiFi.RSSI(thisNet));
          Serial.print(" dBm");
          Serial.print("\tEncryption: ");
          Serial.println(WiFi.encryptionType(thisNet));
          if ( WiFi.encryptionType(thisNet) == 7 ) {
             Serial.println( "Attempting to connect to open network...");
             status = WiFi.begin( WiFi.SSID(thisNet));
             delay(10000);
             if( status == WL_CONNECTED ) break;
          }
      }
    }
    if ( status != WL_CONNECTED ) {
      Serial.println( "Unable to connect to network" );
      // don't continue:
      while(true);
    }
 

 

EEPROM에 읽고 쓰기
아두이노의 EEPROM에 숫자나 기타 데이터를 저장해 전원이 끊어졌을 때에도 데이터를 저장하는 기능이 쓸모 있을 때도 자주 있습니다. 내장 EEPROM 라이브러리를 사용하면 아주 쉽게 EEPROM에 숫자를 기록할 수 있지요.

void setNumber(unsigned long ctr) {

   Serial.print("Setting number in EEPROM to = ");
   Serial.println( ctr );
   EEPROM.write(4,(ctr & 0xFFFFFFFF) >> 24); // MSB 기록
   EEPROM.write(3,(ctr & 0xFFFFFF) >> 16); // 3rdB 기록
   EEPROM.write(2,(ctr & 0xFFFF) >> 8); // 2ndB 기록
   EEPROM.write(1,ctr & 0xFF); // LSB 기록
}

기록한 숫자는 다음 함수를 사용해 다시 읽을 수 있습니다.

unsigned long getNumber() {
   unsigned long ctr;

   //숫자 초기화
   if (EEPROM.read(5) != 1) { 

      // 저장 상태가 false일 때
      Serial.println("Initializing number in EEPROM");
      EEPROM.write(1,0); // LSB 0을 기록
      EEPROM.write(2,0); // 2ndB 0을 기록
      EEPROM.write(3,0); // 3rdB 0을 기록
      EEPROM.write(4,0); // MSB 0을 기록
      EEPROM.write(5,1); // 저장 상태를 true로 설정
   }

   //바이트를 더해 32비트 숫자를 알아낸다
   ctr = (EEPROM.read(4) << 24) + (EEPROM.read(3) << 16) + (EEPROM.read(2) << 8 )
   + (EEPROM.read(1));
   Serial.print("Getting number from EEPROM = ");
   Serial.println( ctr );
   return ctr;
}

이 게시물의 코드는 롭 팔루디(Rob Faludi)와 알라스데어 앨런(Alasdair Allan)이 제공한 것입니다. 두 사람의 동의를 얻어 MAKE 사이트에 게시했습니다. 원본 게시물은 2013년 5월 13일에 게시된 것입니다.

원문링크 http://makezine.com/2014/03/24/arduino-helper-functions-2/

 

 

You may also like...