Closed KiraVerSace closed 4 years ago
If I understand correctly, you would like to avoid the use of "delay()" in your code. The usual solution is to think of the sound is two events, not one. See some rough pseudo code below
sound the beep{ turn on buzzer set time to stop = CURRENT_TIME + 200 milliseconds }
set time to sop = 0 main loop{ if (button is down ) sound the beep() if (time to stop > 0 && time >= time to stop) { digitalWrite(BEEP, LOW) set time to stop = 0 } }
The main thing is that when you tun on the beep, you don't wait but you do set a timer. The details don't matter. Some timmers can have call-backs or some times you just monitor the time but in all cases the plan is to schedule a turn-off time.
On Sat, Oct 10, 2020 at 12:34 PM KiraVerSace notifications@github.com wrote:
Hey! Thank you for your library! Here is my question: When I preesed the button in my board, I want my buzzer to sound 200ms, and I use the status request like semaphore in OS, when the key pressed, I release one signal. so my code like this, and I can not avoid use the delay to let user hear the beep sound, and this is against to the principle
Use short efficient callback methods written for cooperative multitasking.
Do you have and good idea? Please help me?
define BUTTON_PEROID 10
void buttonCheckCB(void); Task taskButton(BUTTON_PEROID*TASK_MILLISECOND, TASK_FOREVER, &buttonCheckCB, &taskScheduler, false);
StatusRequest beepSR; void beepOnCB(void); void beepOffCB(void); Task taskBeep(&beepOnCB, &taskScheduler);
// setup() taskButton.enable();
beepSR.setWaiting(1); taskBeep.waitFor(&beepSR);
// My button click event void sButtonClick(void) { beepSR.signal(); Serial.println("sButton click."); }
// My beepOnCB void beepOnCB(void) { digitalWrite(BEEP, HIGH); delay(200); // !!!!!!!!!!!! digitalWrite(BEEP, LOW); beepSR.setWaiting(1); taskBeep.waitFor(&beepSR); }
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/arkhipenko/TaskScheduler/issues/110, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQKNRWPUCT7H5FQ2SCYQW3SKCZNLANCNFSM4SLIKS3Q .
--
Chris Albertson Redondo Beach, California
If I understand correctly, you would like to avoid the use of "delay()" in your code. The usual solution is to think of the sound is two events, not one. See some rough pseudo code below sound the beep{ turn on buzzer set time to stop = CURRENT_TIME + 200 milliseconds } set time to sop = 0 main loop{ if (button is down ) sound the beep() if (time to stop > 0 && time >= time to stop) { digitalWrite(BEEP, LOW) set time to stop = 0 } } The main thing is that when you tun on the beep, you don't wait but you do set a timer. The details don't matter. Some timmers can have call-backs or some times you just monitor the time but in all cases the plan is to schedule a turn-off time. … On Sat, Oct 10, 2020 at 12:34 PM KiraVerSace @.> wrote: Hey! Thank you for your library! Here is my question: When I preesed the button in my board, I want my buzzer to sound 200ms, and I use the status request like semaphore in OS, when the key pressed, I release one signal. so my code like this, and I can not avoid use the delay to let user hear the beep sound, and this is against to the principle Use short efficient callback methods written for cooperative multitasking. Do you have and good idea? Please help me? #define BUTTON_PEROID 10 void buttonCheckCB(void); Task taskButton(BUTTON_PEROIDTASK_MILLISECOND, TASK_FOREVER, &buttonCheckCB, &taskScheduler, false); StatusRequest beepSR; void beepOnCB(void); void beepOffCB(void); Task taskBeep(&beepOnCB, &taskScheduler); // setup() taskButton.enable(); beepSR.setWaiting(1); taskBeep.waitFor(&beepSR); // My button click event void sButtonClick(void) { beepSR.signal(); Serial.println("sButton click."); } // My beepOnCB void beepOnCB(void) { digitalWrite(BEEP, HIGH); delay(200);** // !!!!!!!!!!!! digitalWrite(BEEP, LOW); beepSR.setWaiting(1); taskBeep.waitFor(&beepSR); } — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#110>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQKNRWPUCT7H5FQ2SCYQW3SKCZNLANCNFSM4SLIKS3Q . -- Chris Albertson Redondo Beach, California
Thank you for your help , I got it! Thank you !
If I understand correctly, you would like to avoid the use of "delay()" in your code. The usual solution is to think of the sound is two events, not one. See some rough pseudo code below
The idea is great, however implementation was anti-task scheduler :)
@KiraVerSace: you do not really need StatusRequest for this - since there is no external force that controls the beeper. Just this:
Task tBuzzer (BEEP_INTERVAL, 2, &beepCB, &ts, true);
void beepCB() {
if ( tBuzzer.isFirstIteration() ) {
turnBeeperOn();
}
else {
turnBeeperOff();
}
OR with OnEnable/OnDisable methods:
Task tBuzzer (BEEP_INTERVAL, TASK_ONCE, NULL, &ts, true, &beepOE, &beepOD);
bool beepOE() {
turnBeeperOn();
return true;
}
void boopOD() {
turnBeeperOff();
}
and you activate this option by calling delayed enable/restart:
tBuzzer.enableDelayed() or tBuzzer.restartDelayed();
good luck!
If I understand correctly, you would like to avoid the use of "delay()" in your code. The usual solution is to think of the sound is two events, not one. See some rough pseudo code below sound the beep{ turn on buzzer set time to stop = CURRENT_TIME + 200 milliseconds } set time to sop = 0 main loop{ if (button is down ) sound the beep() if (time to stop > 0 && time >= time to stop) { digitalWrite(BEEP, LOW) set time to stop = 0 } } The main thing is that when you tun on the beep, you don't wait but you do set a timer. The details don't matter. Some timmers can have call-backs or some times you just monitor the time but in all cases the plan is to schedule a turn-off time. … On Sat, Oct 10, 2020 at 12:34 PM KiraVerSace @.> wrote: Hey! Thank you for your library! Here is my question: When I preesed the button in my board, I want my buzzer to sound 200ms, and I use the status request like semaphore in OS, when the key pressed, I release one signal. so my code like this, and I can not avoid use the delay to let user hear the beep sound, and this is against to the principle Use short efficient callback methods written for cooperative multitasking. Do you have and good idea? Please help me? #define BUTTON_PEROID 10 void buttonCheckCB(void); Task taskButton(BUTTON_PEROIDTASK_MILLISECOND, TASK_FOREVER, &buttonCheckCB, &taskScheduler, false); StatusRequest beepSR; void beepOnCB(void); void beepOffCB(void); Task taskBeep(&beepOnCB, &taskScheduler); // setup() taskButton.enable(); beepSR.setWaiting(1); taskBeep.waitFor(&beepSR); // My button click event void sButtonClick(void) { beepSR.signal(); Serial.println("sButton click."); } // My beepOnCB void beepOnCB(void) { digitalWrite(BEEP, HIGH); delay(200);** // !!!!!!!!!!!! digitalWrite(BEEP, LOW); beepSR.setWaiting(1); taskBeep.waitFor(&beepSR); } — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#110>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQKNRWPUCT7H5FQ2SCYQW3SKCZNLANCNFSM4SLIKS3Q . -- Chris Albertson Redondo Beach, California
@chrisalbertson: your solution goes against the very philosophy of this library. the entire idea behind TS is to avoid doing what you suggested and allow library do the scheduling.
If I understand correctly, you would like to avoid the use of "delay()" in your code. The usual solution is to think of the sound is two events, not one. See some rough pseudo code below
The idea is great, however implementation was anti-task scheduler :)
@KiraVerSace: you do not really need StatusRequest for this - since there is no external force that controls the beeper. Just this:
Task tBuzzer (BEEP_INTERVAL, 2, &beepCB, &ts, true); void beepCB() { if ( tBuzzer.isFirstIteration() ) { turnBeeperOn(); } else { turnBeeperOff(); }
OR with OnEnable/OnDisable methods:
Task tBuzzer (BEEP_INTERVAL, TASK_ONCE, NULL, &ts, true, &beepOE, &beepOD); bool beepOE() { turnBeeperOn(); return true; } void boopOD() { turnBeeperOff(); }
and you activate this option by calling delayed enable/restart:
tBuzzer.enableDelayed() or tBuzzer.restartDelayed();
good luck!
Wow, your idea is so cool!, Thank you very much.
May I suggest you start here: https://github.com/arkhipenko/TaskScheduler/wiki/Concept-of-Task-and-Cooperative-Task-Scheduling
and this is for inspiration of doing things differently:
and this is for inspiration of doing things differently:
I try your method, but find a very intersting thing.
Here is my code run on wokwi https://wokwi.com/playground/task-scheduler
#define _TASK_SLEEP_ON_IDLE_RUN
#define _TASK_STATUS_REQUEST
#include <TaskScheduler.h>
Scheduler ts;
#define BUZZER_INTERVAL 40
void buzzerCB(void);
Task taskBuzzer(BUZZER_INTERVAL*TASK_MILLISECOND, 2, &buzzerCB, &ts, true);
void setup()
{
Serial.begin(115200);
Serial.println("HAHAHAHA");
}
void loop() {
ts.execute();
}
void buzzerCB(void)
{
if (taskBuzzer.isFirstIteration())
{
Serial.print("First ");
Serial.println(millis());
}
else if (taskBuzzer.isLastIteration())
{
Serial.print("Last ");
Serial.println(millis());
}
else
{
Serial.println("Happen");
}
}
When the task create, the task will run immediately, and the print is right like this:
HAHAHAHA
First 0
Last 40
But when I run it in my program and download it to the board, something happend! In my thought, the buzzzer should beep at the beginning cause I enable the task, but the result is not this:
void buzzerCB(void)
{
if (taskBuzzer.isFirstIteration())
{
digitalWrite(BUZZER, HIGH);
Serial.print("First ");
Serial.println(millis());
}
else if(taskBuzzer.isLastIteration())
{
digitalWrite(BUZZER, LOW);
Serial.print("LAST ");
Serial.println(millis());
}
else
{
Serial.print("happen ");
Serial.println(millis());
digitalWrite(BUZZER, LOW);
}
}
and this is my SecureCRT print
First 2143
happen 2144
happen 2146
LAST 2147
Do you know why? Why the buzzer do not beep(40ms) at the start?
Please.
and this is for inspiration of doing things differently:
and I find another way to do it. that is use the tone() function! But I want to know why in my last question.
On Sun, Oct 11, 2020 at 11:56 AM Anatoli Arkhipenko < notifications@github.com> wrote:
If I understand correctly, you would like to avoid the use of "delay()" in your code. The usual solution is to think of the sound is two events, not one. See some rough pseudo code below
The idea is great, however implementation was anti-task scheduler :)
I wanted to explain the idea, not a "cut and paste" solution. Hence the very informal code syntax. Usually, I find problems are conceptual and "cut and paste" does not help. --
Chris Albertson Redondo Beach, California
@KiraVerSace too many "if's" and "else's"
#define BUZZER_INTERVAL 40
void buzzerCB(void);
Task taskBuzzer(BUZZER_INTERVAL*TASK_MILLISECOND, 2, &buzzerCB, &ts, false);
void setup()
{
Serial.begin(115200);
Serial.println("HAHAHAHA");
taskBuzzer.enable();
}
void buzzerCB(void)
{
if (taskBuzzer.isFirstIteration())
{
digitalWrite(BUZZER, HIGH);
Serial.print("First ");
Serial.println(millis());
}
if(taskBuzzer.isLastIteration())
{
digitalWrite(BUZZER, LOW);
Serial.print("LAST ");
Serial.println(millis());
}
}
There are only two iterations, really, you can replace it with a single line:
void buzzerCB(void)
{
digitalWrite(BUZZER, taskBuzzer.getRunCounter() & 1 ? HIGH : LOW);
}
@KiraVerSace too many "if's" and "else's"
#define BUZZER_INTERVAL 40 void buzzerCB(void); Task taskBuzzer(BUZZER_INTERVAL*TASK_MILLISECOND, 2, &buzzerCB, &ts, false); void setup() { Serial.begin(115200); Serial.println("HAHAHAHA"); taskBuzzer.enable(); } void buzzerCB(void) { if (taskBuzzer.isFirstIteration()) { digitalWrite(BUZZER, HIGH); Serial.print("First "); Serial.println(millis()); } if(taskBuzzer.isLastIteration()) { digitalWrite(BUZZER, LOW); Serial.print("LAST "); Serial.println(millis()); } }
There are only two iterations, really, you can replace it with a single line:
void buzzerCB(void) { digitalWrite(BUZZER, taskBuzzer.getRunCounter() & 1 ? HIGH : LOW); }
Thank you for your reply. And thank you for your resolution! But my doubt is not that, Have you seen the two results in the same program but in different environment, one is run in my board and one is in the simulation. I think the right result is the buzzer will beep when I enable the task, but true is not, can you see my last post carefully again?
I am from China ,and not good at English, Thank you for your help!
But my doubt is not that, Have you seen the two results in the same program but in different environment, one is run in my board and one is in the simulation. I think the right result is the buzzer will beep when I enable the task, but true is not, can you see my last post carefully again?
Could you please send me the EXACT code you ran on the board? It could be a simple delay() after you initialize Serial in the setup() method that causes a race for task scheduler to "catch up" with the schedule. Why does it start at 2143 milliseconds? what delays it?
But my doubt is not that, Have you seen the two results in the same program but in different environment, one is run in my board and one is in the simulation. I think the right result is the buzzer will beep when I enable the task, but true is not, can you see my last post carefully again?
Could you please send me the EXACT code you ran on the board? It could be a simple delay() after you initialize Serial in the setup() method that causes a race for task scheduler to "catch up" with the schedule. Why does it start at 2143 milliseconds? what delays it?
Thank you ! Here is my code!
/*
* @Description :
* @Version : 0.1
* @Company : V-Think Development Team
* @Author : KiraVerSace@yeah.net
* @Date : 2020-05-22 15:49:56
* @LastEditTime : 2020-10-12 22:54:23
* TODO: ADC add the connect(), improve the stable!
*/
#include <Arduino.h>
#include <XCommon.h>
#include <fml_fram.h>
#define _TASK_SLEEP_ON_IDLE_RUN
#define _TASK_STATUS_REQUEST
#include <TaskScheduler.h>
Scheduler taskScheduler;
#define XSHELL_INTERVAL 10
void xShellRunCB(void);
Task taskXShell(XSHELL_INTERVAL*TASK_MILLISECOND, TASK_FOREVER, &xShellRunCB, &taskScheduler, false);
#define SENSOR_INTERVAL 5000
void sensorSampleCB(void);
Task taskSensorSample(SENSOR_INTERVAL*TASK_MILLISECOND, TASK_FOREVER, &sensorSampleCB, &taskScheduler, false);
#define BUTTON_INTERVAL 10
void buttonCheckCB(void);
Task taskButton(BUTTON_INTERVAL*TASK_MILLISECOND, TASK_FOREVER, &buttonCheckCB, &taskScheduler, false);
#define BUZZER_INTERVAL 40
void buzzerCB(void);
Task taskBuzzer(BUZZER_INTERVAL*TASK_MILLISECOND, 2, &buzzerCB, &taskScheduler, false);
void setup(void)
{
systemInitX();
fram.begin(sizeof(LogRecordT));
fram.saveParameter();
fram.loadParameter();
Serial.print("Limit Count: "); Serial.println(fram.logLimit());
Serial.print("Record Count: "); Serial.println(fram.logCount());
taskXShell.enable();
taskSensorSample.enable();
taskButton.enable();
taskBuzzer.enable();
}
void loop(void)
{
taskScheduler.execute();
}
void xShellRunCB(void)
{
xShell.run();
}
void sensorSampleCB(void)
{
Serial.print("Creating Records... No:");
Serial.print(logRecord.id, DEC);
Serial.println();
logRecord.temperature = sht20.temperature();
Serial.println((String)logRecord.temperature + "°C");
logRecord.humidity = sht20.humidity();
Serial.println((String)logRecord.humidity + " %RH");
logRecord.id++;
Serial.print("Record Count: ");
Serial.println(fram.logCount());
fram.appendLog(EDB_REC logRecord);
lv_task_handler();
Serial.print("AIN0: ");
Serial.println(adc.readADC_SingleEnded(0)*0.125F/120);
Serial.print("AIN1: ");
Serial.println(adc.readADC_SingleEnded(1)*0.125F/120);
Serial.print("AIN2: ");
Serial.println(adc.readADC_SingleEnded(2)*0.125F/120);
Serial.print("AIN3: ");
Serial.println(adc.readADC_SingleEnded(3)*0.125F/120);
Serial.print("Voltage:");
Serial.println(String(analogRead(SENSOR_V)*readVref()*101/40960));
Serial.print("Current:");
currentMonitor.add(analogRead(SENSOR_I)*readVref()/4096/43.11F);
Serial.println(String(currentMonitor.get()));
Serial.print("CPU-VRef: ");
Serial.println(String(readVref()));
Serial.print("CPU-Temperature: ");
Serial.println(String(readTempSensor())+ "°C");
Serial.print("RTC-VBattery: ");
Serial.println(String(readBattery()));
Serial.println(" ");
digitalToggle(LED);
}
void buttonCheckCB(void)
{
sButton.tick();
}
void buzzerCB(void)
{
if (taskBuzzer.isFirstIteration())
{
digitalWrite(BUZZER, HIGH);
Serial.print("First ");
Serial.println(millis());
}
if(taskBuzzer.isLastIteration())
{
digitalWrite(BUZZER, LOW);
Serial.print("LAST ");
Serial.println(millis());
}
}
Is the problem still there now that you enable the tasks at the end of setup()?
Is the problem still there now that you enable the tasks at the end of setup()?
yes you can see it !
How long does xShell.run();
take?
The button callback is the last task in the chain. I am afraid by the time you get there the schedule it already behind.
Why is the first iteration of busser at 1809 ms?
if xShell.run() is a slow method, you will always have overruns. You can do this:
add this at the top:
and right before you enable taskBuzzer in setup add this: taskBuzzer.setSchedulingOption(TASK_INTERVAL);
this changes the scheduling priority to always observing the interval between iterations, rather than original schedule.
I found that if I disable the // taskSensorSample.enable() it works fine,
First 1242 LAST 1281
but why? I don'r know.
define _TASK_SCHEDULING_OPTIONS
and if I do as your suggestion, it works fine too Could you explain it in detail, I am so stupid.
if I change the order of enable, it has no effect, problem is still. The button callback is the last task in the chain is not the key problem
I am sorry, but you will have to experiment and read up on your own. I am afraid I do not have the time to support you at this level.
I am sorry, but you will have to experiment and read up on your own. I am afraid I do not have the time to support you at this level.
thank you all the same, I will work hard on it!
Hey! Thank you for your library! Here is my question: When I preesed the button in my board, I want my buzzer to sound 200ms, and I use the status request like semaphore in OS, when the key pressed, I release one signal. so my code like this, and I can not avoid use the delay to let user hear the beep sound, and this is against to the principle
Do you have and good idea? Please help me?