Creating an offset to 0

Hi, I'm pretty new to arduino programming. I have sort of a multi line volt meter going and I want to analyze the voltages coming in for validation. Basically I have voltage from the power supply giving me about 28-29v. This drives, among other things, a servo. About 5v gets sent to the servo line to tell it to work. What also happens is a drop of about 2-2.5v on the power supply line. Right now, I have it set up to tell me what is coming through all of the lines. Which is a start. What I also want to do is track the variance on the power supply line. Long story short, on power up, I have 28.6v on A2. I want to zero that for a secondary variable so when A2 drops from 28.6 to 26.5 on a servo event, what the secondary veritable actually records goes from 0 to -2.1. I need it to be automatic because one tool may give me 28.6 and another might be 27.9.

Yes, that's what variables are good for. Do exactly what you said but in C++ code.

maybe you want something like this ?

float voltOriginal ;
float voltDifference ;

void setup() {

voltOriginal = A2 ;  // or derived from A2

}

void loop(){

voltDifference = voltOriginal - A2 ;

}

An analog input measures a voltage against 5v (actually, I think it measures it against the vref pin). 30v is a shade spicy for the arduino to deal with, so you will want to run that through a voltage divider.

At this stage, reading a digital input will give you a value between 0 and 1024, tending to float around 975 or so. You want to detect movement in this value.

first, I would suggest rate-limiting your samples to get consistent behaviour
next, I'd suggest a nice rolling average (aka: low-pass filter)
finally, to detect a drop, you just look at if the current reading is X lower than the rolling average, where X is about 68 (assuming the sample voltage drops instantly. Maybe make it a little more sensitive.

Alternatively: keep two rolling averages, but make one more sensitive than the other. It all depends on how fast that voltage drops. This might make it a little more robust - I don't know.

float slowRollingAverage = 0;
float fastRollingAverage = 0;
unsigned long lastMs;

void loop() {
  unsigend long ms = millis();
  // take a reading only every 5 ms
  ms = ms - (ms % 5);
  if(ms == lastMs) return;
  lastMs = ms;

  // for the love of God, don't forget to use a voltage divider
  int reading = analogRead(0); 

  slowRollingAverage = slowRollingAverage * .95f + reading * .05f;
  fastRollingAverage = fastRollingAverage * .75f + reading * .25f;

  if(slowRollingAverage - fastRollingAverage > EXPERIMENTALLY_DETERMINED_THRESHOLD) {
    // ah ha! voltage is dropping!
    // do stuff
  }
}

If you are confident about the timings, you can use a speadsheet to fiddle with finding appropriate values for the filters and the threshhold:

Thank you for the replys. Yes, I'm absolutely using dividers for my lines then using the matching multiplier to send the original values back through serial. I'm not sure if any of the above options allow for this, but my idea is to save a snapshot of the A2 voltage as a value, say 5 seconds after startup, then compare all values on that line against the snapshot. Obviously I'll want a new snapshot everytime it starts up. Any ideas on that?

used a simple delay in the setup then recorded the voltage on the analog pin.

In the main sketch use the recorded valve to compare against new readings to calculate voltage drop. Depending on how you plan to use the recorded valve you may have do some math's and convert it to a float in setup as well.

You can get a lot more complicated by turning certain items on in setup then measuring the voltage just remember to turn everything off before you enter the main loop.

gpop, that sounds like that should work perfectly. Here's the thing, this is pretty much my first project, so I'm still very new to programming an Arduino. Can I get a quick example or at least a link to a reference on how to write that up? Any help on that would be much appreciated.

Gixxerman1980:
gpop, that sounds like that should work perfectly. Here's the thing, this is pretty much my first project, so I'm still very new to programming an Arduino. Can I get a quick example or at least a link to a reference on how to write that up? Any help on that would be much appreciated.

The IDE ships with a large assortment of examples that cover many typical aspects of hardware and software. To make a new app is not plug an play, but playing with those would give you a huge head start. Also make use of the many online resources about C++ and Arduino programming in general.

In a broader sense, computer programming makes sense. Remember, the processor is very stupid. It can't think. Every complex aspect of programming breaks down somehow into simpler tasks. Otherwise it would never be able to run on the machine. Your job is simply to break down the logic and understand it. It's a simple matter of practice and experience.

What you're asking for, is like trying to learn to play the piano by asking someone to play it for you. Concerning references, Google really does work! Also there are such links in the readme posts at the top of this forum.

aarg, I understand where you are coming from. I've done programming in visual basic, which I know isn't the same thing, but when looking at a sketch, I can see what it is doing and make since of it, then adapt it to what I need. Syntax is what I'm having an issue with. I doubt I could write a sketch in the exact same language that I would collect and move data in VB.

I don't mean to have somebody do the work for me. Trust me, I would rather learn it myself. If only this was as simple as playing the piano. One could theoretically play something nice and never know "this key is a G."

You are right, I have used Google to get me as far as I am in my sketch, and I have learned quite a bit. I'll continue my search and see what I can come up with. Thanks for pointing me in the right direction.

Perhaps it has more to do with the venue. A forum just doesn't have the right structure to convey comprehensive knowledge. It's more suited to addressing small, self contained problems or questions.

I'm adding Planning and Implementing an Arduino Program to my list of links.

its hard to write a example so I just wrote something that you may understand

Its always better to have a program that you can test and play with but that would require a way to load the power supply which really requires your own code to drive the servo.

Its not good code but it should give you a idea.

//kept everything in floats so i dont have to test it
//maths between ints and floats can get funny if you are not careful

float preDivider = 28.6; // no load enter correct number here measured on a meter
float baseLine = 0;//make a float called baseline
float calc = 0;//make a float called calc
unsigned long prevMillis = 0; //use in timer

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);//start serial
  delay(500);//allow time to stabilize
  baseLine = analogRead (A2);//0-1024 raw input
  calc = baseLine / preDivider;//used to work out voltage from raw input later
  //placed here as it only needs calculating once
  float voltage = baseLine / calc;//only used during setup for the print
  Serial.print ("voltage =");//will print once
  Serial.println (voltage, 2);//will print once
  delay(750);//allow time for print

}

void loop() {
  // put your main code here, to run repeatedly:
  unsigned long currentmillis = millis();//used in timer

  if (currentmillis - prevMillis >= 500) {//do every 1/2 second
    float newReading = analogRead (A2);//take a new reading
    float voltDrop = (baseLine - newReading) / calc;//work out difference in volts
    Serial.print ("voltage drop =");//print to screen
    Serial.println (voltDrop, 2);
    prevMillis = currentmillis;//new time stamp
  }
}