Sisukord:

SmartBin: 8 sammu
SmartBin: 8 sammu

Video: SmartBin: 8 sammu

Video: SmartBin: 8 sammu
Video: Глобальная версия Xiaomi Band 8. Полный обзор с тестами, все ПЛЮСЫ и МИНУСЫ, сравнение с Band 7 2024, November
Anonim
SmartBin
SmartBin

Este é um projeto para um süsteem inteligente de coletas, no qual os caminhões de lixo recebem dados das lixeiras, identifitseeri a quantidade de lixo presente em cada uma delas, e uma rota de coleta traçada, com base nas informationçe recuperadas.

Para montar este projeto, ja vajadus:

  • NodeMCU
  • Ultrassônico de Distancia andur
  • Caixa de papelão
  • Protoboard
  • Cabos
  • Androidi kasutamiseks

1. samm: Conectando O andur

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:

// määratleb tihvtide numbrid #define pino_trigger 2 // D4

#define pino_echo 0 // D3

Kui kasutate andurit, saate seda kasutada, õppetunde või õpetusi, mis on koostatud FilipeFlopiga, mis on mõeldud vee jaoks.

ujuk cmMsec, inMsec;

pikk mikrosekund = ultraheli.timing ();

cmMsec = ultraheli.konvert (mikrosekund, ultraheli:: CM);

inMsec = ultraheli.konvert (mikrosekund, ultraheli:: IN);

// Exibe info ei sisalda jadamonitori

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

Seeria.print (cmMsec);

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

Serial.println (inMsec);

Stringi andmed = String (cmMsec);

Serial.println (andmed);

2. samm: Montando ja Lixeira

Agora, vamos montar ja lixeira inteligente. Täpne konnektor või ultrassônico andur, millel pole "teto" da lixeira. Näiteks kasutage kaablit ja isoleeritud isolaati. 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 Regardrarmos para uma lixeira vazia.

Simulatsioonisüsteem, ultraviolettanduri anduri ultraviolettkiirguse andur, mis on võimeline kasutama algoritmi, mis võimaldab juhuslikku juhust ja distantsi lida 4 erinevat lixeiras.

// Simulando 4 lixeiras

pikk lixeiraID;

void loop () {

lixeiraID = juhuslik (1, 5);

}

Samm: laadige üles Nuvem

Agora, precisamos enviar estes dados para a nuvem. Eu eshihi või ThingSpeak, perekondlik comade või mesmo. Primeiramente, é requiredário criar um novo canal, recebendo 4 parâmetros, referentes ao volume de cada lixeira.

Paring conectar a aplicação com o ThingSpeak, e -hädavajalik salvar või número da API do canal criado. Siga os passos descritos no site official.

De volta à aplicação, vamos utilizar a biblioteca ESP8266WiFi.h for efetuar conexão com o ThingSpeak, and transferir os dados.

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

void connectWifi () {

Serial.print ("Ühendamine"+ *ssid);

WiFi.algus (ssid, pass);

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

viivitus (500);

Seeria.print (".");

}

Serial.println ("");

Serial.print ("Conectado na rede");

Serial.println (ssid);

Serial.print ("IP:");

Serial.println (WiFi.localIP ());

}

Kasutage seadistust, seadistage efekti ja kontrollige seda.

tühine seadistus () {

Seriaalne algus (9600);

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

// Ühendage Wi-Fi

connectWifi ();

}

E, para enviar os dados para või ThingSpeak, basta abrir uma conexão HTTP padrão, passando o número da API e os parâmetros.

void sendDataTS (float cmMsec, long id) {

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

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

String postStr = apiKey;

postStr += "& väli";

postStr += id;

postStr += "=";

postStr += String (cmMsec);

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

Serial.println (postStr);

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

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

client.print ("Ühendus: sulge / n");

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

client.print ("Content-Type: application/x-www-form-urlencoded / n");

client.print ("Sisu-pikkus:");

klient.print (postStr.length ());

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

klient.print (postStr);

viivitus (1000);

}

klient.peatus ();

}

O primeiro parâmetro vastab distantsile ja tsentrifuugile, mis sisaldab peensooli 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 serve também para identific para kval campo será feito o upload do valor lido.

Samm 4: Recuperando Dados Do ThingSpeak

O ThingSpeak permite efetuar leitura dos dados do seu canal, através de um serviço retornando um JSON. Nagu erinevad optsõ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 directtamente os dados de cada campo. Ootame URL -i para cen cenio:

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. Os mais tähtsad para või projeto são:

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

See on Android -i rakenduse URL -i ja ThingSpeak -i toiteallikas.

Samm 5: Criando ja Aplicação Android

Android -stuudio puudub, andke Androidile uus projekt. Para või korrektne funktsionaalsus aplicação, vajadus konfigureerida kui lubada abaixo no AndroidManifest.

