فهرست مطالب:

SmartBin: 8 مرحله
SmartBin: 8 مرحله

تصویری: SmartBin: 8 مرحله

تصویری: SmartBin: 8 مرحله
تصویری: Mi Band 8 International : Scientific Test 2024, نوامبر
Anonim
SmartBin
SmartBin

سیستم شما را برای سیستم های اطلاعاتی coletas، no qual os caminhões de lixo recebem dados das lixeiras، identicalando and quantidade de lixo presente em cada uma delas، e uma rota de coleta traçada، com base nas informações recuperadas معرفی می کند.

Para montar este projeto، ضروری است:

  • NodeMCU
  • سنسور Ultrassônico de Distancia
  • Caixa de papelão
  • پروتو بورد
  • کابوس
  • Dispositivo اندروید

مرحله 1: سنسور Conectando O

در ابتدا ، می توانید از یک سنسور فوق العاده و NODEMCU استفاده کنید. به طور مستقیم، vamos conectar as portas trigger echo do sensor nas portas D4 e D3 do NodeMCU:

// تعداد پین ها را تعریف می کند #تعریف pino_trigger 2 // D4

#تعریف pino_echo 0 // D3

برای دریافت اطلاعات بیشتر در مورد سنسورها، آموزش بیشتر در زمینه آموزش FilipeFlop، disponível aqui.

شناور cmMsec ، inMsec ؛

microsec طولانی = ultrasonic.timing ()؛

cmMsec = ultrasonic.convert (microsec ، Ultrasonic:: CM) ؛

inMsec = ultrasonic.convert (microsec ، Ultrasonic:: IN) ؛

// Exibe informacoes هیچ مانیتور سریالی ندارد

Serial.print ("Distancia em cm:")؛

Serial.print (cmMsec) ؛

Serial.print (" - Distancia em polegadas:")؛

Serial.println (inMsec) ؛

داده های رشته = رشته (cmMsec) ؛

Serial.println (داده) ؛

مرحله 2: Montando a Lixeira

Agora، vamos montar a lixeira inteligente. Precisaremos conectar o sensor ultrassônico no “teto” da lixeira. برای مثال ، از um cabo e fita isolante استفاده کنید. Em seguida، temos que medir a distância inicial، para saber o valor para a lixeira vazia. No meu caso، foi de 26، 3cm. Esse é o valor que ignrarmos para uma lixeira vazia.

برای شبیه سازی ، می توانید از طریق یک سنسور ultrassônico ، به طور کامل به صورت تصادفی به عنوان یک فاصله بین 4 مورد مختلف از یکدیگر استفاده کنید.

// Simulando 4 lixeiras

long lixeiraID؛

حلقه خالی () {

lixeiraID = تصادفی (1 ، 5) ؛

}

مرحله 3: Para a Nuvem را بارگذاری کنید

Agora، precisamos enviar estes dados para a nuvem. Eu escolhi o ThingSpeak، por familiaridade com o mesmo. Primeiramente، é ضروری criar um novo canal، recebendo 4 parâmetros، referentes ao volume de cada lixeira.

Pará conectar a aplicação com o ThingSpeak ، ضروری است که از طریق API به کانال criado کمک کنید. Siga os passos descritos بدون سایت رسمی.

De volta à aplicação، vamos use a biblioteca ESP8266WiFi.h برای دسترسی بیشتر به 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).

void connectWifi () {

Serial.print ("اتصال به"+ *ssid) ؛

WiFi.begin (ssid ، pass) ؛

while (WiFi.status ()! = WL_CONNECTED) {

تأخیر (500) ؛

Serial.print (".") ؛

}

Serial.println ("")؛

Serial.print ("Conectado na rede")؛

Serial.println (ssid)؛

Serial.print ("IP:")؛

Serial.println (WiFi.localIP ()) ؛

}

در هنگام راه اندازی ، سعی کنید از یک comexde استفاده کنید.

