Well, I actually have SYSTEM_THREAD(ENABLE) as I want to have some control over the time for my application thread, in fact I have FSM that run by events or a given tick provided by a Timer.
I though that since the application thread was running on this own thread the system functions like Paricle.function would still work and able to post a event to my FSM via the callback.
I have commented out my loop() here and both function and variable are working now.
Considering SYSTEM_THREAD(ENABLE) is possible to have a blocking loop without and function Particle.function and Particle.variable? I’m curious on why it would not work like this right way.
#include "Particle.h"
// This turns off optimization for this file which makes it easier to debug.
// Otherwise you can't break on some lines, and some local variables won't
// be available.
//#pragma GCC optimize ("O0")
#include "board_init.h"
#include "gpio_expander.h"
#include "output_ports.h"
#include "ext_rtc.h"
#include "ccu_messages.h"
#include "ccu_app.h"
#include "ccu_main.h"
#include <list>
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(AUTOMATIC);
int counter{0};
os_queue_t main_queue;
void FSM_TICK(void)
{
MainMessage *ptr = new MainMessage();
ptr->type = MSG_TYPE::FSM_TIMER;
ptr->data = nullptr;
os_queue_put(main_queue, &ptr, 0, nullptr);
}
void TEST_CMD(void)
{
MainMessage *ptr = new MainMessage();
ptr->type = MSG_TYPE::SENSOR_CMD_MSG;
SensorCmd *cmd{new SensorCmd()};
cmd->sensor_id = 0;
cmd->channel = 0;
cmd->cmd = SENSOR_CMD::PUB_DATA;
ptr->data = reinterpret_cast<uint8_t*>(cmd);
os_queue_put(main_queue, &ptr, 0, nullptr);
}
int TEST_CMD_CLOUD(String extra)
{
Serial.println("Cloud Command");
TEST_CMD();
return 0;
}
void setup()
{
board_init();
Serial.begin(115200);
Serial.print("Main Task!!!!\r\n");
//Init main queue
if(0 != os_queue_create(&main_queue, sizeof(MainMessage*), 10, nullptr))
{
Serial.print("Main Task queue error!\r\n");
}
else
{
//Do nothing
}
// Add Cloud cmd
bool success = Particle.function("RUN_RTC_CMD", TEST_CMD_CLOUD);
Particle.variable("Counter", counter);
}
void loop()
{
MainMessage *current_msg = nullptr;
std::map<uint8_t, CCUSensor*> active_sensors;
std::map<CCU_APP_ID, CCUApp*> active_apps;
CCUConfig config;
config.LoadConfigFromFlash();
//Add RTC Sensor - TEST
config.AddSensor(SENSOR_TYPE::RTC_SENSOR, 0, 0);
LoadSensors(active_sensors, config.GetSensorList());
LoadApps(active_apps, active_sensors, config.GetAppList());
//Start FSM TICK
Timer *fsm_tick = new Timer(1500, FSM_TICK);
fsm_tick->start();
while(true)
{
//Wait for next msg/event
os_queue_take(main_queue, ¤t_msg, CONCURRENT_WAIT_FOREVER, nullptr);
switch(current_msg->type)
{
case(MSG_TYPE::FSM_TIMER):
{
//Every single tick, we read data from sensors
ReadAllSensors(active_sensors);
//Next we run all apps using the sensor data and place commands in "command_queue"
RunAllApps(active_apps, main_queue);
Particle.publish("FSM_TIMER", "RODOU", PRIVATE, NO_ACK);
counter++;
break;
}
case(MSG_TYPE::SENSOR_CMD_MSG):
{
SensorCmd *cmd;
cmd = reinterpret_cast<SensorCmd*>(current_msg->data);
ExecuteSensorCmd(active_sensors, cmd, main_queue);
//Free the command message
delete cmd;
break;
}
case(MSG_TYPE::ALARMS):
{
break;
}
default:
{
Serial.printf("Type: %d. Pointer: %p\r\n", current_msg->type, current_msg);
break;
}
}
delete current_msg;
}
}
EDIT: I added some of the code so you can get an idea of what’s going on