Samira PeirisPasindu Liyanage
Published © MIT

Industrial Data Acquisition Platform

An IoT platform based on the ATmega328p designed to acquire data using industrial standard 4-20mA sensors and MODBUS protocol.

IntermediateFull instructions provided5 days1,802
Industrial Data Acquisition Platform

Things used in this project

Hardware components

ATmega328
Microchip ATmega328
×2
ESP8266 ESP-12E
Espressif ESP8266 ESP-12E
×1
nRF24 Module (Generic)
×1
SparkFun FTDI Basic Breakout - 5V
SparkFun FTDI Basic Breakout - 5V
×1
Linear Regulator (7805)
Linear Regulator (7805)
×1

Software apps and online services

MQTT
MQTT
AWS EC2
Amazon Web Services AWS EC2
Node-RED
Node-RED

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Hot Air Gun
Crimping Tool

Story

Read more

Schematics

ARMADAS Board - Schematic

Code

ARMADAS Board - Slave

Arduino
This is the code for the RF enabled Slave Device
/* ============================= RF Variables ===================================*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};

/* ============================= Analog Mux Variables ===================================*/

#define Apin A1
#define Bpin A2
#define Cpin A3


/*======================== Totaliser ===============================*/
volatile int counter = 0;
uint32_t totaliserval = 0;


/*===================== MODBUS ============================*/
#include <ModbusMaster.h>
#include <SoftwareSerial.h>
#define MAX485_DE      6
#define MAX485_RE_NEG  6

ModbusMaster node1;
SoftwareSerial ss(5, 4); //RX 5 TX 4

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, HIGH);
  digitalWrite(MAX485_DE, HIGH);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, LOW);
  digitalWrite(MAX485_DE, LOW);
}


int meterval1 = 0;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  analogmuxsetup();
  pulsesetup();
  modbussetup();
  nrfsetup();
  
  
  
}

void loop() {
  decidewhat();
}

void analogmuxsetup(){
  pinMode(Apin,OUTPUT);
  pinMode(Bpin,OUTPUT);
  pinMode(Cpin,OUTPUT);
}

void modbussetup() {
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  ss.begin(9600);

  // Modbus slave ID 1
  node1.begin(5, ss);

  node1.preTransmission(preTransmission);
  node1.postTransmission(postTransmission);

  delay(1000);
}


float readpowermeter() {
  boolean flag = 0;
  uint8_t result;

  result = node1.readHoldingRegisters(0x0A8C, 2); //read 4 registers from 0x0000
  if (result == node1.ku8MBSuccess)
  {

        unsigned long high = node1.getResponseBuffer(0);
        unsigned long low = node1.getResponseBuffer(1);
        long int num = ((high << 16) | low);
        float wppval = *(float*)&num / 1000.00f;
        return wppval;
        
  } else {
    flag = 1;
  }
  node1.clearResponseBuffer();
}

void nrfsetup() {
  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00001
  radio.openReadingPipe(1, addresses[0]); // 00002
  radio.setPALevel(RF24_PA_MAX);
}




void decidewhat() {
  char rmessage = ' ';
  while (1) {
    radio.startListening();
    if (radio.available()) {
      radio.read(&rmessage, sizeof(rmessage));
      Serial.println(rmessage);
      break;
    }

  }

  if (rmessage == 'a') {//ph
    delay(5);
    sendvalue(selectanaloginput(1));
  } else if (rmessage == 'b') {//chlorine
    delay(5);
    sendvalue(selectanaloginput(2));
  } else if (rmessage == 'c') {//cond
    delay(5);
    sendvalue(selectanaloginput(3));
  } else if (rmessage == 'd') {//flowrate
    delay(5);
    sendvalue(selectanaloginput(5));
  }else if (rmessage == 'e') {
    delay(5);
    //totaliserval = counter;
    sendvalue(counter);
  }else if (rmessage == 'f') {
    delay(5);
    sendvalue(readpowermeter());
  }


}

int selectanaloginput(int x) {
  if (x == 1) {
    digitalWrite(Apin, LOW);
    digitalWrite(Bpin, LOW);
    digitalWrite(Cpin, LOW);
    delay(5);
    return analogRead(A0);

  } else if (x == 2 ) {
    digitalWrite(Apin, HIGH);
    digitalWrite(Bpin, LOW);
    digitalWrite(Cpin, LOW);
    delay(5);
    return analogRead(A0);


  } else if (x == 3) {
    digitalWrite(Apin, LOW);
    digitalWrite(Bpin, HIGH);
    digitalWrite(Cpin, LOW);
    delay(5);
    return analogRead(A0);

  }
  else if (x == 4) {
    digitalWrite(Apin, HIGH);
    digitalWrite(Bpin, HIGH);
    digitalWrite(Cpin, LOW);
    delay(5);
    return analogRead(A0);


  } else if (x == 5 ) {
    digitalWrite(Apin, LOW);
    digitalWrite(Bpin, LOW);
    digitalWrite(Cpin, HIGH);
    delay(5);
    return analogRead(A0);


  } else if (x == 6 ) {
    digitalWrite(Apin, HIGH);
    digitalWrite(Bpin, LOW);
    digitalWrite(Cpin, HIGH);
    delay(5);
    return analogRead(A0);


  } else if (x == 7) {
    digitalWrite(Apin, LOW);
    digitalWrite(Bpin, HIGH);
    digitalWrite(Cpin, HIGH);
    delay(5);
    return analogRead(A0);


  } else if (x == 8) {
    digitalWrite(Apin, HIGH);
    digitalWrite(Bpin, HIGH);
    digitalWrite(Cpin, HIGH);
    delay(5); 
    return analogRead(A0);

  }
}


void sendvalue(int message) {

  radio.stopListening();
  radio.write(&message, sizeof(message));
  Serial.println("SENT");
  //delay(100);

}

void waitforack() {

  while (1) {
    radio.startListening();
    if (radio.available()) {
      char rmessage;
      radio.read(&rmessage, sizeof(rmessage));
      Serial.println(rmessage);
      break;
    }

  }
}

void pulsesetup() {
  pinMode(2, INPUT);
  attachInterrupt(digitalPinToInterrupt(3), count, RISING);
}


void count(){
  counter++;
}

ARMADAS Board - Master

Arduino
This is the code for the RF enabled Master device
/*======================= RF Variables ======================*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(15, 14); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};

/*===================== Values ========================*/

int val1, val2, val3, val4, val5, val6, val7, val8 = 0;

/*=========================== SIM800L =======================*/
#include <Sim800l.h>
#include <SoftwareSerial.h> //is necesary for the library!! 
Sim800l Sim800l;  //to declare the library
String textSms, numberSms,MyString;
char* text;
char* number = "0773357892";
uint8_t index1;
bool error;




/*======================= Totaliser =======================*/
volatile int counter = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  //sim800setup();
  nrfsetup();
}

void loop() {
  master_request();
  //checkforsmsreq();
  sendtopc();
  //warn();
}

void nrfsetup() {
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_MIN);
}


void requestvalue(char val) {

  for (int i = 0; i < 5; i++) {

    sendchar(val);
    for (int i = 0; i < 50; i++) {
      radio.startListening();
      if (radio.available()) {
        int rmessage;
        radio.read(&rmessage, sizeof(rmessage));
        if (val == 'a'){//flowrate
          //Serial.println(rmessage);
          val1 =rmessage; //pH
        }else if(val == 'b'){
          val2 =rmessage; //
        }else if(val == 'c'){//Chlorine
          val3 = rmessage;
        }else if(val == 'd'){//Conductivity
          val4 = rmessage;
        }else if(val == 'e'){//Totaliser
          val5 = rmessage;
        }else if(val == 'f'){//kWh
          val6 = rmessage;
        }
        break;
      }
    }
  }
}


void sendchar(char message) {

  radio.stopListening();
  radio.write(&message, sizeof(message));
  //Serial.println("SENT");

}
void sendvalue(int message) {

  radio.stopListening();
  radio.write(&message, sizeof(message));
  //Serial.println("SENT");
  //delay(100);

}



void waitforack() {

  while (1) {
    radio.startListening();
    if (radio.available()) {
      char rmessage;
      radio.read(&rmessage, sizeof(rmessage));
      Serial.println(rmessage);
      break;
    }

  }
}

void master_request(){
  requestvalue('a');
  delay(100);
  requestvalue('b');
  delay(100);
  requestvalue('c');
  delay(100);
  requestvalue('d');
  delay(100);
  requestvalue('e');
  delay(100);
//  requestvalue('f');
//  delay(100);
}

