Filtering multiple analog inputs?

I have total of 4 analog temperature sensors connected to my Core.
Is there a library or function that i could use that could handle multiple inputs? Preferred filter would be median i think.
I’ve been looking for almost 2 days now but i’ve been unable to find a library that can handle multiple inputs, all read single input.

What kind of sensors and library are you using?
You can analogRead() all eight A-pins and the way you do it with one is just the same as you’d do it with all the others.

If you’re using Dallas OneWire then you should be able to do

DallasTemperature dallasD0(new OneWire(D0));
DallasTemperature dallasD1(new OneWire(D1));
DallasTemperature dallasD2(new OneWire(D2));
DallasTemperature dallasD3(new OneWire(D3));

Have you never wondered what the D3 did in your code here?

1 Like

@qwerty009, do you mean a multi-input median filter library? What exactly are your trying to do with the filtering?

I first tried to use Digital temperature sensors but i coudn’t get them to work reliably.
I switched to LM35 analog sensors. http://www.ti.com/lit/ds/symlink/lm35.pdf

Basically code measures room temperature and if it drops below 20c it turns ON pump so that water in radiators starts moving. If temp reaches 22c it turns pump OFF. Sometimes i get 1,5degree fluctuations in temp reading and pump starts stops when it’s not needed. I need filter to get stable readings.
Atm i ported some smoothing library, but it works only for one input. But i would like to run smoothing on all temp sensor inputs. IT also uploads sensor inputs to https://thingspeak.com/channels/20611
My code atm:

[code]#include “analogSmooth.h”

// This #include statement was automatically added by the Spark IDE.
#include “OneWire/OneWire.h”

// This #include statement was automatically added by the Spark IDE.

#include “LiquidCrystal_I2C.h”
#include “SparkTime/SparkTime.h”

String writeAPIKey = “xxx”;
String channelID = “20611”;

// TCP socket initialize
TCPClient client;

int ledRed = A0; //if ON then indicates that there is 230V present and boiler pump is OFF
int ledGreen = A1; // is ON then boiler pump is ON

int radikatemp = A2;
int toatemp = A3;
int pliiditemp = A4;
int pliidiveetemp = A5;

int relayRadiator = D2; //relay to turn ON/OFF radiator pump
int relayBoiler = D3; // relay to turn ON/OFF boiler pump.

int c = 0;

LiquidCrystal_I2C *lcd;
UDP UDPClient;
SparkTime rtc;

unsigned long currentTime;
unsigned long lastTime = 0UL;
String timeStr;

AnalogSmooth as100 = AnalogSmooth(100);

void setup(){

Serial.begin(9600);
Serial.println("===Starting===");
rtc.begin(&UDPClient, "north-america.pool.ntp.org");
rtc.setTimeZone(+2); // gmt offset
lcd = new LiquidCrystal_I2C(0x27, 20, 4); // set the LCD address to 0x20 for a 16x2 //SparkCore bug, address is actually 27 but shifted (0x27*2)
lcd->init(); // initialize the lcd
lcd->backlight();
lcd->clear();

pinMode(radikatemp, INPUT_PULLDOWN);
pinMode(toatemp, INPUT_PULLDOWN);
pinMode(pliiditemp, INPUT_PULLDOWN);
pinMode(pliidiveetemp, INPUT_PULLDOWN);

pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
pinMode(relayRadiator, OUTPUT);
pinMode(relayBoiler, OUTPUT);


digitalWrite(relayRadiator, LOW);
digitalWrite(relayBoiler, LOW);
analogWrite(ledRed,150);
}

void loop(){

currentTime = rtc.now();

if (currentTime != lastTime) {
    timeStr = "";
    timeStr += rtc.hour12String(currentTime);
    timeStr += ":";
    timeStr += rtc.minuteString(currentTime);
    timeStr += ":";
    timeStr += rtc.secondString(currentTime);    
    timeStr += " ";    
    timeStr += rtc.AMPMString(currentTime);
    
    lastTime = currentTime;
}

lcd->setCursor(5,0);
lcd->print(timeStr);

double radikaC = (analogRead(radikatemp) * 3.3) / 4095*100;  //getting the voltage reading from the temperature sensor
double toaC = (analogRead(toatemp) * 3.3) / 4095*100;
double pliidiC = (as100.analogReadSmooth(pliiditemp) * 3.3) / 4095*100;

// double pliidiveeC = (analogRead(pliidiveetemp) * 3.3) / 4095*100;

lcd->setCursor(1,1);
lcd->print("Radikasse");
lcd->setCursor(11,1);
lcd->print(radikaC, 1);
lcd->setCursor(1,2);
lcd->print("Toatemp");
lcd->setCursor(11,2);
lcd->print(toaC, 1);  
lcd->setCursor(1,3);
lcd->print("Pliita");
lcd->setCursor(11,3);
lcd->print(pliidiC, 1);

c = tempkontroll(radikaC, toaC, c);

byte sec = rtc.second(currentTime);
  if (sec == 10) {
          if(Spark.connected())
            {
                ThingSpeakUpdate("field1="+String(toaC)+"&field2="+String(radikaC));
            }
}

delay(1000);

}

void ThingSpeakUpdate(String tsData)
{
Serial.println("Date string: " + tsData);

Serial.println("...Connecting to Thingspeak");
 
// Connecting and sending data to Thingspeak
if(client.connect("api.thingspeak.com", 80))
{
    Serial.println("...Connection succesful, updating datastreams");
     
    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: "+writeAPIKey+"\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(tsData.length());
    client.print("\n\n");
     
    client.println(tsData); //the ""ln" is important here.
 
    // This delay is pivitol without it the TCP client will often close before the data is fully sent
    delay(200);
     
    Serial.println("Thingspeak update sent.");
}
else{
    // Failed to connect to Thingspeak
    Serial.println("Unable to connect to Thingspeak.");
}
 
if(!client.connected()){
    client.stop();
}
client.flush();
client.stop();

}

int tempkontroll(double radikaC, double toaC, int c)
{

    if(toaC < 21 && radikaC > 35 && c == 0) {
    c = 1;
    digitalWrite(relayRadiator, HIGH); //paneb relee "HIGH" asendisse
    }

    else if((toaC > 22 || radikaC < 35) && c == 1) {
    c = 0;
    digitalWrite(relayRadiator, LOW); //paneb relee "LOW" asendisse
    } 
    return c;
}[/code]

Hi @qwerty009

You should be able to make more than one AnalogSmooth object like this:

AnalogSmooth as100 = AnalogSmooth(100);
AnalogSmooth as101 = AnalogSmooth(100);
AnalogSmooth as102 = AnalogSmooth(100);
AnalogSmooth as103 = AnalogSmooth(100);

then later on you can use them

double pliidiC0 = (as100.analogReadSmooth(pliiditemp) * 3.3) / 4095*100;
double pliidiC1 = (as101.analogReadSmooth(pliiditemp) * 3.3) / 4095*100;
double pliidiC2 = (as102.analogReadSmooth(pliiditemp) * 3.3) / 4095*100;
double pliidiC3 = (as103.analogReadSmooth(pliiditemp) * 3.3) / 4095*100;

Not actually your point, but do you really mean INPUT_PULLDOWN?

Would this not influence your readings?

Tnx bko i will try it out.

Spark has 30k or similar internal resistors - they won’t influence readings. In fact without pulldown resistors inputs float at ~160mV. Even when i connected sensor it pulled readings high.

Link to library i used: https://github.com/MichaelThessel/arduino/tree/master/AnalogSmooth

Did as you suggested and it works nicely. Tnx, for help!
Before and after is nicely seen on upper graph (if previuos readings havent been deleted by the time someone checks).
https://thingspeak.com/channels/20611

2 Likes