How to steady voltage measurement.

Hi,

I am trying to make a torch height controller for my plasma cnc. I am measuring the plasma arc voltage through a 50:1 voltage divider I have installed in my plasma cutter. I used divider from this site: https://tamarisktechnicals.com/pages/CheapTHC.html

My divider uses a 100k and 2k resistor, and 2.2mH inductors on the output wires.

When I read arc voltage with my multimeter I get a steady reading of 2.06v on flat metal. With the values of my resistors, this would be around 103.9 volts in reality, which is very close to my plasma cutters spec for arc voltage of 102 volts. So I am happy the divider is working properly.

On my Arduino torch height controller I have an uno reading voltage from divider on A0 pin. I have a 5.1 Zener between A0 and ground incase of voltage spikes. I have a Microchip MCP1541 as an external voltage ref connected to vref pin, with 0.1uf cap on input and 1uf cap on output of MCP1541.

The controller switches three changeover relays when arc voltage is between a certain range, and takes control of Enable, STEP and dir pins of my z axis DRV8825 driver. The controller will then raise and lower z axis according to a set voltage.

This all works on the bench with a variable voltage supply simulating arc voltage. Problem is when I connect it all upto my cnc and plasma cutter. The voltage is wildly jumping all over the place, but I still get a steady reading from my multimeter.

I thought it had something to do with my torch height controller being connected to the same 12v supply as the cnc controller, so I connected it to an external battery. This helped a bit, but it is still not usable. I added a small delay in the code to try and get it to slow down, but it acts as though the delay is not there. Plus the operation of a few buttons I added to adjust set voltage, works, but it goes really fast as if there is no delay, so its hard to tell if it has been set if you know what I mean. Again on the bench it all runs smoothly.

Here is my code. I know it is probably not the best:

#include <TM1637Display.h>
#include <EEPROM.h>

const int CLK = 2; //Set the CLK pin connection to the display
const int DIO = 3; //Set the DIO pin connection to the display

TM1637Display display(CLK, DIO);  //set up the 4-Digit Display.

float input_voltage = 0.0;
float temp = 0.0;
float r1 = 99900.0;
float r2 = 1980.0;
float setVoltage = 102.0;

int eeAddress = 0;

int Enable = 7;
int STEP = 8;
int dir = 9;

int relay1 = 4;
int relay2 = 5;
int relay3 = 6;

int mainSwitch = 13;
int Up = 10;
int Down = 11;

bool startDelay = false;

void setup() {
  Serial.begin(9600);
  display.setBrightness(0x0a);  //set the diplay to maximum brightness
  analogReference(EXTERNAL); // use AREF for reference voltage

  pinMode(mainSwitch, INPUT);
  pinMode(Up, INPUT);
  pinMode(Down, INPUT);

  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
  digitalWrite(relay3, LOW);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  
  pinMode(Enable, OUTPUT);
  pinMode(STEP, OUTPUT);
  pinMode(dir, OUTPUT);
  digitalWrite(Enable, HIGH);
  digitalWrite(STEP, LOW);
  digitalWrite(dir, LOW);

  EEPROM.get(eeAddress, setVoltage);
}

void loop() {
  int analog_value = analogRead(A0);
  delay(2);
  temp = (analog_value * 4.06) / 1024.0; 
  input_voltage = temp / (r2/(r1+r2));
  Serial.print("v= ");
  Serial.println(input_voltage);
  display.showNumberDec(input_voltage);

  if(digitalRead(Up) == LOW){
    setVoltage++;
    EEPROM.put(eeAddress, setVoltage);
    display.showNumberDec(setVoltage);
    delay(1000);
  }

  if(digitalRead(Down) == LOW){
    setVoltage--;
    EEPROM.put(eeAddress, setVoltage);
    display.showNumberDec(setVoltage);
    delay(1000);
  }

  if(digitalRead(mainSwitch) == LOW){
    if(input_voltage >= 90 && input_voltage <=120){
      Serial.println("ARC OK");
      if(startDelay == false){
        delay(1500);
        startDelay = true;
      }
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, HIGH);
      digitalWrite(relay3, HIGH);
      digitalWrite(Enable, LOW);
      if(input_voltage <= setVoltage - 1){
        digitalWrite(dir, HIGH);
        Serial.println("Up");
        for(int i=0;i<200;i++){
          digitalWrite(STEP, HIGH);
          delayMicroseconds(100);
          digitalWrite(STEP, LOW);
          delayMicroseconds(100);
        }
      }
      else if(input_voltage >= setVoltage + 1){
        digitalWrite(dir, LOW);
        Serial.println("Down");
        for(int i=0;i<200;i++){
          digitalWrite(STEP, HIGH);
          delayMicroseconds(100);
          digitalWrite(STEP, LOW);
          delayMicroseconds(100);
        }
      }
    }
    else{
      Serial.println("Arc bad");
      digitalWrite(Enable, HIGH);
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, LOW);
      startDelay = false;
    }
  }
  else{
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, LOW);
      startDelay = false;
  }
  delay(100);
}

Can anyone give me any pointers? I think this will work if only I could stabilise the voltage readings.

Thanks.

You need to look at your arc voltage on an oscilloscope - I expect the voltage is anything but a steady voltage , despite what the multimeter says.

You might be able to filter it better , then take a number of readings and average them. The high frequency noise may still upset your Arduino .

I don’t have an oscilloscope, so can’t try that. Thing is the voltage is jumping around even before I start the arc.

What sort of filtering and averaging would you suggest?

How does the multimeter do it? Can I make the Arduino mimic it?

Thanks

You can try a [u]low-pass RC filter[/u].

As a rough guide to the timing/filtering you can use the RC time constant, which is simply the resistance multiplied by the capacitance. For example, a 1M resistor and a 1uF capacitor has a time constant of 1 second. (In practice, you'd generally want a lower value resistor and a higher value capacitor.) Or, you can look-up the formula for the cutoff frequency of an RC filter, but you'll probably have to experiment anyway.

And/or you can try some [u]software smoothing[/u].

Sounds a bit like what you'd see if you were missing a ground/earth connection.

Show us your circuit.

R1 and R2 of the divider for the A:D with the top of R1 being the input voltage to be measured. The bottom of R! connected to the top of R2 and the input to the A:D, and the bottom of R2 to circuit ground.

My solution to readings that jumped around is soldering. I made the R1:R2:AX junction as short as possible by soldering the resistors directly to the AX pin. I placed a small pad of hot glue onto the bottom of the Arduino circuit board and close to the AX pin that I used for the input as a bed for the resistors to lay on and made the R1:R2:A0 connection. A dab of hot glue on top of the resistors to hold them in place, The bottom of R2 to ground and the top of R1 to the input voltage. I hot glued the R1 input connection to the Arduino board to stabilize and insulate the input.

Of all the other tricks I tried to make the A:D the readings stable, using a short and soldered connection to the analog input of the Uno, Mega, and Pro Mini has worked the best.

I exclude the DUE from this list as the DUE A:D works great without the need for as short as possible connections and the 12 bit input mode gives readings that most closely match my DVM.

On another note. In your setup add:

ADC->ADC_MR |= 0x80; // setting for free running of the A:D
REG_ADC_MR = (REG_ADC_MR & 0xFFF0FFFF) | 0x00020000; // A:D converter start up value

for increased A:D performance.

You can, also, look up how to directly read the A:D converter.

Hi,

Can you post a copy of your circuit please, including the points where you are connected to the welder.

Might I suggest you average your readings to help filter the noise, a dynamic filter would be best as you could still read average over say 20 readings and act on the reading fairly quickly.

Reading a voltage from a plasma arc is going to be difficult because the arc is a primary source of noise that you have to contend with.

Tom.... :slight_smile:

I see a few problems with the variable delays throughout the loop but we can get started on fixing the analog readings without too much trouble.

Instead of taking one reading, why not take 20 or 100 and average them? It will only take about 10ms to grab 100 readings. Be careful adding up that many readings as it will overflow a regular 16-bit int. Make sure you use a long int.

That may still have problems. The welder is likely going to have a very large amount of mains frequency (50 or 60Hz) in the output. Grabbing a lot of readings in a short time may just sample the 'down' part of the wave and you get an artificially low value. 100 readings spread out over 1 second will get a much better average. But you can't afford to have the Arduino locked up for a whole second taking readings because it's supposed to respond to buttons and other inputs.

The second link provided by DVDoug is an example of a moving-average filter. A good example. It does have one disadvantage when the averaging period gets longer because it must store all the samples. Memory usage gets rather high when you increase to 100 or 1000 samples. But I hope you can see how the loop can do useful work in small increments while updating the average over a longer period.

Another way to filter or 'average' the data is to keep the long-term average in a single variable and only update it a little bit each time you get a new reading. Say you want an average similar to a moving-average of 100 samples: you take 99% of the previous average and add 1% of the newest sample. The maths behind this is explained in The Scientist and Engineer's Guide to Digital Signal Processing, Chapter 19

DVDdoug - Is the lowpass filter for the Arduino power supply, or for the A0 pin?

Idahowalker - I have R1 connected to torch coil which would be negative and R2 connected to clamp which would be positive of plasma cutter. You can hopefully see this in the attached pictures. These wires then lead to inductors and caps that are connected to a socket to exit plasma cutter. The caps are earthed through plasma cutters chassis. It sounds like you have done this before. What setup did you use?

From the divider connector on plasma cutter to my Arduino controller is 2 meter length of cable. I didn't want to take the high voltage out of the plasma cutter case.

On the Arduino side I have a mess of wires as you can see from the photos. The green connector is where the 2 meter cable from voltage divider is connected. The relays switch the driver wires of my cnc controller. The Arduino is powered through the 12v jack from the same 12v power supply as the cnc controller. The cnc controller power supply and plasma cutter are connected to the same 230v mains outlet.

I will have a look at some averaging code as well.

Hope you can see what I'm doing from these pics :slight_smile:

Thanks.

IMG_9640[2].JPG

Pic 2

IMG_9641[1].JPG

Pic 3

IMG_9652[1].JPG

Pic 4

DVDdoug - Is the lowpass filter for the Arduino power supply, or for the A0 pin?

The A0 pin. You are not filtering the actual power supply voltage, only voltage on the "other side" of the resistor.

Seedler:
DVDdoug - Is the lowpass filter for the Arduino power supply, or for the A0 pin?

Idahowalker - I have R1 connected to torch coil which would be negative and R2 connected to clamp which would be positive of plasma cutter. You can hopefully see this in the attached pictures. These wires then lead to inductors and caps that are connected to a socket to exit plasma cutter. The caps are earthed through plasma cutters chassis. It sounds like you have done this before. What setup did you use?

From the divider connector on plasma cutter to my Arduino controller is 2 meter length of cable. I didn't want to take the high voltage out of the plasma cutter case.

On the Arduino side I have a mess of wires as you can see from the photos. The green connector is where the 2 meter cable from voltage divider is connected. The relays switch the driver wires of my cnc controller. The Arduino is powered through the 12v jack from the same 12v power supply as the cnc controller. The cnc controller power supply and plasma cutter are connected to the same 230v mains outlet.

A lot different then my thinking. You might consider using a co-axial cable to send the data from the resistor divider network. If only one side of the coax cable was grounded the cable would act like a large filter capacitor dampening out transients running along the center conductor, which would be where your sampling voltage would be.

If the machine has an actual earth ground and the earth ground is connected to the circuit ground of the machine, that's where I'd tie the outer conductor of the coaxial cable. The 2nd option would be to use the circuit ground of the machine. The last and least favorite option, is to tie the coaxial outher connection to the Arduino.

On the machine side, make the connection to the voltage divider, as short as possible, exposing the least amount of unshielded wire to the envronment. You may need to have a long outer braided wire of the coax to reach a ground connection; that's OK. You can wrap the braided wire with electrical tape or heat shrink. If you can, in the machine, secure the coaxial cable, as close as possible to the connection with the divider, so that is does not move around.

And that's what I'd do first with the situation as your've described.

Above my pay-grade but seems to me you should be able to filter the signal in hardware along the same lines that a rectified AC circuit filters out the sine wave when turning AC into DC - or the capacitors used in a DC power supply to take out the ripple.

Idahowalker:
A lot different then my thinking. You might consider using a co-axial cable to send the data from the resistor divider network. If only one side of the coax cable was grounded the cable would act like a large filter capacitor dampening out transients running along the center conductor, which would be where your sampling voltage would be.

If the machine has an actual earth ground and the earth ground is connected to the circuit ground of the machine, that's where I'd tie the outer conductor of the coaxial cable. The 2nd option would be to use the circuit ground of the machine. The last and least favorite option, is to tie the coaxial outher connection to the Arduino.

On the machine side, make the connection to the voltage divider, as short as possible, exposing the least amount of unshielded wire to the envronment. You may need to have a long outer braided wire of the coax to reach a ground connection; that's OK. You can wrap the braided wire with electrical tape or heat shrink. If you can, in the machine, secure the coaxial cable, as close as possible to the connection with the divider, so that is does not move around.

And that's what I'd do first with the situation as your've described.

On my divider the Positive wire is taken from the positive side of the divider, and the negative wire is taken from the center of the divider. Which wire would I connect to the center core of the coax? I need to take a negative to the Arduino as well in order to get a reading. How do I do this if the shielding of coax is only connected to plasma cutter earth or ground?

saildude:
Above my pay-grade but seems to me you should be able to filter the signal in hardware along the same lines that a rectified AC circuit filters out the sine wave when turning AC into DC - or the capacitors used in a DC power supply to take out the ripple.

Are you suggesting a lowpass filter as well?

Thanks.

If the coaxial cable does not work to satisfaction then active filtering could be employed.

Using two amplifiers with unity gain (1). Amplifier A would be a non-inverting non DC blocking amplifier. Amplifier B would be a DC blocking inverting amplifier. Tie the output of Amplifier A to Amplifier B where the inverted AC signal will be met by the non-inverted AC signal and cancel each other out, leaving a 'clean' DC signal for the A:D converter to process.

Seedler:
On my divider the Positive wire is taken from the positive side of the divider, and the negative wire is taken from the center of the divider. Which wire would I connect to the center core of the coax? I need to take a negative to the Arduino as well in order to get a reading. How do I do this if the shielding of coax is only connected to plasma cutter earth or ground?

A yes, the machines reference wire, you can bring that in wrapped, in a long spiral coil, around the coaial cable.

Hi,
Thanks for the pics, but can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Tom.... :slight_smile:

Idahowalker:
A yes, the machines reference wire, you can bring that in wrapped, in a long spiral coil, around the coaial cable.

You've lost me there :slight_smile:

TomGeorge:
Hi,
Thanks for the pics, but can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Tom.... :slight_smile:

I'll try and get a diagram drawn up tomorrow.