void sendtopc(){

  Serial.print((val4*(4.8/402.0)-2.1));//Flowrate (val4*(4.79/402)-2.1447f)
  Serial.print(",");
  Serial.print(val1*(0.7f/134.0)+4.991f);//pH val1*(1.6f/322.0)+5.1f
  Serial.print(",");
  Serial.print(val2*(3.11/479.00)-1.233f);//Chlorine val2*(4.97/404)-2.214
  Serial.print(",");
  Serial.print((val3)*(221.1f/571.00f)-73.92f);//Conductivity ((val3)*(0.15f/125.00f))-0.216f
  Serial.print(",");
  Serial.print(val5/1000.000f);
  Serial.println(",");
}


void sim800setup() {
  Sim800l.begin(); // initializate the library.
  //error = Sim800l.delAllSms(); //clean memory of sms;
}


void checkforsmsreq() {
  textSms = Sim800l.readSms(1); //read the first sms

  if (textSms.indexOf("OK") != -1) //first we need to know if the messege is correct. NOT an ERROR
  {
    if (textSms.length() > 1)  // optional you can avoid SMS empty
    {

      numberSms = Sim800l.getNumberSms(1); // Here you have the number
      //for debugin
      //Serial.println(numberSms);
      textSms.toUpperCase();  // set all char to mayus ;)

      if (textSms.indexOf("FLOW") != -1) {
        
        MyString = String((val4*(4.8/402.0)-2.1), 1); //Convert float to String
        MyString = (MyString + " m3/h");
        // convert string to char starts here
        // Length (with one extra character for the null terminator)
        int str_len = MyString.length() + 1;
        // Prepare the character array (the buffer)
        char char_array[str_len];
        // Copy it over
        MyString.toCharArray(char_array, str_len);
        error = Sim800l.sendSms(number, char_array);
      }
      else if (textSms.indexOf("PH") != -1) {
        
        MyString = String(val1*(0.7f/134.0)+4.991f, 1); //Convert float to String
        MyString = (MyString + " pH");
        // convert string to char starts here
        // Length (with one extra character for the null terminator)
        int str_len = MyString.length() + 1;
        // Prepare the character array (the buffer)
        char char_array[str_len];
        // Copy it over
        MyString.toCharArray(char_array, str_len);
        error = Sim800l.sendSms(number, char_array);
      } else if (textSms.indexOf("CL") != -1) {
        
        MyString = String(val2*(3.11/479.00)-1.233f,1); //Convert float to String
        MyString = (MyString + " mg/l");
        // convert string to char starts here
        // Length (with one extra character for the null terminator)
        int str_len = MyString.length() + 1;
        // Prepare the character array (the buffer)
        char char_array[str_len];
        // Copy it over
        MyString.toCharArray(char_array, str_len);
        error = Sim800l.sendSms(number, char_array);
      }else if (textSms.indexOf("COND") != -1) {
        
        MyString = String((val3)*(221.1f/571.00f)-73.92f, 1); //Convert float to String
        MyString = (MyString + " uS/cm");
        // convert string to char starts here
        // Length (with one extra character for the null terminator)
        int str_len = MyString.length() + 1;
        // Prepare the character array (the buffer)
        char char_array[str_len];
        // Copy it over
        MyString.toCharArray(char_array, str_len);
        error = Sim800l.sendSms(number, char_array);
      }else if (textSms.indexOf("TOT") != -1) {
        
        MyString = String(val5/1000.000f, 4); //Convert float to String
        MyString = (MyString + " kg");
        // convert string to char starts here
        // Length (with one extra character for the null terminator)
        int str_len = MyString.length() + 1;
        // Prepare the character array (the buffer)
        char char_array[str_len];
        // Copy it over
        MyString.toCharArray(char_array, str_len);
        error = Sim800l.sendSms(number, char_array);
      }
      else {
        //Serial.println("Not Compatible");
      }


      Sim800l.delAllSms(); //do only if the message is not empty,in other case is not necesary
      //delete all sms..so when receive a new sms always will be in first position
    }



  }
}

void warn(){
  if(val1 > 900){
    error = Sim800l.sendSms(number, "WARNING");
  }
}

Credits

Samira Peiris

Samira Peiris

13 projects • 64 followers
Electrical and electronic engineer from Sri Lanka. I'm interested in AI, computer vision and embedded systems.
Pasindu Liyanage

Pasindu Liyanage

3 projects • 23 followers
Electrical and Electronics Engineering Undergraduate

Comments