First I send data to Arduino from Matlab, then arduino proceed this data and send a message 'Ready' to Matlab to send him a new one. But this periodic communication is very slow.
This is my Matlab code :
for i =1:nbr
arduino_serial= serial('/dev/cu.wchusbserial1410');
set(arduino_serial,'BaudRate',9600);
set(arduino_serial,'Terminator','CR');
fopen(arduino_serial);
pause(1);
A_string = strcat(num2str(tabx(i)),',',num2str(taby(i)),',',num2str(pression_ref));
%Send
fprintf(arduino_serial,A_string);
%Receive from Arduino
while (strcmp('Ready',fscanf(arduino_serial,'%f'))==0)
end
fclose(arduino_serial);
delete (arduino_serial);
end
My setup in Arduino are :
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
Serial.setTimeout(100);
Is there another way to send periodic data?
Thanks
From your explanation, I think that your code is not apt. I have understood that Matlab waits for 'ready' from arduino, then it can send immediately the new message. Thus you dont have to close serial and reopen it each time; this part adds a delay of at least 1s!
You have to put opening and closing serial outside of your for loop.
For reliability you should increase sleep(1) to sleep(2).
Moreover there can be garbage in arduino serial buffer before you open it; if you encounter this, then you may read from arduino serial to empty the buffer (just after the sleep(2) instruction).
Related
I am reading data from the a device using read(t) from ethernet.
Device continuously sending data over ethernet on some particular node.
I am reading this data continuously using while loop, giving while loop to some impossible condition to stop.
When I run my script I am not able to send any other command to device because while loop running continuously.
The program is not coming out of the while loop.
Is any way to read continuously data from Ethernet using tcpclient command.
Meanwhile, I am reading data from the device, how to send some commands to the device over ethernet using write(t,stop) command. because the script running continuously.
t = tcpclient("172.24.96.81",10952);
write(t,data1);
c=1;
while c~=1 % just to run while loop continuously
data2=read(t);
% manipulation from data2
end
t = tcpclient("172.24.96.81",10952);
Bytes_DATAF=t.NumBytesAvailable
configureCallback(t,"byte",Bytes_DATAF,#(varargin)readf1())
where readf1()
function readf1()
read(t)
end
for more clarity visit this link and this link
I'm creating a MATLAB GUI using the app designer (very similar to, but better than, GUIDE) which I want to use to monitor the data output of my simulink model in real time.
In other words, I have a simulink model and a GUI, both running in the same MATLAB instance and I want to send packets over UDP from the simulink model and use that data in my GUI to update plots. However, I don't know how to read the data from the UDP packet without blocking.
Is there a way to bind a handler when a packet is received so that I can execute a function to update plots/fields?
Of course, beside BytesAvailableFcn matlab has the datagramreceivedfcn to call your custom function on new dagatrams, which is nonblocking while fread/fscanf are blocking (temporarily). Regarding callbacks in matlab read events and cbs
Compilable standalone could look like:
%% standalone main
%{
see docs/*
%}
function exitcode = main(port, remotePort)
% sanitize input
if(~exist('port','var') || ~exist('remotePort','var'))
disp(['args: port remotePort']);
exit(1);
end
if ischar(port)
port=str2num(port);
end
if ischar(remotePort)
remotePort=str2num(remotePort);
end
% create udp object
u = udp('127.0.0.1',remotePort, 'LocalPort', port);
% connect the UDP object to the host
fopen(u);
exitcode = 0;
% since we poll, suppress warning
warning('off','instrument:fscanf:unsuccessfulRead');
warning VERBOSE
% specify callback on datagram
while true
msgEnc= fscanf(u);
% timed out without datagram
if isempty(msgEnc)
continue
end
% do sth with msgEnc (which is a readable string)
fprintf(u, 'heard sth'); %answer
end
end
If you would like to use simulink block use udpreceive
which has a non-blokcking capability
A First In First Out (FIFO) buffer receives the data. At every time
step, the Data port outputs the requested values from the buffer. In a
nonblocking mode, the Status port indicates if the block has received
new data.
I'm trying to get a code to work that triggers an interrupt for a variable data size coming to a RX input of a STM32 board (not discovery) in DMA Circular mode. ex.:CONNECTED\r\nDATAREQUEST\r\n
So far so good, I'm being able to receive data and all, while also triggering the DMA interrupt.
I will then create a sub RX message processing buffer breaking down each \r\n to a different char array pointer.
msgProcessingBuffer[0] = "COM_OK"
msgProcessingBuffer[1] = "DATAREQUEST"
msgProcessingBuffer[n] = "BlahBlahBlah"
My problem comes actually from the trigger of the interrupt. I would like to trigger the interrupt from any amount of data and processing any data received.
If I use the interrupt request bellow:
HAL_UART_Receive_DMA(&huart1,uart1RxMsgBuffer, 30);
The input buffer will take 30 bytes to trigger the interrupt, but that's too much time to wait because I would like to process the RX data as soon as a \r\n is found in the string. So I cannot wait for the full buffer to fill to begin processing it.
If I use the interrupt request bellow:
HAL_UART_Receive_DMA(&huart1,uart1RxMsgBuffer, 1;
It will trigger as I want, but there is no point on using DMA in this case because it will trigger the interrupt for every byte and will create a buffer of just 1 byte (duh) just like in "polling mode".
So my question is, how do I trigger the DMA for the first byte received but still receive/process all data that might come after it in a single interrupt? I believe I might be missing some basic concept here.
Best regards,
Blukrr
In short: HAL/SPL libraries don't provide such feachures.
Generally some MCUs, for example STM32F091VCT6 have hardware supporting of Modbus and byte flow analysis (interrupt by recieve some control byte) - so if you will use such MCU in you project, you can configure receive by circular DMA with interrupts by receive '\r' or '\n' byte.
And I repeat: HAL or SPL don't support this features, you can use it only throught work with registers (see reference manuals).
I was taking a look at some other forums and I've found there a work around for this problem.
I'm using a DMA in circular mode and then I monitor the NDTR which updates its value every time a byte is received through the UART interface. Then I cyclically call a function (in while 1 loop or in a cyclic interrupt handler) that break down each message part always looking for /n /r chars. This function also saves the current NDTR value for comparison if it has changed since the last "while 1" cycle. If the NDTR has changed since last cycle I wait a couple milliseconds to receive the remaining message (UART it's too slow to transmit) and then save those received messages in a char buffer array for post processing.
If you create a circular DMA buffer of about 50 bytes (HAL_UART_Receive_DMA(&huart1,uart1RxMsgBuffer, 50)) I think it's enough to compensate any fluctuations in the program cycle.
In the mean time I opened a ticket to ST and they confirmed what you just said they also added:
SOLUTION PROPOSED BY SUPPORTER - 14/4/2016 16:45:22 :
Hi Gilberto,
The DMA interrupt requests available are listed on Table 50 of the Reference Manual, RM0090, http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf. Therefore, basically, the DMA interrupt can only trigger at the end of one of these events.
• Half-transfer reached
• Transfer complete
• Transfer error
• Fifo error (overrun, underrun or FIFO level error)
• Direct mode error
Getting a DMA interrupt to trigger upon reception of a specific character in your receive data stream is not possible. You may want to trigger the interrupt when you receive packets of say 30 bytes each and then process the datastring to check if your \r\n chars have arrived so you can process the data block.
Regards,
MCU Tech Support
I have two xbee's series 1. I have them as endpoint devices working in API mode and talking to each other. The first xbee is attached at a raspberry pi, while the other is on my pc where I see the terminal tab of XCTU program. The baud rate I use is 125000.
From raspberry pi I try to send a jpg image which is 30Kbytes. I send data frames 100 byte long (the biggest as it is said in the xbee documentation). Inside a loop I create and send the packets, I have also a cout statement that prints the loop number. Everything is fine and all bytes are sent. When I comment out the cout statement not all bytes are sent.
From what I have understood the cout statement works as a delay between packets, but I still cannot understand why is this happening as it is supposed that I use the half speed ...
I hope I was clear and look forward for a reply.
UPDATE
Just to summarize, i changed baud rate to 250000 where there is the same behavior as in 125000. I also implemented hardware flow control by checking cts signal. When xbees are in transparent mode I need a delay between sending characters at around 150us. The same goes for api mode too. The difference with 125000 baud rate in api mode was that the delay needed, was enough to be betwween each data packet, but in 250000 the delay is needed between each byte that i send. If i do the above everything goes well.
The next thing i did was to plug both xbees in my pc in transparent mode. I went to terminal tab of xctu software where i chose assemble packet and sent at around 3000 bytes to the other xbee. The result was the same. The second xbee received at about 1500 bytes and then each time that i was sending one byte from the first to the second, the "lost bytes" were being received at packets of 1000. :/
So could anyone know what am I doing wrong?
You should connect the /CTS pin from the XBee module into the Raspberry Pi, and have your routine stop sending data when the XBee de-asserts it.
At higher baud rates, it's possible to stream data into the XBee module faster than it can send to the remote module. The local XBee module uses the /CTS pin to notify the host when its buffers are almost full and the host should stop sending. People refer to this as hardware flow control.
It may be necessary to modify the serial driver on the Raspberry Pi to make use of that signal -- it should pause the transmit buffer when de-asserted, and automatically resume sending when re-asserted.
I was using the simulink blocks 'serial configuration' and 'serial receive' to receive data from a Xbee module plugged into a serial comport. The Xbee module is supposed to send a string of data at 10Hz to the comport. As i run the program, simulink immediately crashes and shut down. The error message is EXCEPTION_ACCESS_VIOLATION . How could i possibly solve this?