Obsah:

SmartBin: 8 kroků
SmartBin: 8 kroků

Video: SmartBin: 8 kroků

Video: SmartBin: 8 kroků
Video: Xiaomi Smart Band 8: Najlepší fitnes náramok do 50 eur (RECENZIA) 2024, Listopad
Anonim
SmartBin
SmartBin

Jedná se o inteligentní systém, který nemá žádné možnosti přijímat různé verze, identifikovat a kvantifikovat lixo prezentovat em cada uma delas, e uma rota de coleta traçada, com base nas informações rekuperadas.

Para montar este projeto, é needário:

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

Krok 1: Senzor Conectando O

Primeiramente, vamos efetuar and 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:

// definuje čísla pinů #define pino_trigger 2 // D4

#define pino_echo 0 // D3

Para efetuar a leitura dos dados do sensor, foi seguido or tutorial elaborado pelo FilipeFlop, disponibilel aqui.

float cmMsec, inMsec;

dlouhý microsec = ultrasonic.timing ();

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

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

// Exibe informacoes no serial monitor

Serial.print ("Vzdálenost em cm:");

Serial.print (cmMsec);

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

Serial.println (inMsec);

Řetězcová data = Řetězec (cmMsec);

Serial.println (data);

Krok 2: Montando a Lixeira

Agora, montá a inteligentní inteligentní. Přesné připojení nebo ultrassônico senzor bez „teto“da lixeira. Para o exemplo, use camo e fita isolante. Em seguida, temos que medir a distância inicial, para saber o valor para a lixeira vazia. Žádné meu caso, foi de 26, 3 cm. 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 randomicament a distancia lida em 4 lixeiras differententes.

// Simulando 4 lixeiras

dlouhý lixeiraID;

prázdná smyčka () {

lixeiraID = náhodný (1, 5);

}

Krok 3: Nahrajte Para a Nuvem

Agora, precisamos enviar estes dados para a nuvem. Eu escolhi o ThingSpeak, nebo známém setkání o mesmo. Primeiramente, é needário criar um novo canal, recebendo 4 parâmetros, referentes ao volume de cada lixeira.

Parní připojovací zařízení a aplikace ThingSpeak a další rozhraní API pro vytváření kanálů. Siga os passos descritos no site oficial.

Volta a aplicação, vamos use a biblioteca ESP8266WiFi.h para efetuar conexão com o ThingSpeak, e transferir os dados.

Hlavní funkce, funkce a možnosti připojení (definice předchozího přechodu, ssid e průchod , potvrzení o identifikaci a senha de sua rede).

void connectWifi () {

Serial.print ("Připojování k"+ *ssid);

WiFi.begin (ssid, pass);

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

zpoždění (500);

Serial.print (".");

}

Serial.println ("");

Serial.print ("Conectado na rede");

Serial.println (ssid);

Serial.print ("IP:");

Serial.println (WiFi.localIP ());

}

Trvejte na nastavení, získejte efektivitu a připojte se k nákupu.

neplatné nastavení () {

Serial.begin (9600);

Serial.println („Lendo dados do sensor…“);

// Připojení k 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.

neplatné sendDataTS (float cmMsec, dlouhé ID) {

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

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

Řetězec postStr = apiKey;

postStr += "& pole";

postStr += id;

postStr += "=";

postStr += String (cmMsec);

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

Serial.println (postStr);

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

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

client.print ("Připojení: zavřít / n");

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

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

client.print ("Délka obsahu:");

client.print (postStr.length ());

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

client.print (postStr);

zpoždění (1000);

}

client.stop ();

}

Nejvýraznější korespondence s dálkovým ovládáním a snímačem 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 sloužit também para identificar para qual campo será feito o upload do valor lido.

Krok 4: Recuperando Dados Do ThingSpeak

O ThingSpeak prostupuje více než jeden kanál do jiného kanálu, než se vrátí do JSON. Jak se liší v závislosti na krmivu, jak se kanál liší od původu:

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

Nyní projeto, opt-se por ler diretamente os dados de cada campo. Další adresa URL pro cenové kategorie:

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. Nejdůležitější pro projednávání:

  • CHANNEL_ID: kanál número do seu
  • FIELD_NUMBER: o número do campo
  • API_KEY: kanál API do seu

Více a více adres URL pro aplikace pro Android, stejně jako pro obnovení do ThingSpeak.

Krok 5: Criando a Aplicação Android

Žádný Android Studio, crie um novo projeto Android. Para o correto funcionamento da aplicação, and essential needs configurar as permissões abaixo no AndroidManifest.

Využívá Google Maps a mnoho dalších, než je Google. Sosos passccc descritos no link Obter chave de API.

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

Klíč API pro rozhraní API založená na Mapách Google je definován jako řetězcový prostředek.

(Viz soubor „res/values/google_maps_api.xml“).

Všimněte si, že klíč API je propojen se šifrovacím klíčem použitým k podepsání APK. Pro každý šifrovací klíč, včetně uvolňovacího klíče, který se používá k podepsání APK pro publikování, potřebujete jiný klíč API. Klíče pro cíle ladění a uvolnění můžete definovat v src/debug/a src/release/.

<metadata

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

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

Konfigurace je kompatibilní s dalšími funkcemi AndroidManifest a dalšími projekty.

n

Krok 6: Recuperando O Feed Žádný Android

Na hlavní stránce není Android, MainActivity, crie 4 variáve para identificar 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";

Para efetuar a leitura dos dados, iremos utilizar uma classe do Android específica, chamada JSONObject. Nejčastěji se jedná o URL adresy:

Odpověď JSONObjectLixeiraA; JSONObject responseLixeiraB; Odpověď JSONObjectLixeiraC; JSONObject responseLixeiraD;

Para abrir a conexão com as url, vamos usar criar uma classe auxiliar, chamada HttpJsonParser. Klasifikujte více odpovědí na více adres URL, připojte více adres URL, přidejte další kódy a překopírujte objekty typu JSON.

public JSONObject makeHttpRequest (URL řetězce, metoda řetězce, parametry mapy) {

Snaž se {

Uri. Builder builder = nový Uri. Builder (); URL urlObj; Řetězec 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 (metoda)) {url = url + "?" + kódované Params; urlObj = nová URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (metoda);

} else {

urlObj = nová URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (metoda); urlConnection.setRequestProperty ("Content-Type", "application/x-www-form-urlencoded"); urlConnection.setRequestProperty ("Content-Length", String.valueOf (encodedParams.getBytes (). length)); urlConnection.getOutputStream (). write (encodedParams.getBytes ()); } // Připojit k serveru urlConnection.connect (); // Přečíst odpověď je = urlConnection.getInputStream (); Čtečka BufferedReader = nový BufferedReader (nový InputStreamReader (je)); StringBuilder sb = nový StringBuilder (); Řetězec;

// Analyzujte odpověď

while ((line = reader.readLine ())! = null) {sb.append (řádek + "\ n"); } je blízko(); json = sb.toString (); // Převést odpověď na 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", "Chyba při analýze dat" + e.toString ()); } catch (Exception e) {Log.e ("Exception", "Error parsing data" + e.toString ()); }

// návrat objektu JSON

vrátit jObj;

}

}

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

@Override protected String doInBackground (String… params) {HttpJsonParser jsonParser = new 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 or método doInBackgroundé encerrado, or controle de execução do Android passa para o método onPostExecute. Nejčastěji pracujeme na tom, abychom získali Lixeira, a oblíbená rekuperace do ThingSpeak:

protected void onPostExecute (Výsledek řetězce) {pDialog.dismiss (); runOnUiThread (new Runnable () {public void run () {

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

Zobrazit mainView = (Zobrazit) findViewById (R.id.activity_main); if (success == 1) {try {// Cria feedDetail para cada lixeira Lixeira feedDetails1 = new Lixeira (); Feed LixeiraDetails2 = nový Lixeira (); Feed LixeiraDetails3 = nový Lixeira (); Feed LixeiraDetails4 = nový 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

Kalkulačka SmartBinService = nová SmartBinService (); kalkulačka.montaListaLixeiras (feedList);

// Recupera komponenty

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

// Data atual

Datum currentTime = Calendar.getInstance (). GetTime (); SimpleDateFormat simpleDate = nové SimpleDateFormat ("dd/MM/rrrr"); Řetězec currentDate = simpleDate.format (currentTime); createDate.setText (KEY_DATE + currentDate + ""); listaDeLixeiras.setAdapter (adaptér);

} catch (JSONException e) {

e.printStackTrace (); }

} else {

Toast.makeText (MainActivity.this, "Došlo k nějaké chybě při načítání dat", Toast. LENGTH_LONG).show ();

}

} }); }

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

Krok 7: Mostrando No Map

Mostrando Žádná Mapa
Mostrando Žádná Mapa

Ainda at atividade principal, vamos adicionar uma ação a ser relacionada ao Botão Map, at tela inicial.

/ ** Volá se, když uživatel klepne na tlačítko Mapa*/ public void openMaps (Zobrazit zobrazení) {Intent Intent = new Intent (this, LixeiraMapsActivity.class);

// Passa a lista de lixeiras

Bundle bundle = new Bundle (); bundle.putParcelableArrayList ("lixeiras", feedList); intent.putExtras (balíček);

startActivity (záměr);

}

Žádná mapa, temos três atividades a executar:

  1. marcar a posição atual do caminha de lixo
  2. korespondenti marcar os pontos a cada lixeira bez mapy
  3. traçar a rota entre os pontos

Provádějte různé způsoby, jak používat API a pokyny Google. Para desenhar as rotas, foram seguidos os passos do tutorial Drawing driving route addresses between two locations using Google Directions in Google Map Android API V2

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

// Místa

soukromý LatLng proud;

soukromé LatLng lixeiraA; soukromé LatLng lixeiraB; soukromé LatLng lixeiraC; soukromé LatLng lixeiraD;.

Další informace a žádná mapa, například:

private void checkLocationandAddToMap () {// Kontrola, zda uživatel udělil oprávnění if (ActivityCompat.checkSelfPermission (this, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Žádost o povolení k poloze ActivityCompat.requestPermissions (this, new String {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); vrátit se; }

// Načítání posledního známého místa pomocí Fus

Umístění umístění = LocationServices. FusedLocationApi.getLastLocation (googleApiClient);

// MarkerOptions se používají k vytvoření nového Marker. MarkerOptions můžete určit umístění, název atd

this.current = new LatLng (location.getLatitude (), location.getLongitude ()); MarkerOptions markerOptions = new MarkerOptions (). Position (aktuální).title ("Posição atual");

// Přidání vytvořené značky na mapu, přesun kamery na místo

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

// Okamžitě přesuňte kameru na místo se zoomem 15.

mMap.moveCamera (CameraUpdateFactory.newLatLngZoom (aktuální, 15));

// Přiblížení, animace kamery.

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

}

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

private void addBinALocation () {// Kontrola, zda uživatel udělil povolení if (ActivityCompat.checkSelfPermission (this, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission (this, android. Man. ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Žádost o povolení k poloze ActivityCompat.requestPermissions (this, new String {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); vrátit se; }

// Praça da Estação

dvojitá zeměpisná šířka = -19,9159578; dvojnásobná délka = -43,9387856; this.lixeiraA = new LatLng (latitude, longitude);

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

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

Vzhledem k tomu, že zeměpisné šířky a délky jsou k dispozici pro Mapy Google, jsou k dispozici všechny mapy Google. Idealmente, estes valores ficariam salvos em um banco de dados (por exampleplo 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!

Naše hlavní cíle jsou následující:

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

// Původ trasy

Řetězec str_origin = "origin ="+origin.latitude+","+origin.longitude;

// Cíl trasy

Řetězec str_dest = "destinace ="+dest.latitude+","+dest.longitude;

// Trasové body na trase

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

// Senzor povolen

String sensor = "sensor = false";

// Vytváření parametrů pro webovou službu

Parametry řetězce = str_origin+"&"+str_dest+"&"+senzor+"&"+body na trase;

// Výstupní formát

Výstup řetězce = "json";

// Vytvoření adresy URL webové služby

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

návratová URL;

}

E, por fim, juntando tudo no método principál da classe, onMapReady:

@Override public neplatné 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 (); }

// Nakreslete trasy

// Získání adresy URL do rozhraní Google Directions API

Seznam bodů = nový ArrayList (); points.add (lixeiraB); points.add (lixeiraC); points.add (lixeiraD);

Adresa URL řetězce = getDirectionsUrl (aktuální, lixeiraA, body);

DownloadTask downloadTask = nový DownloadTask (); // Začněte stahovat data json z Google Directions API downloadTask.execute (url); }

Aqui passamos apenas pelos pontos principais. Kompatibilní s ostatními projekty, které jsou k dispozici po konzultaci.

Krok 8: Conclusão

Nejčastěji se jedná o koncepci IoT, většina z toho má k dispozici všechny dostupné možnosti, jako je tomu při rozhodování o vzájemném ovlivňování. Em anexo, segue um videde do projeto completo, para illustrationração, and os fontes das atividades criadas no Android.

Doporučuje: