I have an Arduino which has a temperature sensor connected to it constantly printing a temperature value every one second to a bluetooth serial port (using the HC-05 module). What is the best way to plot the data in real-time on the computer? I was thinking maybe MATLAB or python could be used but cannot find any recent tutorials on this.
Nowadays I do all my GUI stuff using HTML and CSS and the Python Bottle web framework.
...R
So if I make a one page website with a graph in the middle of it, would I be able to make it update in real-time with the data being input from a bluetooth connection?
Nurul15:
So if I make a one page website with a graph in the middle of it, would I be able to make it update in real-time with the data being input from a bluetooth connection?
Yes, if the programming on both sides is done correctly.
On the PC you will need code to listen for the data from the Arduino and refresh the web page as needed. Because a server cannot normally send data to a browser window you will need Javascript in the browser that regularly requests new data.
to use GNU Octave to plot serial data from an Arduino install Octave and the instrumeent-control package Octave instrument-control
start Octave GUI and type at the Command Window (only need to do this once)
pkg install -forge instrument-control
you can then recieve serial data and plot it
e.g. this Arduino code transmits sine wave data to the serial port
// SERIAL: send sin(x) data to be plotted by Octave
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.setTimeout(60*60*1000ul);
}
void loop() {
static float angle=0;
Serial.print(sin(angle));
Serial.print('\r');
angle+=2*PI/360;
delay(10);
}
this Octave code recieves the data and plots 1000 samples
# plot sserial recieved from arduino
pkg load instrument-control # load package to support serial
s1 = serial("\\\\.\\COM10"); # change COM port as required
set(s1, "baudrate", 115200) # Change baudrate
srl_flush(s1);
y=double(1) # define array
i=1
do
data = ReadToTermination(s1); # read a line of data
#disp(["data = " data]);
y(i)=str2double(data); # chars to double store in array
#disp(["y = " num2str(y(i))]);
fflush(stdout) ;
i=i+1; # increment array index
#x=kbhit (1) ;
until(i>1000);#x == 'X') # read 1000 samples
srl_close(s1);
plot(y);
it requires the Function ReadToTermination.m
# from https://www.edn.com/design/analog/4440674/Read-serial-data-directly-into-Octave
function [char_array] = ReadToTermination (srl_handle, term_char)
% parameter term_char is optional, if not specified
% then CR = '\r' = 13dec is the default.
if(nargin == 1)
term_char = 13;
end
not_terminated = true;
i = 1;
int_array = uint8(1);
while not_terminated
val = srl_read(srl_handle, 1);
if(val == term_char)
not_terminated = false;
end
% Add char received to array
int_array(i) = val;
i = i + 1;
end
% Change int array to a char array and return a string array
char_array = char(int_array);
#disp("int array ");
#disp(int_array);
endfunction
horace:
to use GNU Octave to plot serial data from an Arduino install Octave and the instrumeent-control package Octave instrument-control
start Octave GUI and type at the Command Window (only need to do this once)
pkg install -forge instrument-control
you can then recieve serial data and plot it
e.g. this Arduino code transmits sine wave data to the serial port
// SERIAL: send sin(x) data to be plotted by Octave
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.setTimeout(60601000ul);
}
void loop() {
static float angle=0;
Serial.print(sin(angle));
Serial.print('\r');
angle+=2*PI/360;
delay(10);
}
this Octave code recieves the data and plots 1000 samples
plot sserial recieved from arduino
pkg load instrument-control # load package to support serial
s1 = serial("\\.\COM10"); # change COM port as required
set(s1, "baudrate", 115200) # Change baudrate
srl_flush(s1);
y=double(1) # define array
i=1
do
data = ReadToTermination(s1); # read a line of data #disp(["data = " data]);
y(i)=str2double(data); # chars to double store in array #disp(["y = " num2str(y(i))]);
fflush(stdout) ;
i=i+1; # increment array index
#x=kbhit (1) ;
until(i>1000);#x == 'X') # read 1000 samples
srl_close(s1);
plot(y);
function [char_array] = ReadToTermination (srl_handle, term_char)
% parameter term_char is optional, if not specified
% then CR = '\r' = 13dec is the default.
if(nargin == 1)
term_char = 13;
end
not_terminated = true;
i = 1;
int_array = uint8(1);
while not_terminated
val = srl_read(srl_handle, 1);
if(val == term_char)
not_terminated = false;
end
% Add char received to array
int_array(i) = val;
i = i + 1;
end
% Change int array to a char array and return a string array
char_array = char(int_array); #disp("int array "); #disp(int_array);
endfunction
a run gives the attached plot
Thank you, this looks great. But how would I do this for receiving data via bluetooth, like through a HC-05 module. Serial data is not what I would be interested in.
your HC-05 bluetooth should appear as a COM port?
using a HC-06 with an Arduino Mega I run
// SERIAL: using Mega and HC-06 bluetooth send sin(x) data to be plotted by Octave
/* connect HC-06 to a Mega2560
GND | GND
5v | 5v
TXD | TX1
RXD | RX1
the pairing key is 1234*/
void setup() {
Serial.begin(9600); // Default connection rate for my BT module
Serial1.begin(9600); // Default connection rate for my BT module
}
void loop() {
static float angle=0;
Serial1.print(sin(angle));
Serial1.print('\r');
angle+=2*PI/360;
delay(10);
}
modify Octave code to suit baudrate and COM port (remember Octave requires ReadToTermination.m function)
# plot sserial recieved from arduino using HC-06
pkg load instrument-control # load package to support serial
s1 = serial("\\\\.\\COM15"); # change COM port as required
set(s1, "baudrate", 9600) # Change baudrate
srl_flush(s1);
y=double(1) # define array
i=1
do
data = ReadToTermination(s1); # read a line of data
#disp(["data = " data]);
y(i)=str2double(data); # chars to double store in array
#disp(["y = " num2str(y(i))]);
fflush(stdout) ;
i=i+1; # increment array index
#x=kbhit (1) ;
until(i>1000);#x == 'X') # read 1000 samples
srl_close(s1);
plot(y);
title("Sine wave from HC-06");