جدول المحتويات:
- الخطوة 1: مستشعر Conectando O
- الخطوة 2: Montando a Lixeira
- الخطوة 3: تحميل Para a Nuvem
- الخطوة 4: Recuperando Dados Do ThingSpeak
- الخطوة 5: Criando a Aplicação Android
- الخطوة 6: Recuperando O Feed No Android
- الخطوة 7: موستراندو نو مابا
- الخطوة 8: Conclusão
فيديو: SmartBin: 8 خطوات
2024 مؤلف: John Day | [email protected]. آخر تعديل: 2024-01-31 10:16
Este é um projeto para um sistema inteligente de coletas، no qual os caminhões de lixo recebem dados das lixeiras، selectando quantidade de lixo present em cada uma delas، e uma rota de coleta traçada، com base nas informações recuperadas.
Para montar este projeto، é Requário:
- NodeMCU
- جهاز الاستشعار Ultrassônico de Distancia
- كايكسا دي بابيلاو
- بروتوبورد
- كابوس
- Dispositivo Android
الخطوة 1: مستشعر Conectando O
Primeiramente ، vamos efetuar a conexão Entre o sensor ultrassônico e o NODEMCU. Para tanto ، vamos conectar كمشغل Portas e echo do sensor nas portas D4 e D3 do NodeMCU:
// يحدد أرقام المسامير #define pino_trigger 2 // D4
#define pino_echo 0 // D3
الفقرة efetuar a leitura dos dados do sensor، foi seguido o التعليمية المتطورة pelo FilipeFlop، disponível aqui.
تعويم cmMsec ، inMsec ؛
ميكروسيك طويل = ultrasonic.timing () ؛
cmMsec = تحويل فوق صوتي (ميكروسيك ، فوق صوتي:: سم) ؛
inMsec = ultrasonic.convert (ميكروسيك ، فوق صوتي:: IN) ؛
// Exibe informacoes بدون شاشة تسلسلية
Serial.print ("Distancia em cm:") ؛
المسلسل المطبوع (سم مسك) ؛
Serial.print ("- Distancia em polegadas:") ؛
Serial.println (inMsec) ؛
بيانات السلسلة = String (cmMsec) ؛
Serial.println (بيانات) ؛
الخطوة 2: Montando a Lixeira
Agora ، vamos montar a lixeira inteligente. Precisaremos conectar o sensor ultrassônico no “teto” da lixeira. Para o exemplo، usei um cabo e fita المعزل. Em seguida، temos que medir a distância inicial، para saber o valor para a lixeira vazia. كاسو نو ميو ، foi de 26 ، 3 سم. Esse é o valor que lookingarmos para uma lixeira vazia.
الفقرة simulação ، visto que não posuo mais de um sensor ultrassônico ، foi feito um algoritmo para salvar randomicamente a distancia em 4 lixeiras diferentes.
// Simulando 4 lixeiras
طويل lixeiraID ؛
حلقة فارغة() {
lixeiraID = عشوائي (1 ، 5) ؛
}
الخطوة 3: تحميل Para a Nuvem
Agora، precisamos enviar estes dados para a nuvem. Eu escolhi o ThingSpeak ، من خلال وسائل مألوفة. Primeiramente ، é ضرورة قناة criar um novo ، recebendo 4 parâmetros ، refentes ao volume de cada lixeira.
Pará conectar a aplicação com o ThingSpeak، é implário salvar o número da API do canal criado. Siga os passos descritos no site oficial.
De volta à aplicação، vamos useizar a biblioteca ESP8266WiFi.h para efetuar conexão com o ThingSpeak، e transferir os dados.
Primeiramente، uma função para efetuar conexão com a rede (defina previamente duas variáveis، ssid e pass ، contendo o identificador e a senha de sua rede).
connectWifi باطل () {
Serial.print ("الاتصال بـ" + * ssid) ؛
WiFi.begin (ssid ، تمرير) ؛
بينما (WiFi.status ()! = WL_CONNECTED) {
تأخير (500) ؛
Serial.print (".") ؛
}
Serial.println ("") ؛
Serial.print ("Conectado na rede") ؛
Serial.println (ssid) ؛
Serial.print ("IP:") ؛
Serial.println (WiFi.localIP ()) ؛
}
إعداد Durante o ، tentamos efetuar a conexão com a rede.
الإعداد باطل() {
Serial.begin (9600) ؛
Serial.println ("Lendo dados do sensor …") ؛
// Conectando ao Wi-Fi
connectWifi () ؛
}
E، para enviar os dados para o ThingSpeak، basta abrir uma conexão HTTP padrão، passando o número da API e os parâmetros.
sendDataTS باطل (عائم cmMsec ، معرّف طويل) {
إذا (client.connect (الخادم ، 80)) {
Serial.println ("Enviando dados para o ThingSpeak") ؛
سلسلة postStr = apiKey ؛
postStr + = "& field"؛
postStr + = معرف ؛
postStr + = "=" ؛
postStr + = String (cmMsec) ؛
postStr + = "\ r / n / r / n"؛
Serial.println (postStr) ؛
client.print ("POST / update HTTP / 1.1 / n") ؛
client.print ("المضيف: api.thingspeak.com / n") ؛
client.print ("الاتصال: إغلاق / n") ؛
client.print ("X-THINGSPEAKAPIKEY:" + apiKey + "\ n") ؛
client.print ("نوع المحتوى: application / x-www-form-urlencoded / n") ؛
client.print ("طول المحتوى:") ؛
client.print (postStr.length ()) ؛
client.print ("\ n / n") ؛
client.print (postStr) ؛
تأخير (1000) ؛
}
client.stop () ؛
}
O Primeiro Parâmetro تتوافق مع المسافات مع أجهزة الاستشعار فائقة السرعة. O segundo parâmetro é o ID da lixeira que foi lida (que foi gerado randomicamente، um número de 1 a 4).
بطاقة التعريف da lixeira تخدم também para identificar para qual campo será feito o upload do valor lido.
الخطوة 4: Recuperando Dados Do ThingSpeak
O ThingSpeak يسمح بـ efetuar leitura dos dados do seu canal، através de um serviço retornando um JSON. نظرًا لأن عمليات التشغيل المختلفة التي تقوم بها الفقرة leitura تقوم بإطعام قناة seu ، فقد تم تحديد الوصف المائي:
www.mathworks.com/help/thingspeak/get-a-ch…
Neste projeto، optou-se por ler diretamente os dados de cada campo. O padrão de URL para este cenário é:
api.thingspeak.com/channels/CHANNEL_ID/fields/FIELD_NUMBER/last.json؟api_key=API_KEY&status=true
Cada campo está descrito no link informado previamente. أهمية نظام التشغيل بالنسبة لمشروع ساو:
- CHANNEL_ID: قناة número do seu
- FIELD_NUMBER: o número do campo
- API_KEY: API chave de seu canal
Esta é a URL que será lida do aplicativa Android ، لاستعادة نظام التشغيل dados do ThingSpeak.
الخطوة 5: Criando a Aplicação Android
لا يوجد Android Studio ، crie um novo projeto Android. الفقرة o correto funcionamento da aplicação، é implário configurar as permissões abaixo no AndroidManifest.
استخدام جزء من خرائط Google ، يجب أن يكون هذا هو الحال بالنسبة إلى Google. Siga os passos descritos no link Obter chave de API.
Uma vez com a chave، você deve também configurá-la na aplicação.
يتم تعريف مفتاح API لواجهات برمجة التطبيقات المستندة إلى خرائط Google على أنه مورد سلسلة.
(راجع ملف "res / القيم / google_maps_api.xml").
لاحظ أن مفتاح API مرتبط بمفتاح التشفير المستخدم لتوقيع APK. أنت بحاجة إلى مفتاح API مختلف لكل مفتاح تشفير ، بما في ذلك مفتاح الإصدار المستخدم لتوقيع APK للنشر. يمكنك تحديد المفاتيح الخاصة بأهداف التصحيح والإصدار في src / debug / and src / release /.
<البيانات الوصفية
android: name = "com.google.android.geo. API_KEY"
android: value = "@ string / google_maps_key" />
التكوين الكامل هو تطبيق AndroidManifest anexado ao projeto.
ن
الخطوة 6: Recuperando O Feed No Android
Na atividade main no Android، MainActivity، crie 4 variáveis para identificar cada um dos canais do Thing
سلسلة خاصة url_a = "https://api.thingspeak.com/channels/429823/fields/1/last.json؟api_key="+API_THINGSPEAK_KEY+"&status=true" ؛ سلسلة خاصة url_b = "https://api.thingspeak.com/channels/429823/fields/2/last.json؟api_key="+API_THINGSPEAK_KEY+"&status=true" ؛ سلسلة خاصة url_c = "https://api.thingspeak.com/channels/429823/fields/3/last.json؟api_key="+API_THINGSPEAK_KEY+"&status=true" ؛ سلسلة خاصة url_d = "https://api.thingspeak.com/channels/429823/fields/4/last.json؟api_key="+API_THINGSPEAK_KEY+"&status=true" ؛
الفقرة efetuar a leitura dos dados، iremos utilizar uma classe do Android específica، chamada JSONObject. Mais uma vez، vamos criar um objeto para cada URL:
استجابة JSONObjectLixeiraA ؛ استجابة JSONObjectLixeiraB ؛ استجابة JSONObjectLixeiraC ؛ استجابة JSONObjectLixeiraD ؛
الفقرة abrir a conexão com as urls، vamos usar criar uma classe auxiliar، chamada HttpJsonParser. Esta classe será Respável por abrir uma conexão com URL، efetuar leitura dos dados encontrados، e retornar o objeto JSON montado.
JSONObject العامة makeHttpRequest (عنوان url سلسلة ، أسلوب السلسلة ، معلمات الخريطة) {
محاولة {
Uri. Builder builder = new Uri. Builder ()؛ URL URLObj ؛ سلسلة encodedParams = ""؛ if (params! = null) {for (Map. Entry entry: params.entrySet ()) {builder.appendQueryParameter (entry.getKey ()، entry.getValue ())؛ }} if (builder.build (). getEncodedQuery ()! = null) {encodedParams = builder.build (). getEncodedQuery ()؛
}
إذا ("GET".equals (طريقة)) {url = url + "؟" + encodedParams ؛ urlObj = URL جديد (url) ، urlConnection = (HttpURLConnection) urlObj.openConnection () ، urlConnection.setRequestMethod (طريقة) ،
} آخر {
urlObj = عنوان URL جديد (url) ، urlConnection = (HttpURLConnection) urlObj.openConnection () ، urlConnection.setRequestMethod (طريقة) ، urlConnection.setRequestProperty ("نوع المحتوى" ، "application / x-www-form-urlencoded") ؛ urlConnection.setRequestProperty ("طول المحتوى" ، String.valueOf (encodedParams.getBytes (). length)) ؛ urlConnection.getOutputStream (). write (encodedParams.getBytes ()) ؛ } // الاتصال بخادم urlConnection.connect () ؛ // اقرأ الإجابة = urlConnection.getInputStream () ؛ BufferedReader reader = new BufferedReader (new InputStreamReader (is))؛ StringBuilder sb = new StringBuilder () ، خط السلسلة
// تحليل الاستجابة
while ((line = reader.readLine ())! = null) {sb.append (line + "\ n")؛ } is.close ()؛ json = sb.toString () ، // تحويل الرد إلى JSON Object jObj = new JSONObject (json) ؛
} catch (UnsupportedEncodingException هـ) {
e.printStackTrace () ، } catch (ProtocolException e) {e.printStackTrace () ؛ } catch (IOException e) {e.printStackTrace ()؛ } catch (JSONException e) {Log.e ("JSON Parser"، "خطأ في تحليل البيانات" + e.toString ())؛ } catch (استثناء هـ) {Log.e ("استثناء"، "خطأ في تحليل البيانات" + e.toString ())؛ }
// إرجاع كائن JSON
عودة jObj ؛
}
}
De volta ، مدير المدرسة ، vamos efetuar a chamada às urls de forma assíncrona، escrevendo este código dentro do método doInBackground.
Override المحمية String doInBackground (String… params) {HttpJsonParser jsonParser = new HttpJsonParser ()؛
responseLixeiraA = jsonParser.makeHttpRequest (url_a، "GET"، فارغ) ؛
responseLixeiraB = jsonParser.makeHttpRequest (url_b، "GET"، فارغ) ؛ responseLixeiraC = jsonParser.makeHttpRequest (url_c، "GET"، فارغ) ؛ responseLixeiraD = jsonParser.makeHttpRequest (url_d، "GET"، فارغ) ؛
عودة فارغة؛}
Quando o método doInBackgroundé encerrado، o control de execução do Android passa para o método onPostExecute. Neste método ، vamos criar os objetos Lixeira ، e popular com os dados recuperados do ThingSpeak:
محمية باطلة onPostExecute (سلسلة نتيجة) {pDialog.dismiss () ؛ runOnUiThread (new Runnable () {public void run () {
// ListView listView = (ListView) findViewById (R.id.feedList) ؛
عرض mainView = (عرض) findViewById (R.id.activity_main) ؛ إذا (النجاح == 1) {جرب {// Cria feedDetail para cada lixeira Lixeira feedDetails1 = new Lixeira () ؛ Lixeira feedDetails2 = جديد Lixeira () ؛ Lixeira feedDetails3 = جديد Lixeira () ؛ Lixeira feedDetails4 = جديد Lixeira () ؛
feedDetails1.setId ("A") ،
feedDetails1.setPesoLixo (Double.parseDouble (responseLixeiraA.getString (KEY_FIELD1))) ؛ feedDetails1.setVolumeLixo (Double.parseDouble (responseLixeiraA.getString (KEY_FIELD1))) ؛
feedDetails2.setId ('B') ،
feedDetails2.setPesoLixo (Double.parseDouble (responseLixeiraB.getString (KEY_FIELD2))) ؛ feedDetails2.setVolumeLixo (Double.parseDouble (responseLixeiraB.getString (KEY_FIELD2))) ؛
feedDetails3.setId ('C') ،
feedDetails3.setPesoLixo (Double.parseDouble (responseLixeiraC.getString (KEY_FIELD3))) ؛ feedDetails3.setVolumeLixo (Double.parseDouble (responseLixeiraC.getString (KEY_FIELD3))) ؛
feedDetails4.setId ('D') ،
feedDetails4.setPesoLixo (Double.parseDouble (responseLixeiraD.getString (KEY_FIELD4))) ؛ feedDetails4.setVolumeLixo (Double.parseDouble (responseLixeiraD.getString (KEY_FIELD4))) ؛
feedList.add (feedDetails1) ؛
feedList.add (feedDetails2) ؛ feedList.add (feedDetails3) ؛ feedList.add (feedDetails4) ؛
// Calcula dados das lixeiras
حاسبة SmartBinService = جديد SmartBinService () ؛ آلة حاسبة.
// مكونات Recupera
TextView createDate = (TextView) mainView.findViewById (R.id.date) ؛ ListView listaDeLixeiras = (ListView) findViewById (R.id.lista) ؛ adaptor.addAll (feedList) ؛
// البيانات أتوال
Date currentTime = Calendar.getInstance (). getTime () ، SimpleDateFormat simpleDate = تنسيق SimpleDateFormat الجديد ("dd / MM / yyyy") ؛ String currentDate = simpleDate.format (currentTime) ، createDate.setText (KEY_DATE + currentDate + "") ؛ listaDeLixeiras.setAdapter (محول) ؛
} catch (JSONException e) {
e.printStackTrace () ، }
} آخر {
Toast.makeText (MainActivity.this، "حدث خطأ أثناء تحميل البيانات" ، Toast. LENGTH_LONG).show () ؛
}
} }); }
Agora، na tela inicial do aplicativo، serão listados os dados de cada lixeira.
الخطوة 7: موستراندو نو مابا
Ainda na atividade teacher، vamos adicionar uma ação a ser relacionada ao botão Mapa، na tela inicial.
/ ** يتم الاتصال عند نقر المستخدم على زر Mapa * / public void openMaps (عرض العرض) {Intent intent = new Intent (this، LixeiraMapsActivity.class)؛
// Passa a lista de lixeiras
حزمة الحزمة = حزمة جديدة () ؛ bundle.putParcelableArrayList ("lixeiras"، feedList) ؛ intent.putExtras (حزمة) ؛
startActivity (intent) ؛
}
لا توجد خريطة ، تيموس تريس أتيفيداديس منفذ تنفيذي:
- marcar a posição atual do caminha de lixo
- marcar os pontos مراسلي cada lixeira no mapa
- traçar a rota entre os pontos
تطبيق تنفيذي لنظام التشغيل passos acima، vamos يستخدم واجهة برمجة تطبيقات Google الاتجاهات. Para desenhar as rotas، foram seguidos os passos do تعليمي رسم اتجاهات طريق القيادة بين موقعين باستخدام اتجاهات Google في Google Map Android API V2
Primeiro ، Vamos Criar localidades para cada um dos pontos que desejamos marcar:
// المواقع
تيار LatLng الخاص ؛
LatLng lixeiraA الخاص ؛ خاص LatLng lixeiraB ؛ خاصة LatLng lixeiraC ؛ خاصة LatLng lixeiraD ؛.
الفقرة adicionar a posição atual no mapa، foi criado o método:
checkLocationandAddToMap () {// التحقق مما إذا كان المستخدم قد منح الإذن إذا كان (ActivityCompat.checkSelfPermission (هذا ، android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission. ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// طلب إذن الموقع ActivityCompat.requestPermissions (this، new String {android. Manifest.permission. ACCESS_FINE_LOCATION}، LOCATION_REQUEST_CODE) ؛ إرجاع؛ }
// جلب آخر موقع معروف باستخدام Fus
موقع الموقع = LocationServices. FusedLocationApi.getLastLocation (googleApiClient) ؛
// MarkerOptions تستخدم لإنشاء علامة جديدة. يمكنك تحديد الموقع والعنوان وما إلى ذلك باستخدام MarkerOptions
this.current = new LatLng (location.getLatitude ()، location.getLongitude ()) ؛ MarkerOptions markerOptions = new MarkerOptions (). position (current).title ("Posição atual") ؛
// إضافة العلامة التي تم إنشاؤها على الخريطة ، وتحريك الكاميرا إلى الموضع
markerOptions.icon (BitmapDescriptorFactory.defaultMarker (BitmapDescriptorFactory. HUE_GREEN)) ؛ System.out.println ("++++++++++++++ Passei aqui! +++++++++++++") ؛ mMap.addMarker (markerOptions) ؛
// انقل الكاميرا على الفور إلى الموقع بتكبير 15.
mMap.moveCamera (CameraUpdateFactory.newLatLngZoom (الحالي ، 15)) ؛
// تكبير وتحريك الكاميرا.
mMap.animateCamera (CameraUpdateFactory.zoomTo (14)، 2000، null) ؛
}
Em seguida، para cada lixeira، foram criados métodos similares ao abaixo:
addBinALocation () باطل خاص {// التحقق مما إذا كان المستخدم قد منح الإذن إذا كان (ActivityCompat.checkSelfPermission (هذا ، android. Manifest.permission. ACCESS_FINE_LOCATION)! ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// طلب إذن الموقع ActivityCompat.requestPermissions (this، new String {android. Manifest.permission. ACCESS_FINE_LOCATION}، LOCATION_REQUEST_CODE) ؛ إرجاع؛ }
// Praça da Estação
خط عرض مزدوج = -19.9159578 ؛ خط الطول المزدوج = -43.9387856 ؛ this.lixeiraA = خط الطول والعرض الجديد ؛
MarkerOptions markerOptions = new MarkerOptions (). position (lixeiraA).title ("Lixeira A") ؛
markerOptions.icon (BitmapDescriptorFactory.defaultMarker (BitmapDescriptorFactory. HUE_RED)) ؛ mMap.addMarker (markerOptions) ؛ }
كما posições de latitude e longitude de cada lixeira foram recuperadas através do próprio Google Maps، e deixadas fixas no código. Idealmente، estes valores ficariam salvos em um banco de dados (por exemplo Firebase). Será a Primeira evolução Deste projeto!
O último passo agora é traçar as rotas entre os pontos. Para tal، um conceito muito important، e que será useizado neste projeto، são os waypoints!
Foi criado um método para traçar a rota entre dois dados pontos:
سلسلة خاصة getDirectionsUrl (أصل LatLng ، LatLng dest ، قائمة نقاط الطريق) {
// أصل الطريق
String str_origin = "origin =" + origin.latitude + "،" + origin.longitude؛
// وجهة الطريق
String str_dest = "الوجهة =" + dest.latitude + "،" + dest.longitude؛
// نقاط الطريق على طول الطريق
//waypoints=optimize:true|-19.9227365، -43.9473546 | -19.9168006، -43.9361124 نقاط مسار السلسلة = "waypoints = optimize: true"؛ لـ (LatLng point: waypointsList) {waypoints + = "|" + point.latitude + "،" + point.longitude ؛ }
// تمكين الاستشعار
مستشعر السلسلة = "sensor = false" ؛
// بناء المعلمات لخدمة الويب
معلمات السلسلة = str_origin + "&" + str_dest + "&" + مستشعر + "&" + نقاط الطريق ؛
// تنسيق الإخراج
إخراج السلسلة = "json" ؛
// بناء عنوان url لخدمة الويب
عنوان url للسلسلة = "https://maps.googleapis.com/maps/api/directions/"+output+"؟"+parameters؛ System.out.println ("++++++++++++++" + url) ؛
رابط العودة
}
E، por fim، juntando tudo no método main da classe، onMapReady:
Override public void onMapReady (GoogleMap googleMap) {mMap = googleMap؛
checkLocationandAddToMap () ،
إذا (lixeirasList.get (0).getVolumeLixo ()> Lixeira. MIN_VOLUME_GARBAGE
|| lixeirasList.get (0).getPesoLixo () - 10> Lixeira. MIN_SIZE_GARBAGE) {addBinALocation () ؛ } if (lixeirasList.get (1).getVolumeLixo ()> Lixeira. MIN_VOLUME_GARBAGE || lixeirasList.get (1).getPesoLixo ()> Lixeira. MIN_SIZE_GARBAGE) {addBinBLocation () ؛ } if (lixeirasList.get (2).getVolumeLixo ()> Lixeira. MIN_VOLUME_GARBAGE || lixeirasList.get (2).getPesoLixo ()> Lixeira. MIN_SIZE_GARBAGE) {addBinCLocation () ؛ } if (lixeirasList.get (3).getVolumeLixo ()> Lixeira. MIN_VOLUME_GARBAGE || lixeirasList.get (3).getPesoLixo ()> Lixeira. MIN_SIZE_GARBAGE) {addBinDLocation () ؛ }
// رسم المسارات
// الحصول على عنوان URL لواجهة برمجة تطبيقات اتجاهات Google
قائمة النقاط = new ArrayList ()؛ النقاط. add (lixeiraB) ؛ Points.add (lixeiraC) ؛ النقاط. add (lixeiraD) ؛
String url = getDirectionsUrl (current، lixeiraA، Points) ؛
DownloadTask downloadTask = new DownloadTask () ؛ // بدء تنزيل بيانات json من واجهة برمجة تطبيقات Google الاتجاهات downloadTask.execute (url) ؛ }
Aqui passamos apenas pelos pontos Principais. وداعا كاملا للمشروع.
الخطوة 8: Conclusão
Este foi um projeto trabalhando conceitos de IoT، mostrando uma das várias opções de conectar detitivos através da nuvem، e efetuar tomada de decisões sem interferência humana direta. Em anexo، segue um vídeo do projeto completeo، para ilustração، e os fontes das atividades criadas no Android.
موصى به:
تصميم اللعبة في فليك في 5 خطوات: 5 خطوات
تصميم اللعبة في Flick in 5 Steps: Flick هي طريقة بسيطة حقًا لصنع لعبة ، لا سيما شيء مثل الألغاز أو الرواية المرئية أو لعبة المغامرة
نظام اردوينو لتنبيه وقوف السيارة عند الرجوع للخلف - خطوات خطوة: 4 خطوات
نظام اردوينو لتنبيه وقوف السيارة عند الرجوع للخلف | خطوات بخطوة: في هذا المشروع ، سأصمم دائرة مستشعر لعكس مواقف السيارات من Arduino باستخدام مستشعر الموجات فوق الصوتية Arduino UNO و HC-SR04. يمكن استخدام نظام التنبيه العكسي للسيارة المستند إلى Arduino للتنقل الذاتي ومجموعة الروبوتات وغيرها من النطاقات
اكتشاف الوجه على Raspberry Pi 4B في 3 خطوات: 3 خطوات
اكتشاف الوجه على Raspberry Pi 4B في 3 خطوات: في هذا Instructable سنقوم باكتشاف الوجه على Raspberry Pi 4 باستخدام Shunya O / S باستخدام مكتبة Shunyaface. Shunyaface هي مكتبة للتعرف على الوجوه / الكشف عنها. يهدف المشروع إلى تحقيق أسرع سرعة في الكشف والتعرف مع
كيف تصنع عداد خطوات؟: 3 خطوات (بالصور)
How to Make Step Counter؟: اعتدت أن أؤدي أداءً جيدًا في العديد من الرياضات: المشي والجري وركوب الدراجة ولعب كرة الريشة وما إلى ذلك ، أحب ركوب الخيل للسفر في وقت قريب. حسنًا ، انظر إلى بطني المنتفخ … حسنًا ، على أي حال ، قررت إعادة التمرين. ما هي المعدات التي يجب أن أحضرها؟
SmartBin: 4 خطوات
SmartBin: الغرض الرئيسي من هذا المشروع هو إنشاء جهاز إلكتروني يستخدم Raspberry Pi واحدًا على الأقل. يتكون الفريق من 5 مهندسين ميكانيكيين في المستقبل ومهندس أتمتة واحد. يتكون مشروعنا من صنع سلة مهملات تفتح وتغلق