teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

参考サイト

2019/05/07 23:55

投稿

ikadzuchi
ikadzuchi

スコア3047

answer CHANGED
@@ -95,4 +95,9 @@
95
95
  {
96
96
  //何もしない
97
97
  }
98
- ```
98
+ ```
99
+ 追記:
100
+ 割り込みとSD出力の参考にしたページです。あとデータシートも。
101
+ [https://qiita.com/suzukinori/items/939cc9f49e535c4eadd7](https://qiita.com/suzukinori/items/939cc9f49e535c4eadd7)
102
+ [http://usicolog.nomaki.jp/engineering/avr/avrInterrupt.html](http://usicolog.nomaki.jp/engineering/avr/avrInterrupt.html)
103
+ [https://garretlab.web.fc2.com/arduino_reference/libraries/standard_libraries/SD/File/write.html](https://garretlab.web.fc2.com/arduino_reference/libraries/standard_libraries/SD/File/write.html)

2

試した

2019/05/07 23:55

投稿

ikadzuchi
ikadzuchi

スコア3047

answer CHANGED
@@ -6,4 +6,93 @@
6
6
 
7
7
  SDの読み書き自体は初期化時以外はいつでも中断してよいので、
8
8
  2つのバッファを交互に使い、書くべき値を作る処理はタイマー割り込みで行い、メインでは512バイト溜まったらSDに書き出すという形でたぶんできると思います。
9
- ArduinoのSDライブラリでは割り込みは使っていませんので、ライブラリ自体を書き換えなくてもいけるはずです。
9
+ ArduinoのSDライブラリでは割り込みは使っていませんので、ライブラリ自体を書き換えなくてもいけるはずです。
10
+
11
+ ---
12
+ 気になったので試してみました。
13
+ 割り込みを利用してのバックグラウンドでの書き込み自体はどうやら成功しました。
14
+ ・400us間隔のタイマー割り込みでバッファに値を溜める
15
+ ・メインのコードでは「バッファを切り替え、書き込んでいない側のバッファをSDに書き出す」を繰り返す
16
+ という処理で、SDには値が400us間隔で生成されているような書き込みがなされました。
17
+ (なお考えてみれば512バイト待つ必要も無かったのと容量を食うのでバッファは256バイトにした)
18
+
19
+ ただ、プログラムの挙動は異常で、setup()がループしてしまっています。どこかで割り込みが使われていて干渉しているのかもしれません(SDライブラリ内か、あるいはSerialか、microsも怪しい)。あるいは何かつまらないミスがあるかもしれません。
20
+ とりあえず思っていた処理はできそうだと分かったので私は満足です。
21
+ ```Arduino
22
+ #include <SD.h>
23
+ #include <SPI.h>
24
+
25
+ const byte SD_SS = 4;
26
+ String fname = "SDwrite.txt";
27
+ File file;
28
+
29
+ unsigned long time_last = 0;
30
+ unsigned long time_now = 0;
31
+
32
+ byte buf[2][256] = {0};
33
+ int count[2] = {0};
34
+ byte phase = 0;
35
+ int i = 0;
36
+
37
+ ISR(TIMER2_COMPA_vect)
38
+ {
39
+ time_now = micros();
40
+ i++;
41
+ unsigned long time_diff = time_now-time_last;
42
+ buf[phase][count[phase] ] = time_diff&0xFF;
43
+ buf[phase][count[phase]+1] = (time_diff>> 8)&0xFF;
44
+ buf[phase][count[phase]+2] = (time_diff>>16)&0xFF;
45
+ buf[phase][count[phase]+3] = i&0xFF;
46
+ count[phase]+=4;
47
+ time_last = time_now;
48
+ }
49
+
50
+ void setup()
51
+ {
52
+ TCCR2A = 0b10000010;
53
+ TCCR2B = 0b00000011; // clk/32
54
+ OCR2A = 199; // 400usで割り込み
55
+ TIMSK2 = 0b00000010;
56
+ Serial.begin(57600);
57
+
58
+ unsigned long temp = 0L;
59
+
60
+ if (!SD.begin(SD_SS))
61
+ {
62
+ Serial.println("SD_FAIL");
63
+ return;
64
+ }
65
+
66
+ Serial.println("start");
67
+ file = SD.open(fname, FILE_WRITE); //ファイル新規作成、書き込みモード
68
+ sei();
69
+
70
+ byte buf_x[100] = {0};
71
+ int num = 100;
72
+
73
+ while (true)
74
+ {
75
+ if(micros() > 5000000L)
76
+ {
77
+ break;
78
+ }
79
+ phase ^= 1;
80
+ temp += count[phase^1];
81
+ if(count[phase^1] != 0)
82
+ {
83
+ file.write(buf[phase^1], count[phase^1]);
84
+ count[phase^1] = 0;
85
+ }
86
+ }
87
+ file.close();
88
+
89
+ Serial.println("close");
90
+ Serial.println(i);
91
+ Serial.println(temp);
92
+ }
93
+
94
+ void loop()
95
+ {
96
+ //何もしない
97
+ }
98
+ ```

1

誤字訂正

2019/05/07 16:48

投稿

ikadzuchi
ikadzuchi

スコア3047

answer CHANGED
File without changes