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.

  • 2
    On NodeMCU you can upload a sketch OTA (Over The Air) using WiFi. – user31481 Nov 22 '17 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 '17 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. – Chris Stratton Nov 23 '17 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 '17 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 '17 at 16:25
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.

| improve this answer | |
  • 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 '17 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.

| improve this answer | |
  • 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. – Chris Stratton Nov 29 '17 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 '17 at 20:22
  • Write/Erase Cycles: 10,000 Flash/100,000 EEPROM – atland Dec 2 '17 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. – Chris Stratton Dec 2 '17 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 '17 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.

| improve this answer | |
  • I need to see how I can update the device with new functionality which was not previously planned. – emir Nov 29 '17 at 20:23
1

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.

| improve this answer | |
-1

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.

Absolutely yes. As a matter of fact that's how many encrypted code works.

| improve this answer | |
  • 1
    how can that be done? – emir Nov 29 '17 at 23:07
  • check out the datasheet on flash programming. essentially you would encrypt your code and store the encrypted code in the flash -> not executable in its current form. once an authentication has been passed, you decrypt the flash and rewrite the decrypted code into it and then execute the flash. – dannyf Dec 2 '17 at 17:05
  • from the later perspective, you can think of the bootloader as something that does the flashing and execution portions of the process described above. – dannyf Dec 2 '17 at 17:06
  • a different way of saying that would be that the bootloader, + your encryption / decryption / authentication, would be what you want. so that would be a great starting point for you. – dannyf Dec 2 '17 at 17:07
  • 1
    @dannyf This answer has been marked as poor quality. I believe you can improve it simply by adding these comments to the answer itself. Thanks. – sa_leinad Dec 7 '17 at 9:51
-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.

| improve this answer | |
  • 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 '18 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 '18 at 19:21

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