回答編集履歴
3
追記
answer
CHANGED
@@ -85,4 +85,121 @@
|
|
85
85
|
で、D3の波形。基本的には1ms毎にパルスが立つんだけど、長い目?で見ると、
|
86
86
|

|
87
87
|
100msの後10msからときとしてもっと長く、書き込みに専念しているようです。~~この期間割り込みも止まっていました。割り込みが動いていればバッファリングで誤魔化す手もあるんだけど...~~(誤り。オシロのサンプリングが足りなくて細くなったパルスが見えてなかった...)
|
88
|
-
512byte溜めて一気に書き込む、というのが対応でしょうね。
|
88
|
+
512byte溜めて一気に書き込む、というのが対応でしょうね。
|
89
|
+
|
90
|
+
---
|
91
|
+
しつこくいじってみました。以下のプログラム参照。多分動いているんじゃないかと。
|
92
|
+
512byte毎にSDカードに書き込んでいて、大抵は10ms~18msぐらいでwriteが終わるのですが時々100ms~170msかかるときがあります(発生原因は把握していませんがSDカードの都合?)。
|
93
|
+
これをカバーしようとするとAD結果のバッファサイズ(BUFSIZE)をそれなりに大きくしなきゃいけない、というあたりが落とし穴か。(100ms以上かかるのが連続しないという保証も実はないのだけれど、UNOではもうメモリに余裕がない)
|
94
|
+
|
95
|
+
```Arduino
|
96
|
+
#include <MsTimer2.h>
|
97
|
+
#include <SD.h>
|
98
|
+
#include <SPI.h>
|
99
|
+
#include <TimerOne.h>
|
100
|
+
|
101
|
+
//#define HARDDEBUG
|
102
|
+
|
103
|
+
const int chipSelect = 10; // Arduino UNOでは10、Arduino MEGAでは53
|
104
|
+
File dataFile;
|
105
|
+
|
106
|
+
const int BUFSIZE = 200;
|
107
|
+
int rbuf[BUFSIZE];
|
108
|
+
int wp = 0, rp = 0;
|
109
|
+
int overrun = 0;
|
110
|
+
|
111
|
+
//電圧測定及びSDカード保存
|
112
|
+
void mesuring(void) {
|
113
|
+
#ifdef HARDDEBUG
|
114
|
+
digitalWrite(4, HIGH);
|
115
|
+
#endif
|
116
|
+
wp = (wp + 1) % BUFSIZE;
|
117
|
+
rbuf[wp] = analogRead(A0);
|
118
|
+
if (wp == rp) {
|
119
|
+
overrun = 1;
|
120
|
+
}
|
121
|
+
#ifdef HARDDEBUG
|
122
|
+
digitalWrite(4, LOW);
|
123
|
+
#endif
|
124
|
+
}
|
125
|
+
|
126
|
+
void setup(void) {
|
127
|
+
pinMode(2, INPUT_PULLUP);
|
128
|
+
#ifdef HARDDEBUG
|
129
|
+
pinMode(3, OUTPUT);
|
130
|
+
pinMode(4, OUTPUT);
|
131
|
+
#endif
|
132
|
+
/* ----- Setting up serial communication with PC ------ */
|
133
|
+
/* ここでUSBを介してPCとシリアル通信を始める。9600はシリアル通信のボーレート
|
134
|
+
*/
|
135
|
+
Serial.begin(115200);
|
136
|
+
while (!Serial) {
|
137
|
+
; // wait for serial port to connect. Needed for native USB port only
|
138
|
+
//何らかの問題があってシリアルポートに接続できないときは、このループにトラップされる
|
139
|
+
}
|
140
|
+
|
141
|
+
/* ----- Initialisation of SD card ------ */
|
142
|
+
Serial.print("Initializing SD card...");
|
143
|
+
// see if the card is present and can be initialized:
|
144
|
+
if (!SD.begin(chipSelect)) {
|
145
|
+
Serial.println("Card failed, or not present");
|
146
|
+
// don't do anything more:
|
147
|
+
while (1)
|
148
|
+
;
|
149
|
+
}
|
150
|
+
Serial.println("card initialized.");
|
151
|
+
dataFile = SD.open("datalog.csv", FILE_WRITE);
|
152
|
+
if (!dataFile) {
|
153
|
+
Serial.println("File Open Error.");
|
154
|
+
while (1)
|
155
|
+
;
|
156
|
+
}
|
157
|
+
Serial.println("File Open.");
|
158
|
+
Timer1.initialize(1000); //マイクロ秒単位で設定
|
159
|
+
Timer1.attachInterrupt(mesuring);
|
160
|
+
}
|
161
|
+
|
162
|
+
void loop(void) {
|
163
|
+
/* SDカードに書き込み */
|
164
|
+
if (wp != rp) {
|
165
|
+
#ifdef HARDDEBUG
|
166
|
+
digitalWrite(3, HIGH);
|
167
|
+
#endif
|
168
|
+
rp = (rp + 1) % BUFSIZE;
|
169
|
+
// Serial.println(rbuf[rp]);
|
170
|
+
pushBuf(rbuf[rp]);
|
171
|
+
#ifdef HARDDEBUG
|
172
|
+
digitalWrite(3, LOW);
|
173
|
+
#endif
|
174
|
+
}
|
175
|
+
if (digitalRead(2) == LOW) {
|
176
|
+
dataFile.close();
|
177
|
+
Serial.println("Stop.");
|
178
|
+
while (1)
|
179
|
+
;
|
180
|
+
}
|
181
|
+
if (overrun) {
|
182
|
+
Serial.println("OR");
|
183
|
+
overrun = 0;
|
184
|
+
dataFile.close();
|
185
|
+
Serial.println(".");
|
186
|
+
while (1)
|
187
|
+
;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
uint32_t t0, t1, t2;
|
191
|
+
void pushBuf(int val) {
|
192
|
+
int wdat = val * 500l / 1023; //固定小数点数
|
193
|
+
t1 = millis();
|
194
|
+
dataFile.print(wdat/100);
|
195
|
+
dataFile.print('.');
|
196
|
+
dataFile.println(wdat %100);
|
197
|
+
t2 = millis();
|
198
|
+
if (t2 - t1 > 8) {
|
199
|
+
Serial.print(t1 - t0);
|
200
|
+
Serial.print("/");
|
201
|
+
Serial.println(t2 - t1);
|
202
|
+
t0 = t2;
|
203
|
+
}
|
204
|
+
}
|
205
|
+
```
|
2
訂正
answer
CHANGED
@@ -84,4 +84,5 @@
|
|
84
84
|
```
|
85
85
|
で、D3の波形。基本的には1ms毎にパルスが立つんだけど、長い目?で見ると、
|
86
86
|

|
87
|
-
100msの後10msからときとしてもっと長く、書き込みに専念しているようです。この期間割り込みも止まっていました。割り込みが動いていればバッファリングで誤魔化す手もあるんだけど...
|
87
|
+
100msの後10msからときとしてもっと長く、書き込みに専念しているようです。~~この期間割り込みも止まっていました。割り込みが動いていればバッファリングで誤魔化す手もあるんだけど...~~(誤り。オシロのサンプリングが足りなくて細くなったパルスが見えてなかった...)
|
88
|
+
512byte溜めて一気に書き込む、というのが対応でしょうね。
|
1
実験してみた
answer
CHANGED
@@ -6,4 +6,82 @@
|
|
6
6
|
もひとつ、割り込み中はいろいろと機能制限があります。大きくは、割り込み中は(それなりの手を打っていないと)他の割り込みが禁止になっています。SPI通信とかは結構割り込みをつかっているんじゃないかしら? 多分Serial.printも危ないです。
|
7
7
|
そういうこともありますので、「割り込みハンドラ内ではあまり大きな仕事をせず、速やかにメインコンテキストに復帰する」のが原則です。
|
8
8
|
|
9
|
-
'Arduino SDカード 書き込み速度'でぐぐったら[こんなのが](https://teratail.com/questions/187675)トップでヒットしました。ご参考まで。
|
9
|
+
'Arduino SDカード 書き込み速度'でぐぐったら[こんなのが](https://teratail.com/questions/187675)トップでヒットしました。ご参考まで。
|
10
|
+
|
11
|
+
---
|
12
|
+
ちょっとやってみたので追記。
|
13
|
+
プログラムは
|
14
|
+
```Arduino
|
15
|
+
#include <MsTimer2.h>
|
16
|
+
#include <SD.h>
|
17
|
+
#include <SPI.h>
|
18
|
+
#include <TimerOne.h>
|
19
|
+
|
20
|
+
const int chipSelect = 10; // Arduino UNOでは10、Arduino MEGAでは53
|
21
|
+
volatile int ainput; //読み取ったbit数:intは整数
|
22
|
+
volatile uint8_t rdy;
|
23
|
+
File dataFile;
|
24
|
+
|
25
|
+
//電圧測定及びSDカード保存
|
26
|
+
void mesuring(void) {
|
27
|
+
if (!rdy) {
|
28
|
+
ainput = analogRead(A0);
|
29
|
+
}
|
30
|
+
rdy = 1;
|
31
|
+
}
|
32
|
+
|
33
|
+
void setup(void) {
|
34
|
+
pinMode(2, INPUT_PULLUP);
|
35
|
+
pinMode(3, OUTPUT);
|
36
|
+
/* ----- Setting up serial communication with PC ------ */
|
37
|
+
/* ここでUSBを介してPCとシリアル通信を始める。9600はシリアル通信のボーレート
|
38
|
+
*/
|
39
|
+
Serial.begin(115200);
|
40
|
+
while (!Serial) {
|
41
|
+
; // wait for serial port to connect. Needed for native USB port only
|
42
|
+
//何らかの問題があってシリアルポートに接続できないときは、このループにトラップされる
|
43
|
+
}
|
44
|
+
|
45
|
+
/* ----- Initialisation of SD card ------ */
|
46
|
+
Serial.print("Initializing SD card...");
|
47
|
+
// see if the card is present and can be initialized:
|
48
|
+
if (!SD.begin(chipSelect)) {
|
49
|
+
Serial.println("Card failed, or not present");
|
50
|
+
// don't do anything more:
|
51
|
+
return;
|
52
|
+
}
|
53
|
+
Serial.println("card initialized.");
|
54
|
+
|
55
|
+
int i = 100; //サンプリング間隔[micro sec]
|
56
|
+
Timer1.initialize(1000); //マイクロ秒単位で設定
|
57
|
+
Timer1.attachInterrupt(mesuring);
|
58
|
+
dataFile = SD.open("datalog.csv", FILE_WRITE);
|
59
|
+
if (!dataFile) {
|
60
|
+
Serial.println("File Open Error.");
|
61
|
+
while (1)
|
62
|
+
;
|
63
|
+
}
|
64
|
+
rdy = 0;
|
65
|
+
}
|
66
|
+
|
67
|
+
void loop(void) {
|
68
|
+
/* SDカードに書き込み */
|
69
|
+
if (rdy) {
|
70
|
+
digitalWrite(3, HIGH);
|
71
|
+
dataFile.println(ainput, HEX);
|
72
|
+
// dataFile.write(&ainput,2 );
|
73
|
+
digitalWrite(3, LOW);
|
74
|
+
rdy = 0;
|
75
|
+
Serial.println(ainput, HEX);
|
76
|
+
}
|
77
|
+
if (digitalRead(2) == LOW) {
|
78
|
+
dataFile.close();
|
79
|
+
Serial.println("Stop.");
|
80
|
+
while (1)
|
81
|
+
;
|
82
|
+
}
|
83
|
+
}
|
84
|
+
```
|
85
|
+
で、D3の波形。基本的には1ms毎にパルスが立つんだけど、長い目?で見ると、
|
86
|
+

|
87
|
+
100msの後10msからときとしてもっと長く、書き込みに専念しているようです。この期間割り込みも止まっていました。割り込みが動いていればバッファリングで誤魔化す手もあるんだけど...
|