回答編集履歴

3

追記

2019/10/25 13:59

投稿

thkana
thkana

スコア7629

test CHANGED
@@ -259,3 +259,235 @@
259
259
  ```
260
260
 
261
261
  とか。
262
+
263
+
264
+
265
+ ---
266
+
267
+ とりあえず解決になったところで、好き勝手に書いてみたのでご参考まで。コンパイルは通ってるけど動作確認はしてません。
268
+
269
+ ```Arduino
270
+
271
+ #include <Servo.h>
272
+
273
+ #include <LiquidCrystal.h>
274
+
275
+
276
+
277
+ //変わりそうな値はプログラム中に値を書き込まず、一旦変数を介する
278
+
279
+ //HARDWARE SETTINGS
280
+
281
+ const int PIN_BUTTON = 7;
282
+
283
+ const int PIN_servoFeed = 13;
284
+
285
+ const int PIN_servoPwr = 8;
286
+
287
+
288
+
289
+ //ANGLE DEFINITIONS
290
+
291
+ const int ANG_CLOSE = 105;//餌箱閉じる角度
292
+
293
+ const int ANG_FEEDING = 50; //餌箱開く
294
+
295
+ const int ANG_PON = 90; //電源ON
296
+
297
+ const int ANG_POFF = 0; //電源OFF
298
+
299
+
300
+
301
+ //TIME DEFINITIONS
302
+
303
+ const int TM_MODE1 = 5000;//餌箱動作時間1
304
+
305
+ const int TM_MODE2 = 10000;//同2
306
+
307
+ const int TM_FEED = 5000; //給餌時間
308
+
309
+ const int TM_WAIT = 1000; //汎用待ち時間
310
+
311
+ const int TM_POFF = 500; //電源OFF待ち時間
312
+
313
+
314
+
315
+ //自明な、プログラムそのままのことはコメントに書かない
316
+
317
+
318
+
319
+ //DEVICE INSTANCE
320
+
321
+ Servo servoFeed; //給餌用サーボ
322
+
323
+ Servo servoPwr; //終了時電源スイッチ操作してOFFするサーボ
324
+
325
+ LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //lcd(RS,ENABLE,D4,D5,D6,D7)を宣言
326
+
327
+
328
+
329
+ //valiables
330
+
331
+ unsigned long time; //時間測定用時刻保持
332
+
333
+ int val = 0; //待ち時間モード保持
334
+
335
+ bool feeding = false; //給餌開始かどうか
336
+
337
+ String modeStr; //モード表示の文字列
338
+
339
+ int feederAngle; //餌箱サーボの角度
340
+
341
+ int pwrAngle; //電源制御の角度
342
+
343
+
344
+
345
+ void setup() {
346
+
347
+ Serial.begin(9600) ; // 9600bpsでシリアル通信のポートを開く
348
+
349
+ lcd.begin(16, 2); //(桁数,行数)を指定
350
+
351
+ pinMode(PIN_BUTTON, INPUT);
352
+
353
+ pinMode(10, OUTPUT); //10PIN?
354
+
355
+ servoFeed.attach(PIN_servoFeed);
356
+
357
+ servoPwr.attach(PIN_servoPwr);
358
+
359
+ feederAngle = ANG_CLOSE;
360
+
361
+ servoFeed.write(feederAngle);
362
+
363
+ pwrAngle = ANG_PON;
364
+
365
+ servoPwr.write(pwrAngle);
366
+
367
+ }
368
+
369
+
370
+
371
+ void lcdPrint(String line1, String line2 = "") {
372
+
373
+ lcd.clear();
374
+
375
+ lcd.print(line1);
376
+
377
+ lcd.setCursor(0, 1);
378
+
379
+ lcd.print(line2);
380
+
381
+ }
382
+
383
+
384
+
385
+ void loop() {
386
+
387
+ if (!feeding) {
388
+
389
+ feederAngle = ANG_CLOSE;
390
+
391
+ unsigned long tm;
392
+
393
+ if (digitalRead(PIN_BUTTON) == HIGH) {
394
+
395
+ //ボタンが押されたら
396
+
397
+ time = millis(); //時計リセット
398
+
399
+ //モード変更
400
+
401
+ val = val + 1;
402
+
403
+ if (val > 2)
404
+
405
+ val = 0;
406
+
407
+ //モードの設定
408
+
409
+ switch (val) {
410
+
411
+ case 0:
412
+
413
+ modeStr = "mode select";
414
+
415
+ digitalWrite(10, HIGH);//???
416
+
417
+ break;
418
+
419
+ case 1:
420
+
421
+ modeStr = "mode 1";
422
+
423
+ tm = TM_MODE1;
424
+
425
+ break;
426
+
427
+ case 2:
428
+
429
+ modeStr = "mode 2";
430
+
431
+ tm = TM_MODE2;
432
+
433
+ break;
434
+
435
+ default:
436
+
437
+ break;
438
+
439
+ }
440
+
441
+ lcdPrint("close", modeStr);
442
+
443
+ delay(20);
444
+
445
+ //ボタンが離されるのを待つ
446
+
447
+ while (digitalRead(PIN_BUTTON) == HIGH) {}
448
+
449
+ }
450
+
451
+ if ( val != 0 && (millis() - time > tm) ) {
452
+
453
+ //時間が来た
454
+
455
+ feeding = true;//給餌に遷移
456
+
457
+ lcdPrint("open", modeStr);
458
+
459
+ time = millis();
460
+
461
+ }
462
+
463
+ } else {
464
+
465
+ //給餌開始
466
+
467
+ feederAngle = ANG_FEEDING;
468
+
469
+ if (millis() - time > TM_FEED) {
470
+
471
+ feederAngle = ANG_CLOSE;
472
+
473
+ lcdPrint("end");
474
+
475
+ if (millis() - time > TM_FEED + TM_POFF) {
476
+
477
+ pwrAngle = ANG_POFF;
478
+
479
+ }
480
+
481
+ }
482
+
483
+ }
484
+
485
+ //サーボ制御はここで一括
486
+
487
+ servoFeed.write(feederAngle);
488
+
489
+ servoPwr.write(pwrAngle);
490
+
491
+ }
492
+
493
+ ```

2

誤記訂正

2019/10/25 13:59

投稿

thkana
thkana

スコア7629

test CHANGED
@@ -232,7 +232,7 @@
232
232
 
233
233
  void loop() {
234
234
 
235
- if (digitalRead(7) != HIGH) {
235
+ if (digitalRead(7) != LOW) {//LOWと比較するのは私の趣味と思って下さい。一応理由はありますが。
236
236
 
237
237
  time = millis();
238
238
 

1

追記

2019/10/22 16:17

投稿

thkana
thkana

スコア7629

test CHANGED
@@ -175,3 +175,87 @@
175
175
  ---
176
176
 
177
177
  これぐらい修正すれば動かないかなぁ...(確認していません)
178
+
179
+
180
+
181
+ ---
182
+
183
+ 追記。
184
+
185
+ for(;;)を抜ける手段が用意されていなくて「電源を切る」ところに行き着かないので...
186
+
187
+ ちょっと格好はよくないですけれど、餌をやり終わったら電源OFF、もcaseの中でやっちゃいましょうか。
188
+
189
+ ```Arduino
190
+
191
+ case 1:
192
+
193
+ servo1.write(105);
194
+
195
+ lcd.clear();
196
+
197
+ lcd.print("mode 1");
198
+
199
+ if(time>5000){
200
+
201
+ lcd.clear();
202
+
203
+ lcd.print("open");
204
+
205
+ servo1.write(50);
206
+
207
+ delay(5000);
208
+
209
+ lcd.clear();
210
+
211
+ lcd.print("end");//このendはほとんど表示される間もなく電源が落ちるかも
212
+
213
+ servo2.write(0);//このサーボ動作で電源OFF
214
+
215
+ while(1); //念の為、無限ループで動作を止める
216
+
217
+ break;
218
+
219
+ case 2:
220
+
221
+ //同様の変更
222
+
223
+ ```
224
+
225
+ そうすると、ついでに(?)for(;;)そのものが不要になったりしますけれど。
226
+
227
+ ```Arduino
228
+
229
+ int val = 0; //valはloop()を出ても保存される必要がある
230
+
231
+
232
+
233
+ void loop() {
234
+
235
+ if (digitalRead(7) != HIGH) {
236
+
237
+ time = millis();
238
+
239
+ val = val + 1;
240
+
241
+ if (val > 2)
242
+
243
+ val = 0;
244
+
245
+ delay(20);
246
+
247
+ while (digitalRead(7) != LOW) {}
248
+
249
+ }
250
+
251
+ switch (val) {
252
+
253
+ //略
254
+
255
+ }
256
+
257
+ }
258
+
259
+ ```
260
+
261
+ とか。