Moje garáž, můj hrad – měříme vzdálenost ultrazvukem

Software máme hotový a je na čase začít řešit hardware. Budeme se zejména věnovat práci s ultrazvukovým dálkoměrem a sběrnicí I2C.
Seriál: Moje garáž, můj hrad (7 dílů)
- Moje garáž, můj hrad – začíná seriál nejen pro kutily 7. 1. 2015
- Moje garáž, můj hrad – zapojujeme Arduino Yún 14. 1. 2015
- Moje garáž, můj hrad – připojujeme Amazon 23. 1. 2015
- Moje garáž, můj hrad – boto nám to zařídí 30. 1. 2015
- Moje garáž, můj hrad – posíláme dotaz do garáže 6. 2. 2015
- Moje garáž, můj hrad – měříme vzdálenost ultrazvukem 13. 2. 2015
- Moje garáž, můj hrad – a konečně parkujeme 20. 2. 2015
Ultrazvukový dálkoměr SRF02
Dálkoměr SRF02 jsem používal na jiném projektu a několik mi jich zbylo. Mám s ním vcelku dost zkušeností, takže to byla pro mě jasná volba. Tento dálkoměr přestává správně fungovat při teplotách nad 28 °C. Nevím proč, ale mám to experimentálně ověřené na několika kusech. Nemá také teplotní kompenzaci, ale to nám může při tomto použití být úplně jedno.
Senzor obsahuje ultrazvukový vysílač a přijímač v jednom pouzdru a podpůrnou elektroniku, která výsledek měření předává na sběrnici I2C v jednotkách cm, inch a ms.
Arduino a I2C
Sběrnice I2C je na deskách Arduino podporována na různých pinech. Na Arduino Yún jsou to piny 2 (SDA) a 3 (SCL). Knihovna pro komunikaci na sběrnici I2C se jmenuje Wire a instaluje se společně s Arduino IDE. Nemusíte ji tak stahovat a konfigurovat samostatně. Pro komunikaci se zařízením na sběrnici I2C musíte znát jeho adresu. U většiny zařízení můžete adresu změnit. Pozor, adresa je 7bitová a u senzoru SRF02 je v dokumentaci uvedena jako 8bitová. Pro zapojení budete potřebovat dva rezistory (pull-up rezistor) o hodnotě 1k8 Ω. Rezistory zapojíte mezi napájecí napětí 5 V a komunikační vodiče SDA a SCL sběrnice I2C.
Pomocí univerzální desky plošných spojů jsem si vytvořil jednoduchý shield. Vypadá dost děsně, ale funguje. Jak už to tak bývá, mělo to být jen dočasné řešení, ale je použito doteď…
Postup při komunikaci
- Otevřete komunikační kanál na adresu senzoru
Wire.beginTransmission(0x70); // v dokumentaci 8-bitová hodnota 0xE0
- Odešlete příkaz, že chcete měřit
Wire.write((byte)0x00);
- Zahajte měření v cm
Wire.write(0x51);
- Ukončete spojení
Wire.endTransmission();
- Je třeba počkat nejméně 70 ms na výsledek. Výsledek je uložen ve dvou bytech.
- Otevřete komunikační kanál na adresu senzoru
Wire.beginTransmission(0x70); // v dokumentaci 8-bitová hodnota 0xE0
- Nastavte adresu registru, od které chcete číst hodnoty
Wire.write(0x02);
- Ukončete spojení
Wire.endTransmission();
- Vyžádejte čtení 2 bytů
Wire.requestFrom(SRF_ADDRESS, 2);
- Byty postupně načtete metodou
read()
highByte = Wire.read();
lowByte = Wire.read();
- Složte výsledek
distance = (highByte << 8) + lowByte;
Kompletní kód aplikace, který vrátí vzdálenost na základě vyvolání přes URL:
#include <Bridge.h>
#include <YunClient.h>
#include <YunServer.h>
#include <Wire.h>
#define SRF_ADDRESS 0x70
#define CMD (byte)0x00
#define RANGEBYTE 0x02
#define UNIT 0x51
byte highByte = 0x00;
byte lowByte = 0x00;
YunServer server;
void setup(){
Wire.begin();
Bridge.begin();
server.listenOnLocalhost();
server.begin();
delay(1000);
}
void loop(){
YunClient client = server.accept();
if (client) {
String command = client.readString();
command.trim();
if (command == "range") {
client.print(getRange());
} else {
client.print("ERROR: " + command);
}
client.stop();
}
delay(50);
}
int getRange(){
int range = 0;
Wire.beginTransmission(SRF_ADDRESS);
Wire.write(CMD);
Wire.write(UNIT);
Wire.endTransmission();
delay(100);
Wire.beginTransmission(SRF_ADDRESS);
Wire.write(RANGEBYTE);
Wire.endTransmission();
Wire.requestFrom(SRF_ADDRESS, 2);
while(Wire.available() < 2);
highByte = Wire.read();
lowByte = Wire.read();
range = (highByte << 8) + lowByte;
return(range);
}
Komunikace Python – Arduino sketch
Jak je vidět z kódu pro Arduino, tak využijeme možnost komunikace přes http. Python skript při spouštění načte zprávy ve frontě a pak je začne procházet. Pokud by se zprávy vyhodnocovali zároveň při načítání, tak se připletou i zprávy právě odeslané. Proto je třeba nejdříve frontu načíst a teprve pak do ní zapisovat. Pokud je ve frontě zpráva, která obsahuje pouze číslo, Google Id, tak se dotáže na vzdálenost a vyhodnotí přítomnost auta. Kontrola Google Id by mohla být samozřejmě sofistikovanější.
#!/usr/bin/python
import boto.sqs
import sys
import ConfigParser
import os
import re
import urllib
local_path = os.path.dirname(os.path.realpath(__file__))
config = ConfigParser.ConfigParser()
config.read(local_path + '/garage.config')
URL = config.get('arduino', 'url')
limit = int(config.get('arduino', 'limit'))
conn = boto.sqs.connect_to_region(config.get('aws', 'aws_region'))
q = conn.get_queue(config.get('aws', 'aws_queue'))
if q is None:
sys.exit(1)
messages = []
message = q.read()
while message is not None:
messages.append(message)
message = q.read()
if len(messages) == 0:
sys.exit(0)
p = re.compile('^\d*$') # looking for number
for message in messages:
body = message.get_body()
# print body
if p.match(body) is None:
continue
rng = urllib.urlopen(URL).read()
# print rng
q.delete_message(message)
answer = 'No'
if rng.isdigit():
if int(rng) > limit:
answer = 'Yes'
else:
answer = rng
# print answer
response = boto.sqs.message.RawMessage()
response.set_body(body + ';' + answer)
q.write(response);
Konfigurační soubor aplikace. Klíče jsou uloženy podle doporučení v souboru ~/.aws/credentials
:
[aws]
aws_region = eu-west-1
aws_queue = garage
[arduino]
url = http://localhost/arduino/range
limit = 200
cron
Konfigurace cron je velmi jednoduchá. Stačí se přihlásit do webového rozhraní pro konfiguraci Arduino Yún a otevřít advanced configuration panel (luci). Na záložce System otevřete záložku Scheduled Tasks. Zde můžete změnit crontab.
Na záložce Startup pak můžete zakázat, povolit nebo restartovat démona cron.
Závěr
Elektroniku máme zapojenou, skripty se spouští a už nám zbývá jen vyrobit krabičku a tu připevnit v garáži. Další díl se bude věnovat 3D tisku držáku ultrazvukového dálkoměru.