Go Down

Topic: Analogue input help! (Read 590 times) previous topic - next topic

Hi,

I am very new to Arduino, although fairly experienced with C++.

I am having a bit of trouble with some code which has a pretty simple purpose: The input of a phone vibration motor is connected to the analogue input A-0 and ground, and I am running an if statement which tries to identify if the PD increases to above 1.5v across the two conductors. This is then supposed to activate a digital output for 30 seconds, however my if statement seems to be constantly true. The code is below. I would be really thankful if somebody might be able to explain what I may have done wrong? I'm not sure if it is a code issue of that my electronics are not quite right (I studied electrical power engineering, not electronic!). As it is analogue, I haven't bothered with a pull-down resistor.

Cheers,

Sam

int phonepin = 0;
int relaypin = 13;
float voltage;
float threshold = 1.5;

void setup()
{
pinMode(phonepin, INPUT);
pinMode(relaypin, OUTPUT);
Serial.begin(9600);

}
void loop()
{
  voltage = analogRead(phonepin)* 5 / 1023;
  Serial.print(voltage);
  delay(500);
  Serial.print("\t");
  digitalWrite(relaypin, LOW);
   
  if (voltage > threshold);   {
      digitalWrite(relaypin, HIGH);
      delay(30000);
      digitalWrite(relaypin, LOW);
      delay(500);
    }
     
}

PaulS

You're not going to share your serial output? That's not very nice.

Hi Paul S,

What do you mean?

Sam

AWOL

Code: [Select]
if (voltage > threshold);
BZZZZT!
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

This is the condition I am looking for in order for pin 13 to go high for a period of time. Should I be writing this differently, or is it inappropriate to use floats?

Sam

AWOL

Inappropriate use of semicolon.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Thanks AWOL, what a silly mistake.

AWOL

You're not the first, and I don't imagine you'll be the last  ;)
Enjoy!
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

robtillaart

Nice app to start with, did you connect directly to the motor or did you use some sensor - so it would work with any vibrating phone?

General remarks:
- please use the # button above the smiley's to tag your code , also doing a CTRL-T in the IDE does a reindent => looks better

more important, you should do the voltage math in float while now it is done in integer
See code below, I applied some other thingies too
- header
- consts where appropriate
- removed one delay to make system more reactive (other is homework ;)
- and the float math where appropriate
(code not tested)
Code: [Select]

//
//    FILE: PhoneBuzzDetector.pde
//  AUTHOR: Sam Glasius
//    DATE: 2012-12-27
//
// PUPROSE:
//

const int phonepin = A0;    // made const as they will not change   #define also a good option
const int relaypin = 13;   // idem

float voltage = 0;  // could be local within loop, minimize scope
float threshold = 1.5;

unsigned long lastOutput = 0;
#define DISPLAY_THRESHOLD  500UL   // 2x per second

void setup()
{
  pinMode(phonepin, INPUT);

  pinMode(relaypin, OUTPUT);
  digitalWrite(relaypin, LOW);

  Serial.begin(9600);
  Serial.println("PhoneBuzzDetector 0.1"); // to recall what is loaded on the Arduino
}

void loop()
{
  voltage = analogRead(phonepin) * 5.0 / 1023;

  //without delay
  unsigned long now = millis();
  if (now - lastOutput >= DISPLAY_THRESHOLD)
  {
    lastOutput += DISPLAY_THRESHOLD;
    Serial.print(now);
    Serial.print("\t");
    Serial.print(voltage, 3);  // use 3 digits
    Serial.println();
}
   
  // the delays can be removed here similar to above in the display part
  // by holding the state of the relay, previous state and a time stamp
  if (voltage > threshold) 
  {
    digitalWrite(relaypin, HIGH);
    delay(30000);
    digitalWrite(relaypin, LOW);
    delay(500);
  }
}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Arrch

Code: [Select]

float voltage;
float threshold = 1.5;
...
  voltage = analogRead(phonepin)* 5 / 1023;
...
  if (voltage > threshold);   {


The Arduino doesn't have an FPU, so any floating point calculations are done through software emulation and are very taxing on these modest devices. In this example, you're doing unnecessary floating point calculations. This could be made much more efficient by just converting 1.5v to the expected 10-bit ADC value:

Code: [Select]
int voltage;
int threshold = 306; // 1.5 * 1023 / 5
...
  voltage = analogRead(phonepin);
...
  if (voltage > threshold) {



robtillaart

@Arrch

+1  good point,
That saifd, for the given application float will still be fast enough .. (one can do quite some float math in delay(500))
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

AWOL

Quote
one can do quite some float math in delay(500)

No, one cannot.
(but I know what you're saying)
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

robtillaart

You got me AWOL ;)

Rephrase: One can do quite some float math in the 500 milliseconds a delay(500) takes.

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up