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

回答編集履歴

3

追記

2019/10/25 13:59

投稿

thkana
thkana

スコア7735

answer CHANGED
@@ -128,4 +128,120 @@
128
128
  }
129
129
  }
130
130
  ```
131
- とか。
131
+ とか。
132
+
133
+ ---
134
+ とりあえず解決になったところで、好き勝手に書いてみたのでご参考まで。コンパイルは通ってるけど動作確認はしてません。
135
+ ```Arduino
136
+ #include <Servo.h>
137
+ #include <LiquidCrystal.h>
138
+
139
+ //変わりそうな値はプログラム中に値を書き込まず、一旦変数を介する
140
+ //HARDWARE SETTINGS
141
+ const int PIN_BUTTON = 7;
142
+ const int PIN_servoFeed = 13;
143
+ const int PIN_servoPwr = 8;
144
+
145
+ //ANGLE DEFINITIONS
146
+ const int ANG_CLOSE = 105;//餌箱閉じる角度
147
+ const int ANG_FEEDING = 50; //餌箱開く
148
+ const int ANG_PON = 90; //電源ON
149
+ const int ANG_POFF = 0; //電源OFF
150
+
151
+ //TIME DEFINITIONS
152
+ const int TM_MODE1 = 5000;//餌箱動作時間1
153
+ const int TM_MODE2 = 10000;//同2
154
+ const int TM_FEED = 5000; //給餌時間
155
+ const int TM_WAIT = 1000; //汎用待ち時間
156
+ const int TM_POFF = 500; //電源OFF待ち時間
157
+
158
+ //自明な、プログラムそのままのことはコメントに書かない
159
+
160
+ //DEVICE INSTANCE
161
+ Servo servoFeed; //給餌用サーボ
162
+ Servo servoPwr; //終了時電源スイッチ操作してOFFするサーボ
163
+ LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //lcd(RS,ENABLE,D4,D5,D6,D7)を宣言
164
+
165
+ //valiables
166
+ unsigned long time; //時間測定用時刻保持
167
+ int val = 0; //待ち時間モード保持
168
+ bool feeding = false; //給餌開始かどうか
169
+ String modeStr; //モード表示の文字列
170
+ int feederAngle; //餌箱サーボの角度
171
+ int pwrAngle; //電源制御の角度
172
+
173
+ void setup() {
174
+ Serial.begin(9600) ; // 9600bpsでシリアル通信のポートを開く
175
+ lcd.begin(16, 2); //(桁数,行数)を指定
176
+ pinMode(PIN_BUTTON, INPUT);
177
+ pinMode(10, OUTPUT); //10PIN?
178
+ servoFeed.attach(PIN_servoFeed);
179
+ servoPwr.attach(PIN_servoPwr);
180
+ feederAngle = ANG_CLOSE;
181
+ servoFeed.write(feederAngle);
182
+ pwrAngle = ANG_PON;
183
+ servoPwr.write(pwrAngle);
184
+ }
185
+
186
+ void lcdPrint(String line1, String line2 = "") {
187
+ lcd.clear();
188
+ lcd.print(line1);
189
+ lcd.setCursor(0, 1);
190
+ lcd.print(line2);
191
+ }
192
+
193
+ void loop() {
194
+ if (!feeding) {
195
+ feederAngle = ANG_CLOSE;
196
+ unsigned long tm;
197
+ if (digitalRead(PIN_BUTTON) == HIGH) {
198
+ //ボタンが押されたら
199
+ time = millis(); //時計リセット
200
+ //モード変更
201
+ val = val + 1;
202
+ if (val > 2)
203
+ val = 0;
204
+ //モードの設定
205
+ switch (val) {
206
+ case 0:
207
+ modeStr = "mode select";
208
+ digitalWrite(10, HIGH);//???
209
+ break;
210
+ case 1:
211
+ modeStr = "mode 1";
212
+ tm = TM_MODE1;
213
+ break;
214
+ case 2:
215
+ modeStr = "mode 2";
216
+ tm = TM_MODE2;
217
+ break;
218
+ default:
219
+ break;
220
+ }
221
+ lcdPrint("close", modeStr);
222
+ delay(20);
223
+ //ボタンが離されるのを待つ
224
+ while (digitalRead(PIN_BUTTON) == HIGH) {}
225
+ }
226
+ if ( val != 0 && (millis() - time > tm) ) {
227
+ //時間が来た
228
+ feeding = true;//給餌に遷移
229
+ lcdPrint("open", modeStr);
230
+ time = millis();
231
+ }
232
+ } else {
233
+ //給餌開始
234
+ feederAngle = ANG_FEEDING;
235
+ if (millis() - time > TM_FEED) {
236
+ feederAngle = ANG_CLOSE;
237
+ lcdPrint("end");
238
+ if (millis() - time > TM_FEED + TM_POFF) {
239
+ pwrAngle = ANG_POFF;
240
+ }
241
+ }
242
+ }
243
+ //サーボ制御はここで一括
244
+ servoFeed.write(feederAngle);
245
+ servoPwr.write(pwrAngle);
246
+ }
247
+ ```

2

誤記訂正

2019/10/25 13:59

投稿

thkana
thkana

スコア7735

answer CHANGED
@@ -115,7 +115,7 @@
115
115
  int val = 0; //valはloop()を出ても保存される必要がある
116
116
 
117
117
  void loop() {
118
- if (digitalRead(7) != HIGH) {
118
+ if (digitalRead(7) != LOW) {//LOWと比較するのは私の趣味と思って下さい。一応理由はありますが。
119
119
  time = millis();
120
120
  val = val + 1;
121
121
  if (val > 2)

1

追記

2019/10/22 16:17

投稿

thkana
thkana

スコア7735

answer CHANGED
@@ -86,4 +86,46 @@
86
86
  のようにbreakを入れてやらなければいけません。
87
87
 
88
88
  ---
89
- これぐらい修正すれば動かないかなぁ...(確認していません)
89
+ これぐらい修正すれば動かないかなぁ...(確認していません)
90
+
91
+ ---
92
+ 追記。
93
+ for(;;)を抜ける手段が用意されていなくて「電源を切る」ところに行き着かないので...
94
+ ちょっと格好はよくないですけれど、餌をやり終わったら電源OFF、もcaseの中でやっちゃいましょうか。
95
+ ```Arduino
96
+ case 1:
97
+ servo1.write(105);
98
+ lcd.clear();
99
+ lcd.print("mode 1");
100
+ if(time>5000){
101
+ lcd.clear();
102
+ lcd.print("open");
103
+ servo1.write(50);
104
+ delay(5000);
105
+ lcd.clear();
106
+ lcd.print("end");//このendはほとんど表示される間もなく電源が落ちるかも
107
+ servo2.write(0);//このサーボ動作で電源OFF
108
+ while(1); //念の為、無限ループで動作を止める
109
+ break;
110
+ case 2:
111
+ //同様の変更
112
+ ```
113
+ そうすると、ついでに(?)for(;;)そのものが不要になったりしますけれど。
114
+ ```Arduino
115
+ int val = 0; //valはloop()を出ても保存される必要がある
116
+
117
+ void loop() {
118
+ if (digitalRead(7) != HIGH) {
119
+ time = millis();
120
+ val = val + 1;
121
+ if (val > 2)
122
+ val = 0;
123
+ delay(20);
124
+ while (digitalRead(7) != LOW) {}
125
+ }
126
+ switch (val) {
127
+ //略
128
+ }
129
+ }
130
+ ```
131
+ とか。