0
\$\begingroup\$

I brought an ATmega328P (SMD) and burned a Duemilanove Bootloader. Everything seemed to be working fine until I tested out conditional statements.

Average set of analog val are: 84 , 143 , 255

Here is the code:

int svalue(int analogVal){
    if((analogVal > 135) && (analogVal < 200)){
        return 1;
    }
    if((analogVal > 200) && (analogVal < 300)){  
        return 2;
    }
    if((analogVal > 50) && (analogVal < 100)){
        return 3;
    }   
}
// Here is my main loop
void loop() {
  int pval = svalue(analogRead(A1));
  mySerial.write(pval);
}

But the above code is always returning '1'. I have tried Serial.print to debug the value of analogVal. Even if the value is 255 it returns 1. Is it a bootloader problem?

\$\endgroup\$
14
  • 1
    \$\begingroup\$ Did you read the compiler warnings? \$\endgroup\$ – Ignacio Vazquez-Abrams Aug 28 '14 at 16:10
  • \$\begingroup\$ What is int defined in your system as? You might try changing it to unsigned short. If you print the value of analogVal just before the "return 1" statement , what do you see? \$\endgroup\$ – tcrosley Aug 28 '14 at 16:16
  • \$\begingroup\$ @tcrosley well but if it's an uint_8 it might also return two or three, if it's an int_8 it might return also three... I never use "int" when programming on a micro but I'm not sure on how the problem can lie there this time. That code have many other problems too anyway. \$\endgroup\$ – Vladimir Cravero Aug 28 '14 at 16:18
  • \$\begingroup\$ @tcrosley or you are saying that for 84 it works the first time, so the return register is set to one and never touched again, and the thing silently fails? that would be awesome. \$\endgroup\$ – Vladimir Cravero Aug 28 '14 at 16:19
  • 2
    \$\begingroup\$ I don’t understand why it is not working. Add a “return 0;” at the end of the “svalue” function and test again. \$\endgroup\$ – Amit Hasan Aug 28 '14 at 16:49
3
\$\begingroup\$

Test the code in a structured, predictable way. Simplify it where possible. Print all values.

Post entire programs (where practical) so people can test it on their machines. Incomplete programs are hard to test, so it is harder to help.

First, what is mySerial? Is it an instance or reference to Serial? Replace mySerial with Serial. Then it is clear to everyone what is being used.

Secondly Serial.write(val) literally prints a binary byte, the lower 8 bits of of an int. which will be interpreted as an ASCII character by the Arduin's serial monitor. Binary values can be very awkward to debug.

Use Serial.print(val) or Serial.println(val) instead. This converts a binary number (e.g. in an int) to a 'human readable' number, by default printed as base 10, using the digits '0' to '9' (see the Arduino Serial documentation)

When testing and something strange is happening, remove every hard to control or predict part. 'Instrument' with print statements to see what is happening. (or get a debugger)

Change

int svalue(int analogVal){
    if((analogVal > 135) && (analogVal < 200)){

to

int svalue(int analogVal){
    Serial.print("entering svalue - analogVal=");
    Serial.println(analogVal);

    if((analogVal > 135) && (analogVal < 200)){

So we can see what is happening inside svalue.

To a reasonable approximation analogRead(A1) generates random numbers with an unknown range.

Replace it with either a fixed value, or something very predictable, like a for loop.

Change

void loop() {
  int pval = svalue(analogRead(A1));
  mySerial.write(pval);
}

To:

void loop() {
  int pval = analogRead(A1);     // = svalue(analogRead(A1));
  Serial.print("analogRead(A1)=");
  Serial.println(pval);
  int i;
  for (i=0; i<1024; i+=10) {    // print range of analogRead, in steps of 10
    pval = svalue(i);
    Serial.print(i);
    Serial.print(" svalue(i)=");
    Serial.print(pval);    // mySerial.write(pval);
    Serial.println();
  }
}

Now you have something which can be debugged more easily.

Edit:
Changed the for loop to use steps of 10 to make it easier to see what is happening, and retained printing analogRead(A1) value. At least this approach tests svalue().

It is plausible that the something is wrong with that analogue input, or the electronics connected to A1 is broken, and hence analogRead returns nonsense.

Try each different analogue input.
Try to use something simple and (mostly) predictable like two fixed resistors (say 1K and 1K) to make a voltage divider for the analogue input to measure. Or try something controllable like a potentiometer which should allow you to see the voltage being driven in a direction, and test most of the range.

If you have an effective way to test binary values, and do need the value from svalue() to be output as a binary character code, replace Serial.print(pval); with Serial.write(pval);.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.