Cov txheej txheem:

SmartBin: 8 Kauj Ruam
SmartBin: 8 Kauj Ruam

Video: SmartBin: 8 Kauj Ruam

Video: SmartBin: 8 Kauj Ruam
Video: Gaming On Xiaomi Smart Band 8 2024, Kaum ib hlis
Anonim
SmartBin
SmartBin

Este é um projeto para um sistema inteligente de coletas, tsis muaj peev xwm os caminhões de lixo recebem dados das lixeiras, txheeb ze thiab muaj nuj nqis de lixo presente em cada uma delas, e uma rota de coleta traçada, com base nas informações recuperadas.

Nyob rau lub caij ntuj sov, nws yog qhov tsim nyog:

  • NodeMCU
  • Sensor Ultrassônico de Distancia
  • Caixa de papelão
  • Protoboard
  • Cabos
  • Dispositivo Android

Kauj ruam 1: Conectando O Sensor

Primeiramente, vamos efetuar a conexão entre o sensor ultrassônico e o NODEMCU. Piv txwv li, vamos conectar li portas trigger e ncho do sensor nas portas D4 e D3 do NodeMCU:

// txhais tus lej lej #define pino_trigger 2 // D4

#define pino_echo 0 // D3

Para efetuar a leitura dos dados sensor, foi seguido o tutorial elaborado pelo FilipeFlop, disponível aqui.

ntab cmMsec, inMsec;

ntev microsec = ultrasonic.timing ();

cmMsec = ultrasonic.convert (microsec, Ultrasonic:: CM);

inMsec = ultrasonic.convert (microsec, Ultrasonic:: IN);

// Exibe informacoes tsis muaj tus saib xyuas

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

Serial.print (cmMsec);

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

Serial.println (inMsec);

Txoj hlua cov ntaub ntawv = Txoj hlua (cmMsec);

Serial.println (cov ntaub ntawv);

Kauj Ruam 2: Montando a Lixeira

Yog lawm, cov neeg saib xyuas kev noj qab haus huv tau txais txiaj ntsig zoo. Precisaremos conectar o sensor ultrassônico no “teto” da lixeira. Los ntawm qhov ua piv txwv, siv cov cuab yeej cuab tam tshwj xeeb. Em seguida, temos que medir a distância inicial, para saber o valor para lixeira vazia. Tsis muaj meu caso, foi de 26, 3cm. Esse é o valor que considerarmos para uma lixeira vazia.

Para simulação, visto que não possuo mais de um sensor ultrassônico, foi feito um algoritmo para salvar randomicamente a distancia lida em 4 lixeiras diferentes.

// Simulando 4 lub lis piam

ntev lixeiraID;

void voj () {

lixeiraID = random (1, 5);

}

Kauj ruam 3: Upload Para a Nuvem

Agora, precisamos enviar estes dados para nuvem. Eu escolhi o ThingSpeak, rau tsev neeg sib koom los yog mesmo. Primeiramente, é necessário criar um novo kwj dej, recebendo 4 parâmetros, referentes ao volume de cada lixeira.

Pará conectar aplicação com o ThingSpeak, é necessário salvar o número da API ua kwj dej criado. Siga os passos descritos tsis muaj qhov chaw raug cai.

Nyob rau hauv cov ntaub ntawv, vamos utilizar 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).

void connectWifi () {

Serial.print ("Txuas rau"+ *ssid);

WiFi.begin (ssid, dhau);

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

ncua (500);

Serial.print (".");

}

Serial.println ("");

Serial.print ("Conectado na rede");

Serial.println (ssid);

Serial.print ("IP:");

Serial.println (WiFi.localIP ());

}

Durante o teeb tsa, lub tsev pheeb suab ntaub ntawv thiab kev sib koom ua ke.

void teeb tsa () {

Serial.begin (9600);

Serial.println ("Lendo dados ua sensor …");

// Txuas Wi-nkaus

txuasWifi ();

}

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.

void sendDataTS (ntab cmMsec, ntev id) {

yog (client.connect (server, 80)) {

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

Txoj hlua postStr = apiKey;

postStr += "& teb";

postStr += id;

postStr += "=";

postStr += Txoj hlua (cmMsec);

postStr += "\ r / n / r / n";

Serial.println (postStr);

client.print ("POST /hloov tshiab HTTP /1.1 / n");

client.print ("Tus tswv tsev: api.thingspeak.com / n");

client.print ("Kev sib txuas: kaw / n");

client.print ("X-THINGSPEAKAPIKEY:" + apiKey + "\ n");

client.print ("Cov ntsiab lus-Hom: thov/x-www-form-urlencoded / n");

client.print ("Cov ntsiab lus-Ntev:");

client.print (postStr.length ());

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

client.print (postStr);

ncua (1000);

}

client.stop (); cov.

}

