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);