├── README.md ├── license.txt ├── main.py └── rp2-pico-20220618-v1.19.1.uf2 /README.md: -------------------------------------------------------------------------------- 1 | # Rack Robotics Powercore EDM Power Supply Unit Firmware [23.07.14] 2 | 3 | This repository contains the firmware for Rack Robotics's Powercore, an affordable, hackable transistor EDM power supply unit. It is released under the [Creative Commons CC-BY-SA 2.0 license.](https://creativecommons.org/licenses/by-sa/2.0/legalcode) 4 | 5 | ## Overview 6 | 7 | Scope of Powercore EDM Power Supply Unit Firmware [23.07.14]: 8 | 1) Provide control over power MOSFET for high-voltage + high-current switching 9 | 2) Monitor thermister & power MOSFET temperature 10 | 3) Deactivate PSU in the event of overheating to prevent damage to unit 11 | 12 | Electrical discharge machining (EDM) utilizes a thermoelectric process called 'spark erosion'. Sparks erosion removes material 13 | by vaporizing/boiling away metal using many very small electric sparks. Sparks happen very quickly, lasting only for a 14 | fraction of a millisecond. 15 | 16 | The Rack Robotics's Powercore V1 is a transistor-capacitor hybrid EDM power supply unit. The Powercore creates, maintains, and monitors electrical 17 | sparks in an EDM machine. It is designed to be affordable and hackable. The Powercore has several features to achive its purpose: 18 | 19 | On-Board Raspberry Pi Pico - A drop-in Raspberry Pi Pico module is used as an on-board microcontroller, allowing for maximum flexibility. 20 | Micropython come pre-flashed on-board. Do not attempt to program microcontroller while machining, or while 21 | powered on. 22 | 23 | Transistor Control - A high-voltage & high-current power MOSFET (IRF135S203) controls when sparks can form. The MOSFET is 24 | primarily controlled via PWM. The logic of the high-voltage MOSFET is inverted. Meaning that when the 25 | MOSFET pin state is low, current can pass. When the MOSFET pin state is high, current can not pass. 26 | This is because of the low-voltage AOD508 MOSFET used to drive the high-voltage MOSFET. 27 | 28 | Adjustable Frequency - The minimum frequency between sparks is controlled digitally via PWM. Recommended operating frequency is 2 KHz. 29 | Higher frequencies can generate more waste heat than lower frequencies, potentially damaging the switching MOSFET. 30 | 31 | Adjustable Duty cycle - The maximum duration of sparks is controlled digitally via PWM. 32 | 33 | Current Monitoring - Current is monitored via an analog sensor (ACS712_x20A) within a range of +-20 amps. During capacitor dscharge, this maxes out 34 | the current sensor, causing a peak that resembles a digital peak. 35 | 36 | Thermal Monitoring - An onboard thermister monitors the temperature of the power resistor and MOSFET, helping to preventing overheating. 37 | 38 | Short Circuit Alert - (Work in Progress!) Digital feedback is provided during the event of a short by the "short alert" port (3.3 v normal, 0 v during short). 39 | 40 | Analog Feedback - Analog feedback from the ACS712x20A current sensor is provided by the "current" port (1.667 v - 0.333 v) 41 | This system adjusts the reported voltage with a sensitivity of ~0.0667 volts / amp. The baseline voltage 42 | of the system is the voltage reported when no current is flowing through the system. The voltage is approximately 43 | ~1.667 v volts. When current increases, the voltage reported will decrease at a rate of 44 | ~0.667 volts per amp. A reading of 0.333 volts indicates >= 20 amps. During capacitor dscharge, this maxes out 45 | the current sensor, causing a peak that resembles a digital peak. 46 | 47 | ## Installation 48 | 49 | Clone the repository using the following command: 50 | 51 | git clone https://github.com/rack-robotics/powercore-v1-firmware.git 52 | 53 | ## Setup 54 | 55 | Before running the firmware, make sure that your Powercore EDM PSU is correctly installed and connected to your Raspberry Pi Pico. 56 | 57 | Please ensure that you do not attempt to program the microcontroller while machining or while the unit is powered on. 58 | 59 | ## Firmware Configuration 60 | 61 | The firmware comes with a range of predefined settings, including temperature limits for different components, periods for capacitor charge and discharge, and the logic of the power MOSFET. These settings are located in the top portion of the main.py file and can be adjusted based on your needs. 62 | 63 | ## Usage 64 | Ensure that micropython is already uploaded to the pico. Flash this firmware to the pico using the pico-go-w extension in VS Code. 65 | 66 | ## Contributing 67 | We welcome contributions to this project. If you've found a bug or have a feature request, please open an issue. If you would like to improve the firmware, please fork the repository and create a pull request. 68 | 69 | ## License 70 | This software is released by Rack Robotics, Inc. under the Creative Commons CC-BY-SA 2.0 license. 71 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | License 2 | ======== 3 | “This software is released by Rack Robotics, inc. under the [Creative Commons CC-BY-SA 2.0 license.] (https://creativecommons.org/licenses/by-sa/2.0/legalcode "Creative Commons Legal Code") -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | # Rack Robotics, Inc. 2 | # Rackrobo.io 3 | # Powercore EDM Power Supply Unit Firmware [23.07.14] 4 | 5 | """ 6 | “This software is released by Rack Robotics, inc. under the [Creative Commons CC-BY-SA 2.0 license.] (https://creativecommons.org/licenses/by-sa/2.0/legalcode "Creative Commons Legal Code") 7 | """ 8 | 9 | """ 10 | Scope of Powercore EDM Power Supply Unit Firmware [23.07.14]: 11 | 1) Provide control over power MOSFET for high-voltage + high-current switching 12 | 2) Monitor thermister & power MOSFET temperature 13 | 3) Deactivate PSU in the event of overheating to prevent damage to unit 14 | """ 15 | 16 | """ 17 | Electrical discharge machining (EDM) utilizes a thermoelectric process called 'spark erosion'. Sparks erosion removes material 18 | by vaporizing/boiling away metal using many very small electric sparks. Sparks happen very quickly, lasting only for a 19 | fraction of a millisecond. 20 | 21 | The Rack Robotics's Powercore is a transistor EDM power supply unit. The Powercore creates, maintains, and monitors electrical 22 | sparks in an EDM machine. It is designed to be affordable and hackable. The Powercore has several features to achive its purpose: 23 | 24 | On-Board Raspberry Pi Pico - A drop-in Raspberry Pi Pico module is used as an on-board microcontroller, allowing for maximum flexibility. 25 | Micropython come pre-flashed on-board. Do not attempt to program microcontroller while machining, or while 26 | powered on. 27 | 28 | Transistor Control - A high-voltage & high-current power MOSFET (IRF135S203) controls when sparks can form. The MOSFET is 29 | primarily controlled via PWM. The logic of the high-voltage MOSFET is inverted. Meaning that when the 30 | MOSFET pin state is low, current can pass. When the MOSFET pin state is high, current can not pass. 31 | This is because of the low-voltage AOD508 MOSFET used to drive the high-voltage MOSFET. 32 | 33 | Adjustable Frequency - The minimum frequency between sparks is controlled digitally via PWM. Recommended operating frequency is 2 KHz. 34 | Higher frequencies can generate more waste heat than lower frequencies, potentially damaging the switching MOSFET. 35 | 36 | Adjustable Duty cycle - The maximum duration of sparks is controlled digitally via PWM. 37 | 38 | Current Monitoring - Current is monitored via an analog sensor (ACS712_x20A) within a range of +-20 amps. During capacitor dscharge, this maxes out 39 | the current sensor, causing a peak that resembles a digital peak. 40 | 41 | Thermal Monitoring - An onboard thermister monitors the temperature of the power resistor and MOSFET, helping to preventing overheating. 42 | 43 | Short Circuit Alert - (Work in Progress!) Digital feedback is provided during the event of a short by the "short alert" port (3.3 v normal, 0 v during short). 44 | 45 | Analog Feedback - Analog feedback from the ACS712x20A current sensor is provided by the "current" port (1.667 v - 0.333 v) 46 | This system adjusts the reported voltage with a sensitivity of ~0.0667 volts / amp. The baseline voltage 47 | of the system is the voltage reported when no current is flowing through the system. The voltage is approximately 48 | ~1.667 v volts. When current increases, the voltage reported will decrease at a rate of 49 | ~0.667 volts per amp. A reading of 0.333 volts indicates >= 20 amps. During capacitor dscharge, this maxes out 50 | the current sensor, causing a peak that resembles a digital peak. 51 | """ 52 | 53 | # Imported Modules 54 | # ---------------- 55 | from machine import Pin , ADC, PWM 56 | import math 57 | from utime import sleep 58 | 59 | """ 60 | The minimum period of the EDM system is the sum of the periods. The maximum frequency of the EDM system is the inverse of the minimum period. 61 | """ 62 | 63 | # Target period that capacitor energy is dumped, and a spark forms (microseconds) 64 | electrical_discharge_spark_period = 40 # microseconds 65 | 66 | # Target period that capacitors are charged up, and the dielectric fluid recovers (microseconds) 67 | electrical_discharge_recovery_period = 400 # microseconds 68 | 69 | # Tell system to invert logic for the power MOSFET. Setting the asigned GPIO pin high will set the MOSFET gate low, and vise versa 70 | invert_MOSFET_logic = True 71 | 72 | """ 73 | The Powercore V1 EDM power supply contains a power resistor. The temperature of the power resistor can be monitored as an added safety feature. In the event 74 | that power resistor temperature rises to unsafe levels, then action can be taken by the microcontroller. If the temperature is extremely low, this indicates 75 | an electrical failure, such as the thermister not being connected securely. The same is done for the power MOSFET. 76 | """ 77 | 78 | # Maximum allowable temperature of power resistor board) 79 | maximum_allowable_temperature_of_power_resistor = 368.15 # Kelvin 80 | 81 | # Minimum allowable temperature of power resistor board 82 | minimum_allowable_temperature_of_power_resistor = 273.15 # Kelvin 83 | 84 | # Maximum allowable temperature of power resistor board 85 | maximum_allowable_temperature_of_power_MOSFET = 353.2 # Kelvin 86 | 87 | # Minimum allowable temperature of power resistor board 88 | minimum_allowable_temperature_of_power_MOSFET = 273.15 # Kelvin 89 | 90 | """ 91 | A thermister is a variable resistor. Microcontrollers can not read resistance, only voltages, with an analog to voltage converter. This is done with a voltage 92 | divider, containing the thermister and a 10K pullup resistor. Converting the observed voltage to a temperature requires a beta coefficient, a specification for thermisters. 93 | """ 94 | 95 | # The beta coefficient of the NTC 3950 thermister, which is a specification of the thermister used to calculate temperature 96 | NTC_3950_thermister_beta_coefficient = 3950 97 | 98 | # Nominal resistance of the NTC 3950 thermister 99 | NTC_3950_thermister_normal_resistance = 100000 # ohms 100 | 101 | # The pullup resistor for the thermisters on the Powercore motherboard 102 | thermister_pullup_resistor_value = 10000 # ohms 103 | 104 | # The default value of temperature. This is made default negative as a safety feature 105 | temperature = -100 # Kelvin 106 | 107 | # Periodic checks are conducted using the 'time' module, which requires a variable which is continuously updated 108 | last_check_time_for_thermal_runaway_protection_check_one = 0 109 | last_check_time_for_thermal_runaway_protection_check_two = 0 110 | 111 | # Set up the output pin for initiating spark. This MOSFET is situated between the cathode electrode and ground. 112 | # Current may only flow through the electrodes when this MOSFET pin is high. 113 | high_voltage_MOSFET_pin = Pin(17, Pin.OUT) 114 | 115 | # Set up the analog input pin for the current sensor 116 | ACS712_analog_current_sensor = ADC(Pin(26)) 117 | 118 | # Two JST connects, or pads for JST connectors, are present on the motherboard. Thermisters can be plugged into 119 | # these connectors to monitor the temperature of critical components. A 10K resistor pulls these pins up to 3.3 volts. 120 | thermister_1_analog_input = ADC(Pin(27)) 121 | thermister_2_analog_input = ADC(Pin(28)) 122 | 123 | # This MOSFET is used to control the state of the short alert pin. When this pin is low, the short alert pin is pulled high. 124 | # When this pin is high, the short alert pin is pulled low. 125 | short_alert_MOSFET_pin = Pin(20, Pin.OUT) 126 | 127 | # Three LEDs are present on the motherboard PCB. These are driven by three pins 128 | spark_status_LED = Pin(16, Pin.OUT) 129 | high_voltage_MOSFET_status_LED = Pin(18, Pin.OUT) 130 | short_alert_LED = Pin(19, Pin.OUT) 131 | user_LED = Pin(25, Pin.OUT) # Comes placed on the pico module from factory 132 | 133 | # Function Definition 134 | # ------------------- 135 | 136 | def set_default_pin_states(): 137 | """ 138 | Function to set the default/safe state of GPIO pins for initialization of Powercore EDM power supply 139 | """ 140 | 141 | # Logic for the high voltage MOSFET is inverted. Switching this GPIO pin on turns the high-voltage MOSFET off 142 | if invert_MOSFET_logic == True: 143 | high_voltage_MOSFET_pin.on() 144 | if invert_MOSFET_logic == False: 145 | high_voltage_MOSFET_pin.off() 146 | 147 | # GPIO pins to turn on 148 | user_LED.on() 149 | 150 | # GPIO pins to turn off 151 | spark_status_LED.off() 152 | high_voltage_MOSFET_status_LED.off() 153 | short_alert_LED.off() 154 | short_alert_MOSFET_pin.off() 155 | 156 | def get_temperature(thermister_pin, number_of_samples, pullup_resistor_value, normal_thermister_resistance, beta_coefficient): 157 | """ 158 | Function to get the temperature from a thermister. This function assumes that the thermister is part of a voltage 159 | divider with a pullup resistor. 160 | :param thermister_pin: Analog pin to which thermister is connected 161 | :param number_of_samples: Numbers of samples taken during averaging operation 162 | :param pullup_resistor_value: Value of pullup resistor in thermister voltage divider circuit (ohms) 163 | :param normal_thermister_resistance: Normal value of the thermister (ohms) 164 | :param beta_coefficient: Beta coefficient of thermister 165 | :return: Temperature of thermister in kelvin 166 | """ 167 | voltage_sum = 0 168 | 169 | # Collect multiple readings and average their values 170 | for i in range(number_of_samples): 171 | 172 | # Calculate the voltage observed on the pico digital to analog converter 173 | voltage = thermister_pin.read_u16() * (3.3 / 65535) 174 | 175 | voltage_sum += voltage 176 | 177 | average_voltage = voltage_sum / number_of_samples 178 | 179 | # Calculate the resistance, of the NTC 3950 thermisterm which corresponds to the observed voltage 180 | observed_thermister_resistance = pullup_resistor_value / ((3.3 / average_voltage) -1) 181 | 182 | # Calculate the resistance in Kelvin using the Steinhart-Hart equation 183 | steinhart = observed_thermister_resistance / normal_thermister_resistance 184 | steinhart = math.log(steinhart) 185 | steinhart /= beta_coefficient 186 | steinhart += 1.0 / (25 + 273.15) 187 | steinhart = 1.0 / steinhart 188 | temperature = steinhart 189 | 190 | # Report the temperature over serial 191 | #print('Thermister Temperature: ' + str(temperature) + ' K') 192 | 193 | return temperature 194 | 195 | def thermal_runaway_protection_check(thermister_pin, maximum_temperature, minimum_temperature): 196 | """" 197 | Function to check temperature observed by thermister. 198 | :Param thermister_pin: Analog pin to which thermister and voltage divider are connected 199 | :Param maximum_temperature: Upper limit for allowable observed temperature 200 | :Param minimum_temperature: Lower limit for allowable observed temperature 201 | :Param interval: How often to conduct thermal runaway checks (ms) 202 | :Param time_check: Time check variable 203 | """ 204 | 205 | # Observes the temperature of a thermister 206 | observed_temperature = get_temperature(thermister_pin, 3, thermister_pullup_resistor_value, NTC_3950_thermister_normal_resistance, NTC_3950_thermister_beta_coefficient) 207 | 208 | # Report observed_temperature 209 | print(str(thermister_pin) + ":" + str(observed_temperature) + " K") 210 | 211 | # Checks of observed temperature is higher than or equal to maximum_temperature 212 | if observed_temperature > maximum_temperature: 213 | 214 | # Reset pins to safe state, and report error 215 | set_default_pin_states() 216 | PWM_output.deinit() 217 | 218 | # Report problem 219 | print('Observed thermister temperature: ' + str(observed_temperature) + 'K, Shutting Down...') 220 | 221 | # Command CPU into low-power state to indefinitely pause program 222 | machine.deepsleep() 223 | 224 | # Checks of observed temperature is lower than or equal to minimum_temperature 225 | if observed_temperature < minimum_temperature: 226 | 227 | # Reset pins to safe state, and report error 228 | set_default_pin_states() 229 | PWM_output.deinit() 230 | 231 | # Report problem 232 | print('Observed thermister temperature: ' + str(observed_temperature) + 'K, Shutting Down...') 233 | 234 | # Command CPU into low-power state to indefinitely pause program 235 | machine.deepsleep() 236 | 237 | def calculate_PWM_parameters(): 238 | """ 239 | Function to calculate PWM parameters of spark 240 | """ 241 | 242 | global spark_period 243 | global spark_frequency 244 | global spark_duty_cycle 245 | 246 | # Calculate the spark period in microseconds 247 | spark_period = electrical_discharge_spark_period + electrical_discharge_recovery_period 248 | 249 | # Calculate the spark frequency in hertz 250 | spark_frequency = 1 / (spark_period / 1000000) 251 | 252 | # Calculate the spark duty cycle (0 - 1) 253 | spark_duty_cycle = (electrical_discharge_spark_period / (electrical_discharge_spark_period + electrical_discharge_recovery_period)) 254 | 255 | if invert_MOSFET_logic == True: 256 | spark_duty_cycle = 1 - spark_duty_cycle 257 | 258 | def enable_high_power_pwm(): 259 | """ 260 | Function to generate high-power EDM waveforms using the power MOSFET 261 | """ 262 | 263 | global PWM_output 264 | 265 | # Assign PWM_output pin 266 | PWM_output = PWM(high_voltage_MOSFET_pin) 267 | 268 | # Set PWM frequency 269 | PWM_output.freq(int(spark_frequency)) 270 | 271 | # Initialize PWM with specific duty cycle 272 | PWM_output.duty_u16(round(spark_duty_cycle * 65535)) 273 | 274 | #Turn on status LED 275 | high_voltage_MOSFET_status_LED.on() 276 | 277 | # Main code 278 | # -------- 279 | # Initialize Powercore EDM power supply 280 | print("Starting up...") 281 | set_default_pin_states() 282 | calculate_PWM_parameters() 283 | enable_high_power_pwm() 284 | print("initialized") 285 | 286 | while True: 287 | user_LED.toggle() 288 | thermal_runaway_protection_check(thermister_1_analog_input, maximum_allowable_temperature_of_power_resistor, minimum_allowable_temperature_of_power_resistor) 289 | thermal_runaway_protection_check(thermister_2_analog_input, maximum_allowable_temperature_of_power_MOSFET, minimum_allowable_temperature_of_power_MOSFET) 290 | sleep(1) -------------------------------------------------------------------------------- /rp2-pico-20220618-v1.19.1.uf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rack-Robotics/Powercore-V1.0-Firmware/f127f5777432f134d93bd21d2f5547904daf1e17/rp2-pico-20220618-v1.19.1.uf2 --------------------------------------------------------------------------------