로그인회원등록 내글장바구니주문조회현재접속자
 상품 검색








 게시판 검색





 
 
회원등록 비번분실


온라인 입금계좌
ㆍ기업은행
ㆍ219-043192-01-028
ㆍ이건영

      거래은행 바로가기
 
 Arduino Open Source
아듀이노 함수의 상세설명
작성자 avrtools™        
작성일 2018/02/10
ㆍ추천: 0  ㆍ조회: 146   
  sine wave table 생성방법
sine wave DDS table을 생성하는 방법을 설명합니다.

가끔 Arduino로 PWM이나 DAC를 이용하여 Sine wave를 만들 필요가 있습니다.
이 방식을 DDS(직접구동 주파수 합성) 라고 합니다. 이때 반드시 필요한 것이 sine wave table 입니다.

인터넷으로 다른 사람의 소스를 찾아도 되지만,
결국 내 입맛에 맞추기는 쉽지 않지요,,,

예를 들어  100 개의 table로 sine wave를 0~360도 회전시킨다면,
다음과 같이 정의하면 됩니다.
//********************************************
// sinewave table for DAC-0 output
//********************************************
#define Num_Samples 100
static  byte WaveTable[Num_Samples] =  
{
 // SINE Table 0-360 deg
 0,    1,    2,    4,    6,   8,    12,   15,   19,   24,  
 29,   34,   40,   46,   52,  59,   66,   73,   80,   88,  
 95,   103,  111,  119,  127, 129,  135, 143,  151,  159,  
 166,  174,  181,  188,  195, 202,  208,  214,  220,  225,  
 230,  235,  239,  242,  246, 248,  250,  252,  253,  254,  
 255,  254,  253,  252,  250, 248,  246,  242,  239,  235,  
 230,  225,  220,  214,  208, 202,  195,  188,  181,  174,  
 166,  159,  151,  143,  135, 127,  119,  111,  103,  95,  
 88,   80,   73,   66,   59,  52,    46,  40,    34,  29,  
 24,   19,   15,   12,   8,    6,    4,    2,    1,   0,    
};

문제는 이 sine wave table을 내가 원하는 데로 만들 수 있는 게 중요합니다.
아두이노 스켓치를 엽니다. 새로 작성에서 setup() 에 다음과 같이 소스를 넣어 줍니다.
통신창을 엽니다. 타겟(UNO도 좋고 작동되는 아무 Arduino 기판이면 OK)

소스가 완성된다음 Upload하면, UNO가 작동하고 통신창으로 Table값이 한즐로 쭉 들어 옵니다.
한줄로 나온 Table 값들을 마우스로 훑어서 control+C 한다음, 소스창에 대고 conrol+V 하면 들어갑니다.

setup()
{
 Serial.begin(115200); // init debug monitor
 Serial.println();

 // 여기서 부터 sine wave table을 만들어서 통신으로 전송합니다.
 // 이걸 수신하여 복사한뒤 소스에 다음과 같이 {}; 안에 추가합니다
 // static  byte WaveTable[100] ={ 0, 1, 2, 3,,,,,,, 100 };   <-- 이 안에 " ,"로 구분하여 넣습니다.

 for (int x =0; x <100; x++)   // 만드는 테이블은 100개,  시작 sine 값 0은 나중에 버려도 됩니다.
 {
   // sine(x) 함수는 0~360 도의 각도값으로 들어 가야 합니다.
   // 360도/100개 =3.6도/1개가 됩니다.

   double y =sin((3.6 *x *M_PI) /180) *255;  // 8비트 분해능이면 255, 10비트면 1023, 12 비트면 2047
   y =127 +(y /2);      // 127은 AC 파형의 1/2 전압 (8비트는 127, 10 비트는 511, 12 비트는 1023)
   if (y < 0) y = 1 -y;  //  180도~360도의 sine 값은 -이므로 -가 나오면 양수로 변환하는 함수

   Serial.print(y, 0);    // 이제 0~255의 8비트 값으로 만들어진 360도/100 개의 table을 송신
   Serial.print(", ");    // table 정의시 필요한 ", " 에 space 까지 추가한다.
 }
 Serial.println();
};

loop()
{
 // main은  비워 놓아도 됩니다. 다른 소스가 있어도 그대로 OK (직렬포트로 송신하지 않는 소스)
};

삼각함수는 sin(x)은 필요에 따라서  cos(x), tan(x), asin(x), acos(x), atan(x)로 바꿀 수 있습니다.
Arduino IDE 스켓치에서 원주율 파이 값이 필요하면 M_PI 라고 대문자로 쓰면 바로 파이 값이 상수로 들어 갑니다.

이 테이블로 DAC를 구동하여 아날로그 1KHz 정현파를 출력하려면, 1/1000Hz =1us의 Timer가 필요합니다.
1us 타이머의 interrupt가 작동된다면, Timer Interrupt Handller에서 다음과 같이 DDS 생성 코드를 넣어 줍니다.

//********************************************
// sine wave generator to DAC_0
// 0~360도 1주기 소요시간 =10us *100 table =1000us,
// DDS 주파수는 1/1000us =1KHz
//********************************************
#define DAC0  (25)  // 8bit DAC #0 of ESP32
#define DAC1  (26)  // 8bit DAC #1 of ESP32

