The Inner Machinations Of The Arduino Are An Enigma

Arduinos have been the microcontroller platform of choice for nearly two decades now, essentially abstracting away a lot of the setup and lower-level functions of small microcontrollers in favor of sensible IDEs and ease-of-use. This has opened up affordable microcontrollers to people who might not be willing to spend hours or days buried in datasheets, but it has also obscured some of those useful lower-level functions. But if you want to dig into them, they’re still working underneath everything as [Jim] shows us in this last of a series of posts about interrupts.

For this how-to, [Jim] is decoding linear timecodes (LTCs) at various speeds. This data is usually transmitted as audio, so the response from the microcontroller needs to be quick. To make sure the data is decoded properly, the first thing to set up is edge detection on the incoming signal. Since this is about using interrupts specifically, a single pin on the Arduino is dedicated to triggering an interrupt on these edges. The rest of the project involves setting up an interrupt service routine, detecting the clock signal, and then doing all of the processing necessary to display the received LTC on a small screen.

The project page goes into great detail about all of this, including all of the math that needs to be done to get it set up correctly. As far as general use of interrupts goes, it’s an excellent primer for using the lower-level functionality of these microcontrollers. And, if you’d like to see the other two projects preceding this one they can be found on the first feature about precision and accuracy, and the second feature about bitbanging the protocol itself.

88 thoughts on “The Inner Machinations Of The Arduino Are An Enigma

      1. Arduino doesn’t even move the needle for number of microcontrollers used in the world. It’s a very niche framework used by noobs and people too lazy to learn anything else. Nothing wrong with that, but the “of choice” claim really needs a qualifier, because microcontrollers are inside so many things in the world and arduino is simply not. Microchip sells a billion MCUs a year, none of them running arduino code. Yes, arduino is the framework “of choice” for people that aren’t doing anything in any real quantity, and that’s where “of choice” ends.

        1. The microcontroller of choice these days is anything you can buy, unfortunately. And as for noobs and lazy people, it’s a bit unfair I’d say. The Arduino framework offers massive portability and quick time to “first blink” not to mention a gigantic user base and excellent documentation. I wish I could say that for the SAME70 I’m working with now, or Microchip Studio. It also means that during early development, you’re not locked in to one chip, or even one vendor, and if you want to dig deep, then it’s all still there. Arduino covers 95% of what 95% of users need, and that remaining smidge isn’t worth getting uptight.

          Arduino has changed the world for everyone, and we have more and better EEs and CSs as a result.

    1. Your choices are basically either Arduino, or nothing. There really isn’t much else out there that’s worthy of being called a “platform” in the embedded space.

      (Ok, there might still be some weirdos trying to make mbed happen. All I can say to them is godspeed.)

      1. Something like the 328P or the AVR family in general are not that difficult to master. It’s just a case of helping too much with Arduino, so you’re not really helping at all. Teach a man to fish etc.

      2. Gratefully, the Arduino Uno/Genuino Uno board can be built at home, at least.
        So there’s the possibility to build your own compatible boards once the official Uno is no longer sold.

        Chinese producers do (legally) take advantage of this option, too.
        The original bootloader was replaced by Optiboot years ago, also, which is compatible but smaller.

        I think that’s what contributes to the charme of the platform, also.
        Being both able and allowed to just build a custom board that serves a specific function.
        All it needs is an ATmega328p, essentially. Or it’s predecessor.

        Last but not least, the mother project, Wiring, can still be used as an alternative.
        The early release of the Arduino IDE was heavily derived from the project.

        Last but not least, AVRdude can create Arduino Uno compatible binaries since a while, too.

        1. But why would you? It’s easy enough to do whatever you want with an AVR instead of replicating the Arduino. You don’t really need the bootloader for anything and trying to use the Arduino platform for any further development just stands in your way.

          1. Why is the Raspberry Pi so successful, but other Linux SBCs aren’t successful ?
            It’s not the hardware, it’s the community/ecosystem.

            The Arduino has many neat projects and there are many nice souls that work on them. The Arduino platform connects these people who otherwise wouldn’t do any homebrew (anymore).

            Some of them come from the ex home computer platforms, also. They know how to program and how to interface off-the-shelf components to an USER port.

            However, they may not feel comfortable building everything from scratch. Or if they have to use C/ASM-compilers only. That’s when Arduino/Pi come in handy.

            They provide a common platform fir these guys. So they can assist each others and work together.
            If all of them had to build same hardware from scratch, the motivation would be quite a bit lower to get back to homebrewing.

            And the Arduino IDE provides some sort of hardware abstraction layer, too.
            Thinking how horrible development for the PIC platform was.
            Each PIC had a different instruction set/architecture. Projects originally made for the PIC16C84/PIC16F84 weresln’t usable on other PICs. Also, because ASM sources and HEX files were common. Atmels AVR series was less extreme, by comparison, but the chips were still not able of being drop-in replacements.

            PS: Sure, the bootloader isn’t absolutely necessary. However, it’s not hindering, either. Optiboot is quite small. Using it during software development is less annoying than using pin headers+an ISP plug or removing the ATmega328p each time for re-programming in a TL866 (which I still do often, nevertheless).

            Oh and I’m one of those few sickos which like to have a traditional serial port on my Arduino compatible (no USB). For interfacing with a serial terminal or a 486 PC, for example. ;)

          2. > it’s the community/ecosystem.

            Or marketing and finding the right time for the right product. It’s hard to pin down what really did it.

            >few sickos which like to have a traditional serial port on my Arduino compatible (no USB)

            Getting real time performance out of the USB stack is sometimes very difficult because it can be hung up by the computer at the other end, and then your buffers run full and everything crashes.

        1. Pi Pico has instantly become my favourite platform.

          Good documentation, pico-Sdk sits you at an int main. Arduino environment support if you want it.

          Flash a second pico to make a debugger/programmer.

          I think there was mixed messaging on release, and people thinking it was micro python only, or heavily focused.

      3. TI’s arm based processors (and MSP430s for low power/cheap applications) come with hacker friendly evaluation boards and documentation for days. The libraries are a bit harder to use but that is just the result of more people from more diverse needs putting in more time on Arduino.

      4. Nobody needs Arduino to do anything with microcontrollers, it’s a convenience, and for some, a crutch. A microcontroller, an assembler, and a device programmer is all you really need.

  1. As always, remember that the Arduino libraries themselves do stuff with interrupts, which can really glitch your code if you expect your interrupt to repeat with regularity. You can disable the other interrupts quite simply by writing to a register, but then you lose stuff like serial comms, the millisecond counter, one-wire, servo libraries, etc. and you have to re-implement them yourself.

    That’s the problem with Arduino – there’s quite a steep climb from doing a thing from an example, and mashing up multiple things in the same “sketch” because they give you very poor documentation about what you’re actually doing and how it may conflict with other stuff.

    In the end, it’s often easier to just open the data sheet like you should have in the first place and throwing whatever Arduino is doing up in the winds, but that’s not easy when you come from a “maker culture” which treats the technology more like alchemy than something actually understood by the audience.

    1. >In the end […]
      Yes. Especially i want to emphasize that using Arduino does not mean you should not look at the datasheet. It might be hard to understand for a beginner but if you want to progress you will have to work a little bit more than copy and paste code from the internet… I’ve seen people wiring DC motors directly to the Arduino and wondering why it does not work (or does produce smoke)… And don’t forget that an Arduino-whatever is basically a PCB with an AVR and some other stuff, it is perfectly fine to only use their hardware (or clones…) and write your own firmware from scratch in C or even Assembler if you really need to.

      1. What I find is that people coming through the educational system are taught to solve problems, not look for solutions. The Arduino “ecosystem” is geared in this same way – to provide the necessary starting conditions and then having the people go through the motions to get particular end results. They are taught methods and algorithms, not how you actually solve problems in an independent, creative and critical way, so you end up with people who explicitly do not search for or read data sheets unless they are given a data sheet and told which page to read.

        This is not helped by being “helpful” and pushing you directly towards the goal. The more sinister point about this is that it pushes people towards sellers that give you parts without so much as telling you what they are, so it creates a culture of canned tricks where people will always return back to Arduino and the affiliated sellers – not for any real competence or understanding. The training wheels are permanently welded to the bike: without knowing what you’re fundamentally doing, never having gone through the trouble of figuring it out, you can’t extrapolate.

        1. I’d argue you are taking the position to rather an extreme – making the core functionality simple enough you can get started easily doesn’t preclude you from digging deeper, and being opensource in many ways that digging is actively encouraged. At least if you are the type of mind that actually can deal with the raw abstraction free environment its all there for you to dig into. With a huge body of working examples you have already used and can now study to understand how they take x and y, do some black magic to get 42…

          Not everyone is wired up in a way that suits pure number theory, or working at the rawest of the raw flapping butterfly wings to binary program – Platforms like Arduino let these people get some understanding of how it all works. Even if its to the expert a toddler level oversimplification that is much more understanding than they would have without, and some folks will find ‘hold on a minute I actually see the matrix holding this together, lets see how deep the rabbit hole goes!’. Which without such a platform they are unlikely to do – rather hard to know you want to learn about something if you don’t even know it exists, and with any computer more modern than perhaps the earliest generations of 32 bits you are not going to find out this rabbit hole of electronics exists unless you have that techie relative, after school club, really decent teacher willing to go off on tangents not strictly on the curriculum to expose you to it.

          1. But what IS the core functionality? I’d argue the timers and counters, peripherals, interrupts etc. are what makes the controller useful rather than the convenience of being able to digitalWrite() an arbitrarily labeled pin. This is exactly what the Arduino environment hides away and the documentation even tells you not to manipulate your registers because it’s a “bad idea”. Go see what it says about direct port manipulation in the online programming documentation.

            I find that the abstraction doesn’t make things any easier – it just changes the syntax and semantics to a different one with equal or worse complexity and a lot of problems and gotchas. Poking bits in a register is easy and has concrete results – figuring out how object oriented C/C++ really works so you’re not just cargo-cult programming your stuff is hard.

            >With a huge body of working examples

            There were such things like AVR Freaks that documented this stuff and showed you how to do it. That’s how I got into it. Only difference is, they didn’t wrap it up in a layer of mystery and “convenient” library functions – they just told you how to do it.

          2. Poking bits in a register is easy to understand and has concrete results, learning object oriented C/C++ to understand what you’re doing, instead of doing cargo-cult programming with stuff you don’t understand, is actually hard.

        2. “Culture of canned tricks”
          This is so in many technology fields. To the point where we say “technology has advanced so much”, but the base technology has not advanced. Rather we have come up with new ways of stacking the same lego pieces. It’s a hard nut to crack, inventing genuinely new technologies.

    2. “because they give you very poor documentation about what you’re actually doing and how it may conflict with other stuff.”

      Well… Basically all the libraries are open source, right? So, the source code is the documentation. And there is no more detailed documentation than the source code. :)

      Granted, the documentation (as in: the source code) might be unreadable, if that documentation was written by people who never read ‘Clean Code’ by Doctor Martin. :P

      1. I agree that the code should be better structured and be written to be understood, not just write-only code. But Uncle Bob is hardly a gold standard to apply to C/C++ code, since a lot of the clean code dogma is around a Java-centric ecosystem and best practices that work well in that language that don’t all translate to other platforms equally well. Other criticisms of Uncle Bob are summarized here, there are some cracks in the armour: https://blog.wesleyac.com/posts/robert-martin

        1. Ugh, C/C++.. No, please no. Away with it. 🤢

          The hardware tinkerers of the 1980s/1990s prefered BASIC (home computers, CP/M machines, 8052 AH BASIC SBC boards), Assembler and Borland Turbo Pascal for a reason..

          On Windows 3.1/95 PCs, it were RAD environments like Visual Basic 1 to 6, Delphi. Both not bound to object-oriented/-based programming, gratefully!

          C/C++ are a hellish idea for low-level/microcontroller stuff. It’s a bloated high-level labguage, far more than Pascal and Basic. It’s nice for OS development, but it’s not very suited for bit-banging at the hardware level. If you’re going to do timing-sensitive things, the order of processing might be important. Procedural programming and ‘spaghetti’ code are much better or safer here, because being predictable.

      2. Then there’s the point that even if you are competent enough as a programmer to read the source and figure out what it does, the conflicts are still there and the library doesn’t do what you want to do.

        You can try to fix it, fight the river to push it upstream and have your fix implemented, wait for other people to fix it, or just conclude that it’s never going to happen because the system is built for the lowest common denominator and not for you, so you have to pick up the data sheet and code your own routines anyways.

    3. It falls apart pretty quickly for non-trivial applications. Reminds me of Verifone TCL code. It was a very quick way to write an application for a credit card terminal. “M N L” will read the magstripe, print that, and repeat. That’s a lot of code in ASM, which was the only other option at the time. But applications got big and complicated, and there was NO protection against accidentally overwriting code. In fact it was a “feature” unless it was someone else’s application overwriting yours. I’ve been writing AVR code since before the 8515 was released (I had a sample chip with date code “ES”) mostly in assembler. I found it WAY easier than dealing with the PIC chips of the day.

      IMHO, Arduino makes the easy things easier, and the hard things harder.

  2. The thing with the arduino libraries is that they give people a starting point – from there they might go nowhere further ie staying with a one page ardunio library based program OR they may get more and more involved it writing the code themselves, and slowly replacing the ardunio libraries for how they want to do it.

    In addition, the ardunio libraries are a great example of source code that does something with the hardware, and much external hardware. It is sometimes very useful to look are what people have done for an ardunio library, and the data sheet, to figure out how something works.

    It is also not a bad path to go on to eventually not use them at all on another chip, or even on a chip that does have them ie I do a lot with the esp32 and don’t use the ardunio libraries at all.

    1. A starting point in the sense that a box of lego is a “starting point” to building a bridge of some sort, but you’re never going to build actual bridges out of lego. At some point you have to throw the legos away and learn actual structural engineering and material sciences, which is almost as good as starting from scratch.

      It’s not a platform you can really build on in the greater sense – more like an introduction to a concept – unless you want to make a career at designing kits for LEGO, or Arduino for that matter.

      1. There are a lot of people without engineering degrees, who just want to build stuff. If an Aduino gets the job done, quick and cheap, why not? Not everybody is looking to make a career out of it, or produce comercial products. Basically, it’s a hobby. we aren’t going to quit our day jobs, which pays our bills, feeds our family. For some, and arduino isn’t going to cut it, for what they want to build. They will either abandon the idea, or learn what they need to make it happen.

        Of course, some would say why bother building anything, when you can just buy off the shelf…

        1. Heck, there’s a lot of engineers that just want to build stuff. I’m an ME, got the PE license and everything. But I’ve got no interest in digging into the details on all this, I am perfectly happy standing on the shoulders of others that make everything go.

      2. I’ve got around a dozen Arduinos around the house doing small tasks. To me they are an actual bridge, in the sense that they actually work and do their job. Sure, it’s not a commercial grade product, but they let me solve a one-off problem quite fast and far easier than going to bare chips and bare metal programming.

        Just because something is simplified doesn’t mean it doesn’t have a legitimate place. As they say, “if it’s stupid but it works it ain’t stupid”.

        1. I get the use of Arduinos as a “poor man’s PLC” of sorts, but then you can actually buy a real PLC for less than $100, sometimes as low as $50 which is already in the Arduino plus IO interface shields territory, and they usually come in ladder logic or flow diagram programming styles so you actually have to learn less to use them.

          1. >Very limited functionality.

            For a specific domain of problems. However, what I find is that people think they need the Arduino because the solutions they’re going for are over-complicated for the task – like using a hobby servo where a solenoid would do the job. Of course the cheap and simple PLC is limited for not being able to control the servo, so it seems like you need the Arduino.

      3. I think you would be surprised at just what is possible with Lego, and a bottomless pit of money to afford enough of it… Even without Technic you can use advanced building technique to create stiff and strong structure overcoming the low clutch force of the bricks, with Technic it becomes easier – you really could build an actual bridge – its just going to cost an absolute fortune.

        But the way of thinking about material properties (especially the lateral thinking of using something out of it ‘traditional’ mode), loading, counterweights and balancing strength to weight etc of structures very much still applies to Lego, all the same mathematics can be done. Its a rather solid ground work for moving on to bricks and mortar if you care to treat it that way, as all you end up doing is using a different collection of material properties sheets.

    2. One thing I do find Arduino very useful at though is quickly testing some concept, because you don’t have to re-invent the wheel every time. Need to test an I2C sensor really quick, or turn a stepper motor back and forth to test a mechanism? There’s a library for that. It’s a great developer tool for once you already know what you’re doing.

      1. +1

        Also, sime commenters make it sound as if we’re totally beginners, just because we don’t memorize all the PIC/AVR registers. In reality, we do at least understand the conceptual working of the chip and have/will develop a basic understanding for electronics. So we haven’t lost total control yet. We’re more than just monkeys pushing some buttons. The chip isn’t a total black box to us, we have the datasheets available if we need. For example, checking the fuse settings. Or the reference clock rate. Things like this. Plus, the source codes and libraries often contain comments, that we will use if needed.

      1. Been there….

        Arduino IDE 2.0 has debugger support, but most hardware requires so expensive debugger hardware (other than Arduino Zero). In fact I might just buy Arduino Zero and use it when I’m needing a proper debugger.

      2. ROFLMAO! I usually dedicate a couple of I/O pins for debug, like set pin high when entering interrupt, set it low on exit. That tells me in realtime on a scope when that int is happening and how long it took, and fortunately SBI and CBI don’t mess with registers. I usually use a couple of ring buffers to store the task ID of an interrupt and of major routines, so I have a “black box” of what the system was doing when it crashed, expand and tweak as needed. At the end of main, a “sanity check” routine that is customized to the package, but always checks things what is the value of the stack pointer (it should never change) key registers, etc, which executes single WDR instruction if and only if all tests pass, otherwise the WDT reboots the system.

        I have a little routine called “ping” that can send me a byte on an i/o pin timed so that the ones and zeroes are the same width. I have stacked up as many as 50 ping commands to communicate system state which I then read on a scope by single shotting it and reading off the bits.

        Horses for courses.

        Serial is just way too slow for many things.

  3. Maybe I am in the last generation to read the chip datasheet and work it out. Interrupts on the avr are really easy. But what do I know, embedded systems engineer since 1983 and AVR enthusiast since before the 8515 was released.

      1. “everyone”? Not hardly based on decades of expereience on the MIT Piclist, my own AVR chat group (several thousand members at it’s peak and more than 10 years running), AVRfreaks, and various Arduino forums. As the saying goes, if I had a dime for every email I’ve sent starting with “It says here in the data sheet” I could probably retire. :) But I wouldn’t want to, I LOVE my job!

        “Grandpa” is a badge I wear with pride, father of two, grandfather of two, and almost 40 years as an embedded systems engineer, designing for companies like Verifone and Hunter Douglas. I’m almost 65, and still setting the state of the art in my field. Two patents, and one more very significant one recently applied for. I’ve solved some NASTY problems in my time, including several silicon bugs in Atmel and other companies chips. How big is your slide rule? :)

      2. Dont be rude and call random people grandpa. Show some basic respect. You don’t want to be called a toddler either, I am sure. How comes people feel it’s okay to cross these boundaries with strangers or assume their family status?

  4. Arduino 20 years??

    Oh wait, I guess you can start counting back to when Wiring was invented in 2003 by Hernando Barragán (who was Massimo Banzai’s student… but that’s totally a coincidence…).

    1. Wiring is important piece of history IMHO and shouldn’t be forgotten.. The Arduino Uno (or that prototype with rs232) wasn’t his invention, however? The big success came later with the ATmega168 boards (meanwhile upgraded to ATmega328p), didn’t it? 🤷‍♂️

  5. Some of us here just want to get stuff done and dont have time or inclination to get into the nitty gritty of micro-processors. Not that I’m not interested – I’d love to do it, but there are other priorities such as building machines that make agriculture more practical and efficient, going off grid, etc.

  6. My son and I used interrupts on the Arduino very effectively on a project we did a number of years ago. This was our first electronic project so we were pretty naïve about the hardware side of things, although I’ve been a software guy my whole life. We built a small robot that we controlled with the remote from our DVD player. It turns out these remotes modulate an IR carrier wave to send pulses of different widths that encode the bits. You can buy a cheap sensor to demodulate the carrier wave and then it’s just a matter of timing the width of the pulses, which a small interrupt handler on the Arduino can do very nicely. Here’s a bit longer explanation: http://geekspiel.blogspot.com/2009/02/ir-receiver-circuit.html

    Some of the criticisms here of the Arduino platform sound like Marie Antoinette: “Let them read datasheets!” It’s a great platform for beginners to get quick results, and some of them will be inspired to go further. There’s a fantastic maker community online and if you want to you can learn to do anything. Arduino should be seen as something like a “gateway drug” for DIY electronics.

    1. That’s the common argument, but I see Arduino mostly as a tool to sell Arduino – it helps you skip over so much stuff and sets the expectations so high that you’re stuck in the woods trying to do it properly from the ground up, so you just end up buying more Arduinos and the associated ready-made hardware that lets you operate above your actual skill level.

      1. Someone elsewhere was asking about programming them, and I gave some broad pointers based on my experience with C.

        I got curious, so I bought a cheap book about Arduino. I’m sure beginners get something out of it, but therewas nothing there for me. Way too simple.

      2. You sound like someone who is highly skilled, but may have forgotten what it is like to be a beginner. There are many alien concepts to learn when you are first exposed to computers, and many more when you encounter digital logic at the hardware level. I submit that there’s nothing wrong with eliding most of that complexity for the beginner so they can learn basic concepts and get motivated by immediate results. If most of them never go beyond that, no problem! The ones with a knack for it who get intrigued can go deeper. In the meantime, you can do a lot of things with an Arduino without plumbing the deeper recesses of its functionality. If that makes it easier, great! For example, as a software guy I’ve written lots of assembly code but I would always choose a higher level language if I can. I just got a Raspberry Pi Pico W and I’ve decided to do my first project with MicroPython, because it’s easier and looks like it can handle what I want to do.

        I had a professor at MIT who taught Transport Phenomena, one of the most math-heavy courses ChE majors take. I would come to class hoping he’d explain the chapter we just read, but he always assumed we had mastered that and spent the lecture discussing some further extension of the concepts. I couldn’t follow him at all, but I took copious notes and hoped I could figure out later. I noticed that everyone else in the class was doing the same thing…except for one guy. He sat on the front row and took no notes, following the professor with rapt attention. Periodically he would just nod his head. The professor, delighted to see understanding in the eyes of at least one student, focused all his attention on him. You might think this guy was just a suck up, but he aced every test and ruined the curve for the rest of us. One day I had an epiphany: this is the guy who will be a professor himself one day! And our professor was just like him back when he was an undergraduate. It occurred to me that’s why many professors are such bad teachers. They simply don’t know what it’s like to not understand, because it made sense to them the first time they heard it! It’s like standing on top of a tall building and trying to guess which person on the ground is tallest. You don’t have the perspective to see it.

        Arduino is a better teacher than you think because it meets students at a level of understanding they can handle. Most won’t graduate to be a hardware designer, but they are still enriched by the level of understanding they gain from the Arduino. And it is a practical tool for doing many interesting and useful things, even if an expert doesn’t need the help.

        1. I think this is perhaps the most eloquent way of putting the idea I’ve seen.

          Even for those of us usually on the understanding everything side of things there will be a subject we are coming into too blind to just understand, or maybe that requires thinking in a way we just don’t. At which point we will suddenly be happy for whatever the Arduinio equivalent for that subject is! Accessible enough for the novice and a good introduction and foundation for going further!

          (Though for me most professors are terrible teachers because they don’t have presentation skills their delivery often punctuated with so many ‘erms’ ‘ums’ and ‘oookaays’ the actual meaning starts getting lost, and often won’t actually finish any thought outloud either having distracted themselves with the pauses… We actually called one of our worst professors Dr Erm – as probably 50% of the noises made during a lecture were some form of erm, very smart bloke who communicates clearly when you get to talk to them but hopeless in the lecture.)

      3. Why don’t be honest to yourself for a change and build everything from ground up, as it was normal in the 1970-1990s? :)
        Get a bread board or do some etching at home.
        As someone who’s worried about the world turning into total consumption, I’m dead serious about this.

        Also, the Arduino Uno board itself is open, the complete schematic and bootloader is available online.

        https://www.arduino.cc/en/uploads/Main/arduino-uno-schematic.pdf

        https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf

        See? No need to support Arduino company financially by buying their stuff. The Uno essentially is just the chip with some headers, anyway. Your own design will be free and independent. It’s the Arduino community that’s great and it’s not paid by Arduino.

  7. At the risk of writing a comment few will read, and to add a solitary datapoint to the often contentious discussion about arsuino vs. micro, I started with arduino and eventually got sucked into learning to use micros as I wanted to exceed the limitations that are inherent to abstraction. Now I use both…

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.