Prevent unwanted Toggling in a Timer - arduino

I have a problem with arduino due timers. First let me explain what i know of them.I don't know if there is a way to solve this issue for general timers. Due timers features:
1) They always start from zero,
2) They work as UP-COUNTING or UP-DOWN counting timers,
3) Each timer has two compare registers.
My project involves cases to work in sampled times(period), i.e. timer runs for a sampled time and based on values in compare registers the outputs TIOA and TIOB toggles.I am working in up-down mode. Now the problem is when I have zero in a compare register I expect a zero output (on TIOA and TIOB) for whole period. But the timer is toggling output for zero comparison also. i.e. instead of getting a zero always i am getting a square wave with (2*period) as its time period. Is this common problem for other timers also?
Can you guys suggest me a workaround for this problem?
Thanks in advance.
#include <AdvaDueTC.h>
int default_clock = 1;
int RCcntS = 2187*2;
int period0 = 65536;
int a = 2180;
int b = 0;
void subrtn()
{
changeTC_TC3_Period(RCcntS); // loading sampler TC3 with RCcntS
changeTC_TC0_Period(RCcntS/2,a,b); // loading timer TC0 with RCcntT
}
void setup() {
setupTC3_Interrupt(period0,default_clock ,subrtn);//setup sampler interrupt
setupTC_TC0_Timing(period0, default_clock);
}
void loop() {
// put your main code here, to run repeatedly:
}
functions used are :
Here TC3 is in UP mode and TC0 is in UPDOWN mode of operation. TIOA0 and TIOB0 are used for obtaining toggling output.(i.e. in REG_TC0_CMR0, ACPA,BCPB are set to 3). Here TIOB0 is toggling and I want to stay at one valve (0 or 3.3v) for whole period.
Thanks for your suggestion.

when I have zero in a compare register I expect a zero output
i expect the output to be triggered two times (UP and DOWN) every tick (i think you call it period), because the timer is overflowing EVERY tick.
Solution is turn off the timer comparison.
this seems to me a PWM, maybe you'll get better result using the dedicated HW

Yes what you said is correct. At first I couldn't get it but this MCU timer has option to set or clear the timer output value for whole period. so without going for TOGGLE always, I used these options to get desired operation.

Related

Qt measuring rendering time during which application is frozen

I have a Qt application, where, among other things, there is a function render which goes through a list of objects and creates for each an according (subclassed) QGraphicsPathItem which it then puts as a child in a (subclassed) QGraphicsScene. (It is done in the code below through a visitor GGObjConstructor which gets initialized with the variable scene which is the scene where the items are to be added to).
XTimer timer;
timer.start();
gobjlist gobjlis = ogc._gobjectlis;
GGObjConstructor ggoc(scene, z_value, bkground_color);
for(auto obj: gobjlis) {
obj->exec( &ggoc );
}
timer.stop();
My class XTimer is used in an obvious way to measure the time for this proceeding.
Now the problem is: Only the time spent in the loop where all the items are prepared and inserted into the scene is measured by timer. For a typical example with ~165000 items this gives about 7.5 sec as timer-value at reaching timer.stop(). But the application is after these 7.5 sec still frozen, with the screen-window where the scene is to by displayed yet invisible and only after about 25 sec (hand-stopped) suddenly the display window appears with all the items to be displayed.
Now of course I would like to measure these "freeze time" (or time till the application becomes responsive again, or maybe time till display window appears). But I found no way to do this although I looked some time through stackoverflow or the net in general. The best hint I found was
stackoverflow question
The answer there seemed to imply, that it would be not really simple to achieve (overriding paintEvent method and such things).
Question: Is this true? Or is there a simple way to measure the time till the application becomes responsive again/the image is really displayed?
I had a similar problem with an application once, where I wanted to measure the time the app freezes to figure out with logging what was causing these freezes. What I came up was to measure how long the Eventloop of the mainthread was not responding, because this directly corresponds to a frozen app.
The basic idea is to not run a QApplication but inherit from QApplication and override the notify() function. Some apps do this anyway to catch exceptions which would otherwise break the eventloop. Here is some pseudo-code which should bring the idea across:
bool MyApplication::notify( QObject * receiver, QEvent * event )
{
// something like storing current time like:
// auto start = std::chrono::system_clock::now();
// auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(start - end );
// if( elapsed.count() > 1000 ){
// log something like: Mainthread responds again after <elapsed> seconds
// }
// Note that end must be a member variable
// end = start;
return QApplication::notify(receiver, event);
}
Note 1: If your app does not continuesly run through notify() you can for testing purposes introduce a dummy QTimer which triggers faster than the logging time threshold.
Note 2: if you use multiple threads, esp. QThreads it could be necessary to filter the receiver object and perform that code only if the reciever is in the mainthread.
With this code you can log every freeze of the main-thread (frozen GUI) and determine the length of the freeze. With proper logging you can figure out whats causing the freezes.
Keep in mind that this will only log after the freeze has resolved!
Addition:
It is more complicated and slow, but for debugging/investigation purposes you can store the last event and Object-Tree of the reciever and log that as well. Than you even know which was the last event which triggered the freeze and the recieving Object.

How to use Serial as an interrupt for other functions

I'm making an LED control program (using FastLED, of course) and using Serial (with the Serial monitor) to control it. I just connected it via USB and for the most part it works just fine. However, I noticed with the long, flashing routines that I couldn't stop them and make the LEDs do something else. The flash routine in my code is very simple:
void flash(CRGB color, int count, int del){
for(int i = 0; i < count; i++){
if(pause){
break;
}
fillLeds(color.r, color.g, color.b);
milliDelay(del);
fillLeds(0,0,0);
milliDelay(del);
}
}
With fillLeds(r,g,b) being a for loop, looping through and setting all LEDs to a certain color, and milliDelay is just delay() using millis and not the delay() function.
I need to be able to pause not just this, but other functions as well (probably using break;) and then execute other code. It seems easy, right? Well, I've noticed that when I send a byte over Serial, it goes into this "queue," if you will, and then is sequentially read.
I can’t have this happen. I need the next byte entering Serial to activate some kind of event that pauses the other flash() function running, and then be used. I have implemented this like:
void loop()
{
if (Serial.available() > 0)
{
int x = Serial.read();
Serial.print(x);
handleRequest(x);
}
FastLED.show();
FastLED.delay(1000 / UPDATES_PER_SECOND);
}
Where handleRequest(x); is just a long switch statement with calls to the flash method, with different colors being used, etc.
How can I make the Arduino pause other loops whenever a new byte is received, instead of adding it to this "queue" to be acted upon later? If this is not possible thanks for reading anyway. I've tried using serialEvent() which doesn't appear to work.
I think you need two loops. You have one, which is your main loop, and you can add another (like a multi threading) with the TimerOne library. Like this:
Timer1.initialize(your desired delay in this loop);
Timer1.attachInterrupt(your desired function in this loop);
So maybe you can add an if statement with a variable in your second loop to prevent some function and update the variable in your first loop or something like that.
Presuming you want interrupt-like functionality when a new byte arrives:
Unfortunately, serialEvent() is not a true interrupt. It only runs at the end of loop(), if there is serial data available.
However, serialEvent() is just a function, and there isn't any reason why you can't call it in your code as often as you like. This is effectively polling for new serial data as often as possible. So, while your loops are running, call serialEvent() during your delays and handle the serial data there.
You may need to restructure your code to avoid recursion though. If flash calls serialEvent(), which calls flash, which calls serialEvent, etc... then you may end up overflowing the stack.

Unable to cause horizontalSlider to slide at regular time intervals

I need to make a Music Player using Qt, in which the slider slides as the song progresses.
this->ui->horizontalSlider->setValue(10);
sleep(1);
this->ui->horizontalSlider->setValue(20);
I was trying things like above but could not cause it to display the changing values, as the program pauses for 1 second and only the second value(20) is displayed.
How can i achieve this?
Whatever library you use for audio playback should asynchronously notify you of progress in playing the file. You should react to such progress and update the slider. Using hardcoded delays will quickly desynchronize the slider from real audio playback, even if we forget the fact that you block the event loop.
In any modern application development framework there's generally no need ever to block a thread to sleep. If you write such code, it's the wrong approach in 99.99% of the cases.
Sleeping will block the program for 1 second. Meaning that anything going on (music playback, or any process running inside your app) will basically not work.
What will happen is that the program will set the value to 10, sleep one second (nothing will happen), set 20, and block the program for 1 second again. So basically, your program blocks all the time, and sets the slider's value every second.
The solution is to get the progress value, for example :
int total_time, current_time; //Durations in seconds
int progress; //Will hold the progress percentage
//Somehow you get the total song time and the current song timer
//...
progress = (current_time/total_time)*100
this->ui->horizontalSlider->setValue(progress);
Or :
/*When initializing the slider*/
int total_time; //Duration in seconds
//Somehow you get the the total song time...
//...
this->ui->horizontalSlider->setRange(0,total_time);
And in your routine
/* In the routine where you refresh the slider */
int current_time; //Duration in seconds
//Somehow you get the the current song timer...
//...
this->ui->horizontalSlider->setValue(current_time);

Qt crash when drawing, even though in GUI thread

