Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Pilot Otomatis untuk Kapal Layar (Sistem Kemudi Otomatis)

Komponen dan persediaan

Arduino UNO
× 1
Arduino Nano R3
× 1

Tentang proyek ini

Kata Pengantar:

Saya suka berlayar sendirian karena ketika seorang pria berada di laut dengan perahu layarnya, dia mendapatkan semua yang dia butuhkan untuk berkembang ke tingkat yang lebih tinggi. Berlayar di laut mentah dengan cuaca buruk bisa sangat sulit tetapi jika dia memilih hari dengan cuaca yang baik dengan matahari dan angin yang bagus, kenikmatannya akan maksimal.

Kebahagiaan berarti cakrawala yang tak terbatas, teknik atletik yang sempurna, pilihan yang optimal, tetapi juga hal-hal manusia sebagai minuman yang baik dan sandwich yang lezat! Tepat saat ini datang bantuan Autopilot:ia bekerja sebagai pengganti Anda sementara Anda memiliki teh &biskuit pukul 17:00 di laut. :-)

Apa yang dapat dilakukan Autopilot untuk Anda:

Kapal layar tidak memiliki mesin dan tidak dapat mengikuti jalur terprogram dari pelabuhan ke pantai, lalu ke tempat pemancingan, memutari Mercusuar dan kembali, semuanya sendiri tidak bisa.

Seluruh pekerjaan dilakukan oleh Pelaut, kita harus memahaminya pada titik ini:memotong layar, mengendalikan cuaca dan sumber/kecepatan angin, mengeraskan atau melepaskan tali, memikirkan lalu lintas dengan kapal lain, memutuskan arah dan kemudi... Kapan Pelaut memutuskan untuk istirahat, katakanlah hanya 10 detik atau beberapa menit ("waktu minum teh" yang terkenal), dia mengaktifkan Autopilot. Dalam hitungan detik GPS-nya memperoleh posisi, kecepatan dan arah perahu serta mampu menjaga arah (rute). Sistem kemudi, tongkat yang dihubungkan ke kemudi, biasanya digerakkan oleh tangan-tangan ahli pelaut, sekarang dikendalikan oleh Autopilot melalui Motor Stepper yang dihubungkan dengan katrol dan tali.

Kontrol kemudi adalah pekerjaan penyetelan halus atau kasar yang terus menerus. Semakin kecil (ringan) kapal dan semakin besar perubahan arah faktor yang mempengaruhinya:gelombang laut, arah dan tekanan angin, pergeseran berat kapal oleh gerakan Pelaut, arus laut. Tapi Pelaut selalu terjaga, bahkan dengan autopilot aktif, membuat perubahan pada rute sebenarnya dengan remote control :ada 4 tombol di atasnya, berlabel +1 -1 +10 -10, untuk perubahan derajat kecil atau besar, menambah atau mengurangi nilainya. Tombol ini ada di Autopilot juga, yang hijau (kanan) dan merah (kiri). Tombol biru (tengah) untuk mengaktifkan atau menonaktifkan Autopilot, jeda. Ini juga merupakan tombol hitam untuk menyiapkan parameter dalam memori.

Sirkuit:

Pemrosesan utama dilakukan oleh MCU Arduino Uno . MCU lainnya, Arduino Nano , adalah pengawas:Saya tahu itu memang ada semacam pengawas di dalam Uno tetapi saya suka melakukannya dengan mikrokontroler eksternal dan independen, itu adalah mimpi seumur hidup yang saya tutupi, saya bahagia sekarang! Uno harus memberi makan Nano dengan cara pin 3 -> A0 menempatkannya tinggi/rendah, 5/0 volt, setidaknya satu kali setiap 2,5 detik (feedingInterval); jika tidak, berarti Uno sedang "tidur" atau "terblokir", dan Nano me-reset Uno... Belum pernah terjadi, percayakah?

Ini digunakan sebagai tampilan populer dalam hubungannya dengan konverter sirkuit i2c keduanya disolder bersama, akhirnya hanya menggunakan 4 kabel untuk menghemat pin digital secara signifikan untuk berkomunikasi dengan Uno. Juga cara menghubungkan tombol dan kendali jarak jauh dilakukan oleh pembagi tegangan resistansi untuk mencapai tujuan menggunakan port MCU sesedikit mungkin; Saya memilih resistor presisi 1%, nilai perbandingan analog harus antara nilai yang saya masukkan ke dalam kode; jika tidak ada tombol yang dikenali karena Anda memilih jenis resistor lain, cukup buat beberapa perubahan pada konstanta juga (modifikasi kode di "checkRfRC()" dan "checkHWButtons()"). Rangkaian Remote Control (RC) RF 433Mhz bekerja dengan baik; untuk meningkatkan jangkauan jarak dan peluang keberhasilan, saya menambahkan antena koil yang dapat Anda buat sendiri dengan sepotong kawat tembaga; Saya mengujinya pada jarak 10 meter tetapi saya pikir itu dapat bekerja bahkan pada jarak 20 meter atau lebih, lebih dari cukup mengingat kapal layar target yang saya gunakan untuk menguji Autopilot hanya sepanjang 4,20 meter.

Untuk unit GPS Saya awalnya menggunakan EM406A yang bagus tapi sayangnya saya menemukan itu menderita Week-Rollover-Bug, itu terlalu tua, maka saya harus mengubahnya dengan Beitian BN-220T yang sangat baik dan populer. Dengan perangkat lunak konfigurasinya, harap setel ke "spit" 2 kali per detik (2Hz) hanya perlu kalimat serial NMEA "$GNRMC". GPS mengirimkan data serial (TX) ke pin 0 (RX) dari Uno. Data tersebut berisi semua data navigasi yang digunakan untuk menghitung koreksi yang harus dilakukan oleh Motor:tanggal, waktu, posisi lintang dan bujur, jalur sebenarnya, kecepatan dan validitas penetapan satelit. Karena pemrograman IDE Arduino menggunakan port pin 0 (RX), ingatlah untuk memutuskan sementara GPS selama operasi ini...

Mimpi saya yang lain adalah menggunakan EEPROM . IC 2404 adalah sirkuit terintegrasi i2c 512 byte yang indah. Saya biasa membaca/menulis dalam chip memori ini beberapa parameter untuk pergerakan Motor Stepper yang akan saya jelaskan nanti di bawah paragraf "Perangkat Lunak".

Daftar Komponen:

  • Arduino Uno sebagai MCU
  • Arduino Nano sebagai WatchDog
  • GPS BN-220T Beitian
  • Motor Stepper, model 23LM, 54 langkah =1/4 putaran
  • Kunci Kontroler L298 untuk motor
  • RF433Mhz RC XD-YK04 + 4 tombol remote control + antena koil
  • 6 Tombol terbuka normal (2xMerah, 2xHijau, 1xHitam, dan 1xBiru)
  • Mengaktifkan/menonaktifkan daya (Putih)
  • Konektor bulat 6 pin Wanita + Pria untuk Motor Stepper eksternal
  • Buzzer
  • Menampilkan LCD1602 2x16 karakter + rangkaian konverter i2c
  • 3 LED (merah, biru dan kuning))
  • IC 24c04 i2c eeprom
  • Multiplexer IC 4051
  • Baterai LiPo 2s 7.4v 2600mA
  • Pengatur tegangan IC 7805 + peredam panas
  • Termistor NTC MF52-103 10k
  • Sekering 2A yang Dapat Disetel Ulang
  • 6x 1N4148 dioda (D1-D6)
  • Resistor pada pelindung Daya (R1-R4=10k, R5=100k)
  • Resistor pada pelindung Autopilot (R1=330, R2=1k, R3=2k, R4=5.1k, R5=1k, R6/R7/R14=330, R8-R13=10k, R15=10M)
  • Kapasitor (C1=470uF 16v, C2=100n)
  • Resistor 2W 0,22 Ohm (R6)
  • Pin pria
  • Header pin panjang wanita
  • Casing transparan dan "tahan air"

Ada beberapa sensor pada rangkaian semua terhubung ke Arduino Uno dengan bantuan IC 4051 multiplexer . Ini adalah Termistor untuk mengontrol suhu disipator pemanas pengatur tegangan, resistor 2W dan 4x10k sebagai pembagi tegangan untuk menghitung Ampere sebagai konsumsi daya dari seluruh sirkuit. Juga tegangan baterai dikendalikan:LiPo diketahui kritis ketika elemen tunggal dilepaskan di bawah 3.3v; sirkuit ini memiliki dua elemen (2S) LiPo dalam satu paket, jika tegangan rendah (di bawah 7.0v) buzzer akan memberi tahu Anda dengan bunyi bip cepat singkat. Jangan menunggu terlalu lama untuk mematikan, dan segera isi ulang! Leds :yang kuning berkedip pada 1Hz memberi tahu Anda bahwa WatchDog berfungsi; yang biru menyala saat Autopilot aktif, mati jika dijeda; led merah berkedip ketika salah satu tombol remote control ditekan.

Semua sirkuit bekerja pada 5.0v yang disuplai oleh baterai LiPo 2S 7.4v 2600mA/h dan pengatur tegangan IC 7805 . Arus tidak boleh lebih besar dari 800mA, tetapi biasanya sekitar 100-450mA. Harap pasang penghilang pemanas . Termistor ditempatkan di atasnya dan bel akan berbunyi jika suhu melebihi 50°C.

Papan Sirkuit Cetak PCB dan perakitan:

Digunakan PCB wajah tunggal untuk alasan itu saya harus menyertakan beberapa kabel jumper (yang garis putus-putus) untuk memecahkan rute untuk seluruh sirkuit. Ditampilkan di sini muka komponen tetapi di bawah ini Anda memiliki semua file, komponen dan muka solder, dicerminkan, untuk diunduh dan dicetak melalui printer laser pada lembaran "kuning" atau "biru". Saya menggunakan yang kuning tetapi mereka mengatakan yang biru lebih baik (tetapi harganya jauh lebih tinggi). Saat mencetak ingatlah untuk menonaktifkan pengaturan hemat toner, gunakan resolusi 1200 dpi untuk mendapatkan hasil hitam pekat yang nyata. Proses transfer toner dari lembaran ajaib ke PCB dibuat dengan menggunakan setrika panas... Mencetak di kedua sisi, juga di sisi komponen, memudahkan untuk mengenali posisi item dan bahkan menjadikan proyek "profesional".

Kedua PCB berukuran cocok satu dengan Arduino Uno lainnya sebagai tumpukan :unit Daya pertama kemudian unit Autopilot secara keseluruhan.

Pilihan saya adalah menyatukan semua hal, PCB, MCU, RC, sirkuit Driver Motor, baterai, GPS, tombol, sakelar, kabel, konektor, dll. berpikir untuk menggunakannya kembali suatu hari nanti:Saya tidak menyoldernya bersama-sama, saya bekas tajuk dan kabel/koneksi Dupont populer sebagai gantinya. Ada sekitar 200 koneksi yang tidak disolder, itu berarti malfungsi yang tidak terduga dan tidak diinginkan atau perilaku rangkaian yang berbeda dapat terjadi dari waktu ke waktu, itu normal. Sarannya adalah menyolder semuanya untuk sirkuit yang lebih stabil!

Pengaturan Parameter dan menampilkan nilai sensor:

Menekan tombol hitam di sisi kotak itu masuk dalam mode Penyiapan; ini bisa dilakukan juga saat navigasi aktif, tidak perlu masuk Pause dulu. Halaman pertama tampilan menunjukkan tegangan baterai (V=7.83), konsumsi daya (mA=177) dan suhu sensor termistor dekat disipator (38°C); menekan lagi dan lagi tombol hitam yang Anda masukkan ke halaman berikutnya; halaman ke-2, ke-3, ke-4 dan ke-5 menampilkan parameter yang tercantum di bawah ini dan Anda dapat mengubah nilai ini dengan tombol -1 dan +1. Halaman ke-6 menunjukkan "Memperbarui..." jika Anda mengubah sesuatu, nilai disimpan dalam memori EEPROM.

  • Interval: yaitu 2000 mSec, adalah waktu antara satu percobaan dan percobaan lainnya oleh Motor Stepper untuk mengembalikan "H" menuju rute "R", menggerakkan tongkat kemudi ke kanan atau ke kiri;
  • Minimum: yaitu 2°, adalah jumlah minimum derajat di luar rute untuk mendapatkan intervensi Autopilot; hingga nilai ini kemudi tetap pada posisi tengah dengan stabil;
  • Maks: yaitu 40 °, adalah perubahan kemudi maksimum pada suatu waktu oleh Stepper Motor; jika perhitungan yang dilakukan adalah untuk perubahan 50°, ternyata Stepper hanya akan bergerak 40°;
  • Koefisien.: yaitu 1,50 x °, adalah koefisien untuk perubahan kemudi pada suatu waktu; jika perhitungan yang dilakukan adalah untuk perubahan 40°, ternyata Motor Stepper akan bergerak sebesar (40 x 1,50)=60°;

Parameter ini diperlukan untuk menyempurnakan Autopilot saat dipasang di kapal layar. Respon, kepekaan dan kehalusan tergantung pada diameter puli, berapa banyak puli, diameter puli utama pada Motor Stepper, sensitivitas kemudi, berapa panjang tongkat kemudi yang terhubung di atasnya, dan sebagainya. Biarkan instal semuanya dan biarkan mencoba dan membuat pengalaman di papan. Tentu saja pilih hari yang cerah dan cerah dengan angin sepoi-sepoi untuk semua fase pengujian!

Cara kerjanya "langsung":

Anda menavigasi di laut, di danau atau hanya di sekitar pelabuhan. Saatnya Teh dan coke Anda dan sandwich favorit Anda sedang menunggu di saku. Inilah kami:beralih Autopilot pada dan biarkan GPS satelit memperbaikinya, Anda sekarang harus membaca pada tampilan kecepatan sebenarnya dalam knot, jam dan arah arah yaitu H270° (R=rute untuk diikuti, H=arah sebenarnya) dalam derajat (ingat 180°=selatan, 270° =barat, 360° atau 0°=utara dan 90°=timur). Nilai R dan H sama saat dalam mode Jeda (STOP ditampilkan). Hubungkan sekarang tali kemudi, dari Stepper Motor ke tongkat kemudi, dan tekan tombol biru untuk memulai kemudi Autopilot; pada titik ini Autopilot memegang R=arah rute dan mengendalikan apa yang terjadi dengan heading H=. Pasti ada perubahan nomor judul , lambat atau cepat tergantung kondisi cuaca yang sudah kita bicarakan. Autopilot kemudian mencoba mengembalikan ke R=arah rute membuat koreksi yaitu -10°, +5°, dst. hingga nilai H sama dengan nilai R . Anda dapat memutuskan beberapa perubahan pada Route dan Anda dapat mengubah nomor menggunakan tombol merah dan hijau pada unit (-1 -10 +1 +10) atau dengan remote control. Untuk mengambil kembali kendali dari yang kemudi Anda hanya perlu menekan tombol Pause blue, lepaskan tali dari tongkat kemudi melanjutkan pekerjaan dengan tangan Anda. Bagus.

Sisi perangkat lunak:

Kodenya cukup panjang tapi saya harap cukup jelas agar mudah dimengerti. Dalam hal apapun saya akan menjelaskan bagaimana melakukannya. Sketsa menggunakan sekitar 65% program dan sekitar 45% memori. Bahkan menggunakan kelas String, sebagian besar untuk manipulasi kalimat Serial NMEA, seluruh aliran elaborasi stabil dan solid; ia menggunakan "serialEvent()" untuk menerima data dari GPS dua kali per detik , kemudian memanggil "nmeaExtractData()" dan akhirnya memeriksa paket data dengan "nmea0183_checksum() untuk memastikan integritas data. Jika Anda menggunakan GPS merek dan model lain pastikan kalimatnya memiliki struktur yang sama atau Anda harus membuat beberapa perubahan di sini . Misalnya EM406A menggunakan id paket "$GPRMC" , BT220 menggunakan "$GNRMC" sebagai gantinya... hanya sedikit perubahan nama... Tautan yang berguna dapat membantu Anda dengan tes checksum:https://nmeachecksum.eqth.net - Berikut contoh kalimat NMEA lengkap, berisi :id, waktu, validitas, lintang, bujur, kecepatan, jalur sebenarnya, tanggal, variasi, dan checksum.

$GPRMC, 095836.000, A, 4551.9676, N, 01328.7118, E, 2.09, 341.84, 280519,, *08

Selama "Setup()" EEPROM diperiksa :jika baru atau tidak dikenal itu diinisialisasi (diformat). Parameter dalam memori dibaca/tulis sebagai byte:0=0x29, 1=0x00, 2-3=interval, 4-5=min, 6-7=max, 8-11=koefisien (byte, byte, int, int, mengambang). Saya menangani operasi r/w EEPROM dengan hati-hati, mungkin terlalu defensif... Sensor diperiksa setiap 10 detik melalui "readMuxSensors()" oleh multiplexer dan dapat menyebabkan alarm jika baterai lemah atau suhu tinggi. Resolusi konsumsi daya rendah, sekitar 40mA. Tombol perangkat keras dan RC diperiksa terus menerus; apa yang mereka lakukan bergantung pada nilai boolean "IsSetup" serta tampilan "RefreshDisplay()" tidak . Inti dari kode ini adalah bagian KONTROL KEMUDI yang memanggil fungsi "gomotor()" untuk menggerakkan Stepper keluar dan mundur; ya, itu mungkin menggerakkan kemudi 10 ° ke kanan dan setelah nilai interval itu bergerak kembali ke posisi kemudi nol, dan seterusnya setelah putaran perhitungan baru. Seperti yang sudah dikatakan, kerja kemudi juga dilakukan selama Penyetelan karena hanya memengaruhi beberapa tombol dan perilaku tampilan. Memberi makan whatchdog sangat sederhana namun penting:cukup pasang/matikan Pinnya sesegera mungkin.

Cara memasangnya di Kapal Layar:

Seperti yang ditunjukkan pada gambar di bawah ini, saya memilih untuk menempatkan Autopilot dan Motor Stepper di buritan, keduanya terpasang dengan baik dengan baut, dll.; seutas tali berdiameter 6mm dimulai dari puli Motor utama dan melingkari dua puli lain yang ditempatkan di kedua sisi. Kedua katrol ini harus "dipasang" ke perahu dengan cara dua cincin bungee untuk menjaga sedikit ketegangan tali. Pada titik ini, akhirnya, Anda harus memutuskan bagaimana menghubungkan tali ke tongkat kemudi (sambungan sementara); itu harus terhubung saat Anda ingin Autopilot beraksi, mudah terhubung dan mudah diputuskan. Jauhkan sistem Autopilot dari air! :-)

Berita &Pembaruan:

  • 10.05.2020, ditambahkan untuk mengunduh file proyek .STEP 3D CAD untuk katrol stepper (oleh saya) dan pelat pemasangan (oleh Andrew Barney), dan gambar pratinjau 3D.

Penafian &Peringatan:

Katakanlah ini adalah permainan yang kita mainkan di sini, tidak ada ke bersikaplah serius! Beberapa tahun yang lalu saya melakukan perjalanan panjang, 16 bulan, keliling Dunia dengan kapal layar. Kami menavigasi secara ekstensif dengan autopilot nyata (BUKAN INI SATU!) di semua kondisi cuaca, bahkan kondisi cuaca buruk. Sebuah autopilot nyata adalah sesuatu sangat kuat baik perangkat keras maupun perangkat lunak yang harus Anda percayai banyak. Ini Arduino Autopilot sebagai gantinya adalah permainan yang fantastis untuk dimainkan dengan dan ke menghabiskan waktu untuk bersenang-senang.

Selamat bersenang-senang!

Marco Zonca

Kode

  • Sketsa autopilot (untuk Uno)
  • Sketsa WatchDog (untuk Nano)
Sketsa autopilot (untuk Uno)Arduino
/* Sketsa ini berfungsi sebagai Autopilot untuk kapal layar kecil, oleh Marco Zonca, 2019 Arduino UNO sebagai CPU, Arduino Nano sebagai pengawas, GPS BT-220 nmea, motor stepper + pengontrol, rf433Mhz RC, 6 tombol, buzzer, i2c display, 2 leds, i2c 24c04 eeprom, Mux 4051 untuk sensor, lipo 2s 7.4v 2600mA, regulator tegangan 7805, Thermistor;*/#include #include #include # include String inputString ="";String nm_time ="00:00:00";String nm_validity ="V";String nm_latitude ="ddmm.mmmm'N";String nm_longitude ="dddmm.mmmm'E ";String nm_knots ="0.0kn";float nmf_knots =0.0;String nm_truecourse ="360";float nmf_truecourse =360;String nm_date ="dd/mm/tttt";String nm_routetofollow ="000";float nm_knots =0; unsigned long beforeStearingMillis =0;unsigned long currentStearingMillis =0;unsigned long prevCheckSensorsMillis =0;unsigned long currCheckSensorsMillis =0;int CheckSensorsInterval =10000;bool stringComplete =false;bool isfirstfix =true;bool ispause =true;bool isStearing =false;bool isSetup =false;int s=0;int y=0;int z=0;int d=0;int rfRemoteControlValue =0;int HWButtonValue =0;int SetupParameter =0;float calcmove =0;float cm =0;float Stearing =0;float prevStearing =0;float t =0;int EEdisk =0x50;int EEid1 =0x29;int EEid2 =0x00;unsigned int EEaddress =0;unsigned int EEbytes =12;byte EEdata[12];byte EEbytedata;int EEerr =0;float SensorVBatt=0;float SensorVRes=0;float SensorTemp=0;float SensormAmp=0;// parameter berikut adalah default tetapi dibaca/tulis dalam eeprom// eeprom diinisialisasi jika pada alamat 0 dan 1 isi alamat berbeda len ketik catatan// 0-255 byte pada 0x50 EEdisk, 256-512 byte pada 0x51 (tidak digunakan) ---------- -------------------------------------------------- ---// 0 1B byte 01001001 (0x29 sebagai id proyek autopilot1)// 1 1B byte 00000000 (0x00 " " id2)int StearingInterval =2000; // milis antara mencoba dan mundur 2 2B int StearingInterval 1000-5000 langkah 100int StearingMinToMove =2; // kompas_derajat 4 2B int StearingMinToMove 0-20 langkah 1int StearingMaxMove =40; // kompas_derajat 6 2B int StearingMaxMove 10-45 langkah 1float StearingCoeffMove =1,5; // digunakan sebagai (derajat_kompas * koefisien) 8 4B float StearingCoeffMove 0.1-4 langkah 0.1// 12 gratis//byte bStearingInterval[sizeof(int)];byte bStearingMinToMove[sizeof(int)];byte bStearingMaxMove[sizeof(int)];byte bStearingCoeffMove[sizeof(float)];int prev_StearingInterval=0;int prev_StearingMinToMove=0;int prev_StearingMaxMove=0;float prev_StearingCoeffMove=0;const int ledpausePin =2;const int watchDogPin =7Bit Mux;Sconst int watchDogPin // 00=Vin 01=Vbatt 10=Tempconst int MuxSelBit1Pin =6; // const int motorsABenablePin =13;const int MuxIOPin =14;const int TombolPin =15;const int rfRemoteControlPin =16;const int speakerPin =17;const int RCtombol kiri =201;const int RCkanan tombol =202;const int RC310tombol kiri const int RCright10button =204;const int HWtombol kiri =101;const int HWtombol kanan =102;const int HWpausebutton =103;const int HWsetupbutton =104;const int HWleft10button =105;const int HWright10button =200Pert tombolRevolution =106 // 200 untuk model 23LM, 54 langkah =1/4 revolusiLiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIF);Motor stepper(motorStepsPerRevolution, 9, 10, 11, 12 );void setup() { Serial.begin(4800); lcd.begin(16,2); Kawat.mulai(); motor.setSpeed(60); inputString.reserve(200); pinMode(motorsABenablePin, OUTPUT); pinMode(MuxSelBit0Pin, OUTPUT); pinMode(MuxSelBit1Pin, OUTPUT); digitalWrite(motorsABenablePin, RENDAH); digitalWrite(MuxSelBit0Pin, RENDAH); digitalWrite(MuxSelBit1Pin, RENDAH); pinMode(ledpausePin, OUTPUT); pinMode(watchDogPin, OUTPUT); digitalWrite(ledpausePin, RENDAH); digitalWrite(watchDogPin, RENDAH); // baca+periksa EEPROM (memformat jika baru (atau tidak teridentifikasi)) lcd.clear(); lcd.setCursor(0,0); lcd.print("Memeriksa memori..."); lcd.setCursor(0,1); for (s =0; s =CheckSensorsInterval) { readMuxSensors(); if ((SensorVBatt <=7.0) || (SensorTemp>
=50)) { lcd.clear(); lcd.setCursor(0,0); lcd.print("Sensor alarm! "); lcd.setCursor(1,1); lcd.print("V="); lcd.print(SensorVBatt); lcd.print(""); lcd.print(int(SensorTemp)); lcd.write(0xDF); lcd.print("C"); NewTone (pin speaker, 10); penundaan (1000); tidak adaNadaBaru(); } prevCheckSensorsMillis =currCheckSensorsMillis; } // KONTROL PENGEMUDIAN ---------------- currentStearingMillis =milis(); if (currentStearingMillis - sebelumnyaStearingMillis>=StearingInterval) { if (isStearing ==false &&ispause ==false) { // coba (pindahkan stearing) calcmove =nmf_routetofollow - nmf_truecourse; if (calcmove <(-180)) { calcmove =calcmove + 360; } else { if (calcmove> (+180)) { calcmove =calcmove - 360; } } if (abs(calcmove)>=StearingMinToMove) { if (abs(calcmove)>=StearingMaxMove) { if (calcmove <0) { cm =(StearingMaxMove * -1); calcmove =cm; } else { cm =(StearingMaxMove * 1); calcmove =cm; } } Stearing =(calcmove * StearingCoeffMove); gomotor(int((Memutar * 216) / 360)); // 54 langkah =1/4 putaran prevStearing =Stearing; isStearing =benar; } } else { // kembali (pindahkan stearing ke posisi "nol") if (isStearing ==true) { Stearing =(prevStearing * -1); gomotor(int((Memutar * 216) / 360)); // 54 langkah =1/4 putaran Stearing =0; prevStearing =0; isStearing =salah; } } sebelumnyaStearingMillis =saat iniStearingMillis; } // TOMBOL RF RC ------------------ rfRemoteControlValue =checkRfRC(); if (rfRemoteControlValue) { switch (rfRemoteControlValue) { case RCleftbutton:// Tombol RC kiri goleft(); merusak; case RCrightbutton:// Tombol RC kanan goright(); merusak; case RCleft10button:// Tombol RC kiri-10 goleft10(); merusak; case RCright10button:// Kanan+10 tombol RC goright10(); merusak; } } // TOMBOL ------------------------ HWButtonValue =checkHWButtons(); if (HWButtonValue) { switch (HWButtonValue) { case HWleftbutton:// Kiri(-1) Tombol HW if (isSetup ==false) { goleft(); } else { setupMinus(); } merusak; case HWrightbutton:// Kanan(+1) Tombol HW if (isSetup ==false) { goright(); } else { setupPlus(); } merusak; case HWpausebutton:// Jeda tombol HW gopause(); merusak; case HWsetupbutton:// Atur tombol HW gosetup(); merusak; case HWleft10button:// Kiri(-10) tombol HW goleft10(); merusak; case HWright10button:// Kanan(+10) Tombol HW goright10(); merusak; } } // GPS NMEA ------------------ if (stringComplete ==true) { // menerima kalimat nmea oleh serial port RX bool ret; ret =nmeaExtractData(); inputString =""; stringLengkap =salah; if (ret ==true) { RefreshDisplay(); } } // MAKANAN PENGAWAS ---------------- if (digitalRead(watchDogPin) ==LOW) { digitalWrite(watchDogPin, HIGH); } else { digitalWrite(watchDogPin, RENDAH); }}// membaca sensor pada multiplexervoid readMuxSensors() { float Vo =0; mengapung n =0; mengapung n1 =0; mengambang v1ad =0; mengambang v2ad =0; float corr =0; mengapung R1 =10.000; float logR2 =0; mengapung R2 =0; mengapung T =0; float c1 =1,009249522e-03; float c2 =2.378405444e-04; float c3 =2.019202697e-07; digitalWrite(MuxSelBit0Pin, RENDAH); // 00=Vbatt digitalWrite(MuxSelBit1Pin, RENDAH); n =analogRead(MuxIOPin); v1ad=n; n1=(((10.00 * n) / 1023.00)); SensorVBatt=(n1 + ((n1 * 0.0) /100)); // koreksi sewenang-wenang (tidak aktif =0,0%) digitalWrite(MuxSelBit0Pin, LOW); // 01=Vres digitalWrite(MuxSelBit1Pin, HIGH); n =analogRead(MuxIOPin); v2ad=n; n1=(((10.00 * n) / 1023.00)); SensorVRes=(n1 + ((n1 * 0.0) /100)); // koreksi sewenang-wenang (tidak aktif =0,0%) digitalWrite(MuxSelBit0Pin, HIGH); // 10=NTC Temp digitalWrite(MuxSelBit1Pin, LOW); Vo =analogRead(MuxIOPin); R2 =R1 * (1023.0 / Vo - 1.0); logR2 =log(R2); T =(1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2)); SensorTemp =T - 273,15; // Celcius n =(v1ad - v2ad); n1 =(n / 0,22) * 1000.00; SensormAmp =(((10.00 * n1) / 1023.00));}// ekstrak data dari nmea inputStringbool nmeaExtractData() { bool ret =false; //benar jika nmea kalimat =$GNRMC dan CHKSUM valid jika ((inputString.substring(0,6) =="$GNRMC") &&(inputString.substring(inputString.length()-4,inputString.length()- 2) ==nmea0183_checksum(inputString))) { y=0; for (s =1; s <11; s ++) { y=inputString.indexOf(",",y); switch (s) { kasus 1://waktu z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_time=inputString.substring(y+1,y+2+1)+":"+inputString.substring(y+1+2,y+4+1)+" :"+inputString.substring(y+1+4,y+6+1); } y=z; merusak; kasus 2://validitas z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_validity=inputString.substring(y+1,y+1+1); } y=z; merusak; kasus 3://lintang z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_latitude=inputString.substring(y+1,y+2+1)+""+inputString.substring(y+1+2,y+10+1)+"' "; } y=z; merusak; kasus 4://utara/selatan z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_latitude=nm_latitude + inputString.substring(y+1,y+1+1); } y=z; merusak; case 5://bujur z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_longitude=inputString.substring(y+1,y+3+1)+""+inputString.substring(y+1+3,y+11+1)+"' "; } y=z; merusak; kasus 6://timur/barat z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_longitude=nm_longitude + inputString.substring(y+1,y+1+1); } y=z; merusak; kasus 7://kecepatan knot z=inputString.indexOf(",",y+1); if (z>(y+1)) { nmf_knots=inputString.substring(y+1,z).toFloat(); t=roundOneDec(nmf_knots); nm_knots=String(t,1)+"kn"; } y=z; merusak; kasus 8://kursus benar z=inputString.indexOf(",",y+1); if (z>(y+1)) { nmf_truecourse=inputString.substring(y+1,z).toFloat(); d=nmf_truecourse; nm_truecourse=d; } y=z; merusak; kasus 9://tanggal z=inputString.indexOf(",",y+1); if (z>(y+1)) { nm_date=inputString.substring(y+1,y+2+1)+"/"+inputString.substring(y+1+2,y+4+1)+" /20"+inputString.substring(y+1+4,y+6+1); } y=z; merusak; kasus 10:// pernyataan break; default:// pernyataan break; } } if ((isfirstfix ==true) || (ispause ==true)) { nm_routetofollow=nm_truecourse; nmf_routetofollow=nmf_truecourse; isfirstfix=salah; } ret=benar; } return ret;}// kenaikan(+) nilai parameter selama setupvoid setupPlus() { switch (SetupParameter) { case 2://interval StearingInterval =(StearingInterval + 100); if (StearingInterval> 5000) { StearingInterval =5000; } merusak; kasus 3://mnt. untuk memindahkan StearingMinToMove =(StearingMinToMove + 1); if (StearingMinToMove> 20) { StearingMinToMove =20; } merusak; kasus 4://maks. pindah StearingMaxMove =(StearingMaxMove + 1); if (StearingMaxMove> 45) { StearingMaxMove =45; } merusak; kasus 5://koefisien StearingCoeffMove =(StearingCoeffMove + 0.1); if (StearingCoeffMove> 4) { StearingCoeffMove =4; } merusak; } penundaan (200); RefreshDisplay();}// penurunan(-) nilai parameter selama setupvoid setupMinus() { switch (SetupParameter) { case 2://interval StearingInterval =(StearingInterval - 100); if (StearingInterval <1000) { StearingInterval =1000; } merusak; kasus 3://mnt. untuk memindahkan StearingMinToMove =(StearingMinToMove - 1); if (StearingMinToMove <0) { StearingMinToMove =0; } merusak; kasus 4://maks. pindah StearingMaxMove =(StearingMaxMove - 1); if (StearingMaxMove <10) { StearingMaxMove =10; } merusak; kasus 5://koefisien StearingCoeffMove =(StearingCoeffMove - 0,1); if (StearingCoeffMove <0,1) { StearingCoeffMove =0,1; } merusak; } penundaan (200); RefreshDisplay();}// kontrol motor (+)=maju (-)=mundursvoid gomotor(int langkahToMove) { digitalWrite(motorsABenablePin, HIGH); motor.step(stepsToMove); digitalWrite(motorsABenablePin, LOW);}// refresh data di displayvoid RefreshDisplay() { if (isSetup ==false) { //---------normal lcd.clear(); lcd.setCursor(0,0); lcd.print("R"+nm_routetofollow); lcd.write(0xDF); lcd.print("H"+nm_truecourse); lcd.write(0xDF); if (jeda ==benar) { lcd.print("STOP"); } else { if (Memutar> 0) { lcd.print(" +"); } if (Stearing ==0) { lcd.print(" "); } if (Stearing <0) { lcd.print(" "); } lcd.print(int(Stearing)); } lcd.setCursor(0,1); lcd.print(nm_time+" "+nm_knots); } if (isSetup ==true) { //-----------setup lcd.clear(); lcd.setCursor(0,0); lcd.print("setup:"); switch (SetupParameter) { case 1://display sensors readMuxSensors(); lcd.print("V="); lcd.print(SensorVBatt); lcd.setCursor(1,1); lcd.print("mA="); lcd.print(int(SensormAmp)); lcd.print(""); lcd.print(int(SensorTemp)); lcd.write(0xDF); lcd.print("C"); merusak; case 2://interval lcd.print("interval"); lcd.setCursor(7,1); lcd.print(StearingInterval); lcd.print(" mSec"); merusak; case 3://min. to move lcd.print("minimum"); lcd.setCursor(7,1); lcd.print(StearingMinToMove); lcd.write(0xDF); merusak; case 4://max. move lcd.print("max"); lcd.setCursor(7,1); lcd.print(StearingMaxMove); lcd.write(0xDF); merusak; case 5://coefficient lcd.print("coeffic."); lcd.setCursor(7,1); lcd.print(StearingCoeffMove); lcd.print(" x "); lcd.write(0xDF); merusak; } }}/* SerialEvent occurs whenever a new data comes in the hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response. Multiple bytes of data may be available.*/void serialEvent() { while (Serial.available()) { char inChar =(char)Serial.read(); inputString +=inChar; // if the incoming character is a newline, set a flag so the main loop can // do something about it if (inChar =='\n') { stringComplete =true; } } }//calculate checksum of nmea sentenceString nmea0183_checksum(String nmea_data) { int crc =0; String chSumString =""; di aku; // ignore the first $ sign, checksum in sentence for (i =1; i <(nmea_data.length()-5); i ++) { // remove the - 5 if no "*" + cksum + cr + lf are present crc ^=nmea_data[i]; } chSumString =String(crc,HEX); if (chSumString.length()==1) { chSumString="0"+chSumString.substring(0,1); } chSumString.toUpperCase(); return chSumString;}//check RC which button is pressedint checkRfRC() { int n =0; int res =0; n =analogRead(rfRemoteControlPin); if ((n>350) and (n<460)) { // button A res =RCleftbutton; } if ((n> 90) and (n<190)) { // button B res =RCrightbutton; } if ((n>540) and (n<640)) { // button C res =RCleft10button; } if ((n>225) and (n<325)) { // button D res =RCright10button; } return res; }//check HW which button is pressedint checkHWButtons() { int n =0; int res =0; n =analogRead(ButtonsPin); //Serial.println(n); if ((n>465) and (n<565)) { // button left res =HWleftbutton; } if ((n>290) and (n<390)) { // button right res =HWrightbutton; } if ((n>130) and (n<220)) { // button pause res =HWpausebutton; } if ((n>625) and (n<725)) { // button setup res =HWsetupbutton; } if ((n>975) and (n<1075)) { // button left-10 res =HWleft10button; } if ((n>800) and (n<900)) { // button right+10 res =HWright10button; } return res; }void gosetup() { // setup button if (isSetup ==false) { SetupParameter =1; isSetup =true; } else { if (SetupParameter <5) { SetupParameter ++; } else { if (prev_StearingInterval !=StearingInterval || prev_StearingMinToMove !=StearingMinToMove || prev_StearingMaxMove !=StearingMaxMove || prev_StearingCoeffMove !=StearingCoeffMove) { lcd.clear(); lcd.setCursor(0,0); lcd.print("updating... "); penundaan (1000); goupdateEEPROM(); if (EEerr) { lcd.print("E="); lcd.print(EEerr); penundaan (1000); } prev_StearingInterval =StearingInterval; prev_StearingMinToMove =StearingMinToMove; prev_StearingMaxMove =StearingMaxMove; prev_StearingCoeffMove =StearingCoeffMove; } isSetup =false; } } NewTone (speakerPin,2000); penundaan (200); noNewTone(); RefreshDisplay();}void goupdateEEPROM() { EEaddress =0; //id1 EEdata[0] =EEid1; EEbytedata =EEid1; writeEEPROM (EEdisk, EEaddress, EEbytedata); EEaddress =1; //id2 EEdata[1] =EEid2; EEbytedata =EEid2; writeEEPROM (EEdisk, EEaddress, EEbytedata); memcpy(bStearingInterval, &StearingInterval, sizeof(int)); memcpy(bStearingMinToMove, &StearingMinToMove, sizeof(int)); memcpy(bStearingMaxMove, &StearingMaxMove, sizeof(int)); memcpy(bStearingCoeffMove, &StearingCoeffMove, sizeof(float)); memcpy(EEdata+2,bStearingInterval,sizeof(int)); memcpy(EEdata+4,bStearingMinToMove,sizeof(int)); memcpy(EEdata+6,bStearingMaxMove,sizeof(int)); memcpy(EEdata+8,bStearingCoeffMove,sizeof(float)); for (s =2; s  360) { nmf_routetofollow =1; } d=nmf_routetofollow; nmf_routetofollow=d; nm_routetofollow=d; NewTone (speakerPin,800); penundaan (200); noNewTone(); } else { NewTone (speakerPin,1000); penundaan (50); noNewTone(); } RefreshDisplay();}void goright10() { // right 10x button/RC if (ispause ==false) { for (s =1; s <11; s ++) { nmf_routetofollow ++; if (nmf_routetofollow> 360) { nmf_routetofollow =1; } } d=nmf_routetofollow; nmf_routetofollow=d; nm_routetofollow=d; NewTone (speakerPin,800); penundaan (200); noNewTone(); } else { NewTone (speakerPin,1000); penundaan (50); noNewTone(); } RefreshDisplay();}void gopause() { // pause button/RC if (ispause ==true) { ispause=false; digitalWrite(ledpausePin, HIGH); NewTone (speakerPin,50); penundaan (200); NewTone (speakerPin,200); delay(800); noNewTone(); } else { ispause=true; digitalWrite(ledpausePin, LOW); NewTone (speakerPin,200); penundaan (200); NewTone (speakerPin,50); delay(800); noNewTone(); } RefreshDisplay();}// reading eeprombyte readEEPROM (int diskaddress, unsigned int memaddress) { byte rdata =0x00; Wire.beginTransmission (diskaddress); Wire.write (memaddress); if (Wire.endTransmission () ==0) { Wire.requestFrom (diskaddress,1); if (Wire.available()) { rdata =Wire.read(); } else { EEerr =1; //"READ no data available" } } else { EEerr =2; //"READ eTX error" } Wire.endTransmission (true); return rdata;}// writing eepromvoid writeEEPROM (int diskaddress, unsigned int memaddress, byte bytedata) { Wire.beginTransmission (diskaddress); Wire.write (memaddress); Wire.write (bytedata); if (Wire.endTransmission () !=0) { EEerr =3; //"WRITING eTX error" } Wire.endTransmission (true); penundaan (5); }// round zero decimalfloat roundZeroDec(float f) { float y, d; y =f*1; d =y - (int)y; y =(float)(int)(f*1)/1; if (d>=0.5) { y +=1; } else { if (d <-0.5) { y -=1; } } return y;}// round one decimalfloat roundOneDec(float f) { float y, d; y =f*10; d =y - (int)y; y =(float)(int)(f*10)/10; if (d>=0.5) { y +=0.1; } else { if (d <-0.5) { y -=0.1; } } return y;}// round two decimalfloat roundTwoDec(float f) { float y, d; y =f*100; d =y - (int)y; y =(float)(int)(f*100)/100; if (d>=0.5) { y +=0.01; } else { if (d <-0.5) { y -=0.01; } } return y;}
WatchDog sketch (for Nano)Arduino
/* * This sketch is a Watchdog to keep CLIENT under control, on Arduino NANO 3.0 by Marco Zonca * CLIENT must feed Whatcdog sooner then feedingInterval otherwise will be forced to restart * */const int feedingPin =14;const int ledPin =15;const int restartPin =16;const int buzzerPin =17;const long ledInterval =1000;const long feedingInterval =2500;const long timeForClientStart =16000;int ledState =LOW;int previousFeedingState =LOW;int feedingState =LOW;unsigned long previousLedMillis =0;unsigned long previousFeedingMillis =0;void setup() { digitalWrite(restartPin, HIGH); // LOW will force CLIENT to restart pinMode(ledPin, OUTPUT); pinMode(buzzerPin, OUTPUT); pinMode(restartPin, OUTPUT); pinMode(feedingPin, INPUT); delay(timeForClientStart); // let time to CLIENT to start...}void loop() { unsigned long currentMillis =millis(); // BLINK LED ------------------- if (currentMillis - previousLedMillis>=ledInterval) { previousLedMillis =currentMillis; if (ledState ==LOW) { ledState =HIGH; } else { ledState =LOW; } digitalWrite(ledPin, ledState); } // CHECK THE FEEDING ------------------- feedingState =digitalRead(feedingPin); // CLIENT must set pin HIGH -> LOW frequently to prove it's alive if (feedingState ==HIGH) { if (previousFeedingState ==LOW) { previousFeedingMillis =currentMillis; } previousFeedingState =HIGH; } else { previousFeedingState =LOW; } if (currentMillis - previousFeedingMillis> feedingInterval) { // CLIENT is sleeping ledState =HIGH; digitalWrite(ledPin, ledState); tone(buzzerPin,1500); penundaan (500); digitalWrite(restartPin, LOW); //restart CLIENT tone(buzzerPin,1500); penundaan (500); digitalWrite(restartPin, HIGH); tone(buzzerPin,1500); delay(timeForClientStart); // let CLIENT time to restart... noTone(buzzerPin); currentMillis =millis(); previousFeedingState =LOW; previousFeedingMillis =currentMillis; previousLedMillis =currentMillis; }}

Suku cadang dan penutup khusus

23lm-stepper-plate-v2_PlvJaff9Hl.step 23lm-stepper-pulley-56_UhsbaWbiBt.step

Skema


Proses manufaktur

  1. Sistem Sensor Gerak Inframerah DIY untuk Raspberry Pi
  2. Bangun Sistem Pemulihan Parasut Balistik untuk Drone Anda
  3. Apakah sistem pemantauan berkelanjutan tepat untuk Anda?
  4. Pengubah Alat Otomatis untuk Robot
  5. Apakah sistem Anda siap untuk IoT?
  6. Polygon Cutters Untuk Mesin Bubut Otomatis
  7. Bubut Otomatis CNC untuk Suku Cadang Presisi
  8. Sistem Propulsi untuk Penerbangan Hipersonik
  9. Prinsip kerja sistem transmisi manual dan otomatis
  10. Pengertian Sistem Transmisi Otomatis