I got these 2 tasks in my project (these are running in parallel):
First task: one that sends JSON formatted messages to AWS if connected to the internet. If not connected, the program will buffer these messages as JSON files in the USER partition.
Second task: this one sends those buffered JSON messages to AWS once the PLC is reconnected.
now, after each publish to AWS, I subscribe to a response that I setup in AWS. I put a 10s timer to wait for the message to arrive (most of the time, the response takes about 100ms to arrive and process). I do this for both tasks. I put these seperate because when the PLC is connected again, I want send the buffered data while new data is getting collected.
Why is it that the TON timer works in my first task, but not in the second. The code is the exact same.
IF delay_new.IN = FALSE THEN
delay_new.PT := T#10000ms;
delay_new.IN := TRUE;
END_IF;
IF delay_new.Q = TRUE THEN
state := state_reset;
aws_connected := FALSE;
END_IF;
It’s hard to tell from just those snippets, but I have a few ideas:
Make sure that you are calling the function block delay_new(). The timer will not run and the outputs will not update until the function block call
I’m not sure if the timers are named the same in both tasks, or if you’re using the same global variable for both tasks. It’s not a good idea to make function blocks global as then multiple tasks can influence their execution. Instead, there should be two separate (local) declarations. However both local declarations can have the same variable name if you want
The timer starts on a rising edge of the IN input. This needs to be reset at some point, which I don’t see happening in your code snippets
In addition to @marcusbnr I would like to add that you usually don’t guard the setting of the input variables, at least not when it’s just to check if it’s already set (you can, of course, if you want to start the timer only on certain conditions):
// I don't check if it's already set or not - I simply set it here
delay_new.PT := T#10s; // I have changed this to seconds, easier to read
delay_new.IN := TRUE;
IF delay_new.Q THEN // It's a bool. No need to explicitly check for TRUE
state := state_reset;
aws_connected := FALSE;
delay_new.IN := FALSE; // create a falling edge
END_IF
delay_new(); // the actual FUB-call
Additional note: your delay_new has a very broad name and can’t easily be distinguished from other variables as being a FUB. Recommendation: FB_Delay_new (where the _new should also be changed to something more of a descriptive nature)