void setup () {

Serial.begin (9600)؛

Serial.println ("Lendo dados do sensor …") ؛

// Conectando ao Wi-Fi

connectWifi () ؛

}

E، para enviar os dados para o ThingSpeak، برنامه های HTTP padrão، passando o número da API e os parimmetros.

void sendDataTS (شناور cmMsec ، شناسه طولانی) {

if (client.connect (سرور ، 80)) {

Serial.println ("Enviando dados para o ThingSpeak")؛

رشته postStr = apiKey؛

postStr += "& فیلد"؛

postStr += id؛

postStr += "="؛

postStr += رشته (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 ("Content-Length:")؛

client.print (postStr.length ())؛

client.print ("\ n / n")؛

client.print (postStr)؛

تاخیر (1000) ؛

}

client.stop ()؛

}

O primeiro parâmetrorespond à distância em centímetros encontrada pelo sensor ultrassônico. O segundo parâmetro é o ID da lixeira que foi lida (que foi gerado randomicamente، um número de 1 a 4).

O ID da lixeira برای اطلاع از ویژگی های لازم برای بارگذاری و ارتقاء ارزش خدمات رسانی کنید.

مرحله 4: Recuperando Dados Do ThingSpeak را انجام دهید

O ThingSpeak permite efetuar leitura dos dados do seu canal، através de um serviço retornando um JSON. As diferentes opções para leitura do feed do seu canal estão descritas aqui:

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 بدون پیوند اطلاعاتی پیشگیرانه است. Os mais importantes para o projeto são:

  • CHANNEL_ID: número do seu canal
  • FIELD_NUMBER: o número do campo
  • API_KEY: a chave de API do seu canal

این یک URL است که به شما اجازه می دهد تا Android را نصب کنید ، برای بازیابی سیستم عامل ThingSpeak.

مرحله 5: Criando and Aplicação Android

اندروید استودیو وجود ندارد ، برنامه اندروید را نصب کنید. برای استفاده از این برنامه ، باید پیکربندی را به عنوان اجازه انجام بدون AndroidManifest انجام دهید.

برای استفاده از Google Maps ، لازم است که از Google یا Google استفاده کنید. Siga os passos descritos بدون پیوند Obter chave de API.

Uma vez com a chave، você deve também configurá-la na aplicação.

کلید API برای API های مبتنی بر Google Maps به عنوان منبع رشته تعریف شده است.

(فایل "res/values/google_maps_api.xml" را ببینید).

توجه داشته باشید که کلید API به کلید رمزگذاری استفاده می شود که برای امضای APK استفاده می شود. شما برای هر کلید رمزگذاری به یک کلید API متفاوت نیاز دارید ، از جمله کلید انتشار که برای امضای APK برای انتشار استفاده می شود. می توانید کلیدهای اشکال زدایی و انتشار اهداف را در src/debug/و src/release/تعریف کنید.

<فرا داده

android: name = "com.google.android.geo. API_KEY"

android: value = "@string /google_maps_key" />

یک پیکربندی کامل برای سیستم عامل AndroidManifest anexado ao projeto است.

n

مرحله 6: Recuperando O Feed No Android

Na atividade principal no Android، MainActivity، crie 4 vari paraveis para identicalar cada um dos canais do ThingSpeak a serem lidos:

رشته خصوصی 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" ؛

برای دسترسی آسان به برنامه های کاربردی ، استفاده از سیستم عامل اندروید ، chamada JSONObject را انجام دهید. Mais uma vez، vamos criar um objeto para cada URL:

JSONObject responseLixeiraA؛ JSONObject responseLixeiraB؛ JSONObject responseLixeiraC؛ JSONObject responseLixeiraD؛

Para abrir a conexão com as urls، vamos usar criar uma classe auxiliar، chamada HttpJsonParser. برای دسترسی سریعتر به آدرس URL ، دسترسی سریع به پرونده و دسترسی سریع به JSON montado ، از طریق آدرس زیر وارد شوید.

public JSONObject makeHttpRequest (آدرس رشته ، روش رشته ، پارامترهای نقشه) {

تلاش كردن {

Uri. Builder builder = new Uri. Builder ()؛ آدرس urlObj؛ String 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 ()؛

}

if ("GET".equals (method)) {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 ("Content-Length"، String.valueOf (encodedParams.getBytes (). طول))؛ urlConnection.getOutputStream (). بنویسید (encodedParams.getBytes ()) ؛ } // اتصال به سرور urlConnection.connect ()؛ // خواندن پاسخ is = urlConnection.getInputStream ()؛ BufferedReader reader = BufferedReader جدید (InputStreamReader جدید (هست)) ؛ StringBuilder sb = جدید StringBuilder ()؛ خط رشته ؛

// تجزیه پاسخ

while ((line = reader.readLine ())! = null) {sb.append (خط + "\ n") ؛ } نزدیک است()؛ json = sb.toString ()؛ // تبدیل پاسخ به JSON Object jObj = new JSONObject (json)؛

} catch (UnsupportedEncodingException e) {

e.printStackTrace ()؛ } catch (ProtocolException e) {e.printStackTrace ()؛ } catch (IOException e) {e.printStackTrace ()؛ } catch (JSONException e) {Log.e ("JSON Parser" ، "Error parsing data" + e.toString ()) ؛ } catch (استثنا ه) {Log.e ("استثنا" ، "خطا در تجزیه داده ها" + e.toString ()) ؛ }

// بازگشت JSON Object

بازگشت jObj؛

}

}

