Arduino MEGA
Description
The Arduino MEGA interface equipment type is a way of using the Arduino MEGA as a control system and/or data logger with SAFE. This can be used for simple control of LEDs, 5 volt inputs and much. It can also be used for simple data logging using the digital and analog pins. To use the Arduino MEGA you are only required to upload some specific code letting SAFE communicate with the Arduino MEGA over the serial interface. Find the Arduino MEGA code you need to copy in the bottom of this page.
Attributes
Attribute | Value |
---|---|
Name | |
Manufacturer | |
Model | |
Serial Number | |
Internal Number | |
COM PORT | COM1 |
Baud Rate | 115200 |
Sample Rate | 1 |
Channels (IN) | 60 |
Channels (OUT) | 44 |
Name
Name specifies the name of the block. It will automatically be given the name of the device.
Manufacturer
Manufacturer is an optional specification you can write.
Model
Model is an optional specification you can write.
Serial Number
Serial Number is an optional specification you can write.
Internal Number
Internal Number is an optional specification you can write.
COM Port
COM Port is the communication port that the Arduino MEGA is connected to your computer on. The default is COM1
, to see what your port the device
is connected on, go to device manager and find it.
Baud Rate
Baud Rate is the rate at which information is transferred. It is default 115200
for our Arduino Code but can be set to anything as
long as the Baud Rate in the Arduino code and in SAFE are identical.
Sample Rate
Sample Rate is how many times the device samples per second given in Hertz (Hz). Default is 1 Hz but it can be set to what you want. It is stronly recommended that it is set to between 0.1 Hz and 20 Hz. REMEMBER that the sample rate in SAFE and fs in the Arduino code MUST match.
Channels (IN)
Channels (IN) contains the 60 usable input channel available on Arduino MEGA including analog inputs and digital inputs.
For each digital input you can choose the Pin Mode
to be either INPUT
or INPUT_PULLUP
.
For each analog input you can specify the sensitivity which default is 204.6 FS per Volt.
Channels (OUT)
Channels (OUT) contains the 44 usable output channel available on the Arduino MEGA. There are no specific output channel settings
Arduino MEGA Code
In order to test with the Arduino in SAFE you must upload the following code to the Arduino MEGA using the Arduino IDE
In the code you can set fs to your desired fs as long as it is identical to the Sample Rate
of the Arduino on the Configuration board.
If you need a digital output you must define it in the Arduino code. Default the are commented in the code. So uncomment the pinMode of
the pin you want as an output.
int pinVal = 0;
// define the ports
int digital_ports [] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53};
int analog_inputs [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
// char array for serial input data
const byte numChars = 45;
char receivedChars[numChars];
boolean newData = false;
// variables for sampling
String writeString;
boolean do_sample = false;
unsigned long timeBetweenSamples = 0;
unsigned long loopEndTime = 0;
unsigned long loopStartTime = 0;
/****************************************************
Define the sample rate
Range: 0.1 < fs < 20
****************************************************/
float fs = 1;
int delay_ms = 0;
#define UNKNOWN_PIN 0xFF
void setup() {
Serial.begin(115200);
/****************************************************
Define digital pinmodes, if different from INPUT
****************************************************/
//pinMode(2, OUTPUT);
//pinMode(3, OUTPUT);
//pinMode(4, OUTPUT);
//pinMode(5, OUTPUT);
//pinMode(6, OUTPUT);
//pinMode(7, OUTPUT);
//pinMode(8, OUTPUT);
//pinMode(9, OUTPUT);
//pinMode(10, OUTPUT);
//pinMode(11, OUTPUT);
//pinMode(12, OUTPUT);
//pinMode(13, OUTPUT);
//pinMode(22, OUTPUT);
//pinMode(23, OUTPUT);
//pinMode(24, OUTPUT);
//pinMode(25, OUTPUT);
//pinMode(26, OUTPUT);
//pinMode(27, OUTPUT);
//pinMode(28, OUTPUT);
//pinMode(29, OUTPUT);
//pinMode(30, OUTPUT);
//pinMode(31, OUTPUT);
//pinMode(32, OUTPUT);
//pinMode(33, OUTPUT);
//pinMode(34, OUTPUT);
//pinMode(35, OUTPUT);
//pinMode(36, OUTPUT);
//pinMode(37, OUTPUT);
//pinMode(38, OUTPUT);
//pinMode(39, OUTPUT);
//pinMode(40, OUTPUT);
//pinMode(41, OUTPUT);
//pinMode(42, OUTPUT);
//pinMode(43, OUTPUT);
//pinMode(44, OUTPUT);
//pinMode(45, OUTPUT);
//pinMode(46, OUTPUT);
//pinMode(47, OUTPUT);
//pinMode(48, OUTPUT);
//pinMode(49, OUTPUT);
//pinMode(50, OUTPUT);
//pinMode(51, OUTPUT);
//pinMode(52, OUTPUT);
//pinMode(53, OUTPUT);
delay_ms = (1 / fs) * 1000;
}
void loop() {
loopStartTime = millis();
// sample input values and transmit to serial
if (do_sample == true) {
// Write pinstates to PC
for (int pin : digital_ports) { // if channel is input
if (getPinMode(pin) == INPUT || getPinMode(pin) == INPUT_PULLUP) {
pinVal = digitalRead(pin);
writeString += String(pinVal) + ":";
}
else { // add -1 if channel is not active as an input
writeString += "-1:";
}
}
for (int pin : analog_inputs) {
pinVal = analogRead(pin);
writeString += String(pinVal) + ":";
}
writeString.remove(writeString.length() - 1, 1);
Serial.println(writeString);
writeString = "";
do_sample = false;
}
// read output states from serial and set them
recvWithStartEndMarkers();
if (newData == true) { // if all the new data has arrived
int idx = 0;
for (int pin : digital_ports) {
if (getPinMode(pin) == OUTPUT) { // if pin is output
pinVal = receivedChars[idx] - '0'; // convert char array value to int
if (pinVal == 0 || pinVal == 1) {
digitalWrite(pin, pinVal);
}
}
idx = idx + 1;
}
newData = false;
}
delay(1);
loopEndTime = millis();
// check sample time
if (do_sample == false) {
timeBetweenSamples = timeBetweenSamples + (loopEndTime - loopStartTime);
if (timeBetweenSamples >= delay_ms) {
do_sample = true;
timeBetweenSamples = 0;
}
}
}
uint8_t getPinMode(uint8_t pin)
// Function to get pinMode on a specific pin
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
// I don't see an option for mega to return this, but whatever...
if (NOT_A_PIN == port) return UNKNOWN_PIN;
// Is there a bit we can check?
if (0 == bit) return UNKNOWN_PIN;
// Is there only a single bit set?
if (bit & bit - 1) return UNKNOWN_PIN;
volatile uint8_t *reg, *out;
reg = portModeRegister(port);
out = portOutputRegister(port);
if (*reg & bit)
return OUTPUT;
else if (*out & bit)
return INPUT_PULLUP;
else
return INPUT;
}
boolean recvWithStartEndMarkers() {
// function that reads serial input between to marker characters
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
boolean read_something = false;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
read_something = true;
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
return read_something;
}