Caught up between a rock (Arduino) and a hard (ARM) place. - Page 1
Forum section: electronics / general

author: CM800
author_rank: Frequent Contributor
timestamp: July 23, 2015, 07:22:01 pm
content: Hi All,For a while now I have been wanting to progress myself beyond Arduino and begin to learn more about microcontrollers and become more capable, I need to home my skills.Problem is, I know Arduino and I feel I keep diving off into the deep end, I have spent quite a bit of money on devkits for microcontrollers I think may be too complex for me.Now, I have stepped back a bit and I want to start again into microcontrollers, I feel Arduino has just kinda messed it up, making it too simple to the point I feel lazy not understanding or doing anything beyond simple Arduino 'stuff'.I want to try get into protocols, timing and so on, controlling Switching systems (Transformer drivers) and communications and busses, get involved with motor drivers and all sorts.The real question I have... Where should I truly start and how? Tutorials etc. I have been kidding myself into thinking 'I know all this' for too long. When I don't really.What I have already:TI Launchpad Tiva C Series.A Huge pile of Arduino products (Nanos, Megas and Unos)Cypress CY8CKIT (the USB stick one)Freescale FRDM-KL43ZSAM4S-EK2 Dev BoardWhat would you recommend I get or start with (I don't mind buying more if it is worth while...)What tutorials can I look at.I really appreciate any response or advice, feedback or thoughts!

author: chicken
author_rank: Frequent Contributor
timestamp: July 23, 2015, 07:35:12 pm
content: You could reuse the Tiva-C and take this embedded systems course on edX:https://www.edx.org/course/embedded-systems-shape-world-utaustinx-ut-6-02xThe course was discussed in detail on a recent embedded.fm podcast:http://embedded.fm/episodes/107EDIT: Never mind, course enrollment is closed for now

author: westfw
author_rank: Super Contributor
timestamp: July 24, 2015, 01:10:40 am
content: One of the "annoying" things you may notice is that TI, Cypress, Freescale, and Atmel ARM boards will all want you to use their own special libraries that will "make things easier" and probably hide the same things that the Arduino is hiding from you. (Just not as successfully. And all different from one another. Sigh.)The UT online class would be a good starting point, if it's offered again. It was a really good intro.Depending on how much you don't know, one useful idea is to translate some of the Arduino projects you have done (or have become familiar with) intro code that is NOT dependent on the Arduino framework. Go ahead and read the Arduino source code, or figure out how to do each thing that an Arduino library has done without using their code. Use the other vendor code, or don't (both are useful exercises.)

author: Mr.B
author_rank: Unknown
timestamp: July 24, 2015, 01:25:23 am
content: Quote from: westfw on July 24, 2015, 01:10:40 amI agree.That is basically what I did to move to the next phase.I am using Atmel Studio for the majority of my work.I still buy arduino pro mini clones to use as cheap quick project boards, but use Atmel Studio andnotthe arduino framework, bootloader and IDE.

author: ralphd
author_rank: Frequent Contributor
timestamp: July 24, 2015, 01:38:35 am
content: I'd look at programming the AVRs with the Atmel toolchain (avr-gcc/avr-libc). AVRs are much simpler than ARM MCUs. As Bill said different ARM vendors will have you use their custom libs, while in comparison its much easier to write AVR code that directly manipulates the registers.If you want to do protocols, then I recommend learning assembler. You can't bit-bang a high speed protocol like a UART in C.

author: rs20
author_rank: Super Contributor
timestamp: July 24, 2015, 01:41:31 am
content: Download the Atmel Studio, get yourself a JTAGICE3 (or preferably, a cheap clone), and start programming your Arduino that way using the 2x3 header on the Arduino itself. At that point, you're not "doing Arduino" per se, you're programming an ATMega328P.Or even better, just stay with the Arduino IDE, but wean yourself off the Arduino libraries and try coding things directly, referring directly to the ATMega328P datasheet. For example:-- Replace digitalWrite and digitalRead with direct manipulation of the DDRx, PINx, and PORTx registers.-- Replace analogWrite with direction manipulation of the timer/counter registers-- Replace Serial.begin and friends with direction manipulation of the UART registersOnce you've done that, you'll have pure, bare metal ATMega328P source code that is not Arduino in any sense of the word, and ready for direct use in gcc-avr or Atmel Studio.I'm not advocating coding like this for the rest of your life; libraries are useful and time-saving and they exist for a reason! (Having said that, digitalWrite ishorrendouslybloated for something that should take a single clock cycle.) But by changing things one feature at a time, you'll never be too far out of your depth, and by the time you've converted your code to being purely register-based, you'll be confident at tackling the other preipherals (SPI, ADC, etc), and you'll be far more confident that you can tackle any other reasonably simple MCU.If you get stuck interpreting the ATMega328P datasheet, ask us.

author: Muxr
author_rank: Super Contributor
timestamp: July 24, 2015, 02:11:06 am
content: You need a purpose in order to really learn. I mean sure some things you can learn by just tinkering or reading about it, but real learning comes from doing and accomplishing goals, learning from the mistakes you make.Decide on a project you want to do, find out what tools are needed and how you want to go about accomplishing that project. Learn the tools by doing.No one can tell you what that project should be. What I can tell you is that you will hit obstacles, so picking the right project which will keep you motivated to keep going is half the battle.

author: ralphd
author_rank: Frequent Contributor
timestamp: July 24, 2015, 03:04:55 am
content: Quote from: rs20 on July 24, 2015, 01:41:31 amWith Wiring (which Arduino is based on), digitalWrite(13,HIGH) compiles to a single sbi instruction (which is 2 clock cycles).http://wiring.org.co

author: rs20
author_rank: Super Contributor
timestamp: July 24, 2015, 03:41:03 am
content: Quote from: ralphd on July 24, 2015, 03:04:55 amSince when? I've fixed many a slow bit-banging sketch in the past by getting rid of digitalWrite. Does that optimization fail with a dynamically determined output value (e.g. digitalWrite(13, bitOut)??

author: FreddyVictor
author_rank: Regular Contributor
timestamp: July 24, 2015, 06:32:45 am
content: Quote from: TCWilliamson on July 23, 2015, 07:22:01 pmthis is my main gripe with arduino....how about trying to program the arduino as an ATmega chip instead ?all info you need regarding hardware registers/modules is in thedatasheetthis is a small jump rather than the giant leap into ARM which I fear will be too greatyou just need a programmer. The AVR ISP MkII was the std one to use but is now OOP, replaced by theICE, but cheaper alternatives are availableas per rs20 !

author: CM800
author_rank: Frequent Contributor
timestamp: July 24, 2015, 06:50:06 am
content: Huge thanks to all of you for your responses.I will take a look at programming the Arduinos 'manually'Is this what I need to get for it?http://uk.farnell.com/atmel/atatmel-ice-basic/debugger-atmel-arm-avr-basic-kit/dp/2407172?MER=en-mer-0713-pd-r2-acce

author: Chris C
author_rank: Frequent Contributor
timestamp: July 24, 2015, 08:20:54 am
content: , I have not worked with Arduino. But as I understand it, it works as a Hardware Abstraction Layer (HAL) that hides the complexity of the hardware, and differences between platforms.One way you might approach this is by starting to write your own HAL. You might even choose to start this on the Arduino. That offers the advantage of being a familiar platform to you, and allows you to gradually replace Arduino calls with calls to your own HAL.Start with plain old digital I/O. As you write this, you'll obviously learn how to directly access the AVR's digital I/O registers. But perhaps more importantly, you'll learn more about some general coding practices, that the Arduino experience might have deprived you of.For example, even though I haven't used an Arduino, I know that:Quote from: ralphd on July 24, 2015, 03:04:55 amThis type of optimization is only possible when the pin number is a constant (at very least). In this example, the address of the hardware register, bit position within the register, and value are all known at compile time; therefore the compiler has the opportunity to condense it to a single instruction.Otherwise, the digitalWrite function is called, which even I know is notoriously slow. So is the one in my HAL. Every time it's called, it must:1) Check that the pin number is within the valid range of physical pins, and that the pin supports digital I/O.2) Convert the pin number to both a register address and bit number within the address.3) Modify the bit.It's #1 and #2 that consume most of the time! In the process of writing my HAL, I realized that there was a better way. (Which oddly, I have never seen reference to being used on the Arduino.)Assume one wants to write a digital pin, which is not a constant, and so cannot be optimized at compile time. But that pin will typically be written repeatedly, and that's where the slowness of a function like digitalWrite really hurts; because it has to check and convert that pin repeatedly, when that isn't really necessary. So instead, when we know we're going to be writing a pin repeatedly, we could do something like this:1) Define a structure in the HAL (FASTPIN) that will store the register address and bit number.2) Create a function in the HAL (FastPinInit) that when passed an instance of the structure and a pin number, checks the pin for validity, converts the pin to register address and bit number, and stores this in the structure.3) Create macros that when passed the initialized structure, will set (FastPinSet), clear (FastPinClear), or toggle (FastPinToggle) the pin based on the info stored in the structure.And in your code:1) Create an instance of FASTPIN.2) Initialize it by calling FastPinInit.3) Repeatedly write it by calling FastPinSet, FastPinClear, or FastPinToggle.Which accelerates writing the pin greatly! It's not as fast as a single instruction, obviously; but still an order of magnitude of faster than calling digitalWrite.Assume you've implemented something like this on the Arduino, that handles both writes and reads. As well as some bit-banged (software) I2C and SPI routines, that use your FastPin implementation.Later you want to convert it to ARM. Digital I/O is a little different there, but not much. You might need to change what information is stored in FASTPIN, but that's no big deal, you only need to change the structure definition in one place; all your code that uses FASTPIN will use the new definition. Then rewrite FastPinInit, and the FastPin* macros, and...Voila. In a few hours, you have reasonably fast digital I/O on ARM. As well as I2C and SPI, on any pin. Eventually you may implement hardware I2C and SPI, perhaps even driven by DMA. But you might not need that level of performance right away, so you can do that later - when needed, or at your leisure. This helps make moving to a new platform faster and less intimidating.(I took that concept even further in my own HAL. Once I get a single timer, its associated interrupt, and a few other things working on the new platform, I use it to drive a C state engine that functions as a scheduler. This lets me simulate additional timers, PWMs, and other "virtual" peripherals. Not high performance by any means, but it gets me up and running on new platforms really fast. After just a week on PIC32 I have all this running, and can port useful code to it; I'm just taking some time to learn and tweak before moving on to gradually implementing the real peripherals. Of course, writing the original scheduler was difficult, but at least for me, it was fun. You need not take things this far!)Sorry for the length of this post, but I think it demonstrates how writing your own HAL can be both educational and useful.

author: picandmix
author_rank: Frequent Contributor
timestamp: July 24, 2015, 09:05:38 am
content: Quote from: TCWilliamson on July 24, 2015, 06:50:06 amThink you will find one of these £5 programmers will do a lot of chips you have, use one myself.http://www.ebay.co.uk/itm/USBASP-USB-ISP-Programmer-10-Pin-ISP-interface-Cable-AVR-ATMEL-ATMega-/171863554646?pt=LH_DefaultDomain_3&hash=item2803ddba56Sure you could readily sell and unwanted dev boards on this forum or ebay/preloved.While every one has talked about other high level options for you to program with, don't forget there is also Assembly code which really takes you much deeper into the hardware; its main drawback is, though possible, its not really suited to complex code used in high end code like USB ,Can etc.

author: FreddyVictor
author_rank: Regular Contributor
timestamp: July 24, 2015, 09:20:22 am
content: Quote from: TCWilliamson on July 24, 2015, 06:50:06 amyes, thats the official programmer (it also will do PDI programming if you should want to play with ATXmegas).TBH, it's a bit pricey, others have had success with the cheap USBASP programmers such asthesemake sure you get a 10pin->6pin adaptor tho' such as the one shown inthis picnb: I have an AVR ISP MkII so havn't tried these other options, others should be able to help on this forum

author: Yansi
author_rank: Super Contributor
timestamp: July 24, 2015, 09:29:43 am
content: ...glad that at least someone woke up and wrote"I feel Arduino has just kinda messed it up, making it too simple to the point I feel lazy not understanding or doing anything beyond simple Arduino 'stuff'."'d be nice if more people would come to the same conclusion.Thumbs up for your decision, keep the good work man!

author: rs20
author_rank: Super Contributor
timestamp: July 24, 2015, 09:31:12 am
content: Quote from: Yansi on July 24, 2015, 09:29:43 am+1, well put. I was trying to say the same thing, but couldn't put it into words.

author: westfw
author_rank: Super Contributor
timestamp: July 24, 2015, 09:33:49 am
content: QuoteThat's the one to get, if you get anything. Unlike the earlier models (the jtagICE3 that someone mentioned), the newer Atmel ICE will program and debug Atmel ARM *and* AVR chips. The cheap USBASP type programmers won't do debugging either.The cheapest route to AVR debugging would probably involve an "ATmega328 Xplained Mini" board, which is sort-of Arduino compatible, about $10, and includes a debugging interface... (Your TI and Freescale boards already have debugging support as well.) TI is supposed by the Arduino-like "Energia", so a similar learning progression should be possible. But it IS a much more complex chip than the AVR.But you don't "need" to get it; you can load bare-C applications onto the Arduino using the arduino bootloader just fine. (you won't have debugging, though.)As for DigitlaWrite() on Wiring vs Arduino, the original Wiring and Arduino code have the "slow" implementation that permits variable and abstract pin numbers and values. Later, the original wiring author jumped back on the bandwagon with his own newer version of "Wiring" that has the "improved" digitalWrite(). (it hasn't gained a lot of users, as far as I can tell.) Faster "smart" digitalWrite() implementations have been written several different ways, but the Arduino powers aren't particularly interested. For one thing, it wouldn't be a great thing for slightly different calls to digitalWrite() to have 20 or 30 to 1 performance variations.Understanding and re-writing digitalWrite() in various ways would be one of the exercises you should do in your quest for deeper knowledge...

author: poorchava
author_rank: Super Contributor
timestamp: July 24, 2015, 10:08:46 am
content: Other than ARM, PIC microcontrollers (despite being shit in general) give you a possibility to debug the code with genuine Microchip tool that costs like $40. Obviously ARM debug tools are cheaper.BTW, stating that ARM microcontrollers are complex is bizarre. It'a not hard.-get IDE that supports chosen chip-create new project. In almost every case the IDE will create the startup script, linker script and such automatically.-start writing codein order to use a peripheral just enable the peripheral clock (otherwise it won't answer or will produce a system fault of some sort) and write values to the registers.To check what to write where and in what order just read the datasheet (or other reference manual there is for peripherals) same as you would do programming any other microcontroller.That's it.Stuff like interrupts is common to all ARM microcontrollers, as it is built into the core itself.

author: ralphd
author_rank: Frequent Contributor
timestamp: July 24, 2015, 01:14:26 pm
content: Here's the detaila on the speed of digitalWrite in Wiring (good) vs. Arduino (bad):http://nerdralph.blogspot.ca/2014/04/a-better-digitalwrite-for-arduino.html

author: Yansi
author_rank: Super Contributor
timestamp: July 24, 2015, 02:10:56 pm
content: Shouldn't it be better to learn how to use the GPIO registers directly, instead of using any of these higly limited bullshitware functions? (The same applies for most ARM vendor libraries...)

author: tech5940
author_rank: Unknown
timestamp: July 24, 2015, 02:52:17 pm
content: To the OP,I was in a similar situation as you. I was happy with Arduino's ease of use and the available pre made library's. It was a great introduction into what can be done with microcontrollers but I just knew there was so much I was missing and it really shouldn't be this simple to plug this board into another board and upload a "sketch" and just have it all work. The first thing I did was order some bare ATMEGA328P chips and wire them up like an Arduino by hand, and then learn to burn the Arduino's boot loader to the blank chip. I moved on from there and would make projects that still used the Arduino framework but I would put the ATMEGA328P in the project and only wire up what was needed. I was still left with the feeling that there is way more to all this that I don't yet understand..So my approach was to completely separate from ATMEL and give PIC microchip's a try. I'm not saying this is the correct approach for you but it's what I chose. This isn't an attempt at starting a PIC/ATMEL war either, my reasoning was along the lines of wanting to completely separate from Arduino/Atmel and learn from scratch. I was worried if I chose to stay with ATMEL that I would be constantly crossing paths with the "Arduino" way of programming which may have been hard to separate and cause confusion.So I purchased a PicKit3, a selection of midrange pic microcontrollers, downloaded MPLAB X IDE and the XC8 compiler. I picked the cheapest micro I had purchased, downloaded its Data sheet and got to work trying to figure out how to make a LED flash. I quickly learned that YES there was lots going on behind the scenes with Arduino that was hidden from its user, and that just getting a simple LED to flash from scratch was much more involved. I stuck with using C code and that is where some of my experience with Arduino helped out.One thing I came across that helped me tremendously (aside from the EEVBlog) was a website with two free books (if you view them online). It is based on PIC micro's and just seemed to explain everything in a very visual way which is how I learn. It might not be for everyone, but here are the links if your interested. The creator of the book has his/her? own PIC micro compiler software for sale, I didn't use that and just skipped over the part in the book specific to that compiler. The rest of it was great and useful information.http://www.mikroe.com/chapters/view/14/chapter-1-world-of-microcontrollers/http://www.mikroe.com/chapters/view/1/introduction-world-of-microcontrollers/MPLAB X can be a bit intimidating at first but keep with it, and try and keep things simple to start. It has many features that will help you configure the chip and it's functions which may be of use later but to start I'd recommend a blank main.c file with Datasheet in hand and get to work with simple tasks like flashing a LED. Once you have got that to work then you need to decide on projects, what do you want the micro to do for you and from there you will be forced to learn what is needed while at the same time having a goal so you don't give up on it.The path you choose is up to you, and I'm really not partial to PIC, however I am glad that I decided to do things the "Hard" way and really learn what's going on behind the scene's. Even though I'm still using a compiler and C code (rather then machine code) I feel what your still close enough the the internals of the micro to get an idea of what is actually going on.If I could tell you only a few things they would be:Registers, Registers, Registers! Data sheets are your friends learn how to read them and understand them. Learn the difference / relation to Binary, Hex, and Decimal numbers.I'm not sure on the OP's background so if some of this advice is a bit to simplistic I apologize. I just wanted to share the route I took from zero experience with digital electronics and what helped me learn along the way. The website I linked to above I have no affiliation with, and I shouldn't discount the vast resources that the EEVBlog itself has to provide. Dave's video's have been extremely helpful, and this forum was frequently in the top of the list when searching online for help. Truth be told if it wasn't for the EEVBlog I'm not sure id even know what a Microcontroller is.Good luck,

