#include <SoftwareSerial.h>
#include <Wire.h>
#include "EEPROM.h" // Ensure you have this header defined correctly
// Define software serial pins (e.g., pin 10 for RX, pin 11 for TX)
SoftwareSerial keithleySerial(10, 11); // RX, TX
#define EEPROM_ADDRESS 0x50 // Change this to your EEPROM's address
#define TEST_ADDRESS 5
#define TEST_VALUE 524 // Write data test only
// Define relay pins
#define D1_RELAY 2
#define D2_RELAY 3
#define D3_RELAY 4
#define D4_RELAY 5
#define D5_RELAY 6
#define D6_RELAY 7
#define D7_RELAY 8
#define EEPROM_VBUS_RELAY 9 // Activate relay to supply power to EEPROM
bool isReceiving = false; // Flag to check if the system is in "start" state
void setup() {
Serial.begin(9600);
keithleySerial.begin(9600);
delay(1000);
// Set relay pins as outputs
pinMode(D1_RELAY, OUTPUT);
pinMode(D2_RELAY, OUTPUT);
pinMode(D3_RELAY, OUTPUT);
pinMode(D4_RELAY, OUTPUT);
pinMode(D5_RELAY, OUTPUT);
pinMode(D6_RELAY, OUTPUT);
pinMode(D7_RELAY, OUTPUT);
pinMode(EEPROM_VBUS_RELAY, OUTPUT);
Serial.println("Arduino is ready. Waiting for request.");
initializeKeithley(); // Initialize Keithley 2400
}
void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim(); // Remove any trailing whitespace
if (input.equalsIgnoreCase("request")) {
handleRequest();
} else if (input.equalsIgnoreCase("start")) {
isReceiving = true;
Serial.println("Started receiving voltage and relay commands.");
} else if (input.equalsIgnoreCase("end")) {
isReceiving = false;
resetRelaysAndVoltage();
Serial.println("Stopped receiving commands. All relays off, voltage set to 0.");
} else if (isReceiving) {
handleVoltageAndRelayCommands(input);
} else {
Serial.println("Not in receiving mode. Enter 'start' to begin.");
}
}
}
// Function to handle "request"
void handleRequest() {
Serial.println("Request received. Activating EEPROM power.");
digitalWrite(EEPROM_VBUS_RELAY, HIGH); // Activate relay
delay(1000); // Wait for power stabilization
if (isEEPROMAvailable()) {
byte readValue = readEEPROM(TEST_ADDRESS); // Read directly from EEPROM
Serial.print("Value read from EEPROM: ");
Serial.println(readValue);
if (readValue != TEST_VALUE) {
Serial.print("Warning: Value read (");
Serial.print(readValue);
Serial.print(") does not match written value (");
Serial.print(TEST_VALUE);
Serial.println(").");
} else {
Serial.println("Value read matches the written value.");
}
} else {
Serial.println("EEPROM not available. Please check connections.");
}
digitalWrite(EEPROM_VBUS_RELAY, LOW); // Deactivate EEPROM power
Serial.println("Deactivated EEPROM power.");
initializeKeithley();
}
// Function to initialize Keithley 2400
void initializeKeithley() {
sendCommand("*RST");
sendCommand("SOUR:FUNC VOLT");
sendCommand("SOUR:CURR 0.02"); // Set current limit to 20 mA
sendCommand("OUTP ON"); // Turn on the output
}
// Function to handle voltage and relay commands
void handleVoltageAndRelayCommands(String input) {
int spaceIndex = input.indexOf(' ');
if (spaceIndex != -1) {
String voltageValue = input.substring(0, spaceIndex);
String relayNumber = input.substring(spaceIndex + 1);
// Validate input
if (isValidFloat(voltageValue) && isValidRelay(relayNumber)) {
resetRelaysAndVoltage();
activateRelay(relayNumber.toInt());
String command = "SOUR:VOLT " + voltageValue;
sendCommand(command);
sendCommand("MEAS:CURR?");
delay(500);
if (keithleySerial.available() > 0) {
String response = keithleySerial.readString();
Serial.println("Current measured: " + response + " A");
}
} else {
Serial.println("Invalid input. Please enter 'voltage relay_no' (e.g., '5.0 3').");
}
} else {
Serial.println("Invalid format. Please enter 'voltage relay_no' (e.g., '5.0 3').");
}
}
// Function to send command to Keithley via SoftwareSerial
void sendCommand(String command) {
keithleySerial.println(command); // Send SCPI command to Keithley 2400
delay(100); // Small delay to allow command processing
}
// Function to check if a string represents a valid float
bool isValidFloat(String str) {
float value = str.toFloat();
return (value != 0 || str.equals("0") || str.equals("0.0"));
}
// Function to check if the relay number is valid
bool isValidRelay(String str) {
int relay = str.toInt();
return (relay >= 1 && relay <= 7); // Relay numbers should be between 1 and 7
}
// Function to reset all relays and set the voltage to 0
void resetRelaysAndVoltage() {
digitalWrite(D1_RELAY, LOW);
digitalWrite(D2_RELAY, LOW);
digitalWrite(D3_RELAY, LOW);
digitalWrite(D4_RELAY, LOW);
digitalWrite(D5_RELAY, LOW);
digitalWrite(D6_RELAY, LOW);
digitalWrite(D7_RELAY, LOW);
sendCommand("SOUR:VOLT 0");
}
// Function to activate the corresponding relay
void activateRelay(int relayNumber) {
switch (relayNumber) {
case 1: digitalWrite(D1_RELAY, HIGH); break;
case 2: digitalWrite(D2_RELAY, HIGH); break;
case 3: digitalWrite(D3_RELAY, HIGH); break;
case 4: digitalWrite(D4_RELAY, HIGH); break;
case 5: digitalWrite(D5_RELAY, HIGH); break;
case 6: digitalWrite(D6_RELAY, HIGH); break;
case 7: digitalWrite(D7_RELAY, HIGH); break;
default: Serial.println("Invalid relay number."); break;
}
}
// Function to check if EEPROM is available
bool isEEPROMAvailable() {
Wire.beginTransmission(EEPROM_ADDRESS);
int error = Wire.endTransmission();
return (error == 0);
}