De volta a atividade main، vamos efetuar a chamada às urls de forma assíncrona، escrevendo este código dentro do metodo doInBackground.

Override String doInBackground (String … params) محافظت شده {HttpJsonParser jsonParser = new HttpJsonParser ()؛

respondLixeiraA = jsonParser.makeHttpRequest (url_a ، "GET" ، null) ؛

respondLixeiraB = jsonParser.makeHttpRequest (url_b ، "GET" ، null) ؛ respondLixeiraC = jsonParser.makeHttpRequest (url_c ، "GET" ، null) ؛ respondLixeiraD = jsonParser.makeHttpRequest (url_d ، "GET" ، null) ؛

بازگشت null؛}

Quando o método doInBackgroundé encerrado ، o controle de execução do Android passa para an metodo onPostExecute. Neste método، vamos criar os objetos Lixeira، e popular com os dados recuperados do ThingSpeak:

محافظت از خلاء onPostExecute (نتیجه رشته) {pDialog.dismiss ()؛ runOnUiThread (Runnable جدید () {اجرای عمومی خالی () {

// ListView listView = (ListView) findViewById (R.id.feedList) ؛

مشاهده mainView = (مشاهده) findViewById (R.id.activity_main)؛ if (success == 1) {try {// Cria feedDetail para cada lixeira Lixeira feedDetails1 = جدید Lixeira ()؛ Lixeira feedDetails2 = Lixeira جدید ()؛ Lixeira feedDetails3 = جدید Lixeira ()؛ Lixeira feedDetails4 = Lixeira جدید ()؛

feedDetails1.setId ('A')؛

feedDetails1.setPesoLixo (Double.parseDouble (respondLixeiraA.getString (KEY_FIELD1)))) ؛ feedDetails1.setVolumeLixo (Double.parseDouble (respondLixeiraA.getString (KEY_FIELD1)))) ؛

feedDetails2.setId ('B')؛

feedDetails2.setPesoLixo (Double.parseDouble (respondLixeiraB.getString (KEY_FIELD2)))) ؛ feedDetails2.setVolumeLixo (Double.parseDouble (respondLixeiraB.getString (KEY_FIELD2)))) ؛

feedDetails3.setId ('C')؛

feedDetails3.setPesoLixo (Double.parseDouble (respondLixeiraC.getString (KEY_FIELD3)))) ؛ feedDetails3.setVolumeLixo (Double.parseDouble (respondLixeiraC.getString (KEY_FIELD3)))) ؛

feedDetails4.setId ("D") ؛

feedDetails4.setPesoLixo (Double.parseDouble (respondLixeiraD.getString (KEY_FIELD4)))) ؛ feedDetails4.setVolumeLixo (Double.parseDouble (respondLixeiraD.getString (KEY_FIELD4)))) ؛

feedList.add (feedDetails1) ؛

feedList.add (feedDetails2) ؛ feedList.add (feedDetails3) ؛ feedList.add (feedDetails4) ؛

// محاسبه dados das lixeiras

ماشین حساب SmartBinService = SmartBinService جدید ()؛ calculator.montaListaLixeiras (feedList) ؛

// اجزای Recupera

TextView createDate = (TextView) mainView.findViewById (R.id.date) ؛ ListView listaDeLixeiras = (ListView) findViewById (R.id.lista) ؛ adapter.addAll (feedList) ؛

// داده ها atual

date currentTime = Calendar.getInstance (). getTime ()؛ SimpleDateFormat simpleDate = جدید SimpleDateFormat ("dd/MM/yyyy") ؛ رشته currentDate = simpleDate.format (currentTime) ؛ createDate.setText (KEY_DATE + currentDate + "") ؛ listaDeLixeiras.setAdapter (آداپتور) ؛

} گرفتن (JSONException e) {

e.printStackTrace ()؛ }

} دیگری {

Toast.makeText (MainActivity.this ، "هنگام بارگذاری داده ها خطایی رخ داد" ، Toast. LENGTH_LONG).show ()؛

}

} }); }

Agora، na tela inicial do aplicativo، ser listo listados os dados de cada lixeira.

مرحله 7: Mostrando No Mapa

Mostrando No Mapa
Mostrando No Mapa

Ainda na atividade principal، vamos adicionar uma ação a ser relacionada ao botão Mapa، na tela inicial.

/ ** وقتی کاربر روی دکمه Mapa ضربه می زند*/ public void openMaps (مشاهده نمای) {Intent قصد = new Intent (این ، LixeiraMapsActivity.class) ؛ فراخوانی می شود.

// Passa a lista de lixeiras

بسته نرم افزاری = بسته جدید ()؛ bundle.putParcelableArrayList ("lixeiras" ، feedList) ؛ qëllim.putExtras (بسته نرم افزاری) ؛

startActivity (قصد) ؛

}

بدون نقشه ، temos três atividades a اجرا کننده:

  1. marcar a posição atual do caminha de lixo
  2. marcar os pontos خبرنگار cada lixeira no mapa است
  3. traçar a rota entre os pontos

برای اجرای osos passos acima ، vamos از API Google Directions استفاده کنید. برای پیش بینی برنامه های کاربردی ، آموزش ترسیم مسیرهای رانندگی بین دو مکان با استفاده از Google Directions در 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؛.

برای پیوستن به هیچ گونه نقشه ، foi criado یا metodo:

خصوصی خلأ چک ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// درخواست مجوز فعالیت ActivityCompat.requestPermission (این ، رشته جدید {android. Manifest.permission. ACCESS_FINE_LOCATION} ، LOCATION_REQUEST_CODE) ؛ برگشت؛ }

// واکشی آخرین مکان شناخته شده با استفاده از Fus

موقعیت مکانی = LocationServices. FusedLocationApi.getLastLocation (googleApiClient) ؛

// MarkerOptions برای ایجاد یک نشانگر جدید استفاده می شود. شما می توانید مکان ، عنوان و غیره را با MarkerOptions مشخص کنید

this.current = جدید LatLng (location.getLatitude () ، location.getLongitude ()) ؛ MarkerOptions markerOptions = MarkerOptions جدید (). موقعیت (فعلی).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:

private void addBinALocation () {// بررسی اینکه آیا کاربر اجازه (if ActivityCompat.checkSelfPermission (this، android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission (. این ، ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// درخواست مجوز فعالیت ActivityCompat.requestPermission (این ، رشته جدید {android. Manifest.permission. ACCESS_FINE_LOCATION} ، LOCATION_REQUEST_CODE) ؛ برگشت؛ }

// Praça da Estação

عرض جغرافیایی دو برابر = -19.9159578 ؛ طول جغرافیایی دو برابر = -43.9387856 ؛ this.lixeiraA = LatLng جدید (عرض جغرافیایی ، طول جغرافیایی) ؛

MarkerOptions markerOptions = MarkerOptions جدید (). position (lixeiraA).title ("Lixeira A")؛

markerOptions.icon (BitmapDescriptorFactory.defaultMarker (BitmapDescriptorFactory. HUE_RED)) ؛ mMap.addMarker (markerOptions) ؛ }

همانطور که در عرض جغرافیایی و طول جغرافیایی در نظر گرفته می شود ، می توانید از نقشه های گوگل استفاده کنید ، و هیچ گونه برنامه ای را برای آن تعیین نکنید. Idealmente، estes valores ficariam salvos em um banco de dados (برای مثال Firebase). Será a primeira evolução deste projeto!

O último passo agora é traçar as rotas entre os pontos. Para tal، um conceito muito importante، and que será utilisado neste projeto، são os Waypoints!

Foi criado um método para traçar a rota entre dois dados pontos:

رشته خصوصی getDirectionsUrl (مبدا LatLng ، LatLng dest ، List waypointsList) {

// مبدا مسیر

String str_origin = "origin ="+origin.latitude+"،"+origin.longitude؛

// مقصد مسیر

String str_dest = "destination ="+dest.latitude+"،"+dest.longitude؛

// نقاط مسیر در طول مسیر

//waypoints=optimize:true|-19.9227365، -43.9473546 | -19.9168006، -43.9361124 String waypoints = "waypoints = optimize: true"؛ for (نقطه LatLng: waypointsList) {waypoints += "|" + point.latitude + "،" + point.longitude؛ }

// سنسور فعال است

حسگر رشته = "sensor = false"؛

// ایجاد پارامترهای سرویس وب

پارامترهای رشته = str_origin+"&"+str_dest+"&"+sensor+"&"+waypoints؛

// فرمت خروجی

خروجی رشته = "json"؛

// ساخت url به سرویس وب

url رشته = "https://maps.googleapis.com/maps/api/directions/"+output+"؟"+ پارامترها ؛ System.out.println ("++++++++++++++++"+url) ؛

url بازگشت ؛

}

E، por fim، juntando tudo no método principal da classe، onMapReady:

Override public void onMapReady (GoogleMap googleMap) {mMap = googleMap؛

checkLocationandAddToMap ()؛

if (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 به API Google Directions

نقاط لیست = ArrayList جدید ()؛ points.add (lixeiraB) ؛ points.add (lixeiraC) ؛ points.add (lixeiraD) ؛

url رشته = getDirectionsUrl (جاری ، lixeiraA ، نقاط) ؛

DownloadTask downloadTask = جدید DownloadTask ()؛ // شروع به بارگیری داده های json از Google Directions API downloadTask.execute (url) ؛ }

Aqui passamos apenas pelos pontos principais. O código completeo do projeto será disponibilizado برای مشاوره انجام دهید.

مرحله 8: نتیجه گیری

Este foi um projeto trabalhando conceitos de IoT، mostrando uma das várias opções de conectar dispositivos através da nuvem، efetuar tomada de decisões sem interferência humana direta. با استفاده از این برنامه، می توان به طور کامل برنامه های کاربردی خود را، برای مثال ها، و فونت های موجود در کریاداهای بدون سیستم عامل اندروید استفاده کرد.

توصیه شده: