I am trying to plot the real time graph of all the axes of the accelerometer wirelessly by XBee through MATLAB.
I have achieved the following until now:
On the transmitter side, I have an Arduino connected with an Xbee shield. I am using a Series 2 Xbees for this purpose.
I have an ADXL335 breakout board accelerometer hooked in to the analog pins Arduino+Shield combo and also the XBee (Co-Ordinator API) on the shield.
On the receiver side, I have an XBee (Router AT) connected to a computer which will record the output and plot it in MATLAB.
I also want to mention that I am using the Arduino library for MATLAB for the Arduino code.
Now, when I wire up the Arduino (i.e. I don't use the Xbee) then I get a perfect output of all the axis of the accelerometer.
But when I hook in the Xbee and try to communicate with the arduino I get nothing. E.g. when use the Xbee the command to plot the graph is:
a = arduino(COM X);
where X is the COM port where the Arduino is connected.
How should I change the command when I connect my Xbee? (Recalling again that my Arduino and accelerometer are not connected to the computer but my receiver side Xbee is.)
Here is my MATLAB code:
a.pinMode(15,'input');
a.pinMode(16,'input');
a.pinMode(17,'input');
a.pinMode(18,'output');
a.pinMode(19,'output');
a.digitalWrite(18,0);
a.digitalWrite(19,1);
xval = zeros();
yval = zeros();
zval = zeros();
xval(1) = a.analogRead(3);
yval(1) = a.analogRead(2);
zval(1) = a.analogRead(2);
pause(.001);
for i = 2:1000
xval(i) = a.analogRead(3);
yval(i) = a.analogRead(2);
zval(i) = a.analogRead(2);
xmod = (xval-496)/300;
ymod = (yval-511)/300;
zmod = (zval-508)/300;
subplot( 3,1,1)
plot(xmod, 'r');
axis([1 1000 -0.5 0.5]);
title( 'x' );
subplot( 3,1,2)
plot(ymod, 'r');
axis([1 1000 -0.5 0.5]);
title( 'y' );
subplot( 3,1,3)
plot(zmod, 'r');
axis([1 1000 -0.5 0.5]);
title( 'z' );
pause(0.001);
end
If I understand your setup correctly, it sounds like the problem is that you're using API firmware on the XBee connected to your Arduino. If you're looking to use XBee modules as a serial cable replacement (i.e., data arrives on serial port of XBee A, and is sent out on serial port of XBee B), then you should use "AT mode" firmware on both, and configure the DH/DL registers with the address of the paired node (with a shortcut of using zeros for DH/DL to indicate the coordinator as the destination node).
The API firmware requires a "smart host" that sends and parses "frames" of data that include header bytes and a checksum footer.
Digi's XBee Examples Site has some nice tutorials on getting XBee modules paired to each other for transparent serial communications.
Related
I currently have NI BNC-2110 connect to the NI USB-6255 which is then connected to my computer.
My goal is to generate a digital output through the NI BNC-2110 and then read the output on an analog input on the same NI BNC-2110. (The purpose of this is to make sure that I know how to properly output a digital signal and can input an analog signal, and I figured this would just check both things simultaneously.)
The setup works when generating a digital signal and reading an analog when I use the software NI MAX, my problem is when I try and do the same thing in Matlab.
Here is my current code in Matlab:
d = daq.getDevices
s = daq.createSession('ni');
addAnalogInputChannel(s,'dev1', 'ai0', 'Voltage');
s.Rate = 8000;
q = daq.createSession('ni');
addDigitalChannel(q,'dev1','Port2/Line0:0','OutputOnly');
for p = 1:1:100
outputSingleScan(q,1)
pause(0.1)
data = s.inputSingleScan;
data
outputSingleScan(q,0)
pause(0.1)
data = s.inputSingleScan;
data
end
My current results are an analog input of ~0 Volts, and what I expect is a square wave from my analog input.
Any help on this would be much appreciated.
I am expecting something with a syntax in Matlab with port to be the problem, but not to sure.
I'm using the analog pins of an Arduino to measure voltage and print it to the serial port with serial.print(string). This is working, it outputs one value in the form of xxxx.yyyy with varying length, this I checked with the build in serial viewer. To read it, I'm using Matlab with fscanf() or fgetl(). This shows the correct thing, aaaa.bbbb, but with a weird kind of delay. When I change the voltage, the reading lags behind 5-10 seconds, but when I increase the voltage from 0 to 3 to 5, within this timeframe, like 3 seconds between 3 and 5, the reading changes as well. It does not in the same way as I changed the voltage, but it does get these values, as if it were 2 step inputs, even though I changed them by hand not super fast.
When reading and researching, I came across the fact that maybe the BaudRate was too low, so I changed it to the maximum of the Arduino at 115200. I changed the value in the Matlab code as well. I also tried the Arduino Hardware support package, with the readVoltage() function, but this has a too low sampling rate.
The settings for the serial port:
s = serial('com3');
set(s, 'BaudRate', 115200); % set BaudRate to 115200
set(s, 'Parity', 'none'); % set Parity Bit to None
set(s, 'DataBits', 8); % set DataBits to 8
set(s, 'StopBit', 1); % set StopBit to 1
set(s,'Terminator','LF') % set terminating character to LF/new line
fopen(s);
The reading loop:
for i =1:am
val(:,i) = string(fgetl(s)); %retrieve value of serial port, in the form aaaa.bbbb where a and b can vary in length
if mod(i,10) == 0 %Display every 10 iterations
volt1 = floor(val)*5/1023; %Calculating actual voltage for A1, where floor(val) is first value
volt2= (volt1-floor(val))*5/0.1023; %getting only decimals for second voltage
plot(volt1) %plot the values
hold on
plot(volt2)
hold off
ylim([0 5])
xlim([i-1000 i]) %make the plot chug along
drawnow %Live
end
clc
toc
end
There are no error messages and using the other serial port, I had no visible delay. This should also be possible with Matlab, as people get refresh rates of 2-3kHz using this.
The problem is the way you are using plot in a loop. This is very inefficient.
Depending on your Matlab version and the overhead on your serial link you might be able to speed things up calling clf at the beginning of the loop to prevent a wild number of plots stacking on top of each other.
If the problem persist you might want to try animated line and addpoints in the loop.
Finally, there are a couple of things you might want to check: the Arduino connection for Matlab (I never tried it myself but I've read it gives good performance) and the latency timer on your serial port (that might be having an effect at low baud rates).
I am currently using a Tenney Environmental Chamber which uses a Watlow F4 temperature controller to read out the temperature of the chamber. On the back of the Tenney Chamber is a 25 pin connector labelled for Watlow modbus communication. I connected to this terminal using a 25-pin-to-serial-232 adapter and a serial-232-to-usb cable. According to Watlow, to communicate with the temperature controller you must use the modbus RTU protocol. I am trying to read register 100, which is specified by Watlow as getting the actual chamber temperature.
This is very similar to another question that was asked here (Matlab serial Communication with Watlow F4 via Modbus RTU), and when I formatted my code like this it also did not work, so it has me thinking that maybe it has something to do with the 25-pin-to-serial-to-usb connection, but I'm really not sure.
Here is my code:
%create object connected to COM10
s = serial('COM10');
set(s, 'InputBufferSize', 3000);
%open object
fopen(s);
set(s, 'BaudRate', 9600);
set(s, 'Terminator', 'CR');
set(s, 'Timeout', 100);
%format request
request3= uint8(hex2dec(['01'; '03'; '00'; '64'; '00'; '01'; 'C5'; 'D5']))%FROM WATLOW EXAMPLE ONLINE: http://www.testequity.com/documents/chambers/Modbus_Packet.pdf
%write request to modbus
fwrite(s, request3);
%read reply from modbus
outdec3 = fread(s)
However, when I run this code this is the response I get:
Warning: Unsuccessful read: The specified amount of data was not returned within the Timeout period.
Am I formatting my request incorrectly? Or setting up the serial object incorrectly? Any help that can be provided would be greatly appreciated.
I have used a load cell. Arduino is sending the load perfectly. When the load sensed by arduino crossess some value I want to send a simple signal to matlab. Then a MATLAB should capture the image. If someone has already worked on it please share how you have done it!.
You could use the MATLAB Support Package for Arduino or plain old serial communication. The former is pretty straightforward; see the documentation. Below is a simple example of how the latter would work.
Arduino:
void setup() {
Serial.begin(9600);
}
void loop() {
int load = getLoad();
if (Serial.available()) {
Serial.println(load);
}
}
MATLAB:
% Connect to Arduino
s = serial('COM1', 'Baudrate', 9600, 'Parity', 'none', 'Databits', 8, 'Stopbits', 1);
fopen(s);
set(s, 'Timeout', 2000, 'Flowcontrol', 'none');
s.ReadAsyncMode = 'continuous';
% Read data from Arduino
load = fscanf(s, '%d');
% Close connection when done
fclose(s);
Check out the following resources for more details:
"Arduino Serial Data Acquisition" by Ye Cheng on MATLAB Central File Exchange
"Arduino and Matlab: let them talk using serial communication!" by gianluca88 on Instructables
"How To Send Data From The Arduino To MATLAB" by Miguel on AllAboutEE
"How can I communicate from Arduino to MATLAB" by Bill Nace on Arduino Stack Exchange
"Getting Started with Serial I/O" in the MATLAB Documentation
"Write and Read Data" in the MATLAB Documentation
matlabarduino.org
I'm working on MATLAB, I want to connect only a LED & resistor to a serial port.
When a specific action happens in my program, the LED must turn on.
What I did but nothing had happened:
S = serial( 'com1' );
fid = fopen( s ); # ... 've checked the s vs. S ?
You should be able to control the DTR and RTS lines (on DB-9 connectors on pins 4 and 7, respectively) from MATLAB. According to the reference, serial port objects have the properties DataTerminalReady and RequestToSend, which can be toggled. For example,
S = serial('com1');
for ii = 1:5
set(S, 'RequestToSend', 'on');
pause(1)
set(S, 'RequestToSend', 'off');
pause(1)
end
will flash an LED connected to the RTS pin five times.