This is sample.

Dependencies:   USBHost mbed

このページは

イルミネーション制御用のコードページです。
使い方の説明があります。

概要

LocalFileSystem利用なのでLPC1768専用と思ってください。
"local/test.csv"ファイルが作成されます。
USBキーボードの利用が絶対です。 PCとのSerial通信も必要です。
エスケープシーケンスをちょっと利用してるので、WindowsはTeraTerm、Macはscreenコマンドをオススメします。

どんなプログラム?

プログラムの構造は 基本は2つのモードを's'キーによって切り替えて使います。(常に's'キーが有効です。)

モード内容有効なキー
入力モード数字の入力、表示、保存 (起動時はこれ)'s','0-9','\b','\r','\n' ( 'd' / 'y' )
表示モード履歴の表示のみ。キー入力で次々表示's','\r','\n'

通常の運用では入力モードでの動作になります。
キーボードのコードは

  • '\b':バックスペース(BS)
  • '\r','\n':エンターキー(LF:'\n'==0x0a)です。なんとなく'\r'足しました。

モードの説明

  • 入力モード
    • 数字(0-9)を入力するとセットされます。(2,1,3と入力すると「13」、3,0,2と入力すると「2」となります。)
    • バッファが空のときにはエンターキー'\r''\n'の入力は無視されます。
    • エンターキー('\r','\n')を入力すると
      • 1回目:確認用に表示します。(prenote)
      • 2回目:(確定され)表示・保存されます。(show,save)
      • 3回目:バッファがクリアされ待機状態になります。(Delete)
      • (4回目:バッファは空なので無視されます。)
    • 'd'を入力するとファイル削除の確認をしますので(Remove)
      • 'y'キーで削除
      • その他のキーで取り消し
    • BackSpace'\b'キーでバッファクリア(Delete)
  • 表示モード
    • エンターキー('\r','\n')を入力すると
      • 過去の保存済み数字(saved)を古い順番に表示します
      • すべて表示すると"EOF"(End Of File)と表示され入力モードに戻ります。

再起動後にファイルがある場合はそのファイルに追加編集されます。(消したい場合は入力モードで削除して)

警告

表示モードの途中で's'を入力すると、再び表示モードになったときに途中からの表示になります。
これでいい?
グローバル変数としてフラグ2つ(delete,remove)、数値2桁、数値の桁位置指示、があります。

Quote:

基本的にテストページなので好きなだけいじってください。
不明な点は福田まで。

考慮すべき点

  • 要相談
    • テンキーの場合のキー割当はどうする?
    • 既に保存した数値(already exiting!)も表示(prenote,show)まではするべき?(saveだけしない)
    • ハードウェアのソフトウェアインターフェースが不明なのでint[2]に(ASCII)グローバルで実装中。表示関数(show)は"void show(int);"がいい?
      • いやいや、10進数表示だからそのままでいい(by福田)
    • 表示モード中のモード切り替えに対して、ファイル位置を戻すべき?
    • 表示モード中に次々表示されるが、戻ることも可能にする?
    • Enterを間違えて2回押すと確定されちゃう。(4回連続入力に対しては無視)
  • ソフトウェアの気になる点
    • クラス化の必要性はある?(グローバルむき出しと構造が細かいのは精神衛生的に……)
    • 10進数2桁限定なので、3桁に対応させるべき?(対応済みコードあり)
    • (表示モード中)160行目はshow();に対応するためにもshowだけは引数ありshow(int *)or(int)にしたほうがいい。(prenoteにも渡すべきなら同様に)
    • 保存、読込フォーマットは"%02d\r\n"ですが何か?(1->"01\r\n"、23->"23\r\n"など)
    • デバッグ用にUSBシリアルに対応させる(切替仕様にす)べき?

実際の動作

ログの内容です。

[USB_INFO: /src/USBHost/USBHost/USBHost.cpp:158]New device connected: 10002c6c [hub: 0 - port: 1]
[USB_INFO: /src/USBHost/USBHostHID/USBHostKeyboard.cpp:120]New Keyboard device: VID:04fe PID:000d [dev: 10002c6c - intf: 0]
[connected]
      set :'12'
create file "/local/test.csv"
  prenote :'12'
     show :'12'
    saved :'12'
   Delete :'12'
      set :'45'
  prenote :'45'
     show :'45'
    saved :'45'
   Delete :'45'
      set :'67'
      set :'65'
      set :'45'
already exiting!
   Delete :'45'
      set :'45'
already exiting!
   Delete :'45'
mode change:Show
12
45
EOF
auto change:Number
Do you want to remove File? [y/n] "/local/test.csv"
Removed"/local/test.csv"
Committer:
lelect
Date:
Fri Oct 24 12:00:04 2014 +0000
Revision:
0:318e4fa6590e
Child:
1:c50f6764f528
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lelect 0:318e4fa6590e 1 #include "mbed.h"
lelect 0:318e4fa6590e 2 #include "USBHostKeyboard.h"
lelect 0:318e4fa6590e 3
lelect 0:318e4fa6590e 4 #define LOG_DEBUG
lelect 0:318e4fa6590e 5 #ifdef LOG_DEBUG
lelect 0:318e4fa6590e 6 #define log_debug(format,...) std::printf(format,##__VA_ARGS__)
lelect 0:318e4fa6590e 7 #else
lelect 0:318e4fa6590e 8 #define log_debug(format,...)
lelect 0:318e4fa6590e 9 #endif
lelect 0:318e4fa6590e 10
lelect 0:318e4fa6590e 11 typedef enum {
lelect 0:318e4fa6590e 12 Init,
lelect 0:318e4fa6590e 13 Wait,
lelect 0:318e4fa6590e 14 Prenote,
lelect 0:318e4fa6590e 15 Delete,
lelect 0:318e4fa6590e 16 } num_state_t;
lelect 0:318e4fa6590e 17
lelect 0:318e4fa6590e 18 typedef enum {
lelect 0:318e4fa6590e 19 EXISTING,
lelect 0:318e4fa6590e 20 NONE,
lelect 0:318e4fa6590e 21
lelect 0:318e4fa6590e 22 DONE,
lelect 0:318e4fa6590e 23 CANTWRITE,
lelect 0:318e4fa6590e 24 UNKNOWN
lelect 0:318e4fa6590e 25 } file_write_t;
lelect 0:318e4fa6590e 26
lelect 0:318e4fa6590e 27 typedef enum {
lelect 0:318e4fa6590e 28 Number =0,
lelect 0:318e4fa6590e 29 Show =!Number
lelect 0:318e4fa6590e 30 } mode_key_t;
lelect 0:318e4fa6590e 31 const char *const mode_string[] = {"Number","Show"};
lelect 0:318e4fa6590e 32
lelect 0:318e4fa6590e 33 LocalFileSystem local("local");
lelect 0:318e4fa6590e 34 BusOut led(LED1,LED2,LED3,LED4);
lelect 0:318e4fa6590e 35
lelect 0:318e4fa6590e 36 #define NUMBER_FILE_DIRECTORY "/local/"
lelect 0:318e4fa6590e 37 #define FILE_NAME_TEMPLATE "test"
lelect 0:318e4fa6590e 38 #define FILE_NAME_EXTENTION "csv"
lelect 0:318e4fa6590e 39 static const char *const filename = NUMBER_FILE_DIRECTORY FILE_NAME_TEMPLATE"."FILE_NAME_EXTENTION;
lelect 0:318e4fa6590e 40 #define NUM_OF_NUME (2)
lelect 0:318e4fa6590e 41 int remove_flag = 0;
lelect 0:318e4fa6590e 42 int number_flag = 0;
lelect 0:318e4fa6590e 43 int numidx = 0;
lelect 0:318e4fa6590e 44 int numbers[NUM_OF_NUME];
lelect 0:318e4fa6590e 45
lelect 0:318e4fa6590e 46
lelect 0:318e4fa6590e 47 void onKey(uint8_t);
lelect 0:318e4fa6590e 48
lelect 0:318e4fa6590e 49 int mode_number(int);
lelect 0:318e4fa6590e 50 int mode_show(int);
lelect 0:318e4fa6590e 51 void switch_mode(mode_key_t *);
lelect 0:318e4fa6590e 52 void setNum(int);//'0'~'9' is guaranteed
lelect 0:318e4fa6590e 53 file_write_t isExisting();
lelect 0:318e4fa6590e 54 void deleteNum();
lelect 0:318e4fa6590e 55 void prenoteNum();
lelect 0:318e4fa6590e 56 FILE *openFile(const char *mode);
lelect 0:318e4fa6590e 57 void removeFile();
lelect 0:318e4fa6590e 58 void showNum();
lelect 0:318e4fa6590e 59 void showList();
lelect 0:318e4fa6590e 60 int saveNum();
lelect 0:318e4fa6590e 61
lelect 0:318e4fa6590e 62
lelect 0:318e4fa6590e 63 void onKey(uint8_t key)
lelect 0:318e4fa6590e 64 {
lelect 0:318e4fa6590e 65 static mode_key_t state_mode = Number;
lelect 0:318e4fa6590e 66 switch (key) {
lelect 0:318e4fa6590e 67 case 's':
lelect 0:318e4fa6590e 68 switch_mode(&state_mode);
lelect 0:318e4fa6590e 69 printf("mode change:%s\r\n",mode_string[state_mode]);
lelect 0:318e4fa6590e 70 break;
lelect 0:318e4fa6590e 71 }
lelect 0:318e4fa6590e 72 if((Number == state_mode ? mode_number : mode_show)(key)) {
lelect 0:318e4fa6590e 73 switch_mode(&state_mode);
lelect 0:318e4fa6590e 74 printf("auto change:%s\r\n",mode_string[state_mode]);
lelect 0:318e4fa6590e 75 }
lelect 0:318e4fa6590e 76 }
lelect 0:318e4fa6590e 77
lelect 0:318e4fa6590e 78 inline void switch_mode(mode_key_t *mode)
lelect 0:318e4fa6590e 79 {
lelect 0:318e4fa6590e 80 *mode = Number == *mode ? Show : Number;
lelect 0:318e4fa6590e 81 }
lelect 0:318e4fa6590e 82
lelect 0:318e4fa6590e 83 int mode_number(int key)
lelect 0:318e4fa6590e 84 {
lelect 0:318e4fa6590e 85 static num_state_t state = Init;
lelect 0:318e4fa6590e 86 switch (state) {
lelect 0:318e4fa6590e 87 case Prenote:
lelect 0:318e4fa6590e 88 if ('\r'==key || '\n'==key) {
lelect 0:318e4fa6590e 89 showNum();
lelect 0:318e4fa6590e 90 saveNum();
lelect 0:318e4fa6590e 91 deleteNum();
lelect 0:318e4fa6590e 92 }
lelect 0:318e4fa6590e 93 state = Wait;
lelect 0:318e4fa6590e 94 if (0) {
lelect 0:318e4fa6590e 95 case Init:
lelect 0:318e4fa6590e 96 deleteNum();
lelect 0:318e4fa6590e 97 state = Wait;
lelect 0:318e4fa6590e 98 }
lelect 0:318e4fa6590e 99 case Wait:
lelect 0:318e4fa6590e 100 switch (key) {
lelect 0:318e4fa6590e 101 case '0':
lelect 0:318e4fa6590e 102 case '1':
lelect 0:318e4fa6590e 103 case '2':
lelect 0:318e4fa6590e 104 case '3':
lelect 0:318e4fa6590e 105 case '4':
lelect 0:318e4fa6590e 106 case '5':
lelect 0:318e4fa6590e 107 case '6':
lelect 0:318e4fa6590e 108 case '7':
lelect 0:318e4fa6590e 109 case '8':
lelect 0:318e4fa6590e 110 case '9':
lelect 0:318e4fa6590e 111 setNum(key);
lelect 0:318e4fa6590e 112 break;
lelect 0:318e4fa6590e 113 case '\n':
lelect 0:318e4fa6590e 114 case '\r'://this does not work after deleting.
lelect 0:318e4fa6590e 115 if (number_flag) {
lelect 0:318e4fa6590e 116 file_write_t file_state = isExisting();
lelect 0:318e4fa6590e 117 if (NONE == file_state) {
lelect 0:318e4fa6590e 118 prenoteNum();
lelect 0:318e4fa6590e 119 state = Prenote;
lelect 0:318e4fa6590e 120 } else if (EXISTING == file_state) {
lelect 0:318e4fa6590e 121 printf("already exiting!\r\n");
lelect 0:318e4fa6590e 122 deleteNum();
lelect 0:318e4fa6590e 123 }
lelect 0:318e4fa6590e 124 }
lelect 0:318e4fa6590e 125 break;
lelect 0:318e4fa6590e 126 }
lelect 0:318e4fa6590e 127 break;
lelect 0:318e4fa6590e 128 default:
lelect 0:318e4fa6590e 129 break;
lelect 0:318e4fa6590e 130 }
lelect 0:318e4fa6590e 131 led = state;
lelect 0:318e4fa6590e 132 if (remove_flag) {
lelect 0:318e4fa6590e 133 remove_flag = 0;
lelect 0:318e4fa6590e 134 if ('y' == key)
lelect 0:318e4fa6590e 135 removeFile();
lelect 0:318e4fa6590e 136 else
lelect 0:318e4fa6590e 137 printf("Remove canceled...\r\n");
lelect 0:318e4fa6590e 138 }
lelect 0:318e4fa6590e 139
lelect 0:318e4fa6590e 140 if ('d' == key) {
lelect 0:318e4fa6590e 141 printf("Do you want to remove File? [y/n] \"%s\"\r\n", filename);
lelect 0:318e4fa6590e 142 remove_flag = 1;
lelect 0:318e4fa6590e 143 } else if ('\b' == key) {
lelect 0:318e4fa6590e 144 deleteNum();
lelect 0:318e4fa6590e 145 state = Wait;
lelect 0:318e4fa6590e 146 }
lelect 0:318e4fa6590e 147 return 0;
lelect 0:318e4fa6590e 148 }
lelect 0:318e4fa6590e 149
lelect 0:318e4fa6590e 150 int mode_show(int key)
lelect 0:318e4fa6590e 151 {
lelect 0:318e4fa6590e 152 //このままだとshow中にモード切り替えされるとseekは保持される。
lelect 0:318e4fa6590e 153 int c;
lelect 0:318e4fa6590e 154 static off_t seek=0;
lelect 0:318e4fa6590e 155 FILE *fp = openFile("r");
lelect 0:318e4fa6590e 156 if ('\r'==key || '\n'==key) {
lelect 0:318e4fa6590e 157 fseek(fp, seek, SEEK_SET);
lelect 0:318e4fa6590e 158 if (EOF != (fscanf(fp, "%d",&c))) {
lelect 0:318e4fa6590e 159 seek =ftell(fp);
lelect 0:318e4fa6590e 160 printf("%2d\r\n",c);
lelect 0:318e4fa6590e 161 } else {
lelect 0:318e4fa6590e 162 seek = 0;
lelect 0:318e4fa6590e 163 printf("EOF\r\n");
lelect 0:318e4fa6590e 164 fclose(fp);
lelect 0:318e4fa6590e 165 return 1;
lelect 0:318e4fa6590e 166 }
lelect 0:318e4fa6590e 167 }
lelect 0:318e4fa6590e 168 fclose(fp);
lelect 0:318e4fa6590e 169 return 0;
lelect 0:318e4fa6590e 170 }
lelect 0:318e4fa6590e 171
lelect 0:318e4fa6590e 172 void debug_show(const char *str)
lelect 0:318e4fa6590e 173 {
lelect 0:318e4fa6590e 174 if (numbers[numidx]) {
lelect 0:318e4fa6590e 175 printf("%9s :'",str);
lelect 0:318e4fa6590e 176 putchar(numbers[numidx]);
lelect 0:318e4fa6590e 177 putchar(numbers[1-numidx]);
lelect 0:318e4fa6590e 178 printf("'\r\n");
lelect 0:318e4fa6590e 179 }
lelect 0:318e4fa6590e 180 }
lelect 0:318e4fa6590e 181
lelect 0:318e4fa6590e 182 void setNum(int ascii)
lelect 0:318e4fa6590e 183 {
lelect 0:318e4fa6590e 184 if(!number_flag) {
lelect 0:318e4fa6590e 185 number_flag = 1;
lelect 0:318e4fa6590e 186 } else {
lelect 0:318e4fa6590e 187 printf("\e[1A\e[2K\e[1G");
lelect 0:318e4fa6590e 188 }
lelect 0:318e4fa6590e 189 numbers[numidx] = ascii;
lelect 0:318e4fa6590e 190 numidx = 1-numidx;
lelect 0:318e4fa6590e 191 debug_show("set");
lelect 0:318e4fa6590e 192 }
lelect 0:318e4fa6590e 193 void deleteNum()
lelect 0:318e4fa6590e 194 {
lelect 0:318e4fa6590e 195 debug_show("Delete");
lelect 0:318e4fa6590e 196 numidx = 0;
lelect 0:318e4fa6590e 197 number_flag = 0;
lelect 0:318e4fa6590e 198 numbers[0]='0';
lelect 0:318e4fa6590e 199 numbers[1]='0';
lelect 0:318e4fa6590e 200 }
lelect 0:318e4fa6590e 201
lelect 0:318e4fa6590e 202 void prenoteNum()
lelect 0:318e4fa6590e 203 {
lelect 0:318e4fa6590e 204 debug_show("prenote");
lelect 0:318e4fa6590e 205 }
lelect 0:318e4fa6590e 206
lelect 0:318e4fa6590e 207 void showNum()
lelect 0:318e4fa6590e 208 {
lelect 0:318e4fa6590e 209 debug_show("show");
lelect 0:318e4fa6590e 210 }
lelect 0:318e4fa6590e 211
lelect 0:318e4fa6590e 212 FILE *openFile(const char *mode)
lelect 0:318e4fa6590e 213 {
lelect 0:318e4fa6590e 214 int file_existing = 0;
lelect 0:318e4fa6590e 215 FILE *fp;
lelect 0:318e4fa6590e 216
lelect 0:318e4fa6590e 217 if (!file_existing) {
lelect 0:318e4fa6590e 218 if (NULL != (fp = fopen(filename, "r"))) {
lelect 0:318e4fa6590e 219 file_existing = 1;
lelect 0:318e4fa6590e 220 fclose(fp);
lelect 0:318e4fa6590e 221 } else {
lelect 0:318e4fa6590e 222 if (NULL != (fp =fopen(filename, "w"))) {
lelect 0:318e4fa6590e 223 file_existing = 1;
lelect 0:318e4fa6590e 224 printf("create file \"%s\"\r\n",filename);
lelect 0:318e4fa6590e 225 fclose(fp);
lelect 0:318e4fa6590e 226 } else {
lelect 0:318e4fa6590e 227 printf("unknow error \"%s\"\r\n",filename);
lelect 0:318e4fa6590e 228 }
lelect 0:318e4fa6590e 229 }
lelect 0:318e4fa6590e 230 }
lelect 0:318e4fa6590e 231
lelect 0:318e4fa6590e 232 fp = fopen(filename, mode);
lelect 0:318e4fa6590e 233 return fp;
lelect 0:318e4fa6590e 234 }
lelect 0:318e4fa6590e 235
lelect 0:318e4fa6590e 236 void removeFile()
lelect 0:318e4fa6590e 237 {
lelect 0:318e4fa6590e 238 if(0 == remove(filename)) {
lelect 0:318e4fa6590e 239 printf("Removed\"%s\"\r\n",filename);
lelect 0:318e4fa6590e 240 } else {
lelect 0:318e4fa6590e 241 printf("could not remove file!\r\n");
lelect 0:318e4fa6590e 242 }
lelect 0:318e4fa6590e 243 }
lelect 0:318e4fa6590e 244
lelect 0:318e4fa6590e 245 //存在の確認(retval:NONE or EXISTING)
lelect 0:318e4fa6590e 246 file_write_t isExisting()
lelect 0:318e4fa6590e 247 {
lelect 0:318e4fa6590e 248 FILE *fp = openFile("r");
lelect 0:318e4fa6590e 249 int c;
lelect 0:318e4fa6590e 250 char buff[2];
lelect 0:318e4fa6590e 251 int digit = 0;
lelect 0:318e4fa6590e 252 file_write_t ret = NONE;
lelect 0:318e4fa6590e 253 while (EOF != (c=getc(fp))) {
lelect 0:318e4fa6590e 254 if ('\r'==c || '\n'==c) {
lelect 0:318e4fa6590e 255 if (digit) {
lelect 0:318e4fa6590e 256 digit = 0;
lelect 0:318e4fa6590e 257 if (numbers[numidx] == buff[0] && numbers[1-numidx]==buff[1]) {
lelect 0:318e4fa6590e 258 ret = EXISTING;
lelect 0:318e4fa6590e 259 break;
lelect 0:318e4fa6590e 260 }
lelect 0:318e4fa6590e 261 }
lelect 0:318e4fa6590e 262 } else {
lelect 0:318e4fa6590e 263 buff[digit++] = c;
lelect 0:318e4fa6590e 264 }
lelect 0:318e4fa6590e 265 }
lelect 0:318e4fa6590e 266 fclose(fp);
lelect 0:318e4fa6590e 267 return ret;
lelect 0:318e4fa6590e 268 }
lelect 0:318e4fa6590e 269
lelect 0:318e4fa6590e 270 //存在しなければ保存
lelect 0:318e4fa6590e 271 int saveNum()
lelect 0:318e4fa6590e 272 {
lelect 0:318e4fa6590e 273 file_write_t state = isExisting();
lelect 0:318e4fa6590e 274 switch (state) {
lelect 0:318e4fa6590e 275 case NONE: {
lelect 0:318e4fa6590e 276 FILE *fp = openFile("a");
lelect 0:318e4fa6590e 277 putc(numbers[numidx], fp);
lelect 0:318e4fa6590e 278 putc(numbers[1-numidx], fp);
lelect 0:318e4fa6590e 279 putc('\r', fp);
lelect 0:318e4fa6590e 280 putc('\n', fp);
lelect 0:318e4fa6590e 281 fclose(fp);
lelect 0:318e4fa6590e 282 debug_show("saved");
lelect 0:318e4fa6590e 283 return DONE;
lelect 0:318e4fa6590e 284 }
lelect 0:318e4fa6590e 285 case EXISTING:
lelect 0:318e4fa6590e 286 printf("number is existing\r\n");
lelect 0:318e4fa6590e 287 return CANTWRITE;
lelect 0:318e4fa6590e 288 default:
lelect 0:318e4fa6590e 289 break;
lelect 0:318e4fa6590e 290 }
lelect 0:318e4fa6590e 291 // printf("WARN:not implimented %s", __func__);
lelect 0:318e4fa6590e 292 return UNKNOWN;
lelect 0:318e4fa6590e 293 }
lelect 0:318e4fa6590e 294
lelect 0:318e4fa6590e 295
lelect 0:318e4fa6590e 296 void keyboard_task(void const *)
lelect 0:318e4fa6590e 297 {
lelect 0:318e4fa6590e 298 USBHostKeyboard keyboard;
lelect 0:318e4fa6590e 299 while(1) {
lelect 0:318e4fa6590e 300 while(!keyboard.connect()) {
lelect 0:318e4fa6590e 301 Thread::wait(500);
lelect 0:318e4fa6590e 302 }
lelect 0:318e4fa6590e 303 keyboard.attach(onKey);
lelect 0:318e4fa6590e 304 printf("[connected]\r\n");
lelect 0:318e4fa6590e 305 while(keyboard.connected()) {
lelect 0:318e4fa6590e 306 Thread::wait(500);
lelect 0:318e4fa6590e 307 }
lelect 0:318e4fa6590e 308 }
lelect 0:318e4fa6590e 309 }
lelect 0:318e4fa6590e 310 int main()
lelect 0:318e4fa6590e 311 {
lelect 0:318e4fa6590e 312 Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 256 * 4);
lelect 0:318e4fa6590e 313 while(1) {
lelect 0:318e4fa6590e 314 Thread::wait(500);
lelect 0:318e4fa6590e 315 }
lelect 0:318e4fa6590e 316 }