Go Down

Topic: Getting output highs when I should be getting lows (Read 15775 times) previous topic - next topic

substance


This doesn't do what you think it does:
Code: [Select]
aRead += analogRead(PHOS_IN_A1 && BOR_IN_A2 && ARS_IN_A3);
As you surmise, you need to do them one at a time.

Try adding more serial prints so you can see what readings your sensors are actually giving the Arduino - might flush out a wiring issue. Speaking of which, seeing the wiring diagram may well help too.

Also, it sounds like you're using an Arduino output pin to drive an external device (timer). Is this direct? In which case does this device draw more than 40ma? You may need a transistor or relay to drive it from another source.


No the load (timer) is below 40mA. I have had the timers going but because I did not tell the chip what to do if no gasses were flowing, then my chip latched out and kept giving me a high on my output, when I needed it to be low.
Paul put me on the right path and I am slowly getting my head round the code and how it works.
I think my wiring is ok mate as I have my dvm out checking voltages and so on and it seems to be working. I just need to sort my code out and resolve this issue regarding uploading the code.
Let me have a brew, bath and bite to eat and I will crack on again. I will let you know how i get on later this afternoon.
Cheers fellas :-)

AWOL

Code: [Select]
int BGA_IN_A4 = 4;
int BGB_IN_A5 = 4;l

Oopsie.

substance


substance

#18
Mar 22, 2012, 02:33 pm Last Edit: Mar 22, 2012, 02:48 pm by substance Reason: 1

Quote
I need to put an else statement in don't I

Yes, but be careful where you put this else. You do not want to turn the pin off if gas 2 is not flowing, after turning it on because gas 1 IS flowing.

You should probably add a boolean, gasIsFlowing, with an initial value of false. In each gas test, set the glat true if the gas is flowing.

Then, after all three tests, turn the pin on or off, based on the flag.


Paul
I am unsure what you think I should do here. Could you explain it a bit more or perhaps show me an example?
Would I put GasIsFlowing in my setup bit and declare it false? Then in each bit for the gas flowing, instead of saying if gas < 2000, give me a gigh on the dep timer.  I would put GasIsFlowing = true. Then after it had read all the pin inputs, I would put, If GasIsFlowing = True, DigitalWrite Dep_Time, High. Else DigitalWrite Dep_time = Low.
Would it be something along them lines?
Dave
Dave

PaulS

If you take AWOL's advice to move the pin reading/average calculation code into a function, you would call it like so:
Code: [Select]
void loop()
{
  float voltage = readVoltage(PHOS_IN_A1);
  if( voltage <= 2000 )  //If voltage less than 2V
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else if( voltage > 2000 )   //If voltage more than 2V
  {
    digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
  }

  voltage = readVoltage(BOR_IN_A2);
  if( voltage <= 2000 )  //If voltage less than 2V
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else if( voltage > 2000 )   //If voltage more than 2V
  {
    digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
  }

  voltage = readVoltage(ARS_IN_A3);
  if( voltage <= 2000 )  //If voltage less than 2V
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else if( voltage > 2000 )   //If voltage more than 2V
  {
    digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
  }
}

which clearly would be a problem, as the timer would be turned on if a gas was flowing, and off if the last gas was not flowing. So, you fix that by adding a flag:
Code: [Select]
void loop()
{
  bool gasIsFlowing = false;
  float voltage = readVoltage(PHOS_IN_A1);
  if( voltage <= 2000 )  //If voltage less than 2V
     gasIsFlowing = true;

  voltage = readVoltage(BOR_IN_A2);
  if( voltage <= 2000 )  //If voltage less than 2V
     gasIsFlowing = true;

  voltage = readVoltage(ARS_IN_A3);
  if( voltage <= 2000 )  //If voltage less than 2V
     gasIsFlowing = true;

  // If gas is flowing, turn on the timer
  if(gasIsFlowing)
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else
  {
    digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
  }
}
The art of getting good answers lies in asking good questions.

substance


If you take AWOL's advice to move the pin reading/average calculation code into a function, you would call it like so:
Code: [Select]
void loop()
{
  float voltage = readVoltage(PHOS_IN_A1);
  if( voltage <= 2000 )  //If voltage less than 2V
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else if( voltage > 2000 )   //If voltage more than 2V
  {
    digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
  }

  voltage = readVoltage(BOR_IN_A2);
  if( voltage <= 2000 )  //If voltage less than 2V
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else if( voltage > 2000 )   //If voltage more than 2V
  {
    digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
  }

  voltage = readVoltage(ARS_IN_A3);
  if( voltage <= 2000 )  //If voltage less than 2V
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else if( voltage > 2000 )   //If voltage more than 2V
  {
    digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
  }
}

which clearly would be a problem, as the timer would be turned on if a gas was flowing, and off if the last gas was not flowing. So, you fix that by adding a flag:
Code: [Select]
void loop()
{
  bool gasIsFlowing = false;
  float voltage = readVoltage(PHOS_IN_A1);
  if( voltage <= 2000 )  //If voltage less than 2V
     gasIsFlowing = true;

  voltage = readVoltage(BOR_IN_A2);
  if( voltage <= 2000 )  //If voltage less than 2V
     gasIsFlowing = true;

  voltage = readVoltage(ARS_IN_A3);
  if( voltage <= 2000 )  //If voltage less than 2V
     gasIsFlowing = true;

  // If gas is flowing, turn on the timer
  if(gasIsFlowing)
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else
  {
    digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
  }
}



Cheers Paul. I was just editing my reply as you did this and that is how I was thinking. I have never declared a flag before so I was a bit unsure of where it went etc. I was just digging through my notes while I tried to see what you meant, but it was making sense what I had to do

AWOL

Code: [Select]
if( voltage <= 2000 )  //If voltage less than 2V
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else if( voltage > 2000 )  

And, of course, if a voltage is not less than or equal to a particular value, it isn't really necessary to test to see if it is greater than that same value.

substance


Code: [Select]
if( voltage <= 2000 )  //If voltage less than 2V
  {
    digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
  }
  else if( voltage > 2000 )  

And, of course, if a voltage is not less than or equal to a particular value, it isn't really necessary to test to see if it is greater than that same value.


I thought that mate but when I did my original sketch, my chip latched out and stayed high when I wanted it low. I am learning bit by bit. Work wanted me to use pressure switches on the pneumatics that open the gas vales etc but I wanted to go this way and try to learn a bit more rather than just the brief look I got last year at uni. I know I have gone around the houses a bit and made life difficult for myself but I have learnt some stuff and I am thankfull for your help and advice :-)

substance

For all my sins fellas. How does this look? Please be gentle

Code: [Select]
int PHOS_IN_A1 = 1; //Declares an integer of Phos input
int BOR_IN_A2 = 2;  //Declares an integer of Boron input
int ARS_IN_A3 = 3;  //Declares an integer of Arsine input
int BGA_IN_A4 = 4;  //Declares an integer of BGA input
int BGB_IN_A5 = 5;  //Declares an integer of BGB input
int DEP_TIME = 12;  //Declares an integer of Dep timer
int A_SIDE = 11;    //Declares an integer of BGA timer
int B_SIDE = 10;    //Declares an integer of BGB timer

long aRead = 0;  //Assumes voltage range from input


void setup()
{
Serial.begin(9600);  //Serial console for debugging

pinMode(DEP_TIME, OUTPUT);  //Sets dep timer as an output
pinMode(A_SIDE, OUTPUT);    //Sets BGA as an output
pinMode(B_SIDE, OUTPUT);    //Sets BGB as an output
}

void loop()
{

bool gasIsFlowing = false;
float voltage = readVoltage(PHOS_IN_A1);

for(int i=0; i <10; i++)   //Takes 10 readings
aRead += analogRead(PHOS_IN_A1);  //Reads phos in pin
aRead = aRead/10;        //Takes the average of 10 readings
voltage = (aRead * 5.0)/1024.0;   //Converts to digital
voltage = voltage*1000;           //Converts to millivolts

if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;
}


float voltage = readVoltage(BOR_IN_A2);

for(int i=0; i <10; i++)  //Takes 10 readings
aRead += analogRead(BOR_IN_A2);  //Reads boron in pin
aRead = aRead/10;        //Takes the average of 10 readings
voltage = (aRead * 5.0)/1024.0;  //Converts to digital
voltage = voltage*1000;  //Converts to millivolts

if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;

}


float voltage = readVoltage(ARS_IN_A3);

for(int i=0; i <10; i++) //Takes 10 readings
aRead += analogRead(ARS_IN_A3); //Reads arsine in pin
aRead = aRead/10; //Takes the average of 10 readings
voltage = (aRead * 5.0)/1024.0;  //Converts to digital
voltage = voltage*1000;          //Converts to millivolts

if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;

}

// If gas is flowing, turn on the timer
   if(gasIsFlowing)
   {
     digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
   }
   else
   {
     digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
   }


for(int i=0; i <10; i++)  //Takes 10 readings
aRead += analogRead(BGA_IN_A4);  //Reads BGA in pin
aRead = aRead/10; //Takes the average of 10 readings
voltage = (aRead * 5.0)/1024.0;  //Converts to digital
voltage = voltage*1000;          //Converts to millivolts

if( voltage <= 2000 )           //If voltage less than 2V
{
digitalWrite(A_SIDE, HIGH);   //Gives 5V output to BGA timer
}
else
{
digitalWrite(A_SIDE, LOW);   //Give no output on a side
}


aRead = 0;  //Assumes voltage range from input


for(int i=0; i <10; i++)   //Takes 10 readings
aRead += analogRead(BGB_IN_A5);  //Reads BGB in pin
aRead = aRead/10;   //Takes the average of 10 readings
voltage = (aRead * 5.0)/1024.0;  //Converts to digital
voltage = voltage*1000;  //Converts to millivolts

if( voltage <= 2000 )  //If voltage less than 2V

{
digitalWrite(B_SIDE, HIGH); //Gives 5V output to BGB timer

}
else
{
digitalWrite(B_SIDE, LOW);   //Give no output on B side
}

aRead = 0;  //Assumes voltage range from input
//Debug info to serial console
    Serial.print("Analog: "); 
    Serial.print(aRead);
    Serial.print(" Voltage:");
    Serial.println(voltage);

    delay(1000);  //1 sec delay between measurements
}

PaulS

Code: [Select]
float voltage = readVoltage(PHOS_IN_A1);
So, where is this function?

Code: [Select]
for(int i=0; i <10; i++)   //Takes 10 readings
aRead += analogRead(PHOS_IN_A1);  //Reads phos in pin
aRead = aRead/10;        //Takes the average of 10 readings
voltage = (aRead * 5.0)/1024.0;   //Converts to digital
voltage = voltage*1000;           //Converts to millivolts

Why is this still here? It belongs in the function.
The art of getting good answers lies in asking good questions.

substance

I am not sure what I am doing in the function. I have just been speaking to AWOL. I just tried upping my code and it did not like it lol. Suppose as long as I learn from my mistakes then I will get there eventualy

AWOL

#26
Mar 22, 2012, 03:57 pm Last Edit: Mar 22, 2012, 09:41 pm by AWOL Reason: 1
Code: [Select]

#define N_READINGS 10    // somewhere near the top of your program

// just about anywhere in your program, except inside another function
float readVoltage (int pin)
{
 long aRead = N_READINGS / 2;  //pre-round the result
 for(int i=0; i <N_READINGS; i++)   //Takes 10 readings
   aRead += analogRead(pin);  //Reads phos in pin
 
 aRead = aRead / N_READINGS;        //Takes the average of 10 readings
 float voltage = (aRead * 5.0)/1024.0;   //Converts to digital
 return voltage*1000;      
}

substance

I am lost now peeps. It is starting to drive me mad

Code: [Select]
int PHOS_IN_A1 = 1; //Declares an integer of Phos input
int BOR_IN_A2 = 2;  //Declares an integer of Boron input
int ARS_IN_A3 = 3;  //Declares an integer of Arsine input
int BGA_IN_A4 = 4;  //Declares an integer of BGA input
int BGB_IN_A5 = 5;  //Declares an integer of BGB input
int DEP_TIME = 12;  //Declares an integer of Dep timer
int A_SIDE = 11;    //Declares an integer of BGA timer
int B_SIDE = 10;    //Declares an integer of BGB timer

long aRead = 0;  //Assumes voltage range from input

#define N_READINGS 10    // somewhere near the top of your program
void setup()
{
Serial.begin(9600);  //Serial console for debugging

pinMode(DEP_TIME, OUTPUT);  //Sets dep timer as an output
pinMode(A_SIDE, OUTPUT);    //Sets BGA as an output
pinMode(B_SIDE, OUTPUT);    //Sets BGB as an output
}

// just about anywhere in your program, except inside another function
float readVoltage (int pin)
{
  long aRead = N_READINGS / 2;  //pre-round the result
  for(int i=0; i <10; i++)   //Takes 10 readings
    aRead += analogRead(pin);  //Reads phos in pin
 
  aRead = aRead / N_READINGS;        //Takes the average of 10 readings
  float voltage = (aRead * 5.0)/1024.0;   //Converts to digital
  return voltage*1000;       
}

void loop()
{
   bool gasIsFlowing = false;
   float voltage = readVoltage(PHOS_IN_A1);
   if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;


   voltage = readVoltage(BOR_IN_A2);
   if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;


   voltage = readVoltage(ARS_IN_A3);
   if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;
}
{

   // If gas is flowing, turn on the timer
   if(gasIsFlowing)
   {
     digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
   }
   else
   {
     digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
   }

{
float voltage = readVoltage(BGA_IN_A4 );
if( voltage <= 2000 )           //If voltage less than 2V
{
digitalWrite(A_SIDE, HIGH);   //Gives 5V output to BGA timer
}
else
{
digitalWrite(A_SIDE, LOW);   //Give no output on a side
}

{
float voltage = readVoltage(BGB_IN_A5 );

if( voltage <= 2000 )  //If voltage less than 2V

{
digitalWrite(B_SIDE, HIGH); //Gives 5V output to BGB timer

}
else
{
digitalWrite(B_SIDE, LOW);   //Give no output on B side
}

aRead = 0;  //Assumes voltage range from input
//Debug info to serial console
    Serial.print("Analog: "); 
    Serial.print(aRead);
    Serial.print(" Voltage:");
    Serial.println(voltage);

    delay(1000);  //1 sec delay between measurements
}

PaulS

Way too many { and } in loop. Try this:
Code: [Select]
void loop()
{
   bool gasIsFlowing = false;
   float voltage = readVoltage(PHOS_IN_A1);
   if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;

   voltage = readVoltage(BOR_IN_A2);
   if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;

   voltage = readVoltage(ARS_IN_A3);
   if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;

   // If gas is flowing, turn on the timer
   if(gasIsFlowing)
   {
     digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
   }
   else
   {
     digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
   }

   voltage = readVoltage(BGA_IN_A4 );
   if( voltage <= 2000 )           //If voltage less than 2V
   {
      digitalWrite(A_SIDE, HIGH);   //Gives 5V output to BGA timer
   }
   else
   {
      digitalWrite(A_SIDE, LOW);   //Give no output on a side
   }

   voltage = readVoltage(BGB_IN_A5 );
   if( voltage <= 2000 )  //If voltage less than 2V
   {
      digitalWrite(B_SIDE, HIGH); //Gives 5V output to BGB timer
   }
   else
   {
      digitalWrite(B_SIDE, LOW);   //Give no output on B side
   }

//Debug info to serial console
    Serial.print(" Voltage:");
    Serial.println(voltage);

    delay(1000);  //1 sec delay between measurements
}
The art of getting good answers lies in asking good questions.

substance

Finally managed to get this code into my uno but I am getting absolutely nothing now :-(
I am full out of ideas now

Code: [Select]
int PHOS_IN_A1 = 1; //Declares an integer of Phos input
int BOR_IN_A2 = 2;  //Declares an integer of Boron input
int ARS_IN_A3 = 3;  //Declares an integer of Arsine input
int BGA_IN_A4 = 4;  //Declares an integer of BGA input
int BGB_IN_A5 = 5;  //Declares an integer of BGB input
int DEP_TIME = 12;  //Declares an integer of Dep timer
int A_SIDE = 11;    //Declares an integer of BGA timer
int B_SIDE = 10;    //Declares an integer of BGB timer

long aRead = 0;  //Assumes voltage range from input

#define N_READINGS 10    // somewhere near the top of your program
void setup()
{
Serial.begin(9600);  //Serial console for debugging

pinMode(DEP_TIME, OUTPUT);  //Sets dep timer as an output
pinMode(A_SIDE, OUTPUT);    //Sets BGA as an output
pinMode(B_SIDE, OUTPUT);    //Sets BGB as an output
}

// just about anywhere in your program, except inside another function
float readVoltage (int pin)
{
  long aRead = N_READINGS / 2;  //pre-round the result
  for(int i=0; i <10; i++)   //Takes 10 readings
    aRead += analogRead(pin);  //Reads phos in pin
 
  aRead = aRead / N_READINGS;        //Takes the average of 10 readings
  float voltage = (aRead * 5.0)/1024.0;   //Converts to digital
  return voltage*1000;       
}

void loop()
{
   bool gasIsFlowing = false;
   float voltage = readVoltage(PHOS_IN_A1);
   if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;

   voltage = readVoltage(BOR_IN_A2);
   if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;

   voltage = readVoltage(ARS_IN_A3);
   if( voltage <= 2000 )  //If voltage less than 2V
      gasIsFlowing = true;

   // If gas is flowing, turn on the timer
   if(gasIsFlowing)
   {
     digitalWrite(DEP_TIME, HIGH); //Gives 5V output to dep timer
   }
   else
   {
     digitalWrite(DEP_TIME,  LOW) ;   //Gives no output if no gasses are flowing
   }

   voltage = readVoltage(BGA_IN_A4 );
   if( voltage <= 2000 )           //If voltage less than 2V
   {
      digitalWrite(A_SIDE, HIGH);   //Gives 5V output to BGA timer
   }
   else
   {
      digitalWrite(A_SIDE, LOW);   //Give no output on a side
   }

   voltage = readVoltage(BGB_IN_A5 );
   if( voltage <= 2000 )  //If voltage less than 2V
   {
      digitalWrite(B_SIDE, HIGH); //Gives 5V output to BGB timer
   }
   else
   {
      digitalWrite(B_SIDE, LOW);   //Give no output on B side
   }

//Debug info to serial console
    Serial.print(" Voltage:");
    Serial.println(voltage);

    delay(1000);  //1 sec delay between measurements
}

Go Up