Jangan Sesekali Sendirikan: Sistem Keamanan Sepeda Pintar
Komponen dan Perlengkapan
LED 5 mm: Merah – 2 unit
u-blox Ublox neo 6m GPS – 1 unit
Arduino MKR Fox 1200 – 1 unit
Baterai, 3.7 V – 1 unit
Buzzer – 1 unit
Tombol Tekan SparkFun 12mm – 1 unit
Tombol Geser – 1 unit
Resistor 1k ohm – 1 unit
SeeedGrove - Sensor Getaran (SW-420) – 1 unit
Alat dan Mesin yang Diperlukan
Printer 3D (umum) – 1 unit
Tentang Proyek Ini
Halo semuanya, saya Jesús Soriano, mahasiswa teknik elektronik, wirausaha... dan sepeda!
Saya sudah mengendarai sepeda sejak usia 12 tahun, dan saya biasanya berlatih sendirian. Selama latihan ini, saya mengalami banyak jatuh, kecelakaan dan malapetaka lain. Suatu hari, saya menyadari bahwa, jika saya mengalami kecelakaan berat dan kehilangan kesadaran, saya bisa mati. Saya sendirian di pegunungan!
Lebih mudah untuk memahami apa yang saya maksud dengan video singkat. Bayangkan: Anda sedang mengendarai sepeda, menikmati pemandangan dan tiba-tiba, sebuah mobil muncul dan menabrak Anda. Anda jatuh dari lereng, dan pengemudi melarikan diri. Anda tetap tidak sadar, terjebak, tak terlihat oleh dunia.
Dua atau tiga jam kemudian, keluarga Anda akan mulai khawatir. Layanan darurat akan mencoba menemukan Anda, dan mereka akan setelah 4-5 jam. Anda kemungkinan besar akan mati.
Jadi saya mulai melakukan riset, dan saya melihat banyak opsi yang menarik: Pertama, aplikasi, Strava Summit. Dalam kasus kecelakaan, itu dapat mengirim posisi GPS ke teman. Angi, dari Specialized, juga adalah opsi. Sistem terintegrasi di helm, dan dalam kasus tabrakan, itu dapat meminta bantuan. Tapi itu masalahnya. Semua sistem ini membutuhkan sinyal ponsel untuk bekerja. Baterai, GPS dan sinyal ponsel diperlukan.
Itulah bagaimana Never Ride Alone, NRA, hadir. Saya menemukan Sigfox sebagai solusi saya untuk pengiriman data di pegunungan, dan ketika saya menemukan bahwa mereka memiliki Arduino dengan modul sigfox... Itu luar biasa!
Saya memutuskan bahwa NRA akan bekerja seperti alarm terbalik. Saat Anda bersepeda, Anda mengaktifkan NRA dengan menekan tombol. LED mulai berkedip, sambil mereka juga meningkatkan visibilitas. Jika NRA tidak mendeteksi gerakan selama 30 detik, itu mengaktifkan mode darurat. Itu mulai berdengung, dan jika tidak ada yang menghentikannya (mungkin Anda tidak dalam bahaya, tapi Anda lupa mematikannya) itulah Anda cedera. Secara otomatis, modul GPS mulai bekerja di NRA, dan itu mengirim lokasi GPS melalui jaringan SigFox ke semua teman/keluarga Anda.
Saya bertanya kepada banyak pengendara sepeda, dan saya menghasilkan desain minimalis. Pengendara sepeda ingin perangkat yang mudah digunakan, dan dengan baterai yang baik. Dengan NRA, Anda hanya perlu menekan tombol dan berpedal. Setelah latihan, Anda hanya perlu mematikannya dan mengisi daya.
Casing NRA terbuat dari plastik ABS. Saya menggunakan printer 3D, yang disediakan oleh Universitas Politeknik Valencia.
Anda dapat mengedit/mengunduh file desain NRA di sini:
Untuk pembuatan ini, saya menggunakan Arduino MKR1200, Neo 6-m GPS, tombol, 2 LED, satu resistor 1k Ohm, buzzer, sensor getaran dan baterai 3.7v 150mah.
Setelah itu, saya memulai dengan konfigurasi Arduino dan SigFox. Ini adalah konfigurasi saya pada Halaman Backend SigFox:
Saat Arduino MKR1200 mengirim data, server ini mengonversi data mentah yang diberikan menjadi informasi. Dalam kasus saya, saya menggunakan lintang, bujur dan ketinggian. Dengan informasi ini, saya mengirim e-mail ke semua orang dalam pengaturan saya (teman, keluarga...) sehingga mereka dapat mengklik tautan google maps, dan tahu di mana pelari sepeda yang cedera berada.
Ini adalah cara semua komponen dipasang di casing:
Pertama-tama, modul GPS. Kita hanya membutuhkan positif, negatif, dan kabel transfer data. Antena ditempel pada kerangka. Arduino akan diletakkan di atasnya.
Kami juga menambahkan baterai, terhubung ke Arduino, dan juga saklar. Dengan cara ini, kita dapat menyalakan/mematikannya.
Kami memiliki konektor baterai, sehingga kita dapat mengisi daya NRA. Harus dalam keadaan mati.
Selama proyek ini saya telah menggunakan pengisi baterai drone untuk mengisi daya NRA. Ini bekerja sempurna.
Setelah membuat pemasangan kabel, kami meletakkan antena di atas Arduino. Agak rumit untuk menggabungkan semua komponen dalam cangkang ini, tetapi dengan perhatian itu dapat dilakukan.
Dalam pembuatan ini, kami tidak menggunakan sensor getaran. Dalam kasus ini, saat NRA diaktifkan, ia mulai mengirim posisi GPS setiap 10 menit. Hasilnya bagus.
Kami juga menguji NRA di sepanjang jalan raya. Itu adalah pengalaman yang sangat baik.
Sangat mudah digunakan, dan memberi Anda perasaan bahwa Anda memiliki perangkat yang baik di tangan Anda.
Jadi inilah sejarah Never Ride Alone, sebuah perangkat yang selalu waspada terhadap Anda. Setiap kali Anda bersepeda, Anda tahu Anda aman, karena dalam kasus kecelakaan, Anda akan selalu terlacak.
Dari tim Never Ride Alone kami juga telah mencoba untuk meningkatkan planet kita. Selama semua uji coba pengendaraan ini, kami juga telah mengumpulkan semua sampah yang kami lihat di sekitar pegunungan. Menurut Tujuan Pembangunan Berkelanjutan, kami mencoba menghapus semua tong sampah yang kami lihat selama pengendaraan.
Setelah mengumpulkan semua ini, kami menyadari bahwa sebagian besar sampah di pegunungan berasal dari pengendara sepeda! Kami telah mengumpulkan banyak plastik bar energi, gel dan ban. Sekarang, kami mencoba untuk meningkatkan kesadaran di kalangan semua pengendara sepeda. Dalam balapan, kami telah menciptakan titik bersih, tempat orang dapat membuang semua sampah mereka tanpa berhenti dan kehilangan waktu. Area ini dibatasi dan, saat balapan selesai, semuanya dibersihkan.
Terima kasih telah membaca, dan berkendara aman :)
Kode
NEVER RIDE ALONE V.0.1
NEVER RIDE ALONE V.0.1Arduino
Kode NRA. Tidak menggunakan sensor. Mengirim semua data GPS setiap 10 menit.
///// NEVER RIDE ALONE V.0.1 ///// //.............................// ////AUTOR: JESUS SORIANO ADAM//// ////////FECHA: 05/05/2019 /////// ///////////////////////////////// #include <SigFox.h> #include <ArduinoLowPower.h> #include <TinyGPS.h>//we include TinyGPS #define WAITING_TIME 10 //waiting time during every message #define GPS_PIN 2 //(tranistor pin, for energy saving. not used now) #define GPS_INFO_BUFFER_SIZE 128 bool debug = true; ////////DEBUG///// const int backlights=4; const int pulsador=5; const int audio=3; TinyGPS gps;//GPS Object //GPS data variables int year; byte month, day, hour, minute, second, hundredths; unsigned long chars; unsigned short sentences, failed_checksum; char GPS_info_char; char GPS_info_buffer[GPS_INFO_BUFFER_SIZE]; unsigned int received_char; bool message_started = false; int i = 0; // GPS coordinate structure, 12 bytes size on 32 bits platforms struct gpscoord { float a_latitude; // 4 bytes float a_longitude; // 4 bytes float a_altitude; // 4 bytes }; float latitude = 0.0f; float longitude = 0.0f; float altitud = 0; //////////////// Waiting function ////////////////// void Wait(int m, bool s) { //m minutes to wait //s slow led pulses if (debug) { Serial.print("Waiting: "); Serial.print(m); Serial.println(" min."); } digitalWrite(LED_BUILTIN, LOW); if (s) { int seg = m * 30; for (int i = 0; i < seg; i++) { digitalWrite(backlights, HIGH); delay(500); digitalWrite(backlights, LOW); delay(500); } } else { int seg = m * 15; for (int i = 0; i < seg; i++) { digitalWrite(backlights, HIGH); delay(500); digitalWrite(backlights, LOW); delay(500); } } } /////////////////// Sigfox Send Data function //////////////// void SendSigfox(String data) { if (debug) { Serial.print("Sending: "); Serial.println(data); if (data.length() > 12) { Serial.println("Message too long, only first 12 bytes will be sent"); } } // Remove EOL //data.trim(); // Start the module SigFox.begin(); // Wait at least 30mS after first configuration (100mS before) delay(100); // Clears all pending interrupts SigFox.status(); delay(1); if (debug) SigFox.debug(); delay(100); SigFox.beginPacket(); SigFox.print(data); if (debug) { int ret = SigFox.endPacket(true); // send buffer to SIGFOX network and wait for a response if (ret > 0) { Serial.println("No transmission"); } else { Serial.println("Transmission ok"); } Serial.println(SigFox.status(SIGFOX)); Serial.println(SigFox.status(ATMEL)); if (SigFox.parsePacket()) { Serial.println("Response from server:"); while (SigFox.available()) { Serial.print("0x"); Serial.println(SigFox.read(), HEX); } } else { Serial.println("Could not get any response from the server"); Serial.println("Check the SigFox coverage in your area"); Serial.println("If you are indoor, check the 20dB coverage or move near a window"); } Serial.println(); } else { SigFox.endPacket(); } SigFox.end(); } ////////////////// Convert GPS function ////////////////// /* Converts GPS float data to Char data */ String ConvertGPSdata(const void* data, uint8_t len) { uint8_t* bytes = (uint8_t*)data; String cadena ; if (debug) { Serial.print("Length: "); Serial.println(len); } for (uint8_t i = len - 1; i < len; --i) { if (bytes[i] < 12) { cadena.concat(byte(0)); // Not tested } cadena.concat(char(bytes[i])); if (debug) Serial.print(bytes[i], HEX); } if (debug) { Serial.println(""); Serial.print("String to send: "); Serial.println(cadena); } return cadena; } ////////////////////////// Get GPS position function///////////////////// String GetGPSpositon() { int messages_count = 0; String pos; if (debug) Serial.println("GPS ON"); digitalWrite(GPS_PIN, HIGH); //Turn GPS on Wait(1, false); while (messages_count < 5000) { while (Serial1.available()) { int GPS_info_char = Serial1.read(); if (GPS_info_char == '$') messages_count ++; // start of message. Counting messages. if (debug) { if (GPS_info_char == '$') { // start of message message_started = true; received_char = 0; } else if (GPS_info_char == '*') { // end of message for (i = 0; i < received_char; i++) { Serial.write(GPS_info_buffer[i]); // writes the message to the PC once it has been completely received } Serial.println(); message_started = false; // ready for the new message } else if (message_started == true) { // the message is already started and I got a new character if (received_char <= GPS_INFO_BUFFER_SIZE) { // to avoid buffer overflow GPS_info_buffer[received_char] = GPS_info_char; received_char++; } else { // resets everything (overflow happened) message_started = false; received_char = 0; } } } if (gps.encode(GPS_info_char)) { gps.f_get_position(&latitude, &longitude); altitud = gps.altitude() / 100; // Store coordinates into dedicated structure gpscoord coords = {altitud, longitude, latitude}; gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths); if (debug) { Serial.println(); Serial.println(); Serial.print("Latitud/Longitud: "); Serial.print(latitude, 5); Serial.print(", "); Serial.println(longitude, 5); Serial.println(); Serial.print("Fecha: "); Serial.print(day, DEC); Serial.print("/"); Serial.print(month, DEC); Serial.print("/"); Serial.print(year); Serial.print(" Hora: "); Serial.print(hour, DEC); Serial.print(":"); Serial.print(minute, DEC); Serial.print(":"); Serial.print(second, DEC); Serial.print("."); Serial.println(hundredths, DEC); Serial.print("Altitud (metros): "); Serial.println(gps.f_altitude()); Serial.print("Rumbo (grados): "); Serial.println(gps.f_course()); Serial.print("Velocidad(kmph): "); Serial.println(gps.f_speed_kmph()); Serial.print("Satelites: "); Serial.println(gps.satellites()); Serial.println(); digitalWrite(backlights, HIGH); delay(500); digitalWrite(backlights, LOW); delay(500); } gps.stats(&chars, &sentences, &failed_checksum); if (debug) Serial.println("GPS turned off"); digitalWrite(GPS_PIN, LOW); //GPS turned off pos = ConvertGPSdata(&coords, sizeof(gpscoord)); //Send data return pos; } } } pos = "No Signal"; } //////////////////SETUP/////////////////// void setup() { pinMode(4 , OUTPUT); pinMode(backlights, OUTPUT); pinMode(pulsador, INPUT); pinMode(audio, OUTPUT); if (debug) { Serial.begin(9600); while (!Serial) {}// wait for serial port to connect. Needed for native USB port only Serial.println("Serial Connected"); } //Serial1 pins 13-14 for 3.3V connection to GPS. Serial1.begin(9600); while (!Serial1) {} if (debug) { Serial.println("GPS Connected"); } pinMode(GPS_PIN, OUTPUT); //pin de interruptor del GPS if (!SigFox.begin()) { Serial.println("Shield error or not present!"); return; } // Enable debug led and disable automatic deep sleep if (debug) { SigFox.debug(); } else { SigFox.end(); // Send the module to the deepest sleep } } //////////////////////LOOP//////////////////////// void loop() { String position_data; position_data = GetGPSpositon(); SendSigfox(position_data); Wait(WAITING_TIME, false); }
Bagian dan Enclosure Kustom
Pas untuk mkr1200, baterai, tombol, LED, GPS dan buzzer. Pas untuk mkr1200, baterai, tombol, LED, GPS dan buzzer.nra_v_0_1_qCsc7I6QvO.zip