Turinys:

„SmartBin“: 8 žingsniai
„SmartBin“: 8 žingsniai

Video: „SmartBin“: 8 žingsniai

Video: „SmartBin“: 8 žingsniai
Video: Xiaomi Mi Band 8 vs Mi Band 7 2024, Lapkritis
Anonim
„SmartBin“
„SmartBin“

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

Para montar este projeto, ir mustário:

  • NodeMCU
  • Ultrassônico de Distancia jutiklis
  • Caixa de papelão
  • Protoboard
  • Kabos
  • „Android“disponavimas

1 žingsnis: „Conectando O“jutiklis

Pirminis, patogus ir lengvas jutiklis, ultrasoninis jutiklis ir NODEMCU. Para tanto, vamos conectar kaip portas trigger e echo do sensor nas portas D4 e D3 do NodeMCU:

// apibrėžia kaiščių skaičius #define pino_trigger 2 // D4

#define pino_echo 0 // D3

Naudokite jutiklį, naudokite leitura dos dados do jutiklį, naudokite jo pamoką arba mokomąją programą „FilipeFlop“, skirtą vandeniui.

plūdė cmMsec, inMsec;

ilgas mikrosekundė = ultragarsas.laikas ();

cmMsec = ultragarsinis konvertavimas (mikrosekundė, ultragarsas:: CM);

inMsec = ultragarsas.konvertuoti (mikrosekundė, ultragarsas:: IN);

// „Exibe“informacija be serijinio monitoriaus

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

Serijinis atspaudas (cmMsec);

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

Serial.println (inMsec);

Eilutės duomenys = Styga (cmMsec);

Serial.println (duomenys);

2 žingsnis: Montando ir Lixeira

Agora, vamos montar a lixeira inteligente. Iš anksto suprojektuotas jutiklis arba ultragarsinis jutiklis be „teto“da lixeira. Pavyzdžiui, naudokite „cabo e fita Isolante“. Em seguida, temos que medir a distância inicial, para saber o valor para a lixeira vazia. Nėra meo caso, 26, 3 cm. Esse é o valor que Regardrarmos para uma lixeira vazia.

Simuliacinis, visapusiškas jutiklis turi ultravioletinį jutiklį, kuris yra pagrįstas algoritmu, skirtu atsitiktiniam atsitiktinumui ir 4 distancijoms.

// Simulando 4 lixeiras

ilgas lixeiraID;

void loop () {

lixeiraID = atsitiktinis (1, 5);

}

3 veiksmas: įkelkite „Nuvem“

Agora, precisamos enviar estes dados para a nuvem. Es eshi ThingSpeak, familiaridade com o mesmo. Primeiramente, é requiredário criar um novo canal, recebendo 4 parâmetros, referentes ao volume de cada lixeira.

Parodykite „ThingSpeak“aplikatorių ir taikomąją programą, būtiną salvarą arba número da API prie kanalo. Siga os passos descritos no site official.

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

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

void connectWifi () {

Serial.print ("Prisijungimas prie"+ *ssid);

WiFi.begin (ssid, pass);

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

vėlavimas (500);

Serijinis atspaudas (".");

}

Serial.println ("");

Serial.print („Conectado na rede“);

Serial.println (ssid);

Serial.print („IP:“);

Serial.println (WiFi.localIP ());

}

Durante o setup, tentamos efetuar a conexão com a rede.

void setup () {

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.

void sendDataTS (plūdė cmMsec, ilgas ID) {

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

Serial.println („Enviando dados para o ThingSpeak“);

Styginių įrašasStr = apiKey;

postStr += "& laukas";

postStr += id;

postStr += "=";

postStr += Styga (cmMsec);

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

Serial.println (postStr);

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

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

client.print ("Ryšys: uždaryti / n");

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

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

client.print ("Turinio ilgis:");

client.print (postStr.length ());

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

client.print (postStr);

vėlavimas (1000);

}

client.stop ();

}

O „primeiro parâmetro“atitinka distanciją ir centrinius metrus, esančius pelės jutiklyje 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 identifik para para campo será feito o upload do valor lido.

4 žingsnis: atkurkite Dados Do ThingSpeak

O ThingSpeak permite efetuar leitura dos dados do seu canal, através de um serviço retornando um JSON. Kaip 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 directtamente os dados de cada campo. Arba URL adresas, esantis centre:

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. Svarbi informacija apie projektą:

  • CHANNEL_ID: número do seu kanalas
  • FIELD_NUMBER: o número do campo
  • API_KEY: „chave de API do seu“kanalas

Tai yra „Android“programos URL adresas, „ThingSpeak“rekuperatorius.

5 veiksmas: „Criando a Aplicação Android“

Nėra „Android Studio“, pradėkite kurti „Android“. Jei norite naudoti „AndroidManifest“, galite naudoti teisingą konfigūraciją ir konfigūraciją.

Naudokite „Google“žemėlapius, būtinai naudokitės „Google“paslaugomis. 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“žemėlapiais pagrįstų API API raktas yra apibrėžtas kaip eilutės šaltinis.

(Žr. Failą „res/values/google_maps_api.xml“).

Atminkite, kad API raktas yra susietas su šifravimo raktu, naudojamu APK pasirašyti. Kiekvienam šifravimo raktui reikia skirtingo API rakto, įskaitant išleidimo raktą, kuris naudojamas APK pasirašymui paskelbti. Derinimo ir išleidimo tikslų raktus galite apibrėžti src/debug/ir src/release/.

<metaduomenys

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

„Android“: value = "@string /google_maps_key" />

Užbaigta konfigūracija, skirta „AndroidManifest“aneksui.

n

6 veiksmas: atkurkite kanalą „Android“

Nėra pagrindinio „Android“, „MainActivity“, 4 versijų, skirtų identifikuoti cada um dos canais do 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";

Naudojant „Android“programas, naudojant „JSONObject“, gali būti panaudota „Android“programa. Mais uma vez, vamos criar um objeto para cada URL:

JSONObjekto atsakasLixeiraA; JSONObjekto atsakymasLixeiraB; JSONObjekto atsakymasLixeiraC; JSONObjekto atsakymasLixeiraD;

Para abrir a conexão com as url, vamos usar criar uma classe auxiliar, chamada HttpJsonParser. Esta classe seria atsakas į abrir uma conexão com um URL, efetuar leitura dos dados encontrados, e retornar or objeto JSON montado.

public JSONObject makeHttpRequest (eilutės URL, eilutės metodas, žemėlapio parametrai) {

bandyti {

Uri. Builder builder = naujas 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".lygus (metodas)) {url = url + "?" + užkoduotiParamai; urlObj = naujas URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (metodas);

} Kitas {

urlObj = naujas URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (metodas); urlConnection.setRequestProperty ("Content-Type", "application/x-www-form-urlencoded"); urlConnection.setRequestProperty ("Turinio ilgis", String.valueOf (encodedParams.getBytes (). length)); urlConnection.getOutputStream (). write (encodedParams.getBytes ()); } // Prisijungti prie serverio urlConnection.connect (); // Skaityti atsakymą yra = urlConnection.getInputStream (); BufferedReader reader = new BufferedReader (new InputStreamReader (is)); StringBuilder sb = naujas StringBuilder (); Styginių linija;

// Analizuokite atsakymą

while ((line = reader.readLine ())! = null) {sb.append (eilutė + "\ n"); } yra arti(); json = sb.toString (); // Konvertuoti atsakymą į JSON objektą jObj = new JSONObject (json);

} catch (UnsupportedEncodingException e) {

e.printStackTrace (); } sugauti (ProtocolException e) {e.printStackTrace (); } sugauti (IOException e) {e.printStackTrace (); } catch (JSONException e) {Log.e ("JSON Parser", "Klaida analizuojant duomenis" + e.toString ()); } catch (Išimtis e) {Log.e ("Išimtis", "Klaida analizuojant duomenis" + e.toString ()); }

// grąžinti JSON objektą

grįžti 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 apsaugota eilutė doInBackground (String… params) {HttpJsonParser jsonParser = naujas 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, o control of execução do Android pass para or método onPostExecute. Neste método, vamos criar os objetos Lixeira, e popular com os dados recuperados do ThingSpeak:

protected void onPostExecute (eilutės rezultatas) {pDialog.dismiss (); runOnUiThread (new Runnable () {public void run () {

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

View mainView = (View) findViewById (R.id.activity_main); if (success == 1) {try {// Cria feedDetail para cada lixeira Lixeira feedDetails1 = new Lixeira (); Lixeira feedDetails2 = nauja Lixeira (); Lixeira feedDetails3 = nauja Lixeira (); Lixeira feedDetails4 = nauja 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“skaičiuoklė = nauja „SmartBinService“(); calculator.montaListaLixeiras (feedList);

// Recupera komponentai

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

// Duomenys aktualūs

Data currentTime = Calendar.getInstance (). GetTime (); SimpleDateFormat simpleDate = naujas SimpleDateFormat ("dd/MM/yyyy"); Eilutės dabartinė data = paprasta data.formatas (dabartinis laikas); createDate.setText (KEY_DATE + currentDate + ""); listaDeLixeiras.setAdapter (adapteris);

} laimikis (JSONException e) {

e.printStackTrace (); }

} Kitas {

Toast.makeText (MainActivity.this, "Įkeliant duomenis įvyko klaida", Toast. LENGTH_LONG).show ();

}

} }); }

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

7 žingsnis: Mostrando No Mapa

Mostrando No Mapa
Mostrando No Mapa

Tai reiškia, dainų tekstai: Ainda na atividade direktorius, vamos skelbimas uma ação a ser relacionada ao botão Map, na tela inicial.

/ ** Skambinama, kai vartotojas paliečia mygtuką „Žemėlapis“*/ public void openMaps (Rodinio rodinys) {Intencijos ketinimas = naujas Intent (tai, LixeiraMapsActivity.class);

// Passa a list de lixeiras

Bundle bundle = naujas Bundle (); bundle.putParcelableArrayList ("lixeiras", feedList); aim.putExtras (paketas);

startActivity (ketinimas);

}

Nėra žemėlapio, temos três atividades a executar:

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

Vykdydami „pass pass“, naudokite „Google“nuorodų API. Vaizdo maršruto nuorodų tarp dviejų vietų piešimas naudojant „Google“nuorodas „Google“žemėlapyje „Android API V2“

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

// Vietos

privati LatLng srovė;

privati LatLng lixeiraA; privatus LatLng lixeiraB; privatus LatLng lixeiraC; privatus LatLng lixeiraD;.

Pvz., Poziciono atual no map, foi criado o método:

private void checkLocationandAddToMap () {// Tikrinama, ar vartotojas suteikė leidimą, jei (ActivityCompat.checkSelfPermission (tai, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat. Meck. Shemp. Shemp. ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Vietos leidimo ActivityCompat.requestPermissions prašymas (tai, nauja eilutė {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); grįžti; }

// Paskutinės žinomos vietos gavimas naudojant „Fus“

Vietovės vieta = LocationServices. FusedLocationApi.getLastLocation (googleApiClient);

// „MarkerOptions“naudojamos kuriant naują žymeklį. Galite nurodyti vietą, pavadinimą ir tt naudodami „MarkerOptions“

this.current = new LatLng (location.getLatitude (), location.getLongitude ()); MarkerOptions markerOptions = naujas MarkerOptions (). Pozicija (dabartinė).title ("Posição atual");

// Pridėjus sukurtą žymeklį žemėlapyje, perkeliant kamerą į vietą

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

// Nedelsdami perkelkite fotoaparatą į vietą, priartindami 15.

mMap.moveCamera („CameraUpdateFactory.newLatLngZoom“(dabartinis, 15));

// Padidinti, pagyvinti fotoaparatą.

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

}

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

private void addBinALocation () {// Tikrinama, ar vartotojas suteikė leidimą, jei (ActivityCompat.checkSelfPermission (tai, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission.html ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Vietos leidimo ActivityCompat.requestPermissions prašymas (tai, nauja eilutė {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); grįžti; }

// Praça da Estação

dviguba platuma = -19,9159578; dviguba ilguma = -43,9387856; this.lixeiraA = new LatLng (platuma, ilguma);

MarkerOptions markerOptions = naujas MarkerOptions (). Pozicija (lixeiraA).title ("Lixeira A");

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

Kaip galima platumos ir ilgumos ilgis, kad būtų galima atkurti „Google Maps“, „deixadas fixas no código“. Idealiai, estes valores ficariam salvos em um banco de dados (pavyzdžiui 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!

Žiūrėkite, ar ne taip, kaip buvo atliktas rotacinis procesas:

private String getDirectionsUrl (LatLng origin, LatLng dest, List waypointsList) {

// Maršruto kilmė

Styga str_origin = "origin ="+origin.latitude+","+origin.longitude;

// Maršruto paskirtis

Eilutė str_dest = "tikslas ="+paskirties platuma+","+paskirties ilguma;

// Kelio taškai maršrute

//waypoints=optimize:true|-19.9227365, -43.9473546 | -19.9168006, -43.9361124 Eilutės kelio taškai = "kelio taškai = optimizuoti: tiesa"; for (LatLng point: waypointsList) {waypoints += "|" + taškas. platuma + "," + taškas.ilguma; }

// Jutiklis įjungtas

Styginių jutiklis = "sensor = false";

// Parametrų kūrimas žiniatinklio paslaugai

Eilutės parametrai = str_origin+"&"+str_dest+"&"+sensor+"&"+kelio taškai;

// Išvesties formatas

Eilutės išvestis = "json";

// Kuriant žiniatinklio paslaugos URL

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

grąžinimo URL;

}

E, por fim, juntando tudo no método principas 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 (); }

// Nubrėžti maršrutus

// URL gavimas į „Google“nuorodų API

Sąrašo taškai = naujas ArrayList (); taškai.pridėti (lixeiraB); taškai.pridėti (lixeiraC); taškai.pridėti (lixeiraD);

String url = getDirectionsUrl (dabartinis, lixeiraA, taškai);

DownloadTask downloadTask = naujas DownloadTask (); // Pradėkite atsisiųsti „json“duomenis iš „Google“nurodymų API downloadTask.execute (url); }

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

8 žingsnis: „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. Tai aneksas, visas vaizdo įrašas, skirtas visam projektui, iliustracijai ir šriftui, skirtam „Android“.

Rekomenduojamas: