使用Arduino UNO板、DHT11温湿度传感器和ESP

您所在的位置:网站首页 温湿度传感器怎么使用 使用Arduino UNO板、DHT11温湿度传感器和ESP

使用Arduino UNO板、DHT11温湿度传感器和ESP

2024-07-18 05:10:33| 来源: 网络整理| 查看: 265

文章目录

前言一、spring boot后台的快速搭建1.数据库以及表的搭建2.spring boot 项目的快速初始化3.Data Access 层的实现3.1 dao包的实现① Sensor类② SensorRepository接口4.Service 层的实现4.1 dto包的实现① SensorDTO类4.2 converter包的实现① SensorConverter类4.3 service包的实现① SensorService 接口② SensorServiceImpl 类5.Controller 层的实现5.1 Response 类的实现5.2 controller包的实现① SensorController 类6.测试API① 插入数据测试② 访问所有数据测试二、通过Arduino UNO、DHT11和ESP-01S调用接口插入温湿度数据1.连线2.Arduino 代码3.测试三、前端页面的绘制1.前端代码2.spring boot项目配置2.1 config包① CrossConfig类2.2 测试3.spring boot项目实现页面导航3.1 添加页面静态文件3.2 实现 PageController 进行页面导航3.3 测试总结 前言

本文简要介绍如何自己搭建一个后台,并使用Arduino UNO板、DHT11温湿度传感器和ESP-01S WiFi模块向后台发送数据来实现物联。

这里我说一下简要的思路,我们搭建一个spring boot后台,预留出2个接口,一个接口用于存储数据,即接收ESP-01S发送过来的温湿度数据,并存储到数据库中;一个接口用于检索数据库的数据,即数据库中存储的温湿度数据,然后我们再利用这些数据来渲染页面。

所需器件:Arduino UNO板、DHT11温湿度传感器、ESP-01S Wi-Fi模块

使用的库:DHT11

后台:spring boot,Spring Data JPA

前端:Echarts、HTML、JavaScript、CSS

数据库:MySQL

用到的编辑器:IDEA、Arduino IDE

一、spring boot后台的快速搭建

我们要通过 ESP-01S Wi-Fi 模块来发送AT命令实现数据的传输和存储(对数据库的操作),就要把后台的 API 实现出来,以便访问。下图是 spring boot 框架的示意图,我们要实现 API 层,就需要从 Data Access 层、Service 层到 API 层逐步实现。

1.数据库以及表的搭建

这里我们想要显示一个页面,其包含时间、温度和湿度,故我们要创建一个这样的表,其字段包含时间、温度和湿度等属性,为了标识不同的字段,我们还添加一个id属性,故该数据库和表定义为:

sensor 数据库:

sensordata 表:

2.spring boot 项目的快速初始化

这里我推荐一个网页,可以帮助我们快速初始化一个spring boot应用框架:https://start.spring.io/

我们的选择如下:

这里我简要介绍一些各个选项的意义:

① project 我们用 Maven 来进行管理依赖;

② 我们搭建后台的语言是 Java;

③ 我们选择的spring boot版本是3.2.6;

④ Project Metadata则是项目名、包名的定义等等;

⑤ 我们打包时会打包成 Jar 包;

⑥ 我们的 Java 版本为 Java17;

⑦ 导入依赖:

        Spring Web :我们提供 API 服务需要 Spring Web; 

        Spring Data JPA :Spring 对访问数据库的一个抽象,具体实现例如Hibernate(默认);

        MySql Driver:我们使用 Mysql 数据库,故需要 MySql Driver。

点击下方的“GENERATE”,便可生成初始的项目代码:

下载完后,我们把压缩包解压,并使用 IDEA 打开:

选择 pom.xml 打开,然后选择 Open as Project:

打开完之后,这里我简要说一下项目的目录结构:

① 首先,我们 Java 的源代码基本都是放在 src/main/java 当中;

② resources 则是放置我们的一些静态文件:例如前端页面、配置文件等等;

③ application.properties 是默认的全局配置文件;

④ pom.xml 是我们项目配置依赖的文件。

到这里,我们spring boot 项目就已经快速初始化好了。

这里我们可以进行一个测试,首先我们在 application.properties中连接我们的数据库。

(因为我们有导入JPA依赖,所以如果没配置数据库的话,运行会报错。)

点击“Reload All Maven Projects”

然后我们运行项目:

这里我们可以看到服务在本地的8080端口运行,故我们打开浏览器访问 localhost:8080:

(这里我们没提供API,故出现Whitelabel Error Page是正常的)

3.Data Access 层的实现

Data Access 层是访问数据库的代码。由于MySql 是关系型数据库,而 Java 又是面向对象的语言,故我们需要把 MySql 的表结构映射成 Java 对象,这里我们通过 JPA 来实现。

3.1 dao包的实现

新建dao包:

然后我们需要创建一个类和一个接口,分别是 Sensor 类与 SensorRepository 接口。

① Sensor类

这里我们会使用@注解把它加入到Spring的容器中,方便后续其他对象的注入。

@Entity 表示它是映射到数据库表的一个对象;

@Id 表示它是一个主键;

@Column 则是指定映射表的哪个字段;

@GeneratedValue(strategy = GenerationType.IDENTITY) 表示 Id 是数据库帮助我们生成的。

(最后注意实现其 Getter 和 Setter 方法)

最终 Sensor 类的代码如下:

package com.jmu.sensor.dao; import jakarta.persistence.*; import java.time.LocalDateTime; @Entity @Table(name="sensordata") public class Sensor { @Id @Column(name="id") @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name="timestamp") private LocalDateTime date; @Column(name="temperature") private double temperature; @Column(name="humidity") private double humidity; public int getId() { return id; } public void setId(int id) { this.id = id; } public LocalDateTime getDate() { return date; } public void setDate(LocalDateTime date) { this.date = date; } public double getTemperature() { return temperature; } public void setTemperature(double temperature) { this.temperature = temperature; } public double getHumidity() { return humidity; } public void setHumidity(double humidity) { this.humidity = humidity; } } ② SensorRepository接口

SensorRepository 的话主要就继承 JpaRepository 接口,该接口会帮助我们实现许多关于数据库的常用操作。

SensorRepository 接口代码如下:

package com.jmu.sensor.dao; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface SensorRepository extends JpaRepository { }

最终dao包的目录结构为:

 

4.Service 层的实现

我们实现好了了 Data Access 层后,便可访问数据库的数据,这时候就可以开始进行业务逻辑的处理了,这部分代码主要集中在 Service 层。

4.1 dto包的实现

如果我们数据库的字段有些不想透露给用户看,例如这里我们的传感器只提供温度和湿度给后台,而我们的数据库表中除了包含温度和湿度字段,还包含了id、时间戳字段,这些我们不希望是通过传感器来进行设置,故我们可以通过新增加一个类来实现,该类所包含的属性就仅仅包含我们希望透露给用户的属性,即温度和湿度。

新建 dto 包:

① SensorDTO类

SensorDTO 只需要包含希望透露给用户的属性,即温度和湿度,故其代码如下:

(注意要实现 Getter 和 Setter 方法)

package com.jmu.sensor.dto; public class SensorDTO { private double humidity; private double temperature; public double getHumidity() { return humidity; } public void setHumidity(double humidity) { this.humidity = humidity; } public double getTemperature() { return temperature; } public void setTemperature(double temperature) { this.temperature = temperature; } }

最终 dto 包的目录结构为:

4.2 converter包的实现

实现了 dto 包,假设当用户传入 SensorDTO 数据时,我们需要对其进行转换,转换成 Sensor 数据;同理,当我们后台反馈给用户数据时,Sensor 数据也可能需要转化为 SensorDTO 数据,这时候就需要一些方法来实现他们之间的转换,这里我们在converter包实现。

① SensorConverter类

SensorConverter类主要包含了2个静态方法,即把 Sensor 对象转化为 SensorDTO 对象,还有把 SensorDTO 对象转化为 Sensor 对象。

把 Sensor 对象转化为 SensorDTO 对象,比较简单,即把 Sensor 的温湿度属性值传给SensorDTO的温湿度属性值即可;

把 SensorDTO 对象转化为 Sensor 对象,则除了把 SensorDTO 的温湿度属性值传给 Sensor,还需要设置 Sensor 的时间戳属性值。(id是数据库自增的,不用设置)

故 SensorConverter 类的实现代码如下:

package com.jmu.sensor.converter; import com.jmu.sensor.dao.Sensor; import com.jmu.sensor.dto.SensorDTO; import java.time.LocalDateTime; public class SensorConverter { public static SensorDTO convertSensor(Sensor sensor) { SensorDTO sensorDTO = new SensorDTO(); sensorDTO.setHumidity(sensor.getHumidity()); sensorDTO.setTemperature(sensor.getTemperature()); return sensorDTO; } public static Sensor convertSensor(SensorDTO sensorDTO) { Sensor sensor = new Sensor(); sensor.setDate(LocalDateTime.now()); sensor.setHumidity(sensorDTO.getHumidity()); sensor.setTemperature(sensorDTO.getTemperature()); return sensor; } }

最终converter包的目录结构如下:

4.3 service包的实现

新建 service 包:

service 包我们也需要实现一个接口和类,即 SensorService 接口和它的实现类 SensorServiceImpl

① SensorService 接口

SensorService 接口中,我们需要指定其实现类要实现的方法。

