Simulink and arduino serial communication - simulink

I am running a code on arduino which works fine in arduinoide, I want to get those values in simulink for real time using serial connection.
I am burnig a program in arduino and want to access both send and receive function of serial monitor, on simulink. I want these to plot graphs in real time and run PID algorithm using simulink.
But for some odd reason, simulink values are either not updating(in external mode) or fluctuating some odd values(in normal mode). Any help.

If you are doing a communication between the Arduino and Simulink there might be some problems in your connection. I'm assuming you are using the Serial Send and Serial Receive block to do the communication.
I did a complete tutorial how to connect both platforms in my Github page.
By your description I can think of this problems:
Simulink is not updating?
If your Simulink is not updating probably because it is waiting Arduino to send some serial data, but is not receiving anything. Some possible causes of this problem might be:
Wrong Serial baud rate
Wrong data type (i.e. If you are sending Arduino float you have to receive a single in Simulink.)
Wrong data size
Different step time (Remember to use the same step time in Simulink and Arduino)
Simulink receiving odd values?
If Simulink is updating but showing odd values, the communication between both might be damaged.
Desynchronization of the communication - Try to use a Header and a Terminator in the Serial Send and Serial Receive block and remember to set this in your Arduino code.
Different step time - Make sure both application are sending and receiving at same rate.
Verify what you are sending - You can check what exactly you are sending to the serial with a scope, remember that in the Serial Send block the input signal must be a byte. If you are using a single or double remember to cast it to byte with a Byte Pack block.

Related

STM32F04xx UART transmit unreadable chars when HAL_Delay is set higher than 90 milliseconds

I'm working on transceiving data on stm32F04xx. When I transmit data from the MCU at lower speed, it looks like if the baudrate was wrong and I get a bunch of question marks. When I increate transmission speed. I can read the data I'm sending. I've used to stm32cubeIDE to generate a simple UART code and only added
HAL_UART_Transmit(&huart2, "test\r\n", sizeof("test\r\n"), 1000);
HAL_Delay(500);
in the while loop.
On my NUCLEO-F042K6 evaluation board, I don't see any issues printing data on the tty port. But I have another device which uses the same stm32f042xx chip that only works when transmitting UART data at higher speed. so when i change my delay to something like 80 milliseconds, I can read the data flow.
I've attempted to flash the same binary that I flashed on my evaluation board on the other MCU I have but again the data only readable at higher transmission speed.
I'm flashing the MCU with stm32flash tool so I don't know if that can make a difference where on the eval board, I'm using the stm32cubeIDE to flash it.
I'm not sure what's going on here, I've tried different baudrates and different clock configurations and that doesn't seem to help too.
What could possibly cause the data to be unreadable like if the baudrate was wrong when transmitting at low speed?

How to synchronize readout of binary streams on serial port of Matlab

I'm having an issue which is partially Matlab- and partially general programming-related, I'm hoping that somebody can help me brainstorm for solutions.
I have an external microcontroller that generates a large stream of binary data (~40kb) every 400ms and sends it via UART to a PC running Matlab scripts. The data is not encoded in hexa or dec characters, but true binary (hence, there's no terminator defined as all 256 values are possible, valid combinations of data). Baudrate is set at 1024000. In short, it takes roughly 375ms for a whole stream of data to be sent, with 25ms of dead time in between streams
In Matlab, the serial port is configured correctly (also 1024000, 8x bits, 1x stop bit, no parity, no hardware flow control, etc.). I am able to readout the data I'm sending via the microcontroller correctly (i.e. there's no corruption of data), but I'm not being able to synchronize the serial readout on Matlab. My script is as follows:
function data_show = GetDATA
if ~isempty(instrfind)
fclose(instrfind);
end
DATA_TOTAL_SIZE = 38400;
DATA_buffer = uint8(zeros(DATA_TOTAL_SIZE,1));
DATA_show = reshape(DATA_buffer(1:2:end)',[160,120])';
f_data_in = false;
f_data_out = true;
serialport = serial('COM11','BaudRate',1024000,'DataBits',8,'FlowControl','none','Parity','none','StopBits',1,...
'BytesAvailableFcnCount',DATA_TOTAL_SIZE,'BytesAvailableFcnMode','byte','InputBufferSize',DATA_TOTAL_SIZE * 2,...
'BytesAvailableFcn',#GetPortData);
fopen(serialport);
while (get(serialport,'BytesAvailable') ~= 0) % Skip first packet which might be incomplete
fread(serialport,DATA_TOTAL_SIZE,'uint8');
end
f_data_out = true;
while (1)
if (f_data_in)
DATA_buffer = fread(serialport,DATA_TOTAL_SIZE,'uint8');
DATA_show = reshape(DATA_buffer(1:2:end)',[160,120])'; %Reshape array as matrix
DATAsc(DATA_show);
disp('DATA');
end
pause(0.01);
end
fclose(serialport);
delete(serialport);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function GetPortData (obj,~)
if f_data_out
f_data_in = true;
end
end
end
The problem I see is that what I end up reading is always the correct size, but belongs to multiple streams, because I haven't found a way to tell Matlab that these 25ms of no data should be used to synchronize (i.e. data from before and after that blank period should belong to different streams).
Does anyone have any suggestions for this?
Thanks a lot!
For completeness, I would like to post the current implementation I have fixing this issue, which is probably not a suitable solution in all cases but might be useful in some.
The approach I took consists in moving into a bi-directional communication protocol, in which Matlab initiates the streaming by sending a very short command as a trigger (e.g. single, non-printable character). Given the high baudrate it does not add significant delay due to processing in the microcontroller's side.
The microcontroller, upon reception of this trigger, proceeds to transmit only one full package (as opposed to continuously streaming package at a 5Hz rate). By forcing Matlab to pickup a serial package of the known length right after issuing the trigger, it ensures that only one package and without synchronization issues is received.
Then it becomes just a matter of encapsulating the Matlab script in a routine with a 5Hz tick given by a timer, in which the sequence is repeated (send trigger, retrieve package, do whatever processing, and repeat).
Advantages of this:
It solves the synchronization problems
Disadvantages of this:
Having Matlab running on a timer tick does not ensure perfect periodicity, and hence the triggers might not always be sent at exactly 5Hz. If triggers are sent at "inconvenient" times for the microcontroller, packages might need to be skipped in order to avoid that a package is updated in memory while it is still being transmitted (since transmission takes a significant part of the 200ms time slot)
From experience, performance can vary a lot depending on what the PC running Matlab is doing. For example, it works fine when the PC is left on its own to do the acquisition, but if another program is used (e.g. Chrome), Matlab begins to lag and that results in delays in transmission of triggers.
As mentioned above, it's not a complete answer, but it is an approach that might be sufficient in some situations. If someone has a more efficient option, please fell free to share!

PC receives wrong data using high baudrate of usart

i wanted to use 4Mb baud rate of stm32f103 usart. how can i check that data received in PC are correct? I used hyper terminal but in its setting there is no 4Mb baud rate and when i run my code i receive wrong characters.but in low baud rates like 115200b data received correctly.
If the transmitter and receiver are not sending at the same speed, the receiver will erroneously read the data. Each byte has a start bit that synchronizes the receiver, and the remaining bits are determined by time.
Typical PC RS-232 serial ports only go up to 115200 bps. It is likely that your PC can't handle the 4 Mbps rate. I would recommend using 115200 or lower speed.
If you are communicating between devices and need higher speed, and just using the PC to debug, you could change the speed for debug purposes and set it faster once your comms are working. Alternatively, you could use a logic analyzer - This could be tedious to do manually, but some may have functions to read serial data.
If you have two of the stm32f19 modules, connect them using the USART at 4Mb, at then send a block of data with a checksum (or even a hardcoded block that you can compare). On the receiving unit, either confirm the checksum, or compare the data to see if the link works.

Using MATLAB to send multiple serial signals through the same port

I'd like to send multiple signals (4 inputs and outputs and 7 outputs) from my Laptop to a microcontroller. I'm thinking of using a USB to serial converter and multiplexing the data through the port. I'll need to write codes both in the laptop end and in the microcontroller to multiplex the data.
Eg:
Tx of microcontroller:
1.Temperature sensor ADC output->Laptop
2.Voltage sensor to laptop
3.Current Sensor to Laptop
4.Photodiode current to Laptop
So I need to write a program in the microcontroller to send the data in this order. How can I accomplish this? I was thinking of an infinite loop which sends the data with time delays in between.
At the Rx pin of Microcontroller,
Seven bit sequences. Each bit sequence will be used to set the duty cycle of a PWM generated by the microcontroller.
I also need the same multiplexing or demultiplexing arrangement in the matlab end. Here too, I'm thinking of allotting some virtual 'channels' at different instants of time. What kind of algorithm would I need?
In case you always send all the inputs/outputs at the same rate, you could simply pack them into 'packets', which always start with one or more bytes with a fixed value that form a 'packet header'. The only risk is that one of the bytes of the sensor data might have the same value as the start-byte at the moment you try to start receiving bytes and you are not yet synchronized. You can reduce this risk by making the header longer, or by choosing a start-byte that is illegal output for the sensors (typically OxFF or so).
The sending loop on the microcontroller is really easy (pseudocode):
while True:
measure_sensors()
serial.send(START_BYTE)
serial.send(temperature)
serial.send(voltage)
serial.send(current)
serial.send(photodiode)
end while
The receiving loop is a bit more tricky, since it needs to synchronize first:
while True:
data = serial.receive()
if data != START_BYTE:
print 'not synced'
continue #restart at top of while
end if
temperature = serial.receive()
voltage = serial.receive()
current = serial.receive()
photodiode = serial.receive()
do_stuff_with_measurements()
end while
This same scheme can be used for communication in both directions.

Unable Send Data From Matlab To DSPIC 30f4011

I am facing some problems while trying to send data from Matlab To DSPIC30f4011 through USB to UART Converter. Here is my code:
function comparison()
global x1 y1
s=serial('COM3');
set(s,'BaudRate',9600);
fopen(s);
fprintf(s,'2');
out=fscanf(s);
fclose(s);
But my circuit board is unable to receive the data. How can I solve this problem?
Receive:
I always had problems receiving data from a serial port, so I used a mex file GetSerialData.cpp, but right now I can't figure were came from.
Send:
To send data correctly it is really important that you got the right baud rate and COM-port. You could check the com-port in your windows device manager. Mine shows up in the (COM & LPT) group as USB Serial Port (COM7).
The baud rate depends on your DSPIC30F4011 device, which you probably also have to configure.