질문게시판 > ADC를 통해 변환한 가변저항 값으로 피아노 연주하기 질문

TODAY193 TOTAL2,582,272
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 질문게시판 | ADC를 통해 변환한 가변저항 값으로 피아노 연주하기 질문

페이지 정보

작성자 KHYDH 작성일2022-12-01 02:44 조회395회 댓글0건

본문

	

안녕하세요 주의사항에도 불구하고 현재 프로젝트 진행중에 코딩을 제대로 공부한적이 없어 코딩관련 지식이 매우 부족하고 MCU와 관련하여 지식 수준이 매우낮아 마땅히 어디 물어볼곳도 없고 하여 질문드리게 되었습니다.  염치 없지만 시간이 나셔서 답변을 해주신다면 정말 감사할 것 같습니다!

저는 ADC를 통해 변환한 가변저항 값을 범위를 설정해주어 범위 마다 특정 음이 나도록 하여 가변저항을 돌려가며 특정 값의 범위에서 도레미파솔라시도 소리가 나와 직접 피아노를 연주할 수 있도록 하는 코드를 작성하였습니다. 일단 계이름 도에 대한 코드만을 작성하였는데 동작하지않아 가변저항의 값이 변환되는 속도가 굉장히 빨라  piano_play 함수가 실행은 되지만 adc_data값이 너무 빠르게 갱신되어 소리가 나지않는다고 판단하여 가변저항 값에 대한 데이터를 변환시키고 지속시킬 수 있게 하거나 갱신되는 속도를 늦출 수 있는 방법에 대해 찾아보다가 질문드리게 되었습니다. 제가 생각한 이유 때문에 작성한 코드가 생각한대로 동작하지 않는 것인지 작성한 코드 자체가 잘못된 것인지 아니면 애초에 구현할 수 없는것을 제가 시도하고 있는 것인지에 대해 여쭤 보고 싶습니다. 해당 코드에 다른 함수들도 섞여있고 주석도 달아 놓지 않아 보기 불편하실텐데 양해 부탁드리겠습니다..

ATMEGA128, Microchip studio 사용중입니다

 

#define F_CPU 16000000

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

 

#define STOP 0

#define START 1

#define INIT 2

 

#define C1 523 // 도

#define D1 587 // 레

#define E1 659 // 미

#define F1 699 // 파

#define G1 784 // 솔

#define A1 880 // 라

#define B1 988 // 시

#define C2 C1*2 // 도

#define DLY_4 4

 

//mode selector

unsigned char mode_sel=0;

 

// display

const unsigned char Segment_Data[] =

{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x6F};

char COLUMN[4]={0,0,0,0};

 

//clock

unsigned char count_int=0;

unsigned int Seconds=0, Minutes=0, Hours=0;

 

//stopwatch

int state=STOP;

int SHOW_NUMBER=0, SHOW_NUMBER12=0, SHOW_NUMBER34=0;

 

//piano

volatile int Doremi[8]={C1,D1,E1,F1,G1,A1,B1,C2};

volatile int Doremi_length[8]={DLY_4,DLY_4,DLY_4,DLY_4,DLY_4,DLY_4,DLY_4,DLY_4};

volatile unsigned char TIMERvalue=0xFF;

volatile int freq = 1000, i,j;

 

//pianoplay

unsigned int adc_data;

 

// display

void Show_Display(unsigned int number);

void Show_stop_watch_Display(int number);

void ShowDigit(int i, int digit);

// mode

void mode0_clock();

void mode1_stop_watch();

void mode2_piano();

void mode3_piano_play();

//stopwatch

void Run(void);

// piano

void Shimpyo(int time);

void Cutoff_Play(void);

void piano_up(void);

// piano play

void adc_init(void);                  // void 변수(입력 x)를 갖는 void 함수 adc_init을 선언

void startConvertion(void);           // 입력을 필요로 하지않는 void형 함수 startConvertion을 선언한다.

unsigned int readConvertData(void);   // 입력을 필요로 하지않는 unsigned int형 함수 readConvertData 함수를 선언한다.

void piano_play();

 

ISR(TIMER0_OVF_vect)

{

count_int++;

if(count_int == 244)

{

PORTG ^= 0x03;

Seconds++;

count_int=0;

}

}

ISR(TIMER2_OVF_vect)

{

if(mode_sel==2)

{

TCNT2= TIMERvalue;

PORTB ^= 0x10;

}

}

 

ISR(INT0_vect)

{

if(++mode_sel>3)

{

mode_sel=0;

}

}

 

ISR(INT1_vect)

{

if(mode_sel==1)

{

if(state==STOP) state=START;

else            state=STOP;

}

}

 

ISR(INT2_vect)

{

if(mode_sel==1)

{

state=INIT;

}

}

 

int main(void)

{

DDRA = 0xff;

DDRB = 0x10;

DDRC = 0xff;

DDRG = 0x03;

 

TCCR0 = 0x06;

TCNT0 = 0x00;

TCCR2 = 0x04;

TCNT2 = 0x00;

TIMSK = 0x41;

EICRA=0x3F;

EIMSK=0x07;

SREG |= 0x80;

while (1)

{

switch(mode_sel)

{

case 0:

mode0_clock();

break;

case 1:

mode1_stop_watch();

break;

case 2:

mode2_piano();

break;

case 3:

mode3_piano_play();

break;

default:

mode0_clock();

break;

}

}

}

 

void Show_Display(unsigned int number)

{

COLUMN[0]   = (Minutes%100)/10;

COLUMN[1]   = (Minutes%10);

COLUMN[2]   = (Seconds%100)/10;

COLUMN[3]   = (Seconds%10);

for(int i=0;i<4;i++)

{

ShowDigit(COLUMN[i],i);

_delay_ms(2); // wait for a second

}

}

 

void Show_stop_watch_Display(int number)

{

COLUMN[0] = number/1000;

COLUMN[1] = (number%1000)/100;

COLUMN[2] = (number%100)/10;

COLUMN[3] = (number%10);

for(int i=0;i<4;i++){

ShowDigit(COLUMN[i],i);

_delay_ms(2); // wait for a second

}

}

 

void ShowDigit(int i, int digit)

{

PORTC=~(0x01<<digit);

if(mode_sel==1)

{

if(digit==1)

PORTA = Segment_Data[i]|0x80;

else

PORTA = Segment_Data[i];

}

else PORTA = Segment_Data[i];

}

 

 

void mode0_clock()

{

Show_Display(Seconds);

if(Seconds>=60)

{

Seconds=0;

Minutes++;

}

if(Minutes>=60)

{

Minutes=0;

Hours++;

}

if(Hours>=24)

{

Hours=0;

}

}

 

void mode1_stop_watch()

{

Run();

SHOW_NUMBER=SHOW_NUMBER12*100+SHOW_NUMBER34;

Show_stop_watch_Display(SHOW_NUMBER);

}

 

void mode2_piano()

{

piano_up();

_delay_ms(1000);

}

 

void mode3_piano_play()

{

piano_play();

}

 

void Run(void)

{

switch(state)

{

case STOP : break;

case START: SHOW_NUMBER34++;

if(SHOW_NUMBER34>99)

{

SHOW_NUMBER12++;

if(SHOW_NUMBER12>99) SHOW_NUMBER12=0;

SHOW_NUMBER34=0;

}

break;

case INIT : SHOW_NUMBER12=0, SHOW_NUMBER34=0, state=STOP;

break;

}

}

 

void piano_up(void)

{

for(int i=0;i<8;i++)

{

freq = Doremi[i];

TIMERvalue = 255-(1000000/(8*freq));

Shimpyo(Doremi_length[i]);

Cutoff_Play();

}

}

 

void Shimpyo(int time)

{

for(int i=0;i<time;i++)

{

_delay_ms(50);

}

}

 

void Cutoff_Play(void)

{

_delay_ms(300);

TIMERvalue=255;

_delay_ms(20);

}

 

//ADC initialize

void adc_init(void) // adc_init 함수

{

ADCSRA = 0x00; // A/D 컨버터에 인가되는 클럭의 분주비는 2이고 나머지 A/D 컨버터의 기능이 전혀 사용

               // 되지 않으며 A/D 컨버터의 모든 동작이 금지된다.

ADMUX = 0x00;  // AD 변환 설정 레지스터로 기준전압이 Aref단자가 되고 변환결과 저장시 위치를 ADCL 0BIT부터 저장한다.

               // ADC의 입력단자를 선택하고 단일입력이므로 단극성입력이 ADC0가 된다.

ACSR = 0x80;   // 아날로그 비교기 레지스터로 0x80이 1000 0000이므로 7bit가 Set이어서 아날로그 비교기의 동작을 off한다는

               // 의미이다.

ADCSRA = 0xC7; // ADC 변환 시작을 의미한다.

}

 

void startConvertion(void) // startConvertion 함수

{

ADCSRA =0xc7; // ADC 변환 시작을 의미함

ADMUX = 0x00; // ADC 입력을 0으로 설정한다.

ADCSRA = ADCSRA | 0xc7; // ADCSRA 값과 1100 0111값을 or한 결과값을 ADCSRA가 갖게되는데 OR연산시

// 기본적으로 비트 7,6,2,1,0은 항상 1 값을 갖기 때문에 A/D 컨버터의

// 동작이 허용되고 변환이 시작되며 분주비는 128값을 갖는다.

}

 

unsigned int readConvertData(void) // readConvertData 함수

{

volatile unsigned int temp; // RAM영역의 unsigned int형 변수 temp 선언

while((ADCSRA & 0x10) ==0); //ADCL, ADCH레지스터가 갱신될때까지 무한루프

ADCSRA = ADCSRA | 0x10; // A/D 변환완료 인터럽트를 요청한다. 이때, SREG레지스터의 |비트가 1로 설정되어 있으면 인터럽트

                                             // 발생

temp = (int)ADCL + (int)ADCH*256; // AD 변환값을 읽는다.

ADCSRA = ADCSRA | 0x10; // A/D 변환완료 인터럽트를 요청한다. 이때, SREG레지스터의 |비트가 1로 설정되어 있으면 인터럽트

                                              // 발생

return temp;            // temp값을 반환한다.

}

 

void piano_play()

{

adc_init();

startConvertion();

adc_data = readConvertData();

if(adc_data>=0 && adc_data<128)

{

freq = Doremi[0];

TIMERvalue = 255-(1000000/(8*freq));

Shimpyo(Doremi_length[0]);

Cutoff_Play();

}

}

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글 0

조회수 395

등록된 댓글이 없습니다.

질문게시판HOME > 질문게시판 목록

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 17080
공지 사이트 이용 안내댓글[28] master 17-10-29 33544
질문 sd카드 이미지 전송댓글[1] 새글 던지기마스터 23-03-24 12
질문 초음파센서를 이용한 모터제어 질문있습니다.댓글[3] 이미지새글첨부파일 뉴비에오 23-03-24 22
질문 부품 관련 문의댓글[1] 새글 타코 23-03-23 17
질문 모터 작동 시, 일부 모듈이 꺼지는 현상에 대해 질문드립니다. 이미지 그렇찌 23-03-22 22
답변 답변글 답변 : 모터 작동 시, 일부 모듈이 꺼지는 현상에 대해 질문드립니다. 이미지새글 master 23-03-23 15
질문 ESP로 원격 모터제어를 할 수 있나용?댓글[1] 비차 23-03-22 18
질문 HC06을 마스터로 설정하면 HC06끼리만 통신되나요?댓글[4] 비차 23-03-21 27
질문 아두이노 제어하기댓글[3] 매드닥터 23-03-19 45
질문 atmega128 압력센서 관련 질문입니다댓글[1] 공린이 23-03-19 53
질문 아두이노 스텝모터 각도제어 질문댓글[3] master 23-03-17 59
질문 아두이노와 파이썬(중점좌표) 시리얼 통신 질문드립니다.댓글[1] 이미지첨부파일 아두이노어렵잖아 23-03-16 42
질문 아두이노 3LED 버튼 관련 질문댓글[1] 이츤 23-03-16 43
질문 ATmega328p로 pca9685를 이용하여 서보모터(mg996r, mg90s)를 pwm로 제어 중 떨림댓글[1] 이미지첨부파일 토비 23-03-15 46
질문 hm-10 다중연결 질문있습니다.댓글[1] 첨부파일 뉴비에오 23-03-14 39
질문 while loop 실행 속도댓글[1] 412904 23-03-12 62
질문 AND 연산 질문드립니다.댓글[1] 412904 23-03-11 67
질문 아두이노 테트리스 게임댓글[1] 첨부파일 지욱애 23-03-02 150
질문 아두이노우노 블루투스 2개 연결댓글[1] dsfadfs 23-02-28 103
질문 스텝모터 코딩 질문입니다..댓글[2] 무야더싱 23-02-25 127
질문 아두이노 나노33 IOT 의 BLE 연결 문제 이미지 가루밀 23-02-24 73
질문 220V AC를 직류로 바꾸면 건전지 5V 건전지 55개를 대체할 수 있는건가요?댓글[1] hghh 23-02-22 93
질문 HM-10 모듈 사용하는데 질문있습니다.댓글[2] 뉴비에오 23-02-21 129
질문 아두이노 블루투스 관련 질문입니다. 생물공학도 23-02-21 100
답변 답변글 답변 : 아두이노 블루투스 관련 질문입니다. master 23-02-21 99
질문 자율주행 로봇을 만드는데 질문있습니다.댓글[2] 뉴비에오 23-02-18 161
질문 블루투스에서 아두이노로 신호전달에 대하여(2)댓글[1] 이미지첨부파일 밍경 23-02-14 190
질문 블루투스에서 아두이노로 신호전달에 대하여 밍경 23-02-13 140
답변 답변글 답변 : 블루투스에서 아두이노로 신호전달에 대하여 master 23-02-14 115
게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기