package com.jmu.sensor.service; import com.jmu.sensor.dao.Sensor; import com.jmu.sensor.dto.SensorDTO; import java.util.List; public interface SensorService { // 查询所有传感数据 List getAllSensorData(); // 插入一条传感数据 long addNewSensorData(SensorDTO sensorDTO); } ② SensorServiceImpl 类

SensorServiceImpl 类则是实现了SensorService 接口,其需要通过 @Autowired 注入我们在 Data Access 层实现的 SensorRepository,帮助我们实现对数据库的访问,可以访问数据库之后,便可以进行一些业务逻辑的操作。

这里我们需要实现接口中的方法,即查询所有传感数据 getAllSensorData(),以及插入一条新的传感数据 addNewSensorData()。

package com.jmu.sensor.service; import com.jmu.sensor.converter.SensorConverter; import com.jmu.sensor.dao.Sensor; import com.jmu.sensor.dao.SensorRepository; import com.jmu.sensor.dto.SensorDTO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class SensorServiceImpl implements SensorService{ @Autowired private SensorRepository sensorRepository; @Override public List getAllSensorData() { List sensorsList = sensorRepository.findAll(); return sensorsList; } @Override public long addNewSensorData(SensorDTO sensorDTO) { Sensor sensorData = sensorRepository.save(SensorConverter.convertSensor(sensorDTO)); return sensorData.getId(); } }

最终 service 包的目录结构如下:

5.Controller 层的实现

实现了 Service 层,我们就可以在 Controller 层中预留接口,提供给用户访问。

5.1 Response 类的实现

通常我们访问 API 后会返回结果,无论是否成功调用 API, 我们通常返回“后端是否报错”、“数据”还有“错误信息”作为访问后端结果的统一封装。

这里我们新建一个Response类来帮助我们实现这一功能:

Response类包含 返回数据 data、是否访问成功的标志 success 以及错误信息 errorMsg。

当访问成功时, success为true,并返回数据 data;

当访问失败时,success为false,并返回错误信息 errorMsg。

package com.jmu.sensor; public class Response { private T data; // 返回数据 private boolean success; // 是否访问成功 private String errorMsg; // 错误信息 public static Response newSuccess(K data) { Response response = new Response(); response.setData(data); response.setSuccess(true); return response; } public static Response newFaild(String errorMsg) { Response response = new Response(); response.setErrorMsg(errorMsg); response.setSuccess(false); return response; } public T getData() { return data; } public void setData(T data) { this.data = data; } public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } } 5.2 controller包的实现

新建 controller 包:

① SensorController 类

SensorController类 通过 @Autowired 注入我们在Service 层实现的 SensorService,帮助我们进行一些业务逻辑的操作。

这里我们预留了2个API接口,一个是通过GET方式访问“/sensordata”,获取全部传感数据;一个是通过POST方式访问“/sensordata”,来向数据库插入新的传感数据。

package com.jmu.sensor.controller; import com.jmu.sensor.Response; import com.jmu.sensor.dao.Sensor; import com.jmu.sensor.dto.SensorDTO; import com.jmu.sensor.service.SensorService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class SensorController { @Autowired private SensorService sensorService; @GetMapping("/sensordata") public Response getAllSensorData() { List sensorList = sensorService.getAllSensorData(); return Response.newSuccess(sensorList); } @PostMapping("/sensordata") public Response addNewSensorData(@RequestBody SensorDTO sensorDTO) { return Response.newSuccess(sensorService.addNewSensorData(sensorDTO)); } }

最终controller包的目录结构如下:

(后续可能添加一个PageController用来导航页面)

6.测试API

这里推荐使用一个测试接口的工具:Postman

下载地址:Postman API Platform

这里我们运行该项目,确定该项目在本地端口8080运行:

① 插入数据测试

然后我们使用 Postman 尝试插入一条数据:

这里我们可以看到,返回结果success为true,且也返回了data,表示我们插入成功。

我们查看数据库:

可以看到我们已经成功插入数据,表示我们插入数据的接口无误。

② 访问所有数据测试

使用 Postman 发送 GET 请求,获取所有数据:

这里可以看到返回的数据中包含了我们刚刚插入的数据,表示我们访问所有数据的接口也无误。

至此,API测试完毕。

二、通过Arduino UNO、DHT11和ESP-01S调用接口插入温湿度数据

这里的话可以参考我上次写的如何通过 Arduino UNO、DHT11 和 ESP-01S 在乐为物联上传输数据的文章,本质上大差不差:使用Arduino、DHT11温湿度传感器 和 ESP-01S 实现在乐为物联上传输数据_dht11 arduino代码-CSDN博客

1.连线 ArduinoDHT11    12数字接口DATA5VVCCGNDGND Arduino ESP-01S              2数字接口(软串口RX)TX3数字接口(软串口TX)RX3.3V3.3VGNDGND

2.Arduino 代码

这里简要说一下需要修改的地方:

① ssid需要修改为你的Wi-Fi名;

② password需要修改为你的Wi-Fi密码;

(注意:你的Wi-Fi的网络频带需要为2.4GHz)

③ loop中的sendHttpPostRequest中的IP地址需要修改为你服务器的IP地址,或者你本地机子的IP,这里我的本地机子的IP为 172.20.10.3 。

④ sendHttpPostRequest 中的 host 需要修改为你服务器的IP地址,或者你本地机子的IP。

#include #include #define POST_TIME 10000 SoftwareSerial espSerial(2, 3); // RX, TX DHT11 dht11(12); // 12号引脚用于连接温湿度传感器 const String ssid = "iPhone"; // Wi-Fi名 const String password = "Fyh6597611"; // Wi-Fi密码 void setup() { Serial.begin(115200); espSerial.begin(115200); connectToWiFi(); } void loop() { /* 读取温湿度 */ int temperature = 0; int humidity = 0; int result = dht11.readTemperatureHumidity(temperature, humidity); //String postData = "[{\"Name\":\"T1\",\"Value\":\"" + String(temperature) + "\"},{\"Name\":\"H1\",\"Value\":\"" + String(humidity) + "\"}]"; String postData = "{\"humidity\":\"" + String(humidity) + "\",\"temperature\":\"" + String(temperature) + "\"}"; /* 调用的api以及发送数据 */ sendHttpPostRequest("http://172.20.10.3:8080/sensordata", postData); delay(POST_TIME); } void connectToWiFi() { bool wifiConnected = false; Serial.println("AT+CWJAP=\"" + ssid + "\",\"" + password + "\"" + "\r\n"); espSerial.println("AT+CWMODE=1"); // 设置模式为 Station mode(如果在串口调试器已经调试好了的,可以不用在这里设置) while (!wifiConnected) { espSerial.println("AT+CWJAP=\"" + String(ssid) + "\",\"" + String(password) + "\"" + "\r\n"); // 连接WiFi delay(2000); if (espSerial.find("OK")) { Serial.println("Connected to WiFi."); wifiConnected = true; // 设置标志位为true,跳出循环 break; } else { Serial.println("Connection failed. Retrying..."); delay(2000); } } } void sendHttpPostRequest(const String& url, const String& postData) { String host = "172.20.10.3"; int port = 8080; espSerial.println("AT+CIPCLOSE"); // 每次连接服务器之前先断开当前的连接,否则有bug,每次只有第一次运行才可以上传数据 espSerial.println("AT+CIPSTART=\"TCP\",\"" + host + "\"," + String(port)); delay(2000); if (espSerial.find("CONNECT")) { Serial.println("Connect Succesfully\n"); // 测试能否发送数据 /* AT+CIPSEND给出数据长度 */ String cmd = "AT+CIPSEND="; cmd += String(postData.length() + 104); espSerial.println(cmd); /* 连接成功后便可发送数据 */ if (espSerial.find(">")) { Serial.println("begin to send!!!"); espSerial.println("POST /sensordata HTTP/1.1"); espSerial.println("Host: "+ host); espSerial.println("Content-Type: application/json"); espSerial.println("Content-Length: " + String(postData.length())); espSerial.println(); espSerial.print(postData); // 测试:用于检测输出是否正确 Serial.println("----------------------------------------------"); Serial.println("POST /sensordata HTTP/1.1"); Serial.println("Host: "+host); Serial.println("Content-Type: application/json"); Serial.println("Content-Length: " + String(postData.length())); Serial.println(); Serial.println(postData); Serial.println("----------------------------------------------"); } else { Serial.println("Failed to initiate data transmission."); } /* 无论结果如何,最后都要断开连接 */ // espSerial.print("AT+CIPCLOSE"); } else { Serial.println("Failed to connect to server."); } } 3.测试

打开 Arduino IDE,把如上的 Arduino 代码传输到连接好的 Aruino UNO 板中。

打开控制台,这里我们可以看到已经成功发送了一次数据,时间在 8:31 左右。

查看数据库,我们可以切确地看到有条时间为 8:31 的记录。

至此,传感器向后台发送数据也已经成功了。

三、前端页面的绘制

(这里我前端页面写得不规范,大家可以自行修改。)

完成了数据的上传,我们就可以在前端页面调用访问全部数据的API来获取数据,再通过这些数据进行页面的渲染。

1.前端代码 温湿度数据展示 .container { display: flex; flex-direction: column; } 日期 温度 (°C) 湿度 (%RH) // 使用fetch从API获取数据 fetch('http://172.20.10.3:8080/sensordata') .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); // 获取API返回的是JSON格式的数据 }) .then(data => { // 对每个数据项中的日期进行格式化处理 const formattedData = data.data.map(item => { // 将"2024-06-07T02:37:14"格式转换为"2024-06-07 02:37:14" const formattedDate = item.date.replace('T', ' '); return { ...item, date: formattedDate }; }); // 初始化ECharts图表 const chart = echarts.init(document.getElementById('chartContainer')); const option = { xAxis: { type: 'category', data: formattedData.map(item => item.date) }, yAxis: [ { type: 'value', name: '温度(°C)', min: 0 }, { type: 'value', name: '湿度(%RH)', min: 0, position: 'right' } ], legend: { data: ['温度', '湿度'] }, tooltip: { show: true, trigger: 'axis', // 触发类型,'axis' 表示坐标轴触发,即鼠标在轴上移动时显示tooltip }, dataZoom: [ { type: 'slider', // 这里是滑块型数据区域缩放组件 show: true, start: 0, // 初始显示数据的起始百分比 end: 100, // 初始显示数据的结束百分比 handleSize: '80%', // 滑块的大小 xAxisIndex: [0], // 控制x轴,如果有多个x轴,可以指定控制哪个轴 filterMode: 'filter' // 过滤模式,表示滑动时会过滤掉不在此范围内的数据 }, { type: 'inside', // 内置型数据区域缩放组件,用户可以通过鼠标滚轮或双击来缩放 xAxisIndex: [0], filterMode: 'filter' } ], series: [ { name: '温度', type: 'line', data: formattedData.map(item => item.temperature) }, { name: '湿度', type: 'line', yAxisIndex: 1, // 使用右侧的y轴 data: formattedData.map(item => item.humidity) } ] }; chart.setOption(option); // 动态插入表格数据 const dataTableBody = document.getElementById('dataTableBody'); formattedData.forEach(item => { const row = `${item.date}${item.temperature}${item.humidity}`; dataTableBody.innerHTML += row; }); }) .catch(error => { console.error('There has been a problem with your fetch operation:', error); }); 2.spring boot项目配置

如果你遇到了如下错误,表明你遇到了跨源资源共享(CORS)策略的限制。

CORS是一种安全策略,用于限制网页上的脚本访问不同源(协议+域名+端口)的资源。当你从一个域名(比如localhost或一个网站地址)上的网页尝试请求另一个域名上的数据时,浏览器会实施同源策略(Same-origin policy),默认阻止这种跨域请求,除非被请求的服务明确允许来自特定来源的请求。

这里我们可以在spring boot项目下新建一个类,用来处理该问题。

2.1 config包

新增一个config包:

① CrossConfig类

在config包下新建CrossConfig类

package com.jmu.sensor.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CrossConfig implements WebMvcConfigurer { public static final String[] METHOD= {"GET","POST","PUT","PATCH","DELETE"}; @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**")//对于哪些请求进行拦截 .allowedOriginPatterns("*") .allowedHeaders("*") .allowedMethods(METHOD) .allowCredentials(false) .maxAge(6000); } } 2.2 测试

重新运行后台项目,然后再运行一下前端代码,查看是否可以获取数据并渲染页面:

至此,前端页面已经可以正常请求到数据,并进行渲染。

3.spring boot项目实现页面导航 3.1 添加页面静态文件

将上述的前端代码复制到spring boot项目的 resources/static 目录下。

3.2 实现 PageController 进行页面导航

然后添加 PageController,实现页面导航:

PageController代码:

package com.jmu.sensor.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class PageController { @GetMapping("records") public String sensorRecordsPage() {return "records.html";} } 3.3 测试

重新运行项目,打开浏览器,然后输入"localhost:8080/records",访问页面。

访问成功,且页面成功渲染,至此,实现Arduino UNO、DHT11和ESP-01S与后台的物联。

总结

1、最终spring boot后台项目的代码结构如下:

2、本文只是简单介绍了如何搭建一个spring boot后台并预留一个上传数据和一个获取数据的接口,并通过Arduino UNO板、DHT11温湿度传感器和ESP-01S WiFi模块与后台交互,实现物联。其中,前端页面书写并不规范,大家可以自行修改。同时,后台完成的功能也比较简单,大家可以自行扩展。

3、本文实现物联总体的思路是:

① 搭建一个spring boot后台,预留出2个接口:一个接口用于接收数据,并存储到数据库中;一个接口用于获取数据库的数据,即数据库中存储的温湿度数据;

② Arduino UNO、DHT11温湿度传感器获取温湿度数据, 并通过ESP-01S发送过来的温湿度数据到预留的API接口,实现将温湿度传感器传输并保存到后台数据库中;

③ 前端页面调用获取数据库数据的API,并通过获取的数据进行页面的渲染。



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


    图片新闻

    实验室药品柜的特性有哪些
    实验室药品柜是实验室家具的重要组成部分之一,主要
    小学科学实验中有哪些教学
    计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
    实验室各种仪器原理动图讲
    1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
    高中化学常见仪器及实验装
    1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
    微生物操作主要设备和器具
    今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
    浅谈通风柜使用基本常识
     众所周知,通风柜功能中最主要的就是排气功能。在

    专题文章

      CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