Kasutage Google Mapsi või Google’i ja Google'i teenuseid. Siga os passos descritos no link Obter chave de API.

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

Google Mapsi-põhiste API-de API-võti on määratletud stringiressursina.

(Vt faili "res/values/google_maps_api.xml").

Pange tähele, et API -võti on seotud APK allkirjastamiseks kasutatud krüptimisvõtmega. Teil on vaja iga krüptimisvõtme jaoks erinevat API -võtit, sealhulgas vabastusvõtit, mida kasutatakse APK avaldamiseks allkirjastamiseks. Silumise ja vabastamise sihtmärkide võtmed saate määrata failides src/debug/ja src/release/.

<metaandmed

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

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

Täielik konfiguratsioon, mis on loodud AndroidManifest anexado jaoks.

n

6. toiming: O -voo taastamine Androidi puudumine

Kui teil pole Androidi, MainActivity'i, 4 versiooni, saate tuvastada 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";

Efekti ja leitura dos dados, iremos utilizar uma classe do Android específica, chamada JSONObject. Mais uma vez, vamos criar um objeto para cada URL:

JSONObjekti vastusLixeiraA; JSONObjekti vastusLixeiraB; JSONObjekti vastusLixeiraC; JSONObjekti vastusLixeiraD;

Para abrir a conexão com as urls, vamos usar criar uma classe auxiliar, chamada HttpJsonParser. Estaclasse sera vastus on abrir uma conexão com um URL, efetuar leitura dos dados encontrados, e retornar or objeto JSON montado.

public JSONObject makeHttpRequest (stringi URL, stringi meetod, kaardi parameetrid) {

proovi {

Uri. Builder builder = uus Uri. Builder (); URL 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 (meetod)) {url = url + "?" + kodeeritudParams; urlObj = uus URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (meetod);

} muud {

urlObj = uus URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (meetod); urlConnection.setRequestProperty ("Content-Type", "application/x-www-form-urlencoded"); urlConnection.setRequestProperty ("Content-Length", String.valueOf (encodedParams.getBytes (). length)); urlConnection.getOutputStream (). write (encodedParams.getBytes ()); } // Ühenda serveriga urlConnection.connect (); // Vastuse lugemine on = urlConnection.getInputStream (); BufferedReader lugeja = new BufferedReader (uus InputStreamReader (on)); StringBuilder sb = uus StringBuilder (); Stringijoon;

// Sõeluda vastus

while ((rida = lugeja.lugemine ())! = null) {sb.append (rida + "\ n"); } is.close (); json = sb.toString (); // Teisenda vastus JSON -objektiks jObj = new JSONObject (json);

} saak (UnsupportedEncodingException e) {

e.printStackTrace (); } saak (ProtocolException e) {e.printStackTrace (); } saak (IOException e) {e.printStackTrace (); } catch (JSONException e) {Log.e ("JSON Parser", "Viga andmete parsimisel" + e.toString ()); } catch (Erand e) {Log.e ("Erand", "Viga andmete parsimisel" + e.toString ()); }

// tagasta JSON -objekt

tagasi jObj;

}

}

De volta a atividade princip, vamos efetuar a chamada às urls de forma assíncrona, escrevendo este código dentro do método doInBackground.

@Override kaitstud string doInBackground (String… params) {HttpJsonParser jsonParser = uus 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);

return null;}

Quando o método doInBackgroundé encerrado, või control of execução do Android passage or metod on on PostExecute. Neste método, vamos criar os objetos Lixeira, e popular com os dados recuperados do ThingSpeak:

protected void onPostExecute (Stringi tulemus) {pDialog.dismiss (); runOnUiThread (uus Runnable () {public void run () {

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

Vaata mainView = (Vaata) findViewById (R.id.activity_main); if (edu == 1) {try {// Cria feedDetail para cada lixeira Lixeira feedDetails1 = new Lixeira (); Lixeira feedDetails2 = uus Lixeira (); Lixeira feedDetails3 = uus Lixeira (); Lixeira feedDetails4 = uus 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 kalkulaator = uus SmartBinService (); calculator.montaListaLixeiras (feedList);

// Taastuskomponendid

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

// Andmete aktuaalne

Kuupäev currentTime = Calendar.getInstance (). GetTime (); SimpleDateFormat simpleDate = uus SimpleDateFormat ("pp/kk/aaaa"); String currentDate = simpleDate.format (currentTime); createDate.setText (KEY_DATE + currentDate + ""); listaDeLixeiras.setAdapter (adapter);

} saak (JSONException e) {

e.printStackTrace (); }

} muud {

Toast.makeText (MainActivity.this, "Andmete laadimisel ilmnes tõrge", Toast. LENGTH_LONG).show ();

}

} }); }

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

Samm 7: Mostrando No Mapa

Mostrando No Mapa
Mostrando No Mapa

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

/ ** Helistatakse, kui kasutaja puudutab nuppu Mapa*/ public void openMaps (Kuva vaade) {Intent aim = new Intent (this, LixeiraMapsActivity.class);

// Passa a list de lixeiras

Bundle bundle = new Bundle (); bundle.putParcelableArrayList ("lixeiras", feedList); aim.putExtras (kimp);

startActivity (kavatsus);

}

Pole kaarti, temos três atividades a executar:

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

Kasutage täidesaatva täideviimise korral Google'i juhiste API -d. Para desenhar as rotas, foram seguidos os passos do tutorial Sõidumarsruudi juhiste joonistamine kahe asukoha vahel, kasutades Google'i juhiseid rakenduses Google Map Android API V2

Primeiro, vamos criar localidades para cada um dos täp que desejamos marcar:

// Asukohad

privaatne LatLng vool;

privaatne LatLng lixeiraA; privaatne LatLng lixeiraB; privaatne LatLng lixeiraC; era LatLng lixeiraD;.

Kui soovite, et kaart pole saadaval, siis võib see olla:

private void checkLocationandAddToMap () {// Kontrollimine, kas kasutaja on loa andnud, kui (ActivityCompat.checkSelfPermission (see, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat. Meach. ChempSystem, ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Asukohaloa taotlemine ActivityCompat.requestPermissions (see, uus string {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); tagasipöördumine; }

// Viimase teadaoleva asukoha toomine Fusi abil

Asukoha asukoht = LocationServices. FusedLocationApi.getLastLocation (googleApiClient);

// MarkerOptions kasutatakse uue Markeri loomiseks. MarkerOptions abil saate määrata asukoha, pealkirja jne

this.current = uus LatLng (location.getLatitude (), location.getLongitude ()); MarkerOptions markerOptions = uus MarkerOptions (). Position (current).title ("Posição atual");

// Loodud markeri lisamine kaardile, kaamera liigutamine asendisse

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

// Liigutage kaamera koheselt asukohta 15 -kordse suumiga.

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

// Suurendamine, kaamera animeerimine.

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

}

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

private void addBinALocation () {// Kontrollimine, kas kasutaja on loa andnud, kui (ActivityCompat.checkSelfPermission (see, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission.html, ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Asukohaloa taotlemine ActivityCompat.requestPermissions (see, uus string {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); tagasipöördumine; }

// Praça da Estação

kahekordne laiuskraad = -19,9159578; topeltpikkus = -43,9387856; this.lixeiraA = uus LatLng (laius- ja pikkuskraadid);

MarkerOptions markerOptions = new MarkerOptions (). Position (lixeiraA).title ("Lixeira A");

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

Nagu positiivi laiuskraad ja pikkuskraad de cada lixeira foram recuperadas através do próprio Google Maps, e deixadas fixas no código. Ideaalne, parim valik ficariam salvos em um banco de dados (näiteks 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, e que será utilizado neste projeto, são os Waypoints!

Tähendab lyrics: Foi criado um método para traçar a rota entre dois dados täpne:

privaatstring getDirectionsUrl (LatLng päritolu, LatLng sihtkoht, teekonnapunktide loendi loend) {

// Marsruudi päritolu

String str_origin = "päritolu ="+päritolu.laius+","+päritolu.pikkus;

// Marsruudi sihtkoht

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

// Teekonnapunktid marsruudil

//waypoints=optimize:true|-19.9227365, -43.9473546 | -19.9168006, -43.9361124 Stringi teekonnapunktid = "teekonnapunktid = optimeeri: tõsi"; for (LatLng point: waypointsList) {waypoints += "|" + punkt.laiuskraad + "," + punkt.pikkuskraad; }

// Andur lubatud

Stringiandur = "sensor = false";

// Parameetrite loomine veebiteenusele

Stringi parameetrid = str_origin+"&"+str_dest+"&"+sensor+"&"+teekonnapunktid;

// Väljundvorming

Stringi väljund = "json";

// URL -i loomine veebiteenusele

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

tagastamise URL;

}

E, por fim, juntando tudo no método princip da dalasse, onMapReady:

@Orride 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 (); }

// Joonista marsruute

// URL -i hankimine Google'i juhiste API -le

Loendipunktid = uus ArrayList (); points.add (lixeiraB); points.add (lixeiraC); points.add (lixeiraD);

String url = getDirectionsUrl (praegune, lixeiraA, punktid);

DownloadTask downloadTask = uus DownloadTask (); // Alusta json -andmete allalaadimist Google Directions API -lt downloadTask.execute (url); }

Aqui passamos apenas pelos täpne põhimõte. O código complete to do projeto será disponibilizado para consulta.

8. samm: 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 directta. Em anexo, segm videomängude täielikuks projekteerimiseks, illustratsiooniks, e -kirjadeks ja Androidi jaoks.

Soovitan: