Spisu treści:

Autostat: zdalny termostat: 8 kroków (ze zdjęciami)
Autostat: zdalny termostat: 8 kroków (ze zdjęciami)

Wideo: Autostat: zdalny termostat: 8 kroków (ze zdjęciami)

Wideo: Autostat: zdalny termostat: 8 kroków (ze zdjęciami)
Wideo: Top 20 porad i wskazówek dotyczących systemu Windows 10 2024, Lipiec
Anonim
Autostat: zdalny termostat
Autostat: zdalny termostat

Pytanie, które prawdopodobnie zadajesz, brzmi „dlaczego robisz kolejny zdalny termostat?”

Odpowiedź na to pytanie jest taka, że musiałem, a inteligentne termostaty na rynku są za drogie.

Uczciwe ostrzeżenie, jest to kompilacja „sprawdzająca koncepcję”, która wymagałaby kilku dodatkowych wyjść, aby faktycznie sterować termostatem, ale rdzeń jest na miejscu i można go zmodyfikować w zależności od konkretnych okoliczności. Ponadto nadal trwają prace, więc spodziewaj się kilku aktualizacji i zmian (zwłaszcza w kodzie Matlaba)

Aby rozpocząć, chcę cię ostrzec, wymaga to trzech programów (jeden z nich jest dość drogi), wielu bibliotek i pakietów wsparcia dla programów i musisz je wszystkie rozmawiać ze sobą. To ból głowy. Z tym ostrzeżeniem zacznijmy od materiałów.

Sprzęt komputerowy

  • arduino nano
  • arduino uno (lub inne nano, właśnie użyłem uno, bo miałem jeden leżący)
  • różne kable połączeniowe, niektóre męskie / męskie i dwa zestawy trzech połączonych zworek męskich / żeńskich
  • Odbiornik częstotliwości radiowej 433 MHz (RF), użyłem MX-05V
  • Nadajnik RF 433 MHz, użyłem MX-FS-03V
  • Termometr DHT11 o wysokiej dokładności i czujnik wilgotności (ten, którego użyłem, jest zainstalowany na trzybolcowym chipie z już zainstalowanymi wymaganymi rezystorami)
  • płytka stykowa (jeśli nie chcesz tego wszystkiego lutować)
  • telefon z GPS (w tym przypadku iPhone 8, ale korzystałem też z Galaxy S8)
  • Pojemnik wydrukowany w 3D (niekoniecznie potrzebny, każdy pojemnik będzie działał lub wcale)

Oprogramowanie

  • Matlab od MathWorks (mam edycję 2018a, ale korzystałem też z edycji 2017a-b)
  • Matlab mobilny zainstalowany na twoim telefonie
  • pakiet wsparcia arduino dla Matlab
  • Pakiet czujników iPhone dla Matlab
  • Arduino IDE
  • Pakiety wsparcia RadioHead i biblioteki arduino IDE
  • Biblioteka DHT11 dla arduino IDE
  • python 3.7 (upewnij się, że zainstalowana jest biblioteka pyserial lub biblioteka szeregowa, która powinna być w wersji 3.4 lub nowszej)

Krok 1: Złożenie wszystkiego razem

Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem
Kładąc wszystko razem

Przede wszystkim sugerowałbym, abyś zrobił kilka samouczków arduino dotyczących nadajników RF, aby upewnić się, że twoje części działają, a okablowanie jest prawidłowe. Dostępnych jest wiele przykładów z dołączonym kodem (dla tych z nas, którzy wiedzą niewiele lub nic o C i C++).

Postępuj zgodnie ze schematami połączeń poniżej, aby zmontować arduino i czujniki. Jedną rzeczą, o której należy pamiętać podczas podłączania arduino, jest to, że porty danych, których użyłem, nie są wymagane, ale zalecane.

Jeśli zdecydujesz się zmienić używane porty danych, wystarczy zdefiniować piny w swoim kodzie. Osobiście uważam, że łatwiej jest trzymać się domyślnych portów, które rozpoznają biblioteki arduino.

Aby było jasne, nano i uno są wymienne, ale użyłem nano po stronie nadajnika projektu, aby zmniejszyć rozmiar monitora temperatury.

Uwaga na marginesie: zielone urządzenie trzymające nano to pojemnik wydrukowany w 3D.

Krok 2: Odbiornik

Odbiorca
Odbiorca

Krok 3: Nadajnik

Nadajnik
Nadajnik

Krok 4: Kodeks

Po zakończeniu okablowania musisz uruchomić wszystkie programy i zainstalować biblioteki (jeśli jeszcze tego nie zrobiłeś), po prostu zakładam, że tak, musisz uruchomić Matlab i uruchomić pakiet wsparcia iPhone'a. W tym momencie zarówno telefon, jak i Matlab muszą być w tej samej sieci Wi-Fi.

W oknie poleceń Matlaba napisz:

złącze włączone

To poprosi Cię o wprowadzenie pięciocyfrowego hasła, którego będziesz używać do łączenia się na swoim iPhonie. Upewnij się, że pamiętasz hasło. Po wpisaniu hasła Matlab wyświetli pewne informacje, w tym Twój adres IP. Użyj tego w następnym kroku, który pochodzi z instrukcji z menu pomocy „Pierwsze kroki z czujnikami” w aplikacji mobilnej Matlab.

  • Wykonaj poniższe czynności, aby wysłać dane z czujnika do MathWorks Cloud lub komputera:
  • Jeśli wysyłasz dane z czujnika do komputera i jeśli nie jest jeszcze zainstalowany, pobierz i zainstaluj pakiet wsparcia MATLAB dla czujników Apple iOS w MATLAB.
  • Połącz MATLAB Mobile z MathWorks Cloud lub komputerem za pomocą Ustawień.
  • Utwórz obiekt mobiledev w MATLAB (na twoim komputerze), na przykład: >> m = mobiledev
  • Wybierz jeden lub więcej czujników i dotknij Start.

Wykonaj poniższe czynności, aby rejestrować dane z czujnika lokalnie na urządzeniu:

  • Na ekranie Czujniki wybierz czujniki, z których chcesz zbierać dane.
  • Wybierz Dziennik.
  • Stuknij przycisk Start.
  • Po zakończeniu zbierania danych dotknij przycisku Zatrzymaj.
  • W wyskakującym okienku wprowadź nazwę dziennika czujnika.
  • W razie potrzeby powtórz kroki 1-5.

Ta sekcja zostanie ponownie przywołana w części 4, więc nie trzeba jeszcze zaczynać zbierania danych. Po prostu trzymaj telefon pod ręką i mobilny Matlab gotowy.

Teraz musisz utworzyć folder gdzieś na swoim komputerze, aby przechowywać pliki kodu Matlab. Będziesz mieć cztery oddzielne pliki, dwa dla funkcji działających w tle (pliki.m) i jeden plik kodu Matlab dla GUI (.mlapp),.

Pierwszym z nich jest obliczenie masy powietrza w twoim domu (dzięki temu Matlab wie, ile czasu zajmuje ogrzanie/schłodzenie domu)

funkcja [Masa]= CalcMass(T_ins, P_out, Chng_dir)

runCalc=0; Tmp_start=T_ins; time_start=zegar; time_end = 0 while runCalc <= 1 if T_ins==(Tmp_start+(7*Chng_dir)) time_end=clock; PwrCntr = 0; runCalc=0; w przeciwnym razie PwrCntr = P_out; runCalc=runCalc+0.1 koniec koniec time_diag= time_end-time_start Mass=(P_out*time_diag)/7.035

A drugi:

function [znaczniki czasu, pwr_usage]= dist_cntrl(Lat_in, Lon_in, P_out, r_pref, speed, T_pref, mass)

Autostat = 1; i = 1; podczas gdy AutoStat == 1 time_start=zegar; m = mobiledev; t = csvread('wartości.csv', 0, 1); t= t(i); znaczniki czasu= [0, 0, 0, 0, 0, 0]; pwr_usage = 0; i = i+1; format długig; Wzór %haversine do obliczania odległości na podstawie szerokości geograficznej i %longintude a_hav=(sind((m. Latitude-Lat_in)./2)).^2+cosd(Lat_in).*cosd(m.latitude).*(sind((m. Longitude-Lon_in)./2).^2; c_hav= 2.*atan2d(sqrt(a_hav), sqrt(1-a_hav)); d_hav= 6371.*c_hav; Dist=d_hav.*1000; %oszacuje Twój czas na zwrócenie time_rtn=(Dist-r_pref)./speed; % oblicza niezbędne ustawienie termostatu na podstawie poboru mocy % klimatyzatora i masy powietrza w domu. calcTmp_set=((-1.*P_out.*time_rtn)./(masa*(1.005)))+T_pref; %określa, czy bieżące ustawienie termostatu wymaga zmiany, jeśli round(calcTmp_set) ~= round(t) timeACon = clock; PwrCntr = P_out; timeACon= czasACon + zegar-czas_start; koszt=P_out*czasACon*stawka; w przeciwnym razie PwrCntr = 0 znaczników czasu końca(end+1, [1:6]) = zegar; pwr_usage(koniec+1, 1)=PwrCntr; pauza (5) koniec koniec

Oba te pliki są funkcjami Matlaba. Nie będziesz musiał uzyskiwać do nich dostępu, chyba że planujesz ich modyfikację do określonych potrzeb, ponieważ będziesz wywoływać je z GUI. Zapisz oba pliki osobno, pierwszy jako CalcMass.m, a drugi jako dist_cntrl.m, będą to nazwy, których kod GUI używa do wywoływania funkcji, więc jeśli nie chcesz edytować reszty kodu poniżej, trzymaj się konwencja nazewnictwa.

Zanim przejdziesz do kodu GUI, musisz otworzyć projektanta aplikacji dla Matlaba, który możesz otworzyć, nawigując w pasku menu Matlaba lub moją ulubioną metodą, która polega na wpisaniu następującego polecenia w oknie poleceń Matlaba:

projektant aplikacji

Po otwarciu projektanta aplikacji otwórz nowy plik aplikacji (.mlapp) i usuń cały domyślny kod z okna kodu. Następnie zastąp to wszystko następującym i naciśnij przycisk uruchamiania.

classdef Control_1 < matlab.apps. AppBase % Właściwości, które odpowiadają właściwościom składników aplikacji (dostęp = public) UIFigure matlab.ui. Figure TabGroup matlab.ui.container. TabGroup SetupTab matlab.ui.container. Tab RunDiagnosticButton matlab.ui.control. przycisk EnergyEfficiencyRatingEditFieldLabel matlab.ui.control. Label EnergyEfficiencyRatingEditField matlab.ui.control. NumericEditField PowerOutputRatingEditFieldLabel matlab.ui.control. Label PowerOutputRatingEditField matlab.ui.control. NumericEditField AvgLocalSpeedEditFieldLabel matlab.ui.control. Label AvgLocalSpeedEditField matlab.ui.control. NumericEditField DesiredDistancefromHouseEditFieldLabel matlab.ui.control. Label DDFH matlab.ui.control. NumericEditField TemperatureDirectionSwitchLabel matlab.ui.control. Label TemperatureDirectionSwitch matlab.ui.control. Switch TempSettingsTab matlab.ui.container. Tab Temperature1SpinnerLabel matlab.ui.control. Label ui.control. Spinner Temperature2SpinnerLabel matlab.ui.cont rol. Label Temperature2Spinner matlab.ui.control. Spinner Switch matlab.ui.control. Switch EditFieldLabel matlab.ui.control. Label tempnow matlab.ui.control. NumericEditField GaugeLabel matlab.ui.control. Label Gauge matlab.ui.control. Gauge SavingsTab matlab.ui.container. Tab Osie UIA matlab.ui.control. UIAx ThisMonthCostEditFieldLabel matlab.ui.control. Label ThisMonthCostEditField matlab.ui.control. NumericEditField TotalSavingsEditFieldLabel matlab.uEditFieldFieldcontrol endlab.ui.

metody (dostęp = prywatny)

% Funkcja zmiany wartości: tempnow

funkcja tempnowValueChanged(aplikacja, zdarzenie) temp = app.tempnow. Value; temp=randi([60, 90], 1, 50) App. Gauge. Value = 0 for i = length(temp) App. Gauge. Value= temp(i) pauza(1) koniec koniec

% Funkcja zmiany wartości: TemperatureDirectionSwitch

funkcja TemperatureDirectionSwitchValueChanged(aplikacja, zdarzenie) sposób = app. TemperatureDirectionSwitch. Value; way= uint8(way) way = length(way) if way == 4 Chng_dir = -1; inaczej Chng_dir = 1; koniec Chng_dir; kończyć się

% Funkcja zmiany wartości: DDFH

funkcja DDFHValueChanged(aplikacja, zdarzenie) r_pref = app. DDFH. Value; kończyć się

% Funkcja zmiany wartości: AvgLocalSpeedEditField

function AvgLocalSpeedEditFieldValueChanged(aplikacja, zdarzenie) speed = app. AvgLocalSpeedEditField. Value; kończyć się

% Funkcja zmiany wartości: PowerOutputRatingEditField

funkcja PowerOutputRatingEditFieldValueChanged(aplikacja, zdarzenie) wartość = app. PowerOutputRatingEditField. Value; kończyć się

% Funkcja zmiany wartości: EnergyEfficiencyRatingEditField

function EnergyEfficiencyRatingEditFieldValueChanged(app, event) value = app. EnergyEfficiencyRatingEditField. Value; kończyć się

% Funkcja naciśnięcia przycisku: RunDiagnosticButton

funkcja RunDiagnosticButtonPushed(aplikacja, zdarzenie) sposób = app. TemperatureDirectionSwitch. Value; way= uint8(way) way = length(way) if way == 4 Chng_dir = -1; w przeciwnym razie Chng_dir = 1; koniec T_ins = app.tempnow. Value P_out = app. PowerOutputRatingEditField. Value CalcMass1(T_ins, P_out, Chng_dir)

kończyć się

% Funkcja zmiany wartości: Temperature1Spinner

funkcja Temperature1SpinnerValueChanged(aplikacja, zdarzenie) wartość = app. Temperature1Spinner. Value; kończyć się

% Funkcja zmiany wartości: Temperature2Spinner

funkcja Temperature2SpinnerValueChanged(aplikacja, zdarzenie) wartość = app. Temperature2Spinner. Value; kończyć się

% Funkcja zmiany wartości: Przełącznik

funkcja SwitchValueChanged(aplikacja, zdarzenie) m = mobiledev; Lat_in = m. Szerokość geograficzna Lon_in = m. Długość P_out = 0; r_pref = aplikacja. DDFH. Wartość; T_pref = aplikacja. Temperatura1Spinner. Wartość; prędkość = m. Prędkość; masa = 200; prędkość = app. AvgLocalSpeedEditField. Value; Auto_Stat = aplikacja. Przełącznik. Wartość; dist_cntrl(Lat_in, Lon_in, P_out, r_pref, T_pref, speed, mass) end end

% Inicjalizacja i budowa aplikacji

metody (dostęp = prywatny)

% Utwórz UIFigure i komponenty

funkcja createComponents(aplikacja)

% Utwórz UIFigure

app. UIFigure = uifigure; app. UIFigure. Position = [100 100 640 480]; app. UIFigure. Name = 'Rysunek interfejsu użytkownika';

% Utwórz grupę kart

app. TabGroup = uitabgroup(app. UIFigure); ok. GrupaTab. Pozycja = [1 1 640 480];

% Utwórz kartę ustawień

app. SetupTab = uitab(app. TabGroup); app. SetupTab. Title = 'Konfiguracja';

% Utwórz RunDiagnosticButton

app. RunDiagnosticButton = uibutton(app. SetupTab, 'push'); app. RunDiagnosticButton. ButtonPushedFcn = createCallbackFcn(app, @RunDiagnosticButtonPushed, true); app. RunDiagnosticButton. FontWeight = 'pogrubiony'; app. RunDiagnosticButton. Position = [465 78 103 23]; app. RunDiagnosticButton. Text = 'Uruchom diagnostykę';

% Utwórz ocenę efektywności energetycznejEditFieldLabel

app. EnergyEfficiencyRatingEditFieldLabel = uilabel(app. SetupTab); app. EnergyEfficiencyRatingEditFieldLabel. HorizontalAlignment = 'prawo'; app. EfficiencyRatingEditFieldLabel. Position = [8 425 135 22]; app. EnergyEfficiencyRatingEditFieldLabel. Text = 'Ocena efektywności energetycznej';

% Utwórz ocenę efektywności energetycznejEditField

app. EnergyEfficiencyRatingEditField = uieditfield(app. SetupTab, 'numeric'); app. EfficiencyRatingEditField. Limits = [0 100]; app. EnergyEfficiencyRatingEditField. ValueChangedFcn = createCallbackFcn(app, @EnergyEfficiencyRatingEditFieldValueChanged, true); app. EnergyEfficiencyRatingEditField. HorizontalAlignment = 'środek'; app. EnergyEfficiencyRatingEditField. Position = [158 425 100 22];

% Utwórz ocenę mocy wyjściowejEdytuj etykietę pola

app. PowerOutputRatingEditFieldLabel = uilabel(app. SetupTab); app. PowerOutputRatingEditFieldLabel. HorizontalAlignment = 'prawo'; app. PowerOutputRatingEditFieldLabel. Position = [18 328 118 22]; app. PowerOutputRatingEditFieldLabel. Text = 'Ocena mocy wyjściowej';

% Utwórz ocenę mocy wyjściowejPole edycji

app. PowerOutputRatingEditField = uieditfield(app. SetupTab, 'numeric'); app. PowerOutputRatingEditField. Limits = [0 Inf]; app. PowerOutputRatingEditField. ValueChangedFcn = createCallbackFcn(app, @PowerOutputRatingEditFieldValueChanged, true); app. PowerOutputRatingEditField. HorizontalAlignment = 'środek'; app. PowerOutputRatingEditField. Position = [151 328 100 22];

% Utwórz AvgLocalSpeedEditFieldLabel

app. AvgLocalSpeedEditFieldLabel = uilabel(app. SetupTab); app. AvgLocalSpeedEditFieldLabel. HorizontalAlignment = 'prawo'; app. AvgLocalSpeedEditFieldLabel. Position = [27 231 100 22]; app. AvgLocalSpeedEditFieldLabel. Text = 'Śr. Lokalna prędkość”;

% Utwórz AvgLocalSpeedEditField

app. AvgLocalSpeedEditField = uieditfield(app. SetupTab, 'numeric'); app. AvgLocalSpeedEditField. Limits = [0 70]; app. AvgLocalSpeedEditField. ValueChangedFcn = createCallbackFcn(app, @AvgLocalSpeedEditFieldValueChanged, true); app. AvgLocalSpeedEditField. HorizontalAlignment = 'środek'; app. AvgLocalSpeedEditField. Position = [142 231 100 22];

% Utwórz pożądaną odległość od domuEdytujEtykieta pola

app. DesiredDistancefromHouseEditFieldLabel = uilabel(app. SetupTab); app. DesiredDistancefromHouseEditFieldLabel. HorizontalAlignment = 'prawo'; app. DesiredDistancefromHouseEditFieldLabel. Position = [24 129 100 28]; app. DesiredDistancefromHouseEditFieldLabel. Text = {'Pożądana odległość'; 'z domu'};

% Utwórz DDFH

app. DDFH = uieditfield(app. SetupTab, 'numeric'); app. DDFH. Limity = [0 50]; app. DDFH. ValueChangedFcn = createCallbackFcn(app, @DDFHValueChanged, true); app. DDFH. HorizontalAlignment = 'środek'; ok. DDFH. Pozycja = [139 135 100 22];

% Utwórz etykietę przełącznika kierunku temperatury

app. TemperatureDirectionSwitchLabel = uilabel(app. SetupTab); app. TemperatureDirectionSwitchLabel. HorizontalAlignment = 'środek'; app. TemperatureDirectionSwitchLabel. Position = [410 343 124 22]; app. TemperatureDirectionSwitchLabel. Text = 'Kierunek temperatury';

% Utwórz przełącznik kierunku temperatury

app. TemperatureDirectionSwitch = uiswitch(app. SetupTab, 'suwak'); app. TemperatureDirectionSwitch. Items = {'W górę', 'W dół'}; app. TemperatureDirectionSwitch. ValueChangedFcn = createCallbackFcn(app, @TemperatureDirectionSwitchValueChanged, true); app. TemperatureDirectionSwitch. Position = [449 380 45 20]; app. TemperatureDirectionSwitch. Value = 'W górę';

% Utwórz kartę TempUstawienia

app. TempSettingsTab = uitab(app. TabGroup); app. TempSettingsTab. Title = 'Temp. Ustawienia”;

% Utwórz etykietę temperatury 1Spinner

app. Temperature1SpinnerLabel = uilabel(app. TempSettingsTab); app. Temperature1SpinnerLabel. HorizontalAlignment = 'środek'; app. Temperature1SpinnerLabel. Position = [66 363 76 28]; app. Temperature1SpinnerLabel. Text = {'Temperatura '; '#1'};

% Utwórz Temperaturę1Spinner

app. Temperature1Spinner = uispinner(app. TempSettingsTab); app. Temperatura1Spinner. Limity = [60 90]; app. Temperature1Spinner. ValueChangedFcn = createCallbackFcn(app, @Temperature1SpinnerValueChanged, true); ok. Temperatura1Spinner. Pozycja = [157 346 100 68]; app. Temperatura1Spinner. Value = 60;

% Utwórz etykietę temperatury2SpinnerLabel

app. Temperature2SpinnerLabel = uilabel(app. TempSettingsTab); app. Temperature2SpinnerLabel. HorizontalAlignment = 'środek'; app. Temperature2SpinnerLabel. Position = [66 248 76 28]; app. Temperature2SpinnerLabel. Text = {'Temperatura '; '#2'};

% Utwórz Temperaturę2Spinner

app. Temperature2Spinner = uispinner(app. TempSettingsTab); app. Temperatura2Spinner. Limity = [60 90]; app. Temperature2Spinner. ValueChangedFcn = createCallbackFcn(app, @Temperature2SpinnerValueChanged, true); app. Temperature2Spinner. Position = [157 230 100 70]; app. Temperatura2Spinner. Value = 60;

% Utwórz przełącznik

app. Switch = uiswitch(app. TempSettingsTab, 'suwak'); app. Switch. Items = {'1', '0'}; app. Switch. ValueChangedFcn = createCallbackFcn(app, @SwitchValueChanged, true); app. Switch. FontName = 'Nyala'; app. Switch. FontSize = 28; pozycja.przełącznika aplikacji = [522 21 74 32]; app. Switch. Value = '0';

% Utwórz etykietę pola edycji

app. EditFieldLabel = uilabel(app. TempSettingsTab); app. EditFieldLabel. HorizontalAlignment = 'prawo'; app. EditFieldLabel. Position = [374 291 25 22]; app. EditFieldLabel. Text = '';

% Utwórz szablon

app.tempnow = uieditfield(app. TempSettingsTab, 'numeric'); app.tempnow. Limity = [60 89]; app.tempnow. ValueChangedFcn = createCallbackFcn(app, @tempnowValueChanged, true); app.tempnow. HorizontalAlignment = 'środek'; app.tempnow. FontSize = 26; ok.temperatura. Pozycja = [409 230 133 117]; ok.temperatura. Wartość = 60;

% Utwórz etykietę miernika

app. GaugeLabel = uilabel(app. TempSettingsTab); app. GaugeLabel. HorizontalAlignment = 'środek'; app. GaugeLabel. Position = [225 32 42 22]; app. GaugeLabel. Text = 'Wskaźnik';

% Utwórz wskaźnik

app. Gauge = uigauge(app. TempSettingsTab, 'okrągły'); App. Gauge. Limity = [60 90]; App. Gauge. MajorTicks = [60 65 70 75 80 85 90]; App. Gauge. Position = [185 69 120 120]; App. Gauge. Value = 60;

% Utwórz kartę oszczędności

app. SavingsTab = uitab(app. TabGroup); app. SavingsTab. Title = 'Oszczędności';

% Utwórz osie UIA

app. UIAxes = uiaxes(app. SavingsTab); title(app. UIAxes, 'Oszczędności') xlabel(app. UIAxes, 'Miesiąc i rok') ylabel(app. UIAxes, 'Pieniądze') app. UIAxes. PlotBoxAspectRatio = [1 0.606666666666667 0.606666666666667]; ok. Osie. UIA. Kolor = [0,9412 0,9412 0,9412]; app. UIAxes. Pozycja = [146 219 348 237];

% Utwórz w tym miesiącuKosztEdytujetykietępola

app. ThisMonthCostEditFieldLabel = uilabel(app. SavingsTab); app. ThisMonthCostEditFieldLabel. HorizontalAlignment = 'środek'; app. ThisMonthCostEditFieldLabel. Position = [439 96 94 22]; app. ThisMonthCostEditFieldLabel. Text = 'Koszt w tym miesiącu';

% Utwórz w tym miesiącuKosztEdytujPole

app. ThisMonthCostEditField = uieditfield(app. SavingsTab, 'numeric'); app. ThisMonthCostEditField. Limits = [0 Inf]; app. ThisMonthCostEditField. ValueDisplayFormat = '%7.2f'; app. ThisMonthCostEditField. HorizontalAlignment = 'środek'; app. ThisMonthCostEditField. Position = [417 39 137 58];

% Utwórz TotalSavingsEditFieldLabel

app. TotalSavingsEditFieldLabel = uilabel(app. SavingsTab); app. TotalSavingsEditFieldLabel. HorizontalAlignment = 'prawo'; app. TotalSavingsEditFieldLabel. Position = [111 96 77 22]; app. TotalSavingsEditFieldLabel. Text = 'Całkowite oszczędności';

% Utwórz TotalSavingsEditField

app. TotalSavingsEditField = uieditfield(app. SavingsTab, 'numeric'); app. TotalSavingsEditField. Limits = [0 Inf]; app. TotalSavingsEditField. ValueDisplayFormat = '%9.2f $'; app. TotalSavingsEditField. HorizontalAlignment = 'środek'; app. TotalSavingsEditField. Position = [88 39 137 58]; koniec koniec

metody (dostęp = publiczny)

% Konstruuj aplikację

aplikacja funkcji = Control_1

% Twórz i konfiguruj komponenty

tworzenie komponentów (aplikacja)

% Zarejestruj aplikację w Projektancie Aplikacji

registerApp (aplikacja, aplikacja. UIFigure)

jeśli nargout == 0

wyczyść koniec aplikacji

% Kod, który jest wykonywany przed usunięciem aplikacji

funkcja usuń (aplikacja)

% Usuń UIFigure po usunięciu aplikacji

usuń (app. UIFigure) koniec koniec koniec

Prawdopodobnie otrzymasz błąd, co nie stanowi problemu. Po prostu zamknij GUI, który został wygenerowany po naciśnięciu run, za chwilę zbierzemy resztę niezbędnych programów i danych.

Ponieważ Matlab jest skonfigurowany, możemy przejść do Pythona. Najpierw uruchom program Python z wiersza poleceń (w systemie Windows) lub używając pliku.exe w folderze Pythona. Upewnij się, że wszystkie odpowiednie biblioteki zostały zainstalowane za pomocą polecenia importu.

importuj serial

czas importu import csv

Oto trzy biblioteki, które musisz zacząć, chociaż wkrótce stworzymy własną bibliotekę. Jeśli wystąpił jakiś błąd z tymi poleceniami, wróć i upewnij się, że biblioteki są zainstalowane i znajdują się w folderze Lib w folderze Pythona. Następnie będziemy generować coś, co nazwałem biblioteką pythonlogger. Ta nazwa nie jest konieczna, możesz nazwać ją jak chcesz, to tylko nazwa pliku Pythona (.py), który tworzysz.

Otwórz edytor tekstu, używam Sublime3, ale notatnik działa dobrze i wprowadź ten kod.

def pythonprint():

import pythonlogger import serial import time import csv ser = serial. Serial('COM8') # COM8 to port szeregowy arduino, prawdopodobnie będzie to inne dla każdego użytkownika, tj. sprawdź port szeregowy w arduino IDE ser.flushInput() podczas True: try: ser_bytes = ser.readline() print(ser_bytes) with open("test_data.csv", "a") as f: writer = csv.writer(f, delimiter=", ") # ustawia dane na być wprowadzone jako oddzielone przecinkami writer.writerow([time.time(), ser_bytes]) #zapisuje dane do test_data.csv z wyjątkiem: print("Wystąpił błąd") break

Zapisz tekst jako „wstaw nazwę żądanej biblioteki”.py w folderze Lib. Zauważ również, że linia def pythonprint() definiuje nazwę funkcji, którą zamierzasz wywołać, więc możesz to zmienić na def "wstaw nazwę, którą chcesz dla swojej funkcji"(). Po zapisaniu biblioteki możemy przejść do kodu arduino.

Otwórz arduino IDE i otwórz dwa nowe okna szkicu. Zapisz te dwa pliki szkiców w dogodnym miejscu, nazwa tych plików nie ma znaczenia. Następnie usuń cały domyślny kod i zastąp go następującym.

Dla arduino odbiorczego:

#włączać

#include #include #include // nie jest używane, ale potrzebne do kompilacji sterownika RH_ASK; struct struktura danych { float temp; }moje dane; void setup() { Serial.begin(9600); // Debugowanie tylko jeśli (!driver.init()) Serial.println("inicjowanie nie powiodło się"); } void loop() { uint8_t buf[RH_ASK_MAX_MESSAGE_LEN]; uint8_t buflen = rozmiar(buf); if (driver.recv(buf, &buflen)) // Nieblokujący { int i; // Otrzymano wiadomość z poprawną sumą kontrolną, zrzuć ją. //driver.printBuffer("Got:", buf, buflen); memcpy(&myData, buf, sizeof(myData)); Serial.println(""); Serial.print(mojeDane.temp); } }

PS //sterownik.printBuffer…. itp. to kod testowy. Nie musisz się tym martwić, chyba że przeprowadzasz diagnostykę i chcesz dowiedzieć się, czy rzeczywiście otrzymujesz dane.

Do nadajnika arduino

#włączać

#include #include #include // to nie jest używane, ale potrzebne do kompilacji#include #include int pin=4; DHT11 dht11(pin); sterownik RH_ASK; struct struktura danych { float temp; }moje dane; bajt tx_buf[sizeof(mojeDane)] = {0}; //Więc argumentami są bitrate, pin transmisji (tx), // pin odbioru (rx), pin ppt, isInverse. Ostatnie 2 nie są używane.void setup() { Serial.begin(9600); // Debugowanie tylko jeśli (!driver.init()) Serial.println("inicjowanie nie powiodło się"); } void loop() { int err; temperatura pływania, humi; komunikat uint8_t; if((err=dht11.read(humi, temp))==0) mojeDane.temp = temp; memcpy(tx_buf, &myData, sizeof(myData)); bajt zize=sizeof(mojeDane); { Serial.println(mojeDane.temp); driver.send((uint8_t *)tx_buf, zize); driver.waitPacketSent(); //wstrzymaj wykonywanie do momentu wysłania wszystkich danych delay(2000); //czekaj 2 sekundy } }

Polecenia include powinny wystarczyć, ale jeśli będziesz miał później problemy z transferem danych, możesz zajrzeć do folderu biblioteki RadioHead i dołączyć pozostałe nazwy plików w tym samym formacie.

Krok 5: Sprawienie, by to zadziałało

Sprawiając, że to działa
Sprawiając, że to działa
Sprawiając, że to działa
Sprawiając, że to działa
Sprawiając, że to działa
Sprawiając, że to działa

Teraz, gdy mamy już cały kod i zmontowane arduino, możemy podłączyć arduino do komputera i załadować kod. Upewnij się, że wysyłasz poprawny kod do mikrokontrolerów odbierających i nadających. Możesz mieć oba arduino podłączone do komputera, gdy jest on uruchomiony, ale musisz upewnić się, że masz wybrany właściwy port do przodu, lub możesz odłączyć przesyłające arduino i zasilić je z innego źródła, gdy kod zostanie załadowany.

Mówiąc o tym, powinieneś teraz wybrać port, który jest podłączony do twojego odbierającego arduino z menu narzędzi IDE i uruchomić Pythona.

Nie otwieraj monitora szeregowego, gdy to robisz, python nie może odczytać numeru seryjnego, gdy monitor jest otwarty. Gdy python jest otwarty, wywołaj funkcję pythonprint w następujący sposób.

pythonlogger.pythonprint()

Rozpocznie to zbieranie danych z portu szeregowego arduino. Jeśli otworzysz teraz folder Pythona, zobaczysz, że został utworzony nowy plik.csv o nazwie „test_data.csv”, który zawiera wszystkie informacje o czasie i temperaturze. Będzie to plik, do którego Matlab ma dostęp, aby wykonać wszystkie obliczenia i kontrole.

Kolejne ostrzeżenie: nie otwieraj test_data.csv podczas uzyskiwania dostępu lub zapisu danych. Jeśli to zrobisz, python i/lub kod Matlaba ulegną awarii i odeśle błąd

Jeśli zdecydujesz się później otworzyć plik.csv, zauważysz, że kolumna czasu to po prostu bardzo duży ciąg liczb. Dzieje się tak, ponieważ polecenie time.time() zapisuje liczbę sekund od 1 stycznia 1970 roku.

W tym momencie python powinien drukować dane temperatury, które odczytuje z portu szeregowego. Powinien wyglądać mniej więcej tak:

b'25.03'/r/n

Nie martw się o dodatkowe znaki, kod Matlaba indeksuje pięć środkowych wartości w drugiej kolumnie pliku.csv.

Teraz, gdy wszystkie programy pomocnicze działają i dane są zbierane, możemy rozpocząć zbieranie danych GPS z programu mobilnego Matlab, który został wcześniej skonfigurowany i uruchomić kod Matlab GUI. Gdy znajdziesz się w zakładce czujnika w Matlab mobile, wybierz GPS i naciśnij przycisk Start.

Jeśli jesteś nowy w Matlab Mobile, wróć do kroku 4 i spójrz na powyższe zrzuty ekranu. Jeśli nadal masz problemy, upewnij się, że jesteś podłączony do komputera, który wybrałeś wcześniej (w zakładce ustawień) i użyj linku z polecenia "connector on", aby sprawdzić, czy Matlab jest online.

Krok 6: Korzystanie z programu

Korzystanie z programu
Korzystanie z programu

W tym systemie w tle dzieje się wiele rzeczy. Dane o temperaturze są gromadzone i rejestrowane przez arduino i pyton, Matlab zbiera dane GPS z telefonu i przeprowadza obliczenia, aby zobaczyć, jak daleko jesteś od domu i ustawia termostat na podstawie wszystkich tych informacji. Miejsce, w którym wchodzisz, podaje twoje preferencje.

Uruchom kod GUI Matlaba. Otwórz plik.mlapp i spójrz na pierwszą kartę. Będziesz musiał sam zebrać informacje na ten temat, wydajność i moc znamionową urządzenia grzewczego/chłodzącego można zwykle znaleźć na samym urządzeniu, a średnia prędkość to tylko dobre oszacowanie tego, jak szybko jeździsz. Po wprowadzeniu wartości naciśnij przycisk „Uruchom diagnostykę”, a program steruje termostatem, aby zebrać informacje o Twoim domu.

Przejdź do następnego menu.

Krok 7: Kontrola temperatury

Kontrola temperatury
Kontrola temperatury

To menu pozwala wybrać preferowaną temperaturę w domu i poza nim. Ustaw Temperaturę #1 na komfortową temperaturę, a Temperaturę #2 na wysoką lub niską wartość, która jest bezpieczna dla Twojego domu (upewnij się, że nie ustawiasz jej na 100 stopni, gdy masz w domu psy itp.).

Krok 8: Dane historyczne

Dane historyczne
Dane historyczne

Wreszcie możesz sprawdzić, ile pieniędzy zaoszczędziłeś, korzystając z automatycznej kontroli. To zasadniczo szacuje, ile energii zostałoby zużyte, gdyby termostat był ustawiony na preferowaną temperaturę 24 godziny na dobę, 7 dni w tygodniu, a następnie odejmuje faktycznie zużytą energię.

Powodzenia w budowaniu.

Zalecana: