Проблема с объединением двух разных скетчей в один скетч
Ниже два прилагаются два кода, второй код предназначен для использования микрофона для обнаружения кашля и чихания, где первый код используется для влажности и температуры.
// Для сканирования параметров выдоха Insitu через nRFConnect или любое приложение службы BLE
// Углекислый газ и летучие ОКС были псевдокартированы под давлением и осадками соответственно(ppm & ppb);)
#include <ArduinoBLE.h>
#include <Wire.h>
#include <SparkFunBME280.h>
#include <SparkFunCCS811.h>
#define CCS811_ADDR 0x5B
#define PIN_NOT_WAKE 5
CCS811 myCCS811(CCS811_ADDR);
BME280 myBME280;
BLEService sensorService("181A"); // Environmental_Sensor-Service
// 180D HeartRate
// 181B BodyComposi.
BLEShortCharacteristic sensorLevelChar1("2A6E", BLERead | BLENotify); // Температурная характеристика
BLEShortCharacteristic sensorLevelChar2("2A6F", BLERead | BLENotify); // Влажность-Характеристика
BLELongCharacteristic sensorLevelChar3("2A6D", BLERead | BLENotify); // PCo2-Характеристика
BLELongCharacteristic sensorLevelChar4("2A78", BLERead | BLENotify); // PTVoC-Характеристика
// 2A37 HRmeasurement
// 2A2C Magdeclination
// 2A98 weight
// 2A6D Pressure
// 2A9D Recom.HRMax.
// 2A8E Height
// 2A8D Max.HR
// 2A8C Gender
// 2A00 DeviceName
// 2A38 bodysensorlocation
int oldSensorLevel1 = 0;
int oldSensorLevel2 = 0;
int oldSensorLevel3 = 0;
int oldSensorLevel4 = 0;
long previousMillis = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(23, OUTPUT);
if (!BLE.begin()) {
Serial.println("Bluetooth init. failed!");
while (1);
}
Wire.begin();
CCS811Core::status returnCode = myCCS811.begin();
Serial.print("CCS811 begin exited with: ");
printDriverError( returnCode );
Serial.println();
myBME280.settings.commInterface = I2C_MODE;
myBME280.settings.I2CAddress = 0x77;
myBME280.settings.commInterface = I2C_MODE;
myBME280.settings.I2CAddress = 0x77;
myBME280.settings.runMode = 3; //Normal mode
myBME280.settings.tStandby = 0;
myBME280.settings.filter = 4;
myBME280.settings.tempOverSample = 5;
myBME280.settings.pressOverSample = 5;
myBME280.settings.humidOverSample = 5;
delay(10);
myBME280.begin();
BLE.setLocalName("Mask.xME");
BLE.setAdvertisedService(sensorService);
sensorService.addCharacteristic(sensorLevelChar1);
BLE.addService(sensorService);
sensorLevelChar1.writeValue(oldSensorLevel1);
sensorService.addCharacteristic(sensorLevelChar2);
BLE.addService(sensorService);
sensorLevelChar2.writeValue(oldSensorLevel2);
sensorService.addCharacteristic(sensorLevelChar3);
BLE.addService(sensorService);
sensorLevelChar3.writeValue(oldSensorLevel3);
sensorService.addCharacteristic(sensorLevelChar4);
BLE.addService(sensorService);
sensorLevelChar4.writeValue(oldSensorLevel4);
// start advertising
BLE.advertise();
Serial.println("Bluetooth active, waiting to be connected.....");
}
void loop() {
// ожидание центрального устройства BLE.
BLEDevice central = BLE.central();
if (central) {
Serial.print("Connected to central: ");
Serial.println(central.address());
digitalWrite(23, HIGH); // indicate connection
while (central.connected()) {
if (myCCS811.dataAvailable())
{
myCCS811.readAlgorithmResults();
printInfoSerial();
float BMEtempC = myBME280.readTempC();
float BMEhumid = myBME280.readFloatHumidity();
myCCS811.setEnvironmentalData(BMEhumid, BMEtempC);
}
else if (myCCS811.checkForStatusError())
{
printSensorError();
}
long currentMillis = millis();
if (currentMillis - previousMillis >= 200) {
previousMillis = currentMillis;
updateSensorLevel1();
updateSensorLevel2();
updateSensorLevel3();
updateSensorLevel4();
}
}
digitalWrite(23, LOW);
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
}
void updateSensorLevel1() {
float temperature = myBME280.readTempC();
Serial.print("Temperature = ");
Serial.print(temperature, 0);
//float T = myBME280.readTempC();
Serial.println(" °C");
float sensorLevel1 = map(temperature, 0, 100, 0, 10000);
sensorLevelChar1.writeValue(sensorLevel1);
oldSensorLevel1 = sensorLevel1;
}
void updateSensorLevel2() {
float humidity = myBME280.readFloatHumidity();
Serial.print("Humidity = ");
Serial.print(humidity, 0);
Serial.println(" %");
float sensorLevel2 = map(humidity, 0, 100, 0, 10000);
sensorLevelChar2.writeValue(sensorLevel2);
oldSensorLevel2 = sensorLevel2;
}
void updateSensorLevel3() {
float CO2 = myCCS811.getCO2();
Serial.print("Co2 = ");
Serial.print(CO2);
Serial.println(" ppm");
float sensorLevel3 = map(CO2, 0, 100, 0, 1000);
sensorLevelChar3.writeValue(sensorLevel3);
oldSensorLevel3 = sensorLevel3;
}
void updateSensorLevel4() {
float VoC = myCCS811.getTVOC();
Serial.print("TVoC = ");
Serial.print(VoC);
Serial.println(" ppb");
float sensorLevel4 = map(VoC, 0, 100, 0, 100);
sensorLevelChar4.writeValue(sensorLevel4);
oldSensorLevel4 = sensorLevel4;
}
void printInfoSerial()
{
Serial.println("CCS811 data:");
Serial.print(" CO2 concentration : ");
Serial.print(myCCS811.getCO2());
Serial.println(" ppm");
Serial.print(" TVOC concentration : ");
Serial.print(myCCS811.getTVOC());
Serial.println(" ppb");
Serial.println("BME280 data:");
Serial.print(" Temperature: ");
Serial.print(myBME280.readTempC(), 2);
Serial.println(" degrees C");
Serial.print(" %RH: ");
Serial.print(myBME280.readFloatHumidity(), 2);
Serial.println(" %");
Serial.println();
}
void printDriverError( CCS811Core::status errorCode )
{
switch ( errorCode )
{
case CCS811Core::SENSOR_SUCCESS:
Serial.print("SUCCESS");
break;
case CCS811Core::SENSOR_ID_ERROR:
Serial.print("ID_ERROR");
break;
case CCS811Core::SENSOR_I2C_ERROR:
Serial.print("I2C_ERROR");
break;
case CCS811Core::SENSOR_INTERNAL_ERROR:
Serial.print("INTERNAL_ERROR");
break;
case CCS811Core::SENSOR_GENERIC_ERROR:
Serial.print("GENERIC_ERROR");
break;
default:
Serial.print("Unspecified error.");
}
}
void printSensorError()
{
uint8_t error = myCCS811.getErrorRegister();
if ( error == 0xFF ) //comm error
{
Serial.println("Failed to get ERROR_ID register.");
}
else
{
Serial.print("Error: ");
if (error & 1 << 5) Serial.print("HeaterSupply");
if (error & 1 << 4) Serial.print("HeaterFault");
if (error & 1 << 3) Serial.print("MaxResistance");
if (error & 1 << 2) Serial.print("MeasModeInvalid");
if (error & 1 << 1) Serial.print("ReadRegInvalid");
if (error & 1 << 0) Serial.print("MsgInvalid");
Serial.println();
}
}
Код 2
// Cough & Sneeze Classifier built through Edge Impulse Studio.
// If your target is limited in memory remove this macro to save 10K RAM
#define EIDSP_QUANTIZE_FILTERBANK 0
#include <PDM.h>
#include <cscan2_inference.h>
typedef struct {
int16_t *buffer;
uint8_t buf_ready;
uint32_t buf_count;
uint32_t n_samples;
} inference_t;
static inference_t inference;
static bool record_ready = false;
static signed short sampleBuffer[2048];
static bool debug_nn = false; // Set this to true to see e.g. features generated from the raw signal
/**
* @brief Arduino setup function
*/
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("SpecVital Inference...");
// summary of inferencing settings (from model_metadata.h)
ei_printf("Inferencing settings:\n");
ei_printf("\tInterval: %.2f ms.\n", (float)EI_CLASSIFIER_INTERVAL_MS);
ei_printf("\tFrame size: %d\n", EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE);
ei_printf("\tSample length: %d ms.\n", EI_CLASSIFIER_RAW_SAMPLE_COUNT / 16);
ei_printf("\tNo. of classes: %d\n", sizeof(ei_classifier_inferencing_categories) / sizeof(ei_classifier_inferencing_categories[0]));
if (microphone_inference_start(EI_CLASSIFIER_RAW_SAMPLE_COUNT) == false) {
ei_printf("ERR: Failed to setup audio sampling\r\n");
return;
}
}
/**
* @brief Arduino main function. Runs the inferencing loop.
*/
void loop()
{
ei_printf("Starting inferencing in 2 seconds...\n");
delay(5000);
ei_printf("Recording...\n");
bool m = microphone_inference_record();
if (!m) {
ei_printf("ERR: Failed to record audio...\n");
return;
}
ei_printf("Recording done\n");
signal_t signal;
signal.total_length = EI_CLASSIFIER_RAW_SAMPLE_COUNT;
signal.get_data = µphone_audio_signal_get_data;
ei_impulse_result_t result = { 0 };
EI_IMPULSE_ERROR r = run_classifier(&signal, &result, debug_nn);
if (r != EI_IMPULSE_OK) {
ei_printf("ERR: Failed to run classifier (%d)\n", r);
return;
}
// print the predictions
ei_printf("Predictions (DSP: %d ms., Classification: %d ms., Anomaly: %d ms.): \n",
result.timing.dsp, result.timing.classification, result.timing.anomaly);
for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
ei_printf(" %s: %.5f\n", result.classification[ix].label, result.classification[ix].value);
}
#if EI_CLASSIFIER_HAS_ANOMALY == 1
ei_printf(" anomaly score: %.3f\n", result.anomaly);
#endif
}
/**
* @brief Printf function uses vsnprintf and output using Arduino Serial
*
* @param[in] format Variable argument list
*/
void ei_printf(const char *format, ...) {
static char print_buf[1024] = { 0 };
va_list args;
va_start(args, format);
int r = vsnprintf(print_buf, sizeof(print_buf), format, args);
va_end(args);
if (r > 0) {
Serial.write(print_buf);
}
}
/**
* @brief PDM buffer full callback
* Get data and call audio thread callback
*/
static void pdm_data_ready_inference_callback(void)
{
int bytesAvailable = PDM.available();
// read into the sample buffer
int bytesRead = PDM.read((char *)&sampleBuffer[0], bytesAvailable);
if (record_ready == true || inference.buf_ready == 1) {
for(int i = 0; i < bytesRead>>1; i++) {
inference.buffer[inference.buf_count++] = sampleBuffer[i];
if(inference.buf_count >= inference.n_samples) {
inference.buf_count = 0;
inference.buf_ready = 1;
}
}
}
}
/**
* @brief Init inferencing struct and setup/start PDM
*
* @param[in] n_samples The n samples
*
* @return { description_of_the_return_value }
*/
static bool microphone_inference_start(uint32_t n_samples)
{
inference.buffer = (int16_t *)malloc(n_samples * sizeof(int16_t));
if(inference.buffer == NULL) {
return false;
}
inference.buf_count = 0;
inference.n_samples = n_samples;
inference.buf_ready = 0;
// configure the data receive callback
PDM.onReceive(&pdm_data_ready_inference_callback);
// optionally set the gain, defaults to 20
PDM.setGain(80);
//ei_printf("Sector size: %d nblocks: %d\r\n", ei_nano_fs_get_block_size(), n_sample_blocks);
PDM.setBufferSize(4096);
// initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate
if (!PDM.begin(1, EI_CLASSIFIER_FREQUENCY)) {
ei_printf("Failed to start PDM!");
}
record_ready = true;
return true;
}
/**
* @brief Wait on new data
*
* @return True when finished
*/
static bool microphone_inference_record(void)
{
inference.buf_ready = 0;
inference.buf_count = 0;
while(inference.buf_ready == 0) {
delay(10);
}
return true;
}
/**
* Get raw audio signal data
*/
static int microphone_audio_signal_get_data(size_t offset, size_t length, float *out_ptr)
{
arm_q15_to_float(&inference.buffer[offset], out_ptr, length);
return 0;
}
/**
* @brief Stop PDM and release buffers
*/
static void microphone_inference_end(void)
{
PDM.end();
free(inference.buffer);
}
#if !defined(EI_CLASSIFIER_SENSOR) || EI_CLASSIFIER_SENSOR != EI_CLASSIFIER_SENSOR_MICROPHONE
#error "Invalid model for current sensor."
#endif
@Harbaj Cheema, 👍0
Обсуждение1 ответ
У вас есть 2 различные проблемы, которые вам нужно решить, прежде чем вы сможете объединить эти скетчи.
Первый скетч имеет петлю внутри петли. в psuedocode это так:
void loop(){
Connection con = connect();
while(con.connected()){
doStuff();
}
notify_disconnected();
}
Это проблема, потому что цикл никогда не выходит в нормальном режиме.
вы можете переписать это в
Connection con;
void loop(){
if(con.connected()){
was_connected = true;
doStuff();
} else{
if(was_connected){
notify_disconnected();
was_connected = false;
}
con = connect();
}
}
Другой скетч имеет классическую проблему задержки, которую первый скетч дает пример обработки.
void loop(){
delay(5000);
doStuff();
}
это можно изменить в
void loop(){
long currentMillis = millis();
if (currentMillis - previousMillis >= 5000) {
previousMillis = currentMillis;
doStuff();
}
}
После того, как вы сделаете эти исправления и убедитесь, что имена глобалов и функций не сталкиваются и никакие ненужные провода не пересекаются, вы можете поместить их в один и тот же скетч:
void setup(){
setup_sketch1();
setup_sketch2();
}
void loop(){
loop_sketch1();
loop_sketch2();
}
- устаревшее преобразование из строковой константы в 'char*'
- Какие есть другие IDE для Arduino?
- Esp8266 Vin контакт
- Плата для разработки STM8 с Arduino IDE
- Поскольку double и float представляют один и тот же тип данных (обычно), что предпочтительнее?
- Скрытие пароля WLAN при отправке на GitHub
- Как я могу прервать задержку() при нажатии кнопки?
- Изменение времени тика в FreeRTOS
И... в чем заключается ваша "проблема"?, @Majenko