|
1. 背景 |
1.背景
Teensy4.1 通过 UART 驱动 DFR0760 语音合成器。
1.1 硬件
Gravity 语音合成器配置,拨码开关从 I2C 拨到 UART。
| Teensy4.1 | 语音合成器 (UART 接口) |
SEK-SEN66传感器 (I2C 接口) |
| UART8_TX (Io35) | RX | -- |
| UART8_RX (IO34) | TX | -- |
| I2C1_SDA (IO18) | -- | SDA |
| I2C1_SCL (IO19) | -- | SCL |
2.代码
/**
* [url=home.php?mod=space&uid=1307177]@File[/url] main.cpp
* [url=home.php?mod=space&uid=1315547]@author[/url] LinTeX9527 (lintex9527@yeah.net)
* [url=home.php?mod=space&uid=159083]@brief[/url] * [url=home.php?mod=space&uid=252314]@version[/url] 0.1
* [url=home.php?mod=space&uid=311857]@date[/url] 2026-03-10
*
* @copyright Copyright (c) 2026
*
*/
#include <Arduino.h>
#include <SensirionI2cSen66.h>
#include <Wire.h>
#include "DFRobot_SpeechSynthesis_V2.h"
/* SEK-SEN66 Sensor ------------------------------------------------------------*/
// macro definitions
// make sure that we use the proper definition of NO_ERROR
#ifdef NO_ERROR
#undef NO_ERROR
#endif
#define NO_ERROR 0
/**
* @brief 传感器无效的数据值
* @{
*/
#define INVALID_PM1P0 (6553.50f)
#define INVALID_PM2P5 (6553.50f)
#define INVALID_PM4P0 (6553.50f)
#define INVALID_PM10P0 (6553.50f)
#define INVALID_NOX (3276.70f)
#define INVALID_CO2 (65535)
/**
* @}
*/
SensirionI2cSen66 sen66_sensor;
static char errorMessage[64];
static int16_t error;
/* Gravity Speech ------------------------------------------------------------*/
#define ttsSerial Serial8 /* TX8--35, RX8--34 */
DFRobot_SpeechSynthesis_UART tts;
int effect_mode = 0; // 语音合成器音效
/* 局部函数 -------------------------------------------------------------------*/
void sen66_init(void)
{
Wire.begin();
sen66_sensor.begin(Wire, SEN66_I2C_ADDR_6B);
error = sen66_sensor.deviceReset();
if (error != NO_ERROR)
{
Serial.print("Error trying to execute deviceReset(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
delay(1200);
int8_t serialNumber[32] = {0};
error = sen66_sensor.getSerialNumber(serialNumber, 32);
if (error != NO_ERROR)
{
Serial.print("Error trying to execute getSerialNumber(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
Serial.print("serialNumber: ");
Serial.print((const char *)serialNumber);
Serial.println();
error = sen66_sensor.startContinuousMeasurement();
if (error != NO_ERROR)
{
Serial.print("Error trying to execute startContinuousMeasurement(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
}
void tts_init(void)
{
ttsSerial.begin(115200);
tts.begin(ttsSerial);
tts.setVolume(1);
tts.setSpeed(5);
tts.setTone(5);
tts.setEnglishPron(tts.eWord);
}
void setup()
{
Serial.begin(115200);
while (!Serial)
{
delay(100);
}
sen66_init();
tts_init();
}
unsigned long lastReadTime = 0;
unsigned long lastSpeechTime = 0;
void loop()
{
unsigned long currentTime = millis();
// 每隔1秒读取一次传感器数据并打印
if (currentTime - lastReadTime >= 1000)
{
float mass_pm1p0 = 0.0;
float mass_pm2p5 = 0.0;
float mass_pm4p0 = 0.0;
float mass_pm10p0 = 0.0;
float humidity = 0.0;
float temperature = 0.0;
float vocIndex = 0.0;
float noxIndex = 0.0;
uint16_t co2 = 0;
error = sen66_sensor.readMeasuredValues(
mass_pm1p0, mass_pm2p5, mass_pm4p0,
mass_pm10p0, humidity, temperature, vocIndex, noxIndex,
co2);
if (error != NO_ERROR)
{
Serial.print("Error trying to execute readMeasuredValues(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
lastReadTime = currentTime; // 更新时间以避免重复错误
return;
}
Serial.print("mass_pm1p0: ");
Serial.print(mass_pm1p0);
Serial.print("\t");
Serial.print("mass_pm2p5: ");
Serial.print(mass_pm2p5);
Serial.print("\t");
Serial.print("mass_pm4p0: ");
Serial.print(mass_pm4p0);
Serial.print("\t");
Serial.print("mass_pm10p0: ");
Serial.print(mass_pm10p0);
Serial.print("\t");
Serial.print("humidity: ");
Serial.print(humidity);
Serial.print(" \t");
Serial.print("temperature: ");
Serial.print(temperature);
Serial.print("\t");
Serial.print("vocIndex: ");
Serial.print(vocIndex);
Serial.print("\t");
Serial.print("noxIndex: ");
Serial.print(noxIndex);
Serial.print(" \t");
Serial.print("co2: ");
Serial.println(co2);
lastReadTime = currentTime;
// 检查数据是否有效
bool isValidData = true;
if ((mass_pm1p0 == INVALID_PM1P0) ||
(mass_pm2p5 == INVALID_PM2P5) ||
(mass_pm4p0 == INVALID_PM4P0) ||
(mass_pm10p0 == INVALID_PM10P0) ||
(noxIndex == INVALID_NOX) ||
(co2 == INVALID_CO2))
{
isValidData = false;
}
// 每隔5秒语音播报一次有效数据
if (currentTime - lastSpeechTime >= 5000 && isValidData)
{
// TTS语音播报
char speechBuffer[256];
snprintf(speechBuffer, sizeof(speechBuffer),
"温度 %.1f 摄氏度,湿度 %.1f%%,二氧化碳浓度 %u PPM",
temperature, humidity, co2);
tts.speak(speechBuffer);
// 切换音效
effect_mode++;
if (effect_mode > 6) {
effect_mode = 0;
}
memset(speechBuffer, 0, sizeof(speechBuffer));
snprintf(speechBuffer, sizeof(speechBuffer), "[e%d]", effect_mode);
tts.speak(speechBuffer);
// 等待TTS播报完成,避免连续播报冲突
delay(2000); // 根据语音长度调整延迟时间
lastSpeechTime = currentTime; // 只有播报成功后才更新时间
}
}
// 让处理器处理其他任务
yield();
}