3

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.

  • Can you source the bare AVRs and USB-UART bridge modules instead? – Ignacio Vazquez-Abrams Feb 3 '15 at 20:24
  • 3
    Very very hard. Where can I send the money to help you purchase enough Arduinos so each kid can have one? Getting more Arduinos is an easier solution than "simulating" multi-tasking. – Jasmine Feb 3 '15 at 21:22
  • 3
    Why don't you just have them wright normal programs and swap the board back and forth? one person codes, the other testes, repeat. Or if you want to get this complicated with a server and everything, what about just using an avr emulator for half the class's code? some work pretty well. – BrettAM Feb 3 '15 at 21:50
  • 3
    Your time would be better spent engineering a simulation environment to make progress less dependent on the hardware, than on trying to get some sort of pre-emptive multitasking running on the board and lock out constructs such as interrupt handlers which would have global effect. Realistically, I'd say only a small minority of my firmware development time consists of testing on hardware (though that does sometimes involve extended periods), but be reasonable about the fact that the hardware (or at least its alternatives) costs about what students will spend on two lunches. – Chris Stratton Feb 3 '15 at 22:32
  • 2
    Not what you asked per se, but I buy these,they work well and are liable to be well below what you pay now. Other models available from same source. I have no relationship with them other than as a happy customer. – Russell McMahon Feb 3 '15 at 22:42
4

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.

2

How can I allow two sketches to run on the same board, and allow the user to upload sketches without resetting the board?

This is "easily" dealt with as long as you can enforce certain minimum disciplines.

Students must only use assigned pins.

Identifiers (functions, variables ...) defined by a group must always be unique to that group. This can be as simple as eg always starting with a group specific symbol or eg one group NEVER using a z in names and the other ALWAYS using Z etc. Annoying but easy.

Loop() contains calls to two non-terminating functions eg Group1() and Group2() All code for Group1 is in Group1() and ....

One digital pin is assigned for Giulio's use.
When GiuliosPin is low the system executes Group1() - and never exits it until restarted.
When GiuliosPin is high the system executes Group2() - and never exits it until restarted.

I uses a system very close to the Group1() / Group2() selection for my own purposes to allow multiple sketches to be compiled at once - but I use a constant which is set as I compile to choose which to run. My concern is the ability to test multiple code fragments.


Added:

After reading Mac's similar answer I see I missed mentioning Setup().
Code from both users can be merged into the same Setup() as the identifiers are unique.
Or the Setup() function for each Group can be carried out inside their unique Groupx() function with a "run once" function at the start of their code. This is a matter of programming discipline and not in any way hard per se.

  • Although this isn't exactly what I was looking for (I was aiming at a board where students can upload their code and see it "live", not upload a series of sketches and run one of their choice), this looks like a step in the right direction. – Giulio Muscarello Feb 3 '15 at 23:03
  • @GiulioMuscarello multithreading isn't an efficient solution, if that's what you're looking for. I would recommend checking a small switch at the start of the sketch so you can tell if it should run A or B. – Anonymous Penguin Feb 4 '15 at 14:10
2

There is no native multitasking on an Arduino. A few solutions have been suggested above, all of which depend on cooperative multitasking - each half has to play fair.

An alternative may be this:

Buy some AtTiny chips - e.g. AtTiny 24a; they are about $2-3 each. Buy some VeroBoard. Solder the AtTiny on to the board, so each verboard strip has 2 pins on it (not the other way, where each veroboard strip has half of the pins on it). Solder on some pins, cut the track between the pairs of pins, and cut the board to size. You should be able to get a working board, with 12 usable pins per board, and you'll be paying less than $5 per board in your local currency. Buy a USBISP, and hook up the pins, whenever you need to program them - I suggest using the FreeTronics programmer, like this one here: http://www.jaycar.com.au/productView.asp?ID=XC4237 - you can solder 2 pins for the "slow clock" option - you'll need this. Optionally, you could make an adapter board which plugs into all of the relevant pins in one go, to program it. You should only need one of these. To figure out which wires to connect where, compare the top diagram on http://www.dz863.com/datasheet-8310956563-ATTINY24A-SSU_8-bit-Microcontroller-With-2k-4k-Bytes-In-system-Programmable-Flash/ with https://www.olimex.com/Products/AVR/Programmers/AVR-ICSP/resources/AVR-ICSP.gif

You can power them with AA batteries or an external power supply - you could easily make one power supply that runs many boards. Check out the spec sheet for the voltage required - it varies, depending on the clock speed (default clock speed as described is 1 MHz, google "avr fuses" for how to set them to e.g. 8 MHz at no extra cost).

1

A little late, but I used a potentiometer as a switch to determine which "sketch" to run; in this case swapping LEDs on/off. I assume it can be applied to this instance, the students just have to share/divide pins and declare variables together at the top with comments. (I'm new at this, but I think a shift register (75HC595) could be used if you run out of pins). Thoughts?

EDIT: Potentiometers give a value of 0-1023. I split that up into 2, 3, and 4 separate sketches with no problems. You just have to change the IF/ELSEIFs to reflect how many sketches you want to run (512 for 2, 341 for 3, ~256 for 4, etc).

int sensorPin = 0;
int sensorValue = 0;
int ledPin1 = 4;
int ledPin2 = 8;

void setup() {

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop() {

  sensorValue = analogRead(sensorPin);

  if (sensorValue < 512)
{
    digitalWrite(ledPin1,HIGH);
    digitalWrite(ledPin2,LOW);
}

  else
{
    digitalWrite(ledPin2,HIGH);
    digitalWrite(ledPin1,LOW);
}
}
0

There is a solution. It requires some programming discipline from your students, but it is feasible.

1) Make sure each group uses different variable and function naming conventions (one starts all variable and functions with a_ and the other group with b_). These functions will be written in separate include files.

2) In the setup() and in the loop() functions, you will call either a_setup() or b_setup(), and either a_loop() or b_loop(). Each of the group setup and loop functions will call their functions and use their variables as the groups want to, but they are not allowed to call variables/functions from the other group. Other resources can also be allocated by you in advance for each team.

3) During the setup() function, start by reading a specific input that you will either connect to GND or to 5V. Use the result of this reading to execute either one version of the software, or the other.

This is not elegant, but it gets two program into each Arduino.

  • However, this would make the development flow of each team dependent on the other's, because the board must be reset upon each upload. What I was seeking is something that allows for independent development flows. – Giulio Muscarello Feb 3 '15 at 22:27
  • The arduino cannot run from it's limited RAM and is not going to be particularly efficient at executing a virtual machine doing so... at that point, you might as well run your custom virtual machine on something more powerful, such as the computer the students are sitting at. – Chris Stratton Feb 3 '15 at 22:35
  • On relooking I see that my answer is essentially the same as MAC's but explained slightly differently. As each answer contributes somewhat differently I'll leave mine in place BUT MAC said it first. And yes, it works well. Some student discipline is required - but minimal. – Russell McMahon Feb 3 '15 at 22:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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