There are other issues with my code, but at the moment, it is only the array issue I am hunting down, the other issues will be cleaned up once I have MVP working
#include <Arduino.h>
#include <avr/wdt.h>
#include "src/ArduinoUniqueID/ArduinoUniqueID.h"
#include "src/Vrekrer_scpi_parser/Vrekrer_scpi_parser.h"
/*
This is the pin mapping for MimicOctopus v1.0
*/
#define VerPin0 50
#define VerPin1 51
#define VerPin2 52
#define VerPin3 53
byte cibVersion = 0;
const byte VERPINS[4] = {
VerPin0,
VerPin1,
VerPin2,
VerPin3
};
#define SDAPin 20
#define SCLPin 21
#define dataPin 23
#define latchPin 25
#define clockPin 27
#define registerCount 15 // Count of how many shift registers there are in total.
byte relayCoils[registerCount * 8];
// The Chanels 1 and 2 Shift register is the first one!
#define heartLED 13 // This is also the built in LED pin on the Mega 2560
#define V3_3_test A0 //Netname 3v3_test - Issue with non letter first charictor.
#define V12_test A1 //Netname 12v_test
#define V5_test A2 //Netname 5v_test
#define Ain3 A3
#define Ain4 A4
#define DUT_V_Mon A15
#define DUT_I_Mon1 A9
#define DUT_I_Mon2 A10
#define Eq_V_Mon1 A14
#define Eq_I_Mon1 A8
#define Eq_V_Mon2 A13
#define Eq_I_Mon2 A7
#define Eq_V_Mon3 A12
#define Eq_I_Mon3 A6
#define Eq_V_Mon4 A11
#define Eq_I_Mon4 A5
#define RAG1 36
#define RAG2 37
#define Enable 38
#define Door_Closed 6
#define InterlockLoop 5
#define Test_Start 4
#define CIO0 22
#define CIO1 12
#define CIO2 11
#define CIO3 10
#define EIO0 9
#define EIO1 8
#define EIO2 7
#define EIO6 3
#define EIO7 2
#define FIO3 39
#define FIO4 40
#define FIO5 41
#define FIO6 42
#define FIO7 43
#define MIO0 44
#define MIO1 45
#define MIO2 46
#define Debug Serial1
SCPI_Parser my_instrument;
void setup() {
// Grab the hardware revision once at the startup.
hardWare();
initScpi();
Serial.begin(9600);
Debug.begin(9600);
// Heartbeat
pinMode(heartLED, OUTPUT);
// fill the relayCoil array with zeros (off).
for (int i = 0; i < sizeof(relayCoils); i++) {
relayCoils[i] = 0;
}
// Shift Register setup
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
// Set latchpin low, this means the relays won't chatter during power up.
digitalWrite(latchPin, LOW);
// All relay coils set to off:
for (int i = 0; i < sizeof(relayCoils); i++) {
shiftOut(dataPin, clockPin, MSBFIRST, relayCoils[i]);
}
digitalWrite(latchPin, HIGH); //return the latch pin high to signal chip that it is over
// CIB Version detection
for (int i = 0; i < 4; i++) {
pinMode(VERPINS[i], INPUT);
}
pinMode(V3_3_test, INPUT);
pinMode(V5_test, INPUT);
pinMode(V12_test, INPUT);
pinMode(DUT_V_Mon, INPUT);
pinMode(DUT_I_Mon1, INPUT);
pinMode(DUT_I_Mon2, INPUT);
pinMode(Eq_V_Mon1, INPUT);
pinMode(Eq_I_Mon1, INPUT);
pinMode(Eq_V_Mon2, INPUT);
pinMode(Eq_I_Mon2, INPUT);
pinMode(Eq_V_Mon3, INPUT);
pinMode(Eq_I_Mon3, INPUT);
pinMode(Eq_V_Mon4, INPUT);
pinMode(Eq_I_Mon4, INPUT);
}
void loop() {
heartBeat();
relays();
my_instrument.ProcessInput(Serial, "\n");
}
/*
Blinks the built in LED at 2 Hz to confirm that the processor is still alive.
*/
byte heartbeat = LOW;
unsigned long previousBeat = 0;
void heartBeat() {
if (millis() - previousBeat >= 500) {
// save the last time you blinked the LED
previousBeat = millis();
// if the LED is off turn it on and vice-versa:
if (heartbeat == LOW) {
heartbeat = HIGH;
} else {
heartbeat = LOW;
}
digitalWrite(heartLED, heartbeat);
}
}
/*
Hardware Revision
*/
void hardWare() {
for (int i = 0; i < 4; i++) {
cibVersion |= (digitalRead(VERPINS[i]) << i);
}
}
/*
Smoothing
Reads repeatedly from an analog input, calculating a running average and
printing it to the computer. Keeps 10 readings in an array and continually
averages them.
*/
const int NUMREADINGS = 10;
float readValue(float inputPin, int normalised) {
int readings; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
float average = 0; // the average
for (int thisReading = 0; thisReading < NUMREADINGS; thisReading++) {
// read from the sensor:
readings = analogRead(inputPin);
// add the reading to the total:
total = total + readings;
// advance to the next position in the array:
readIndex = readIndex + 1;
}
// calculate the average of the readings:
average = total / NUMREADINGS;
// map the average onto the range 0 - normalised
return average / normalised;
}
/*
scpi commands
*/
const String COPYRIGHT = "ChargePoint 2022";
const String PRODUCT = "CIB - MimicOctopus";
const String SOFTWAREREV = "0.1";
const String DIVIDER = ";";
void initScpi() {
// Set up scpi tree
// Use "#" at the end of a token to accept numeric suffixes.
my_instrument.RegisterCommand(F("*IDN?"), &Identify);
my_instrument.RegisterCommand(F("*RST"), &SetReset);
my_instrument.RegisterCommand(F("RELay#?"), &RelayState);
my_instrument.RegisterCommand(F("RELay#"), &RelayStateChange);
my_instrument.SetCommandTreeBase(F("MEASure:VOLTage"));
my_instrument.RegisterCommand(F(":DUT#?"), &GetVoltDUT);
my_instrument.RegisterCommand(F(":EQUIpment#?"), &GetVoltEquipment);
my_instrument.RegisterCommand(F(":CIB#?"), &GetVoltCIB);
my_instrument.SetCommandTreeBase(F(":MEASure:CURRent"));
my_instrument.RegisterCommand(F(":DUT#?"), &GetCurDUT);
my_instrument.RegisterCommand(F(":EQUIpment#?"), &GetCurEquipment);
}
// SCPI Commands
/*
* Respond to *IDN?
*
* Uses the ArduinoUniqueID Library to get the Unique ID / Manufacture Serial Number from the Atmel AVR.
*/
void Identify(SCPI_C commands, SCPI_P parameters, Stream& interface) {
interface.print(COPYRIGHT + DIVIDER + PRODUCT + DIVIDER + "SW:" + SOFTWAREREV + DIVIDER + "HW:" + cibVersion + DIVIDER + "SN:");
for (size_t i = 0; i < UniqueIDsize; i++) {
interface.print(UniqueID[i], HEX);
}
interface.println(F(""));
}
/*
* Respond to *RST
*
* Delay is required to allow for entire string to be sent over serial.
*/
void SetReset(SCPI_C commands, SCPI_P parameters, Stream& interface) {
interface.print("Resetting");
delay(1000);
wdt_disable();
wdt_enable(WDTO_15MS);
while (1) {}
}
void GetVoltEquipment(SCPI_C commands, SCPI_P parameters, Stream& interface) {
//MEAS:VOLT<index>?
//Queries the voltage on [index]
//Return values are Analouge values, normalised to the expected voltage of the line being read.
//Examples:
// MEAS:VOLT:EQUP1? Queries the Equipment Chanel 1
//Get the numeric suffix/index (if any) from the commands
String header = String(commands.Last());
header.toUpperCase();
int suffix = -1;
sscanf(header.c_str(), "%*[MEAS:VOLT]%u", &suffix);
if (suffix = 1) {
interface.print(readValue(Eq_V_Mon1, 12));
} else if (suffix = 2) {
interface.print(readValue(Eq_V_Mon2, 12));
} else if (suffix = 3) {
interface.print(readValue(Eq_V_Mon3, 12));
} else if (suffix = 4) {
interface.print(readValue(Eq_V_Mon4, 12));
}
}
void GetVoltCIB(SCPI_C commands, SCPI_P parameters, Stream& interface) {
//MEAS:VOLT<index>?
//Queries the voltage on [index]
//Return values are Analouge values, normalised to the expected voltage of the line being read.
//Examples:
// MEAS:VOLT:CIB33? Queries the CIB 3v3 rail
//Get the numeric suffix/index (if any) from the commands
String header = String(commands.Last());
header.toUpperCase();
int suffix = -1;
sscanf(header.c_str(), "%*[MEAS:VOLT]%u", &suffix);
if (suffix = 33) {
interface.print(readValue(V3_3_test, 3.3));
} else if (suffix = 5) {
interface.print(readValue(V5_test, 5.0));
} else if (suffix = 12) {
interface.print(readValue(V12_test, 12));
}
}
void GetVoltDUT(SCPI_C commands, SCPI_P parameters, Stream& interface) {
//MEAS:VOLT<index>?
//Queries the voltage on [index]
//Return values are Analouge values, normalised to the expected voltage of the line being read.
//Examples:
// MEAS:VOLT:DUT1? Queries DUT supply Voltage
//Get the numeric suffix/index (if any) from the commands
String header = String(commands.Last());
header.toUpperCase();
int suffix = -1;
sscanf(header.c_str(), "%*[MEAS:VOLT]%u", &suffix);
interface.print(readValue(DUT_V_Mon, 12));
}
void GetCurEquipment(SCPI_C commands, SCPI_P parameters, Stream& interface) {
//MEAS:CURR:EQUIpment<index>?
//Queries the current on [index]
//Return values are Analouge values, normalised to the expected current of the line being read.
//Examples:
// MEAS:CURR:EQUI1? Queries the Equipment Chanel 1
//Get the numeric suffix/index (if any) from the commands
String header = String(commands.Last());
header.toUpperCase();
int suffix = -1;
sscanf(header.c_str(), "%*[MEAS:VOLT]%u", &suffix);
if (suffix = 1) {
interface.print(readValue(Eq_I_Mon1, 12));
} else if (suffix = 2) {
interface.print(readValue(Eq_I_Mon2, 12));
} else if (suffix = 3) {
interface.print(readValue(Eq_I_Mon3, 12));
} else if (suffix = 4) {
interface.print(readValue(Eq_I_Mon4, 12));
}
}
void GetCurDUT(SCPI_C commands, SCPI_P parameters, Stream& interface) {
//MEAS:CURR:DUT<index>?
//Queries the current on DUT[index]
//Return values are Analouge values, normalised to the expected current of the line being read.
//Examples:
// MEAS:CURR:EQUP1? Queries the Equipment Chanel 1
//Get the numeric suffix/index (if any) from the commands
String header = String(commands.Last());
header.toUpperCase();
int suffix = -1;
sscanf(header.c_str(), "%*[MEAS:VOLT]%u", &suffix);
if (suffix = 1) {
interface.print(readValue(DUT_I_Mon1, 12));
} else if (suffix = 2) {
interface.print(readValue(DUT_I_Mon2, 12));
}
}
void RelayState(SCPI_C commands, SCPI_P parameters, Stream& interface) {
// RELay<index>?
String header = String(commands.Last());
header.toUpperCase();
int suffix = -1;
sscanf(header.c_str(), "%*[RELay]%u", &suffix);
if ((suffix >= 0) && (suffix < sizeof(relayCoils))) {
if (relayCoils[suffix] == 1) {
interface.println("Closed");
} else { //LOW
interface.println("Open");
}
}else{
interface.println("Error - Check relay number");
}
}
void RelayStateChange(SCPI_C commands, SCPI_P parameters, Stream& interface) {
//RELay<index> state
//Get the numeric suffix/index (if any) from the commands
String header = String(commands.Last());
header.toUpperCase();
int suffix = -1;
sscanf(header.c_str(),"%*[RELay]%u", &suffix);
//If the suffix is valid,
//use the first parameter (if valid) to set the digital Output
String first_parameter = String(parameters.First());
first_parameter.toUpperCase();
if ( (suffix >= 0) && (suffix < sizeof(relayCoils))) {
if ((first_parameter == "HIGH") || (first_parameter == "ON") || (first_parameter == "1") ) {
relayCoils[suffix] = 1;
} else if ((first_parameter == "LOW") || (first_parameter == "OFF") || (first_parameter == "0") ) {
relayCoils[suffix] = 0;
}
}
}
void relays() {
digitalWrite(latchPin, LOW);
for (int i = 0; i < sizeof(relayCoils); i++) {
shiftOut(dataPin, clockPin, MSBFIRST, relayCoils[i]);
}
digitalWrite(latchPin, HIGH);
}