Talaan ng mga Nilalaman:

SmartBin: 8 Hakbang
SmartBin: 8 Hakbang

Video: SmartBin: 8 Hakbang

Video: SmartBin: 8 Hakbang
Video: ТЕПЕРЬ НЕ ПРОПАДУ 10-ть самоделок ВЫРУЧАТ ГДЕ УГОДНО! 2024, Nobyembre
Anonim
SmartBin
SmartBin

Este é um projeto para um sistema inteligente de coletas, no qual os caminhões de lixo recebem maging das lixeiras, identificando a quantidade de lixo presente em cada uma delas, e uma rota de coleta traçada, com base nas informações recuperadas.

Para sa iyong proyekto, kinakailangan:

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

Hakbang 1: Conectando O Sensor

Primeiramente, vamos efetuar a conexão entre o sensor ultrassônico e o NODEMCU. Para tanto, vamos conectar as portas trigger e echo do sensor nas portas D4 e D3 do NodeMCU:

// tumutukoy sa mga numero ng pin # tukuyin ang pino_trigger 2 // D4

#define pino_echo 0 // D3

Para sa efetuar a leitura dos magiging do sensor, mayroon ding tutorial o detalyadong impormasyon tungkol sa FilipeFlop, disponível aqui.

float cmMsec, inMsec;

mahabang microsec = ultrasonic.timing ();

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

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

// Exibe informacoes walang serial monitor

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

Serial.print (cmMsec);

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

Serial.println (inMsec);

String data = String (cmMsec);

Serial.println (data);

Hakbang 2: Montando a Lixeira

Agora, vamos montar a lixeira inteligente. Precisaremos conectar o sensor ultrassônico no “teto” da lixeira. Para sa exemplo, utilizei um cabo e fita isolante. Em seguida, temos que medir a distância inicial, para saber o valor para a lixeira vazia. Walang meu caso, foi de 26, 3cm. Ito ay ang lakas ng loob na isinasaalang-alang para sa lahat ng tao.

Para sa simulação, paningin ang mga ito na maaaring mag-isip ng sensor ng ultrassônico, upang magawa ang algorithm para sa salvar randomicamente a distancia lida em 4 lixeiras diferentes.

// Simulando 4 lixeiras

mahabang lixeiraID;

void loop () {

lixeiraID = random (1, 5);

}

Hakbang 3: Mag-upload Para sa Nuvem

Agora, precisamos enviar estes maging para a nuvem. Eu escolhi o ThingSpeak, sa pamilyar na com o mesmo. Ang Primeiramente, ay kinakailangan ng pag-uusap sa kanal, muling pagtatakda ng 4 na parirala, mga sanggunian sa dami ng mga ito.

Pará conectar a aplicação com o ThingSpeak, é mustário salvar o número da API do canal criado. Siga os passos describes walang site oficial.

Sa volta à aplicação, vamos utilizar a biblioteca ESP8266WiFi.h para sa efetuar conexão com o ThingSpeak, at transferir osimong.

Primeiramente, uma função para efetuar conexão com a rede (defina previamente duas variáveis, ssid e pass , contendo o identificador at a senha de sua rede).

walang bisa ang connectWifi () {

Serial.print ("Kumokonekta sa" + * ssid);

WiFi.begin (ssid, pass);

habang (WiFi.status ()! = WL_CONNected) {

pagkaantala (500);

Serial.print (".");

}

Serial.println ("");

Serial.print ("Conectado na rede");

Serial.println (ssid);

Serial.print ("IP:");

Serial.println (WiFi.localIP ());

}

Sa pag-setup, mag-imbak ng isang koneksyon sa isang muling gawin.

walang bisa ang pag-setup () {

Serial.begin (9600);

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

// Conectando ao Wi-Fi

connectWifi ();

}

E, para sa mga ito ay magiging para sa ThingSpeak, basta abrir uma conexão HTTP padrão, passando o número da API e os parâmetros.

walang bisa ang sendDataTS (float cmMsec, mahabang id) {

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

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

String postStr = apiKey;

postStr + = "& field";

postStr + = id;

postStr + = "=";

postStr + = String (cmMsec);

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

Serial.println (postStr);

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

client.print ("Host: api.thingspeak.com / n");

client.print ("Koneksyon: isara / n");

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

client.print ("Uri ng Nilalaman: application / x-www-form-urlencoded / n");

client.print ("Haba ng Nilalaman:");

client.print (postStr.length ());

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

client.print (postStr);

pagkaantala (1000);

}

client.stop ();

}

O primeiro parâmetro corresponde à 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 ay maihahatid sa iyo para sa pagkakakilanlan para sa kwalipikasyon ng kampo o i-upload ang iyong pagmamahal.

Hakbang 4: Ang Recuperando Dados Do ThingSpeak

O ThingSpeak permite efetuar leitura dos dados do seu canal, através de um serviço retornando um JSON. Tulad ng mga pagkakaiba-iba ng mga pagpipilian para sa leitura gawin feed gawin ang isang kanal na ito na inilalarawan sa aqui:

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

Para sa iyo, mag-optou-se por ler diretamente os maging de cada campo. O padrão de URL para sa iyo itong:

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

Cada campo está describes no link informado previamente. Mahalaga ang mga proyekto para sa iyo:

  • CHANNEL_ID: número do seu canal
  • FIELD_NUMBER: o número do campo
  • API_KEY: isang chave de API gawin ang seal kanal

Ang isang URL na ito ay maaari mong gawin sa Android, upang masulit ang iyong gawin sa ThingSpeak.

Hakbang 5: Criando a Aplicação Android

Walang Android Studio, mag-ulat ng Android. Para sa iyo upang mai-install ang app, kailangan mong i-configure bilang pinahihintulutan na walang AndroidManifest.

Para sa paggamit ng Google Maps, kailangan mong tingnan ang lahat ng Google. Siga os passos descriptitos walang link na Mawawalan ng chave de API.

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

Ang API key para sa mga API na nakabatay sa Google Maps ay tinukoy bilang isang mapagkukunan ng string.

(Tingnan ang file na "res / values / google_maps_api.xml").

Tandaan na naka-link ang key ng API sa naka-encrypt na key na ginamit upang lagdaan ang APK. Kailangan mo ng ibang API key para sa bawat key ng pag-encrypt, kasama ang susi ng paglabas na ginagamit upang lagdaan ang APK para sa pag-publish. Maaari mong tukuyin ang mga key para sa pag-debug at pakawalan ang mga target sa src / debug / at src / release /.

<meta-data

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

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

Isang configuração na kumpleto sa iyo para sa AndroidManifest anexado ao projeto.

n

Hakbang 6: Recuperando O Feed Walang Android

Na punong-punong prinsipyo ng walang Android, MainActivity, 4 na mga pagpipilian para sa pagkakakilanlan na gawin ang ThingSpeak a serem lidos:

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

Para sa efetuar a leitura dos dados, maaari mong gamitin ang lahat ng classe sa Android específica, 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. Estudyante classe será responsável por abrir uma conexão com um URL, efetuar leitura dos magiging encontrados, e retornar o objeto JSON montado.

publikong JSONObject makeHttpRequest (String url, String na pamamaraan, Mga parok ng mapa) {

subukan {

Uri. Builder builder = bagong Uri. Builder (); URL urlObj; Naka-encodeParams ang string = ""; kung (params! = null) {para sa (Map. Entry entry: params.entrySet ()) {builder.appendQueryParameter (entry.getKey (), entry.getValue ()); }} kung (builder. build (). getEncodedQuery ()! = null) {encodedParams = builder. build (). getEncodedQuery ();

}

kung ("GET".equals (pamamaraan)) {url = url + "?" + na-encodeParams; urlObj = bagong URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (pamamaraan);

} iba pa {

urlObj = bagong URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (pamamaraan); urlConnection.setRequestProperty ("Uri ng Nilalaman", "application / x-www-form-urlencoded"); urlConnection.setRequestProperty ("Haba ng Nilalaman", String.valueOf (encodedParams.getBytes (). haba)); urlConnection.getOutputStream (). isulat (encodedParams.getBytes ()); } // Kumonekta sa server urlConnection.connect (); // Basahin ang tugon ay = urlConnection.getInputStream (); Mambabasa ng BufferedReader = bagong BufferedReader (bagong InputStreamReader (ay)); StringBuilder sb = bagong StringBuilder (); Linya ng string;

// Ipa-parse ang tugon

habang ((line = reader.readLine ())! = null) {sb.append (line + "\ n"); } ay malapit(); json = sb.toString (); // I-convert ang tugon sa JSON Object jObj = bagong 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 sa pag-parse ng data" + e.toString ()); } catch (Exception e) {Log.e ("Exception", "Error sa pag-parse ng data" + e.toString ()); }

// ibalik ang JSON Object

bumalik jObj;

}

}

