日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【物联网毕设】基于Arduino与树莓派的智能鱼缸【二】

發布時間:2024/1/1 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【物联网毕设】基于Arduino与树莓派的智能鱼缸【二】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔

文章目錄

  • 前言
  • 一、Arduino與樹莓派進行通信
  • 二、樹莓派把數據上傳到服務器
    • 1.在樹莓派上用Django搭建服務器
    • 2.在樹莓派上搭建MySQL數據庫
    • 3.樹莓派把數據post到服務器上
  • 三、微信小程序通過服務器獲取數據庫的值
  • 總結


前言

本文主要講的是智能魚缸樹莓派部分,也是我的畢業設計我認為最棘手的部分。

一、Arduino與樹莓派進行通信

看過我上一篇文章的小伙伴們應該知道,現在我們已經實現了Arduino讀取傳感器的值,那我們怎么將它傳給樹莓派呢?(注:如果你手里是一塊全新的樹莓派,需要安裝鏡像源,實現遠程訪問等準備工作,推薦B站樹莓派教程:https://www.bilibili.com/video/BV1bt411c7fC?share_source=copy_web只看前四節課就完全ok)
參考鏈接:樹莓派與Arduino通信

在跟著這個帖子成功實現簡單的通訊后(我用的是USB通訊),接下來要做的就是把我的Arduino里接收到的傳感器的數據傳給樹莓派了。
上代碼!
在Arduino IDE里寫入下面這段代碼,覆蓋我上一篇文章里Arduino IDE上的代碼(此代碼在之前的基礎上加入了Arduino向樹莓派傳數據的部分):
Arduino代碼:

#include <OneWire.h> #include <DallasTemperature.h>#define tempPin 2// 溫度傳感器數據輸出腳接開發板數字引腳2 #define waterpower 7 //水位傳感器VCC引腳 #define waterpin A0 //水位傳感器輸出引腳 #define oxygenpin A1//溶解氧傳感器輸出引腳OneWire oneWire(tempPin); DallasTemperature sensors(&oneWire);int temp_relaypin=3;//溫度傳感器繼電器1引腳為3 int waterup_relaypin=4;//水位傳感器繼電器引腳為4 int waterdown_relaypin=5;//水位傳感器繼電器引腳為5 int oxygen_relaypin=9;//溶解氧傳感器繼電器引腳為9float temperature; int oxygen; int water_level; int val=0; int incomedate = 0;void setup(void) {Serial.begin(9600);//連接到電腦串口監視器sensors.begin();pinMode(temp_relaypin,OUTPUT);//設置繼電器1為輸出模式pinMode(tempPin,OUTPUT);//溫度傳感器輸出模式pinMode(waterup_relaypin,OUTPUT);//繼電器輸出模式pinMode(waterdown_relaypin,OUTPUT);//繼電器輸出模式pinMode(waterpower,OUTPUT);//將水位傳感器VCC引腳設置成輸出模式pinMode(oxygen_relaypin,OUTPUT);//溶解氧繼電器4輸出模式 digitalWrite(waterpower,LOW);//先將水位傳感器VCC引腳關閉 }int readwatersensor() {digitalWrite(waterpower,HIGH);//將水位傳感器VCC電源打開給傳感器供電delay(10);val=analogRead(waterpin);//讀取水位傳感器A0引腳的值digitalWrite(waterpower,LOW);//將水位傳感器電源關閉return val;//返回val值 }void loop(void) { //溫度sensors.requestTemperatures(); // 發送命令獲取溫度temperature=sensors.getTempCByIndex(0);//溶解氧int analog=analogRead(A1);//讀取模擬輸入值oxygen=map(analog,0,1023,0,10);//將模擬輸入0~1023等比映射到0mg/L~10mg/LanalogWrite(9,oxygen);//水位int level=readwatersensor();//讓level=valwater_level=readwatersensor();//讓water_level=valif(Serial.available()){incomedate = Serial.read();//獲取串口接收到的數據if (incomedate == 't'){ Serial.println(temperature); //向樹莓派發送信息}else if (incomedate == 'w'){ Serial.println(water_level); //向樹莓派發送信息}else if (incomedate == 'o'){ Serial.println(oxygen); //向樹莓派發送信息}}//繼電器控制加熱棒if(temperature<25)//如果溫度小于25度{digitalWrite(temp_relaypin, HIGH);//繼電器1開,加熱棒開}else{digitalWrite(temp_relaypin,LOW); //繼電器1關,加熱棒關; }delay(500);//繼電器控制水泵if(water_level<550)//如果水位在傳感器1CM之下{digitalWrite(waterup_relaypin, HIGH);//繼電器2開,放水水泵開}else{if(water_level>640){digitalWrite(waterdown_relaypin, HIGH);//繼電器3開,抽水水泵開}else{digitalWrite(waterup_relaypin, LOW);//繼電器2關digitalWrite(waterdown_relaypin, LOW);//繼電器3關}}//繼電器控制增氧泵if(oxygen<5){digitalWrite(oxygen_relaypin, HIGH);//繼電器4開,充氧泵開}else{digitalWrite(oxygen_relaypin, LOW);//繼電器4關,充氧泵開}delay(500); }

在樹莓派上新建一個post.py文件,寫入:
樹莓派代碼:

import RPi.GPIO as GPIO import serial import time import json,requests import datetime ser = serial.Serial('/dev/ttyUSB0', 9600,timeout=1); #open named port at 9600,1s timeot #try and exceptstructure are exception handler while 1:for i in range(2):send='t';ser.write(send.encode());#wrt a string to porttime.sleep(2);temperature = ser.readline().decode();#read a string from portprint(temperature);send='w';ser.write(send.encode());#wrt a string to porttime.sleep(2);water_level= ser.readline().decode();#read a string from portprint(water_level);send='o';ser.write(send.encode());#wrt a string to porttime.sleep(2);oxygen = ser.readline().decode();#read a string from portprint(oxygen);

注意樹莓派代碼第六行里的:/dev/ttyUSB0,還有人是/dev/ttyACM0,要知道你的是什么,把樹莓派和Arduino用USB連接后,在樹莓派終端輸入: ls /dev/tty*查看兩者連接端口的名字,多出哪個就是哪個。
for i in range(2): 的意思是讓樹莓派打印兩次,因為經過實驗,發現第一個值一直打不出來,咱也不知道為什么,硬件有時候就是玄學,所以就讓這段代碼循環兩次,讓樹莓派和Arduino之間實現穩定的傳值。
提醒一下之后post.py里還要寫入一部分代碼,也就是說目前上面的這段樹莓派里的代碼只是一部分,所以你試驗的時候,可能會出現多余的頭文件,然后樹莓派的IDE報錯,沒事,暫時把沒有用到的頭文件注釋掉就好了,后面會用得著的(我可真是太貼心了)。
運行結果:

注意這里是后期要放在論文里的截圖,特意把第一個沒有打出來的temperature蓋住了(怕老師問我我答不上來),然后讓程序循環了五次。

二、樹莓派把數據上傳到服務器

現在我們的樹莓派已經得到了從Arduino上傳過來的傳感器數據了。接下來就是把數據上傳到服務器,通過服務器寫入到數據庫了。首先,我們得有一個基于樹莓派的服務器。其次,我們樹莓派上得有一個MySQL數據庫。然后,我們要把服務器和數據庫連接起來。最后,把樹莓派上的數據post到服務器。接下來我一部分一部分的細說。
參考鏈接:https://blog.csdn.net/weixin_52079689/article/details/109383872?spm=1001.2014.3001.5506

1.在樹莓派上用Django搭建服務器

參考鏈接:https://blog.csdn.net/damanchen/article/details/85224686
跟著這個鏈接,我們可以在樹莓派上下載好Django。需要注意的是,你的樹莓派要有python,我的3B里python默認的是python2。為了之后方便操作,我需要將python2換成python3,這個視情況而定,你不一定非得改。如果你也想改,推薦鏈接:https://blog.csdn.net/ylzmm/article/details/107827065
好的。現在我們的樹莓派上已經有Django了,可以正式開始創建一個服務器了。
輸入:

django-admin.py startproject fish_tank2#生成網站 cd fish_tank2 python manage.py startapp index2#生成app

創建好后的截圖:

配置功能:
需要說明以下我的項目名都是fish_tank,app都叫index。上面的項目和app是我為了演示新建的。名字會有變化。
fish_tank/setting

這里是有關樹莓派數據庫的,要加這兩句代碼。

import pymysql pymysql.install_as_MySQLdb()


[’*’]是為了讓同一局域網下面不同ip都可以訪問該服務器。

這是連接數據庫。后面會講到樹莓派上搭建數據庫,這里就是將數據庫與服務器連接起來的代碼。
fish_tank/urls.py

from django.conf.urls import url from django.urls import path, includeurlpatterns = [#path('admin/', admin.site.urls),url(r'^sensor/', include('index.urls')), ]

fish_tank/index/admin.py

from django.contrib import admin# Register your models here. from .models import *class SensorAdmin(admin.ModelAdmin):list_display = ('id', 'time', 'temperature','water_level','oxygen')admin.site.register(Sensors, SensorAdmin)

fish_tank/index/app.py

from django.apps import AppConfigclass IndexConfig(AppConfig):default_auto_field = 'django.db.models.BigAutoField'name = 'index'

fish_tank/index/models.py

from django.db import models# Create your models here. class Sensors(models.Model):time = models.DateTimeField(auto_now_add=False)temperature = models.CharField(max_length=10)water_level= models.CharField(max_length=10)oxygen = models.CharField(max_length=10)def __str__(self):return self.time

fish_tank/index/serializers.py(沒有的文件就右鍵新建)

from rest_framework import serializers from index.models import Sensors class SensorSerializer(serializers.ModelSerializer):class Meta:model = Sensorsfields = ['time', 'temperature','water_level','oxygen']

fish_tank/index/urls.py

from django.conf.urls import url from index import viewsurlpatterns = [url(r'^post', views.Sensors_api.as_view(),name='sensor.Sensors_api'),url(r'^get', views.SensorView.as_view(),name='sensor.Sensors_api'), ]

這里新建了兩個網址,post用來接收樹莓派上傳的數據,得到的是所有的數據;get用來顯示最新的數據,因為我們只需要當前的數據。為什么要寫成兩個網址呢?是因為post用的接口和get不一樣,get用的那個接口可以顯示最新值,但是post的那個接口我沒有找到如何顯示最新的值的方法,所以就寫了兩個網址,一個用來接收數據,一個用來顯示最新數據到服務器上,后續小程序也方便get到最新數據。
fish_tank/index/views.py

from rest_framework.response import Response from rest_framework.views import APIViewfrom index.models import Sensors from index.serializers import SensorSerializer from rest_framework import generics# Create your views here. class Sensors_api(generics.ListCreateAPIView):#queryset = Sensors.objects.last()queryset = Sensors.objects.all()serializer_class = SensorSerializerclass SensorView(APIView):def get(self, request, *args, **kwargs):sensor = Sensors.objects.last()obj = SensorSerializer(sensor)return Response(obj.data)

這里就可以看出來,我post用的是ListCreateAPIView這個接口,get用的是APIView這個接口。
到此,樹莓派上成功搭建起了一個web服務器。

2.在樹莓派上搭建MySQL數據庫

在樹莓派上設置安裝MySQL,設置用戶名密碼,推薦鏈接:點我
注意這里設置的用戶名密碼要和setting里連接的一樣。
建議在pc端下載Navicate,連接樹莓派上的數據庫,這樣有了圖形化界面,建表看著也舒心。
然后執行給數據庫建表的兩句代碼:
參考鏈接:點我

python manage.py makemigrations python manage.py migrate

Navicate與樹莓派數據庫連接成功:

到此,數據庫和服務器全都創建成功,并且進行了連接。

3.樹莓派把數據post到服務器上

在剛才樹莓派post.py后面加上此代碼:

# Post Data to webpagerqs_headers={'Content-Type': 'application/json'}requrl ='http://192.168.43.121:8000/sensor/post/'new_data = {"time": datetime.datetime.now(),"temperature": temperature,"water_level": water_level,"oxygen": oxygen}class ComplexEncoder(json.JSONEncoder):def default(self, obj):if isinstance(obj, datetime.datetime):return obj.strftime('%Y-%m-%d %H:%M:%S')elif isinstance(obj, datetime.date):return obj.strftime('%Y-%m-%d')else:return json.JSONEncoder.default(self, obj)test_data = json.dumps(new_data, cls=ComplexEncoder)response = requests.post(url=requrl, headers=rqs_headers, data=test_data)time.sleep(50);

運行服務器:
記得要先進入項目的文件夾在文件夾在運行哦

運行:

python manage.py runserver 0.0.0.0:8000

在瀏覽器上輸入:192.168.43.121:8000/sensor/post/和192.168.43.121:8000/sensor/get/
192.168.43.121是我樹莓派的ip地址,你們輸網址的時候要改成自己的ip地址。

運行post.py文件,可以看到post頁面獲取到了所有的值,get頁面獲取到了最新值,Navicat中可以看到數據庫里更新了值。
post頁面:

get頁面:

Navicat連接數據庫頁面:

如果你不想手動點擊post.py,而是想讓它自動每60秒執行一次,可以:

sudo -i crontab -e */1 * * * * python /home/pi/Desktop/post.py #把這個命令加到最后一行,我設定的是每分鐘運行一次,用的時候把注釋去掉就好了。 sudo /etc/init.d/cron restart

這個時候post.py里的while 1 就可以去掉了。我把自動執行的放到post2.py里,手動執行的放在post.py里,手動的方便調試,自動的最后使用。
至此,由arduino獲取傳感器數值,并傳給樹莓派,樹莓派上傳到服務器,通過服務器寫入到數據庫就完成了。

三、微信小程序通過服務器獲取數據庫的值

最后一步!!終于快寫完了!!
我們要開發一個微信小程序,讓小程序通過服務器獲取到傳感器的數值。
微信小程序課程推薦的B站鏈接:
下載微信開發者工具
注冊賬號,獲取到appid

其實不用做那么復雜,只需要改兩段代碼,其他的默認就行:
index.wxml

<!--index.wxml--> <view class="container"><view class="userinfo"><block wx:if="{{canIUseOpenData}}"><view class="userinfo-avatar" bindtap="bindViewTap"><open-data type="userAvatarUrl"></open-data></view><open-data type="userNickName"></open-data></block><button type="primary" bindtap="get_message">獲取傳感器數值</button><view>時間:{{message.time}}</view><view>溫度:{{message.temperature}}</view><view>水位:{{message.water_level}}</view><view>溶解氧:{{message.oxygen}}</view><view>加熱棒:{{message.temperature >25 ? '關': '開'}}</view><view>充氧泵:{{message.oxygen >5 ? '關': '開'}}</view><view>加水水泵:{{message.water_level <550 ? '開': '關'}}</view><view>抽水水泵:{{message.water_level >640 ? '開': '關'}}</view></view> </view>

這里只加了一個按鈕
index.js

// index.js // 獲取應用實例 const app = getApp()Page({data: {message:[],motto: 'Hello World',userInfo: {},hasUserInfo: false,canIUse: wx.canIUse('button.open-type.getUserInfo'),canIUseGetUserProfile: false,canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需嘗試獲取用戶信息可改為false},// 事件處理函數bindViewTap() {wx.navigateTo({url: '../logs/logs'})},onLoad() {if (wx.getUserProfile) {this.setData({canIUseGetUserProfile: true})}},getUserProfile(e) {// 推薦使用wx.getUserProfile獲取用戶信息,開發者每次通過該接口獲取用戶個人信息均需用戶確認,開發者妥善保管用戶快速填寫的頭像昵稱,避免重復彈窗wx.getUserProfile({desc: '展示用戶信息', // 聲明獲取用戶個人信息后的用途,后續會展示在彈窗中,請謹慎填寫success: (res) => {console.log(res)this.setData({userInfo: res.userInfo,hasUserInfo: true})}})},getUserInfo(e) {// 不推薦使用getUserInfo獲取用戶信息,預計自2021年4月13日起,getUserInfo將不再彈出彈窗,并直接返回匿名的用戶個人信息console.log(e)this.setData({userInfo: e.detail.userInfo,hasUserInfo: true})},get_message(){var that = this;wx.request({url: 'http://192.168.43.121:8000/sensor/get',success(data){console.log(data.data)that.setData({message:data.data})}})}, })

這里get數據。
在手機上運行的結果:(我點擊按鈕會出來傳感器數值)

總結

終于寫完了,最后再整體捋一遍
1、arduino獲取傳感器數值
2、arduino與樹莓派進行通訊,樹莓派獲取傳感器數值
3、樹莓派將數值上傳到服務器上,通過服務器寫入數據庫,服務器用Django寫,然后與樹莓派上數據庫進行連接。
4、微信小程序通過服務器獲取數據庫值。
我去歇一會兒。

總結

以上是生活随笔為你收集整理的【物联网毕设】基于Arduino与树莓派的智能鱼缸【二】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。