I think I'm having a problem similar to the one in Qt crash when redrawing Widget, and switching to Qt::QueuedConnection fixed the problem. However, in my case, both the signal emitter and received are always in the same thread (the main thread).
I have a QAbstractItemModel with entry rows, and a QSortFilterProxyModel for filtering. Since the model can be very large, I wanted to make a progress bar when filtering. Updating the filter basically does this in a slot that is connected to a QAction::toggled signal:
m_ProgressBar = new QProgressBar(); // Put into status bar etc.
auto connection = connect(m_filteredModel, SIGNAL(filterProgressChanged(int)), m_ProgressBar, SLOT(setValue(int)), Qt::QueuedConnection);
m_filteredModel->UpdateFilter();
delete m_ProgressBar;
disconnect(connection);
UpdateFilter basically does some housekeeping and then calls invalidate, making the filter model requery filterAcceptsRow for every row.
The filter model then emits the filterProgressChanged(int) signal within filterAcceptsRow (works by incrementing a counter and dividing by the source model's row count, and is only emitted when the actual int progress value changes).
UpdateFilter returns when the filtering is complete. The progress bar is not deleted until then (verified), so it should work in my opinion. Not deleting the progress bar leads to getting a new one every call, but the crash is still the same.
Everything is done in the main thread: Creating the progress bar, calling UpdateFilter, emitting the filterProgressChanged signal. However, when the connection is created as Qt::AutoConnection, i.e. direct, it crashes (only when disabling the filter, for some reason) within repainting the progress bar. The same happens when I call setValue directly in my own event handler, which is what I did prior to switching to the current code.
Now I have a solution that works, but I don't understand why the original code does not work. I thought that a DirectConnection would only make an actual difference when sender and receiver of the signal are in different threads, but they're not. You can easily see in the stack trace that everything happens within the same thread, and that is even true with the queued connection.
So, what's going wrong in the original code? Is there something I just missed? Is there any way to get more information out of the actual crash?
I only found out that in void QRasterPaintEngine::clip(const QRect &rect, Qt::ClipOperation op), state() returns 0, and the code assumes it never returns 0, which is the immediate crash reason, but likely not the reason. And the stack trace points to painting as the problem area, that's all I saw when debugging this.
I'm on Windows with Qt 5.4.2 (also tried 5.7), and with MSVC 2013, if any of that matters.
Edit: As requested by code_fodder, I added the UpdateFilter and emit code (actualFilterFunction performs the actual filtering, but has nothing to do with signals or GUI or anything).
void MyModel::UpdateFilter() {
m_filterCounter = 0;
m_lastReportedProgress = -1;
invalidate();
}
bool MyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
m_filterCounter++;
int progress = (100 * m_filterCounter) / m_sourceModel->rowCount();
if (progress != m_lastReportedProgress) {
emit filterProgressChanged(m_lastReportedProgress = progress);
}
return actualFilterFunction();
}

Replacement for Arduinos millis() that is reliable also with disabled interrupts

As stated in stackoverflow-17135805 the millis() function does not return the correct time, if the interrupts where disabled, while Arduino had to detect an overflow of timer0.
I have a time critical program that uses a lot of functions which have to disable the interrupts. So my program runs 1:30 while it thinks it was running only for 1:00.
Is there another timer that I can use to avoid this problem?
It happens to me when I use the GSM Module:
// startpoint
unsigned long t = 0;
unsigned long start = millis();
while ( (millis()-start) < 30000 ){
//read a chunk from the gprs module
for (int i=0;i<8;i++)
client.read();
//do this loop every 10ms
while( (millis()-start) < t*10 ){};
t++;
}
//endpoint
From the startpoint to the endpoint it should take 30 seconds. Instead it takes 65 seconds.
If you have to disable interrupts so often and so long your best bet would be to use an external timer. I highly recommend DS3231. Since it has a build in crystal it is easier to setup than a 1307 and it is also significantly more accurate.
You could use one of the other hardware timers
to keep track of the time. For example, on the Leonardo Timer 1 is a 16 bit timer.
To set it up directly (this obliterates code portability) there are a couple steps.
TCCR1A = 0;
this puts the timer in "normal" mode, meaning it just runs to 0xFFFF and wraps back to 0x0000.
TCCR3B = 0;
TCCR3B = _BV(CS11) | _BV(CS10);
this starts the timer and sets it to use a clock/64 prescale, which equates to 1 tic every 4us.
To check the time:
long time; // declared somewhere in scope.
time = TCNT1; // this reads the timer count register
time *= 4; // this multiplies time by 4 to give you us.
As mentioned earlier, TCNT1 wraps around at 0xFFFF = 65536. So, with the pre-scaler set as above, that gives you about 65536 * 4E-6 = .262 seconds of counting before your program needs to put the data into a bigger variable (assuming you care). Hopefully it isn't a problem to poll things more often than 4 times a second, which gets you away from interrupts.
Several arduino core functions utilize these timers, so you'll need to verify that the core functions you need don't depend on the timer you choose. For example, doing the above will break analogWrite() on certain pins.

Resources