İçindekiler:

SmartBin: 8 Adım
SmartBin: 8 Adım

Video: SmartBin: 8 Adım

Video: SmartBin: 8 Adım
Video: Xiaomi Smart Band 8 kutu açılımı! - Saatleri titreten akıllı bileklik! 2024, Kasım
Anonim
Akıllı Kutu
Akıllı Kutu

Este é é um projeto para um sistema inteligente de coletas, hiçbir nitel os os caminhões de lixo reebem dados das lixeiras, identificando ve lixo liko sunumu em cada uma delas, e uma rota de coleta traçada, õ com base bilgi.

Para montar este projeto, é necessário:

  • DüğümMCU
  • Sensör Ultrassônico de Distancia
  • Caixa de papelão
  • protokol
  • kabinler
  • Android

Adım 1: Conectando O Sensörü

Primeiramente, vamos efetuar bir conexão giriş o sensör ultrasônico ve NODEMCU. Para tanto, vamos conectar as portas tetikleyici ve eko sensör olarak D4 ve D3 portas portları için NodeMCU:

// pin numaralarını tanımlar #define pino_trigger 2 //D4

#define pino_echo 0 //D3

Para efetuar bir leitura dos dados do sensor, foi seguido o öğretici ayrıntılı pelo FilipeFlop, disponível aqui.

float cmMsec, inMsec;

uzun mikrosaniye = ultrasonic.timing();

cmMsec = ultrasonic.convert(mikrosaniye, Ultrasonik::CM);

inMsec = ultrasonic.convert(mikrosaniye, Ultrasonik::IN);

//Exibe bilgileri seri monitör yok

Serial.print("Mesafe cm cm: ");

Serial.print(cmMsec);

Serial.print(" - Uzak mesafeler: ");

Serial.println(inMsec);

Dize verisi = Dize(cmMsec);

Seri.println(veri);

2. Adım: Montando ve Lixeira

Agora, vamos montar bir lixeira inteligente. Precisaremos conectar o sensör ultrassônico "teto" da lixeira yok. Para ya da örnek, kullanımdan yararlanma. Em seguida, temos que medir a distância incial, para saber o valor para a lixeira vazia. Hiçbir meu caso, foi de 26, 3cm. Esse é o valor que dikkate armos para uma lixeira vazia.

Para eşanlamlı, mümkün olmayan en büyük sensör ultrassônico, foi tüm algoritmo para salvar rastgele bir uzaklık ve 4 farklı değişkenler yelpazesi.

//Simulando 4 lüks

uzun lixeiraID;

boşluk döngüsü () {

lixeiraID = rastgele(1, 5);

}

Adım 3: Para a Nuvem yükleyin

Agora, precisamos enviar estes dados para a nuvem. Eu escolhi veya ThingSpeak, por tanıdık geldi. Primeiramente, é necessário criar um novo canal, recebendo 4 parametre, referanslar ao cada lixeira hacmi.

ThingSpeak, é necessário salvar o número da API do canal criado için bir uygulama. Siga os passos descritos hiçbir site resmi değil.

ESP8266WiFi.h ve ThingSpeak için bir kaynakçadan yararlanın.

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

geçersiz connectWifi(){

Serial.print( + *ssid'e bağlanılıyor);

WiFi.begin(ssid, pass);

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

gecikme(500);

Seri.print(".");

}

Seri.println("");

Serial.print("Konectado ve rede ");

Serial.println(ssid);

Seri.print("IP:");

Serial.println(WiFi.localIP());

}

Durante veya kurulum, tentamos efetuar ve conexão com a redde.

geçersiz kurulum() {

Seri.başla(9600);

Serial.println("Lendo dados sensör yapar…");

//Conectando ve Wi-Fi

bağlanWifi();

}

E, ThingSpeak, HTTP padrão, passando o número ve API e os parâmetros için en iyi uygulamalar.

void sendDataTS(float cmMsec, uzun kimlik){

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

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

String postStr = apiKey;

postStr += "&alan";

postStr += kimlik;

postStr += "=";

postStr += Dize(cmMsec);

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

Serial.println(postStr);

client.print("POST /HTTP/1.1 güncelleme\n");

client.print("Ana Bilgisayar: api.thingspeak.com\n");

client.print("Bağlantı: kapat\n");

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

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

client.print("İçerik-Uzunluk: ");

client.print(postStr.length());

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

client.print(postStr);

gecikme(1000);

}

istemci.durdur();

}

O primeiro parâmetro, uzaklıklara ve merkezlere karşılık gelen encontrada pelo sensörü 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, também para identificar para qual campo será feito o yükleme do valor lido'ya hizmet eder.

Adım 4: Recuperando Dados Do ThingSpeak

O ThingSpeak izni efetuar leitura dos dados do seu canal, através de um serviço retornando um JSON. Farklı opções para leitura do seu canal estão descritas aqui'yi beslemek için:

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

Neste projeto, optou-se porler diretamente os dados de cada campo. O URL para este cenário é:

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

Cada campo está açıklayan hiçbir bağlantı bilgisi ön inceleme. Os mais önemlies para o projeto sao:

  • CHANNEL_ID: número do seu kanalı
  • FIELD_NUMBER: o número do campo
  • API_KEY: seu canal için bir API çağrısı

Android için bir URL sorgulayın, ThingSpeak için para kazanın.

Adım 5: Criando ve Aplicação Android

Android Studio yok, Android için yeni proje. AndroidManifest'te izin verilen şekilde yapılandırılması için gerekli olan işlevsel işlevler.

Google Haritalar'ın para kullanımı, Google'a ilişkin gerekli bilgiler. Siga os passos açıklamaları bağlantı yok Obter chave de API.

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

Google Haritalar tabanlı API'ler için API anahtarı, bir dize kaynağı olarak tanımlanır.

("res/values/google_maps_api.xml" dosyasına bakın).

API anahtarının APK'yı imzalamak için kullanılan şifreleme anahtarına bağlı olduğunu unutmayın. APK'yı yayınlamak üzere imzalamak için kullanılan yayın anahtarı da dahil olmak üzere her şifreleme anahtarı için farklı bir API anahtarına ihtiyacınız vardır. Hata ayıklama ve yayın hedefleri için anahtarları src/debug/ ve src/release/ içinde tanımlayabilirsiniz.

<meta-veri

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

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

AndroidManifest'in tüm projeleriyle ilgili tüm yapılandırmaları tamamlayın.

n

Adım 6: Recuperando O Feed No Android

Na atividade Principal no Android, MainActivity, crie 4 variáveis para identificar cada um dos canais do ThingSpeak a serem lidos:

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

Para efetuar ve leitura dos dados, iremos uma classe do Android özellikleri, chamada JSONObject. Ana sayfa, vamos criar um objeto para cada URL'si:

JSONObject yanıtıLixeiraA; JSONObject yanıtıLixeiraB; JSONObject yanıtıLixeiraC; JSONObject yanıtıLixeiraD;

Para abrir a conexão com as url'ler, vamos usar criar uma classe auxiliar, chamada HttpJsonParser. URL'yi en kısa zamanda ve en iyi şekilde yanıtlayın.

