How can I set up a timer when playing a log file. The timer should start when the log file starts. At a certain event the timer should be printed out in the write window.
There are som built in functions in CAPL do you know how they work?
For example TimeToElapse
Thanks
First insert a replay block in your measurement configuration. In the replay block select your log file and uncheck "Start replay on measurement start" if you want to start the replay from CAPL code.
In the following example I bound the procedure to two on key events:
on key 'a' {
replayStart("ReplayBlockName");
setTimer(mytimer, mytime);
}
on timer mytimer {
// on timer event needed so that setTimer function works properly
}
on key 's' {
write("time to elapse = %d", timeToElapse(mytimer));
}
So basically hit the key 'a' during measurement and afterwards key 's' to see how much time is left. Keep in mind that the output is dependent on your timer. When declaring a regular timer, timeToElapse returns whole seconds. When declaring a msTimer, timeToElapse returns milli seconds.
Related
I am a newbie in CANOPEN. I wrote a program that read actual position via PDO1 (default is statusword + actual position).
void canopen_init() {
// code1 setup PDO mapping
nmtPreOperation();
disablePDO(PDO_TX1_CONFIG_COMM);
setTransmissionTypePDO(PDO_TX1_CONFIG_COMM, 1);
setInhibitTimePDO(PDO_TX1_CONFIG_COMM, 0);
setEventTimePDO(PDO_TX1_CONFIG_COMM, 0);
enablePDO(PDO_TX1_CONFIG_COMM);
setCyclePeriod(1000);
setSyncWindow(100);
//code 2: enable OPeration
readyToSwitchOn();
switchOn();
enableOperation();
motionStart();
// code 3
nmtActiveNode();
}
int main (void) {
canopen_init();
while {
delay_ms(1);
send_sync();
}
}
If I remove "code 2" (the servo is in Switch_on_disable status), i can read position each time sync send. But if i use "code 2", the driver has error "sync frame timeout". I dont know driver has problem or my code has problem. Does my code has problem? thank you!
I don't know what protocol stack this is or how it works, but these:
setCyclePeriod(1000);
setSyncWindow(100);
likely correspond to these OD entries :
Object 1006h: Communication cycle period (CiA 301 7.5.2.6)
Object 1007h: Synchronous window length (CiA 301 7.5.2.7)
They set the SYNC interval and time window for synchronous PDOs respectively. The latter is described by the standard as:
If the synchronous window length expires all synchronous TPDOs may be discarded and an EMCY message may be transmitted; all synchronous RPDOs may be discarded until the next SYNC message is received. Synchronous RPDO processing is resumed with the next SYNC message.
Now if you set this sync time window to 100us but have a sloppy busy-wait delay delay_ms(1), then that doesn't add up. If you write zero to Object 1007h, you disable the sync window feature. I suppose setSyncWindow(0); might do that. You can try to do that to see if that's the issue. If so, you have to drop your busy-wait in favour for proper hardware timers, one for the SYNC period and one for PDO timeout (if you must use that feature).
Problem fixed. Due to much EMI from servo, that make my controller didn't work properly. After isolating, it worked very well :)!
i have problem on "reseting" the values for gauges because "life stops" as soon http servervice is started or when i start looping my "runJob" then is server not started..
the way how i am trying to establish this:
i load all the Job-s from YAML array.
i generate gauges from that, then i run loop to get some values for them.
Then i register them.
And after that i start http service for prometheus.
All works perfect, until next cycle - next cycle is just not starting.
I tryed to move functions inside functions etc..
so thats my main function:
//gets poll time from yaml (60s)
timerCh := time.Tick(time.Duration(appConf.PollTimeSec) * time.Second)
//loop after given time
for range timerCh {
runJobs()
}
//start new muxServer
server := http.NewServeMux()
log.Println("DEBUG: Starting server")
server.Handle(appConf.HostPath, promhttp.Handler())
http.ListenAndServe(":"+appConf.ListenerPort, server)
and my runJobs function basicly gets Http response codes
and ads them to prometheus gauge values.
-- everything is OK with that and it works very well on starting, but after i try to start it wheet sleep (as shown in main go) it just gets stuck -
Server is up and values do not change.
So i have (my optinion) two possible ways of fixing it:
My "runJobs" is infinitive loop what runs after every minute
thats why is server not started.
But when i add there a if statement that on first run(cycle) should server be started, then it still gets stuck when server gets started (next loop cycle just woun't get started)
And the other part, when i start the server first, then it never gets to the part where it starts runJobs()
Prefered outcome should be that:
server is started with first values, and after every minute it runs "runJobs" again.
The way it is written, your program will not go beyond that for loop. Try this instead:
go func() {
//loop after given time
for range timerCh {
runJobs()
}
}()
This runs the for loop in its own goroutine, and runJobs executes every so often.
I'm basically trying to get a LED to light up after I push a button. Below is the snippet of the code that's supposed to handle this:
void task_player1(void *pvParameters)
{
while (1)
{
if (xSemaphoreTake(player1_signal, portMAX_DELAY))
{
printf(">>>Semaphore taken\n<<<");
ioport_set_pin_level(L1, HIGH);
xSemaphoreGive(player1_signal);
}
else
{
ioport_set_pin_level(L1, LOW);
}
}
}
void task_ctrl(void *pvParameters)
{
bool button1 = 0;
while (1)
{
button1 = ioport_get_pin_level(B1);
if (button1)
{
xSemaphoreGive(player1_signal);
printf("Semaphore given\n");
}
}
}
The way I'm envisioning this is that task_ctrl gives the semaphore on button press. Task_player1 is blocked until it takes the semaphore after which it should turn on the LED.
The problem is it never seems to take the semaphore. I'm running the printf statements to show me how far the program reaches and it never gets into the part where the LED lights up. But when I run xSemaphoreGive without the button press in task_ctrl the semaphore is taken.
The weird part is that "Semaphore given\n" statement gets printed out on button click which should mean that the semaphore is given as well but never gets taken.
The tasks work on their own, I've even managed to give the semaphore without the button press if-statement like I stated above.
I'm guessing it's something with the button press code, which also works on it's own outside the tasks. So what am I doing wrong? Am I not using the FreeRTOS correctly?
Edit: Including the task creation code
#define TASK_STACK_SIZE (2048/ sizeof(portSTACK_TYPE))
xTaskCreate(task_ctrl, (const signed char * const) "Control", TASK_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(task_player1, (const signed char * const) "Player1", TASK_STACK_SIZE, NULL, 1, NULL);
Edit 2: Probably something I should have mentioned is that I'm using FreeRTOS 7.3 since Atmel Studio doesn't have any newer versions. So no yield functions are available, as far as I can tell.
task_ctrl never blocks - which will prevent any task of equal or lower priority from ever running. So if task_player is equal or lower priority the the task will never be scheduled even when the semaphore is given.
It appearing to work without the button polling is harder to explain, but you have not shown that code so I cannot comment.
You should do two things:
Ensure that task_ctrl has lower priority that at least task_player1 (and lower than any task if it does not block - the idle task will never run in this case).
Ensure that task_ctrl blocks - even if that is just a polling delay, so that it does not eat up all available CPU cycles.
while (1)
{
button1 = ioport_get_pin_level(B1);
if (button1)
{
xSemaphoreGive(player1_signal);
printf("Semaphore given\n");
vtaskDelay( 1 ) ; // at least 1 tick
}
}
One possible problem with task_ctrl is that it will give the semaphore continuously and repeatedly while the button is held. Some sort of state change detection and switch de-bounce rather then level polling might be preferable.
An alternative solution to a polling task is to use a hardware interrupt for teh button and have either the polling task block on an event from the ISR, or have the ISR give the semaphore directly - in either case you will have to deal with debounce.
Lets say I want to control 2 outputs:
One should send a PWM modulated signal (50Hz). The other one should send a audio signal (lets say a sinus-signal) (lets say with 2kHz).
One of those two tasks is simple to do: just run in a loop:
send some value to output
delay the execution for some ms and jump to 1. again
But how would you solve this problem of sending 2 signals (lets say with different loop frequency, like in our example - 50Hz- 2kHz)?
I'm not sure what is required to output sinus-signal, but here's my take on a solution. First, what I understand you have:
void loop() {
update_pwm_output();
delay(1000/50); // 50 Hz
}
A possible solution:
int last_update = 0;
void loop() {
int mill = millis();
if (mill-last_update > (1000/50)) {
last_update = mill;
update_pwm_output();
}
}
This solution would allow you to execute other code in between updates to your PWM signal.
There are a couple ways to keep a PWM updated while running other code. A library I've used, SoftwareServo, allows you to call its refresh() method periodically and it'll update, where as the Servo library takes up a timer and uses an interrupt to do its updates.
I can't for the life of my work out why this is happening. I have in a class derived from CCLayer. I am scheduling a method call like so when initialising the class
//create an update method for keeping track of how long its been since an animation has played
[self schedule:#selector(playIdleAnimation:)];
And the method is
//an update method that will play an idle animation after a random period of idleness
-(void) playIdleAnimation:(ccTime) dt {
//if the user isn't playing an animation, increment the time since last animation variable
if ([bodySprite numberOfRunningActions] == 0) {
timeSinceLastAnimation += (float)dt;
//now check to see if we have surpassed the time set to cause an idle animation
if (timeSinceLastAnimation > (arc4random() %14) + 8) {
//reset the cooldown timer
timeSinceLastAnimation = 0;
[bodySprite stopAllActions];
//play the idle animation
//[bodySprite runAction:[CCAnimate actionWithAnimation:waitAnimation restoreOriginalFrame:NO]];
NSLog(#"PLAYING IDLE ANIMATION");
}
}
//player is currently playing animation so reset the time since last animation
else
timeSinceLastAnimation = 0;
}
But yet, when I go to run the program the console statements show the condition is being passed twice each cooldown
012-06-29 09:52:57.667 Test Game[5193:707] PLAYING IDLE ANIMATION
2012-06-29 09:52:57.701 Test Game[5193:707] PLAYING IDLE ANIMATION
2012-06-29 09:53:05.750 Test Game[5193:707] PLAYING IDLE ANIMATION
2012-06-29 09:53:05.851 Test Game[5193:707] PLAYING IDLE ANIMATION
I am trying to fix a bug where the game crashes when I finish playing the idle animation, and I'm certain this has something to do with it.
I don't see where you are unscheduling the selector. I bet that it's normal behavior to be called ever frame kicks in, and you see it being triggered twice because it takes a frame for the layer to be deallocated.
If you want a one-time method call, do this:
-(void) playIdleAnimation:(ccTime) dt {
[self unschedule:_cmd];
// rest of the code here
}
Cocos2d 2.0 has a scheduleOnce method that you can use instead.