Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

Serial Interrupt on Separate thread
Goto page 1, 2  Next
 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
azny

Bascom Member



Joined: 25 Aug 2008
Posts: 33
Location: usa

usa.gif
PostPosted: Tue Feb 13, 2018 3:31 am    Post subject: Serial Interrupt on Separate thread Reply with quote

Hello

I have a requirement where I need to do some freq calculation in my main code and then if I receive char "a" on the UART then I need to print my calculated frequency out.
I need to send the char"a" every 10ms and read the frequency.
The frequency calculation loop takes 10ms by itself.

My problem is
If I read continuous data every 10ms then many times I miss the data or I receive corrupted data. My assumption is I am getting corrupted data because at times I am in the middle of the freq calculation loop.

Is there a way where my calculation runs on main thread and when I receive a char over UART it sends data out without stopping the main calculation thread.

(BASCOM-AVR version : 2.0.7.5 , Latest : 2.0.8.1 )
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 1466

blank.gif
PostPosted: Tue Feb 13, 2018 6:20 am    Post subject: Reply with quote

Could have said it short No code - No service, but a bit longer: in code where a single core processor is busy with timing work, any interruption does alter the result.
Such thing as a 'thread' would thus also interrupt any measurement.
You need to work on your sync concept, maybe simply put the result out without request after each measurement period, maybe use a faster frequency measurement method, measure the period and calculate therefrom the frequency.
Maybe it's better to describe the problem more exactly, than describing an unfit solution.
Back to top
View user's profile
azny

Bascom Member



Joined: 25 Aug 2008
Posts: 33
Location: usa

usa.gif
PostPosted: Tue Feb 13, 2018 5:14 pm    Post subject: Reply with quote

**** will replace the code with something more easily understood as it seems to have confused some people***

Last edited by azny on Tue Feb 13, 2018 8:57 pm; edited 2 times in total
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 1466

blank.gif
PostPosted: Tue Feb 13, 2018 7:09 pm    Post subject: Reply with quote

With this line
Code:
Arr(3) = F1
it doesn't compile.
Beside that I suggest to wait at
Code:
If Ischarwaiting() = 1 Then
for the incoming request, as you have a problem getting the whole thing in sync.
Surly you get data of unknown age the first time the master is doing its round, but after then, data age is uniformly delayed, depending on the pace of the master's queries.

Also I do not believe you need a buffered serial, as the UART buffers one char itself and it won't help the case, if more "a"'s can be fetched from the pipeline.
With your current code a value-request may just come in, as the the loop's start is executed. It will last at min 15ms, potentially longer, to answer the data request.

It is however possible to immediately execute a label at an incoming "a", see BYTEMATCH option for the buffered serialin, or do it yourself with
Code:
On URXC yourlabel
But still then the processor may be in-midst requesting data from the sensors, it makes little to no sense that the master's request gets immediately answered, while data is only partly or not at all valid.
Back to top
View user's profile
JC

Bascom Member



Joined: 15 Dec 2007
Posts: 440
Location: Cleveland, OH

usa.gif
PostPosted: Tue Feb 13, 2018 7:39 pm    Post subject: Reply with quote

Without a diagram of the overall system, and more explanation, it is difficult to understand exactly what you are trying to do.

That said, a few thoughts:

I don't have Bascom on my current computer where I am, but go read the help / info on the waituS command.
I think you will see that it is a very crude timing, and it certainly isn't 1 uSec.
WaituS is especially inaccurate at very low counts.

How fast is the frequency you are counting?

For accurate counting one might consider using a Timer/Counter module set up to count the pulses in hardware for you, (not in software), and use another Timer/Counter to control the gate interval. One might use an ISR to turn off the gate. This will have a few clock cycles worth of delay, hence the question as to the frequency of the incoming signal, the gate time, and how accurate you need the count.

One could, perhaps, route a very precise T/C signal to control the gate time of another T/C which is actually counting the pulses, if needed.

The key concept is you want the hardware to do the counting independent of the micro and any interrupts the micro is processing for other tasks, (e.g. the USART).
This effectively lets you run "two threads" simultaneously, in a single core processor.

Next, as your USART communications is critical, you don't want to turn off interrupts.
Setting up USART comm's to run interrupt driven is good, but you defeat the benefit when you turn off interrupts during a time when you might be receiving data.

The USART ISR receives a Byte in hardware, at whatever baud rate, (fast or slow, it doesn't matter), and then when the full Byte is received it generates an interrupt to stuff the Byte in a buffer and increment a pointer, then exit the ISR. This is very fast.

If the very short amount of time the USART ISR runs causes a significant error in your gate time, (i.e. it occurs just when you should be turning off the gate), then consider options.
Again, let the hardware itself generate the gate, as mentioned above.
Or, run your micro at 16 MHz or 20 Mhz (depends on the micro), instead of 3.x MHz.
16 MHz gives you 4 times the clock for the micro, and therefore it can run the USART ISR four times faster, causing much less interruption of the gate interval, if you still control the gate from software.

Want to take that to the extreme, switch to the Xmega32E5, (or a larger Xmega).
It runs at 32 MHz, almost 10 times faster than your current setup.
So 1/10th the delay caused by the USART ISR, which is, in this case, perhaps 1 or 2 microseconds.
Hence, again, the need to know the input frequency, gate time, and accuracy needed.
How many pulses can you possible miss with the 2 uSec error / jitter in the gate interval.

Know, also that the Xmega32E5 has a programmable logic unit within the micro.
If you are using an external chip to gate the clock in hardware, then this could likely be handled by the uC itself, in hardware, (without software intervention).
That is what the programmable logic unit is good at!

The goals should be, (generally), let the hardware do the counting, let the micro control the hardware, don't disable the USART when you need to rely on it for incoming data.

JC
Back to top
View user's profile Visit poster's website
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 1466

blank.gif
PostPosted: Tue Feb 13, 2018 8:28 pm    Post subject: Reply with quote

@JC: maybe you shot something on your hunt, but it may have been a tree or fellow hunter ;D

Didn't you notice reading PinC is rather reading an external counter?
Where in the whole code do you see a soft- or internal counter to be used?
That means he already uses some kind of hardware counter, something you did suggest he should do.
Also, didn't you notice the us-delay seems rather a delay to allow some latches to become stable?
And even the us-delay actually would be a gate-time, didn't you notice that interrupts are disabled for this part of code?
Thus a waitus will last every time exactly the same, even exact to the same cycle.
And disabling interrupts even with a buffered serial is perfectly ok as long it's short enough, the UART can keep one byte in UDR and another in it's incoming shift register.
Nearly two bytes, means a delay of 1sec / (Baudrate / (10 * 1.5)) should be still save.

Won't anticipate the TO's own evaluation, but still wondering what you was hunting for.
Back to top
View user's profile
azny

Bascom Member



Joined: 25 Aug 2008
Posts: 33
Location: usa

usa.gif
PostPosted: Tue Feb 13, 2018 9:15 pm    Post subject: Reply with quote

OK, i removed the code so no one is confused-- it's more of a conceptual question. we can deal with the code latter if necessary.

Here's how it's done until now.

(1) a frequency is measured using an external counter and the count is read in via PortC. while the external counting is done, interrupts are turned off so as not to corrupt the counting and read from counter cycle. then interrupts are turned back on after the counting process has completed so that the micro can listen on for the master controller

(2) however, an asynchronous character, call it "a" from the master controller (MC) can be received at anytime requesting that the count value be sent to the master controller.

What we are seeing is that received data by the MC sent from the device can be corrupted and even missing after sending the character "a".

we thought that the ischarcterwaiting buffer should handle this.

However, when the MC initiates the process i.e. send "a" to device, which causes the device to count, and then send back the count to the MC, the process works fine, no data loss or corruption.

Its only when its done asynchronously i.e. "a" and external counting are not sequential, that we have a problem.

So the question is-- how to get two asynchronous processes (1) responding to "a" with the last measured counts and (2) device external counting to not cause corruption of data?
Back to top
View user's profile
JC

Bascom Member



Joined: 15 Dec 2007
Posts: 440
Location: Cleveland, OH

usa.gif
PostPosted: Tue Feb 13, 2018 9:58 pm    Post subject: Reply with quote

No system overview / diagram can make it difficult to interpret what the system is.

It was, admittedly, a brief look at the code, not a detailed analysis.

That said, OP had 5 mSec pauses scattered throughout the code, and reported apparent problems with USART commands.
Hence, IMHO, reasonable to stop disabling interrupts...

Not sure why a presumably 8-bit external counter is being used when the uC could do this, but anyway, it still isn't clear what disabling interrupts on the micro has to do with an external counter counting pulses.

I'd think that if a request for data came in one would set a flag and then wait for the current gate time to time out, and then upload the data.

Receiving USART commands and running gate times & reading the counter can be two independent tasks.

Perhaps your current system isn't waiting for the counter to finish its gate time before initiating a read?

I commented on the waituS 1 as it always catches my eye when someone uses that instruction.
IIRC there is significant overhead, and the % error is very high for small counts...
Agreed it might not matter for a delay between toggleing bits on an external chip.
But a NOP or two would like suffice.
The waituS 1 implies a precision that isn't there, and I was just pointing it out.

The original post also states that one has to send the "a" every 10 mSec, and that the freq calc process takes 10 mSec.
That clearly sets up a critical race. If one is going to send data every 10 mSec, then why not stick the data in a packet with a check sum and just send it every 10 mSec without the request?

The comments about the micro's clock speed still apply, if you are taking the full 10 mSec to do your calculations, then change to 16 MHz and you now take about 4 mSec to process your data, leaving you lots of time to process the control aspect of the project.

JC

Edit: Typo
Back to top
View user's profile Visit poster's website
azny

Bascom Member



Joined: 25 Aug 2008
Posts: 33
Location: usa

usa.gif
PostPosted: Tue Feb 13, 2018 10:34 pm    Post subject: Reply with quote

guess more explanation is needed.

ideally we would like the measure/counter to run continuously. When an "a" is received the micro sends the last measurement from the counter.

if we do the following process (#1) everything works fine:
(1) is character "a" waiting? Yes go to (2), No- wait (go back to 1)
(2) disable interrupts to ensure gate time of 10ms is accurately repeated each time
(3) make measurement
(4) print data to master controller
(5) goto 1

if we do the following process (#2) things get screwed up:
(1) disable interrupts to ensure gate time of 10ms is accurately repeated each time
(2) make measurement
(3) is character "a" waiting? Yes go to (4), No- go back to (1)
(4) print data to master controller
(5) goto 1

Anticipating some questions:
- we use a high speed (>20MHz) 24 bit counter so that we can make up to 0.5sec gate times of counting
- clock speed is low for power consumption requirements

alloting 10msec for polling and 10msec for measurement should have nothing to do with each other as they should be independent--or so we thought. Also, IScharacterwaiting should be completely independent as it has a buffer in it.

So why does #2 not work? that's the question.

Now we can start looking at code if my explanation makes sense. if so, what parts of the code would you like to see?
Back to top
View user's profile
JC

Bascom Member



Joined: 15 Dec 2007
Posts: 440
Location: Cleveland, OH

usa.gif
PostPosted: Tue Feb 13, 2018 11:24 pm    Post subject: Reply with quote

Just to be clear, in process #2, (the one that doesn't work):

Step 2.5 is re-enable interrupts?

JC
Back to top
View user's profile Visit poster's website
JC

Bascom Member



Joined: 15 Dec 2007
Posts: 440
Location: Cleveland, OH

usa.gif
PostPosted: Tue Feb 13, 2018 11:29 pm    Post subject: Reply with quote

Also, please describe what controls the gate time?
How do you time and control the gate time signal?
Related to that, how accurate, +/- X uSec, must the gate time be?

Is there a multiplexer controlling which sensor feeds its signal to the counter?
(Presumably yes, and presumably under the micro's control.)

JC
Back to top
View user's profile Visit poster's website
azny

Bascom Member



Joined: 25 Aug 2008
Posts: 33
Location: usa

usa.gif
PostPosted: Wed Feb 14, 2018 12:47 am    Post subject: Reply with quote

Yes, 2.5 is right

Timing is done by simply setting a pin high for 10msec using the waitms command- suprisingly very stable using a crystal for the clock
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 1466

blank.gif
PostPosted: Wed Feb 14, 2018 1:10 am    Post subject: Reply with quote

azny wrote:
OK, i removed the code so no one is confused-- it's more of a conceptual question.

Hmm, the only one confused is you, as the code perfectly showed your problems, for me they are obvious.
You seem to have found a helper less 'demanding' than me, so good luck.
My language is code, if yours is not I'm out here.
Back to top
View user's profile
azny

Bascom Member



Joined: 25 Aug 2008
Posts: 33
Location: usa

usa.gif
PostPosted: Wed Feb 14, 2018 1:55 am    Post subject: Reply with quote

@mws why so rough? I thought people r here to help, i would welcome any help you can give, what part of the code do u want me to put back up?
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 1466

blank.gif
PostPosted: Wed Feb 14, 2018 3:12 am    Post subject: Reply with quote

azny wrote:
@mws why so rough? I thought people r here to help, i would welcome any help you can give, what part of the code do u want me to put back up?

Made it a rule to respond like the discussion partner responds to me.
You have to think about why people are taking an effort to care about your problem, remember that members here are not part of the Bascom team, neither we get paid for.
So why do we respond? One motive is having fun, to solve a riddle for example.
If my discussion partner makes it harder for me to solve the riddle, for example by removing the code in question, it's not fun and I am out.

And no, you don't need to repost the code or parts of it, I did a local copy, compiled and checked the assembly whether processor registers R12 to R15 are affected by interrupt code for the buffered serial. These processor registers are used for floating point operations and an interrupt altering these registers would lead to data corruption.
Was able to notice there was no problem about it.

So it's the asynchronicity problem, you simply need some time to collect data, while a request for data can occur anytime.
You can't have both at the same time, it would not even work with a multicore system to do that in the same time.
So either you collect data in advance, with the disadvantage to have old data ready, or you initiate collection on request, with the disadvantage of wasting precious time.
Basically that's your choice.

What you can do is to split up the three measurements and allow data collection in between, minimizing time to wait for data.
As already said: good luck.
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum