How can I run multiple programs on an Arduino? I'm trying to get students to experiment with Arduino. However, due to a lack of boards, two teams of students will collaborate on each board. They will push their own code (independent from each other) and use half the pins.

The "hardware" part isn't really a concern: students will push their sketches on a server that uploads them on the board, or something like that.

What I'm worried about is the software part. How can I allow two sketches to run on the same board, and allow the user to upload sketches without resetting the board?



As of my understanding, using the flash memory isn't an option, because the board must be reset before it can be written.

My first idea was to compile the students' C code into custom-made "assembly", and then push the assembly code to the board, which stores it into RAM and interprets it. However, my biggest problem would be implementing functions, I don't really have a clue of how I could do that. While common C functions could just be encoded in a fashion like FUNC printf STRING %s VAR a for printf("%s", a), I don't know how to encode user-defined functions. Besides, I don't even think the RAM is sufficient for running the client, storing two small programs, and running them.

Then, I thought about running the C code on the computer, but replacing digitalWrite with appropriate signals to the board. However, I'm worried about the performance of this, mostly when dealing with "high" speeds - say, using a custom-made library to print text on a LCD driver.
In addition to the other answers, I have a few ideas:

1.) Instead of doing variable prefixes, have them wrap all of their code inside a namespace! Please note that you can't wrap "setup" or "loop" in that namespace. Example

setup() {
  if(conditionIsTrue) {
    aGroup::setup();
  } else {
    bGroup::setup();    
  }
}

loop() {
  if(conditionIsTrue) {
    aGroup::loop();
  } else {
    bGroup::loop();    
  }
}

namespace aGroup {
setup() {
  // Code
}

loop() {
  // Code
}
}

namespace bGroup {
setup() {
  // Code
}

loop() {
  // Code
}
}


2.)

Please note you'll have issues with a student tries to access an analog pin and doesn't prefix it with A. For example, if I wanted analog pin 5, I should do analogRead(A5);, not analogRead(5);. That could cause some major issues.