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

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

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


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

페이지 정보

작성자 KHYDH 작성일2022-12-01 02:44 조회248회 댓글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

조회수 248

등록된 댓글이 없습니다.

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

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 16063
공지 사이트 이용 안내댓글[28] master 17-10-29 33189
질문 가스 센서를 쓰려면 새글 테스터 23-02-08 16
질문 ATmega328p + pca9685 + 서보모터 새글 토비 23-02-08 21
답변 답변글 답변 : ATmega328p + pca9685 + 서보모터댓글[2] 새글 master 23-02-08 23
질문 아두이노 LED 시간 제어가 안됩니다.댓글[3] 새글 고양이33 23-02-08 25
질문 Ozone 2 click 센서를 쓰려고하는데댓글[1] 새글 라칸 23-02-07 23
질문 님들 stm32 spi를 사용할떄댓글[1] 이미지 라칸 23-02-06 21
질문 ULPSM 센서의 bias 용도댓글[3] 이미지 라칸 23-02-02 41
질문 아두이노 시리얼 통신 버퍼링 이슈 이미지 엔야 23-02-02 30
답변 답변글 답변 : 아두이노 시리얼 통신 버퍼링 이슈 master 23-02-02 38
질문 풍향계 구동에서의 오류댓글[2] 이미지 kksp12y 23-02-02 39
질문 모터 전진 후진 기본 주행구현 관련 질문댓글[1] MJAY 23-02-01 42
질문 (앱인벤터)아두이노로 엘리베이터를 구현하려고 합니다.댓글[1] 이미지첨부파일 라임망고 23-01-31 48
질문 아두이노 스텝모터 연결 질문댓글[2] 아이산타 23-01-31 69
질문 미세먼지 센서를 해보는데댓글[3] 라칸 23-01-30 54
질문 가스 센서 공식댓글[2] 이미지첨부파일 풀이싫은초식동물 23-01-27 83
질문 adc값 가지고 센서 측정값을 찾고 싶은데댓글[2] 라칸 23-01-25 89
질문 님들 센서 측정값 계산식 찾는법좀댓글[2] 라칸 23-01-13 127
질문 아케이드 키, LED 연결방법댓글[1] 이런것까지 23-01-11 84
질문 블루투스 모듈을 이용해 정해진 위치로 이동할 수가 있나요?댓글[2] BBAM 23-01-05 133
질문 RTC하고 타이머로 시간 정보를 수정하고 싶은데댓글[1] 라칸 23-01-04 104
질문 AVRstudio(Atmega128) if문 질문댓글[1] 일렉트릭붐 23-01-02 165
질문 이더넷칩(RMII) 리셋 코드로 시키는 방법 이미지 라칸 23-01-02 85
질문 아두이노 uno wifi rev2 인터럽트 사용댓글[3] 이미지첨부파일 신비한호랑이 22-12-31 216
질문 dc모터 제어관련 질문드려요댓글[1] 이미지첨부파일 직장인 22-12-29 120
질문 Atmega128 RGB 밝기조절댓글[5] 일렉트릭붐 22-12-29 403
질문 아두이노에서 nRF24L01 양방향 통신 관련 질문 드립니다댓글[3] 홍챠 22-12-28 225
질문 아두이노 외부 pulse 카운트 관련 질문 애울 22-12-28 116
답변 답변글 답변 : 아두이노 외부 pulse 카운트 관련 질문댓글[3] master 22-12-28 189
게시물 검색

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
모바일버전으로보기