Index

Arduino Multi-Processor

Hardware Design

Bus Organisation

Library Software

  1. Port Registers

The Bus Controller

Node Identifiers

Miscellaneous Functions

Programming Techniques

Schematics

Firmware

images/6-1.png

Node Identifiers



images/6-2.png

Each processing node needs to know its own node identifier. This allows it to respond to communications addressed to it and to select the task allotted to it when the system starts. There are insufficient pins on the ATmega 328 to allow node identifiers be set on each board by a hardware input, e.g. a set of switches defining 4 bits. Instead, node identifiers are sent to the nodes during a system configuration process and stored in each chip's EPROM space at location 0. The DataFlow library's init_dataflow function retrieves this value from the EPROM and stores it in the node_id global variable where it can be accessed using the this_node function. Initialising the EPROM in each node is achieved by loading special software into all the nodes and the bus controller. However, this only needs to be done once unless boards are swapped or processor chips are replaced.

The following node identifier receiver program must be loaded into all the nodes before the configuration process is started.

#include <EEPROM.h>

const byte  send_pin    =   2;
const byte  led_pin     =  13;

const int   id_addr     =   0;
const int   setup_delay = 100;

byte        node_id     =   0;

void setup()
{
  pinMode(send_pin, INPUT );
  pinMode(led_pin,  OUTPUT);
  digitalWrite(led_pin, LOW);
  Serial.begin(9600);
  while (!Serial);
  delay(setup_delay);  
}

void loop()
{
  if (Serial.available())
  {
    byte addr = Serial.read();
    if (digitalRead(send_pin) == LOW)
    {
      node_id = addr - '0';
      EEPROM.write(id_addr, node_id);
      digitalWrite(led_pin, HIGH);
      while (true);
    }
  }
}


After configuring its inputs, outputs and the serial connection, this waits for a setup_delay which is shorter than that used by the program running in the bus controller so that it will be active when the bus controller starts sending out node identifiers. When a character is available on the serial input, it is read it in and the program checks to see if the send_pin is LOW. If it is not, it simply waits for more characters to be sent. If the send_pin is LOW, the code for an ASCII ‘0’ is subtracted from the value received to recover the node identifier (see bus controller program below). This is then written to the first location in the EPROM. The on-board LED is then turned on and the program halts by looping forever.

During the configuration process, the system must be powered by the serial connector on the bus controller, and the link which connects the serial output of the bus controller to the common serial inputs of all the nodes must be inserted. This link is under the reset button on the bus controller (see previous image).

The configuration process is initiated by loading the following program into the bus controller via its serial connection and then resetting the entire system.

const byte send_pins[] = {234, A1, A2, A3, A4, 56789101112, A0};

const int  setup_delay  = 500;
const int  send_delay   =   1;
const int  serial_delay = 100;

void setup()
{
  for (byte i = 0; i < sizeof(send_pins); i = i + 1
  {
    pinMode     (send_pins[i], OUTPUT); 
    digitalWrite(send_pins[i], HIGH  );
  }
  Serial.begin(9600);
  while (!Serial);
  delay(setup_delay);
}

void loop()
{
  for (byte node_id = 0; node_id < sizeof(send_pins); node_id = node_id + 1)
  {
    digitalWrite(send_pins[node_id], LOW);
      delay(send_delay);
      Serial.print((char)(node_id + '0'));
      delay(serial_delay);
    digitalWrite(send_pins[node_id], HIGH);
  }
  while (true);
}


The send_pins array lists the pins in the order they are connected to the individual nodes on the bus from node 0 to node 15. All of these pins are defined as outputs by the setup function and initially set to HIGH. The serial line is then initialised to 9600 baud. After this the function waits for a setup_delay to give all the processing nodes time to complete there setups after a system wide reset.

When the loop function runs, it iterates through the send_pins. For each pin, it first sets it to LOW, waits for a short time and then outputs the associated node identifier as a single character on the serial line. To avoid sending a null character for node 0, it adds the code for an ASCII ‘0’ character to each node identifier. After another delay to allow the selected node to receive its identifier, the send pin is reset to HIGH and the process is repeated for all the other pins.

When the whole system runs the two programs shown above the LEDs on the individual processing node boards light up one after another to show that it is working.

Once the node identifiers are configured in this way, the link on the bus controller board can be removed and the normal bus controller software can be uploaded. Finally the serial adapter can be reconnected to the connector on the bus.

Next: Miscellaneous Functions