O primeiro parâmetro sib tham à 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 pabcuam também para identificar para qual campo será feito o upload do valor lido.

Kauj ruam 4: Recuperando Dados Ua ThingSpeak

O ThingSpeak tso cai efetuar leitura dos dados do seu kwj dej, através de um serviço retornando um JSON. Raws li diferentes opções para leitura ua pub rau seu kwj dej estão descritas aqui

www.mathworks.com/help/thingspeak/get-a-ch…

Neste projeto, optou-se por ler diretamente os dados de cada campo. Hauv kab ntawv URL rau qhov zoo sib xws:

api.thingspeak.com/channels/CHANNEL_ID/fields/FIELD_NUMBER/last.json?api_key=API_KEY&status=true

Cada campo está descrito tsis muaj qhov txuas xov xwm yav dhau los. Os mais importantes para o projeto são:

  • CHANNEL_ID: nyob zoo cov phooj ywg
  • FIELD_NUMBER: o número do campo
  • API_KEY: chave de API ua seu kwj dej

Esta é a URL que será lida do aplicativa Android, para recuperar os dados ua ThingSpeak.

Kauj Ruam 5: Criando thiab Aplicação Android

Tsis muaj Android Studio, tsim tawm tshiab rau hauv Android. Para o correto funcionamento da aplicação, é necessário configurar as permissões abaixo no AndroidManifest.

Txhawm rau siv Google Maps, siv cov txiv maj phaub uma chave junto rau Google. Siga os passos descritos no link Obter chave de API.

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

API qhov tseem ceeb rau Google Maps-based APIs tau txhais tias yog txoj hlua siv.

(Saib cov ntawv "res/values/google_maps_api.xml").

Nco ntsoov tias tus yuam sij API txuas nrog tus yuam sij encryption siv los kos npe APK. Koj xav tau tus lej API sib txawv rau txhua tus yuam sij encryption, suav nrog tus lej tso tawm uas tau siv los kos npe APK rau tshaj tawm. Koj tuaj yeem txhais cov yuam sij rau kev debug thiab tso lub hom phiaj hauv src/debug/thiab src/release/.

<meta-cov ntaub ntawv

android: lub npe = "com.google.android.geo. API_KEY"

android: tus nqi = "@hlua /google_maps_key" />

Ib qho kev teeb tsa ua tiav raws li cov lus qhia hauv AndroidManifest anexado ao projeto.

n

Kauj Ruam 6: Recuperando O Pub Tsis Android

Yog tus thawj xibfwb tsis muaj Android, MainActivity, crie 4 variáveis para identificar cada um dos canais ua ThingSpeak a serem lidos:

private String url_a = "https://api.thingspeak.com/channels/429823/fields/1/last.json?api_key="+API_THINGSPEAK_KEY+"&status=true"; private String url_b = "https://api.thingspeak.com/channels/429823/fields/2/last.json?api_key="+API_THINGSPEAK_KEY+"&status=true"; private String url_c = "https://api.thingspeak.com/channels/429823/fields/3/last.json?api_key="+API_THINGSPEAK_KEY+"&status=true"; private String url_d = "https://api.thingspeak.com/channels/429823/fields/4/last.json?api_key="+API_THINGSPEAK_KEY+"&status=true";

Txhawm rau ua kom tau txais txiaj ntsig zoo, siv iremos siv uma classe rau Android específica, chamada JSONObject. Ntxiv rau, vamos criar um objeto para cada URL:

JSONObject tebLixeiraA; JSONObject tebLixeiraB; JSONObject tebLixeiraC; JSONObject tebLixeiraD;

Para abrir a conexão com as urls, vamos usar criar uma classe auxiliar, chamada HttpJsonParser. Esta classe será responsável por abrir uma conexão com um URL, efetuar leitura dos dad encontrados, e retornar o objeto JSON montado.

