Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 1:c50f6764f528, committed 2014-10-27
- Comitter:
- kusakagenohara
- Date:
- Mon Oct 27 18:04:00 2014 +0000
- Parent:
- 0:318e4fa6590e
- Commit message:
- ??????????????????????????????????????????
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 318e4fa6590e -r c50f6764f528 main.cpp --- a/main.cpp Fri Oct 24 12:00:04 2014 +0000 +++ b/main.cpp Mon Oct 27 18:04:00 2014 +0000 @@ -16,51 +16,80 @@ } num_state_t; typedef enum { - EXISTING, - NONE, - - DONE, - CANTWRITE, - UNKNOWN -} file_write_t; - -typedef enum { Number =0, Show =!Number } mode_key_t; const char *const mode_string[] = {"Number","Show"}; -LocalFileSystem local("local"); -BusOut led(LED1,LED2,LED3,LED4); +/*ヒープ領域に作る線形リストのノード構造体。いちいちstructって書くの面倒なんでtypedefしとく*/ +typedef struct node{ + int number; //レコード(数字) + struct node *next; //次のノードへのポインタ + }node; + + -#define NUMBER_FILE_DIRECTORY "/local/" -#define FILE_NAME_TEMPLATE "test" -#define FILE_NAME_EXTENTION "csv" -static const char *const filename = NUMBER_FILE_DIRECTORY FILE_NAME_TEMPLATE"."FILE_NAME_EXTENTION; -#define NUM_OF_NUME (2) -int remove_flag = 0; +LocalFileSystem local("Local"); +BusOut led(LED1,LED2,LED3,LED4); +/*******************ポート設定(水野)***************************/ +/*通信端子*/ +Serial uart_subdisplay(p9,p10); // tx,rx +//Serial uart_ps(p28,p27); +/*7セグの十の位(端子名はwikipediaの通り)*/ +DigitalOut a10(p14); +DigitalOut b10(p15); +DigitalOut c10(p16); +DigitalOut d10(p17); +DigitalOut e10(p18); +DigitalOut f10(p19); +DigitalOut g10(p20); +/*7セグの一の位(端子名はwikipediaの通り)*/ +DigitalOut a1(p29); +DigitalOut b1(p26); +DigitalOut c1(p25); +DigitalOut d1(p24); +DigitalOut e1(p23); +DigitalOut f1(p22); +DigitalOut g1(p21); +/*本体操作スイッチ*/ +DigitalIn delete_yes(p11); +DigitalIn delete_no(p12); +DigitalIn on_off(p13); +DigitalOut file_alart_led(p8); + +/*グローバル変数*/ +static const char *const filename = "/Local/BINGO.csv"; //ファイル名 int number_flag = 0; int numidx = 0; -int numbers[NUM_OF_NUME]; +int numbers[2] = {0,0}; //バッファ。numbers[0]が十の位、numbers[1]が一の位。ってことは、ディスプレイ系関数は配列を受け取るように変更。 + +node *entr; //線形リストの先頭アドレス。mainの中に置くと面倒なのでグローバルで。 + +/*プロトタイプ宣言*/ void onKey(uint8_t); - int mode_number(int); int mode_show(int); void switch_mode(mode_key_t *); -void setNum(int);//'0'~'9' is guaranteed -file_write_t isExisting(); +void setNum_new(int);//'0'~'9' is guaranteed void deleteNum(); -void prenoteNum(); -FILE *openFile(const char *mode); -void removeFile(); -void showNum(); -void showList(); -int saveNum(); + +void effect(int); +int main_display(int*); +void power_supply_control(int,int,int,int); +void power_supply_shutdown_protect(void); +void start_up_file_check(void); +int number_converter(int*); +node* nodealloc(void); +void save_file(int); +void start_up_read_file(node*); +node* add_node(int,node*); +int kisyutu_check(); +void save_data(); -void onKey(uint8_t key) +void onKey(uint8_t key)/*キーが押されたら*/ { static mode_key_t state_mode = Number; switch (key) { @@ -78,48 +107,80 @@ inline void switch_mode(mode_key_t *mode) { *mode = Number == *mode ? Show : Number; + if(*mode == Number) + { + uart_subdisplay.printf("101\n"); //サブディスプレイ「入力モード」点灯 + } + if(*mode == Show) + { + uart_subdisplay.printf("102\n"); //サブディスプレイ「復習モード」点灯 + } } + int mode_number(int key) { static num_state_t state = Init; switch (state) { - case Prenote: - if ('\r'==key || '\n'==key) { - showNum(); - saveNum(); - deleteNum(); + case Prenote: //表示確認モードのとき + if ('\r'==key || '\n'==key) //エンターが押されたら + { + save_data(); //線形リストとファイルに保存する関数をコール + + if(main_display(numbers)) //メインディスプレイ表示 + { //switch-case中にバッファを消されると死ぬので、終了のサイン戻り値を待って、 + deleteNum(); //バッファをクリア + } } - state = Wait; + state = Wait; //入力待ちモードにセット if (0) { case Init: deleteNum(); state = Wait; } - case Wait: - switch (key) { + case Wait: //入力待ちモードなら + switch (key) { //数字が入力されたらアスキーコードを数字に変換して収納 case '0': + setNum_new(0); //「値はintで欲しい」って言ったような気が・・・7セグじゃputc使えないし。 + break; case '1': + setNum_new(1); + break; case '2': + setNum_new(2); + break; case '3': + setNum_new(3); + break; case '4': + setNum_new(4); + break; case '5': + setNum_new(5); + break; case '6': + setNum_new(6); + break; case '7': + setNum_new(7); + break; case '8': + setNum_new(8); + break; case '9': - setNum(key); + setNum_new(9); //setnumへ渡す(バッファへ保存とサブディスプレイへの出力) break; - case '\n': - case '\r'://this does not work after deleting. - if (number_flag) { - file_write_t file_state = isExisting(); - if (NONE == file_state) { - prenoteNum(); - state = Prenote; - } else if (EXISTING == file_state) { - printf("already exiting!\r\n"); - deleteNum(); + case '\n': //エンターが押されたら + case '\r': + if (number_flag) //数字フラグが1なら + { + if((kisyutu_check()) == 0){ //既出でなければ + state = Prenote; //入力確認モードへ移行 + uart_subdisplay.printf("111\n"); // サブディスプレイ「よろしいですか?」点灯 + } else if ((kisyutu_check()) == 1) { //既出なら + uart_subdisplay.printf("112\n"); //サブディスプレイ「既出です」点灯 + wait(1.0); //を1秒点灯 + deleteNum(); //バッファをクリア } } break; @@ -129,171 +190,56 @@ break; } led = state; - if (remove_flag) { - remove_flag = 0; - if ('y' == key) - removeFile(); - else - printf("Remove canceled...\r\n"); - } - - if ('d' == key) { - printf("Do you want to remove File? [y/n] \"%s\"\r\n", filename); - remove_flag = 1; - } else if ('\b' == key) { - deleteNum(); - state = Wait; + if ('\b' == key) {//b(バックスペース)なら + deleteNum(); //バッファをクリアし + state = Wait; //入力待ちモードへ } return 0; } +/*復習 メモ:福田君のモード選択アルゴリズム → 1を返すと自動的に入力モードになる*/ + int mode_show(int key) { -//このままだとshow中にモード切り替えされるとseekは保持される。 - int c; - static off_t seek=0; - FILE *fp = openFile("r"); - if ('\r'==key || '\n'==key) { - fseek(fp, seek, SEEK_SET); - if (EOF != (fscanf(fp, "%d",&c))) { - seek =ftell(fp); - printf("%2d\r\n",c); - } else { - seek = 0; - printf("EOF\r\n"); - fclose(fp); - return 1; - } + static node *current = entr; //enterのたび呼び出されるので、satatic。自動変数にしてかなり悩んだ~。だけど、復習直後に復習するとバグル。 + int main_output[2]; //mainディスプレイは配列入力なので欲しい。 + int temp; + + if(current -> next == NULL) + { + return 1; //電源ON直後に復習に入れないためのフェイルセーフ。 } - fclose(fp); + + if (key == '\r' || key == '\n') + { + current = current-> next; //先頭リストは空、最後のリストはデータあるんで、処理前に進めとく。 + temp = current -> number; //線形リストから初っ端の字取り出し + uart_subdisplay.printf("%d\n",temp); //サブディスプレイに表示 + main_output[0] = temp / 10; //INTなんで小数点以下切り捨て + main_output[1] = temp - main_output[0] * 10; //一の位取り出し + main_display(main_output); //メインディスプレイに表示 + + + if(current -> next == NULL){ //次のリストがなければ + current = entr; //復習直後に復習してもバグらない。 + return 1; //関数を抜ける + } + } return 0; } -void debug_show(const char *str) -{ - if (numbers[numidx]) { - printf("%9s :'",str); - putchar(numbers[numidx]); - putchar(numbers[1-numidx]); - printf("'\r\n"); - } -} - -void setNum(int ascii) -{ - if(!number_flag) { - number_flag = 1; - } else { - printf("\e[1A\e[2K\e[1G"); - } - numbers[numidx] = ascii; - numidx = 1-numidx; - debug_show("set"); -} -void deleteNum() -{ - debug_show("Delete"); - numidx = 0; - number_flag = 0; - numbers[0]='0'; - numbers[1]='0'; -} - -void prenoteNum() -{ - debug_show("prenote"); -} - -void showNum() -{ - debug_show("show"); -} - -FILE *openFile(const char *mode) +void deleteNum() //バッファクリア関数 { - int file_existing = 0; - FILE *fp; - - if (!file_existing) { - if (NULL != (fp = fopen(filename, "r"))) { - file_existing = 1; - fclose(fp); - } else { - if (NULL != (fp =fopen(filename, "w"))) { - file_existing = 1; - printf("create file \"%s\"\r\n",filename); - fclose(fp); - } else { - printf("unknow error \"%s\"\r\n",filename); - } - } - } - - fp = fopen(filename, mode); - return fp; -} - -void removeFile() -{ - if(0 == remove(filename)) { - printf("Removed\"%s\"\r\n",filename); - } else { - printf("could not remove file!\r\n"); - } -} - -//存在の確認(retval:NONE or EXISTING) -file_write_t isExisting() -{ - FILE *fp = openFile("r"); - int c; - char buff[2]; - int digit = 0; - file_write_t ret = NONE; - while (EOF != (c=getc(fp))) { - if ('\r'==c || '\n'==c) { - if (digit) { - digit = 0; - if (numbers[numidx] == buff[0] && numbers[1-numidx]==buff[1]) { - ret = EXISTING; - break; - } - } - } else { - buff[digit++] = c; - } - } - fclose(fp); - return ret; -} - -//存在しなければ保存 -int saveNum() -{ - file_write_t state = isExisting(); - switch (state) { - case NONE: { - FILE *fp = openFile("a"); - putc(numbers[numidx], fp); - putc(numbers[1-numidx], fp); - putc('\r', fp); - putc('\n', fp); - fclose(fp); - debug_show("saved"); - return DONE; - } - case EXISTING: - printf("number is existing\r\n"); - return CANTWRITE; - default: - break; - } - // printf("WARN:not implimented %s", __func__); - return UNKNOWN; + number_flag = 0; + numbers[0]=0; //だからーーー文字コードじゃなくてーーーーー泣 + numbers[1]=0; + uart_subdisplay.printf("110\n"); //サブディスプレイの「よろしいですか?」と「既出です。」消す + wait(0.1); //通信まち + uart_subdisplay.printf("0\n"); //サブディスプレイを0に } -void keyboard_task(void const *) +void keyboard_task(void const *) //もともとあったやつ。 { USBHostKeyboard keyboard; while(1) { @@ -307,8 +253,386 @@ } } } + + +/********************************************関数(水野)*****************************************************/ + +/*setNumを整数型バージョンへ、ついでに自分のわかりやすいアルゴリズムに書き換え*/ + +void setNum_new(int data) //バッファへセット(int用作り直し版) +{ + if(!number_flag) { //数字フラグ(入力したか判定)が立ってなければ立てる + number_flag = 1; + } + numbers[0] = numbers[1]; //一の位の数字を十の位に移して + numbers[1] = data; //一の位を更新 + uart_subdisplay.printf("%d\n",number_converter(numbers)); //2桁整数に直してサブディスプレイへ出力。 +} + +/*エフェクト制御*/ +void effect(int effect_type) +{ + /*理実と相談*/ +} + +/*メインディスプレイ 7セグ(下側MOSFET)制御 numbersが桁で分れてるので配列のままポインタで受け取りに変更*/ +int main_display(int *data) +{ + switch(data[0])//十の位 + { + case 1: + a10 = 1; + b10 = 0; + c10 = 0; + d10 = 1; + e10 = 1; + f10 = 1; + g10 = 1; + break; + case 2: + a10 = 0; + b10 = 0; + c10 = 1; + d10 = 0; + e10 = 0; + f10 = 1; + g10 = 0; + break; + case 3: + a10 = 0; + b10 = 0; + c10 = 0; + d10 = 0; + e10 = 1; + f10 = 1; + g10 = 0; + break; + case 4: + a10 = 1; + b10 = 0; + c10 = 0; + d10 = 1; + e10 = 1; + f10 = 0; + g10 = 0; + break; + case 5: + a10 = 0; + b10 = 1; + c10 = 0; + d10 = 0; + e10 = 1; + f10 = 0; + g10 = 0; + break; + case 6: + a10 = 0; + b10 = 1; + c10 = 0; + d10 = 0; + e10 = 0; + f10 = 0; + g10 = 0; + break; + case 7: + a10 = 0; + b10 = 0; + c10 = 0; + d10 = 1; + e10 = 1; + f10 = 0; + g10 = 1; + break; + case 8: + a10 = 0; + b10 = 0; + c10 = 0; + d10 = 0; + e10 = 0; + f10 = 0; + g10 = 0; + break; + case 9: + a10 = 0; + b10 = 0; + c10 = 0; + d10 = 0; + e10 = 1; + f10 = 0; + g10 = 0; + break; + default: // =0 + a10 = 0; + b10 = 0; + c10 = 0; + d10 = 0; + e10 = 0; + f10 = 0; + g10 = 1; + break; + } + + switch(data[1])//一の位 + { + case 1: + a1 = 1; + b1 = 0; + c1 = 0; + d1 = 1; + e1 = 1; + f1 = 1; + g1 = 1; + break; + case 2: + a1 = 0; + b1 = 0; + c1 = 1; + d1 = 0; + e1 = 0; + f1 = 1; + g1 = 0; + break; + case 3: + a1 = 0; + b1 = 0; + c1 = 0; + d1 = 0; + e1 = 1; + f1 = 1; + g1 = 0; + break; + case 4: + a1 = 1; + b1 = 0; + c1 = 0; + d1 = 1; + e1 = 1; + f1 = 0; + g1 = 0; + break; + case 5: + a1 = 0; + b1 = 1; + c1 = 0; + d1 = 0; + e1 = 1; + f1 = 0; + g1 = 0; + break; + case 6: + a1 = 0; + b1 = 1; + c1 = 0; + d1 = 0; + e1 = 0; + f1 = 0; + g1 = 0; + break; + case 7: + a1 = 0; + b1 = 0; + c1 = 0; + d1 = 1; + e1 = 1; + f1 = 0; + g1 = 1; + break; + case 8: + a1 = 0; + b1 = 0; + c1 = 0; + d1 = 0; + e1 = 0; + f1 = 0; + g1 = 0; + break; + case 9: + a1 = 0; + b1 = 0; + c1 = 0; + d1 = 0; + e1 = 1; + f1 = 0; + g1 = 0; + break; + default: // =0 + a1 = 0; + b1 = 0; + c1 = 0; + d1 = 0; + e1 = 0; + f1 = 0; + g1 = 1; + break; + } + return 1; +} + +/*電源(各色電流)制御*/ +void power_supply_control(int r,int g,int b,int control) //それぞれの明るさ(%)と、制御コード +{ + +} + + +/*停電時の処理(ピン変化割り込み)*/ +void power_supply_shutdown_protecct(void) +{ + + //電源が完成したら挙動を見てどんな処理が必要か考えて実装。 +} + + +/*起動時のファイルチェック*/ +void start_up_file_check(void) +{ + FILE *fp; + if((fp = fopen(filename,"r")) != NULL) //読み込みモードでファイルが開けたら、つまりファイルがあったら + { + file_alart_led = 1; //「ファイルを削除しますか?」ランプ点灯 + fclose(fp); + while(1) + { + if(delete_yes)//削除(3秒長押し) + { + wait(3.0); + if(delete_yes) //削除スイッチが、3秒経過後にまだ押されてたら + { + fp = fopen(filename,"w"); //上書きモードで開いて白紙にして上書き保存 + fclose(fp); + break; + } + } + if(delete_no)//残す(停電復帰後等) + { + start_up_read_file(entr); //ファイルを線形リストに読み込み + wait(0.1); + break; + } + } + file_alart_led = 0; //「ファイルを削除しますか?」ランプ消灯 + } +} + +/*桁ごとの配列を2桁の整数に変換*/ +int number_converter(int *data) +{ + int output_data; + output_data = 10 * data[0] + data[1]; + return output_data; +} + + +/*nodealloc関数。nodeサイズのメモリを確保して、確保したnode型のポインタを返す*/ +node* nodealloc(void) +{ + return (struct node*)malloc(sizeof(node)); //malloocは必ずキャストして使うこと +} + +/*ローカルストレージにバックアップをとる*/ +void save_file(int data) +{ + FILE *fp; + if((fp = fopen(filename,"a")) != NULL) //追記モードで開いて + { + fprintf(fp,"%d\r\n",data); //数字を保存して改行 + fclose(fp); //ファイルを閉じる + } +} + +/*停電復帰時専用。外部ファイルから線形リストに読み込み。開始ノードを引数。*/ +void start_up_read_file(node *start) +{ + int data; + node *current = start; + FILE *fp; + if((fp=fopen(filename,"r")) != NULL) //ファイルが開けたら + { + while(fscanf(fp,"%d",&data) != EOF) + { + current = add_node(data,current); + } + fclose(fp); + } +} + +/*線形リストを追加する すべてがアドレスで動いていることに注意。メモリ内の倉庫に対し、事務所からロケーション番号と作業を指示しているだけ。*/ +node* add_node(int data,struct node *current) +{ + struct node *temp; + + while(current->next != NULL) //停電復帰後はスタートノード=最後もノードになってないので、最後のノードを探す。 + { + current = current->next; + } + + temp = nodealloc(); //まずノードを作る。メモリは確保されるのでローカル変数で良い。 + temp -> number = data; //作ったノードに数字を保存する。 + temp->next = NULL; //作ったやつはケツに足すので、次につなげるのがない最終ノードにする。 + current->next = temp; //受け取ったやつは作ったやつの一個のリストになるため、作ったやつにつながるように書き換える。 + return temp; //作ったやつ(新たに最後になったやつ)のアドレスを返す。 +} + +/*新たにデータを保存する(線形リストと外部ファイル)*/ +void save_data() +{ + static node *current_node = entr; //ノードのアドレスは静的変数で。最初は当然先頭で初期化 + int data = number_converter(numbers); //バッファの中身を2桁整数に変換 + save_file(data); //ファイルに保存 + add_node(data,current_node); //線形リストに保存 +} + +/*既出チェック*/ +int kisyutu_check() +{ + node *task; //ノード型のポインタ変数。 + task = entr; //入り口ノードでスタート + int temp; //処理用変数(バッファを2桁に変換して一旦置くよ) + int flag = 0; //既出フラグ。既出なら1。ちがえば0。 + temp = number_converter(numbers); //2桁に変換して仮置き + + while(task -> next != NULL){ + task = task -> next; //入り口ノードは空。while停止条件のノードにはデータが存在。ってことで一個オフセット。 + if(task -> number == temp) //一致したらフラグを立ててループを抜ける。 + { + flag = 1; + break; + } + } + return flag; +} + + +/******************************************************************************/ + + int main() { +/**********************起動時の処理******************************************/ + +/*ディスプレイの準備*/ + deleteNum(); //numbersを0にして + main_display(numbers); //メインディスプレイを0に + uart_subdisplay.printf("0\n"); // サブディスプレイ0に + wait(0.1); //通信待ち + uart_subdisplay.printf("124\n");//サブディスプレイのステータスランプ全消灯 + +/*先頭ノードを用意*/ + entr = nodealloc(); //entr はグローバル変数。 + entr -> number = 0; //先頭ノードはデータを持たないが、考慮めんどくさいんで0にしとく。。 + entr -> next = NULL; //とりあえず一個なのでNULL。 + +/*残留データの削除または読込*/ + start_up_file_check(); + +/*電源起動*/ + + + + uart_subdisplay.printf("101\n"); //サブディスプレイ「入力モード」点灯 +/******************************************************************************/ + + Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 256 * 4); while(1) { Thread::wait(500);