Why Arduino is not the right educational tool

I could have started with ‘why the Arduino sucks’ or ‘why the Arduino is bad’, which would have gotten me a tremendous load of page views. But I didn’t because it simply isnt’t true. The Arduino does not ‘suck’, and neither is it bad in its own right. It just isn’t the right tool to teach people programming, but it’s abused that way. Let me tell you why:

What is the Arduino?

“Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It’s intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments.” There. I just copy-pasted that from www.arduino.cc. And they’re right! The arduino project is great for  creating interactive objects or environments. You’ve got a gazillion of code examples to use, you can easily read out sensors that would take hours to days to get going (even with coding experience) and a large user base to ask questions. Above all, creating interactive objects or environments is about human interaction (fun!). Hook up a sensor to an actuator, create new combinations and play around… But it’s NOT a good standard to learn coding, or benefit from the power of embedded electronics.

And that’s where I’m bearing a grudge to the use of Arduino’s as a ‘getting started with programming’. Learning to work with microcontrollers is sometimes a steep pathway, but leverages the power of these little beasts. Using an Arduino to learn programming is like using MacDonalds to learn cooking; you get your meal, very fast, but you don’t get the skills to cook yourself. When you need a quick meal, the Mac can be OK (debatable, but just to make my point), but it’s not a cooking class.

5 reasons why, in no particular order:

1: no project space / code partioning / decent IDE

To me this is a great nuisance; I understand you don’t want to overwhelm novices with options, but the Arduino IDE ridicules decent code writing. Maybe you’re supposed to bend your knees that they’ve included color highlighting of variables, but come on, if you want to write decent code, at least give the option to look up variable definitions. See what that looks like below, in a screenshot from Code::Blocks. Another, somewhat related point is that you’re supposed to write all your code in one ‘sketch’. When you want to write any substantial program, with functions you’d like to be able to use later on, good practice (or even complimentary practice) is to create modular pieces of code. Writing everything in one long file is going straight against that objective, and stimulates writing ‘spaghetti code’, with definitions of variables everywhere and nowhere.

The concept of why header files are important is described here on www.cplusplus.com. Another good discussion and fast ‘howto’ is written here (read the discussion!). Also, a great document describing why and how modularizing your code is great can be found on this post at embedded.com

To get a good understanding of  ‘how it’s done right’, please take a look at this very clear document from MIT (pdf)  regarding header files:

“A well organized C program has a good choice of modules, and properly constructed header files that make it easy to understand and access the functionality in a module. They also help ensure that the program is using the same declarations and definitions of all of the program components. This is important because compilers and linkers need help in enforcing the One Definition Rule.”

 

Being able to look up definitions and implemenations....

Being able to look up definitions and implementations….

Being able to look up the definitions and implementations of files is a great help in writing modularized code. The Arduino IDE does not provide an easy way to create other c / h files, nor does it enable looking up the definitions of it’s own code (what does ‘digitalWrite’ actually do?). When learning to program C, PLEASE learn to use header  files appropriately!

2:bad abstractions / naming

The Arduino ‘programming language’ uses a lot of predefined functions to use peripherals of the Arduino. A lot of these functions use misguiding names or use bad abstractions, simply not describing what they’re doing. Good hardware abstraction saves the end user from fiddling a lot, bad hardware abstraction confuses. A few examples:

  1. analogWrite(int): “writes an analog value (PWM) to a pin”. You say what? PWM is analog? It’s as much analog as a CD contains analog information. Pulse width modulation is NOT analog; the rate is ‘approximately’ 490Hz, and no clues are given to what RC combination you should use to make it analog. This is misguiding; good enough for a LED but it’s not the ‘Analog’ you’d like to use as a setpoint for an analog control system. 
  2. OK, and if you generate PWM, at LEAST let me be able to set the PWM frequency.
  3. pinMode(): I have to admit this is fixed now, but a while ago you had the options ‘INPUT’ and ‘OUTPUT’ only. When you wanted to have an input with pullup, you also had to do a digitalWrite() to the pin you just made an INPUT. When you know the AVR architecture, you know that you’re writing the DDRx and PORTx registers, but to a newbie it’s quite strange to ‘write’ to a pin you just made ‘input’ to get a pullup. It’s fixed now, but it took too long; the pinMode function was already available, and it just needed this extra option. This was not abstracting the hardware, but even creating code that will not be able to port nicely to other microcontrollers (which is probably why it was fixed around the time the Due came).
  4. variables: why use all the chars, ints, longs, etcetera? Using stdint (uint8_t, uint16_t, int32, …) will give more insight, and more portable code. The int for AVR-GCC is 16-bit, while it is 32-bit for the GNU ARM compiler….
  5. Missing abstraction / feature: progmem. A lot of people use strings in memory for debugging. Fixed strings could be stored in flash memory and read from that memory, that feature is present in avr-libc. My guess is that 90% of people saying ‘my Arduino is full’ would benefit from adding some kind of keyword.

3: horrible documentation

Again, this article / rant is based on using it for educational purposes. The documentation on the functions tells nothing about which peripherals are used, not even on a deeper level, hidden away from normal users. I’ve used openFrameworks before, and at least with their IDE you can look in the code how functions are implemented. When using the Arduino, you’re kept dumb. Could I be using a timer while running the servo() functions? Will sending a serial string block my program? Will using analogWrite interfere with other timed functions? You can’t read it in their reference manual.

The Arduino reference also describes its ‘language’. The underlying framework uses some C and some C++ features, both not clearly described. If you want to learn programming, ‘Arduino’ is not the language you’d like to have on your resume, you want to be able to program in C! The difference / equality is not clear, and leads to confusement when going to other microcontrollers or ANSI-C environments. Where are classes used? Where are structs used? I understand that Arduino doesn’t want to scare off new users, but there is no roadmap to ‘advanced’ use.

4: no access to peripherals / wasting resources

I know, you do have access to the peripherals of the Arduino / Atmel chip when you mingle your Arduino code with ‘real’ C and use the Atmel registers. But when you’re that far, please do yourself a pleasure and write your own code, where you know which peripherals are used in which way. When I started programming microcontrollers I was amazed at the speed at which they worked (8 MHz PIC); writing code optimized for the peripherals, using interrupts to do as much parallel as possible showed me what power lies in embedded devices and computers. To me, using the Arduino to learn programming embedded systems takes away that golden edge of creating ‘lean and mean’ applications.

At my current job, people are trying to write control loops using the Arduino; by using the micros() funciton they take the start time of the loop() function, do their tasks, and then poll the micros() function to wait until their loop time has passed. This wastes so much potential for future tasks that should be added, or for processes that are not running at the same timebase. This alone is what makes the mbed better; it’s implementation of ‘Ticker’ functions has its drawbacks, but at least uses interrupt-based timing, leaving the main loop for ‘slow processing’ tasks.

5: no ‘real’ debugging

When the Atmega328 was used no debugging port was available; now the Due is released and the Atmel devices have debug ports from tiny series (DebugWire) to the XMEGA series (PDI and JTAG), this powerfull toolset is kept from the Arduino users. I think development time of applications drops by 30% for me when being able to use a proper debugger setup. At least the ARM could use the OpenOCD implementation, and give power to the programmers. A few breakpoints give a very fast indication of what code is executed, and what error conditions happen. This is where I get very enthousiastic about all new ARM development kits with debugger hardware included. Add arm-gdb and OpenOCD, and you’re up! Setting up those toolchains can be a bit fiddly, but completely worth it when trying to make a decent embedded application.

 

What’s your alternative?

I think that’s enough for complaining. Your next question should be: how do we educate programming with a good environment? I have several options, all of whom might be worse or more difficult to start with. To get back to my comparison between the Mac and learning to cook yourselve: learning to cook takes someone to teach you. I’ve helped quite a few people to show how to start using other tools, and in general they’re a bit grumpy at the start (why is this so laborious?), and happy in the end (now I understand what’s happening!).

  1. Scratch. To get youngsters to start programming, this is fun, and shows what programs are. It’s fun and easy, and it even enables code partitioning! It’s not embedded though, but if you start out young, this is a good way to learn programming.
  2. mbed. Now open sourced, this lets you use NXP boards and the inexpensive Freescale Freedom board. Here I’m getting quite enthousiastic. The compiler is online, which is great for novices, as you don’t have to install toolchains. Also a humongous archive of code examples is available that you can easily import into your project. Yes, projects! You can organize and partition your code, and use version control online. The code provided by mbed is C++, using classes and operator overloading, which was a bit confusing for me as ANSI-C-er at first, but the documentation is SO clear, and easily available (again found in your project) that it was more encouraging me to also use those features. Peripherals cannot be used simply, but you can use timers indirectly to generate timing interrupts, and again this is well documented.  You don’t like online services? You can also use it offline. The only downside to the mbed for me is that you can’t debug using breakpoints or watchpoints.
  3. AVR-GCC /WinAVR, with Xmega series. The AVR-GCC toolchain (with avr-libc) has a respectable reputation and a very good userbase (www.avrfreaks.net). The reason I recommend the Xmega series is the *fantastic* documentation, the fact that the peripherals each have their own application note, that Atmel Studio is bloated, but gives you the real tools in hands for code partitioning (Goto definition of…), debugging (breakpoints!) and simulation (view bits in peripherals!). When using the (overpriced) Dragon debugger you can debug devices up to 32k code size. Starting with this setup without any coding knowledge might be a bit too steep though, try to get help online, or ask a knowledgeable friend to help out. Reading the application notes just gives me that fizzling feeling that you can make a system that does SO much on its own once you set it up; DMA’s to get ADC values into memory, event system to trigger timers to trigger DACs, etcetera. Quite a bit of work, but than you’re doing embedded-fu. Like making Sushi instead of going to the Mac…..
  4. Use Launchpad/STM32/… Other ARM board. Yes and no here… Yes, ARM is the future, but it’s quite complicated to start with, I think. Also, when using free toolchains you have to put a lot of work into setting up the toolchain. It’s rewarding though; boards with debuggers for takeaway prices (EUR 8 for an STM32F0 Discovery -> Atmel, are you reading this?!), and something to put on your resume: I’ve worked with ARM. The documentation however is mostly poor and frightingly large…. Also, the option set for compilers and IDE’s is so large, that it’s hard to find out why your program is not compiling when it isn’t…

Conclusion

The Arduino is great ‘programming fastfood’: easily available, quick result and sometimes quite tasty. But it isn’t suitable for educating ‘how to program’ or ‘getting performance out of microcontrollers’, or use it as a first step that has an advanced level for enthousiasts. To do that learn real cooking; start with boiling water with scratch, cook potatoes with mbed and make sushi with Atmel to end up going freestyle on the ARM development boards. Now you’re playing with power!

 