void IRAM_ATTR onTimer()  // wave table output to DAC_0
{
 dacWrite(DAC0, WaveTable[wavePtr]);  // waveform output to DAC_0
 if (++wavePtr >99) wavePtr =0; // restart wave form
};

만일 I2C-DAC라면 dacWrite(DAC_port, DDS_vlaue)에 I2C 구동 함수를 넣어 주면 됩니다.

어째서 main()에서 일일이 for 루프를 돌리지 않고 timer interrupt 함수에서 처리하는가?
이유는 단 한나. timer interrrupt로 돌리면 타이머 처리함수에서 1/1000 초마다 자동으로 1 table씩 처리됩니다.

그러면 main(), 즉 아듀이노는 loop()에서 DDS 출력은 timer 한테 맡기고 main은 다른 일을 하면 됩니다. (비서가 생긴 겁니다)
즉 system(하드웨어 장치) 처리함수는 Timer에서 multi Tasking으로 실행하는 것과 같습니다. (RTOS 보다 간단하고 빠릅니다)

Timer Interrupt 함수에서 여유가 있으면 입력 port를 읽어서 저장하거나, 입력 port의 falg을 처리하거나,
주기적으로 천천히 적당하게 처리해야 할, Matrix Keyboard 혹은 10-key 같은 주변장치들을 scan 할 수도 있습니다.
경우에 따라 adc 변환을 주기적으로 Timer 값에 따라 trigger 해도 좋습니다.
어쨋든 적당한 타이머(Interval Timer)의 가로채기(interrupot) 처리함수(handller)는 매우 편리하게 응용할 수 있습니다.

이 자료의 무단복제 및 무단 배포를 금합니다.(게시할 때는 출처를 밝혀 주시기 바랍니다)
이 프로그램은 무료 소프트웨어로, 신체와 재산 상의 어떤 위험과 손해를 보상하지 않습니다.
이 프로그램은 GNU 무료 소프트웨어 배포규정을 따릅니다.
AVRTOOLS™
   
  0
9999
윗글 판매상품의 사용설명서는 다른 자료실에,,,
아래글 LCD 문자표시 (신형)
    N         제목    글쓴이 작성일 조회 추천
판매상품의 사용설명서는 다른 자료실에,,, avrtools™ 2011/08/30 (화) 1692 0
24 sine wave table 생성방법 avrtools™ 2018/02/10 (토) 146 0
23 LCD 문자표시 (신형) avrtools™ 2012/04/12 (목) 2419 0
22 아듀이노 멜로디 연주 avrtools™ 2008/08/22 (금) 3712 0
21 아듀이노 4비트 LCD (구형) avrtools™ 2008/09/02 (화) 4648 0
20 아듀이노 가변저항 avrtools™ 2008/08/26 (화) 3306 0
19 직렬 데이터 이동(shift) 출력 avrtools™ 2012/04/10 (화) 1948 0
18 디지털 신호의 펄스폭을 측정하는 함수 avrtools™ 2012/04/10 (화) 2209 0
17 EEPROM 읽기, 쓰기 함수 avrtools™ 2012/04/10 (화) 2710 0
16 변수의 크기 avrtools™ 2012/04/10 (화) 1874 0
15 플레시 메모리에 상수를 저장하고 읽는 함수 avrtools™ 2012/04/10 (화) 2177 0
14 소프트웨어 Serial 함수 avrtools™ 2012/04/10 (화) 2073 0
13 아듀이노 터치스위치 [3] avrtools™ 2008/08/11 (월) 4506 0
12 아듀이노 shiftOut avrtools™ 2008/09/10 (수) 3693 0
11 아듀이노 스위치와 LED점등 avrtools™ 2008/08/13 (수) 5184 0
10 아듀이노의 주파수 출력 함수 avrtools™ 2009/10/20 (화) 3072 0
9 One Button Switch Library avrtools™ 2012/03/09 (금) 2119 0
8 아듀이노 논리연산 avrtools™ 2008/08/26 (화) 3332 0
7 아듀이노 PS2 키보드 읽기 avrtools™ 2008/09/10 (수) 4610 0
6 아듀이노 가로채기 함수 avrtools™ 2008/08/23 (토) 3534 0
5 아듀이노 전용명령 avrtools™ 2008/09/16 (화) 4170 0
4 아듀이노 PWM 출력과 타이머1 전용명령 avrtools™ 2008/08/19 (화) 3852 0
3 8비트 포트의 단일비트 조작방법 avrtools™ 2010/10/30 (토) 2738 0
2 직렬포트에서 문자를 받아 숫자 int로 저장 avrtools™ 2012/04/08 (일) 1945 0
1 직렬통신포트의 초기화 avrtools™ 2012/04/06 (금) 1687 0
1

바구니 : 0
 보관함 : 0
오늘뷰 : 0
HOME   |   회사소개   |   제휴안내   |   회사위치   |   서비스이용 약관   |   개인정보 보호정책   |   사이트맵
17015 경기도 용인시 기흥구 동백중앙로16번길 16-25, 508호. 전화 : 031-282-3310
사업자 등록번호 : 697-47-00075 / 대표 : 이건영 / 업태 : 제조업 / 종목 : LED조명, LED전원, 제어장치.
개인정보 관리책임자 : 홈페이지 관리자 . Copyright ⓒ2016 아크레즈 (ACLEDS INC.)
HOME TOP PREVNEXT 0 0 0