创意方案介绍
这个项目作为物联网方向应用,可以实现将电池供电的传感器模块置于冰箱内,实时检测冰箱环境状态,并显示在AtomS3的小屏幕上;与此同时,便于观察,不必要每次看信息都需要开冰箱,相关的信息会被同时同步在冰箱外的冰箱贴上。该冰箱贴使用Cardputer制作。
方案框图介绍
本项目使用的核心模块有两个,一个是冰箱内的AtomS3,另一个是冰箱外的Cardputer。两个模块间通信使用MQTT会更加便捷,但是考虑到还需引入额外的MQTT服务器,因此直接使用HTTP来进行通信。
方案中用到的指定厂商元器件介绍
1,AtomS3 是一款基于ESP32-S3主控的高集成度可编程控制器,内部集成了ESP32-S3主控,集成WiFi功能,8M片上FLASH,0.85寸IPS屏幕,屏幕下方具有可编程按键功能,内置5V转3.3V电路,6轴陀螺仪传感器MPU6886,板载Type-C接口,供电及固件下载,一个HY2.0-4P扩展端口,底部预留6个GPIO以及电源引脚,方便扩展应用。产品大小只有24*24*13mm,适用于各种嵌入式的智能设备应用。
2,Cardputer是一款适合工程师的卡片电脑,采用M5StampS3作为主控,在控制交互方面,配备56按键键盘与1.14寸TFT屏幕进行显示交互,另外板载SPM1423数字MEMS麦克风可以进行录音或者唤醒等,此外还连接腔体喇叭进行声音的播放,搭载一个红外发射管对外进行红外控制交互.扩展方面,板载一个Grove口,可以自定义扩展传感器.存储方面,板载一个Micro SD卡槽,可以进行存储空间的扩容.供电方面,内部配备120mAh+1400mAh(底座中)的锂电池的方案对整机进行供电,大大提高续航能力,内含锂电池充电和升压降压电路.结构方面,底座含磁铁可以进行金属吸附,结构设置兼容乐高孔扩展.该产品使用于工程师快速功能验证设计,工业控制,家居控制系统等.
原理图介绍
原理图就是三组排针/排母,分别是用来连接AtomS3和BMP280模块。
PCB设计介绍
PCB在原理图的基础上手绘了四个焊盘,主要是用来贴B628升压模块,以使用锂电池进行供电。
成品展示
B628模块的焊盘设计的大一些,这样可以更加方便焊接。
代码介绍
AtomS3代码使用Arduino编写。主要功能是1,从BMP280获取温度。2,将温度显示在屏幕上。3,通过request方法将温度作为url参数传递给http服务器。
#include <Arduino.h>
#include <Arduino_GFX_Library.h>
#include "DFRobot_BMP280.h"
#include "Wire.h"
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "";
const char* password = "";
String serverName = "http://192.168.50.39:5000/";
#define GFX_BL 16
Arduino_DataBus* bus = new Arduino_ESP32SPI(33 /* DC */, 15 /* CS */, 17 /* SCK */, 21 /* MOSI */, GFX_NOT_DEFINED /* MISO */);
Arduino_GFX* gfx = new Arduino_GC9107(bus, 34 /* RST */, 0 /* rotation */, true /* IPS */);
void gfx_init() {
#ifdef GFX_EXTRA_PRE_INIT
GFX_EXTRA_PRE_INIT();
#endif
// Init Display
if (!gfx->begin()) {
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
}
typedef DFRobot_BMP280_IIC BMP; // ******** use abbreviations instead of full names ********
BMP bmp(&Wire, BMP::eSdoLow);
#define SEA_LEVEL_PRESSURE 1015.0f // sea level pressure
void bmp_init() {
bmp.reset();
Serial.println("bmp read data test");
while (bmp.begin() != BMP::eStatusOK) {
Serial.println("bmp begin faild");
printLastOperateStatus(bmp.lastOperateStatus);
delay(2000);
}
Serial.println("bmp begin success");
}
// show last sensor operate status
void printLastOperateStatus(BMP::eStatus_t eStatus) {
switch (eStatus) {
case BMP::eStatusOK: Serial.println("everything ok"); break;
case BMP::eStatusErr: Serial.println("unknow error"); break;
case BMP::eStatusErrDeviceNotDetected: Serial.println("device not detected"); break;
case BMP::eStatusErrParameter: Serial.println("parameter error"); break;
default: Serial.println("unknow status"); break;
}
}
void wifi_init() {
WiFi.begin(ssid, password);
Serial.println("Connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
}
void get_request(float temp) {
HTTPClient http;
String serverPath = serverName + "?data=" + String(temp);
http.begin(serverPath.c_str());
int httpResponseCode = http.GET();
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String payload = http.getString();
Serial.println(payload);
} else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
http.end();
}
void setup() {
Serial.begin(115200);
gfx_init();
gfx->setTextSize(3);
gfx->setTextColor(RED);
bmp_init();
wifi_init();
}
void loop() {
float temp = bmp.getTemperature();
uint32_t press = bmp.getPressure();
float alti = bmp.calAltitude(SEA_LEVEL_PRESSURE, press);
Serial.println();
Serial.println("======== start print ========");
Serial.print("temperature (unit Celsius): ");
Serial.println(temp);
Serial.print("pressure (unit pa): ");
Serial.println(press);
Serial.print("altitude (unit meter): ");
Serial.println(alti);
Serial.println("======== end print ========");
gfx->fillScreen(BLACK);
gfx->setCursor(20, 50);
gfx->println(temp);
get_request(temp);
delay(1000);
}
Cardputer代码使用Circuitpython进行编写,主要功能是搭建一个HTTP服务器,当接收到访问时,将url中的参数拿出来显示在屏幕上。
import board
import terminalio
from adafruit_display_text import label
import socketpool
import wifi
from adafruit_httpserver import Server, Request, Response
display = board.DISPLAY
text = ""
font = terminalio.FONT
color = 0x0000FF
text_area = label.Label(font, text=text, color=color)
text_area.anchor_point = (0.5, 0.5)
text_area.anchored_position = (120, 67)
text_area.scale = 5
display.root_group = text_area
pool = socketpool.SocketPool(wifi.radio)
server = Server(pool, "/static", debug=True)
@server.route("/")
def base(request: Request):
text_area.text = request.query_params.values()[0]
return Response(request, "Success!")
server.serve_forever(str(wifi.radio.ipv4_address))
功能展示
可以看到,两台设备的温度可以进行同步。
心得体会
这两台小设备非常精致,集成了多种外设。它们协作的方式有很多,可以用它们实现很多有意思的项目。这个项目仅仅是一个符合活动主题的示例,作为抛砖引玉。未来的活动希望还能再将这两个小设备应用进去,实现更好的创意。