Sisukord:
- 1. samm: Conectando O andur
- 2. samm: Montando ja Lixeira
- Samm: laadige üles Nuvem
- Samm 4: Recuperando Dados Do ThingSpeak
- Samm 5: Criando ja Aplicação Android
- 6. toiming: O -voo taastamine Androidi puudumine
- Samm 7: Mostrando No Mapa
- 8. samm: Conclusão
Video: SmartBin: 8 sammu
2024 Autor: John Day | [email protected]. Viimati modifitseeritud: 2024-01-31 10:18
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
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:
- marcar a posição atual do caminha de lixo
- marcar os täpne korrespondent a a cada lixeira no mapa
- 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:
Atari punkkonsool beebiga 8 sammu järjestus: 7 sammu (piltidega)
Atari punkkonsool koos beebi 8-astmelise sekveneerijaga: see vaheehitus on kõik-ühes Atari punk-konsool ja beebi 8-astmeline järjestus, mida saate freesida Bantam Tools töölaua PCB-freespingis. See koosneb kahest trükkplaadist: üks on kasutajaliidese (UI) plaat ja teine on utiliit
Akustiline levitatsioon Arduino Unoga samm-sammult (8 sammu): 8 sammu
Akustiline levitatsioon Arduino Uno abil samm-sammult (8 sammu): ultraheliheli muundurid L298N DC-naissoost adapteri toiteallikas isase alalisvoolupistikuga Arduino UNOBreadboard ja analoogpordid koodi teisendamiseks (C ++)
4G/5G HD -video otseülekanne DJI droonilt madala latentsusega [3 sammu]: 3 sammu
4G/5G HD-video otseülekanne DJI droonilt madala latentsusega [3 sammu]: Järgnev juhend aitab teil saada HD-kvaliteediga otseülekandeid peaaegu igalt DJI droonilt. FlytOSi mobiilirakenduse ja veebirakenduse FlytNow abil saate alustada drooni video voogesitust
Polt - DIY juhtmeta laadimise öökell (6 sammu): 6 sammu (piltidega)
Bolt - DIY juhtmeta laadimise öökell (6 sammu): Induktiivsed laadimised (tuntud ka kui juhtmeta laadimine või juhtmeta laadimine) on traadita jõuülekande tüüp. See kasutab kaasaskantavatele seadmetele elektrit pakkumiseks elektromagnetilist induktsiooni. Kõige tavalisem rakendus on Qi traadita laadimisst
SmartBin: 4 sammu
SmartBin: Selle projekti peamine eesmärk on luua elektrooniline seade, mis kasutab vähemalt ühte Raspberry Pi. Meeskonda kuulub 5 tulevast mehaanikainseneri ja üks automaatikainsener. Meie projekt seisneb prügikasti valmistamises, mis avaneb ja sulgub