工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

作りやすいペットフィーダー

コンポーネントと消耗品

>
Arduino Nano R3
コンパクトなハウジングを使用する場合は、ArduinoNanoを使用するのが最適です
× 1
Adafruitリアルタイムクロック
× 1
連続回転サーボ
× 1
シリアルディスペンサー
× 1
ホールセンサーUNIPOLAR
× 1
ロッドマグネット3mm直径、5mm長
× 6
AdafruitRGBバックライトLCD-16x2
× 1
lcdi2cバックパック
× 1
ApemプッシュボタンモーメンタリIP67
× 1
瞬間的な小さな押しボタン
× 1
LED(汎用)
× 6
フランジ付きハモンドマルチABSハウジング
× 1

アプリとオンラインサービス

LCD文字ジェネレーター

このプロジェクトについて

更新2018-09-06

私の2匹のペットフィーダーは過去7ヶ月間完璧に働いています。もちろん日中はペットの世話をしますが、今では定期的に餌をもらっています。システムにとても満足しています!

なぜ別のペットフィーダー?

私のバージョンのペットフィーダーは、Arduinoマイクロコントローラーに基づいています。使用する材料は比較的安価で、簡単に作れると思います!

もちろん、周りにはたくさんのバージョンがありますが、必要な機能を備えたビルドの準備ができている完全なプロジェクトを見つけることができなかったので、最初から始めました。

機能は次のとおりです。

  • *正確な部分*が毎回配信されます! (ホールセンサーを使用)
  • 1日2回の給餌
  • *非常に*正確なリアルタイムクロック(純正のDS3231チップのみ)
  • ディスプレイとLEDインジケーターを備えた両方のタイマーについて、今後の給餌を個別にキャンセルできます。キャンセルは、設定した時間が経過すると自動的にリセットされます。
  • 手差し機能(ボタンを押すごとに1つの部分)
  • 2回の給餌時間のそれぞれに調整可能な部分(1〜9部分)
  • メイン画面で設定されたすべてのパラメータの概要
  • メニューシステムの操作が簡単
  • 給餌が成功したかどうかのLED表示
  • LCDバックライトタイマー(30秒後にオフ、ボタンを押すとオン)
  • 時間やその他の設定はメモリ(EEPROM)に安全に保存されます

デモンストレーションビデオ:

ビデオについては、ここをクリックしてください

より詳細な説明ビデオ:ここをクリック

スローモーションでペットフィーダー!こちらをクリック

写真:

<図> <図>

必要な部品:

  • 1xシリアルディスペンサー(Ebayで安い)
  • シリアルディスペンサーマウントを構築するためのいくつかの(スクラップ)木材
  • 1x Arduino Uno
  • 1x I2C DS3231(非常に正確)またはDS1307リアルタイムクロック
  • 1xLCDディスプレイ16文字/ 2行
  • LCDディスプレイ用の1xI2Cバックパック
  • 1xローテーションサーボを継続します(良いものを購入してください!)
  • 1xハネウェルSS443Rユニポーラホールセンサー
  • 1x 12Volts / 1 Amp外部電源(ACアダプタ)
  • 7xプッシュボタン-モーメンタリ
  • 6x LED(2x RED、3x GREEN、1 YELLOW)
  • 2x抵抗1KΩ(赤いLED用)
  • 4x抵抗560Ω(緑と黄色のLED用)
  • 電子機器用の1xエンクロージャー
  • 外部サーボとホールセンサーを接続するための電源プラグメスとコネクタ
  • たくさんのホットグルー。

可能であれば、サーボにはより高い電圧を使用するのが最善です。もっと力を!私のHSR-2645CRHサーボは7.4ボルトかかる可能性があるので、これも実行したい場合は、次のものが必要です。

  • パフォーマンスボード
  • LM317T可変電圧レギュレータ
  • 出力電圧を設定するための3つの抵抗(1KΩ、150kΩ、4K7)
  • 2つの分極コンデンサ(220µF、10µF)
  • ヒートシンクは不要です。サーボは毎日1〜2秒だけ回転します;)
<図>

オンラインでは、多くのLM317計算機を見つけることができます。

ペット飼料容器

最も安くて最も使いやすいのは、多くの店やイーベイで見つけることができるシリアルディスペンサーです。 Ebayでデュアルシリアルディスペンサーを15ユーロで購入しました(英国からオランダへ)

<図>

課題はフィーダー用のマウントを作ることでしたが、インターネットで見回してもあまり役に立たなかったので、小屋を見て回ると、美しい杉の木片が見つかりました。

プラスチック製のシリアルディスペンサーを保持している木材は3cmの厚さなので、ぐらつくことはありません!穴(私のフィーダーベースは86mm)がしっかりしていることを確認する必要があるので、ドリルする前に測定してください!大きすぎる穴よりも小さな穴を開けて少し形を整える方が良いでしょう。

写真を見て、なぜ、どのように組み合わせるのかを理解してください。

<図> <図> <図> <図> <図> <図> <図> <図> <図> <図> <図> <図> <図> <図> <図> <図> <図>

サーボとディスペンサーパドルホイールへの取り付け

必ず良いサーボを購入してください。最初にMG996Rサーボを購入しましたが、これを連続回転用に変更しましたが、それはお金の無駄でした...次に、高品質のサーボ、私の場合はHSR-2645CRHサーボを入手しました

連続回転モデルでなければなりません!!私が行ったように通常のサーボを変更しようとしないでください。パフォーマンスは十分ではなく、停止したときはすぐには実行されませんでした。

サーボトライアルのビデオ:ここをクリック

ディスペンサーパドルホイールへのサーボ接続

さて、質問は次のとおりです。サーボをフィーダーパドルホイールに接続する方法は?最初はプロジェクトの最も難しい部分のように見えましたが、実際には非常に単純でした。

私は5mmのポリカーボネートを1枚取り、フレットソーで約6cmの丸いディスクを切り取りました。中央に8mm(フィーダー軸の厚さ。このプラスチック軸は外輪から取り外し可能)の穴を開けました。

<図>

外側に磁石の厚さ3mmの穴を6つ開けます。これらは、フィーダーペドルホイールの位置に関するArduinoフィードバックを提供するために使用されます。

<図>

パドルホイールには6つのゴム製パドルがあったので、6つの磁石を使用して、ポリカーボネートディスクの端の周りでそれらを分割しました。 360度を6で割ると60度になります。ロッドマグネットがぴったりとはまります。

ホールセンサーは6つの磁石のそれぞれを検出するため、その情報を使用してパドルホイールを正確に配置および停止できます。サーボ停止遅延時間変数は、の遅延を追加するために使用されます 給餌、停止する前 サーボ。したがって、この遅延により、パドルホイールの正確な位置を微調整できます。 「停止」位置が間違っていると、フィードがパドルホイールから完全に出ないため、これは重要です。また、ホールセンサーの位置が異なる場合があります。サーボ停止遅延可変時間を微調整すると、これが解決されます。

<図>

これで、パドルホイールの軸をポリカーボネートディスクに接着できます。

<図> <図> <図> <図>

白い丸いサーボホーンは、3本のM3ボルトでポリカーボネートディスクにボルトで固定されています。スペーサーとしていくつかの余分なナットを使用し、締めすぎないでください!

<図> <図> <図>

これでサーボがフィーダーアセンブリの一部になっているので、それを木製の台紙に入れて、サーボの下にある木片の高さを測定できます。

<図> <図> <図>

ホールセンサー

私が使用したホールセンサーはUNIPOLARタイプです。磁石が近くにあり、出力を再びHIGHにリセットするために磁石の逆極性を必要としない場合、LOW出力を提供します。したがって、ユニポーラホールセンサーを使用すると、はるかに簡単になります。

<コード> !!!ホールセンサーには10KΩのプルアップ抵抗が必要です。

私はホールセンサーの真上に0805SMD抵抗器を取り付けましたが、あなたはそれを自分のやり方で行うことができます。この抵抗器を忘れないでください!

次に、古いボールペンを取り、センサーのホルダーとしてプラスチックを使用しました。

<図> <図> <図>

エレクトロニクスハウジング

フランジ付きのハモンドABSハウジングを使用しました。 120 x 65 x 40 mm

<図> <図> <図> <図> <図> <図>

外部接続には、安価な中国製のコネクタではなく、メスの精密ソケットコネクタを使用しました。私はすべてのプロジェクトでこれらをよく使用します。接続不良が原因で(見つけるのが難しい)失敗することほど悪いことはありません。

<図> <図> <図> <図> <図> <図> <図> <図> <図> <図> <図> <図>

Arduinoのプログラミングを簡単にするために、外部FTDI接続があります:

<図> <図>

フロントパネル

安くて見栄えの良いフロントパネルを作るためにたくさんの方法を試しました...

まず、Mod Podgeを使用して、ハウジングの前面に紙のレーザープリントを接着し、さらにModPodgeで覆いました。 ->失敗

次に、アクリル酸ポリウレタン分散液をベースにした透明なワニスを試しました。非常に耐久性があり、乾燥すると丈夫です。紙をハウジングにしっかりと接着し、フロントパネルプリントの上面にニスを塗ると非常に見栄えがしましたが、プリントのレーザープリンターのトナー部分には付着しませんでした。 ->失敗

その後、フロントパネルのレーザープリントを取り、ラミネートPCVでトップのみをラミネートしました。とても素敵な仕上がりで、フロントを保護し、色を美しく持ち上げます。次に、ラミネート紙をワニスでハウジングに接着しました。私の考えは、ニスが紙に浸透して耐水性になるというものでした。しかし、機能しない厚紙を使用し、耐水性をテストするために湿らせたため、紙がハウジングから丸まってしまいました。 -> PARTLY FAIL、さらに調査する必要があります。

別の試み:レーザー印刷用に作られた特別なアルミホイルを購入しました。 1枚あたり2.25ユーロ。結果は素晴らしかったですが、私は特別な透明なホイルでトナーを保護したかったのです。写真1に見られるような欠陥を取り除くことができなかったので、それは成功ではありませんでした:

<図>

その後、透明なニスで保護するための別の試み、それはアルミホイルを非常に高い光沢にしました!しかし...繰り返しになりますが、ニスがトナーに付着しないため、ニスを永久に放棄しました...

最後に...私は保護なしでホイルプリントを使用しました...頻繁に扱うとビンガープリントが表示されます(このページの上部にある写真の[戻る]ボタンの下を見て、鶏の餌に入れてください)ので、理想的ではありませんが、それでも良いです私には十分です。

これ以上の写真は許可されていないようです...

それはすべての人々です... 持っている 楽しい!

コード

  • ペットフィード-O-Maticv 1.1-20-02-2018
Pet Feed-O-Matic v 1.1-20-02-2018 Arduino
v 1.1:キャンセル1または2ボタンを押すと、説明が表示されます
 // c ++のもの... //#include  //#line 1 //#line 1 "/ Users / Erik / Documents / PlatformIO / Projects / 180202-151127-uno / src / Pet_Feeder_1_1_ENG.cpp "/ * _ _ / \ | | (_)/ \ _ __ __ | | _ _ _ _ __ ___ / / \ \ | '__ / _` | | | | | '_ \ / _ \ / ____ \ | | | (_ | | | _ | | | | | |(_)| / _ / \ _ \ _ | \ __、_ | \ __、_ | _ | _ | | _ | \ ___ / _____ _ ______ _ | __ \ | | | ____ | | | | | __)| __ | | _ | | __ ___ ___ __ | | ___ _ __ | ___ / _ \ __ | | __ / _ \ / _ \ / _` | / _ \ '__ | | | | __ / | _ | | | __ / __ /(_ | | __ / | | _ | \ ___ | \ __ | | _ | \ ___ | \ ___ | \ __、_ | \ ___ | _ | Erik de Ruiter -------- -------------------------------------------------- -------------------実行方法:-リモートフィード?-メニュー編集可能アイテムの最終変更としてのフィーダー停止遅延:dinsdag 20 februari 2018-17:20:28機能:- *毎回正確な分量*(ホールセンサーを使用)-1日1回2回の給餌-*非常に*正確なリアルタイムクロック(純正のDS3231チップのみ)-ディスプレイとLEDインジケーター付きの両方のタイマーの今後の給餌を個別にキャンセル。時間が経過すると自動的にリセットされます。-手差し機能(ボタンを押すごとに1つの部分)-2つの送り時間ごとに調整可能な部分(1〜9の部分)-メイン画面で設定されたすべてのパラメータの概要-ナビゲートしやすいメニューシステム-フィードが成功した場合のLED表示-LCDバックライトタイマー(30秒後にオフ、ボタンを押すとオン)-ホールセンサーに障害が発生した場合のバックアップ-Hass senホールセンサーが故障した場合、sor LEDは深夜まで点滅します-時間とその他の設定はEEPROM WEBSITESに安全に保存されます:LCDHD44780キャラクタージェネレーターWebサイトで独自の液晶シンボルを作成https://omerk.github.io/lcdchargen/Arduino Sketch Largeレターコメントジェネレーターhttp://patorjk.com/software/taag/#p=display&c=c%2B%2B&f=Big&t=CommentRevisions:zondag 28 januari 2018-20:17:10 * //////// ////////////////////////////////////////////////// /////////////////////////ユーザー変更可能な変数////////////////////// ////////////////////////////////////////////////// //////////ホールセンサーの故障バックアップ機能に使用されます。//間隔時間は1つの60度よりもいくらか長くする必要があります//フィーダーの回転(一部)#define HALL_SENSOR_BACKUP_VALUE 300 //遅延前フィード後にフィーダーサーボを停止します。このようにして、回転するペドルホイールを正しい位置で停止させることができます。 MENU_TIMEOUT_VALUE 7000 //////////////////////////////////////////////// ////////////////////////////////// https:// github.com/fdebrabander/Arduino-LiquidCrystal-I2C- library#include  // https:// github.com/JChristensen/Button#include  // http:// github.com/JChristensen/DS3232RTC#include  // http:// www.arduino.cc/playground/Code/Time#include  // http:// arduino.cc/en/Reference/Wire(Arduino IDEに含まれています)#include  #include  //接続://// LCD(I2Cモジュール):// SCL-A5 // SDA-A4 // VCC // GND //割り込みホールセンサーピン#defineHALL_SENSOR_PIN 3#define BUTTON_BACK_PIN 4#define BUTTON_UP_PIN 5#define BUTTON_DOWN_PIN 6#define BUTTON_SELECT_PIN 7#define B UTTON_CANCEL1_PIN 8#define BUTTON_CANCEL2_PIN 9#define BUTTON_MANUAL_PIN 10#define LED_CANCEL1_PIN A0#define LED_CANCEL2_PIN A1#define LED_SUCCESS1_PIN A2#define LED_SUCCESS1_PIN A2#define LED_SUCCESS2_PIN A3 //フィーダーサーボ出力Pin#def (16x2)0x27または0x3FLiquidCrystal_I2C lcd(0x3F、16、2); //ボタンライブラリ設定の定義//通常は20ミリ秒のデバウンス時間が適切に機能します//触覚ボタンスイッチの場合。 long press#define REPEAT_FIRST 1000 //長押しの繰り返し間隔#defineREPEAT_INCR 200 //簡単にするために、Arduinoの内部プルアップ抵抗を使用します。#definePULLUP true#define INVERT true //ボタンを宣言しますButtonbuttonSelect(BUTTON_SELECT_PIN、PULLUP 、INVERT、DEBOUNCE_MS);ボタンbuttonUp(BUTTON_UP_PIN、PULLUP、INVERT、DEBOUNCE_MS);ボタンbuttonDown(BUTTON_DOWN_PIN、PULLUP、INVERT、DEBOUNCE_MS);ボタンがtonBack(BUTTON_BACK_PIN、PULLUP、INVERT、DEBOUNCE_MS);ボタンbuttonCancel1(BUTTON_CANCEL1_PIN、PULLUP、INVERT、DEBOUNCE_MS);ボタンbuttonCancel2(BUTTON_CANCEL2_PIN、PULLUP、INVERT、DEBOUNCE_MS);ボタンbuttonManual(BUTTON_調整される数値intcount; //以前のcountの値(スケッチの開始時に異なることを確認するために初期化されます)int lastCount =-1; //長押しの繰り返しを駆動するために使用される可変時間unsignedlong rpt =REPEAT_FIRST; //メニューのタイムアウトに使用-outunsignedlong timeoutValue =0; //手動キャンセルフィード時間変数booleanmanualCancelFeed1 =false; boolean manualCancelFeed2 =false; //手動フィードオプションbooleanmanualFeed =false; //フィード量(部分)intfeedAmount1 =1; int feedAmount2 =1; boolfeederSuccess =false; //フィーダー部分int部分=0; intターン=0; //入力actionsenum {btnSELECT、btnUP、btnDOWN、btnBACK、btnCANCEL1、btnCANCEL2、btnMANUAL、trigTIMEOUT}; //州有限状態機械(FSM)列挙STATES {MAIN、MENU_EDIT_FEEDTIME1、MENU_EDIT_FEEDTIME2、MENU_EDIT_FEEDAMOUNT、MENU_EDIT_TIME、MENU_EDIT_DATE、MENU_EDIT_SETTINGS、EDIT_FEED_TIME1_HOUR、EDIT_FEED_TIME1_MINUTE、EDIT_FEED_TIME1_ON_OFF、EDIT_FEED_TIME2_HOUR、EDIT_FEED_TIME2_MINUTE、EDIT_FEED_TIME2_ON_OFF、EDIT_FEED_AMOUNT1、EDIT_FEED_AMOUNT2、EDIT_HOUR、EDIT_MINUTE、EDIT_DAY、EDIT_MONTHのS-、 EDIT_YEAR、EDIT_SERVO_STOP_DELAY、EDIT_SERVO_BACKUP_DELAY、}; // systemSTATES状態の現在の状態を保持します; int8_tuserInput; int8_t trigger; int Second; int Minute; int Hour; int Day; int Month; int Year; int8_t DoW; String day_of_week; unsigned char address、data; int testt =0; int feed_time1_hour; int feed_time1_minute; bool feed_time1_active =false; bool alarm1Activated =false; int feed_time2_hour; int feed_time2_minute; bool feed_time2_active =false; bool alarm2Activated =false; //点滅機能に使用される場合値の編集uint32_tblink_interval =500; uint32_tblink_previousMil lis =0; uint32_t flash_currentMillis =0; boolean flash_state =false; //値を編集するときに点滅機能に使用uint32_tspinningWheel_interval =170; uint32_t spiningWheel_previousMillis =0; uint32_t spiningWheel_currentMillis =0; int spiningWheelSymbol =0バックアップ機能の失敗//間隔時間は、フィーダーの60度の回転(一部)よりもいくらか大きくする必要があります。uint32_thallSensorBackup_interval=HALL_SENSOR_BACKUP_VALUE; uint32_t hallSensorBackup_currentMillis =0; boolean hallSensorFail =false; // lcdバックライト時間に使用lcdBacklight_interval =LCD_BACKLIGHT_ON_TIME; uint32_t lcdBacklight_currentMillis =0; boolean RTC_error =true; boolean long_press_button =false; // LCDディスプレイのカスタムシンボルを定義bytebell_symbol_Char [8] ={B00100、B01110、B01110、B01110、B11111; byte reverse_one_Char [8] ={0b11111、0b11011、0b10011、0b11011、0b11011、0b11011、0b10001、0b11111}; by te reverse_two_Char [8] ={0b11111、0b11011、0b10101、0b11101、0b11011、0b10111、0b10001、0b11111}; byte arrow_up_Char [8] ={0b00100、0b01110、0b11111、0b01110、0b01110、0b01110、0b01 [8] ={0b00000、0b01110、0b01110、0b01110、0b01110、0b11111、0b01110、0b00100};バイトinverted_p_Char [8] ={0b11111、0b10001、0b10101、0b10001、0b10111、0b10111、0b11111、0b00000};バイトバック] ={0b00000、0b10000、0b01000、0b00100、0b00010、0b00001、0b00000、0b00000};バイトthickDash_Char [8] ={0b00000、0b00000、0b11111、0b11111、0b11111、0b00000、0b00000、0b00000};揮発性ブールホールセンサー//割り込み1voidHallSensorIsr(){hallSensorActivated =true; //ホールセンサーLEDをオンにしますdigitalWrite(LED_HALL_SENSOR_PIN、HIGH);} //このスケッチをC ++ファイルにするためにこれらの行が必要です。//Atom//テキストエディターとPlatformIOaddでコードを編集するために使用します-onvoid HallSensorIsr(); void setup(); void loop(); void change_states(); void check_inputs(); void transition(int trigger); void check_alarm(); void check_manual_feed(); void display_menu_option_set_feedtime1(); void display_menu_option_set_feedtime2 (); void display_menu_option_set_feed_amount(); void display_menu_option_set_time(); void display_menu_option_set_date(); void midnight_reset(); void display_time(); void displayFeedingAmouts(); void displayFeedingTimes(); void set_feedAmount(); void set_time(); void set_date (); void set_feeding1_time(); void set_feeding2_time(); void get_time(); void get_date(); void write_time(); void write_date(); void write_feeding_time1(); void write_feeding_time2(); void write_feedamount(); void get_feedamount (); void get_feed_time1(); void get_feed_time2(); void check_RTC( ); byte decToBcd(byte val); byte bcdToDec(byte val); void Leading_zero(int Digits); void brightFunction(); void displaySpinningWheel(); void startFeederServo(); void stopFeederServo(); void activateFeeder(int部分); void check_LcdBacklight(); void lcd_backlight_ON(); void ledsAndLcdDisplayStartup(); void hallSensorCheck();#line 355 // ************************* ************************************************** *** // SETUPvoid setup(){//液晶画面をアクティブにしますlcd.begin(); // lcdバックライトをオンにして、バックライトをオフにします-タイマーlcd_backlight_ON(); // I2C Wire.begin();を開始します//フィーダーの回転を検出するためのホールセンサー入力/送り量出力チェックpinMode(HALL_SENSOR_PIN、INPUT_PULLUP); pinMode(LED_HALL_SENSOR_PIN、OUTPUT); pinMode(SERVO_OUTPUT_PIN、OUTPUT); pinMode(LED_CANCEL1_PIN、OUTPUT); pinMode(LED_CANCEL2_PIN、OUTPUT); pinMode(LED_SUCCESS1_PIN、OUTPUT); pinMode(LED_SUCCESS2_PIN、OUTPUT); // LEDのデフォルト状態をOFFに設定digitalWrite(LED_CANCEL1_PIN、LOW); digitalWrite(LED_CANCEL2_PIN、LOW); digitalWrite(LED_SUCCESS1_PIN、LOW); digitalWrite(LED_SUCCESS2_PIN、LOW); digitalWrite(LED_HALL_SENSOR_PIN、LOW); lcd.createChar(0、thickDash_Char); lcd.createChar(1、bell_symbol_Char); lcd.createChar(2、backslash_Char); lcd.createChar(3、inverted_p_Char); lcd.createChar(4、inverted_one_Char); lcd.createChar(5、inverted_two_Char); lcd.createChar(6、arrow_up_Char); lcd.createChar(7、arrow_down_Char); //フィーダーサーボをデフォルト状態に設定OFFstopFeederServo(); Wire.begin(); // RTCをSyncproviderとして設定しますsetSyncProvider(RTC.get); // RTCとの再同期の秒単位の時間setSyncInterval(60); // SQWピンのデフォルトの方形波を無効にします。 RTC.squareWave(SQWAVE_NONE); //ホールセンサーに割り込みをアタッチします(出力がLOWになるとき)//フィーダーシャフトが60度回転するたびに、ホールセンサーは//割り込みを生成する必要がありますattachInterrupt(INT1、HallSensorIsr、FALLING); //テストledsAndLcdDisplayStartup();を表示します// FSM状態の初期状態=MAIN; // Arduinoメモリから保存されたアラーム値を読み取りますget_feed_time1(); get_feed_time2();}// End SETUP// ******************************************************************************// LOOPvoid loop(){ // change states of FSM change_states(); // check inputs (buttons) check_inputs(); // check if alarm was called check_alarm(); // check if manual feed was requsted check_manual_feed(); // at midnight, reset some variables midnight_reset(); // check connection RTC check_RTC(); // Check the Hall sensor function hallSensorCheck(); // check if lcd backlight must be turned off check_LcdBacklight();}// End of LOOP// ******************************************************************************// ******************************************************************************// ******************************************************************************// ******************************************************************************//******************************************************************************// Finite State Machinevoid change_states(){ // states switch (state) { //--------------------------------------- case MAIN:display_time(); displayFeedingAmouts(); displayFeedingTimes();壊す; //--------------------------------------- case MENU_EDIT_FEEDTIME1:display_menu_option_set_feedtime1();壊す; //--------------------------------------- case MENU_EDIT_FEEDTIME2:display_menu_option_set_feedtime2();壊す; //--------------------------------------- case MENU_EDIT_FEEDAMOUNT:display_menu_option_set_feed_amount();壊す; //--------------------------------------- case MENU_EDIT_TIME:display_menu_option_set_time();壊す; //--------------------------------------- case MENU_EDIT_DATE:display_menu_option_set_date();壊す; //--------------------------------------- case EDIT_FEED_TIME1_HOUR:set_feeding1_time();壊す; //--------------------------------------- case EDIT_FEED_TIME1_MINUTE:set_feeding1_time();壊す; //--------------------------------------- case EDIT_FEED_TIME1_ON_OFF:set_feeding1_time();壊す; //--------------------------------------- case EDIT_FEED_TIME2_HOUR:set_feeding2_time();壊す; //--------------------------------------- case EDIT_FEED_TIME2_MINUTE:set_feeding2_time();壊す; //--------------------------------------- case EDIT_FEED_TIME2_ON_OFF:set_feeding2_time();壊す; //--------------------------------------- case EDIT_FEED_AMOUNT1:set_feedAmount();壊す; //--------------------------------------- case EDIT_FEED_AMOUNT2:set_feedAmount();壊す; //--------------------------------------- case EDIT_HOUR:set_time();壊す; //--------------------------------------- case EDIT_MINUTE:set_time();壊す; //--------------------------------------- case EDIT_DAY:set_date();壊す; //--------------------------------------- case EDIT_MONTH:set_date();壊す; //--------------------------------------- case EDIT_YEAR:set_date();壊す; //--------------------------------------- }}//******************************************************************************// Check INPUTSvoid check_inputs(){ // first check if timeout has occurred if ( millis() - timeoutValue> MENU_TIMEOUT_VALUE ) { userInput =trigTIMEOUT; transition(userInput); } // check state of buttons buttonSelect.read(); buttonUp.read(); buttonDown.read(); buttonBack.read(); buttonManual.read(); buttonCancel1.read(); buttonCancel2.read(); // check manual cancel Feed1 button switch (buttonCancel1.wasPressed()) { case 1:// invert variable value (true to false and vise versa) manualCancelFeed1 =!manualCancelFeed1; //turn on lcd backlight manually lcd_backlight_ON(); // message when Cancel1 button is pressed if (manualCancelFeed1 ==1) { lcd.clear(); lcd.setCursor(0、0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #1"); lcd.setCursor(0、1); lcd.print("cancelled once "); delay(2000); lcd.clear(); } else if (manualCancelFeed1 ==0) { lcd.clear(); lcd.setCursor(0、0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #1"); lcd.setCursor(0、1); lcd.print("canceling undone"); delay(2000); lcd.clear(); } 壊す; } // check manual cancel Feed2 button switch (buttonCancel2.wasPressed()) { case 1:// invert variable value (true to false and vise versa) manualCancelFeed2 =!manualCancelFeed2; //turn on lcd backlight manually lcd_backlight_ON(); // message when Cancel1 button is pressed if (manualCancelFeed2 ==1) { lcd.clear(); lcd.setCursor(0、0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #2"); lcd.setCursor(0、1); lcd.print("cancelled once "); delay(2000); lcd.clear(); } else if (manualCancelFeed2 ==0) { lcd.clear(); lcd.setCursor(0、0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #2"); lcd.setCursor(0、1); lcd.print("canceling undone"); delay(2000); lcd.clear(); } 壊す; } // check manual Feed button switch (buttonManual.wasPressed()) { case 1:manualFeed =true; //turn on lcd backlight manually lcd_backlight_ON();壊す; } // check MENU/SELECT button switch (buttonSelect.wasPressed()) { case 1:userInput =btnSELECT; //turn on lcd backlight manually lcd_backlight_ON(); transition(userInput);壊す; } // check UP button switch (buttonUp.wasPressed()) { case 1:userInput =btnUP; transition(userInput); //turn on lcd backlight manually lcd_backlight_ON();壊す; } // check long press UP button switch (buttonUp.wasReleased()) { case 1:long_press_button =false; rpt =REPEAT_FIRST;壊す; } switch (buttonUp.pressedFor(rpt)) { case 1:// increment the long press interval rpt +=REPEAT_INCR; long_press_button =true; userInput =btnUP; transition(userInput);壊す; } // check DOWN button switch (buttonDown.wasPressed()) { case 1:userInput =btnDOWN; transition(userInput); //turn on lcd backlight manually lcd_backlight_ON();壊す; } // check long press DOWN button switch (buttonDown.wasReleased()) { case 1:long_press_button =false; rpt =REPEAT_FIRST;壊す; } switch (buttonDown.pressedFor(rpt)) { case 1:// increment the long press interval rpt +=REPEAT_INCR; long_press_button =true; userInput =btnDOWN; transition(userInput);壊す; } // check btnBACK button switch (buttonBack.wasPressed()) { case 1:userInput =btnBACK; transition(userInput); //turn on lcd backlight manually lcd_backlight_ON();壊す; }}//******************************************************************************// Check for state transition triggervoid transition(int trigger){ switch (state) { //--------------------------------------- case MAIN:// set time-out timr timeoutValue =millis(); if (trigger ==btnSELECT) { lcd.clear(); state =MENU_EDIT_FEEDTIME1; } else if (trigger ==btnBACK) { //lcd.clear(); //state =ALARM1_AND_2_TIME; } 壊す; //--------------------------------------- case MENU_EDIT_FEEDTIME1:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { //no action, this is the first menu } else if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_FEEDTIME2; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_FEED_TIME1_HOUR; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } 壊す; //--------------------------------------- case MENU_EDIT_FEEDTIME2:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_FEEDTIME1; } else if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_FEEDAMOUNT; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_FEED_TIME2_HOUR; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } 壊す; //--------------------------------------- case MENU_EDIT_FEEDAMOUNT:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_FEEDTIME2; } else if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_TIME; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_FEED_AMOUNT1; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } 壊す; //--------------------------------------- case MENU_EDIT_TIME:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_FEEDTIME2; } if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_DATE; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_HOUR; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } 壊す; //--------------------------------------- case MENU_EDIT_DATE:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_TIME; } else if (trigger ==btnDOWN) { //no action, end of menu items! } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_DAY; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } 壊す; //--------------------------------------- case EDIT_FEED_TIME1_HOUR:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers...This file has been truncated, please download it to see its full contents.

回路図

Arduino based Pet Feeder I used Arduino IDE 1.8.2. BE CAREFUL NOT TO HAVE TWO VERSIONS OF THE SAME LIBRARIES IN YOUR LIBRARIES FOLDER!! arduino_pet_feeder_final_eng_v1_0-ino_hex_libraries_dsoo0HscCr.zip

製造プロセス

  1. ペットフード
  2. Arduino Nano RP2040を使用したDIYPhotoshop編集コンソール
  3. Arduino Spybot
  4. 花-ArduinoNano、CrazyCircuits、DFRobot
  5. 自家製16x8マトリックス上のArduinoNanoTetr​​isゲーム
  6. Arduinoたまごっちクローン-デジタルペット
  7. Arduino Nano:ジョイスティックで2つのステッピングモーターを制御
  8. リモコンペットフィーダー
  9. ArduinoNanoを搭載したハンドヘルドガイガーカウンター
  10. ArduinoNano用TFTシールド-開始
  11. 3Dプリントパーツを備えたペットフィーダー