Schalten Sie einen Ventilator ein, wenn die Temperatur zu hoch ist! – Anleitung für elektrische Imps
In unserem letzten Electric Imp-Tutorial Ubidots Temperatur, Luftfeuchtigkeit und den allgemeinen thermischen Komfort misst . Diesmal bauen wir eine einfache Ein-/Ausschaltsteuerung für einen Ventilator. Wir protokollieren die Temperatur in Ubidots und lösen ein Ereignis aus, sobald sie 30 °C übersteigt, sodass der Electric Imp einen Ventilator einschaltet. Anschließend schalten wir ihn wieder aus, sobald die Temperatur unter 27 °C sinkt.
Es funktioniert wirklich einwandfrei, also los geht's:
Materialien
- Drei weibliche auf weibliche Drähte
- 10k Widerstand
- DHT11 Feuchtigkeits- und Temperatursensor
-Ein kleiner Fan
Verdrahtung
So sollten alle Komponenten miteinander verbunden werden:
…und nur noch eins fehlt: Schließen Sie Ihren Ventilator an!
Codierung
- Melden Sie sich in der Electric Imp IDE an und notieren Sie sich die URL Ihres Imp:
Kopieren Sie die nächsten beiden Codes. Im Agent-Code verwenden wir eine Funktion zur Verarbeitung von HTTP-Anfragen an Ubidots. Vergessen Sie nicht, Ihr Ubidots-Token und die Variablen-ID einzutragen.
- Agentencode:
device.on("temp", function(value) { //server.log("Versuche, den Wert an Ubi zu senden:"); //server.log(value); local headers = { "Content-Type": "application/json", "X-Auth-Token": "NBbF3PWPxWc2IaO40aXOKnhIu8tOv92rYN3ibiEc7Jh6GV3KZUUCHtXuNz7Y" }; // Ersetzen Sie das Token durch Ihr eigenes local url = "ubidots"; // Ersetzen Sie die Variablen-ID durch Ihre eigene local string = {"value": value}; local request = http.post(url, headers, http.jsonencode(string)); local response = request.sendsync(); }); device.on("hum", function(value) { //server.log("Trying to post to Ubi the value:hola"); //server.log(value); local headers = { "Content-Type": "application/json", "X-Auth-Token": "NBbF3PWPxWc2IaO40aXOKnhIu8tOv92rYN3ibiEc7Jh6GV3KZUUCHtXuNz7Y" }; // Ersetzen Sie das Token durch Ihr eigenes local url = "ubidots"; // Ersetzen Sie die Variablen-ID durch Ihre eigene local string = {"value": value}; local request = http.post(url, headers, http.jsonencode(string)); local response = request.sendsync(); }); function requestHandler(request, response) { try { // Prüfen, ob der Benutzer led als Abfrageparameter gesendet hat if ("relay" in request.query) { server.log("entre"); // Falls ja und led=1, Variable auf 1 setzen if (request.query.relay == "1" || request.query.relay == "0") { // Den Abfrageparameter led in eine Ganzzahl umwandeln local relayState = request.query.relay.tointeger(); // Nachricht "led" an das Gerät senden und ledState als Daten senden device.send("relay", relayState); } } // Antwort senden, dass alles in Ordnung war. response.send(200, "OK"); } catch (ex) { response.send(500, "Interner Serverfehler: " + ex); } } // HTTP-Handler registrieren http.onrequest(requestHandler);
- Gerätecode:
Beachten Sie den letzten Teil des Codes, in dem sich eine Funktion zum Ein- und Ausschalten des Lüfters mit dem Powerswitch-Anschluss befindet.
const SPICLK = 937.5; // Klasse zum Auslesen des DHT11 Temperatur-/Feuchtigkeitssensors // Diese Sensoren verwenden ein proprietäres Ein-Draht-Protokoll. Der Imp // emuliert dieses Protokoll mit SPI. // Verwendung: // - MOSI mit MISO über einen 10kΩ-Widerstand verbinden // - MISO mit der Datenleitung des Sensors verbinden class DHT11 { static STARTTIME_LOW = 0.001000; // 1 ms Low-Zeit für den Start static STARTTIME_HIGH = 0.000020; // Mindestens 20 µs High-Zeit für den Start static STARTTIME_SENSOR = 0.000080; // 80 µs Low-/80 µs High-„ACK“ vom Sensor beim Start static MARKTIME = 0.000050; // 50 µs Low-Impuls zwischen 0- und 1-Markierungen static ZERO = 0.000026; // 26 µs High für „0“ static ONE = 0.000075; // 70 µs High für "1" spi = null; clkspeed = null; bittime = null; bytetime = null; start_low_bits = null; start_low_bytes = null; start_high_bits = null; start_high_bytes = null; start_ack_bits = null; start_ack_bytes = null; mark_bits = null; mark_bytes = null; zero_bits = null; zero_bytes = null; one_bits = null; one_bytes = null; // Klassenkonstruktor // Eingabe: // _spi: ein vorkonfiguriertes SPI-Peripheriegerät (z. B. spi257) // _clkspeed: die konfigurierte Geschwindigkeit des SPI // Rückgabe: (None) constructor(_spi, _clkspeed) { this.spi = _spi; this.clkspeed = _clkspeed; bittime = 1.0 / (clkspeed * 1000); bytetime = 8.0 * bittime; start_low_bits = STARTTIME_LOW / bittime; start_low_bytes = (start_low_bits / 8); start_high_bits = STARTTIME_HIGH / bittime; start_high_bytes = (start_high_bits / 8); start_ack_bits = STARTTIME_SENSOR / bittime; start_ack_bytes = (start_ack_bits / 8); mark_bits = MARKTIME / bittime; mark_bytes = (mark_bits / 8); zero_bits = ZERO / bittime; zero_bytes = (zero_bits / 8); one_bits = ONE / bittime; one_bytes = (one_bits / 8); } // Hilfsfunktion // Gegeben ein langer Blob, werden die Zeiten zwischen Übergängen ermittelt und in // Temperatur- und Feuchtigkeitswerte geparst. Geht von einem 40-Bit-Rückgabewert aus (16 Werte für Luftfeuchtigkeit / 16 Werte für Temperatur / 8 Werte für Prüfsumme) // Eingabe: // HexBlob (Blob beliebiger Länge) // Rückgabe: // Tabelle mit: // "rh": relative Luftfeuchtigkeit (float) // "temp": Temperatur in Celsius (float) // Bei einem Lesefehler geben rh und temp 0 zurück function parse(hexblob) { local laststate = 0; local lastbitidx = 0; local gotack = false; local rawidx = 0; local result = blob(5); // 2 Byte Luftfeuchtigkeit, 2 Byte Temperatur, 1 Byte Prüfsumme local humid = 0; local temp = 0; // Iteriere durch jedes Bit jedes Bytes des zurückgegebenen Signals für (local byte = 0; byte < hexblob.len(); byte++) { for (local bit = 7; bit >= 0; bit--) { local thisbit = (hexblob[byte] & (0x01 << bit)) ? 1:0; if (thisbit != laststate) { if (thisbit) { // Übergang von niedrig nach hoch; beobachte, wie lange es hoch ist laststate = 1; lastbitidx = (8 * byte) + (7 - bit); } else { // Übergang von hoch nach niedrig; laststate = 0; local idx = (8 * byte) + (7 - bit); local hightime = (idx - lastbitidx) * bittime; // Wir haben jetzt ein gültiges Informationsbit. Bestimme, welches Symbol es ist. local resultbyte = (rawidx / 8); local resultbit = 7 - (rawidx % 8); //server.log(format("bit %d of byte %d",resultbit, resultbyte)); if (hightime < ZERO) { // this is a zero if (gotack) { // don't record any data before the ACK is seen result[resultbyte] = result[resultbyte] & ~(0x01 << resultbit); rawidx++; } } else if (hightime < ONE) { // this is a one if (gotack) { result[resultbyte] = result[resultbyte] | (0x01 << resultbit); rawidx++; } } else { // this is a START ACK gotack = true; } } } } } //server.log(format("parsed: 0x %02x%02x %02x%02x %02x",result[0],result[1],result[2],result[3],result[4])); humid = (result[0] * 1.0) + (result[1] / 1000.0); if (result[2] & 0x80) { // negative Temperatur result[2] = ((~result[2]) + 1) & 0xff; } temp = (result[2] * 1.0) + (result[3] / 1000.0); if (((result[0] + result[1] + result[2] + result[3]) & 0xff) != result[4]) { return {"rh":0,"temp":0}; } else { return {"rh":humid,"temp":temp}; } } // Sensor auslesen // Eingabe: (keine) // Rückgabe: // Tabelle mit: // "rh": relative Luftfeuchtigkeit (float) // "temp": Temperatur in Celsius (float) // Bei Lesefehlern geben rh und temp 0 zurück function read() { local bloblen = start_low_bytes + start_high_bytes + (40 * (mark_bytes + one_bytes)); local startblob = blob(bloblen); for (local i = 0; i < start_low_bytes; i++) { startblob.writen(0x00,'b'); } for (local j = start_low_bytes; j < bloblen; j++) { startblob.writen(0xff,'b'); } //server.log(format("Sending %d bytes", startblob.len())); local result = spi.writeread(startblob); return parse(result); } } relay <- hardware.pin8; spi <- hardware.spi257; rele.configure(DIGITAL_OUT); function setRelay(relayState){ server.log("relayState:" + relayState ); relay.write(relayState); } agent.on("relay", setRelay); function mainLoop(){imp.wakeup(1.0, mainLoop); clkspeed <- spi.configure(MSB_FIRST, SPICLK); dht11 <- DHT11(spi, clkspeed); data <- dht11.read(); server.log(format("Relative Humidity: %0.1f",data.rh)+" %"); server.log(format("Temperature: %0.1f C",data.temp)); agent.send("temp",data.temp); agent.send("hum",data.rh); }mainLoop();
Ubidots -Events einrichten
-
Erstellen Sie in Ihrem Ubidots -Konto eine Datenquelle mit zwei Variablen: Temperatur und Luftfeuchtigkeit
-
Klicken Sie auf den Abschnitt „Veranstaltungen“ und fügen Sie eine hinzu:
- Wählen Sie „Elektrischer Impuls“ als Quelle und „Temperatur“ (temp) als Variable.
- Füge eine Bedingung hinzu, die ausgelöst wird, wenn die Temperatur über 30ºC liegt.
- Wählen Sie „Anforderungs-URL“ und geben Sie Ihre Imp-URL plus „?relay=1“ ein
- Füge ein weiteres Ereignis mit dieser Bedingung hinzu.
- Wählen Sie „URL anfordern“ und geben Sie Ihre Imp-URL plus „?relay=0“ ein
Zusammenfassung
In diesem Projekt konnten wir mit Electric Imp einen Ventilator über das Internet steuern. Genau wie wir den Ventilator anhand von Temperaturdaten gesteuert haben, lassen sich auch beliebige andere Daten erfassen und darauf basierend Aktionen auslösen. Beispielsweise könnte man das Garagentor öffnen, sobald sich die Katze einem Bewegungsmelder nähert (und somit nach draußen möchte!).
Vergessen Sie nicht, einen Blick auf unsere neuesten Beiträge zu werfen:
- Verbinde einen Electric Imp (imp002) mit Ubidots
- Erstellung eines Echtzeit-Karten-Widgets mit Ubidots
Wenn Sie Ubidots , schauen Sie sich dieses tolle Einführungsstück und melden Sie sich noch heute kostenlos an!