author: ralphd
author_rank: Frequent Contributor
timestamp: July 25, 2015, 01:01:11 am
content: Quote from: westfw on July 24, 2015, 09:33:49 amI don't seem to get your point (or how you come up with 20:1).digitalWrite() in Arduino is ~50 clock cycles.digitalWrite(13,HIGH) in Wiring is 2 clock cycles.digitalWrite(13,stateVar) in Wiring is 5/6 clock cycles.digitalWrite(pinVar,stateVar) in Wiring I expect avr-gcc would use a jumptable and compile to ~15 clock cycles. I've never seen such bad code in any Arduino libraries anyway, so it's more of a moot point.So in real world code, you'll see a 5:2 variation in performance for Wiring's digitalWrite(), and it is an order of magnitude faster. Can you give an example of where Arduino's predictably slow digitalWrite would be preferred?And if consistently fast digitalWrite is what you need, with some inline assembler you could make a digitalWrite that for both constant and variable pin state compiles to 4 instructions/5 cycles:Code:sbrs stateVar, 0cbi PORTMACRO, PINMACROsbrc stateVar, 0sbi PORTMACRO, PINMACRO

author: Chris C
author_rank: Frequent Contributor
timestamp: July 25, 2015, 01:11:06 am
content: Also helpful might be some mention of primitive debugging methods. Without an initial framework to support you, you might initially lack serial and USB. Depending on the hardware/software used to program the MCU, you might even lack in-circuit debugging. Or perhaps any of those methods are too intrusive for what you want to test, skewing the test results.So at some point, you may find that all you can do to diagnose your code is something simple, like toggling a pin. In which case a digital storage oscilloscope would be handy to read the results, but maybe you don't have that either.You can still:1) Hook that pin up to a LED (obviously).2) Perhaps the LED is blinking too fast to see, and just looks constantly on? Try rapidly moving your eyes from left-to-right across it. Persistence of vision will allow you to briefly see faster signals than you normally could. Not useful in all circumstances, but I've been able to determine the approximate duty cycle of a PWM this way.3) Or if the signal is in the audio range, hook the pin up to a little piezo tweeter. Your ears excel at decoding other information. For a repetitive signal in the audio range, I can typically detect jitter of just a few percent.4) You can record audio range signals from the tweeter into a computer or smart phone, giving you some limited oscilloscope functionality.I get a lot of use out of a $10 frequency counter as well. Just used it to profile a repetitive interrupt. Coded a loop to toggle a digital pin as fast as possible. Ran it once with the interrupt disabled to get a baseline measurement, then again with the interrupt enabled; a little math then gives me the average of how long that interrupt is taking to execute. Next I tested interrupt latency. In the interrupt, I recorded the min, max, and average cycles of latency. Recoded the loop so that once every second, it rapidly blinks three different pins, with the number of blinks being the value of the associated statistic. By attaching the frequency counter to each pin in turn, I was able to collect the stats.

author: ralphd
author_rank: Frequent Contributor
timestamp: July 25, 2015, 02:05:12 am
content: Quote from: Chris C on July 25, 2015, 01:11:06 amFor up to 100kHz or so, a modern PC sound card line in can make a decent storage oscilloscope.A basic cypress-based 8-channel 24msps LA is <$6.

author: peter.mitchell
author_rank: Super Contributor
timestamp: July 25, 2015, 02:24:26 am
content: You should get an ARM devboard that is compatible with ARM Mbed. It provides an Arduino like environment for ARM devices, however, it allows you to interact with all the libraries that make that environment, so you can see what is needed to get started. After using it a while you will stop using the Mbed libraries and just migrate over to your own stuff.

author: rs20
author_rank: Super Contributor
timestamp: July 25, 2015, 05:16:38 am
content: Quote from: ralphd on July 25, 2015, 01:01:11 amAbsolute predictability means that changing between the cases you mention won't change the timing of the program. It's nice when time-critical code doesn't suddenly stop working when making seemingly irrelevant changes. Arduino is all about hiding the complexities from the user, and it's moderately complex to understand that different call patterns might lead to different timings. So, Arduino's solution is to hide that complexity from the user. I don't agree with that approach, but it certainly aligns with Arduino's wool-over-the-eyes philosophy.

author: westfw
author_rank: Super Contributor
timestamp: July 25, 2015, 10:02:25 am
content: QuoteMaybe you should check. It looks to me like in the all non-constant case, Wiring ends up using essentially the same code that Arduino uses.Also, I don't see any special cases for one "one argument is constant", so I think you'll see exactly the "two cycles or 50 cycles" behavior I'm worrying about.QuoteReally? I would have thought the C++ libraries with arbitrary pin constructors would be full of calls with both values variable. Here's one from one of the wiring examples:Code:byte rowPins = {2,3,4,5}; //connect to the row pinouts of the keypadbyte colPins = {6,7,8,9}; //connect to the column pinouts of the keypadKeypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );(Not that speed matters much here. slow _pinwrite() is plenty fast. Which is the main reason that the Arduino lib hasn't changed.)I don't know whether anyone has written a digitalWrite() that optimizes ALL the cases. Teensy, perhaps (hard to tell; it's pretty ugly.)Teensy3 too, but ... there's not as much optimization to do on an ARM. Sigh.(In any case, to bring things back to the topic we're supposed to be discussing...looking into the details surrounding this sort of thing can be VERY educational!)

author: CM800
author_rank: Frequent Contributor
timestamp: July 25, 2015, 01:18:12 pm
content: Thanks for all your help, some really interesting points have been made here.I am going to buy the ATATMEL-ICE-BASIC right now.In the long term I want to work my way up to buying and using this microprocessor here:http://www.ti.com/lit/ds/symlink/am3357.pdfFor a product in the future I have in mind making use of those industrial protocols.However that is a long way off I think. The Tech Doc for that MPU is just shy of5000 Pages!

author: TopLoser
author_rank: Unknown
timestamp: July 25, 2015, 01:46:21 pm
content: I think I've got a AM335x development kit somewhere.

author: ralphd
author_rank: Frequent Contributor
timestamp: July 25, 2015, 02:34:51 pm
content: Quote from: rs20 on July 25, 2015, 05:16:38 amOK, I get the point now. It never occurred to me that some Arduino users would be unaware that their code gets compiled to machine instructions, and the speed of execution is related to the number of instructions executed.

author: ralphd
author_rank: Frequent Contributor
timestamp: July 25, 2015, 02:51:42 pm
content: Quote from: westfw on July 25, 2015, 10:02:25 amFrom what I recall of working with VirualWire, it works that way. The output pin was a compile-time define, and the HIGH/LOW value was a runtime variable (user data).QuoteGood point. I forgot about old libs like that. More recently I've been looking at code from talented programmers like Mike Patel who will use things like __builtin_constant_p() to ensure compile-time constants don't have runtime penalties. As I've also pointed out in the past, turning on lto (-flto) can make up for a lot of that bad programming.QuoteSo the way Wiring does it should be preferred. :-) Programmer changes the way the code toggles a pin, notices timing difference, learns objdump to see what the code compiles to, and now has some useful knowledge...

author: CM800
author_rank: Frequent Contributor
timestamp: July 25, 2015, 03:49:51 pm
content: Quote from: TopLoser on July 25, 2015, 01:46:21 pmReally? Even though it will be a long way off from now, if the price is reasonable I would be happy to grab it!

author: jnz
author_rank: Frequent Contributor
timestamp: July 25, 2015, 05:22:26 pm
content: Something I haven't seen brought up yet was vendor lock-in. After more than a decade of being locked into Microchip and having to put up with bad decision after bad decision, no way I'll ever do that again. In ARM I can go to ST or Atmel or NXP or Freescale, etc. ST isn't going to make the part I need? Well, Atmel does and 95% of my code is logic and not peripheral access - so I can make that work.Oh, I use Arduino and depsite (or because of) increased popularity they keep dumbing it down? They don't make the part I want? The series I'm using isn't retail/wholesale available? Their XYZ peripheral sucks? Too bad.On top of that, I don't understand why anyone would still go 8bit when 32bit costs the same or less in a lot of cases.

author: asgard20032
author_rank: Regular Contributor
timestamp: July 25, 2015, 05:46:48 pm
content: 8 and 16 bit are still relevant depending of the complexity and real time requirement. Most of the time, a 16 bit mcu will have less latency than a 32 bit arm to respond to real time, with 1 cycle interrupt latency, and 1 cycle interrupt return while a arm can have as up to 30 cycle to enter and another 30 cycle to leave ISR. Its all about pipeline and other architectural design. 16 bit = less complex, so smaller pipeline. Once the pipeline is going on, an ARM is unbeatable, but when there is a change in order of instruction execution (a while, for, switch, function call, or an ISR... all the pipeline has to stop and start again at another place, so you loose some precious cycle). Pic32 is even worse for cycle lost. But on the other side, all math stuff take less time on the 32 bit arm, with floating point and other DSP extension ( m3 & m4 & m7). So for hard real time, a pic24, dspic, msp430 will be better. If real time is important, but you are not at 20 cycle accuracy, most arm will do the job. Also, you have to consider zero wait state of the flash and ram and other. In the right hand, arm will beat most other common mcu. But if not used correctly, there will be lot of wasted cycle doing nothing...

author: nctnico
author_rank: Super Contributor
timestamp: July 25, 2015, 05:58:29 pm
content: Quote from: jnz on July 25, 2015, 05:22:26 pmStill I like the suggestion to stay with Arduino for a little bit longer and get rid of the Arduino layer and start using the peripherals directly one by one. Once you know how to use Atmel peripherals directly the switch to ARM won't be that hard because what is under the hood works by the same principles. I have given this thread some thought and it is easy to throw all kinds of options at the topic starter but I think the most important first step is to get more comfortable with microcontrollers in general and which place is better than to start with something you already got working and can modify in small steps?

author: asgard20032
author_rank: Regular Contributor
timestamp: July 25, 2015, 06:11:10 pm
content: Some hard step to get into arm world include getting a toolchain setup (or buy an IDE), crosswork is a popular cheap one that do all major arm, understanding that on almost all arm, nothing will work at power on until you setup periphiral clock... GPIO don't work? Setup GPIO clock... Next, how does interrupt work, trap work, reset vector... if you can get across all what i mentioned, then you can pick up almost any arm.Most mcu = get to know how to configure clock, then how to configure each peripheral. Arm has the added toolchain/IDE complexity (Freescale and NXP has their free ide, Atmel has a free one but i hear lot of bad thing about it, TI also got one, but i wouldn't recommend TI for ARM, they are not really general purpose ARM and cost more... and their IDE is lock down to their XDS100 debugger except if you want to pay the price for it). Crosswork, 150$, IDE for all ARM on the market, or almost all. Work on Windows, mac and linux, and it look great. And the other complexity added by arm is that except if you know about whats going on with the clock, you could loose many hour of your life by not knowing that at power on, there is clock in none of the peripheral, not even the GPIO. If you get over those, arm is like all other mcu, but more standard and more popular these day.

author: ralphd
author_rank: Frequent Contributor
timestamp: July 25, 2015, 06:15:16 pm
content: Quote from: jnz on July 25, 2015, 05:22:26 pm337c will get you 10 ATtiny13a, or 169c will get you an ATmega328p Pro Mini board. 175c will get you a USBasp for programming.The instruction set is a bit simpler than ARM, and as others have pointed out, programming the peripherals on ARM MCUs is a lot more complicated. About 10 minutes of browsing the datasheet is all I need to get programming with a new 8-bit AVR.The amount of existing code is the biggest benefit (for some this could be a drawback given how much crap code there is out there). While I often write my own library code from scratch, having someone else's code to look at is a big help. More than once I've come across documentation in a datasheet that is ambiguous. Rather than having to write some test code to see how the part actually works, I can usually find existing code that shows the correct way to do it.Lastly, at least for me, I like creating things that are easy for others to duplicate. Most cities over 100,000 population seem to have electronics stores where you can find an arduino or pro mini board in stock. If I made a project with a stm32f030f4p6, it would be a lot harder for people to duplicate.

author: andersm
author_rank: Super Contributor
timestamp: July 25, 2015, 07:38:12 pm
content: Quote from: asgard20032 on July 25, 2015, 05:46:48 pmCortex-M3/M4/M7 have an interrupt latency of 12 cycles on entry and 10 on exit. If another interrupt is pending on exit, interrupt tail chaining shortens the latency to 6 cycles. CPUs with FPUs can add 17 cycles on entry and exit, depending on configuration. The Cortex M0/M0+ have a longer latency of 16 and 15 cycles, respectively.The Cortex-M hardware interrupt prologue sets up nested interrupts, the runtime environment and vectors to an ISR that can be a normal C functions. Latency numbers for other CPUs are typically counted only until the first instruction of the ISR is executed, but omits mandatory overhead like pushing registers and branching to the correct handler.QuoteCortex-M0/M3/M4 have a 3-stage pipeline, and the Cortex-M0+ a 2-stage pipeline. It is rare to get actual pipeline stalls, but on faster chips there may be flash wait states. (The Cortex-M7 has a 6-stage pipeline, but that's a different class of beast.)QuoteThe Cortex-M can actually be configured to be fully deterministic. Whether the latencies are low enough is of course a separate issue.

author: ralphd
author_rank: Frequent Contributor
timestamp: July 25, 2015, 08:16:40 pm
content: Quote from: andersm on July 25, 2015, 07:38:12 pm8-bit AVRs have a 4-cycle interrupt latency. A basic software pulse generator using a timer interrupt has no need to save/restore registers, and could be done with two instructions:Code:sbi PINREG, PIN;reti;

author: Frost
author_rank: Regular Contributor
timestamp: July 25, 2015, 08:20:49 pm
content: Quote from: jnz on July 25, 2015, 05:22:26 pmBut only if you go the CMSIS way.If you decide to use a vendor SDK then you will be locked again.I came from the AVR world and try to dive into the ARM land now.There was the same question for me like the thread starter,how to begin.So I orderd the FRDM-K64F as a cheap evolution board to startmy ARM journey.The nexed question was, how to start and program this thing,on the freescale page they offer you two paths to start,with a local IDE or to go the mbed way.I decided not to use the mbed web environment, because mymain goal is not to get a project up and running as fast as possible,I would like to understand the CPU and how the ARM world works,not at the lowest possible level but low enough to get a feelingand understanding how the things work behind the scenesand this was the reason for me to decide against the mbed way.Instead I looked for something, that will help me to get a betterunderstandig how the things work and I ended up with a book"The defenitive guide to ARM Cortex-M3 and Cortex-M4"from Joseph Yiu and I would say, it's a must read for every personwho wants to start working with the ARM Cortex-M processors.So you will be able to start with simple bare metal programsand code and raise the complexity step by step with your learningcurve and after you get more and more familiar with the basicsof the cpu.

author: andersm
author_rank: Super Contributor
timestamp: July 25, 2015, 08:30:06 pm
content: Quote from: ralphd on July 25, 2015, 08:16:40 pmYou can always invent special cases. Once you go beyond the trivial (maybe the pin should be cleared once in a while too?) the differences start going away. And for this special case, it would be better handled in hardware, with no interrupts.

author: nctnico
author_rank: Super Contributor
timestamp: July 25, 2015, 11:42:25 pm
content: Quote from: asgard20032 on July 25, 2015, 05:46:48 pmYou forget that a typical 8 or 16 bit CPU will have to push the registers onto the stack using software where the Cortex Mx CPU does this in hardware. So that 1 cycle on an 8 bit or 16 bit CPU quickly expands to 10 cycles or more and then there is 10MHz versus 50MHz (or more). Either way the ARM will be much faster. Even the older ARM7TDMI controllers have a single instruction which stores multiple registers onto the stack.

author: technix
author_rank: Super Contributor
timestamp: August 01, 2015, 05:03:25 am
content: Quote from: rs20 on July 24, 2015, 09:31:12 amI feel the same albeit in a different direction: Arduino's driver model is not exactly plugin friendly and it will take a lot of work to integrate a new piece into the library system. And the IDE is crappy (since my daily driver is Xcode.)

author: obiwanjacobi
author_rank: Super Contributor
timestamp: August 03, 2015, 10:46:54 am
content: I had sort of the same problem - I was also not happy with what Arduino hid from you. So I did this.Quote from: rs20 on July 24, 2015, 01:41:31 amIt's a bit of a learning curve to get down to the MCU level (and reading the datasheet) but its been fun and rewarding.

author: nctnico
author_rank: Super Contributor
timestamp: August 03, 2015, 03:57:52 pm
content: IMHO part of the fun of using microcontrollers is trying to find new sick & twisted ways to use the peripherals for a certain purpose they where not intended for.

author: CM800
author_rank: Frequent Contributor
timestamp: August 12, 2015, 05:45:01 pm
content: Wow,I just programmed a nano to flash an LED through Atmel Studio using my Atmel ICE.... was a heck of a lot easier then I expected.. else I would have done it sooner.... now to do something more useful... haha.Does anyone on here have Steam or Skype who would be willing to chat with me about AVR stuff? Give me some pointers or quick help if I have a problem?

author: Chris C
author_rank: Frequent Contributor
timestamp: August 12, 2015, 06:29:29 pm
content: Congratulations! Getting past the initial intimidation is quite an accomplishment. I'm PIC-only, else I'd take you up on that chat offer.

author: ez24
author_rank: Super Contributor
timestamp: August 12, 2015, 08:39:43 pm
content: OPWhat do you think of thishttp://www.digilentinc.com/Products/Detail.cfm?NavPath=2,719,1471&Prod=LABVIEW-PCKthe hardware and software

author: CM800
author_rank: Frequent Contributor
timestamp: August 12, 2015, 10:55:06 pm
content: Looks interesting, but I imagine the same with Arduino, you will find yourself having fun at the start, but when you begin pushing limits you will cry in frustration like myself and want to move over to a proper set up... that being said, It looks like a fun thing to play with potentially.

author: TheWinterSnow
author_rank: Contributor
timestamp: August 13, 2015, 05:57:20 am
content: I know I am probably late here on the topic, but reading through I wanted to add something.I program my Arduino Mega2560 with the USB connection but program it in C using standard IDE's (in my case Eclipse), so I don't have to worry about needing a programmer. Yes the chip still has the 8kB bootloader but it saves me from spending the money on a programmer. You could always use the Arduino IDE to use your Arduino board as a programmer to program another AVR device.My board is stock yet I can program it in C in a standard C IDE with the standard C library yet I can turn around and program it with the Arduino IDE if I ever felt the need to do so (eww!).I personally refuse to use the Arduino IDE and libraries, give me the old C language and register controls. I was against the Arduino libraries and IDE when I only had experience with the 8051 platform and Arduino was just beginning to get into popularity circa 2009-2010.By writing your code in C or C++, and calling on the header libraries of that specific piece of hardware, in order to learn a new piece of hardware like the ARM system, you only need to study up on the API of the library that is intended for that piece of hardware. In the case with ARM, not all of them use the same header libraries so you have to be careful there. But in the end to me, its much easier and you learn more by programming for a specific target device, plus you save execution time by not using bloated entry level libraries.

author: Roicker
author_rank: Contributor
timestamp: February 16, 2016, 09:52:24 pm
content: Quote from: chicken on July 23, 2015, 07:35:12 pm+1 on using the Tiva C (you already have it!)The main reason would be that you can debug it in-circuit (put breakpoints, execute line by line, look at the memory in any given time, etc) which is something you don't get with the AVR Mega unless you buy an ATMEL ICD.I think it's a good idea to remove the libraries and do your own routines on the Arduino, but without the In-Circuit Debugger it's going to be much harder to figure out when something is not working.I own a Tiva C and I love it, I think it's a great kit for the money, also, the tutorials are great (I already knew embedded before using it, but still).

author: dannyf
author_rank: Super Contributor
timestamp: February 16, 2016, 10:51:03 pm
content: Since you already have arduino, avrs would be a natural starting point.Contrary to what you have been told, there isn't much difference programming an avr vs. Programming an arm. An avr is considerably simpler and much easier to get started.The trick is to be good at C and read lots of data sheet.

author: autobot
author_rank: Regular Contributor
timestamp: February 18, 2016, 07:37:04 pm
content: Quote from: jnz on July 25, 2015, 05:22:26 pmIf you use the mbed, you get access to variety of chips, and much easier portability .

author: captbill
author_rank: Contributor
timestamp: February 19, 2016, 05:38:22 am
content: Quote from: TCWilliamson on July 23, 2015, 07:22:01 pmTake a look at Astrobe :https://youtu.be/qmSqhAG_ea0Astrobe targets the majority of the NXP's LPCxxx series boards. Plus has a really cool RISC5 experimental FPGA core ( a 'soft processor core' much like a PicoBlaze or MicroBlaze by based upon ProjectOberon.com). Google 'Microblaze'. It is much less intimidating to work with FPGA's than you think. Very simple actually and allows you to peek at the actual wires and gates of the 'soft processor'.Now take a look at the compiled binary size from the compile debug panel from the project in the video:Code:Oberon for Cortex-M3 Compiler v5.3.0compiling DisplayDemocode generated = 972 bytes, data = 0 bytesNow give this 300 lines of code a good study and you have the ability to do CAD drawing on an MCU!! And do all this inUNDER 1 KB.This is the core drawing library to what I believe is the same demo in the video.The complete program, including the CAD data for this project is a mere 17KB.Code:MODULE LCDST756R;(* =========================================================================Example ARM Cortex-M3 Oberon ModuleDescription:Sitronix ST756R LCD Controller DriverTarget:mbed systemsTested on:ARM mbed Application Board with a Newhaven C12832A1Z 128 x 32 LCD displayReference:Sitronix ST756R DataSheet Ver 1.5 (10 Mar 2006).(c) 2013-2014 CFB Softwarehttp://www.astrobe.com========================================================================= *)IMPORT Timer, MCU, ResData, SPI, SYSTEM;CONSTBlack* = 0;White* = 1;MaxX* = 127;MaxY* = 31;FontWidth = 6;FontHeight = 8;Cols* = (MaxX + 1) DIV FontWidth;Rows* = (MaxY + 1) DIV FontHeight;Pages* = (MaxY + 1) DIV 8;A0 = {6}; (* P0.6 = mbed P8 *)CS = {18}; (* P0.18 = mbed P11 *)Reset = {8}; (* P0.8 = mbed P6 *)TYPE(* Each bit represents a pixel on the screen *)(* Each page can be refreshed invidually *)BitMap = ARRAY MaxX + 1 OF SET;(* 6 x 8 pixels *)FontPattern = ARRAY FontWidth OF BYTE;VARfont: ResData.Resource;fontPattern: FontPattern;(* In-memory representation of the screen *)bitMap0, bitMap: BitMap;PROCEDURE LoadFont*(name: ARRAY OF CHAR): BOOLEAN;BEGINResData.Open(font, name);RETURN ResData.Size(font) > 0END LoadFont;(* Store the font data for a character in a 2-D pixel array *)PROCEDURE CharToFontPattern(ch: CHAR; VAR fontPattern: FontPattern);VARi, index: INTEGER;BEGINIF (ORD(ch) < ORD(" ")) OR (ORD(ch) > ORD("~")) THEN ch := "." END;index := (ORD(ch) - ORD(" ")) * 8;FOR i := 0 TO FontWidth - 1 DOResData.GetByte(font, index + i, fontPattern);ENDEND CharToFontPattern;PROCEDURE SendData(data: INTEGER);BEGINSYSTEM.PUT(MCU.FIO0SET, A0);SYSTEM.PUT(MCU.FIO0CLR, CS);SPI.SendData(data);SYSTEM.PUT(MCU.FIO0SET, CS);END SendData;PROCEDURE SendCommand(data: INTEGER);BEGINSYSTEM.PUT(MCU.FIO0CLR, A0);SYSTEM.PUT(MCU.FIO0CLR, CS);SPI.SendData(data);SYSTEM.PUT(MCU.FIO0SET, CS)END SendCommand;PROCEDURE SetColumnAddr(x: INTEGER);CONSTColumnAddrLo = 000H;ColumnAddrHi = 010H;BEGINSendCommand(ColumnAddrLo + x MOD 16);SendCommand(ColumnAddrHi + x DIV 16)END SetColumnAddr;PROCEDURE SetPageAddr(n: INTEGER);CONSTPageAddrSet = 0B0H;BEGINSendCommand(PageAddrSet + n)END SetPageAddr;PROCEDURE* DrawDot*(colour, x, y: INTEGER);BEGINIF (x <= MaxX) & (y <= MaxY) & (x >= 0) & (y >= 0) THENIF colour = Black THENbitMap := bitMap + {y}ELSEbitMap := bitMap - {y}ENDENDEND DrawDot;PROCEDURE* DrawVerticalLine*(colour: INTEGER; x, y1, y2: INTEGER);VARyBits: SET;BEGINIF (x >= 0) & (y1 >= 0) & (y2 >= y1) & (y2 <= MaxY) THENyBits := {y1..y2};IF colour = Black THENbitMap := bitMap + yBitsELSEbitMap := bitMap - yBitsENDENDEND DrawVerticalLine;PROCEDURE* FillRectangle*(colour, x1, y1, x2, y2: INTEGER);VARx: INTEGER;yBits: SET;BEGINIF (x >= 0) & (x2 > x1) & (x2 <= MaxX) & (y1 >= 0) & (y2 >= y1) & (y2 <= MaxY) THENyBits := {y1..y2};IF colour = Black THENFOR x := x1 TO x2 DO bitMap := bitMap + yBits ENDELSEFOR x := x1 TO x2 DO bitMap := bitMap - yBits ENDENDENDEND FillRectangle;PROCEDURE* DrawFontChar(fontPattern: FontPattern; col, row: INTEGER);VARi, x, adr, fontAdr: INTEGER;fontData: BYTE;BEGINASSERT((col >= 0) & (col < Cols) & (row >= 0) & (row < Rows), 100);x := (col * FontWidth);adr := SYSTEM.ADR(bitMap) + row;fontAdr := SYSTEM.ADR(fontPattern);FOR i := 0 TO FontWidth - 1 DOSYSTEM.GET(fontAdr, fontData, 1);SYSTEM.PUT(adr, fontData, 4)ENDEND DrawFontChar;PROCEDURE DrawChar*(colour: INTEGER; ch: CHAR; col, row: INTEGER);VARfontPattern: FontPattern;BEGINCharToFontPattern(ch, fontPattern);DrawFontChar(fontPattern, col, row)END DrawChar;PROCEDURE Refresh*();(* Only write the pixel columns that have changed since the last refresh *)VARpageNo, x, adr0, adr: INTEGER;data0, data: BYTE;col: INTEGER;BEGINFOR pageNo := 0 TO Pages - 1 DOSetPageAddr(pageNo);col := -1;adr0 := SYSTEM.ADR(bitMap0) + pageNo;adr := SYSTEM.ADR(bitMap) + pageNo;FOR x := 0 TO MaxX DOSYSTEM.GET(adr0, data0, 4);SYSTEM.GET(adr, data, 4);IF data # data0 THENIF col # x THENSetColumnAddr(x);col := xEND;SendData(data);INC(col)ENDENDEND;bitMap0 := bitMapEND Refresh;PROCEDURE* ClearScreen*(colour: INTEGER);VARx: INTEGER;BEGINIF colour = White THENFOR x := 0 TO MaxX DObitMap := {}ENDELSEFOR x := 0 TO MaxX DObitMap := {0..31}ENDENDEND ClearScreen;PROCEDURE* ConfigureSPI1Pins;VARs: SET;BEGIN(* SPI1 *)(* Setup SCK1, SSEL1, MISO1, MOSI1, no SSEL *)(* PS0 bits 15:14 12:13 17:16, 19:18 := 10B *)SYSTEM.GET(MCU.PINSEL0, s);s := s + {15, 17, 19} - {14, 16, 18};SYSTEM.PUT(MCU.PINSEL0, s)END ConfigureSPI1Pins;PROCEDURE* ConfigureGPIOPins;VARs: SET;BEGIN(* P0.6, P0.8 are GPIO ports *)SYSTEM.GET(MCU.PINSEL0, s);s := s - {12, 13, 16, 17};SYSTEM.PUT(MCU.PINSEL0, s);(* P0.18 is GPIO port *)SYSTEM.GET(MCU.PINSEL1, s);s := s - {4, 5};SYSTEM.PUT(MCU.PINSEL1, s);(* P0.6, 0.8 and 0.18 are outputs *)SYSTEM.GET(MCU.FIO0DIR, s);SYSTEM.PUT(MCU.FIO0DIR, s + A0 + CS + Reset)END ConfigureGPIOPins;PROCEDURE Init*;CONSTnBits = 8;BEGINSPI.Init(SPI.SPI1, nBits, ConfigureSPI1Pins);ConfigureGPIOPins();SYSTEM.PUT(MCU.FIO0CLR, A0);SYSTEM.PUT(MCU.FIO0SET, CS);SYSTEM.PUT(MCU.FIO0CLR, Reset);Timer.uSecDelay(100);SYSTEM.PUT(MCU.FIO0SET, Reset);Timer.uSecDelay(100);SendCommand(0AEH); (* Display off *)SendCommand(0A2H); (* Bias voltage *)SendCommand(0A0H); (* ADC Normal *)SendCommand(0C8H); (* COM Scan normal *)SendCommand(022H); (* Resistor ratio *)SendCommand(02FH); (* Power on *)SendCommand(040H); (* Display start line 0 *)SendCommand(081H); (* Set contrast *)SendCommand(017H);SendCommand(0A6H); (* Display normal *)ClearScreen(Black);bitMap0 := bitMap;ClearScreen(White);Refresh();SendCommand(0AFH); (* DisplayOn *);END Init;END LCDST756R.