05/04/2021 To 11/04/2021
Thingspeak Visualization IOT Platform
Thingspeak.com IOT platform was used to visualize real time data graphically. By using this site we can create a private channel to visualize device data. It has 15 sec latency to data updating speed. Also we can get more less latency service by paid monthly. But in this stage we no need it. Also we can get service MATLAB cloud server services to compare the data.
Administrative Details
Channel Details
Channel Name : Urine Volume Monitoring Platform For Dengue Patients
Maths Work Account : urinevolumemeter@gmail.com
Account Password : Urinevolume2020
Channel ID : 1256809
Read API Key : M1UZKQPGO7UMKZ8I
Write API Key : RAPBZ11S6DYB2NYL
Arduino Code to upload real time processing data to thingspeak platform
Data uploading code through Wifi Module
#include <SoftwareSerial.h>
#define RX 2
#define TX 3
String PID = "S.R.Hettiarachchi";
String AP = "Dialog 4G 193"; // AP NAME
String PASS = "45pZerC56"; // AP PASSWORD
String API = "29B9071Y7JF0OJ20"; // Write API KEY
String HOST = "api.thingspeak.com";
String PORT = "80";
String field = "field1";
int countTrueCommand;
int countTimeCommand;
boolean found = false;
int valSensor = 1;
SoftwareSerial esp8266(RX,TX);
void setup() {
Serial.begin(9600);
esp8266.begin(115200);
sendCommand("AT",5,"OK");
sendCommand("AT+CWMODE=1",5,"OK");
sendCommand("AT+CWJAP=\""+ AP +"\",\""+ PASS +"\"",20,"OK");
}
void loop() {
//valSensor = getSensorData();
String getData = "GET /update?api_key="+ API +"&"+ field +"="+PID;
sendCommand("AT+CIPMUX=1",5,"OK");
sendCommand("AT+CIPSTART=0,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK");
sendCommand("AT+CIPSEND=0," +String(getData.length()+4),4,">");
esp8266.println(getData);delay(1500);countTrueCommand++;
sendCommand("AT+CIPCLOSE=0",5,"OK");
}
int getSensorData(){
return random(1000); // Replace with your own sensor code
}
void sendCommand(String command, int maxTime, char readReplay[]) {
while(countTimeCommand < (maxTime*1))
{
esp8266.println(command);//at+cipsend
if(esp8266.find(readReplay))//ok
{
found = true;
break;
}
countTimeCommand++;
}
if(found == true)
{
//Serial.println("OYI");
countTrueCommand++;
countTimeCommand = 0;
}
if(found == false)
{
//Serial.println("Fail");
countTrueCommand = 0;
countTimeCommand = 0;
}
found = false;
}
Arduino code File
Data Analyzing using MATLA cloud server
Analyze increasing rate of urine drop count at constant time slot
% Template MATLAB code for visualizing data from a channel as a 2D line
% plot using PLOT function.
% Prior to running this MATLAB code template, assign the channel variables.
% Set 'readChannelID' to the channel ID of the channel to read from.
% Also, assign the read field ID to 'fieldID1'.
% TODO - Replace the [] with channel ID to read data from:
readChannelID = 1256809;
% TODO - Replace the [] with the Field ID to read data from:
fieldID1 = 2;
% Channel Read API Key
% If your channel is private, then enter the read API
% Key between the '' below:
readAPIKey = 'M1UZKQPGO7UMKZ8I';
%% Read Data %%
[data, time] = thingSpeakRead(readChannelID, 'Field', fieldID1, 'NumPoints', 10, 'ReadKey', readAPIKey);
A= zeros(1,5);
for x=2:6
A(x-1) = (data(x)-data(x-1))/15;
end
time1 = time(2:6);
%% Visualize Data %%
subplot(2,1,1);
plot(time, data);
xlabel('Time');
ylabel('Urine drop count');
subplot(2,1,2);
plot(time1, A);
xlabel('Time');
ylabel('Increasing Ratio');
Overall Analysis
% Template MATLAB code for visualizing data from a channel as a 2D line
% plot using PLOT function.
% Prior to running this MATLAB code template, assign the channel variables.
% Set 'readChannelID' to the channel ID of the channel to read from.
% Also, assign the read field ID to 'fieldID1'.
% TODO - Replace the [] with channel ID to read data from:
readChannelID = 1256809;
% TODO - Replace the [] with the Field ID to read data from:
fieldID1 = 7;
fieldID2 = 5;
% Channel Read API Key
% If your channel is private, then enter the read API
% Key between the '' below:
readAPIKey = 'M1UZKQPGO7UMKZ8I';
%% Read Data %%
[data, time] = thingSpeakRead(readChannelID, 'Field', fieldID1, 'NumPoints', 15, 'ReadKey', readAPIKey);
[data1, time1] = thingSpeakRead(readChannelID, 'Field', fieldID2, 'NumPoints', 15, 'ReadKey', readAPIKey);
%% Visualize Data %%
plot(data,data1);
Overall progress of Thingspeak channel
Choosing best Display for this device
TFT Display
TFT 1.8 inch colour display was used to display real time data in this device. But we had not implement this display practically due to lack of components in this covid situation. Hence we simulated display performance by using proteus software and arduino microcontroller.
TFT display specifications
TFT LCD module has always been one of the hot products in DIY industry and LCD is basically the necessary products during all projects, at the same time, serial port modules are also the popular ones, because it takes few IO and the usage is simple. This section of the 1.8-inch TFT LCD serial SPI integrated features of compact, SPI interface.
It is a 1.8 "SPI TFT LCD Screen Module, 9pins interface. Not just a LCD break but include SD card (2GB),
The LCD drive ic is ST7735S. It's a 128 X 160 (resolution). The LCD has a wide viewing angle, the contrast is also very suitable.
The display interface is serial, it just needs 5 wires (CS, RS, SCL, SDA, RST) for controlling.
SDcard use hardware SPI interface (CS / MOSI / MISO / SCK), Not solder pins.
LED 3.3V IO and Power Supply pin
LED UTFT Support
SCL Serial clock input
SDA/SDI Serial data input
DC:Data/Command selection
RST:Reset Low level active
CS:Chip Selection,Low level active
GND:Ground
VDD33:3.3V Power Supply pin
Display Simulation Code
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "Keypad.h"
int drop_count = 0;
float time1= 151.2;
float Flow_rate= 50.3;
float Urine_vol= 0.0;
int k = 0;
String ID = "";
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
{ '1','2','3' },
{ '4','5','6' },
{ '7','8','9' },
{ '*','0','#' }
};
byte rowPins[ROWS] = {4,3,2,12};
byte colPins[COLS] = {7,6,5};
Keypad keypad = Keypad(makeKeymap(keys),rowPins, colPins, ROWS, COLS);
// For the Adafruit shield, these are the default.
//#define TFT_DC 9
//#define TFT_CS 10
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// If using the breakout, change pins as desired
Adafruit_ILI9341 tft = Adafruit_ILI9341(8, 9, 11, 13, 10, 12);
void setup() {
Serial.begin(9600);
Serial.println("ILI9341 Test!");
tft.begin();
Serial.println(F("Benchmark Time (microseconds)"));
delay(1);
testText();
tft.fillScreen(ILI9341_WHITE);
Patient_ID();
}
void loop(void) {
if (k==0){
char key = keypad.getKey();
if (key){
if (key == '*'){
k=1;
}
else {
tft.setTextColor(ILI9341_GREEN); tft.setTextSize(5);
tft.print(key);
ID += key;
}
}
}
if (k==1){
tft.fillScreen(ILI9341_WHITE);
Patient_Report();
drop_count =drop_count +1;
Urine_vol = Urine_vol +20.4;
//delay(1000);
}
}
unsigned long testText() {
unsigned long start = micros();
tft.setCursor(15, 70);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
tft.println("URINE VOLUME");
tft.setCursor(80, 100);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
tft.println("METER");
tft.setCursor(35, 125);
tft.setTextColor(ILI9341_MAGENTA); tft.setTextSize(1.5);
tft.println("Smart Urine Volume Detector");
tft.setCursor(0, 150);
tft.setTextColor(ILI9341_GREEN); tft.setTextSize(2);
tft.println("Urine Report Reading");
tft.setCursor(15, 170);
tft.println("Digital Interface");
tft.setCursor(25, 300);
tft.setTextColor(ILI9341_BLACK); tft.setTextSize(1);
tft.println("** UNIVERSITY OF PERADENIYA **");
return micros() - start;
}
unsigned long Patient_Report() {
unsigned long start = micros();
tft.setCursor(0, 10);
tft.setTextColor(ILI9341_MAGENTA); tft.setTextSize(2);
tft.println("Patient Report");
tft.setCursor(5, 50);
tft.setTextColor(ILI9341_BLACK); tft.setTextSize(2);
tft.print("Patient ID : ");
tft.setTextColor(ILI9341_RED); tft.setTextSize(2);
tft.println(ID);
tft.setTextColor(ILI9341_BLACK); tft.setTextSize(2);
tft.setCursor(5, 90);
tft.setTextColor(ILI9341_BLACK); tft.setTextSize(2);
tft.print("Drop Count : ");
tft.setTextColor(ILI9341_RED); tft.setTextSize(2);
tft.println(drop_count);
tft.setTextColor(ILI9341_BLACK); tft.setTextSize(2);
tft.setCursor(5, 130);
tft.print("Drop Time : ");
tft.setTextColor(ILI9341_RED); tft.setTextSize(2);
tft.println(time1);
tft.setTextColor(ILI9341_BLACK); tft.setTextSize(2);
tft.setCursor(5, 170);
tft.print("Urine Volume : ");
tft.setTextColor(ILI9341_RED); tft.setTextSize(2);
tft.println(Urine_vol);
tft.setTextColor(ILI9341_BLACK); tft.setTextSize(2);
tft.setCursor(5, 210);
tft.print("Flow Rate : ");
tft.setTextColor(ILI9341_RED); tft.setTextSize(2);
tft.println(Flow_rate);
tft.setTextColor(ILI9341_BLACK); tft.setTextSize(2);
delay(1000);
return micros() - start;
}
unsigned long Patient_ID() {
unsigned long start = micros();
tft.setCursor(5, 30);
tft.setTextColor(ILI9341_MAGENTA); tft.setTextSize(2);
tft.println("Enter Patient ID");
tft.println();
tft.println();
tft.setCursor(35, 300);
tft.setTextColor(ILI9341_BLACK); tft.setTextSize(1);
tft.println("To confirm, press * button");
tft.setCursor(5, 70);
return micros() - start;
}
Simulation files
Simulation Files
16*2 LCD Display
LCD modules are very commonly used in most embedded projects, the reason being its cheap price, availability and programmer friendly. Most of us would have come across these displays in our day to day life, either at PCO’s or calculators. The appearance and the pinouts have already been visualized above now let us get a bit technical.
16×2 LCD is named so because; it has 16 Columns and 2 Rows. There are a lot of combinations available like, 8×1, 8×2, 10×2, 16×1, etc. but the most used one is the 16×2 LCD. So, it will have (16×2=32) 32 characters in total and each character will be made of 5×8 Pixel Dots.
Now, we know that each character has (5×8=40) 40 Pixels and for 32 Characters we will have (32×40) 1280 Pixels. Further, the LCD should also be instructed about the Position of the Pixels.
16*2 LCD Display code for Atmega328p Microcontroller
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
SoftwareSerial GetData(6, 7);
byte smiley[8] = {
0b00000,
0b00000,
0b01010,
0b00000,
0b00000,
0b10001,
0b01110,
0b00000
};
String Person_ID_Initials;
String Person_ID_Surname ;
String Drop_count ;
String Volume ;
String Flow_rate ;
String Time_Gap ;
String inputString ;
void setup() {
Serial.begin(9600);
GetData.begin(9600);
Person_ID_Initials = "In Progress..";
Person_ID_Surname = "In Progress..";
Drop_count = "In Progress..";
Volume = "In Progress..";
Flow_rate = "In Progress..";
Time_Gap = "";
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Welcome to Urine");
lcd.setCursor(2, 1);
lcd.print("Volume Meter");
delay(3000);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("S3 Engineering");
lcd.setCursor(1, 1);
lcd.print("Lanka (Pvt) LTD");
delay(3000);
lcd.clear();
}
void loop() {
while (GetData.available()) {
char inChar = (char)GetData.read();
inputString += inChar;
}
if (inputString.length()>0){
//Serial.println(inputString);
Read_Input();
}
lcd.setCursor(0, 0);
lcd.print(Person_ID_Initials);
lcd.setCursor(0, 1);
lcd.print(Person_ID_Surname);
delay(5000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Drop Count");
lcd.setCursor(0, 1);
lcd.print(Drop_count);
delay(5000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Urine Volume");
lcd.setCursor(0, 1);
lcd.print(Volume + " ml");
delay(5000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Flow Rate");
lcd.setCursor(0, 1);
lcd.print(Flow_rate + " ml/h");
delay(5000);
lcd.clear();
}
void Read_Input(){
int firstCommaIndex1 = inputString.indexOf(',');
int secondCommaIndex1 = inputString.indexOf(',', firstCommaIndex1+1);
int thirdCommaIndex1 = inputString.indexOf(',', secondCommaIndex1+1);
int forthCommaIndex1 = inputString.indexOf(',', thirdCommaIndex1+1);
int fifthCommaIndex1 = inputString.indexOf(',', forthCommaIndex1+1);
int sixthCommaIndex1 = inputString.indexOf(',', fifthCommaIndex1+1);
Person_ID_Initials = inputString.substring( 1,firstCommaIndex1);
Person_ID_Surname = inputString.substring( firstCommaIndex1+1,secondCommaIndex1);
Drop_count = inputString.substring( secondCommaIndex1+1,thirdCommaIndex1);
Time_Gap = inputString.substring( thirdCommaIndex1+1,forthCommaIndex1);
Volume = inputString.substring( forthCommaIndex1+1,fifthCommaIndex1);
Flow_rate = inputString.substring( fifthCommaIndex1+1,sixthCommaIndex1);
inputString ="";
Serial.println(Person_ID_Initials+ " " + Person_ID_Surname);
Serial.println(Drop_count);
Serial.println(Time_Gap);
Serial.println(Volume);
Serial.println(Flow_rate);
}
Display code file
Overall progress of the display