Skip to content

Instantly share code, notes, and snippets.

@hsiboy
Created July 13, 2023 16:14
Show Gist options
  • Save hsiboy/6e7b5de4f8cc3db43adc22193f828051 to your computer and use it in GitHub Desktop.
Save hsiboy/6e7b5de4f8cc3db43adc22193f828051 to your computer and use it in GitHub Desktop.
Automated Fuse Tester - for testing automative fuses using an arduino
/*
/ You'll need to adjust the current reading code based on the specific sensitivity of your ACS758 model.
/ Remember to adjust `ACS758_SENSITIVITY` based on the specific ACS758 model you're using.
/ The `readCurrent()` function reads the current sensor output and converts it to current based on the sensor sensitivity.
/
/ It's necessary to map the analog voltage reading based on your specific power source and voltage divider setup.
/ The code provided here assumes a 5V power supply for the Arduino, and that the voltage divider reduces the maximum
/ voltage of 15V to within 0-5V for the ADC. The specifics will depend on the actual resistors used in the voltage divider.
/ The Aref pin is supplied with 4.3v from a preecision zenner diode.
/
/ Uses a:
/ K-type thermocouple via a MAX31855 to give 14 bits of temperature.
/ an LCD display (2 rows of 16 chars) via I2C
/ an Allegro ACS758 Linear Current Hall Sensor, to read current.
/ a voltage divider, to read volatage.
/ an opto-coupler (something fast like a 6N137) in paralell to the fuese, to detect the "blown" fuse.
/ a relay to apply power to the Fuse under test.
/ a single SPST momentary button.
/
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_MAX31855.h>
#define RELAY_PIN 7
#define BUTTON_PIN 2
#define TEST_INPUT_PIN 3
#define VOLTAGE_SENSOR A0
#define CURRENT_SENSOR A1
#define NUM_SAMPLES 50
#define ACS758_SENSITIVITY 40.0 // 40mV/A
/*
40.0 for ACS758LCB-050B
60.0 for ACS758LCB-050U
20.0 for ACS758LCB-100B
40.0 for ACS758LCB-100U
13.3 for ACS758KCB-150B
16.7 for ACS758KCB-150U
10.0 for ACS758ECB-200B
20.0 for ACS758ECB-200U
The quiescent Output voltage is factor for VCC that appears at output when the current is zero.
- for Bidirectional sensor it is 0.5 x VCC
- for Unidirectional sensor it is 0.12 x VCC
- e.g for model ACS758LCB-050B, the B at the end represents Bidirectional (polarity doesn't matter)
- e.g for model ACS758LCB-100U, the U at the end represents Unidirectional (polarity must match)
0.50 for ACS758LCB-050B
0.12 for ACS758LCB-050U
0.50 for ACS758LCB-100B
0.12 for ACS758LCB-100U
0.50 for ACS758KCB-150B
0.12 for ACS758KCB-150U
0.50 for ACS758ECB-200B
0.12 for ACS758ECB-200U
*/
#define THERMOCOUPLE_DO 4
#define THERMOCOUPLE_CS 5
#define THERMOCOUPLE_CLK 6
Adafruit_MAX31855 thermocouple(THERMOCOUPLE_CLK, THERMOCOUPLE_CS, THERMOCOUPLE_DO);
LiquidCrystal_I2C lcd(0x27, 16, 2);
volatile unsigned long startTime = 0;
volatile bool testInProgress = false;
volatile bool emergencyStop = false;
void setup() {
lcd.clear();
lcdText(0, "Ready to Test", 1);
lcdText(1, "* Push Start *", 1);
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(TEST_INPUT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), startTest, FALLING);
attachInterrupt(digitalPinToInterrupt(TEST_INPUT_PIN), endTest, RISING);
// Set external reference voltage
analogReference(EXTERNAL);
// alow ADC to settle down
analogRead (0);
}
void lcdText(int row, String text, int justif){
int offset = 0;
switch(justif){
case(0)://Text left justified
lcd.setCursor ( offset, row );
lcd.print(text);
break;
case(1)://Text centred
offset = (displayCharLength - text.length())/2;
lcd.setCursor ( offset, row );
lcd.print(text);
break;
case(2)://Text right justified
offset = (displayCharLength - text.length());
lcd.setCursor ( offset, row );
lcd.print(text);
break;
}
}
void loop() {
if (emergencyStop) {
digitalWrite(RELAY_PIN, LOW);
testInProgress = false;
lcd.clear();
lcdText(0, "!!EMERGENCY STOP!!", 1);
lcdText(1, "* RESET POWER *", 1);
while(1);
}
if (testInProgress) {
double voltage = readVoltage();
double current = readCurrent();
double temp = thermocouple.readCelsius();
// Code to display these readings as you need
// e.g., lcd.setCursor(0, 1); lcd.print("V:" + String(voltage, 2) + " I:" + String(current, 2) + " T:" + String(temp, 2));
// Update display with temperature, voltage, and current
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T: " + String(temp) + " C");
lcd.setCursor(0, 1);
lcd.print("V: " + String(voltage) + " V I: " + String(current) + " A");
}
}
}
void startTest() {
if (!testInProgress) {
digitalWrite(RELAY_PIN, HIGH);
startTime = micros();
testInProgress = true;
} else {
digitalWrite(RELAY_PIN, LOW);
emergencyStop = true;
}
}
void endTest() {
if (testInProgress) {
digitalWrite(RELAY_PIN, LOW);
unsigned long elapsedTime = micros() - startTime;
// Display elapsed time
unsigned int minutes = elapsedTime / 60000000; // Calculate minutes
elapsedTime %= 60000000;
unsigned int seconds = elapsedTime / 1000000; // Calculate seconds
elapsedTime %= 1000000;
float fractional_seconds = elapsedTime / 1000000.0; // Calculate fractional seconds
lcd.clear();
if(minutes > 0) {
lcd.print(minutes);
lcd.print("m ");
}
lcd.print(seconds);
lcd.print(".");
lcd.print(int(fractional_seconds * 100)); // Print only two decimal places
lcd.print("s");
lcd.setCursor(0, 1);
lcd.print("Press start to clear");
testInProgress = false;
}
}
// Function to read voltage from sensor
double readVoltage() {
int raw = analogRead(VOLTAGE_SENSOR);
return (raw / 1023.0) * 4.3; // Convert raw reading to voltage (max 4.3V)
}
// Function to read current from sensor
double readCurrent() {
double total = 0;
for(int i = 0; i < NUM_SAMPLES; i++) {
int raw = analogRead(CURRENT_SENSOR);
double voltage = (raw / 1023.0) * 4.3; // Convert raw reading to voltage
double VQ = 2.5; // quiescent voltage (Vcc/2)
double deltaV = voltage - VQ; // change in voltage from VQ
if (deltaV < 0) deltaV = 0; // only measure current in one direction
double current = (deltaV * 1000.0) / ACS758_SENSITIVITY; // Convert voltage to current
total += current;
}
return total / NUM_SAMPLES; // Return the average current
}
@hsiboy
Copy link
Author

hsiboy commented Jul 14, 2023

This is a WIP to "test" fuses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment