[NEWBIE] Using Arduino to do various calculations and send them through serial.

Hello!

I'm currently working on a project that involves a bit of measuring and calculating, and i'm wondering if the arduino-controller would be able to perform these tasks, as it seems simple to program and very versatile. Things that i'll need the controller to do:

INPUT:
-4 analog temperature readings (NTC) [Analog input]
-2 Waterflow-meter readings (Hall) [Analog input]
-Something to monitor 3-phase current, amperage or kWh, most likely the power-meter will send pulses, so i assume it will be a [Digital Input]

OUTPUT:
-16x2 LCD Screen, or maybe a bigger one with the touch-option, as i have a couple of them already.

For these specifications i have choosed the Arduino Mega 2560, as it's available here, and it has enough (8) analog inputs, compared to the Uno/Nano, which can cause problems in the future.

The question is:
Can i use Arduino for my project? The calculations are not that special, just cooling capacity and stuff like that, to show on the LCD. :~

Totally depends on the sensors.
The NTC'w will be no problem.

The waterflow and KWH sensor will make it a bit difficult, the Arduino UNO has 2 external interrupts and for the flow and KWH meter you need them (3).
You need some multiplexing or - http://www.arduino.cc/playground/Main/PinChangeInt -

robtillaart:
Totally depends on the sensors.
The NTC'w will be no problem.

The waterflow and KWH sensor will make it a bit difficult, the Arduino UNO has 2 external interrupts and for the flow and KWH meter you need them (3).
You need some multiplexing or - http://www.arduino.cc/playground/Main/PinChangeInt -

I'll be starting with only 4 NTC sensors and the 2 waterflow-sensors which are HALL-sensors. Just ordered the Arduino Mega board and a 16x2 LCD. Will be asking more questions as soon as i get stuck with the programming :wink:

The programming language really seems simple compared to visual basic, but i have a lot to learn...

I've ran a couple of tests involving the LCD-screen which works fine, and playing around with an NTC-sensor. Google and this forum have been great help.

Now to the problem: At this time i would like to have the program read the value of one NTC sensor and store it as a variable (no problem, already done). When polled thru serial, it should send the value back.
The problem is that i got it working with one sensor, but with two different polling values it doesn't react to anything but the first sensor.

if(Serial.available()){
  if(Serial.read() == '1')  {
    Serial.println("one");
  }
  else if(Serial.read() == '2')  {
  Serial.println("two");
  }
  }

This is the part that i'm confused with. It sends the respond value when polled with "1", but not when polled with "2". I tried modifying IF / ELSE / ELSE IF statements a lot, but didn't succeed in this.

You're reading from the serial port twice. If you send a 2, it will be read in the test for 1 and your test for 2 will likely see -1, which is what read returns when there is nothing there. Try sending 12, it'll print 'two' I think. This would work better:

int ch;
if(Serial.available())
  {
  ch=Serial.read();
  if( ch== '1')  
    {
    Serial.println("one");
    }
  else if(ch == '2')
    {
    Serial.println("two");
    }
  }

Not sure what kwh meters you have avaiable in your area, but I have used a standard dry contact pulse kwh meter no problems into Arudino "just tinkering" project.
Cannot seem to find the code I was using at the moment I am sorry. But it was when I was seriously starting out with coding and didn't have too much hassle getting it to work.

wildbill:
You're reading from the serial port twice. If you send a 2, it will be read in the test for 1 and your test for 2 will likely see -1, which is what read returns when there is nothing there. Try sending 12, it'll print 'two' I think. This would work better:

int ch;

if(Serial.available())
  {
  ch=Serial.read();
  if( ch== '1') 
    {
    Serial.println("one");
    }
  else if(ch == '2')
    {
    Serial.println("two");
    }
  }

Thanks! This worked like a charm!

I'm thinking of using this polling method to transfer the serial data instead of sending data all the time with separators and so on. The big question now is, what is an EASY program/programming language/method of collecting the data and show it in realtime and graphs on a PC. There are tons of ways to do this, i know, but i have very limited programming skills (though developing all the time). I've played around with VB a bit now, and just tried the PLX-DAQ, but didn't understand how to get the graphs nor the timestamp to work, data was flowing ok.

Really hacky, but the world runs on spreadsheets.

Write to a csv file, set up spreadsheet to read the file and graph it. Program a startup macro so that the reading and display are automatic, then run up the spreadsheet when you want to see the graph.

shelleycat:
Really hacky, but the world runs on spreadsheets.

Write to a csv file, set up spreadsheet to read the file and graph it. Program a startup macro so that the reading and display are automatic, then run up the spreadsheet when you want to see the graph.

Well, now i got data collecting to work in excel, so i've got data with timestamps to work with. So the next issue are excel-related, not arduino :smiley:

Anyhow, that means it'll be time to work on the other probes that will be connected to the arduino:
I have two flowsensors that are hall effect, can i get them to work with a digital input? It's possible to choose wether to use NPN or PNP. The sensor itself needs minimum 12v, but the signal itself can be less(?) if ran in the correct mode (cant remember if it's PNP or NPN, but the mode where voltage is supplied from the Arduino to the sensor, and when sensor detects magnetic, it grounds the pin). Amidoinitrite? :stuck_out_tongue:

wildbill:
You're reading from the serial port twice. If you send a 2, it will be read in the test for 1 and your test for 2 will likely see -1, which is what read returns when there is nothing there. Try sending 12, it'll print 'two' I think. This would work better:

int ch;

if(Serial.available())
  {
  ch=Serial.read();
  if( ch== '1') 
    {
    Serial.println("one");
    }
  else if(ch == '2')
    {
    Serial.println("two");
    }
  }

Wow that was good eye. I love hidden mistake challenges.

For the NTC sensors, are you referring to thermistors? I have a tutorial;

I would use straight polling if the digital inputs are changing slowly (say 100Hz or less) and interrupts if the digital inputs are fast changing.
16X2 display is a good choice. It keeps things simple. You can use color dot-matrix displays but that won't make your result any more realistic :wink:

liudr:
Wow that was good eye. I love hidden mistake challenges.

For the NTC sensors, are you referring to thermistors? I have a tutorial;
Measure temperature | LiuDr Electronic Solutions LLC Official Blog

I would use straight polling if the digital inputs are changing slowly (say 100Hz or less) and interrupts if the digital inputs are fast changing.
16X2 display is a good choice. It keeps things simple. You can use color dot-matrix displays but that won't make your result any more realistic :wink:

Yes, i have 10k thermistors, and they're already hooked up and working, using 10k resistors and this code:

double Temp1in(float RawADC) {
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;            // Convert Kelvin to Celcius
 return Temp;
}

Now to the next problem... I've got two termistors and one flowmeter hooked up, everything is working. Next step is to let arduino calculate the cooling power with a simple code. The problem is that i can't get the code to work.

  CoolingCalc = (float(Calc / 60 * 4.186 * ( Temp1in - Temp2in )),1); //Calculates cooling power

Something's wrong with the Temperature variables, dunno if i should store the variables for the results before calculating, or is it the "float" type that gives me problems?
I just tried to do this in a similar way to the waterflow-calculation which worked fine;

  Calc = (float(Flow1 / 49.03 * 60 )); //(Pulse frequency / 49.03 pulses/ltr x 60 sec = ltr/min)

Temp1in temp2in and calc will all need to be float to make the right calculation. Your float only makes the final answer float, which is too late.

liudr:
Temp1in temp2in and calc will all need to be float to make the right calculation. Your float only makes the final answer float, which is too late.

  CoolingCalc = (float(Calc / 60 * 4.186 * ( float(Temp1in) - float(Temp2in) )),1); //Calculates cooling power

This just gives me errors about converting double to float.
Then, when changed double vars to float vars for Temp1in & Temp2in, it says "ISO C++ forbids using pointer to a function in subtraction".

Not sure where the double issue comes in - can't tell from that fragment. In any event, float and double are the same for arduino. Does this work any better?

CoolingCalc = (float)Calc / 60.0 * 4.186 * ((float)Temp1in - (float)Temp2in); //Calculates cooling power

wildbill:
Not sure where the double issue comes in - can't tell from that fragment. In any event, float and double are the same for arduino. Does this work any better?

CoolingCalc = (float)Calc / 60.0 * 4.186 * ((float)Temp1in - (float)Temp2in); //Calculates cooling power

It didn't work either... so, the problem is, HOW do i get the temp.sensor values stored as variables so that i can use them in my cooling calculation?

#include <math.h>

double Temp1in(float RawADC) {
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;            // Convert Kelvin to Celcius
 return Temp;
}

double Temp2in(float RawADC) {
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;            // Convert Kelvin to Celcius
 return Temp;
}

These (Temp1in & Temp2in) are the ones that i need to work as variables for calculations.

Here's the whole code, still really messy and under construction:

#include <LiquidCrystal.h>              // include the library code:
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);        // initialize the library with the numbers of the interface pins

#include <math.h>

double Temp1in(float RawADC) {
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;            // Convert Kelvin to Celcius
 return Temp;
}

double Temp2in(float RawADC) {
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;            // Convert Kelvin to Celcius
 return Temp;
}



volatile int Flow1; //measuring the rising edges of the signal
float Calc;
float CoolingCalc;
int hallsensor = 2;    //The pin location of the sensor
void rpm ()     //This is the function that the interupt calls
{
  Flow1++;  //This function measures the rising and falling edge of the hall effect sensors signal
}


void setup() 
{
  lcd.begin(16, 2);          // set up the LCD's number of columns and rows: 
  Serial.begin(9600);  
  pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
  attachInterrupt(0, rpm, FALLING); //and the interrupt is attached  
}

void loop() 
{
  Flow1 = 0;	//Set Flow1 to 0 ready for calculations
  sei();		//Enables interrupts
  delay (1000);	//Wait 1 second
  cli();		//Disable interrupts
  Calc = (float(Flow1 / 49.03 * 60 )); //(Pulse frequency / 49.03 pulses/ltr x 60 sec = ltr/min)
  CoolingCalc = (Calc / 60 * 4.186 ); //Calculates cooling power
  
  
  lcd.setCursor(0,0); 
  lcd.print(float(Calc),1); //Prints the number calculated above
  lcd.setCursor(0,6);
  lcd.print(float(CoolingCalc),1);
  lcd.print('\n');
  lcd.setCursor(0, 1);
  lcd.print(float(Temp1in(analogRead(0))),1);
  lcd.print("  ");
  


  Serial.print("DATA,TIME,");
  Serial.print(float(Temp1in(analogRead(0))),1);  // display Celsius
  Serial.print(",");
  Serial.print((Calc),1);
  Serial.print(",11,14,99,7");
  Serial.print('\r');
  delay(1000);
 }

This code works. But what i'm looking for is to add the described lines to the 'CoolingCalc'-function, which just doesn't work. I know it's a little thing, maybe to define the Temp1in & Temp2in as different variables or so.

EDIT: Changing all the double types to float types still gives me an error "error: invalid operands of types 'double' and 'float ()(float)' to binary 'operator*'" as soon as i try to add one of the temperature variables to the calculation.