0

I have Arduino which is programmed to do something. Is it possible that I could allow it to change behaviour by changing program on-the-fly without the need to reprogram Arduino via the computer.

What I need is to send the message via MQTT which will Arduino receive and change its behaviour by it. I managed to change the frequency of messages published or to add some new data, but what if I want to change how decisions are made. What if I want to change some Arduino code, to add some if or another state, can that be done on the fly?

Update: Changing device behaviour on the fly or after restart is acceptable. I am not strict with using arduino, nodemcu is and option. I just need a way to add new functionality to device if I need.

12
  • 2
    On NodeMCU you can upload a sketch OTA (Over The Air) using WiFi.
    – user31481
    Nov 22, 2017 at 23:22
  • But that is using Arduino IDE, isn't it? Is it possible to change some code without need to reprogram it?
    – emir
    Nov 22, 2017 at 23:27
  • 1
    @Peter - you are mistaken. Harvard architecture machines are very much "computers" as well. The arduino is most definitely a "computer". Additionally, although by no means a requirement for being a "computer", the Arduino can alter its own flash, though the process is a bit tricky, and one shouldn't design a scheme to do it repeatedly on an ongoing basis or the flash will wear out. Nov 23, 2017 at 1:53
  • 1
    @Chris Stratton The fact of talking about Harvard had the main purpose of giving a better view of the problem. I played a lot with ASM and Self-modifying code (in the 80') and I see many people struggling, at basic level, with memory problem on the Arduino, because they think of it as a "small computer" when in fact, the principle is different. I agree we can have Harvard or Von Neumann computer, of course :) Cheers.
    – Peter
    Nov 23, 2017 at 14:49
  • 1
    @Peter well, the fact that there is a bootloader able to reprogram the Arduino without an external programmer may tell you that the AVR is indeed capable of writing on its own flash ;)
    – frarugi87
    Nov 29, 2017 at 16:25

5 Answers 5

3

Replacing or modifying the existing code during run-time will require some form of uploading and over-writing the old code. This is deliberately not made straightforward or easy for these kinds of micro-controllers.

But you can change the program's strategy on the fly, if you anticipate the potential changes and include the code for each of the possibilities.

For example, write a set of functions that each embody one of the various ways of operating, and, at run-time, select which function the program should use. You can change the selection by setting a value from the keyboard or the program could sense some external trigger such as a button-press, or a temperature reading and respond by changing the selection - the value of an int, perhaps. A switch statement can use that value to call the appropriate function at the appropriate time:

uint8_t strategy = 0;           // init to the default strategy

switch( selector ){
case(1):                // has event 1 happened?
   func1();
   break;

case(2):                // has event 2 happened?
   func2();
   break;

case(3):                // has event 3 happened?
   func3();
   break;

default:                // none of the above or undefined selector value
   funcDefault();
   break;
}

This does mean that all of the code for the possible operating strategies must be included at upload-time and share the program-memory space, but unless your job is very complex, even an Uno should be capable enough.

Update:

I need to be able to update the device with some new functionality.

There is another approach which may or may not fit in an Uno but would be doable with a Mega 2560 or other larger-RAMmed machine: interpreted code.

  • Define a set of operations that includes whatever you'll need to operate your external device(s): the necessary I/O operations to read your sensors and control your hardware; to make logical and/or arithmetic tests and conditionally branch or call a function based on the test result; to listen for a user-signal from the terminal (for example) and return to the arduino program. This will be the "language" in which you write your control program.

  • Define a concise coding scheme to specify each operation and whatever data it needs, such as reading a temperature sensor and storing the result in a named place. If your control programs won't be too complex, you can get away with pre-defining A, B, ..., Z to be data registers of some appropriate type.

  • In C++, write an interpreter for this new language. It's program will consist of the codes you just defined. But this code will be seen as data by the interpreter. This is the key - this pseudo-code will live in RAM, where your interpreter - a collection of C++ functions - can read and execute it, and the Arduino program can download a new one, over-write the old one, and run the interpreter again.

Caveat: Like the Greek mythological Hydra, this is a job that can grow new challenges as you address the current ones, but it is doable if you keep it simple as possible and include only what you must have to make it work.

Run-time-interpreted code can take 10 - 50 times as long to execute as a natively coded application, so anything that can be pre-coded in C++ should be. The finer and more flexible your interpreted instructions, the more expressive you can be when writing the control program, but the interpreter will be more complex to write, slower to execute, and harder to debug. Design your language to be only as flexible as it must be to allow you to write new control algorithms.

If you try to invent an entire pseudo-computer, completely flexible and capable of being programmed for any and all purposes, you'll drive yourself crazy. Whole businesses have folded after sinking money and time into inventing a new and better computer and got so bogged down they couldn't recover. Don't go that route.

Start with the grossest, least flexible operations you can live with and get that much working. Discover its limitations and address those, and only those, one at a time, until you have a sufficiently flexible system in which to control your device.

1
  • I am aware of this approach, but this would require knowing in advance about what device could do. I need to be able to update the device with some new functionality.
    – emir
    Nov 29, 2017 at 20:13
1
  • Code that writes to flash has to reside in the bootloader section. The only way I know how to execute code in the bootloader section is after a reset. However, even if you could transfer execution to the bootloader section and get something to work, it would have to contend with the fact that flash has limited write cycles and will reduce the life of the device. Possibly to the point of being useless for a practical application.
  • Executing code from RAM. Self explanatory, modify code all you want. There is an application note for AVR that discusses this.
  • Write an interpreter for your needs. yuk!

EDIT: There is some GCC code example here.

5
  • You should be able to jump to locations in the bootloader section provided that you know the assumptions of the code you placed there. You can also do a soft reset. But yes, the flash endurance is an issue. Nov 29, 2017 at 6:28
  • I was not aware of limitation with a number of flashing. Do you refer to firmware flashing or updating a device with code using IDE or over OTA?
    – emir
    Nov 29, 2017 at 20:22
  • Write/Erase Cycles: 10,000 Flash/100,000 EEPROM
    – atland
    Dec 2, 2017 at 13:41
  • The claim about "executing code from RAM" is erronous. That is not supported on an AVR, your link is to a document for an Atmel SAM-series ARM processor, not an AVR. Dec 2, 2017 at 16:51
  • Sorry. Wrong application note. I was wondering why I wrote AVR. It came from this application note for AVR32825: Executing code from external SDRAM Specifically for the AVR 32 UC3A and UC3C series.
    – atland
    Dec 5, 2017 at 8:14
1

You can change the behaviour of Arduino on-the-fly but it's not necessary to reprogram, just design your code to change behaviour with some variables you get form outsite e.g. a server, but this new changes must be defined previously in your code.

If you have a list of states and want to add more, use a dynamic array or use an array with enough space and when send a MQTT message that Arduino parses adding tha new state or even deleting a state.

1
  • I need to see how I can update the device with new functionality which was not previously planned.
    – emir
    Nov 29, 2017 at 20:23
0

Is it possible that I could allow it to change behaviour by changing program on-the-fly without the need to reprogram Arduino via the computer.

(emphasis added by me).

As some answers pointed out, you can change the behaviour if you allow for it in advance. For example, store in EEPROM some setting (like how often something happens) and have a method of changing that setting.


Different bootloader

However if you want to change the behaviour completely then you need to upload new code (whether the code is in RAM or program memory doesn't really change this part).

The bootloader installed as a standard on the Arduinos allows for code to be uploaded via a protocol which arrives at the serial port shortly after reset. There is nothing to stop you writing your own protocol (eg. using MQTT) and make your own bootloader which uses that - assuming it is small enough to fit into bootloader space (the largest bootloader the Atmega328P can hold is 4096 bytes).


Stand-alone programmer

Since you asked about uploading new code without needing to have the computer, an alternative is to program it in the field using a stand-alone programmer. There are various ones around, including one developed by user Crossroads from the Arduino Forum:

Stand-alone programmer

I wrote the code for that one. The basic approach is to write your new code using the IDE (something you would have to do anyway) and then copy the .hex file to a SD or micro-SD card which is then inserted into the programmer as you can see in the photo. The programmer then connects to the target board via a ICSP interface using a 6-core cable as shown. This reprograms the target in about a second. This makes it practical to reprogram a device "in the field" without having to return it to your base, or carry a laptop around with you.

-1

What you need is not a “one trick pony” (arduino) but an actual “horse” - Raspberry Pi. You have no reason not to such as:

  1. Price - RPi Zero - $10
  2. Size - ditto -about the size of a Nano
  3. Functionality::

    Pi . . . . . . . . . . . . . . . . Arduino

wifi . . . . . . . . . . . . . . . . no (wifly /Zigbee now you violate #2)

bluetooth . . . . . . . . . . . . . . . . no

web server . . . . . . . . . . . . . . . . no

mysql database . . . . . . . . . . . .. no

any linux multithreaded apps. . . . . . . .. . . . . . . . . . . . . no

etc etc etc

Did i miss anything? being a technology architect begins with knowing what hardware and software to apply in any given situation. I. E. avoid square pegs in round holes.

2
  • You forgot to mention the RPi Zero won't work without a good quality 4 to 8GB micro SD card for storage (OS, libraries and user programs). You also need a "USB OTG Cable", a 1 amp power supply with Micro USB connector, and if you want to connect it using HDMI, there an adapter required for that too. It would cost me $51.46 CDN plus $5 to $10 for shipping, just to get started with the RPi Zero.
    – VE7JRO
    Nov 4, 2018 at 19:21
  • 1
    Another thing to consider, is whether or not your project needs WiFi, and Bluetooth, and a web server, and MySQL. Why pay for all of this "horse power" if you're not going to use it. The RPi Zero is a computer, and needs to be treated as such. If the power drops on the Arduino, you won’t end up with a corrupt operating system or other software errors: it will just start running code when it’s plugged back in. For Raspberry Pi, you must shut it down within the operating system like any other computer, or else risk corruption and software problems.
    – VE7JRO
    Nov 4, 2018 at 19:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.