33 thoughts on “Why Arduino is not the right educational tool

  1. It depends how you define programming. Not everyone needs to work on a low and professional level.

    I agree with Scratch, since it’s all in one environment.

    Considering working with electronics Arduino is the most easy way to start. Why you think most microcontroller related projects on Kickstarter adapt Arduino. It’s unbeatable if you consider all the resources available and the community. Maybe not the best IDE, but when you start programming with if/else you don’t need the bells and whistles you mention.

    • admin says:

      Hello Kasper,
      There’s no way to beat the number of Arduino-based projects. But that doesn’t mean it’s a good basis to start learning programming.

      If your only goal EVER is to do some if/else logic, and read some sensors and display data (or turn on a motor) on a human-compatible time scale, Arduino is a good tool to do some quick and dirty programming. If you want to do more, now or in the future, there is no direct path to look how the underlying code is written, or a way you’re encouraged to follow ‘good practice’ rules for encapsulation or abstraction. This, in my opinion, cuts off a very important part of learning the skill of programming.
      When I take a look at the mbed, I see that the quick and easy options for programming are still there, but that I can easily have a quick look in the sources if I want to, and that the IDE supports and encourages good coding techniques; see these course notes on writing modular code.
      The fact that Arduino is fully open source, and thus cheap to clone has brought it far, and it deserves credit for making microcontroller projects appealing again. But I’ll keep stating that it’s wasting resources, and that the complete environment discourages good coding practices.

  2. John Lloyd says:

    I would disagree. Arduino is great for imparting a concrete understanding of basic programming concepts to children. Learning loops, conditional logic, and basic functions form the core of any Pri/Sec level CS class. Arduino lets students learn those core concepts through playing with something they can touch and interact with. Projects also require skills from other disciplines which help pique young imaginations.

    • admin says:

      Hello John,
      Thanks for your comment. I value your opinion, but I still think Arduino is almost a dead end ally when it comes to going further with embedded programming. Which is fine if you’re forced to do some electronics in your project, but don’t want to learn all the concepts of embedded programming. If you want to learn programming to ‘young adults’, give them something that opens up their options, instead of closes them in. Although Arduino is open source, it’s quite hard to browse that code from the IDE, and general programming concepts are not taught due to the restricted IDE (encapsulation, abstraction).

    • Tyler says:

      How does arduino teach to children? Kids in my high school are lucky to be able to text! And now all of a sudden, arduino is for children? Yes it may be simple, but for children?

      • admin says:

        Hi Tyler,
        Thanks for your response, but I do not completely get your point. I’ve seen Arduino used as educational platform (for younger and older ‘children’), and I think it is a very unsuitable choice to use it for that purpose. Of course, teaching requires a teacher, especially with more complex stuff as programming. I think I never suggested that any platform would be able to teach ‘by itself’.

  3. Dan says:

    Good point!
    I’ve just add the TI’s Launchpad line on your alternative list.

  4. Jeroen says:

    I would strongly disagree. First there is no difference between avr-gcc and Arduino. It is exactly the same, just packaged in such a way that a beginner can start straight away.
    Second: I have seen how my 13 year old son went from not interested in programming at all to enthusiastically programming and tinkering with his Uno. That is where Arduino excels: in getting people into programming and into electronics. Sure, later in life you have to learn programming on a more serious level. And you know what? You can do that using Arduino! Get the free Atmel IDE and away you go. All the functionality you can ever need. Still not satisfied? Get a Due and learn the future, not some kind of irrelevant sideshow.
    The Arduino is not perfect, especially the documentation of advanced features is unstructured and takes a while to get to grips with. And many versions of the Arduino seem superfluous.

    • Boo says:

      How on earth did you come to this conclusion ? I find Arduino fanatics are always sticking their necks where it doesn’t fit.

    • admin says:

      I think that your son is lucky enough to have a devoted teacher that can help to show the road to a full IDE. That’s missing for all those that learn Arduino and are than scared by the ‘complexity’ of other systems.
      I don’t know how many people not even know that they’re programming C (they’re programming ‘Arduino’!) let alone understand that it’s avr-gcc or understand how to migrate all libraries to a AVR-Studio environment.
      For -again- educational purposes it’s better to have an environment that has a bit steeper learning curve, but also gives the freedom of learning more from the environment you’ve took your first steps in.

  5. Boo says:

    Arduino => Lazy people who loves comfort zones, good for doing quick things.

    True micro controller development teaches you about ISR, registers, multiplexing, setting up a port that shares peripherals interfaces, working in C or ASM.

  6. Mark Beckett says:

    While you can’t deny that Victor is right with regard to popularity and hiding the underlying functions, there is a comparison I once made to someone else.

    I presume most of you drive/own a car.!

    How many of you know the inner workings of the engine, the valve timing, injection, and the engine management computer?
    What about the gearbox (auto or manual) and exactly how each part interacts based on the diff ratio?

    When you get into your car, and want to do a short run to the shop, you really don’t expect to have to set the ignition timing, the fuel ratio, and the gearbox and diff settings.

    Maybe you have some default settings, based on yesterdays trip when it was fully loaded with 4 people.

    Most people just expect to get it, and drive.
    The underlying features are hidden and just work.

    Sure as it sits it has much more potential, and it won’t win a race, compete in a rally, or do some of the other stuff that a specially built version in which each component is adjusted to suit the event and conditions.

    The point is that some people simply want a car to drive.
    Arduino is like that car, hop in, start it and away.

    There are probably thousands of users that will never take up programming, but may start playing with hardware and use the Arduino IDE in order to achieve what they want/need.

    So sorry Victor I think your points are valid, but its still ONE tool available to educate.
    It is certainly not the only tool, but a lot less confusing to many people.

    Mark

    • admin says:

      Hi Mark,
      Very valid point, and good comparison. But if you want to teach engineering, and not teach driving the car, you’ll have to know something about internals. I guess I want to go ‘deeper’ in teaching than others…

      • Greg says:

        The point you are missing is that Arduino is not about teaching engineering. It is about providing an experience where the students can quickly getting something working so they are inspired and have the confidence to try to do more.

        Starting by installing a programming tool chain then trying to understand a proper programmer’s IDE will discourage most of them before they write their first line of code. Dealing with DDR and PORT registers, plus bit operations just to get an LED to blink would further discourage the few that lasted through the setup.

        Your McDonald’s / cooking analogy is poor. McDonald’s is to cooking as handing someone a box with a blinking LED is to programming. A better analogy is that Arduino is like starting to teach a kid to cook by having them make Mac-n-cheese. Using engineering tools to teach a beginner to program is like teaching a kid to cook by having them make a cupcake from scratch in a bakery. They’ve never been in a bakery before, the tools are all oversized for making one cupcake, and there are a dozen steps that have to be done nearly perfectly to get an edible result.

  7. john lim says:

    Not really true. Arduino does exposes its processor architecture like registers and interrupt vector maps etc if you bother to research.

    Moreover as a long time C programmer, I find the arduino a useful tool to teach basic programming construct like loop and conditional cases quickly to some first time young people who are not able to visualize these ideas in their mind without some physical demonstrations.

    A blinking light emphasizes the idea of loop to these kind of people, likewise the selection of action depending on sensor triggered (PIR , Light, sound sensor etc) reinforces to them the idea of if else conditions.

    • admin says:

      Hello John,
      It does expose if you research… But it’s a PITA to open cpp and h files from libraries you’ve included in the Arduino IDE.
      My whole point is that the Arduino environment doesn’t encourage digging into the details. As others have pointed out, sometimes that isn’t necessary, I agree to that.
      But to teach programming, I think it is good to be able to have a quick look what’s under the hood, and to be encouraged to use good coding style like NOT writing everything in the same file. The Arduino IDE is to blame for a lot of the points I’ve made here.
      For general concepts, the Arduino might suffice. But if you want to go for some performance (I’m now teaching how to control a small robot with 2 motors with encoders) and discover how speedy and powerful microcontrollers can be, Arduino is not the right tool. If you have to learn a new tool when you’re ready for more detail, I think you get discouraged. That’s why I think the mbed platform (for instance, it’s just what I have experience with) is better. You can easily look into libraries, see function definitions, use interrupt based timing.
      Maybe the bottom line is: if you teach young kids (elementary school): use Arduino ’cause it’s simple. Any higher: please get some C programming concepts grounded well and use a ‘real’ IDE with consistent naming.

  8. Chey says:

    There are plenty more IDEs out there. Here’s a couple options for those who don’t like the standard Arduino IDE.

    http://playground.arduino.cc/Code/Eclipse
    http://arduinodev.com/codeblocks/

    “to each his own”

  9. Sun says:

    Great finding! Can’t agree more! I just returned the Arduino kit I’ve bought a week ago because my goal is to consolidate my low level knowledge, but just realized it is painful to dig into the low level baremetal with Arduino. I did find all the sources needed to understand the details of initialization and basic drivers in the Arduino IDE, but it is just inconvenient to figure out the programming specs by reading meaningless code rather than reading MCU or a board manual, which I mean should be something like Intel’s x86 software developer manual.

    Not sure about mbed, is it very easy to start programming baremetal mbed without the mbed libs? Is there any simple board with simple processors and just a few peripherals directly connected to the MCU for us to practice programming MCU from the first instruction to execute?

    • admin says:

      At least mbed doesn’t hide everything from view; when you hover over a function call, there’s a way to immediately dive to the function implementation of that function.
      To start from bare metal, you can start with anything. I did this with first with Atmel (AVR-GCC, now included in WinAVR) then MSP430, then ARM (ST, EnergyMicro, LPC). I really like the 8-pin DIP ARM (LPC812) from NXP to do bare metal stuff. It’s so tiny you have to be creative!

  10. Duality says:

    I agree with the post.
    But I started out with arduino, and had alot of fun playing with it, but after a while you find out that there is another way of doing it (through the real C programming),
    And me being me :P I want to be as close as possible to the machine and exactly know What it does why it does it. and knowing gives you power imho :) and it’s alot of fun too!

  11. Graham says:

    I sort of agree but I like the Arduino IDE as a teaching tool. It is simple, yes keeps all the code in one sketch, but it is simple. When we start to teach children Maths for example, we start with the numbers, not necessary at that time to define them as a set if integers! Initially the fact they can be negative is actively ignored. Once they have a grasp of the basics then more concepts can be introduced.
    I would prefer to start with If Then Else and For and While rather than polymorphism! Rather explain simple data types, byte char int rather than portable ones, we can get to those later.
    First I want to get you interested!!

  12. Nikolai says:

    Okay,
    I started out on Arduino 2 months ago. I have developed desktop apps and web/server solutions for more then 10 yers using C#, as main language. I wanted to start out with AVr’s and got a Arduino board with 15 pratical leasons, and found out that there was some way to go. Then i got ‘Make: Electronics’ and ‘Practical Electronics for inventors’ to kickstart my self on basic knowledge. After that the Arduino cookbook. I have read all and experimented with all the analog components to build a basic knowledge. Now Iam digging further down the AVR, and looking in to using pure C to code my stuff. I quickly realised that the AVR is alot smarter enginered then Arduino made me think in the first place. Any ideas on where to go from here. I would like to understand more about using digital components. Even Practical electronics for inventors, has this plug and play approach that doesn’t tell you why it works as it do. By the way. Whitout Arduino i would proberly never have started out on AVR’s ;)

    • admin says:

      Thanks for your comment, and good points.
      I know that recently there’s been a very good course online in programming embedded systems at a university in the States, probably the courseware is open. I’ll see whether I can find the link. You could also take a small step and go to mbed; still a lot of stuff is in libraries, but it’s easier to track down which code is coming from where, and you’re encouraged to create libraries and treat them as such.
      If you want to continue with AVR, AVRFreaks is a great place with lots of knowledge

  13. Davis says:

    Strongly agree!!. I can testify that your article is totally true because i am a student and i am in a arduino infected collage. In theory arduino is useful to start programming and doing quickly prototypes and then migrate to other platforms with better performance. The problem is that in real life, the migration never happens. The bridge between arduino and a better plataform does not exist because arduino has educated students in the wrong way, and now they see very complicated migrate to another plattaform so they decide stay with arduino. They never learn to code properly because arduino dont teach to code properly, and they cant see that there is a world outside arduino with a lot of things to learn.

  14. ramakant says:

    I just dont understand, this is how we blink lights in the ardunio IDE, so what is the big difference, do you do it differently in c/c++ ? Does the built in while(1) really matter so much? What am I missing here?

    #include

    void setup() {
    DDRB = 0xFF;
    }

    void loop() {

    PORTB = 0×20;
    _delay_ms(500);
    PORTB = 0×00;
    _delay_ms(500);
    }

  15. ramakant says:

    delay.h got deleted above

  16. Omar Mokhtar says:

    Totally agree with you! I am lucky to find someone who supports the same opinion!

    Add to that :
    - Arduino does not support multithreading
    - Arduino IDE does not support version control
    - Serial communication in Arduino is polling based not interrupt based. Which is the worst thing ever.
    - Arduino provides the most stupid function ever called ‘delay’ !

  17. Vito says:

    Strongly agree!! but…
    if someone what try to understand, can be an easy way…

    i’m poor, so i’d like to reach big results, witout wasting money and resources..so … i try to build all with my hands… i love microchip’s controllers, thath allow you to have the total controll of the programm, by c++ complier (free) !

  18. George says:

    I’m guessing, like you lead off in your introductory paragraph, you wanted something to shock people into skiming through your article. I do agree with much of your article, but your aggressive stance feels so frustrated possibly targeting a previous teacher or course.

    As an aside, it is ironic that an educational page has so many grammatical and spelling errors. :)

    • admin says:

      Hi George,
      I’m not targetting a teacher, but when writing this down I had had many discussions with colleagues about this subject, and I wanted to write it down for myself completely. So yes, it was born out of frustration, but mainly because I was frustrated with the use of Arduinos and the lack of understanding of embedded systems (wasting resources) in an educational system.
      Maybe this is also a good place to write that I was mainly targeting secondary and university education, not primary schools. I understand the use of Arduinos there.

      Regarding the grammar and spelling errors: please indicate what and where, and I’ll correct them. English is not my native language, so I’m happy to learn what can be improved!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>