pej xeem JSONObject makeHttpRequest (Txoj hlua url, Txoj hlua txoj cai, Daim ntawv qhia chaw params) {

sim {

Uri. Builder builder = tshiab Uri. Builder (); URL urlObj; Txoj hlua encodedParams = ""; yog (params! = null) {rau (Map. Entry nkag: params.entrySet ()) {builder.appendQueryParameter (entry.getKey (), entry.getValue ()); }} yog (builder.build (). getEncodedQuery ()! = null) {encodedParams = builder.build (). getEncodedQuery ();

}

yog ("Tau".equals (txoj kev)) {url = url + "?" + encodedParams; urlObj = URL tshiab (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (txoj kev);

lwm yam {

urlObj = URL tshiab (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (txoj kev); urlConnection.setRequestProperty ("Content-Type", "application/x-www-form-urlencoded"); urlConnection.setRequestProperty ("Content-Length", String.valueOf (encodedParams.getBytes (). ntev)); urlConnection.getOutputStream (). sau (encodedParams.getBytes ()); } // Txuas rau server urlConnection.connect (); // Nyeem cov lus teb yog = urlConnection.getInputStream (); BufferedReader nyeem ntawv = tshiab BufferedReader (tshiab InputStreamReader (yog)); StringBuilder sb = tshiab StringBuilder (); Txoj hlua;

// Txheeb cais cov lus teb

thaum ((kab = nyeem ntawv.readLine ())! = null) {sb.append (kab + "\ n"); } yog.close (); json = sb.toString (); // Hloov cov lus teb rau JSON Object jObj = tshiab JSONObject (json);

} ntes (UnsupportedEncodingException e) {

e.printStackTrace (); } ntes (ProtocolException e) {e.printStackTrace (); } ntes (IOException e) {e.printStackTrace (); } ntes (JSONException e) {Log.e ("JSON Parser", "Yuam kev cais cov ntaub ntawv" + e.toString ()); } ntes (Kev zam e) {Log.e ("Kev zam", "Yuam kev cais cov ntaub ntawv" + e.toString ()); }

// rov JSON Object

rov jObj;

}

}

Los ntawm tus thawj xibfwb atividade, vamos efetuar a chamada's url de forma assíncrona, escrevendo este código dentro do método doInBackground.

@Override tiv thaiv txoj hlua doInBackground (Txoj hlua… params) {HttpJsonParser jsonParser = tshiab HttpJsonParser ();

responseLixeiraA = jsonParser.makeHttpRequest (url_a, "GET", tsis muaj)

responseLixeiraB = jsonParser.makeHttpRequest (url_b, "Tau", tsis muaj); responseLixeiraC = jsonParser.makeHttpRequest (url_c, "GET", tsis muaj) responseLixeiraD = jsonParser.makeHttpRequest (url_d, "GET", tsis muaj)

rov null;}

Quando o método doInBackgroundé encerrado, los ntawm kev tswj hwm ua tiav rau Android passa rau o método onPostExecute. Neste método, vamos criar os objetos Lixeira, e nrov com os dados recuperados ua ThingSpeak:

tiv thaiv tsis muaj dab tsi onPostExecute (Cov txiaj ntsig txoj hlua) {pDialog.dismiss (); runOnUiThread (Runnable tshiab () {pej xeem tsis muaj dab tsi khiav () {

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

Saib mainView = (Saib) findViewById (R.id.activity_main); yog (ua tiav == 1) {sim {// Cria feedDetail para cada lixeira Lixeira feedDetails1 = tshiab Lixeira (); Lixeira feedDetails2 = tshiab Lixeira (); Lixeira feedDetails3 = tshiab Lixeira (); Lixeira feedDetails4 = tshiab Lixeira ();

feedDetails1.setId ('A');

feedDetails1.setPesoLixo (Double.parseDouble (tebLixeiraA.getString (KEY_FIELD1)))); feedDetails1.setVolumeLixo (Double.parseDouble (tebLixeiraA.getString (KEY_FIELD1)));

feedDetails2.setId ('B');

feedDetails2.setPesoLixo (Double.parseDouble (tebLixeiraB.getString (KEY_FIELD2))); feedDetails2.setVolumeLixo (Double.parseDouble (tebLixeiraB.getString (KEY_FIELD2)));

feedDetails3.setId ('C');

feedDetails3.setPesoLixo (Double.parseDouble (tebLixeiraC.getString (KEY_FIELD3))); feedDetails3.setVolumeLixo (Double.parseDouble (tebLixeiraC.getString (KEY_FIELD3)));

feedDetails4.setId ('D');

feedDetails4.setPesoLixo (Double.parseDouble (responseLixeiraD.getString (KEY_FIELD4)))); feedDetails4.setVolumeLixo (Double.parseDouble (tebLixeiraD.getString (KEY_FIELD4)));

feedList.add (feedDetails1);

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

// Txheeb xyuas cov txiv neej das lixeiras

SmartBinService lub laij lej = SmartBinService tshiab (); calculator.montaListaLixeiras (feedList);

// Recupera tivthaiv

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

// Cov ntaub ntawv atual

Hnub timTimeTime = Calendar.getInstance (). GetTime (); SimpleDateFormat simpleDate = tshiab SimpleDateFormat ("dd/MM/yyyy"); Txoj hlua currentDate = simpleDate.format (currentTime); createDate.setText (KEY_DATE + currentDate + ""); listaDeLixeiras.setAdapter (adapter);

} ntes (JSONException e) {

e.printStackTrace (); }

lwm yam {

Toast.makeText (MainActivity.this, "Qee qhov yuam kev tshwm sim thaum thauj cov ntaub ntawv", Toast. LENGTH_LONG).show ();

}

} }); }

Agora, na tela inicial do aplicativo, serão listados os dados de cada lixeira.

Kauj Ruam 7: Mostrando No Mapa

Mostrando Tsis muaj Mapa
Mostrando Tsis muaj Mapa

Ua raws li tus thawj xibfwb, vamos adicionar uma ação a ser relacionada ao botão Mapa, na tela inicial.

/ ** Hu thaum tus neeg siv coj mus rhaub khawm Mapa*/ pej xeem tsis muaj dab tsi openMaps (Saib pom) {Lub hom phiaj xav = xav tshiab (qhov no, LixeiraMapsActivity.class);

// Hla ib daim ntawv teev npe lixeiras

Bundle bundle = Bundle tshiab (); bundle.putParcelableArrayList ("lixeiras", feedList); intent.putExtras (nras);

startActivity (txhob txwm);

}

Tsis muaj mapa, temos três atividades tus executar:

  1. marcar a posição atual do caminha de lixo
  2. marcar os pontos correspondentes a cada lixeira no mapa
  3. traçar a rota entre os pontos

Para executar os passos acima, vam tias siv API Google Cov Lus Qhia. Para desenhar as rotas, foram seguidos os passos do tutorial Teeb duab tsav tsheb qhia kev ntawm ob qhov chaw siv Google Cov Lus Qhia hauv Google Daim Ntawv Qhia Android API V2

Primeiro, vamos criar localidades para cada um dos pontos que desejamos marcar:

// Qhov chaw

ntiag tug LatLng tam sim no;

ntiag tug LatLng lixeiraA; ntiag tug LatLng lixeiraB; ntiag tug LatLng lixeiraC; private LatLng lixeiraD;

Txhawm rau kom ua tiav cov txiaj ntsig zoo ntawm daim ntawv qhia, ua raws cov lus qhia hauv qab no:

ntiag tug void checkLocationandAddToMap () {// Txheeb xyuas yog tias tus neeg siv tau tso cai yog (ActivityCompat.checkSelfPermission (qhov no, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPerman (no, android. ACCESS_COARSE_LOCATION! rov qab; }

// Nrhiav qhov chaw paub kawg uas siv Fus

Qhov chaw nyob = LocationServices. FusedLocationApi.getLastLocation (googleApiClient);

// MarkerOptions tau siv los tsim tus cim tshiab. Koj tuaj yeem hais qhia qhov chaw, npe thiab lwm yam nrog MarkerOptions

this.current = tshiab LatLng (qhov chaw.getLatitude (), qhov chaw.getLongitude ()); MarkerOptions markerOptions = tshiab MarkerOptions (). Txoj haujlwm (tam sim no).title ("Posição atual");

// Ntxiv qhov tsim tus cim rau ntawm daim duab qhia chaw, txav lub koob yees duab mus rau txoj haujlwm

markerOptions.icon (BitmapDescriptorFactory.defaultMarker (BitmapDescriptorFactory. HUE_GREEN)); System.out.println ("+++++++++++++ Passei aqui! +++++++++++++++"); mMap.addMarker (markerOptions);

// Tsiv lub koob yees duab tam sim ntawd mus rau qhov chaw nrog kev nthuav dav ntawm 15.

mMap.moveCamera (CameraUpdateFactory.newLatLngZoom (tam sim no, 15));

// Zoom hauv, ua kom lub koob yees duab muaj zog.

mMap.animateCamera (CameraUpdateFactory.zoomTo (14), 2000, tsis muaj dab tsi);

}

Nyob rau hauv qhov tseeb, nyob rau hauv cov ntaub ntawv ntawm lub cev, foram criados métodos similares ao abaixo:

ntiag tug void addBinALocation () {// Txheeb xyuas yog tias tus neeg siv tau tso cai yog (ActivityCompat.checkSelfPermission (qhov no, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission (qhov no, android. Manifest.per. ACCESS_COARSE_LOCATION! rov qab; }

// Tshaj tawm ntawm Estação

ob txoj kab nruab nrab = -19.9159578; ob qhov ntev = -43.9387856; this.lixeiraA = tshiab LatLng (latitude, longitude);

MarkerOptions markerOptions = tshiab MarkerOptions (). Txoj haujlwm (lixeiraA).title ("Lixeira A");

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

Raws li qhov nruab nrab txoj kab nruab nrab thiab txoj kab nruab nrab ntev ntawm cada lixeira foram recuperadas através ua próprio Google Maps, e deixadas fixas no código. Qhov zoo tshaj plaws, estes valores ficariam salvos em um banco de dados (piv txwv li Firebase). Qhov tseem ceeb ntawm kev hloov pauv mus rau txoj kev npaj!

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

Ua raws li cov lus pom zoo los ntawm tus kws kho mob hauv qab no:

private String getDirectionsUrl (keeb kwm LatLng, LatLng dest, Sau cov npe waypointsList) {

// Keeb kwm ntawm txoj kev

Txoj hlua str_origin = "keeb kwm ="+keeb kwm.latitude+","+keeb kwm.longitude;

// Lub hom phiaj ntawm txoj kev

Txoj hlua str_dest = "destination ="+dest.latitude+","+dest.longitude;

// Waypoints raws txoj kev

//waypoints=optimize:true|-19.9227365, -43.9473546 | -19.9168006, -43.9361124 String waypoints = "waypoints = optimize: true"; rau (LatLng point: waypointsList) {waypoints += "|" + point.latitude + "," + point.longitude; }

// Sensor qhib

Txoj hlua sensor = "sensor = false";

// Tsim cov kev txwv rau kev pabcuam web

Txoj hlua tsis = str_origin+"&"+str_dest+"&"+sensor+"&"+waypoints;

// Tso zis hom

Txoj hlua tso tawm = "json";

// Tsim lub url rau lub vev xaib pabcuam

Txoj hlua url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters; System.out.println ("++++++++++++++"+url);

rov qab url;

}

E, por fim, juntando tudo no método tus thawj xib fwb da classe, onMapReady:

@Override pej xeem void onMapReady (GoogleMap googleMap) {mMap = googleMap;

checkLocationandAddToMap ();

yog (lixeirasList.get (0).getVolumeLixo ()> Lixeira. MIN_VOLUME_GARBAGE

|| lixeirasList.get (0).getPesoLixo ()-10> Lixeira. MIN_SIZE_GARBAGE) {addBinALocation (); } yog (lixeirasList.get (1).getVolumeLixo ()> Lixeira. MIN_VOLUME_GARBAGE || lixeirasList.get (1).getPesoLixo ()> Lixeira. MIN_SIZE_GARBAGE) {addBinBLocation (); } yog (lixeirasList.get (2).getVolumeLixo ()> Lixeira. MIN_VOLUME_GARBAGE || lixeirasList.get (2).getPesoLixo ()> Lixeira. MIN_SIZE_GARBAGE) {addBinCLocation (); } yog (lixeirasList.get (3).getVolumeLixo ()> Lixeira. MIN_VOLUME_GARBAGE || lixeirasList.get (3).getPesoLixo ()> Lixeira. MIN_SIZE_GARBAGE) {addBinDLocation (); }

// Kos txoj kev

// Tau txais URL rau Google Cov Lus Qhia API

Sau cov ntsiab lus = tshiab ArrayList (); points.add (lixeiraB); points.add (lixeiraC); points.add (lixeiraD);

Txoj hlua url = getDirectionsUrl (tam sim no, lixeiraA, cov ntsiab lus);

DownloadTask downloadTask = tshiab DownloadTask (); // Pib rub tawm json cov ntaub ntawv los ntawm Google Cov Lus Qhia API downloadTask.execute (url); }

Aqui passamos apenas pelos pontos tus thawj tswj hwm. Nws yog qhov ua tiav ntawm cov phiaj xwm kev faib tawm rau kev sib tham.

Kauj Ruam 8: Xaus

Este foi um projeto trabalhando conceitos de IoT, mostrando uma das várias opções de conectar dispositivos através da nuvem, e efetuar tomada de decisões sem interferência humana direta. Ua ntej tshaj plaws, segue um vídeo ua projeto tiav, para ilustração, e os fontes das atividades criadas ntawm Android.

Pom zoo: