CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Best way to multitasking
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

Best way to multitasking
PostPosted: Mon Oct 16, 2017 7:32 am     Reply with quote

Hi,

I'm writing some code to measure a LVDT's output over stroke.
Working:
* Excitation frequency generation & voltage adjustment
* Two channel Sample and hold
* Serial commands to set V & F, start and stop readings
* Reading encoder position over serial from another pic on another board
* Outputting channel A & B Voltage from Sample and hold & current position over serial

The readings are received by PC and subsequently drawn on a graph to show output V over
position.

My issue is at 3KHz I can only sample every 10th pulse because my serial string
is too long, "Axxx Bxxx Pxxxx" at 921600Bd.
So for example when LVDT is static the output is good, and if I move the LVDT slowly I
get a nice straight output line. If I move quicker the output line will dip.
How can I use sample continuously and send the serial out in the "background" somehow please?
I tried using the CCS RTOS this morning, but can't get it to sample enough due to
serial Max time, whilst allowing the serial tasks enough Max time.

Any recommendations please?

Thanks!
Ttelmah



Joined: 11 Mar 2010
Posts: 19569

View user's profile Send private message

PostPosted: Mon Oct 16, 2017 7:48 am     Reply with quote

If you are sending at 921600bps, then each character will take 1/92160 second (assuming 8bit). For the string you show, assuming there is a LF at the end, there are 17 character, so the physical transmission alone will take just on 1/5000th second. Now this can be going on while you are doing other jobs, by simply using a serial TX ISR. There is an example with the complier (ST_ISR.c), or you can use the TX_ISR option in the #USE RS232 driver now. However there is a big caveat, that you still have to generate the serial string. If you are sending this as decimal, then 'reconsider' and send as hex, which has the advantage of reducing the amount of calculation needed to send the data, and reducing the transmitted length as well. It is also pointless to be sending A, B & P, and the spaces between.
A packet like:
<STX>HHHHHHHHHH<LF><ETX>, sends 13 characters and can have two 12bit hex values and a 16bit hex value using much less time. It is easy to both encode and decode.
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

PostPosted: Mon Oct 16, 2017 9:53 am     Reply with quote

Thanks Ttelmah, I used the ex_stisr.c example and reducing the serial string as you suggested, I can see on the scope it's working. I just need to amend the c# code to decode the new hex string and hopefully this will solve the problem!

Thanks again
Ttelmah



Joined: 11 Mar 2010
Posts: 19569

View user's profile Send private message

PostPosted: Mon Oct 16, 2017 10:33 am     Reply with quote

Well done.
Even on a PC, hex decodes faster than decimal, so it'll help here (provided you design the layout to suit - depends on the sizes of the numbers involved etc..).
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 16, 2017 12:52 pm     Reply with quote

If you want to do multi-tasking in the future, look at this thread for
techniques:
http://www.ccsinfo.com/forum/viewtopic.php?t=54043

Also, use the forum's search page to search for: multi-tasking
There are several threads on how to do it.
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

PostPosted: Tue Oct 17, 2017 10:13 am     Reply with quote

Dear Guru's,

Linked to my previous question, I now need a solution for the incoming encoder position, as the rate of data coming in when moving LVDT faster is putting my S & H timing off. I've tried disabling and enabling int_rda2 when sampling, which improves the timing, but misses positions being sent. Also tried adding RECEIVE_BUFFER=1024.

Is there an example of incoming buffer anywhere please? I've looked in the examples dir & in the code library? Or try and work out the xmit buffer and rewrite for rcv?

Thanks!
temtronic



Joined: 01 Jul 2010
Posts: 9255
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Oct 17, 2017 2:20 pm     Reply with quote

ex_sisr.c is the CCS example of an ISR driven serial receive. It's in the 'examples' folder. A fair amount of discussion about it so maybe 'search sisr' and see what pops up.
I did a test using a slightly modified version, on an 18F46K22 using both serial ports and 'blasted' away to a PC at 115K200, never lost a byte though the test only ran 2 weeks.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19569

View user's profile Send private message

PostPosted: Tue Oct 17, 2017 11:53 pm     Reply with quote

Honestly though a lot depends on just how fast things have to be.
It is enormously easier to take advantage of hardware. For instance it is relatively easy (couple of logic gates), to build a circuit to give two pulse trains from an encoder, one for each direction. This can be fed into hardware counters. Or some PICs have quadrature counters built in. Or US digital do quadrature decoder IC's.

The critical thing is to start working out what timings genuinely are involved....

For example, if you have an encoder with (say) 512 lines, and it turns at 1000RPM, this potentially gives 8533 lines per second ((512*1000)/60). However a quadrature encoder produces four state changes per line, so 34133 interrupts per second to handle this without loss. Now even if you write efficient assembly code directly for a high priority interrupt handler, you are talking at least perhaps 20 instructions to handle an interrupt. Do it instead using a general handler and you are talking at least perhaps 80 instructions. Now if all your interrupts are at the same hardware priority (from the data rate involved I am assuming you do have a PIC18 or better), then you have to potentially complete any other interrupt handler you have, if it does happen to get called just a moment before a change on the encoder. This in part is why it is so critical to get out of interrupt handlers ASAP, if other things are being handled.
You need to start with things that must be handled. Encoder edges are such things. Calculate the minimum interval involved (as shown above). This then gives a time that the handler has to cope with. Then list other time events that have 'margins'. So (for instance), serial receipt. You have just fractionally under two character times before the UART will overflow. Is there enough time to handle all the edges, and still have some service time left for this?. All of these things have to happen before you have any time left for the 'main' code. If the timings look 'tight', then tweaking may improve a little. However if the timings are not even in the same 'ballpark', then you need to be looking at hardware solutions to give the margins needed. Something like the LFLS7366R connected to the SPI interface on a PIC makes encoder counting a 'doddle', and leaves time for other things.
Some calculations are needed to see what is really practical.
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

PostPosted: Wed Oct 18, 2017 9:43 am     Reply with quote

Thanks for the advice, which caused me to rethink what I'm doing. I've now linked the CH A & B of encoder from the motion board to the analogue board, so I can read in hardware into the QEI and working well. These are only proto's so can respin the change in next build.

Thanks again!
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Thu Oct 19, 2017 1:34 pm     Reply with quote

Hi ccsfred,
You didn't mention what PIC you are using but I just wanted to share with you - I ordered a couple of samples of dsPIC33EV256GM002.
I was surprised that within 15 minutes I had it connected and running a blinking led, CPU running at 70 MIPS (140MHz internal clock)! Powerful 5V beast easily tamed with the CCS compiler.
The 16-bit MCUs (and now some of the newer 8 bit) also have DMA which means you can transmit, receive AND sample simultaneously, all done IN THE BACKGROUND while your main code is running. This solves many of the difficulties of the project you describe.
* Disclaimer - from my experience if you choose this path be prepared that the compiler might have a few bugs which will require you to go to low level registers.
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Fri Oct 20, 2017 1:30 am     Reply with quote

Now this is useful information. A dsPic running of 5V. Will make my life so much easier. Using current sensing chips that are only available in 5 V now have to use opamp and divider to go to 3v. And the best are that I am using the EP128GM, so absolutely code and pin compatable.

Just when programming the EP on an old board with the chip selected as EV128GM, aaaarg Bummed Out
Ttelmah



Joined: 11 Mar 2010
Posts: 19569

View user's profile Send private message

PostPosted: Fri Oct 20, 2017 5:30 am     Reply with quote

There are a few chips like this appearing now. They are basically CPU cores at a low voltage (typically only a couple of volts), with buffered I/O provided, and an internal regulator for the core. Very nice for a lot of things. Smile

Be aware that the DMA is limited by the capabilities of the memory bus. By default the CPU has priority, and if you perform operations doing rapid RAM I/O, the DMA may almost stall. Normally there is plenty of time for the other device(s) while you are doing things like jumps, which don't involve RAM accesses, but it is possible to find the DMA doesn't help as much as you may think it should...
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Fri Oct 20, 2017 9:07 am     Reply with quote

Ttelmah, does this apply to UARTS, ADC etc? These peripherals need the DMA for a single byte/word transfer per thousands of machine cycles, isn't it? Please describe your experience with the subject.

I love the fact that DMA doesn't require an interrupt for each transfer - saves cycles, stack, and usually code complexity.
Ttelmah



Joined: 11 Mar 2010
Posts: 19569

View user's profile Send private message

PostPosted: Fri Oct 20, 2017 2:01 pm     Reply with quote

It applies to all DMA.

There is only one RAM bus. There is an arbiter between the DMA and the processor that (by default) gives priority to the CPU. The DMA can only pull data on the RAM bus on cycles where the CPU is not using the bus. Now normally there are enough cycles when the CPU doesn't use the bus at all (jumps etc.), for the DMA to merrily proceed. However I was using a DMA SPI 'flat out', and at the same time a DMA based MSD USB implementation (basically relaying SD card data via the PIC to a PC), and proceeded to do a large memcpy, and found the DMA bottlenecked when I did this.
Now for something that is only transferring low data rates relative to the CPU, 'no problem', but it does have limits.

As a [spam] example, using DMA to drive an SPI ADC, and it is lovely. Instead of having to interrupt every byte and transfer the next, just program it have the bytes that need to be sent coming from one area of RAM, and the result fed to another, and interrupt when all the bytes have been transferred. Brilliant. Smile Far less overhead than repeatedly calling an interrupt handler, and in normal code flow at the reasonably low SPI rate involved, the transfer finishes only a very few machine cycles longer than the theoretical 'max'.
ccsfred



Joined: 15 Jun 2016
Posts: 33

View user's profile Send private message

PostPosted: Tue Oct 24, 2017 9:55 am     Reply with quote

Hi Guy,
I'm using a dspic33fj256mc710A, thanks I shall read up about DMA not used before!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
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


Powered by phpBB © 2001, 2005 phpBB Group