Setting a Threshold Value

Hi Guys,

A seemingly simple question that I cant find an answer to...

I need to read the output from an INA169 current sensor. When the output value exceeds 300mv as read on analogue read A0, my Arduino has some work to do.

My question is, what value should the threshold that the analogue read value is compared to be set at? Is it the mv (i.e 300 mv) value, or the equivalent integer value (which I think is 66?) once the analogue read value has been converted?
Lots of examples explaining how things are converted to between 0 and 1023, but I cant find any info on what value is actually compared to the nominated threshold value

// These constants won't change:
const int currentPin = A0;    // pin that the current sensor is attached to
const int voltagePin = A1;   // pin that the voltage sensor is attached to
const int relayPin = 13;     // pin that the relay is attached to
const int threshold = 300;   // the current draw threshold level that's in the range of the analog input
unsigned long starTime = 0;    // global variable
unsigned long interval = 5000;     // 5 seconds
bool relayFlag = false;
byte attempts = 0;

void setup() {
  // initialize the RELAY pin as an output:
  pinMode(relayPin, OUTPUT);
  // initialize serial communications:
  Serial.begin(9600);
}

void loop() {
  // read the value of the current sensor:
  int analogValue = analogRead(currentPin);

  // if the analog value is high enough, power the relay:
  if (relayFlag == false && attempts < 3 && analogValue > threshold) 
  {
    digitalWrite(relayPin, HIGH);
    relayFlag = true;
    starTime = millis();    // start timer
  }

  if(relayFlag == true && millis() - starTime >= 5000UL) 
  {   
    // current time - start time >= 5 seconds 
    digitalWrite(relayPin,LOW);
    delay(100);  //this could be removed if needed
    relayFlag = false;
    attempts = attempts + 1;
  }

} //END of loop

Cheers
Chris

You need to use the numbers that come back form the analog input to compare.

Be aware that the values 0-1024 are nominally 0-5V, but actually are zero to whatever the supply voltage is. So if you are at 4.5V then each value is 4.5mV and the threshold is not going to be 60-odd.

Best bet is to experiment a bit and then provide a range, say between 55 and 65, in the code.

The Arduino knows nothing of voltage. It only knows a relative value. Using the 5v reference, the 300mv will give a value of

(300/5000) X 1023

So once the ADC value reaches 61 your voltage is 300mV.

For more accuracy, you can use a 1v reference. Do a search in the box at top of page.

Weedpharma

analogRead turns a value from 0-1024, not millivolts.

Full scale is 5V, so

1024/5 = 204.8 units per volt
204.8*0.3 = 61.44

So your threshold should be 61.

unless you are displaying the reading somewhere you might as well stay in the 0-1024 range of the analog read Depending on the arduino you are using this can be 0-5v or you can change the scaling to something more useful like 0-1.1v (see analogReference).

If you want to work in mv as a programmer then converting it is no big deal just watch the size of the number and use a long if the max number will be higher than 1024.

Hi Guys,

Thanks for your responses. I don't actually care what form its in (mv or integer). I just need to know to get the comparison to work.

Most examples for the INA169 are about determining what current is being drawn. I know what my current is, I just need to use the Arduino (Mega 2560) to monitor it, determine when it exceeds 300mv and switch a relay on (to start a generator).

The 66 value I picked up from another forum post and was the answer to a more specific mv value.
300 mv gives me a reasonable buffer as it represents either one light circuit being on (well under 300mv) or two circuits (about 360mv I think). So i'll work with 61 as a threshold value.

Again, many thanks for your prompt responses..

On a side note and related function.. I need to also monitor a dc battery voltage for shut down. I see most people talk about using a couple of resistors as voltage dividers as a simple approach (which suits me). Do you guys agree, or is there a better way? I need to monitor when I reach about 36 to 37v dc. then trigger a relay which connects ignition to ground and stops the motor.

Cheers
Chris

Oh, incidentally the map function is great for linear conversions like this.

int threshold = map(300, 0, 5000, 0, 1023);

For measuring battery voltage, yes a resistive voltage divider is the way to go.

Hi Guys,

I'll explain what I need my sketch to do and then hope you can tell me what I've done wrong.
There are multiple tasks required, but only one after the other depending on conditions.

I need to:

Task One:

Monitor analogue input current pin
When the value exceeds the threshold (300mv), digital write (at the moment the on board LED for testing) to high but only for 5 seconds. (this starts a generator)

Task Two:

I then need to check another analogue input - voltage pin to see if voltage has changed. The result from this needs to do one of two things, if there is no change, (which means the engine hasn't started) I need to loop back to the first task and repeat both task one and task two to a maximum of three attempts. (once three attempts are made, stop as the engine wont start)
If voltage pin is greater than a set value (I've just stuck a random in for the moment and the change in voltage means the engine has started) then digital write my voltage relay pin to high (to pass the charge to the batteries) and not attempt task one again and move to task three.

Task Three:

This involves ongoing monitoring of battery voltage until a charge threshold of 36v is reached at which time, I need to digital write my shutdown pin to high for 15 seconds. (stopping the motor)
at this point, the entire program needs to loop back to the start.

Currently, when I upload, the engine starting attempts (Task one) commences even with nothing connected to the board, so I serial printed the current pin to see what was happening and I was getting a value of 54 for each attempt. Once three attempts were made, it stops until reset.

Hope this all makes sense...

// These constants won't change:
const int currentPin = A0;    // pin that the current sensor is attached to
const int voltagePin = A1;   // pin that the voltage sensor is attached to
const int relayPin = 13;     // pin that the relay is attached to
const int voltagerelayPin = 26; //pin that the charging cut out relay is attached to
const int shutdownPin = 30; //pin that the shutdown relay is attached to
const int threshold = 61;   // the current draw (300mv)threshold level that's in the range of the analog input
unsigned long starTime = 0;    // global variable
unsigned long interval = 5000;     // 5 seconds
bool relayFlag = false;
byte attempts = 0;

void setup() {
  // initialize the RELAY pins as an output:
  pinMode(relayPin, OUTPUT);
  pinMode(voltagerelayPin, OUTPUT);
  pinMode(shutdownPin, OUTPUT);
  // initialize serial communications:
  Serial.begin(9600);
}

void loop() {
  // read the value of the current sensor:
  int analogValue = analogRead(currentPin);

  // if the analog value is high enough, power the relay:
  if (relayFlag == false && attempts < 3 && analogValue > threshold) 
  {
    digitalWrite(relayPin, HIGH);
    relayFlag = true;
    starTime = millis();    // start timer
  }

  if(relayFlag == true && millis() - starTime >= 5000UL) 
  {   
    // current time - start time >= 5 seconds 
    digitalWrite(relayPin,LOW);
    delay(2000);  //this could be removed if needed
    if(voltagePin > 5)
    digitalWrite (voltagerelayPin,HIGH);
    relayFlag = false;
    attempts = attempts + 1;
          }
  }

oh and Im quite new to all this (if you cant tell) and have been learning by example and forum posts, so please be gentle..

All constructive input would be greatly appreciated..

Cheers
Chris

The first thing you have done wrong is to have two posts with the same questions.

Tasks one and three are covered in the other post and task two logically belongs in the same post.

Weedpharma

That doesn't however answer the question. Why, with no input provided does the board start the three 'start attempts' when the threshold value shouldn't be getting exceeded?

Camel , thanks for your suggestion.

Boulton:
That doesn't however answer the question. Why, with no input provided does the board start the three 'start attempts' when the threshold value shouldn't be getting exceeded?

Camel , thanks for your suggestion.

Unless you've got a resistor or something pulling the voltage on your analog pin to a known state, analog pins will read all kinds of junk when they're not connected.

what does the threshold do regarding a LCD keypad shield and i keep getting:

Arduino: 1.8.5 (Windows Store 1.8.10.0) (Windows 10), Board: "Arduino/Genuino Uno"

sketch_jun19a:22: error: expected constructor, destructor, or type conversion before '(' token

set (sensorValue0, 720);

^

sketch_jun19a:30: error: 'lcd_key' does not name a type

lcd_key = read_LCD_buttons(); // read the buttons

^

C:\Users\taran\Documents\Arduino\sketch_jun19a\sketch_jun19a.ino: In function 'void set(int, int)':

sketch_jun19a:39: error: the value of 'diceOne' is not usable in a constant expression

case (diceOne + diceTwo == 7); {

^

C:\Users\taran\Documents\Arduino\sketch_jun19a\sketch_jun19a.ino:7:6: note: 'int diceOne' is not const

int diceOne;

^

sketch_jun19a:39: error: case label '((diceOne + diceTwo) == 7)' not within a switch statement

case (diceOne + diceTwo == 7); {

^

sketch_jun19a:39: error: expected ':' before ';' token

case (diceOne + diceTwo == 7); {

^

sketch_jun19a:46: error: case label '(0, 6)' not within a switch statement

case (diceOne + diceTwo == 5, 4, 3, 2, 6 ); {

^

sketch_jun19a:46: error: expected ':' before ';' token

case (diceOne + diceTwo == 5, 4, 3, 2, 6 ); {

^

sketch_jun19a:51: error: expected '}' at end of input

}

^

exit status 1
expected constructor, destructor, or type conversion before '(' token

You've got all kinds of problems with the code you didn't post, on the thread you necro-hijacked.
    case (diceOne + diceTwo == 5, 4, 3, 2, 6 );In all the code examples you've seen or worked through, you've never ever seen a construct like that.

1 Like