Satura rādītājs:
- 1. darbība: Conectando O sensors
- 2. solis: Montando un Lixeira
- 3. darbība: augšupielādējiet Nuvem
- 4. solis. Recuperando Dados Do ThingSpeak
- 5. darbība. Criando a Aplicação Android
- 6. darbība. Atjaunojiet barību bez Android
- 7. solis: Mostrando No Mapa
- 8. solis: Conclusão
Video: SmartBin: 8 soļi
2024 Autors: John Day | [email protected]. Pēdējoreiz modificēts: 2024-01-31 10:22
Este é um projeto para um system inteligente de coletas, no qual os caminhões de lixo recebem dados das lixeiras, identificando 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, ja nepieciešams:
- NodeMCU
- Ultrassônico de Distancia sensors
- Caixa de papelão
- Protoboard
- Cabos
- Dispositivo Android
1. darbība: Conectando O sensors
Primeiramente, vamos efetuar a conexão entre o sensor ultrassônico e o NODEMCU. Para tanto, vamos conectar kā portas trigger e echo do sensor nas portas D4 e D3 do NodeMCU:
// definē tapas numurus #define pino_trigger 2 // D4
#define pino_echo 0 // D3
Paredzēts sensoru, leitura dos dados do sensoru, sekošanas vai apmācības izstrādāto pelo FilipeFlop, displeja ūdens.
pludiņš cmMsec, inMsec;
garš mikrosekunde = ultraskaņas.laiks ();
cmMsec = ultraskaņas.konvertēt (mikrosekundes, ultraskaņas:: CM);
inMsec = ultraskaņas.konvertēt (mikrosekundes, Ultraskaņas:: IN);
// Exibe informationcoes nav sērijveida monitora
Serial.print ("Distancia em cm:");
Sērijas nospiedums (cmMsec);
Serial.print (" - Distancia em polegadas:");
Serial.println (inMsec);
Stīgu dati = String (cmMsec);
Serial.println (dati);
2. solis: Montando un Lixeira
Agora, vamos montar un lixeira inteligente. Precizēts konvektors vai sensora ultrassônico no “teto” da lixeira. Piemēram, izmantojiet kabīni un izolantus. Em seguida, temos que medir a distância inicial, para saber o valor para a lixeira vazia. Nav meo caso, foi de 26, 3cm. Esse é o valor que Regardrarmos para uma lixeira vazia.
Para simulação, visto que não possuo mais de um sensor ultrassônico, foi feito um algoritmo para salvar randomicamente and distancia lida em 4 lixeiras diferentes.
// Simulando 4 lixeiras
garš lixeiraID;
void loop () {
lixeiraID = nejaušs (1, 5);
}
3. darbība: augšupielādējiet Nuvem
Agora, precisamos enviar estes dados para a nuvem. Eu escolhi o ThingSpeak, familiaridade com o mesmo. Primeiramente, é needsário criar um novo canal, recebendo 4 parâmetros, referentes ao volume de cada lixeira.
Parādiet konektoru un ThingSpeak aplicação com. Siga os passos descritos no site oficial.
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 variáveis, ssid e pass , contendo o identifador e a senha de sua rede).
void connectWifi () {
Serial.print ("Savienojuma izveide ar"+ *ssid);
WiFi.begin (ssid, pass);
kamēr (WiFi.status ()! = WL_CONNECTED) {
kavēšanās (500);
Sērijas nospiedums (".");
}
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 () {
Sērijas sākums (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 (pludiņš cmMsec, garš id) {
ja (client.connect (serveris, 80)) {
Serial.println ("Enviando dados para o ThingSpeak");
Stīgu postStr = apiKey;
postStr += "& lauks";
postStr += id;
postStr += "=";
postStr += String (cmMsec);
postStr += "\ r / n / r / n";
Serial.println (postStr);
client.print ("POST /atjaunināt HTTP /1.1 / n");
client.print ("Saimnieks: api.thingspeak.com / n");
client.print ("Savienojums: aizvērt / n");
client.print ("X-THINGSPEAKAPIKEY:" + apiKey + "\ n");
client.print ("Content-Type: application/x-www-form-urlencoded / n");
client.print ("Content-Length:");
client.print (postStr.length ());
client.print ("\ n / n");
client.print (postStr);
kavēšanās (1000);
}
client.stop ();
}
O primeiro parâmetro atbilst à distância em centímetros encontrada pelo sensor 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 identifar para kvali campo será feito o upload do valor lido.
4. solis. Recuperando Dados Do ThingSpeak
O ThingSpeak permite efetuar leitura dos dados do seu canal, através de um serviço retornando um JSON. Kā atšķirīgi 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. O padrão de URL para cen cenário é:
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 svarīgākie para o projeto são:
- CHANNEL_ID: número do seu kanāls
- FIELD_NUMBER: o número do campo
- API_KEY: Chave de API do seu kanāls
Šis ir vietrāža URL, kas paredzēts Android lietojumprogrammām, kā arī ThingSpeak rekuperators.
5. darbība. Criando a Aplicação Android
Nav Android Studio, iesakiet jaunu Android versiju. Pareiza vai pareiza funkcionāla aplikācijas programma, kas nepieciešama konfigurācijai kā atļauja abaixo no AndroidManifest.
Izmantojiet Google Maps, jums ir nepieciešams izmantot Google pakalpojumus. Siga os passos descritos no link Obter chave de API.
Uma vez com a chave, você deve também configurá-la na aplicação.
API atslēga uz Google Maps balstītām API ir definēta kā virkņu resurss.
(Skatiet failu "res/values/google_maps_api.xml").
Ņemiet vērā, ka API atslēga ir saistīta ar šifrēšanas atslēgu, ko izmanto APK parakstīšanai. Katrai šifrēšanas atslēgai ir nepieciešama cita API atslēga, ieskaitot atbrīvošanas atslēgu, kas tiek izmantota APK parakstīšanai publicēšanai. Atkļūdošanas un izlaišanas mērķu atslēgas varat definēt sadaļā src/debug/un src/release/.
<metadati
android: name = "com.google.android.geo. API_KEY"
android: value = "@string /google_maps_key" />
Ir pabeigta konfigurācija, kas paredzēta AndroidManifest aneksado lietošanai.
n
6. darbība. Atjaunojiet barību bez Android
Ja jums nav Android, MainActivity, 4 versijas, var identificēt cada um dos canais do ThingSpeak a serem lidos:
privātā virkne url_a = "https://api.thingspeak.com/channels/429823/fields/1/last.json?api_key="+API_THINGSPEAK_KEY+"&status=true"; privātā virkne url_b = "https://api.thingspeak.com/channels/429823/fields/2/last.json?api_key="+API_THINGSPEAK_KEY+"&status=true"; privātā virkne url_c = "https://api.thingspeak.com/channels/429823/fields/3/last.json?api_key="+API_THINGSPEAK_KEY+"&status=true"; privātā virkne url_d = "https://api.thingspeak.com/channels/429823/fields/4/last.json?api_key="+API_THINGSPEAK_KEY+"&status=true";
Lai to paveiktu, leitura dos dados, iremos utilizar uma classe do Android específica, chamada JSONObject. Mais uma vez, vamos criar um objeto para cada URL:
JSONObjekta atbildeLixeiraA; JSONObjekta atbildeLixeiraB; JSONObjekta atbildeLixeiraC; JSONObjekta atbildeLixeiraD;
Para abrir a conexão com as url, vamos usar criar uma classe auxiliar, chamada HttpJsonParser. Esta classe serā atbilde uz abrir uma conexão com um URL, efetuar leitura dos dados encontrados, e retornar or objeto JSON montado.
public JSONObject makeHttpRequest (virknes URL, virknes metode, kartes parametri) {
pamēģini {
Uri. Builder builder = jauns 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 ();
}
ja ("GET".vienāds (metode)) {url = url + "?" + kodētiParams; urlObj = jauns URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (metode);
} vēl {
urlObj = jauns URL (url); urlConnection = (HttpURLConnection) urlObj.openConnection (); urlConnection.setRequestMethod (metode); urlConnection.setRequestProperty ("Content-Type", "application/x-www-form-urlencoded"); urlConnection.setRequestProperty ("Content-Length", String.valueOf (encodedParams.getBytes (). length)); urlConnection.getOutputStream (). write (encodedParams.getBytes ()); } // Savienojuma izveide ar serveri urlConnection.connect (); // Lasīt atbildi ir = urlConnection.getInputStream (); BufferedReader lasītājs = jauns BufferedReader (jauns InputStreamReader (ir)); StringBuilder sb = jauns StringBuilder (); Stīgu līnija;
// Parsēt atbildi
while ((rinda = lasītājs.lasīšanas rinda ())! = null) {sb.append (rinda + "\ n"); } is.close (); json = sb.toString (); // Pārvērst atbildi uz JSON objektu 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", "Error parsing data" + e.toString ()); } catch (Izņēmums e) {Log.e ("Izņēmums", "Kļūda parsējot datus" + e.toString ()); }
// atgriezt JSON objektu
atgriezties jObj;
}
}
De volta a atividade principa, vamos efetuar a chamada às urls de forma assíncrona, escrevendo este código dentro do método doInBackground.
@Pārvarēt aizsargātu virkni doInBackground (String… params) {HttpJsonParser jsonParser = jauns 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 passa para or método onPostExecute. Neste método, vamos criar os objetos Lixeira, e popular com os dados recuperados do ThingSpeak:
protected void onPostExecute (String rezultāts) {pDialog.dismiss (); runOnUiThread (jauns Runnable () {public void run () {
// ListView listView = (ListView) findViewById (R.id.feedList);
Skatīt mainView = (Skatīt) findViewById (R.id.activity_main); if (veiksme == 1) {try {// Cria feedDetail para cada lixeira Lixeira feedDetails1 = new Lixeira (); Lixeira feedDetails2 = jauna Lixeira (); Lixeira feedDetails3 = jauna Lixeira (); Lixeira feedDetails4 = jauna 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 kalkulators = jauns SmartBinService (); calculator.montaListaLixeiras (feedList);
// Recupera komponenti
TextView createDate = (TextView) mainView.findViewById (R.id.date); ListView listaDeLixeiras = (ListView) findViewById (R.id.lista); adapter.addAll (feedList);
// Datu aktualitāte
Datums currentTime = Calendar.getInstance (). GetTime (); SimpleDateFormat simpleDate = jauns SimpleDateFormat ("dd/MM/gggg"); String currentDate = simpleDate.format (currentTime); createDate.setText (KEY_DATE + currentDate + ""); listaDeLixeiras.setAdapter (adapteris);
} nozveja (JSONException e) {
e.printStackTrace (); }
} vēl {
Toast.makeText (MainActivity.this, "Ielādējot datus radās kāda kļūda", Toast. LENGTH_LONG).show ();
}
} }); }
Agora, na tela inicial do aplicativo, serão listados os dados de cada lixeira.
7. solis: Mostrando No Mapa
Ainda na atividade principāls, vamos adicionar uma ação a ser relacionada ao botão Map, na tela inicial.
/ ** Izsaukts, kad lietotājs pieskaras pogai Karte*/ public void openMaps (Skatīt skatu) {Intent aim = new Intent (this, LixeiraMapsActivity.class);
// Passa a lista de lixeiras
Bundle bundle = jauns Bundle (); bundle.putParcelableArrayList ("lixeiras", feedList); aim.putExtras (saišķis);
startActivity (nodoms);
}
Nav kartes, temos três atividades a executar:
- marcar a posição atual do caminha de lixo
- marcar os precīzas korespondentes a cada lixeira no mapa
- traçar a rota entre os pontos
Lai izpildītu visas prasības, izmantojiet API Google norādījumus. Para desenhar as rotas, foram seguidos os passos do apmācība Braukšanas ceļa norāžu zīmēšana starp divām vietām, izmantojot Google norādes Google Map Android API V2
Primeiro, vamos criar localidades para cada um dos pontos que desejamos marcar:
// Atrašanās vietas
privāta LatLng strāva;
privātā LatLng lixeiraA; privāts LatLng lixeiraB; privāts LatLng lixeiraC; privāta LatLng lixeiraD;.
Lai skatītu apo posional no mapa, foi criado o método:
private void checkLocationandAddToMap () {// Pārbaude, vai lietotājs ir piešķīris atļauju, ja (ActivityCompat.checkSelfPermission (šis, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat. Meck. Shemp. Shemp; ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Atrašanās vietas atļaujas pieprasīšana ActivityCompat.requestPermissions (šī, jaunā virkne {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); atgriešanās; }
// Pēdējās zināmās atrašanās vietas iegūšana, izmantojot Fus
Location location = LocationServices. FusedLocationApi.getLastLocation (googleApiClient);
// MarkerOptions tiek izmantotas, lai izveidotu jaunu marķieri. Izmantojot MarkerOptions, varat norādīt atrašanās vietu, nosaukumu utt.
this.current = new LatLng (location.getLatitude (), location.getLongitude ()); MarkerOptions markerOptions = new MarkerOptions (). Position (current).title ("Posição atual");
// Izveidotā marķiera pievienošana kartei, kameras pārvietošana pozīcijā
markerOptions.icon (BitmapDescriptorFactory.defaultMarker (BitmapDescriptorFactory. HUE_GREEN)); System.out.println ("+++++++++++++ Passei aqui! ++++++++++++"); mMap.addMarker (markerOptions);
// Nekavējoties pārvietojiet kameru uz atrašanās vietu ar 15 tālummaiņu.
mMap.moveCamera (CameraUpdateFactory.newLatLngZoom (pašreizējais, 15));
// Tuvināt, animēt kameru.
mMap.animateCamera (CameraUpdateFactory.zoomTo (14), 2000, null);
}
Em seguida, para cada lixeira, foram criados metodos similares ao abaixo:
private void addBinALocation () {// Pārbaude, vai lietotājs ir piešķīris atļauju, ja (ActivityCompat.checkSelfPermission (šis, android. Manifest.permission. ACCESS_FINE_LOCATION)! = PackageManager. PERMISSION_GRANTED && ActivityCompat.checkSelfPermission.html, ACCESS_COARSE_LOCATION)! = PackageManager. PERMISSION_GRANTED) {// Atrašanās vietas atļaujas pieprasīšana ActivityCompat.requestPermissions (šī, jaunā virkne {android. Manifest.permission. ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE); atgriešanās; }
// Praça da Estação
dubults platums = -19.9159578; dubultā garums = -43,9387856; this.lixeiraA = new LatLng (platums, garums);
MarkerOptions markerOptions = new MarkerOptions (). Position (lixeiraA).title ("Lixeira A");
markerOptions.icon (BitmapDescriptorFactory.defaultMarker (BitmapDescriptorFactory. HUE_RED)); mMap.addMarker (markerOptions); }
Kā atrašanās vietas platums un garums, cada lixeira foram recuperadas através do próprio Google Maps, e deixadas fixas no código. Idealmente, estes valores ficariam salvos em um banco de dados (piemēram 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!
Jautājums par to, kā to izdarīt, ir:
privāta virkne getDirectionsUrl (LatLng izcelsme, LatLng galamērķis, List waypointsList) {
// Maršruta izcelsme
String str_origin = "origin ="+origin.latitude+","+origin.longitude;
// Maršruta galamērķis
String str_dest = "target ="+dest.latitude+","+dest.longitude;
// Maršruta punkti maršrutā
//waypoints=optimize:true|-19.9227365, -43.9473546 | -19.9168006, -43.9361124 String waypoints = "waypoints = optimize: true"; for (LatLng point: waypointsList) {waypoints += "|" + punkts. platums + "," + punkts.garums; }
// Sensors iespējots
Stīgu sensors = "sensors = nepatiess";
// Parametru veidošana tīmekļa pakalpojumam
Virknes parametri = str_origin+"&"+str_dest+"&"+sensors+"&"+ceļa punkti;
// Izvades formāts
Stīgu izvade = "json";
// URL veidošana tīmekļa pakalpojumam
String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters; System.out.println ("++++++++++++++"+url);
atgriešanās URL;
}
E, por fim, juntando tudo no método principa da classe, onMapReady:
@Override public void onMapReady (GoogleMap googleMap) {mMap = googleMap;
checkLocationandAddToMap ();
ja (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 (); }
// Zīmēt maršrutus
// URL iegūšana Google virzienu API
Saraksta punkti = jauns ArrayList (); punkti.pievienot (lixeiraB); punkti.pievienot (lixeiraC); punkti.pievienot (lixeiraD);
String url = getDirectionsUrl (pašreizējais, lixeiraA, punkti);
DownloadTask downloadTask = jauns DownloadTask (); // Sāciet lejupielādēt json datus no Google Directions API downloadTask.execute (url); }
Aqui passamos apenas pelos pontos principais. O código complete do do projeto será disponibilizado para consulta.
8. solis: 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. Tā ir aneksija, videomateriāls, kas paredzēts pilnīgai projektēšanai, ilustrācijai un e -fontu izmantošanai, izmantojot Android.
Ieteicams:
Arduino brīdinājuma sistēma par automašīnas novietošanu atpakaļgaitā Soli pa solim: 4 soļi
Arduino brīdinājuma sistēma par automašīnas novietošanu atpakaļgaitā Soli pa solim: Šajā projektā es izveidošu vienkāršu Arduino automašīnas atpakaļgaitas stāvvietas sensora shēmu, izmantojot Arduino UNO un ultraskaņas sensoru HC-SR04. Šo uz Arduino bāzēto automašīnas reverso brīdinājuma sistēmu var izmantot autonomai navigācijai, robotu diapazonam un citiem diapazoniem
Soli pa solim datora veidošana: 9 soļi
Soli pa solim datora veidošana: Piegādes: Aparatūra: mātesplateCPU & CPU dzesētājs PSU (barošanas bloks) Krātuve (HDD/SSD) RAMGPU (nav nepieciešams) Korpuss Instrumenti: skrūvgriezis ESD rokassprādze/matermālā pasta ar aplikatoru
Trīs skaļruņu shēmas -- Soli pa solim apmācība: 3 soļi
Trīs skaļruņu shēmas || Soli pa solim apmācība: Skaļruņu ķēde pastiprina no vides saņemtos audio signālus uz MIC un nosūta to skaļrunim, no kura tiek radīts pastiprināts audio. Šeit es parādīšu trīs dažādus veidus, kā izveidot šo skaļruņu shēmu, izmantojot:
Akustiskā levitācija ar Arduino Uno soli pa solim (8 soļi): 8 soļi
Akustiskā levitācija ar Arduino Uno soli pa solim (8 soļi): ultraskaņas skaņas pārveidotāji L298N līdzstrāvas adaptera strāvas padeve ar vīriešu līdzstrāvas tapu Arduino UNOBreadboard un analogie porti koda konvertēšanai (C ++)
SmartBin: 4 soļi
SmartBin: Šī projekta galvenais mērķis ir izveidot elektronisku ierīci, kas izmanto vismaz vienu Raspberry Pi. Komandā ir pieci topošie mehāniķi un viens automatizācijas inženieris. Mūsu projekts sastāv no miskastes izgatavošanas, kas atveras un aizveras