1
\$\begingroup\$

I am a Mathematical Person. So thinking from that perspective.

To make my question slightly more concrete. I was thinking of controlling a hobby servo through a Uart serial data stream.

I am inventing numbers for the purpose of communicating the idea.

CONTEXT:

Suppose a servo needs to be refreshed at 100 Hz and needs a resolution of 1 degree.

So this implies that the serial communications needs to send DATA (101101000) 9 bits wide. (I realize there is overhead KEEPING IT SIMPLE ATM). @ 100Hz. Therefore 900 bits per second transfer rate.

Given that a servo is controlled by a PWM signal. And In the case of an arduino with 16Mhz clock.

That serial transfer will consume a percentage of the Time, leaving the remainder to produce the PWM signal for controlling the servo.

MAIN QUESTION:

How do I in general find "given the Library nature of programming languages" the number of low level instructions used for particular function or routine. So I can see If I have enough time to fit in in this case. The PWM signal between data transfer.

\$\endgroup\$
  • \$\begingroup\$ Do you mean any particular processor? And which OS do you have in mind? \$\endgroup\$ – Ale..chenski Jul 1 '18 at 23:56
  • \$\begingroup\$ Atmel AtMega32u4 Micro Controller. However My question was general in nature. Because its more about how to find this information for "insert board" and being able to select accordingly. \$\endgroup\$ – Rob Jul 2 '18 at 0:22
  • \$\begingroup\$ thats cool I found an error in question anyways. 9 * 100 = 900 not 9000 lol. Thanks. \$\endgroup\$ – Rob Jul 2 '18 at 0:31
  • \$\begingroup\$ in human terms, the workload on the microcontroller doing a 100Hz servo refresh is similar to you turning a page of a book once every day or so ..... i am really only guessing on the exactness of the comparison \$\endgroup\$ – jsotola Jul 2 '18 at 0:35
  • \$\begingroup\$ You write the code and then benchmark it with a scope. Trigger on UART falling edge, then display the PWM. Trying to come up with a theory of how many instructions the Ardunio libs yield isn't going to happen, there's too much C++ goo between the user code and the hardware. If counting instructions is important, then write the driver yourself. Coding real-time microcontroller systems with Arduino sounds painful. \$\endgroup\$ – Lundin Jul 3 '18 at 9:57
0
\$\begingroup\$

In general any library written in C is probably not going to have information on how many clock cycles it takes to execute a function. The reason is that it depends on your compiler optimization settings, and which compiler you use.

Usually you can only tell from source code how long something is going to take if you are looking at assembly language. And only then by looking up the timing for each instruction in the datasheet.

I believe that the Arduino boards use the Atmel AVR processors. In that case you can use Atmel Studio to simulate the code for any library function. The simulator will count the elapsed time of the simulation.

Just put a breakpoint before and after the code you want to time. Run the code to the first breakpoint and record the time. Then run to the second breakpoint and check the time. The difference in those two times is what you want to measure.

The serial reception and the PWM generation actually run in parallel without CPU involvement because your chip probably has dedicated hardware for both of those functions. The CPU is only required to adjust the PWM duty cycle if it needs to change, and to take a character once the receive buffer is full.

Also with respect to the 9 bits, if your UART supports a 9 bit word then your total number of bits is 9 data bits plus a start and stop bit so 11 bits per value. If your UART only supports 8 bits then you are forced to send two bytes, for a total of 20 bit times if you include the start and stop bits.

Note that the time it will take to send a byte can be roughly determined without simulation just based on the baud rate. For example a 9600 bps rate will take (10 bits)/(9600 bits per second) = 1.04ms per byte (when sending with 8-data bits, 1 start bit, 1 stop bit). Since you only need to update once every 10ms, even 9600 bps (which is pretty slow) would be more than sufficient.

\$\endgroup\$
  • \$\begingroup\$ The UARTs in AVR chips do support 9 bits, but the 9th bit needs to be pulled from a separate register. \$\endgroup\$ – Ignacio Vazquez-Abrams Jul 2 '18 at 1:02
  • \$\begingroup\$ Thanks user96037 that is exactly what I was looking for. I didn't realize PWM was parallel (very useful information). Good point about compiler efficiency. I had a very general conceptual understanding thanks for taking the time to answer! \$\endgroup\$ – Rob Jul 2 '18 at 1:11
  • \$\begingroup\$ Interestingly some of the XMOS parts have a tool chain that displays this information right in the IDE, together with the rather large number of execution units needed to keep each one simple enough to enable this sort of determinism for a useful set of application code. In a more general sense this problem is a special case of the "Halting problem". xmos.com/products/tools \$\endgroup\$ – Dan Mills Jul 2 '18 at 2:18
1
\$\begingroup\$

Even with a RISC processor like this, where all instructions take the same number of cycles, it is going to be difficult if not impossible to determine the exact number of cycles (and thus time) of a given library routine. Especially considering the that every conditional decision within each library call may introduce more or less instructions (and time) into the execution path. If you were working with a full debugger and simulations system (which Atmel may offer at a price), it would then be possible to set breakpoints and measure precise timing of every possible case of every routine. But I suspect it would be frustrating unless the library functions were designed to ensure all cases resulted in the same timing.

That being the case, if I were you and had these concerns I would employ an oscilloscope with at least dual trace and trigger capability to test timing and synchronization, in a more deterministic fashion. That is, I can start any number of test sequences and toggle various digital pins to change output state when a given task completes. This would allow me to clearly see both the total time to complete various tasks, as well as differences between various cases. The result you are hoping for, which I think you'll get given the speed of the CPUs, is that you will have more than sufficient extra time, and all your tasks are be completed in time that is insignificant compared to the much slower speed of the actual 9 bit serial words.

Of course if it turns out that even with negligible processing time, you are still not satisfied with being limited by the speed of the serial transmission, then you'll have to either use a much faster bit/baud rate, or you will have to use multiple processors (each with their own serial I/O). then they can all prepare their data and be triggered to send simultaneously, from a single command (such as a single digital I/O point signalling all CPUs to send).

Good luck! Hopefully you'll find the Arduino speed is not an issue, and sending data to all your servos one at a time is still adequate.

And I don't know if it matters, but all arduino processors I know of have several direct PWM outputs.

But also be aware there are probably better forums than the electrical engineering forum for specific coding or processor capability questions.

\$\endgroup\$
  • \$\begingroup\$ +1, funny (not really) part is that when you compile the code for production, without various debug hooks, the timing will change again. \$\endgroup\$ – Ale..chenski Jul 2 '18 at 1:55
  • \$\begingroup\$ @AliChen Well I've not worked with the Amtel simulation tools, but I can tell you that on other platforms (notably some of the microchip MCUs), the simulation lets you accurately predict execution between any two points. In the early days when built in UARTs cost a bit, I'd successfully designed several serial "bit bangers" that way, and I'd imagine such tools would be good enough for the OP, IF he had those tools, and maintained full control of the code. For his situation, I'd do it the way i suggested. \$\endgroup\$ – Randy Jul 2 '18 at 3:51
  • \$\begingroup\$ Thanks also for your information Randy. I didn't have the words so I just generated a single case where it was clear enough to get the information :). As for my actual needs. You Could build a more complex case where your running multiply servos at much higher than 100Hz refresh. I was thinking about how I would synchronize some external process like a servo or group of servos with internal CPU Decision tree. Obviously The complexity of decision tree can grow very quickly. But with no measure of clock cycles relative to code I had no Idea what to do. \$\endgroup\$ – Rob Jul 2 '18 at 5:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.