20

I have been working on an eBike control project on the Arduino MEGA2560. The program runs 3x PID control loops, one battery capacity control loop (interpolation based on lookup tables), a speedometer (samples based on a reed switch) as well as an LCD screen to display information. Its inputs are 3 analog signals: battery voltage, current and user throttle input as well as a digital input: speedometer (reed switch) on/off signal. Currently, with all this running on "long" arithmetic the Arduino manages to complete 10 loops per second. As the TFT LCD screen takes tremendous amounts of computational power, I am thinking of replacing it with an Alphanumeric screen.

The outputs consist of an analog throttle signal going to a motor controller, the LCD screen and potentially a few other devices requiring analog signals. Thus, ADC converters are essential and DAC would be very useful although I am currently using the Arduino PWM output with an RC low pass filter. Similarly, the capacity to read digital and analog signals without interrupting the processor would be great.

I would like to potentially make a consumer product out of this, hence I want to build my own platform from the ground up with a different microcontroller that could give me at least 100 samples per second (10 times what the Arduino is achieving). Also, to avoid floating points, my calculations use long variables and consequently numbers larger than 16 bits, so I'm assuming a 32bit MCU would be a good idea. Also, a MCU able to do floating point calculations could be interesting to simplify the maths in the code.

In the end I am not sure how to start looking for MCUs that would satisfy these requirements and allow a swift transition from the Arduino environment. Any guidance on how to go about finding such MCUs would be greatly appreciated!

psmears
  • 678
  • 4
  • 6
Eliott W
  • 629
  • 7
  • 19
  • Uh oh. This website does not like questions that ask to recommend parts. – Bradman175 Oct 21 '16 at 12:10
  • 1
    I don't necessarily want to be recommended parts but just a method or platform or any guidance on how to find the platform I need. – Eliott W Oct 21 '16 at 12:11
  • 5
    This is much better than your previous question, but it is still very broad, and some points in your requirements are not clear. For example, what do you mean, "without interrupting the processor"? I'm guessing that you don't really want to do polled I/O, either. You also need to get a better handle on exactly how much computing needs to be done on each set of samples. – Dave Tweed Oct 21 '16 at 12:15
  • 1
    You should consider using integer math. It's the right thing to do. – Scott Seidman Oct 21 '16 at 12:54
  • 4
    related: [How to choose a MCU platform?](http://electronics.stackexchange.com/a/37435/7036) – Nick Alexeev Oct 21 '16 at 13:04
  • @ScottSeidman is long math much different from integer math? Because for the accuracy I would like, I need numbers that are to big to be integers. – Eliott W Oct 21 '16 at 14:16
  • 4
    Integer math, long or short, is much faster than floating point; and integer math that is longer than the "native" bit depth of the processor will also be slow. So 32-bit sounds like a very good idea, maybe one of the "DSP" type devices. – pjc50 Oct 21 '16 at 14:46
  • @EliottW -- you have no coprocessor to do double precision floats, even if you move to an STM32f4. Keep in mind that regardless of best intentions, your ADC inputs and any DAC outputs have integer precision. You could make yourself room by using 32 or 64 bit integers and shifting to the left, leaving plenty of LSBs to work with. In other words, shift the representation to, say, 1/128th's of an ADC LSB. Then, do your integer math in such a way as to not multiply round off errors -- i.e., all your multiplies first, followed by integer divides. – Scott Seidman Oct 21 '16 at 16:37
  • Er… wait. Do you, or do you not, plan on using floating-point arithmetic? You make statements suggesting both. –  Oct 21 '16 at 17:21
  • I will use integer arithmetic in the end. I already change my code to include the round errors by timin git to higher values. – Eliott W Oct 21 '16 at 17:33
  • @duskwuff -- no floats. – Scott Seidman Oct 21 '16 at 17:41
  • While some people do, most people don't generally pick some random micro because they think it might meet some specs. Usually, you use what you know as a baseline, perhaps do some timing captures and if what you know doesn't meet requirements you branch out to micros that are similar to what you know but will meet the specs. So look at all the variations of micros that you know, if none of those work then read up on what others suggest as alternatives. The closer you get to something that you already have numbers for the easier it is to guesstimate the other device's performance. – Dunk Oct 21 '16 at 18:22
  • As a specific suggestion, if you're comfortable with Arduino, why change? Just stick with an Atmel AVR. – chrylis -cautiouslyoptimistic- Oct 21 '16 at 20:47
  • I do wonder what kind of calculations you're doing that you're only getting 10 samples/second. I get the feeling you should be able to optimize the software to get better performance. – marcelm Oct 23 '16 at 09:34
  • The TFT LCD screen was taking most of the computational power. I replaced it with an alphanumeric LCD which gives me a bit more than twice the sample rate. Without any screen, the code gets up to 100Hz... – Eliott W Oct 24 '16 at 11:11
  • Thought so. Think about updating the screen less often, and doing all time-critical stuff in an interrupt routine and you can easily go 10 times higher. Honestly, I thought about your project and think I could fit it in a AT**tiny**88 (with the HD44780 based screen). – Janka Oct 26 '16 at 21:35

6 Answers6

18

(This is a generic guide. I suspect you could also benefit from code optimisation, but that's outside the scope of this website.)

Step 1: Rough sizing, budget, vendor

Pick one of:

  • Computer (Raspberry Pi, Beagleboard, PC104 board, Intel Edison, etc). Boots a general-purpose operating system and has lots of processing power. More expensive and power-hungry. $10-$100.

  • Large MCU. ARM Cortex-A / PIC32 / dsPIC / AVR32 / TI C series DSP etc. Decent computing power, OS optional. ~$5.

  • Small MCU. Cortex-M / PIC16. Not really enough space for a true OS, maybe just a lightweight task scheduler. ~$2.

  • Tiny MCU. Only really for applications where you care about every last microamp of power consumption. ~$1 or less.

You should also consider at this stage which vendors and toolchains you like and dislike. Have a look at the cost of things like in-circuit debugging devices and IDEs.

Step 2: Minimum Peripherals

Do you need things like USB? PCI? HDMI? SATA? Unusually fast ADCs or DACs? Almost all of the "small" or "tiny" category do not have these, although USB is fairly widely available.

Step 3: Prototype

Pick something which meets the above criteria, at random if necessary, make a start, find out how feasible it is and how much space / processing power you need. You've already done some of this. Writing in C should make much of the logic portable.

Once you have the prototype you can say to yourself, "I need one like this, but with more X" and let that guide your decisions.

Step 4: Shrink

It's generally easier to start with the largest (most Flash and RAM) member of a CPU family, write v1 of your application, and then choose a smaller, cheaper one to fit. You can also spend time on the art of fitting software into fewer resources. What's worthwhile depends on how many units you're going to make.

pjc50
  • 46,540
  • 4
  • 64
  • 126
  • 14
    [**Step 0: Tool chain (firmware development environment).**](http://electronics.stackexchange.com/a/37435/7036) Find development environment(s) which you can make work for you. This is where it's won or lost. Even if you have silicon that's perfect fit, but you can't make the firmware development environment work (for any reason), then your project will not get off the ground. (Case in point: the Arduino IDE has got your Arduino-based prototype off the ground.) – Nick Alexeev Oct 21 '16 at 17:06
  • 8
    Categorizing Cortex-M as a "Small MCU", and PIC32/AVR32 as "Large MCU"s seems a bit unfortunate. I haven't used PIC32/AVR32, personally, but based on a quick glance the range of specs, I'd say they should all be in the same bracket. (There are Cortex-M MCUs which run at >200MHz, have many megabytes of flash and more than half a megabyte of RAM) – Aleksi Torhamo Oct 21 '16 at 22:01
13

Nice project. Here are a few hints, but it would be difficult to generalize this for every project, though.

Start with the computational requirements

This is what will tell you what kind of core you need and the general performances of the MCU. I suggest you start with this, since it obviously can't be extended using external components, unlike peripherals.

First, it seems you use heavy mathematical operations with large integers within the loop. So, as you suggested, 32 bit would be useful here, so ARM therefore comes as an ideal candidate. As for the frequency of operation: currently, you're using an Arduino MEGA2560 (running at 16MHz, I assume) and you can make 10 loops/s. If you want to achieve 100 loops/s, you should be fine with a Cortex-M3/M4 in the range of 100MHz or more (rough estimation). Note that the Cortex-M4F has a floating point unit.

We already narrowed down the selection.

Memory requirements

This one is easy: choose the MCU which has the most RAM/Flash of its range for the prototype. Once you validates the prototype, switch to the MCU from the same range that has just enough RAM/Flash, now that you know your exact requirements.

Note that I don't think your application needs amazing amounts of memory.

Now, the peripherals

You absolutely need some ADC. All MCUs of the range we are looking at have some, so it's not a useful criteria. Neither are digital input/outputs, except if you need a very large number of them (which doesn't seem to be your case).

You seem to need a DAC. However, this is something you won't actually find easily and will narrow down the candidates too much. So we don't keep that requirement and we'll stay with a PWM and lowpass (which is certainly acceptable, actually).

You don't mention any communication interface, except the LCD (later on that). Anyway, all MCUs have I2C/SPI/UART/... if you need some.

The LCD

This one is trickier, because there are a lot of different solutions that puts completely different requirements on the MCU. But don't choose the LCD depending on the MCU. Choose the LCD you want for your product and then select the MCU that will drive it efficiently.

  • If you want a character LCD: then the easiest and the least constraining for the MCU is to talk with it through some serial interface (often SPI). This way it won't use too much PINs, you can use smaller/cheaper MCUs and speed is not an issue.
  • If you want a graphic TFT LCD: if it's a small one, the serial link can still be appropriate. However, for 320x200 or larger and if you want to have a nice graphical interface, you'll start wanting to communicate with parallel interface. In this case, either you use some GPIO (but that will put more load on the MCU because you'll have to bit bang the control lines) or you choose a MCU that has a dedicated LCD interface (which is often the same as an external memory interface). This last one puts a strong constraint of the MCU choice, but you don't have other strong constraints, so...

Now, you choose

Go to ST Micro / NXP / Atmel website and use their MCU selection tools. You'll spend lots of time reading datasheets, too. Take this time. It's not wasted. Anything you'll learn here, even if you don't use it specifically for this project, can be useful.

At this point, you also need to have a look at the number of PINs you'll actually need and check the multiplexing scheme of the chosen MCU candidates to verify you can use all the PINs functions you need. Because obviously, you'll want to take the MCUs with the lowest number of pins that fulfills your requirements (for cost/PCB real estate reasons).

Check the prices/availability on Mouser/Digikey. But you shouldn't need something particularily expensive here. Maybe 5€ or so.

Last thing regarding the LCD control

It seems the update of the LCD is part of your main loop. It shouldn't. Especially if you're looping 100 times a second, it's useless. Make the control loop compute everything and adjust the motor command on each iteration, but just update the values to display somewhere in memory. Then, have another loop with lower priority display this information to the user when there's nothing more important to do.

Yeah, ideally, it requires some task switching and stuff. A real OS, actually (lookup FreeRTOS, Coocox OS, Nuttx, ... those are very small, are largely used on Cortex-M, and provide the required multitasking mechanisms).

dim
  • 15,845
  • 3
  • 39
  • 84
  • Thank you very much for your comprehensive answer! I am noticing that the ARM Cortex MCUs all function on 3.3V. My throttle signal needs to scale between 1 and 5V. I'm guessing that if I want to use an ARM controller I'll have to find a way to step-up the voltage as it will be capped at 3.3V from the MCU? – Eliott W Oct 21 '16 at 15:53
  • Yes. The throttle signal is the analog output, right? In that case you could use an opamp to amplify it. – dim Oct 21 '16 at 16:39
  • I'm not sure I agree with the last sentence about requiring "a real OS". I suppose it depends on how much in terms of ready-made solutions you want. If you want something where you can just drop in your business logic and start banging out units, yes, a full-blown OS (note that this doesn't have to mean something like Windows or even Linux!) is certainly useful. – user Oct 26 '16 at 14:34
  • If you want something that can run in less resources, it's not *that* difficult to put together a cooperatively multitasking executive that can run in far less computing resources than anything resembling a modern general-purpose OS. For an example of this, take a look at the Apollo guidance computer and its executive. Some of the design choices there -- particularly, some of the deciding what *not* to include! -- could bring down the implementation complexity quite a bit. I wouldn't be surprised if something like that could be banged out in a few days, when the requirements are known. – user Oct 26 '16 at 14:35
  • 1
    @MichaelKjörling of course, I didn't meant something even remotely like Linux. But rather something like FreeRTOS, Coocox OS, or Nuttx, for example. These are what I consider *real* OS, although very small. I wrote that because indeed, doing this on bare-metal will take more time, be a pain to debug and be less flexible. And the Arduino environment (although I am far from an expert on this) does not seem to provide tasking mechanisms (and, as such, I don't consider it as a *real* OS). – dim Oct 26 '16 at 14:43
  • 1
    Ah. Well, I misread the "real" part, then. Just for the benefit of us outlanders who occasionally end up over here, you may want to consider clarifying that part in your answer. – user Oct 26 '16 at 14:49
4

Note that this is a broad subject which can be answered correctly using multiple (subjective) approaches.

Also, stackexchange format is not good at designing solutions for problems. For example, you seldom get people to design hardware for you. Rather you propose a hardware design and ask questions about it.

That said...

Start with features of the processor you can not change. Such as speed and memory (if applicable) size. Investigate if you need interrupts and how complex the interrupt handling needs to be.

If you need peripheral support such as ADCs or DACs, the situation is more complex. Should these features be built into the processor or be external from the processor. Price, accuracy and even noise are factors in this decision.

If external peripherals are to be supported consider the type of serial communications which are necessary. External hardware may need SPI, I2C or other type of UART. If the data rate is high it might be best to find a processor with DMA features associated with its serial communication ports.

Finally, if this is an embedded processor application (which normally means a processor dedicated to a task), consider breaking down the requirements into several groups and assigning a processor to each. For example, a GUI display processor likely does not need an ADC feature. This objective approach to solving problems has proven successful in software and with dropping processor prices can also be applied to hardware.

In the real world, this approach is iterative. That is, many projects start with one processor and swap out different processors as hardware and / or software problems occur or the scope of the project changes.

st2000
  • 3,228
  • 9
  • 12
  • You are a better judge of what type of numbers to expect than the compiler. I would avoid the generic approach of using floats. For example, it may be that float results are not the same across different platforms! I would use integer arithmetic and tailor the solution to your needs. – st2000 Oct 21 '16 at 13:03
3

I didn't see anyone mention cost of tools. My company choose a TI CC2541 and found out it only compiled with a $4k IAR compiler, definitely a show stopper for a hobbyist. Also the programmer. It can be a $20 or much more. Cheaper tools seem more the norm now, so maybe this will be a thing of the past soon.

Also, if you reflow it yourself, packages like TQFP are easier than, say, BGA. A large BGA is hard to get right, based on personal experience.

Bill
  • 2,496
  • 4
  • 25
  • 36
2

If the product is relatively price-sensitive and you have decent development funding, you can procure a bunch of evaluation boards and profile the code on each to get an idea. That should be fairly straightforward if your code is written in portable C. Aside from the micro you will be evaluating the toolchains with demo versions before shelling out the cost of a full-blown IDE such as IAR or Keil. In some cases you can profile the bottleneck code directly on the IDE without hardware.

If you are tightly constrained on development cost, you may have to compromise to find something that doesn't cost too much for the development setup.

For example, ST has an ARM Cortex M7 eval board with a nice color display for < $100. It has an FPU with DSP features so you could do anything you talked about easily- probably run a PID loop at 100kHZ rather than just 100Hz. It is probably overkill unless that display is a priority.

If you are aiming for a cheaper processor without FPU then you will probably want to profile the PID code in its finished form. Make sure all the scaling and linearization and calibration factors are included, as they can add up in terms of processing time.

Often the peripherals and the associated middleware quality and availabilty (and licensing terms) will strongly influence your choice. If you need BT or Wifi or USB host mode and FAT files to store on a thumb drive, or a fast SD interface these will all be important factors. Some chips have an on-board LCD controller and digitizer controller that can allow the use of a relatively inexpensive TFT panel. Don't overlook the sometimes high licensing fees.

If you have some idea of the program memory required, processing speed and peripherals (include FPU in this) you can do a parametric search at distributor before drilling down into the datasheets. Some things that are too constraining might be - through-hole package, internal DAC, internal Ethernet PHY, FPU. None of these are likely necessary and they may unduly constrain your choices prematurely.

Good luck with it, it's a lot of work to do this properly. In my experience it's a false economy to cut it too close on a new product because the customer(s) will inevitably ask for things you didn't anticipate and you want to have some spare capacity to supply that without starting over. On the other hand, if the product is too expensive you won't be able to sell enough at adequate margins to sustain the business.

Spehro Pefhany
  • 376,485
  • 21
  • 320
  • 842
1

There are multiple different platforms you can start looking at like Arduinos, PIC microcontrollers, FPGAs, and much more. I worked with Arduinos in the past and it has an ADC port capable of achieving 74kS/s. 100 samples per second is extremely slow and I am wondering how you found that out? In the other hand, you want to ask yourself if you will need any kind of interfaces such as SPI, CAN, I2C, or UARTs. They all can have their own benefits and it is for yourself to consider if you will be talking to one or more slaves. The last but probably most important step would be to guess how many pins on the microcontroller you will need to use.

"The capacity to read analog to digital signals without interrupting the processor would be great." I can take a wild guess by saying that you do not want to deal with external or internal buffers that will circulate your data and potentially slow down your data processing. Is that right? If so, that is more programming for you to do but processors are usually capable of handling the speed of 100 samples per second. It will be up to you to program the clock, sampling rate, and the rest.

Also, consider interrupts in your program if you want to keep sampling data continuously and perform other task when a flag is raised.

12Lappie
  • 1,401
  • 1
  • 11
  • 22
  • 2
    I think you've missed the point. He has a prototype built on an Arduino. The sampling isn't slow. The control loops ARE slow. He's got three PID controllers being calculated using floating point on the Arduino, so they are slower than molasses in an antarctic winter. So, sampling isn't the problem. Inefficient code is. – JRE Oct 21 '16 at 12:54
  • You're right about that. – 12Lappie Oct 21 '16 at 13:11
  • Yes, the problem is that although my loops are in long arithmetics and not floating points, there are so many calculations to be done that as the Arduino takes a sample once per loop, my sample rate is very small (currently 20 samples per second). – Eliott W Oct 21 '16 at 14:22