Ang volta isang atividade punong-guro, vamos efetuar a chamada às urls de forma assíncrona, escrevendo este código dentro do método doInBackground.

@Override protektado String doInBackground (String… params) {HttpJsonParser jsonParser = bagong HttpJsonParser ();

responseLixeiraA = jsonParser.makeHttpRequest (url_a, "GET", null);

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

ibalik ang null;}

Quando o método doInBackgroundé encerrado, o controle de execução do Android passa para o método onPostExecut. Ang mga sumusunod na artikulo, ito ay matatagpuan sa Lixeira, at ang tanyag na mga artikulo sa ThingSpeak:

protektadong walang bisa saPostExecut (String resulta) {pDialog.dismiss (); runOnUiThread (bagong Runnable () {public void run () {

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

Tingnan ang mainView = (View) findViewById (R.id.activity_main); kung (tagumpay == 1) {subukan {// Cria feedDetail para cada lixeira Lixeira feedDetails1 = bagong Lixeira (); Lixeira feedDetails2 = bagong Lixeira (); Lixeira feedDetails3 = bagong Lixeira (); Lixeira feedDetails4 = bagong 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

Calculator ng SmartBinService = bagong SmartBinService (); calculator.montaListaLixeiras (feedList);

// Mga bahagi ng Recupera

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

// Data atual

Petsa ng kasalukuyangTime = Calendar.getInstance (). GetTime (); SimpleDateFormat simpleDate = bagong SimpleDateFormat ("dd / MM / yyyy"); String currentDate = simpleDate.format (currentTime); createDate.setText (KEY_DATE + kasalukuyangDate + ""); listaDeLixeiras.setAdapter (adapter);

} catch (JSONException e) {

e.printStackTrace (); }

} iba pa {

Toast.makeText (MainActivity.this, "Ang ilang error ay naganap habang naglo-load ng data", Toast. LENGTH_LONG).show ();

}

} }); }

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

Hakbang 7: Mostrando Walang Mapa

Mostrando Walang Mapa
Mostrando Walang Mapa

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

/ ** Tinawag kapag nag-tap ang gumagamit ng pindutan ng Mapa * / publiko na walang bisa openMaps (Tingnan ang view) {Intent intensiyon = bagong Intent (ito, LixeiraMapsActivity.class);

// Passa a lista de lixeiras

Bundle bundle = bagong Bundle (); bundle.putParcelableArrayList ("lixeiras", feedList); hangarin.putExtras (bundle);

startActivity (hangarin);

}

Walang mapa, temos três atividades isang tagapagpatupad:

  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 sa pagpapatupad ng pass pass acima, gamitin ang isang Direksyon ng Google. Para desenhar as rotas, foram seguidos os passos do tutorial Pagguhit ng mga direksyon sa ruta ng pagmamaneho sa pagitan ng dalawang lokasyon gamit ang Google Direksyon sa Google Map Android API V2

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

// Lokasyon

pribadong LatLng kasalukuyang;

pribadong LatLng lixeiraA; pribadong LatLng lixeiraB; pribadong LatLng lixeiraC; pribadong LatLng lixeiraD;.

Para sa karagdagang impormasyon tungkol sa mapa, alinman sa mga ito:

pribadong void checkLocationandAddToMap () {// Sinusuri kung ang gumagamit ay nagbigay ng pahintulot kung (AktibidadCompat.checkSelfPermission (ito, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && AktibidadCompat.checkSelfPermission (ito, android. ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Humihiling ng pahintulot sa Lokasyon na aktibidadCompat.requestPermissions (ito, bagong String {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); bumalik; }

// Kinukuha ang huling kilalang lokasyon gamit ang Fus

Lokasyon ng lokasyon = LocationServices. FusedLocationApi.getLastLocation (googleApiClient);

// MarkerOptions ay ginagamit upang lumikha ng isang bagong Marker. Maaari mong tukuyin ang lokasyon, pamagat atbp sa MarkerOptions

this.current = bagong LatLng (location.getLasalam (), location.getLongitude ()); MarkerOptions markerOptions = bagong MarkerOptions (). Posisyon (kasalukuyang).title ("Posição atual");

// Pagdaragdag ng nilikha ng marker sa mapa, paglipat ng camera sa posisyon

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

// Ilipat agad ang camera sa lokasyon na may zoom na 15.

mMap.moveCamera (CameraUpdateFactory.newLatLngZoom (kasalukuyang, 15));

// Zoom in, animating the camera.

mMap.animateCamera (CameraUpdateFactory.zoomTo (14), 2000, null);

}

Em seguida, para cada lixeira, foram criados métodos similares ao abaixo:

pribadong void addBinALocation () {// Sinusuri kung ang gumagamit ay nagbigay ng pahintulot kung (AktibidadCompat.checkSelfPermission (ito, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && AktibidadCompat.checkSelfPermission (ito, android. Manifest.permit ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Humihiling ng pahintulot sa Lokasyon na aktibidadCompat.requestPermissions (ito, bagong String {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); bumalik; }

// Praça da Estação

dobleng latitude = -19.9159578; dobleng longitude = -43.9387856; this.lixeiraA = bagong LatLng (latitude, longitude);

MarkerOptions markerOptions = bagong MarkerOptions (). Posisyon (lixeiraA).title ("Lixeira A");

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

Bilang posições de latitude at longitude de cada lixeira foram recuperadas através do próprio Google Maps, at deixadas fixas no código. Idealmente, estes valores ficariam salvos em um banco de dados (por exemplo Firebase). Isang primira evolução deste projeto!

O último passo agora é traçar as rotas entre os pontos. Para sa tal, um conceito muito mahalaga, sa iyong serbisyong paggamit, maaari mong gamitin ang Waypoints!

Mag-click dito upang ma-access ang isang ruta entre dois maging pontos:

pribadong String getDirectionsUrl (pinagmulan ng LatLng, destinasyon ng LatLng, Listahan ng mga waypointsList) {

// Pinagmulan ng ruta

String str_origin = "pinagmulan =" + pinagmulan.latitude + "," + pinagmulan.longitude;

// Destinasyon ng ruta

String str_dest = "patutunguhan =" + dest.latitude + "," + dest.longitude;

// Waypoint sa kahabaan ng ruta

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

// Sensor pinagana

String sensor = "sensor = false";

// Pagbuo ng mga parameter sa serbisyo sa web

Mga parameter ng string = str_origin + "&" + str_dest + "&" + sensor + "&" + mga waypoint;

// Format ng output

String output = "json";

// Pagbuo ng url sa serbisyo sa web

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

bumalik url;

}

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

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

checkLocationandAddToMap ();

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

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

// Gumuhit ng mga ruta

// Pagkuha ng URL sa Google Directory API

List point = bagong ArrayList (); puntos.add (lixeiraB); puntos.add (lixeiraC); puntos.add (lixeiraD);

String url = getDirectionsUrl (kasalukuyang, lixeiraA, mga puntos);

DownloadTask downloadTask = bagong DownloadTask (); // Simulang mag-download ng data ng json mula sa Google Direksyon API downloadTask.execut (url); }

Aqui passamos apenas pelos pontos principais. O código completeo do projeto será disponibilizado para consulta.

Hakbang 8: Conclusão

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. Magagawa natin ito, mag-iwan ng isang proyekto upang makumpleto, para sa karagdagang impormasyon, at ang mga font na ito ay maaaring gawin para sa Android.

Inirerekumendang: