Problems with ohms law code

Project: Calculator
I am writing a 10 stage project to create an ohm's law and resistor calculator, using the arduino uno and eventually a development board. I am having a problem with the code of stage two in my project. I will outline the stages of my project so you can understand what I am trying to achieve. I have a very, very basic understanding of "c" and I am learning as I go along. I know I am doing something wrong but I am not sure what.

Stage one
Write a small programme to calculate one of the three ohm's law equations, then modify to be able to work out all three equations. Each of the three codes run and work as I expect.

Stage two
Combine the three equations into one code picking which equation you want to work out then working out that equation.

Stage three
Write a programme to work out the colour code of 4 band resistors when entering the value

Stage four
Write a programme to give you the value when entering colour code (reverse of stage three)

Stage five
Write a programme to work out the colour code of 5 band resistors when entering the value

Stage six
Write a programme to give you the value when entering colour code (reverse of stage five)

Stage seven
Combine all six projects into one working code choosing which function is wanted then doing that appropriate function.

Stage eight
Add a lcd screen and keypad into the project. so it will work as a stand alone without the computer.

Stage nine
Build a development board to replace the uno

Stage ten
Incorporate this into a case

My code for stage two

// the setup routine runs once when you press reset:
void setup() {                
Serial.begin(9600); 
}

void loop() {
  int current=Serial.read()-'0';
  int voltage=Serial.read()-'0';
  int resistance=Serial.read()-'0';
  int ohmslaw=Serial.read();
  
 Serial.println("What value would you like to work out?");
 Serial.println("1. Resistance");
 Serial.println("2. Current");
 Serial.println("3. Voltage");
 delay(5000);
 Serial.println(ohmslaw);
 delay(2000);

 
  if(ohmslaw ==1){

float resistance =0;
int voltage =Serial.read()-'0';
int current=Serial.read()-'0';

Serial.println("The voltage is  ");
Serial.println(voltage);
Serial.println("The current is  ");
Serial.println(current);
resistance=voltage/current;
Serial.print("The Resistance is  ");
Serial.println(resistance);
delay(5000);
} 

  if(ohmslaw ==2){

float Current =0;
int voltage =Serial.read()-'0';
int resistance=Serial.read()-'0';

Serial.println("The voltage is  ");
Serial.println(voltage);
Serial.println("The resistance is  ");
Serial.println(resistance);
current=voltage/resistance;
Serial.print("The current is  ");
Serial.println(current);
delay(5000);
} 
  if(ohmslaw ==3){

float voltage =0;
int current =Serial.read()-'0';
int resistance=Serial.read()-'0';

Serial.println("The current is  ");
Serial.println(current);
Serial.println("The resistance is  ");
Serial.println(resistance);
voltage=current*resistance;
Serial.print("The voltage is  ");
Serial.println(voltage);
delay(5000);
} 

else Serial.print("Inlavid Selection. ");
  }

If this is in the wrong section please could a mod move it to the correct section.
Thanks in advance for any help.

Read this:

It'll tell you how to use the Serial.read() function. You aren't using it properly.
Also, you just want single digit value for voltage, current, and ohms?

I have read and modified the code but I am still getting the same result. I have even looked at the if statements. All I get in the serial monitor is...

What value would you like to work out?

  1. Resistance
  2. Current
  3. Voltage
    0
    Invalid Selection.
    What value would you like to work out?
  4. Resistance
  5. Current
  6. Voltage

Regardless of what number I put in this keeps repeating. I know its something to do with the serial function but I am unsure as to what. Here is my revised code to show you what I have done...

int incomingByte = 0;   // for incoming serial data
// the setup routine runs once when you press reset:
void setup() {                
Serial.begin(9600); 
}

void loop() {
  int current=Serial.read()-'0';
  int voltage=Serial.read()-'0';
  int resistance=Serial.read()-'0';
    
  if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();
  }
  
 Serial.println("What value would you like to work out?");
 Serial.println("1. Resistance");
 Serial.println("2. Current");
 Serial.println("3. Voltage");
 delay(5000);
 Serial.println(incomingByte);
 delay(2000);

 
  if(incomingByte ==1){

float resistance =0;
int voltage =Serial.read()-'0';
int current=Serial.read()-'0';

Serial.println("The voltage is  ");
Serial.println(voltage);
Serial.println("The current is  ");
Serial.println(current);
resistance=voltage/current;
Serial.print("The Resistance is  ");
Serial.println(resistance);
delay(5000);
} 

 else if(incomingByte ==2){

float Current =0;
int voltage =Serial.read()-'0';
int resistance=Serial.read()-'0';

Serial.println("The voltage is  ");
Serial.println(voltage);
Serial.println("The resistance is  ");
Serial.println(resistance);
current=voltage/resistance;
Serial.print("The current is  ");
Serial.println(current);
delay(5000);
} 
 else if(incomingByte ==3){

float voltage =0;
int current =Serial.read()-'0';
int resistance=Serial.read()-'0';

Serial.println("The current is  ");
Serial.println(current);
Serial.println("The resistance is  ");
Serial.println(resistance);
voltage=current*resistance;
Serial.print("The voltage is  ");
Serial.println(voltage);
delay(5000);
} 

else Serial.println(" Invalid Selection. ");
  }

Your logic is completely backwards.

You need to ask the question, wait for the answer to be available and then read the answer.

So, you read the serial port 3 times without knowing if anything is there.
Then you check to see is something is there, and if it is (unlikely, as you just did three reads), you read into incomingbyte.

Check out this tutorial by Nick Gammon: Gammon Forum : Electronics : Microprocessors : How to process incoming serial data without blocking

PeterH:
Your logic is completely backwards.

You need to ask the question, wait for the answer to be available and then read the answer.

so the code is correct just in the wrong order?

lar3ry:
So, you read the serial port 3 times without knowing if anything is there.
Then you check to see is something is there, and if it is (unlikely, as you just did three reads), you read into incomingbyte.

Check out this tutorial by Nick Gammon: Gammon Forum : Electronics : Microprocessors : How to process incoming serial data without blocking

Thank you but that just confused the hell out of me... :astonished: =( (the link)

I see what you are saying about the serial reading now. I have changed the code to this...

float voltage =0;
float current =0;
float resistance =0;
int incomingByte = 0;   // for incoming serial data
// the setup routine runs once when you press reset:
void setup() {                
Serial.begin(9600); 
}

void loop() {

  
 Serial.println("What value would you like to work out?");
 Serial.println("1. Resistance");
 Serial.println("2. Current");
 Serial.println("3. Voltage");
 Serial.println(incomingByte);
 delay(5000);
 
 if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();
  }

  if(incomingByte ==1){

float resistance =0;
float voltage =Serial.read()-'0';
float current=Serial.read()-'0';

Serial.println("The voltage is  ");
Serial.println(voltage);
Serial.println("The current is  ");
Serial.println(current);
resistance=voltage/current;
Serial.print("The Resistance is  ");
Serial.println(resistance);
delay(5000);
} 

 else if(incomingByte ==2){

float Current =0;
float voltage =Serial.read()-'0';
float resistance=Serial.read()-'0';

Serial.println("The voltage is  ");
Serial.println(voltage);
Serial.println("The resistance is  ");
Serial.println(resistance);
current=voltage/resistance;
Serial.print("The current is  ");
Serial.println(current);
delay(5000);
} 
 else if(incomingByte ==3){

float voltage =0;
float current =Serial.read()-'0';
float resistance=Serial.read()-'0';

Serial.println("The current is  ");
Serial.println(current);
Serial.println("The resistance is  ");
Serial.println(resistance);
voltage=current*resistance;
Serial.print("The voltage is  ");
Serial.println(voltage);
delay(5000);
} 

else Serial.println(" Invalid Selection. ");
  }

I am sorry there are lots of flaws in this code. Lets fix a few, and see if you find the others

Serial.println ... // menu choices
Serial.println(incomingByte);
 delay(5000);

Why print the incomming byte? It hasnt arrived yet.
Why the 5 second delay? To give the user time to read the question? Makes no sense. The code (when written correct) will wait until an entry is made - however long the user takes.

if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();
  }

This means if no key has been pushed we will not read it. We then carry on with the rest of the program whether a key has been pushed or not. You should put the other stuff inside the if. (Actually you have a number of other issues ... we'll get to that later)

if(incomingByte ==1){You are confused about BINARY and test/ASCII numbers. The letter "1" has the internal binary value of 49. So if ( incomingByte ==49 ) would compare if a "1" was pushed. You can comapre single letters directly by more simply writing
if ( incomingByte =='1' ). Please note it is not if ( incomingByte =="1" )

... I'll leave the rest of the program (which I have not read yet) for another day.

Thank you but that just confused the hell out of me..

Well, you need to read and reread until you understand it.

 Serial.println(incomingByte);

You haven't read anything. Why are you printing this?

 delay(5000);

Are you trying to build the worlds slowest calculator?

 if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();
  }

  if(incomingByte ==1){

If there is no (new) serial data, why are you doing anything else in loop()? EVERY SINGLE THING YOU ARE TRYING TO DO RELIES ON SERIAL DATA BEING AVAILABLE. Absolutely nothing should happen outside of the if(Serial.available()) block.

Your prompts belong in setup(), not loop(). You can repeat the prompts AFTER having read all three values, but NOT on every pass through loop().

Ok, it appears I have a lot of studying to do. I am determined to get this working.

Thanks for all your help

One solution for the issue with Serial is to write a blocking read function.

"blocking" means the code waits. The provided version of Serial.read() is non-blocking
(it always returns immediately).

So define something like

int myRead ()
{
  while (Serial.available () == 0)
  {}
  return Serial.read () ;
}

Then just call myRead() instead of Serial.read() or Serial.available().

This is a crude fix though - your sketch cannot do anything else while myRead() blocks,
so it may not be appropriate for your sketch.

Alternatively you can define a read function that returns a designated value to
indicate no character was ready:

int maybeRead()
{
  if (Serial.available () > 0)
    return Serial.read() ;
  else
    return -1 ;
}

void loop ()
{
  int in_char = maybeRead () ;  // use it thus
  if (in_char == '0')   // test for values you expect, which won't be -1
  {
    ..
  }
  if (in_char == '1')
  {
    ..
  }
}

maybeRead() is non-blocking but returns non-negative result only if a valid
character was read.

Both these approaches put calls to available() into an auxiliary function so
they don't appear all over the rest of the sketch making it hard to read.

It’s a pleasure, if you’re learning.

May I suggest you start off with a program that just takes a number and echos it back multiplied by 5? That will help you get number input (as in: more than a single digit) worked out. Se the doc http://arduino.cc/en/Serial/ParseInt

commandosqueak:
Stage one
Write a small programme to calculate one of the three ohm's law equations, then modify to be able to work out all three equations. Each of the three codes run and work as I expect.

[ warning, pedantry ahead :slight_smile: ]
Mathematically there is only one equation. You can solve for different variables,
but that's just algebra, the equation itself isn't different, its an abstract relationship
between variables. Perhaps you mean formula?