public JSONObject makeHttpRequest(Dize url, Dize yöntemi, Harita parametreleri) {

denemek {

Uri. Builder oluşturucu = yeni Uri. Builder(); URL urlObj; Dize kodlanmışParams = ""; if (params != null) { for (Map. Entry girişi: params.entrySet()) { builder.appendQueryParameter(entry.getKey(), entry.getValue()); } } if (builder.build().getEncodedQuery() != null) { encodedParams = builder.build().getEncodedQuery();

}

if ("GET".equals(method)) { url = url + "?" + kodlanmışParamlar; urlObj = yeni URL(url); urlConnection = (HttpURLConnection) urlObj.openConnection(); urlConnection.setRequestMethod(yöntem);

} Başka {

urlObj = yeni URL(url); urlConnection = (HttpURLConnection) urlObj.openConnection(); urlConnection.setRequestMethod(yöntem); urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); urlConnection.setRequestProperty("İçerik Uzunluğu", String.valueOf(encodedParams.getBytes().length)); urlConnection.getOutputStream().write(encodedParams.getBytes()); } //Sunucuya bağlanın urlConnection.connect(); //Yanıtı oku = urlConnection.getInputStream(); BufferedReader okuyucu = new BufferedReader(yeni InputStreamReader(is)); StringBuilder sb = yeni StringBuilder(); Dize hattı;

//Yanıtı ayrıştır

while ((line = okuyucu.readLine()) != null) { sb.append(satır + "\n"); } yakın(); json = sb.toString(); //Yanıtı JSON Nesnesine dönüştürün jObj = new JSONObject(json);

} yakalama (UnsupportedEncodingException e) {

e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } yakalama (IOException e) { e.printStackTrace(); } catch (JSONException e) { Log.e("JSON Ayrıştırıcı", "Veri ayrıştırılırken hata oluştu" + e.toString()); } catch (Exception e) { Log.e("Exception", "Veri ayrıştırılırken hata oluştu " + e.toString()); }

// JSON Nesnesini döndür

jObj'yi döndür;

}

}

Bir atividade ana ilkesi, vamos efetuar bir chamada às forma assíncrona, escrevendo este código dentro doInBackground'ı seçin.

@Override korumalı Dize doInBackground(String… params) { HttpJsonParser jsonParser = new

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

answerLixeiraB = jsonParser.makeHttpRequest(url_b, "GET", null); answerLixeiraC = jsonParser.makeHttpRequest(url_c, "GET", null); answerLixeiraD = jsonParser.makeHttpRequest(url_d, "GET", null);

null döndür;}

Android'i onPostExecute yöntemiyle kontrol etme yöntemi. Neste método, vamos criar os objetos Lixeira, ThingSpeak yapmak için popüler com os dados recuperados:

korumalı void onPostExecute(Dize sonucu) { pDialog.dismiss(); runOnUiThread(yeni Runnable() { public void run() {

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

Görünüm mainView =(Görünüm)findViewById(R.id.activity_main); if (success == 1) { try { //Cria feedDetail para cada lixeira Lixeira feedDetails1 = new Lixeira(); Lixeira feedDetails2 = yeni Lixeira(); Lixeira feedDetails3 = yeni Lixeira(); Lixeira feedDetails4 = yeni 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);

//Hesap dados das lixeiras

SmartBinService hesaplayıcısı = yeni SmartBinService(); hesap makinesi.montaListaLixeiras(feedList);

//Recupera bileşenleri

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

//Veri güncel

Tarih currentTime = Calendar.getInstance().getTime(); SimpleDateFormat simpleDate = new SimpleDateFormat("gg/AA/yyyy"); String currentDate = simpleDate.format(currentTime); createDate.setText(KEY_DATE + currentDate + " "); listaDeLixeiras.setAdapter(adaptör);

} yakalama (JSONException e) {

e.printStackTrace(); }

} Başka {

Toast.makeText(MainActivity.this, "Veriler yüklenirken bazı hatalar oluştu", Toast. LENGTH_LONG).show();

}

} }); }

Agora, ilk uygulamalar, serão listados os dados de cada lixeira.

7. Adım: Mostrando Mapa Yok

Mostrando Harita Yok
Mostrando Harita Yok

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

/** Kullanıcı Mapa düğmesine dokunduğunda çağrılır */ public void openMaps(View view) { Intent aim = new Intent(this, LixeiraMapsActivity.class);

// Listeyi geç

Paket paketi = yeni Paket(); paket.putParcelableArrayList("lixeiras", feedList); niyet.putExtras(paket);

startActivity(niyet);

}

Mapa yok, temos três atividades bir uygulayıcı:

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

Bir API Google Yönergeleri'ni kullanmak için para yürütür. Rotas olarak para desenhar, foram seguidos os passos öğretici yapmak Google Map Android API V2'de Google Directions'ı kullanarak iki konum arasında sürüş rotası tarifleri çizme

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

//Konumlar

özel LatLng akımı;

özel LatLng lixeiraA; özel LatLng lixeiraB; özel LatLng lixeiraC; özel LatLng lixeiraD;.

Para ek bir posição atual no mapa, foi criado o método:

private void checkLocationandAddToMap() { //Kullanıcının izin verip vermediği kontrol ediliyor if (ActivityCompat.checkSelfPermission(this, android. Manifest.permission. ACCESS_FINE_LOCATION) != PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android. Manifest.per) ACCESS_COARSE_LOCATION) != PackageManager. PERMISSION_GRANTED) { //Konum izni isteniyor ActivityCompat.requestPermissions(bu, yeni Dize{android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); dönüş; }

//Fus kullanarak bilinen son konumu getirme

Konum konumu = LocationServices. FusedLocationApi.getLastLocation(googleApiClient);

//MarkerOptions yeni bir Marker oluşturmak için kullanılır. MarkerOptions ile konum, başlık vb belirtebilirsiniz.

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

//Oluşturulan işaretçinin haritaya eklenmesi, kameranın pozisyona getirilmesi

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

// Kamerayı 15 yakınlaştırma ile anında konuma taşıyın.

mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(geçerli, 15));

// Yakınlaştır, kamerayı canlandır.

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

}

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

private void addBinALocation() { //Kullanıcının izin verip vermediği kontrol ediliyor if (ActivityCompat.checkSelfPermission(this, android. Manifest.permission. ACCESS_FINE_LOCATION) != PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android. Manifest.permission. ACCESS_COARSE_LOCATION) != PackageManager. PERMISSION_GRANTED) { //Konum izni isteniyor ActivityCompat.requestPermissions(bu, yeni Dize{android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); dönüş; }

//Praça da Estação

çift enlem = -19.9159578; çift boylam = -43.9387856; this.lixeiraA = new LatLng(enlem, boylam);

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

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

Enlem ve boylam için konum ve konum olarak, Google Haritalar'a özel düzeltmeler, kodsuz düzeltmeler. Idealmente, estes valores ficariam salvos em um banco de dados (örnek olarak Firebase). Será a primeira evolução deste projeto!

O último passo agora é traçar olarak rotas entre os pontos. Para tal, um çok önemli, e que será utilizado iç projeto, são os Waypoints!

Bir rota entre dois dados pontos için en uygun yol:

private String getDirectionsUrl(LatLng orijini, LatLng hedef, List waypointsList){

// Rotanın kökeni

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

// Rotanın hedefi

String str_dest = "hedef="+hedef.latitude+", "+hedef.boylam;

//Rota boyunca ara noktalar

//waypoints=optimize:true|-19.9227365, -43.9473546|-19.9168006, -43.9361124 String yol noktaları = "yol noktaları=optimize:true"; for (Enlem noktası: yol noktalarıListesi){ yol noktaları += "|" + nokta.enlem + ", " + nokta.boylam; }

// Sensör etkin

Dizi sensörü = "sensör=yanlış";

// Parametreleri web servisine inşa etmek

Dizi parametreleri = str_origin+"&"+str_dest+"&"+sensor + "&" + yol noktaları;

// Çıkış formatı

Dizi çıktısı = "json";

// web servisine url oluşturma

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

URL'yi döndür;

}

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

// Rota çiz

// Google Directions API'sinin URL'sini alma

Liste noktaları = yeni ArrayList(); point.add(lixeiraB); point.add(lixeiraC); point.add(lixeiraD);

String url = getDirectionsUrl(geçerli, lixeiraA, puan);

DownloadTask downloadTask = yeni DownloadTask(); // Google Directions API'sinden json verilerini indirmeye başla downloadTask.execute(url); }

Aqui passamos apenas pelos pontos principais. O código, projeyi tamamlamak için, disponibilizado para danışmanlığı.

Adım 8: Sonuç

IoT'nin en iyi projelendirilmesi, en çok, çeşitli değişkenlerin seçeneklerinin kullanılması, her şeyin yeniden değerlendirilmesi, son kararların verilmesi ve insani müdahalelerin önlenmesi. Ek olarak, videonun tamamını izleyin, para ilustração, e os fontes das atividades criadas hiçbir Android.

Önerilen: