チーム2016
課題名
PSoC variable MUSIC BOX
研究者名
2-15-011 Shimon Kato
2-15-012 Yuya Kato
概要
PSoCに予め入力した音楽とは別の音楽をUARTで一気に書き込んで再生することができる。
楽曲は8小節分、A2~A4の2オクターブ+1音(#・♭のつく音は入力として受け付けない)
8小節分再生すると半音上げて再生、を繰り返す。
ボタンを押していると短調化(入力をmajorとしてminorにする)
HSPで実行するプログラムからは、LCDの表示内容の変更、PSoC内部の音楽の書き換え、最初から再生、が可能(予め仕込んだいくつかの楽曲は簡単に入力できる)
ハード接続設定
スピーカーは
p00<==>GND
ジャンパはそれぞれ
Tx<==>p05
Rx<==>p03
SW<==>p14
UserModules
パラメータ(Global & PWM_16)
パラメータ(Counter 8)
パラメータ(UART)
パラメータ(LCD)
パラメータ(Timer16)
Pinout設定
左の+マークをクリックして、それぞれの値を設定してください(この場合変更するのはP1[4]のみ)
割り込み設定
ソースコード(main.c)
//---------------------------------------------------------------------------- // PSoC MUSIC BOX // timer_pwm2:REF scale_freq.xls // gpio_poll // pwn_uart_2 // TODO | | ==>| | // Sys Clock 24MHz, PWM16 Clock = VC3/25, VC3=VC2/1, VC2=VC1/16 //----------------------------------------------------------------------------
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#pragma interrupt_handler myISR
#define SW 0b00010000
enum MELODY_TYPE{MELODY_BASE, MELODY_MAIN};
char ISTAN=0;
#define MELO1(a) tencho(kai[ISTAN][a],MELODY_MAIN)
#define MELO2(a) tencho(kai[ISTAN][a],MELODY_MAIN)
#define MELOb(a) tencho(kai[ISTAN][a],MELODY_BASE)
int PW=125;// Pulse Width
//Array meccha RAM kurau dengana... //Func nara ROM de sumu dengana // onkai //int mpr[26] = {0,288, 273 ,258 ,243 ,229 ,217 ,204 ,193 ,182 ,172 ,162 ,153 ,145 ,136 ,129 ,121 ,115 ,108 ,102 ,96 ,91 ,86 ,81 ,77 ,72, 68};
int mprf(char x){
switch (x){ case 1: return 288; case 2: return 273; case 3: return 258; case 4: return 243; case 5: return 229; case 6: return 217; case 7: return 204; case 8: return 193; case 9: return 182; case 10: return 172; case 11: return 162; case 12: return 153; case 13: return 145; case 14:return 136; case 15:return 129; case 16:return 121; case 17:return 115; case 18:return 108; case 19:return 102; case 20:return 96; case 21:return 91; case 22:return 86; case 23:return 81; case 24:return 77; case 25:return 72; case 26:return 68; default :return 0; }
}
int mprb[13]= {0,545 ,513 ,488 ,458 ,432 ,408 ,385,364,343,324,306,288};
// for major & minor
char kai[2][16] = {
{0, 2, 4, 5, 7, 9, 10, 12, 14, 16, 17, 19, 21, 22, 24, 26},// major {0, 1, 3, 5, 7, 8, 10, 12, 13, 15, 17, 19, 20, 22, 24, 25}//minor
};
//Scale(4bit) //For UART
#define SL 0 //
#define A2 1 //
#define B2 2 //
#define C3 3 //
#define D3 4 //
#define E3 5 //
#define F3 6 //
#define G3 7 //
#define A3 8 //
#define B3 9 //
#define C4 10 //A
#define D4 11 //B
#define E4 12 //C
#define F4 13 //D
#define G4 14 //E
#define A4 15 //F
char TC=0;// Time Count
char tench=0;
int tencho(char kai, char m){
if (kai==0) return 0; if (m){ // MELODY_MAIN if (kai+tench<=26)return mprf(kai+tench); return mprf((kai+tench-26)%12+14); }else { // MELODY_BASE if (kai+tench<=12)return mprb[kai+tench]; return mprb[(kai+tench-1)%12+1]; }
}
// saisyo ha 3 waon MusicBox yarou to shita // uart tsukattara pwm hairan... // kore sono zangai...
/*
unsigned char melo1[64]={
D3<<4|D3, D3<<4|D3, A3<<4|A3, A3<<4|A3, E3<<4|E3, E3<<4|E3, A3<<4|A3, A3<<4|A3, F3<<4|F3, F3<<4|F3, G3<<4|G3, A3<<4|A3, G3<<4|G3, G3<<4|G3, B3<<4|B3, B3<<4|B3, D4<<4|D4, A3<<4|A3, E4<<4|E4, F4<<4|F4, E4<<4|E4, F4<<4|E4, D4<<4|D4, C4<<4|C4, A3<<4|A3, C4<<4|C4, G3<<4|G3, A3<<4|A3, F3<<4|F3, F3<<4|F3, F3<<4|F3, F3<<4|F3, D3<<4|D3, D3<<4|D3, A3<<4|A3, A3<<4|A3, E3<<4|E3, E3<<4|E3, A3<<4|A3, A3<<4|A3, F3<<4|F3, F3<<4|F3, G3<<4|G3, A3<<4|A3, G3<<4|G3, G3<<4|G3, B3<<4|B3, B3<<4|B3, D4<<4|D4, A3<<4|A3, E4<<4|E4, F4<<4|F4, E4<<4|E4, F4<<4|E4, D4<<4|D4, C4<<4|C4, D4<<4|D4, D4<<4|D4, D4<<4|D4, D4<<4|D4, D4<<4|D4, D4<<4|D4, D4<<4|D4, D4<<4|D4
};
unsigned char melo2[64]={
A2<<4|A2, A2<<4|A2, F3<<4|F3, F3<<4|F3, A2<<4|A2, A2<<4|A2, F3<<4|F3, F3<<4|F3, D3<<4|D3, D3<<4|D3, E3<<4|E3, F3<<4|F3, E3<<4|E3, E3<<4|E3, G3<<4|G3, G3<<4|G3, A3<<4|A3, F3<<4|F3, C4<<4|C4, D4<<4|D4, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, F3<<4|F3, A3<<4|A3, E3<<4|E3, F3<<4|F3, D3<<4|D3, D3<<4|D3, D3<<4|D3, D3<<4|D3, A2<<4|A2, A2<<4|A2, F3<<4|F3, F3<<4|F3, A2<<4|A2, A2<<4|A2, F3<<4|F3, F3<<4|F3, D3<<4|D3, D3<<4|D3, E3<<4|E3, F3<<4|F3, E3<<4|E3, E3<<4|E3, G3<<4|G3, G3<<4|G3, A3<<4|A3, F3<<4|F3, C4<<4|C4, D4<<4|D4, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, A3<<4|A3, A3<<4|A3, A3<<4|A3, A3<<4|A3, A3<<4|A3, A3<<4|A3, A3<<4|A3, A3<<4|A3
};
// 1/2 shosetsu *2 * 8
unsigned char bass[4]={
F3<<4|G3, A3<<4|G3, F3<<4|G3, A3<<4|A3
};*/
//** The monster girl of Hartman
unsigned char melo1[64]={
D4<<4|D4, C4<<4|C4, D4<<4|D4, A3<<4|A3, F3<<4|F3, E3<<4|E3, F3<<4|F3, D3<<4|E3, F3<<4|F3, F3<<4|F3, F4<<4|F4, F4<<4|F4, E4<<4|E4, E4<<4|E4, C4<<4|C4, C4<<4|C4, D4<<4|D4, E4<<4|E4, F4<<4|F4, A4<<4|A4, F4<<4|F4, E4<<4|E4, C4<<4|C4, E3<<4|E3, F3<<4|F3, F3<<4|F3, C4<<4|C4, C4<<4|C4, D4<<4|D4, D4<<4|D4, D4<<4|D4, A3<<4|C4, D4<<4|D4, C4<<4|C4, D4<<4|D4, E4<<4|E4, F4<<4|F4, E4<<4|E4, G4<<4|G4, E4<<4|E4, F4<<4|F4, E4<<4|E4, D4<<4|D4, C4<<4|C4, F3<<4|F3, F3<<4|F3, E3<<4|E3, E3<<4|E3, D3<<4|D3, E3<<4|E3, F3<<4|F3, A3<<4|A3, F3<<4|F3, A3<<4|A3, F3<<4|F3, E3<<4|E3, D3<<4|D3, C3<<4|C3, A2<<4|A2, C3<<4|C3, D3<<4|D3, D3<<4|D3, E3<<4|E3, E3<<4|E3
};
/*
unsigned char melo2[64]={
SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, D3<<4|D3, D3<<4|D3, D4<<4|D4, D4<<4|D4, C4<<4|C4, C4<<4|C4, A3<<4|A3, A3<<4|A3, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, C3<<4|C3, D3<<4|D3, D3<<4|D3, E3<<4|E3, E3<<4|E3, F3<<4|F3, F3<<4|F3, F3<<4|F3, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, D4<<4|D4, C4<<4|C4, A3<<4|A3, A3<<4|SL, D3<<4|D3, D3<<4|D3, C3<<4|C3, C3<<4|C3, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, SL<<4|SL, A2<<4|A2, A2<<4|A2, F3<<4|F3, A2<<4|A2, F3<<4|F3, F3<<4|F3, G3<<4|G3, G3<<4|G3
};*/
// 1/2 shosetsu *2 * 8
/*unsigned char bass[4]={
D3<<4|A3, F3<<4|A3, F3<<4|A3, F3<<4|A3
};*/
void myISR(void){
int t; // base /*t=TC/8; if (t&1)PW=MELOb(bass[(t/2)%8]&0b1111); else PW=MELOb(bass[(t/2)%8]>>4); PWM16_3_WritePeriod(PW); PWM16_3_WritePulseWidth(PW/2);*/ // main t=TC/2; // melo1 PW=MELO1( (TC&1) ? melo1[t]&0b1111 : melo1[t]>>4); PWM16_1_WritePeriod(PW); PWM16_1_WritePulseWidth(PW/2); // melo2 /*PW=MELO2( (TC&1) ? melo2[t]&0b1111 : melo2[t]>>4); PWM16_2_WritePeriod(PW); PWM16_2_WritePulseWidth(PW/2); */ // roop & tencho if(TC==127){ TC=0; tench=(tench+1)%12; } else TC++;
}
int htod(char x){
if('0'<=x && x<='9') return x-'0'; else if ('A'<=x && x<='F') return x-'A'+10; return -1;
}
//for UART
char *strPtr;
void main(void)
{
M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts // Insert your main routine code here. PWM16_1_Start(); //PWM16_2_Start(); //PWM16_3_Start(); Timer16_1_EnableInt(); Timer16_1_Start(); LCD_Start(); LCD_Position(0,1); LCD_PrCString("The monster "); LCD_Position(1,1); LCD_PrCString("girl of Hartman"); PRT1DR&=(~SW); UART_CmdReset(); UART_IntCntl(UART_ENABLE_RX_INT); Counter8_WritePeriod(155); Counter8_WriteCompareValue(77); Counter8_Start(); UART_Start(UART_PARITY_NONE);
/* PC=>PSoC num data (0<= num <=FF) num 1 replay 10-1F rewrite music FC-FF rewrite LCD PSoC=>PC SC num | FA num */
while (1){ // push swich => minor // nopush swich =>major if (PRT1DR & SW)ISTAN=1; else ISTAN=0; PRT1DR &=(~SW); //UART if (UART_bCmdCheck()){ // disable interrupt M8C_DisableGInt; if (strPtr = UART_szGetParam()){ int mes_num=0; while (*strPtr!='\0'){ mes_num*=16; if (htod(*strPtr)>=0) mes_num+=htod(*strPtr); else{ mes_num=-1; break; } strPtr++; } if (mes_num<0 | | 256<=mes_num){ //fault UART_CPutString("FA "); UART_PutSHexInt(mes_num); UART_CPutString("\r\n"); }else { //success if(strPtr = UART_szGetParam()){ if (mes_num==0x01){ //reset TC=0; tench=0; }else if (0xFC<=mes_num && mes_num<=0xFF){ char posx[4]={0,0,1,1}, posy[4]={0,8,0,8}, x[9]; char i; for(i=0; strPtr[i]!='\0' ; i++){ x[i]=strPtr[i]; if (x[i]=='_') x[i]=' '; } LCD_Position(posx[mes_num-0xFC],posy[mes_num-0xFC]); LCD_PrCString(" "); LCD_Position(posx[mes_num-0xFC],posy[mes_num-0xFC]); LCD_PrString(x); }else if (0x10<=mes_num && mes_num<=0x1F){ char i; for (i=0; i <4; i++){ int f1= htod(strPtr[2*i]), f2= htod(strPtr[2*i+1]); if(0<=f1 && 0<=f2) melo1[(mes_num-0x10)*4+i]=f1<<4 | f2; else melo1[(mes_num-0x10)*4+i]=0; } }else{ LCD_Position(0,0); LCD_PrCString("Not Found"); LCD_Position(1,0); LCD_PrHexInt(mes_num); } UART_CPutString("SC "); }else { UART_CPutString("FA "); } UART_PutSHexInt(mes_num); UART_CPutString("\r\n"); } } UART_CmdReset(); M8C_EnableGInt; } };
}
ソースコード(HSP)
//------------------------------------------------------- // HSP SourceCode //メリット・GUIが楽 //-------------------------------------------------------
#include "hspext.as"
#include "mod_regexp.as"
//[TODO] 各環境ごとに書き換え
#define COM_PORT 5
onexit *close comopen COM_PORT,"baud=38400 parity=N data=8 stop=1" if stat : dialog "接続エラー" : end //連続的な命令の送信をQueueの形で管理し送信 //ただHSPにキューが無いのでnote系命令で代用 title "PSoC variable MUSIC BOX REWRITER" sdim rxBuffer, 64 sdim txBuffer, 64 font "MS UI Gothic", 13 , 0 sdim cmdbuf, 256 notesel cmdbuf //LCD表示用 sdim uplinemes, 16 sdim btlinemes, 16 sdim x,16 input uplinemes, 240, 20, 16//objid = 0 input btlinemes, 240, 20, 16//objid = 1 //音階書き換え用 sdim melody, 256 sdim melodyToSend, 256 sdim strbuf, 64 mesbox melody,320, 60 //objid = 2 pos 0,100 objsize 160,40 button gosub "音階を書換", *add_Melody //objid = 3 pos 160,100 button gosub "最初から再生", *add_Zero //objid = 4 pos 240,0 objsize 80,40 button gosub "LCDを書換", *add_LCDrewrite//objid = 5 pos 340,20 objsize 80,40 button gosub "Yamada Denki", *music_yamada button gosub "B.B.K.K.B.K.K.", *music_bbkkbkk button gosub "Southern Cross", *music_SouthernCross button gosub "ハルトマン", *music_haltman sdim log,4096 log="Start\n" pos 0,140 mesbox log,320,320,4096 logbox = stat sendmes=0 //キューが空の状態から新しい命令が追加されたことを伝える変数 resendcnt=0 //送信失敗回数を数えるための変数 change=0 //ボタン押下可能かを管理する変数
*main gosub *getdata await 50//何故か長いとバグる? goto *main *getdata comget rxBuffer, 64 if(rxBuffer != ""){ //何らかの文字を取得した時 log+= "GET :\""+replace(rxBuffer,"[\\r\\n]","")+"\"\n" objprm logbox,log split rxBuffer, " ", rslt, num if(rslt == "SC"){ //success resendcnt=0 notedel 0 if(notemax!=0){ gosub *send }else{ gosub *enable } }else{ //fault(resend) if(notemax!=0){ gosub *resend } } } if(sendmes){ gosub *send } return //16部音符単位で記入 8小節。ラ~ソ、ラ↑~ソ↑、ラ↑↑の15音、音伸ばし(ー)、休符(・)以外は無視される //連続で同じ音がなると音符が繋がる。 *music_yamada // music:YamadaDenki melody = "ド↑・ド↑ーーーレ↑ー|ド↑ーーシ↑ラ↑ーソー|ラ↑ーソーファーミー|レーーーーーー・|レーミーファーソー|ラ↑ーソーラ↑ーシ↑ー|ド↑ーシ↑ード↑ーレ↑ー|ミ↑ー・・ド↑ーソー|ーーー・ミ↑・ミ↑ー|ファ↑ーミ↑ーレ↑ード↑ー|・・シ↑ー・・ソー|ラ↑ー・・シ↑ード↑ー|・・・・ミー・・|・・ミー・・ドレ|ミー・・・・・・|・・・・・・・・" objprm 2,melody return *music_bbkkbkk // music:B.B.K.K.B.K.K. melody= "ラ↑ー・ラ↑ー・ソー |ラ↑ー・ラ↑ー・シ↑ー|\nド↑ー・ド↑ー・シ↑ー |ド↑ーシ↑ード↑ーレ↑ー|\nファ↑ー・ファ↑ー・ミ↑ー |ファ↑ー・ファ↑ー・ソ↑ー|\nミ↑ー・ミ↑ー・レ↑ー |ミ↑ーレ↑ード↑ーソー|\nラ↑ー・ラ↑ー・ソー |ラ↑ー・ラ↑ー・シ↑ー|\nド↑ー・ド↑ー・シ↑ー |ド↑ーシ↑ード↑ーレ↑ー|\nファ↑ー・ファ↑ー・ミ↑ー |ファ↑ー・ファ↑ー・ソ↑ー|\n・・・・・・・・ |・・・・・・・・" objprm 2,melody return
*music_southerncross // music:SouthernCross melody= "レーーーラミラミドラミドラ↑ミド↑ラ↑|ミ↑ファ↑ソ↑ミ↑ファ↑ド↑ラ↑ファラ↑ド↑ファ↑ラ↑ド↑ファ↑ミ↑|ド↑ラ↑ファファ↑ミ↑ファ↑ミ↑ミシ↑ド↑ミ↑ミシ↑ソファミ|ソシミソララ↑ララ↑レ↑ド↑シ↑ラ↑ミー・・|ミー・・ラミラミドラミドラ↑ミド↑ラ↑|ミ↑ファ↑ソ↑ミ↑ファ↑ド↑ラ↑ファラ↑ド↑ファ↑ラ↑ド↑ラ↑ファ↑ミ↑|ド↑ラ↑ファファ↑ミ↑ファ↑ミ↑ミシ↑ド↑ミ↑ミシ↑ソファミ|シ↑ミソシ↑ララ↑ラミ↑レドシララ↑ーーー" objprm 2,melody return *music_haltman // music:The monster girl of Hartman melody= "レ↑ード↑ーレ↑ーラ↑ーファーミーファーレミファーーーファ↑ーファ↑ーミ↑ーーード↑ーーーレ↑ーミ↑ーファ↑ーラ↑↑ーファ↑ーミ↑ード↑ーミーファーーード↑ード↑ーレ↑ーーーーーラ↑ド↑レ↑ード↑ーレ↑ーミ↑ーファ↑ーミ↑ーソ↑ーミ↑ーファ↑ーミ↑ーレ↑ード↑ーファーーーミーーーレーミーファーラ↑ーファーラ↑ーファーミーレードーラードーレーーーミーーー" objprm 2,melody return *add_LCDrewrite gosub *enable if(notemax==0){ sendmes=1 } //spaceは_でエスケープ(良い文字ねぇかな) if(uplinemes!=""){ x=strmid(uplinemes, 0, 8)+"________" noteadd "FC "+replace(strmid(x,0,8)," ","_") x=strmid(uplinemes, 8, 8)+"________" noteadd "FD "+replace(strmid(x,0,8)," ","_") } if(btlinemes!=""){ x=strmid(btlinemes, 0, 8)+"________" noteadd "FE "+replace(strmid(x,0,8)," ","_") x=strmid(btlinemes, 8, 8)+"________" noteadd "FF "+replace(strmid(x,0,8)," ","_") } return
*send //キューの先頭(note0行目)のコマンドを送信 noteget txBuffer, 0 txBuffer=replace(txBuffer,"[^A-Za-z0-9_+*\\- \\t]","")
log+= "SEND:\""+txBuffer+"\"\n" objprm logbox,log
comput txBuffer+"\r" txBuffer=null sendmes=0 return
*resend //再送信(4回まで) if(resendcnt>=4){ resendcnt=0 notedel 0 log+= "4times FAULT..." objprm logbox,log return } resendcnt++ noteget txBuffer, 0 txBuffer=replace(txBuffer,"[^A-Za-z0-9_+*\\- ]","")
log+= "RESEND:\""+txBuffer+"\"\n" objprm logbox,log
comput txBuffer+"\r" txBuffer=null return
*add_Melody gosub *enable //入力された音階情報から送信コードを生成 melodyToSend=replace(melody,"ー|―","-") melodyToSend=replace(melodyToSend,"[^ドレミファソラシ↑・-]","") melodyToSend=replace(melodyToSend,"ラ↑↑","F") melodyToSend=replace(melodyToSend,"ソ↑","E") melodyToSend=replace(melodyToSend,"ファ↑","D") melodyToSend=replace(melodyToSend,"ミ↑","C") melodyToSend=replace(melodyToSend,"レ↑","B") melodyToSend=replace(melodyToSend,"ド↑","A") melodyToSend=replace(melodyToSend,"シ↑","9") melodyToSend=replace(melodyToSend,"ラ↑","8") melodyToSend=replace(melodyToSend,"ソ","7") melodyToSend=replace(melodyToSend,"ファ","6") melodyToSend=replace(melodyToSend,"ミ","5") melodyToSend=replace(melodyToSend,"レ","4") melodyToSend=replace(melodyToSend,"ド","3") melodyToSend=replace(melodyToSend,"シ","2") melodyToSend=replace(melodyToSend,"ラ","1") melodyToSend=replace(melodyToSend,"・","0") while match(melodyToSend,"-")!="" melodyToSend=replace(melodyToSend,"(.)-","$1$1") melodyToSend=replace(melodyToSend,"^-","0") wend melodyToSend=replace(melodyToSend,"[^0-9A-F]","") if(notemax==0){ sendmes=1 } repeat 16 //0埋めして半小節ごとにコマンドにし、キュー(note最終行)に追加 strbuf=strmid(melodyToSend, 8*cnt, 8)+"00000000" noteadd strf("1%X ",cnt)+strmid(strbuf, 0, 8) loop return
*add_Zero //最初から再生 gosub *enable if(notemax==0){ sendmes=1 } noteadd "1 0" return *enable //オブジェクトの有効・無効を切り替え repeat 6 objenable cnt, change loop change^=1 return *close comclose end
考察
PSoC variable MUSIC BOXの他のデバイスと異なる特徴は発音情報を都度都度送信するのではなく、楽譜データを一気に送信し、あくまで奏でるのはPSoCであるという点にある。そのため(PSoCにとっては)大容量通信を実現するために相互通信プロトコル(コマンド)を自分らで決めた。
PC側からの送信は1バイトのコマンド番号と12文字程度に収まるデータ, PSoCからはその返答として適切に受信できたことを意味するコードを送信することにした。
これにより、異常な返答ならば再送信するなどの対応が取れる
また、転調と移調を実現するため、
ハ長調入力(0~15) , 転調するかどうか=>音(半音含む)のインデックス(0~26)
音のインデックス, 移調度合い=>実際に鳴らす音のPWM16 Period(int)
の二段階の変換を行うことにした。
元々は3和音を奏でられる書き換え可能なデバイスを作りたかったが、UserModelsの置き場所が足りず、泣く泣く2音分のPWM16を消去したという経緯をたどっている。
(3和音はPWMの各出力をXORすれば実現できた)
そのため、いかにRAM使用量上限を超えないようにするか、ということで64bit配列に128音分の情報を埋め込むかを考え、半音の情報を削除した2オクターブ分15通り(4bit)に制限した。
しかし、情報を圧縮したことで、転調・移調などを複雑な分岐をせずに実装することができた。
楽譜情報の転送の際、再送信や待機なども柔軟にできるよう、キューの構造を使いたかったがHSPにキュー構造が無かった。しかしNOTE系命令で代用できることに気づいた。
課題として、まれに転送に失敗する(PSoCからの返答が得られない)こと, 表現可能な音が2オクターブ程しかないこと, 和音を実現できなかったこと等が挙げられる。
また、LCDに書き換える際、空白が意味のある文字として存在するので、アンダーバーでエスケープしているが、これではアンダーバーが使えない。通常使用しないで動作がおかしくならないような適切な制御文字に変えたい。
転送の失敗度合いはawaitの値を変えることである程度抑えられそうだが、適切な値を検討できずにいる。
参考
hello_world, timer_pwm, gpio_poll, pwn_uart_2, HSPの利用に関してはTAのページを参考にした
- 最終更新:2020-06-02 18:17:12