Created
July 13, 2023 16:14
-
-
Save hsiboy/6e7b5de4f8cc3db43adc22193f828051 to your computer and use it in GitHub Desktop.
Automated Fuse Tester - for testing automative fuses using an arduino
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
/ 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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a WIP to "test" fuses.