Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Re^5: Call function no more than every 0.1 seconds

by jmlynesjr (Deacon)
on Aug 13, 2020 at 22:44 UTC ( #11120695=note: print w/replies, xml ) Need Help??

in reply to Re^4: Call function no more than every 0.1 seconds
in thread Call function no more than every 0.1 seconds

The Vent project was based on the Arduino Nano processor as most of the rapid prototype team came out of the Amateur Radio community and were familiar with the Nano from the uBitx SSB transceiver( It was constantly on the edge of running out of RAM and EEPROM. If you get above 70% memory utilization at compile time you stand the chance of seeing a stack overflow at runtime. In the end all the 3rd party libraries were replaced with internal code with the minimal required functionality. Arduino libraries tend to be bloated, blocking, and poorly documented. That said, it's an easy system to learn and works well for personal hobby applications where setup(), loop(), and delay() aren't an issue. It's much more involved to setup a pseudo real-time environment.

There is a way to tell the compiler to move constant strings into the EEPROM. I'll look it up and get back to you.


There's never enough time to do it right, but always enough time to do it over...

  • Comment on Re^5: Call function no more than every 0.1 seconds

Replies are listed 'Best First'.
Re^6: Call function no more than every 0.1 seconds
by afoken (Canon) on Aug 15, 2020 at 12:09 UTC
    The Vent project was based on the Arduino Nano [...]

    That's an ATmega328, 5 V, 16 MHz, 32 KByte Flash ROM, 2 KByte RAM, 8 bit AVR core. It's a nice microcontroller, and it once was impressive.

    Compare to the Arduino Zero:

    ATSAMD21G18, 3.3 V, up to 48 MHz, 256 KByte Flash ROM, 32 KByte RAM, 32 bit ARM Cortex M0+.

    It easily runs circles around the AVR at less power, and you really don't have to worry about memory or CPU speed as much as you have to do with AVR processors.

    Note: This microcontroller was not designed to be fast. It was designed to be cheap and low-power, for battery-powered gadgets, probably running directly from a lithium primary cell (CR2032 or similar). And still, it runs circles around the AVRs. Of course, if you let it run at 48 MHz with no strict power management, it will drain a CR2032 quite fast. But as long as you have a battery pack or mains power, you don't have to worry about power management. It won't get warm or even hot. Your peripherals will most likely need much more power than the SAMD21.

    One obvious problem when migrating projects are the voltage levels: AVRs on Arduino usually run at 5 V. They could run on 3.3 V and even lower, but the AVR core can't run at full speed with lower supply voltages. Or at least, that's what the datasheet said. Maybe it will run at full speed at 3.3 V, but that is out of spec. The SAM needs 3.3 V I/O voltage, the core runs on a much lower voltage (using an integrated LDO regulator). Interfacing CMOS components (any of the 4000 and 4500 series) is usually a no-brainer, they just work as well on 3.3V. The same is true for many IC and SPI components (EEPROMs, ADCs, DACs, port multiplier). When driving bipolar transistors, you may need to reduce the base resistor a little bit. Driving MOSFETS is again often a no-brainer, they are voltage-driven, not current-driven. But you may have to check if the MOSFET actually switches with a gate voltage of only 3.3 V. Some don't.

    Another, closely related problem is the current sink and source capability of the microcontroller. The AVRs can sink or source 40 mA, depending on the Model. The SAMD21 can sink or source only 2 mA, switchable to 7 mA. So if you drive "high" current components directly from AVR pins, you will need some kind of amplification - a transistor, a logic buffer, or (for analog pins) a voltage follower. If you drive an LED directly from a pin, you need to change the series resistor and perhaps have to change the LED for a low-current, high efficency one.

    The SAMD21 does not have an integrated EEPROM. There are some few models that can transparently emulate an EEPROM using a part of the internal flash, but none of them can be found on an Arduino board. But it should be possible to use the self-programming capability of the SAMD21 to manually emulate an EEPROM in the internal flash.

    Comparing the prices:

    At work, we really like the SAMD21, it has retired the ATmega series within weeks. No new project uses ATmegas any more. The SAMD21 needs less power, is faster, has more resources, more peripherals build-in, more I/Os, has up to six highly flexible SERCOMs offering IC, SPI, and USART in a single peripheral, and is cheap. Less than 3.00 for the top-model SAMD21J18A, less than 1.50 for smaller ones.

    Plus, the big Sparkfun breakout board linked above is a really cheap way to prototype a new device, as almost all controller pins are available on pin headers. At less than 30.00 delivered, we even don't care if we kill one of those boards during development. (So far, we have not managed to kill one.) Yes, it lacks the EDBG. But we have plenty of ICE programmers available, so not having an EDBG blocking pins is actually an advantage for us. The smaller Sparkfun board does not bring out all processor pins. Not a big deal for most projects, but sometimes you really want all pins. So we prefer the larger board.

    See also:


    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      The Team was a group of around 200 Hams from around the world that had a lot of experience with the Nano from the 10,000+ Bitx40 and uBitx transceivers delivered around the world. When the project started in March we were told that Florida would be out of Vents by mid April. People were literally working around the clock on hardware and software design and testing. A sprinkler valve was tested to over a million cycles. The supply chain was shutting down, but the Nano was still available in large quantity. The Bitx PCB design was easy to modify to support pressure sensors, solenoid drivers, and push buttons. It already supported an LCD display. You would not believe the difficulty in sourcing sensors and components during this time period.

      There were dozens of threads discussing alternate processors among our group members and members of other international teams. Our group did not have the time to switch. All design information was open source, so other teams were encouraged to modify our design to match locally available parts(this was a prime design objective). My suggestion was to mount a pin header instead of the Nano and let others plug in whatever processor they could get. Software porting was up to these other teams.

      The bottom line was that a fully functional Vent was designed and ready for manufacture by the end of May. A Nano, a PCB, a sprinkler valve, two washing machine pressure sensors, a 3D printed relief/safety valve, and the code - estimate $200USD - provided greater functionality than the $20,000 commercial Vents now on the market.

      I believe several groups in Europe used higher end processors. India started with the Nano.

      Thanks for your input.


      There's never enough time to do it right, but always enough time to do it over...

      Thank you for posting this, looks like I'll have to get this µC to try for my next project ;-)

Re^6: Call function no more than every 0.1 seconds
by jmlynesjr (Deacon) on Aug 14, 2020 at 00:24 UTC

    Sorry, I know this is not ArduinoMonks, but to close the loop... From: "Arduino Projects for Amateur Radio" by Jack Purdum, W8TEE (Any book by Jack is an excellent reference)

    The F() Macro

    Suppose you have the following statement in your program code:

        Serial.println("Don't forget to activate all of the external sensors.");

    The message contained within the double quotation marks in the statement is called a string literal. A string literal is a sequence of text characters that does not change as the program executes. These string literals are imbedded in your program's memory space and, hence, do use up Flash memory. The problem is that the compiler sees these string literals and copies them into SRAM just before the program starts executing! In other words, the same string literal is duplicated in Flash and SRAM memory! With the message above, you just wasted 53 bytes of precious SRAM. However, if you change the statement to:

        Serial.println(F("Don't forget to activate all of the external sensors.");

    Note that the string literal is contained within the parentheses of the F() macro. Without going into the mechanics of how this works, the end result is that the F() macro prevents the compiler from copying the string literal to SRAM.


    There's never enough time to do it right, but always enough time to do it over...

      the end result is that the F() macro prevents the compiler from copying the string literal to SRAM

      That's perfect, thank you very much! I've worked with other compilers that did this by default, but I guess this is fine too.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11120695]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (7)
As of 2022-01-21 11:20 GMT
Find Nodes?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:

    Results (57 votes). Check out past polls.