I am using Matlab to program an experiment.
In particular, I am using these lines of code to read and send triggers to an external device:
ioObj = io64;
status = io64(ioObj);
io64(ioObj,portWriteAddress,0);
I have found the value for 'portWriteAddress by navigating to:
Device manager -> Ports -> LPT1 -> Resources. Then, in Resources there is an entry called I/O Range/ Settings with a code like 02S7 - 02SS (something like that).
Then I have converted it from Hex to Dec and put it in the line above.
THE PROBLEM IS: I am running this experiment on several different computers. Is there a way to programmatically find this range (or address) information fromMatlab?
Thank you all for your time.
Gluce
P.S.
The OS that I am using is Windows 7 (it should be soon updated to windows 10).
The computers are running either Matlab 2015b or 2016b.
Related
I have the problems with both SAVIHost v1.43 and VSTHost v1.57 for the case of Dexed 0.9.6. As I am a hobbist only, related to both MIDI and IT, I wish to ask some help to overcome these problems detailed below.
My problem with SAVIHost V1.43:
I copied savihost.exe (extracted from savihost3x64.zip) copied into directory "C:\Program Files\Common Files\VST3" (i.e. into the installation directory of Dexed.vst3) then renamed it to Dexed.exe, and launched this Dexed.exe.
I set "loopMIDI Port 1" (created prior by "loopMIDI v1.0.16 (27)") as "Input Port 1" via "Devices|MIDI..." and "1764 samples (25 b/s)" via "Devices|Wave...". (The sample rate was 44100 Hz, and both ports were "MME: Microsoft Sound Mapper).
Then I played some sounds by use of the virtual keyboard, and changed Dexed's programs (instruments) randomly - and Dexed seemed to work well, it played the different sounds with the actually selected instruments. Then I sent some MIDI Messages by Cakewalk by Bandlab to "loopMIDI 1"; Dexed produced the appropriate sounds, according to MIDI Note On/Off messages received - except that all the MIDI Program Change messages (C0 xx) were ignored.
Finally, when I clicked onto icon of Dexed.exe (i.e. renamed savihost.exe) in the Windows 10 Taskbar on the screen: the main window of Dexed.exe was minimized,
but when I clicked onto its icon again, although its main window is restored but crashed immediately. A dialog titled as "Dexed" appered,
containing an error message:
Unhandled exception 0xC0000005 at 00000014005BEBA
reading from FFFFFFFFFFFFFFFF
(followed by a list of the recent content of registers).
Furthermore, I noticed that resizing of window of Dexed.exe (moving its bottom edge upward) also causes a crash, but only after when Dexed.exe received some MIDI messages through "loopMIDI Port 1".
(i.e. playing on virtual keyboard, followed by similar resizing did not cause crashes - at least, I have not realized that.)
The situation was ditto for the case of SAVIHost V1.44 beta.
Problem with VSTHost V1.56 x64:
In the second case, I started VTSHost.exe, then loaded Dexed.vst3 via File|New Plugin... . Dexed.vst3 also seemed to work well at the beginning, i.e. while I played on the virtual keyboard bar, and changed the programs (instruments) and modified some parameters by the knobs on the screen. But when VSTHost received the first MIDI messages through the "loopMIDI Port 1", Dexed does not played any notes anymore. Instead, some extra message lines appeared in the dialog "Info" below the line "Chained as Insert before 1: Engine Output":
...
Processing is turned off (errors in PlugIn?)
ProcessReplacing
Exception 0xC0000005 at 000000014007ABF6 reading from 0000000000000000
...
Stack Trace:
...
Unfortunately, the situation was the same in case of VSTHost V1.57 beta x64.
Comments:
Dexed.vst3 worked without problems in case of other VST host apps (e.g. CakeWalk by BandLab and Cantabile 4 Lite), i.e. also the MIDI Program Change messages were executed properly.
(CakeWalk by Bandlab used Dexed.vst3 directly, Cantabile 4 Light received MIDI messages from CakeWalk by BandLab through "loopMIDI Port 1".)
similarly, the original standalone Dexed application also processed the MIDI Program Change messages through "loopMIDI Port 1" correctly.
version number of Dexed.vst3 reported as 1.0.0 by VSTHost (although is is originated from unzipping of "dexed-0.9.6-win.zip").
my PC has the followings:
-- OS: MS Windows 10, 22H2, build: 19045.2311 (x64)
-- CPU: Intel(R) Core(TM) i5-4460 CPU # 3.20GHz
-- RAM: 8 GB
-- motherboard: Gigabyte Technology Co., Ltd. B85M-D2V
-- sound: Realtek, High Definition Audio (on-board)
Finally, I wish to mention that I have tried other VSTs than Dexed's one with both SAVIHost and VSTHost: "sforzando.vst3" and "Roland Sound Canvas VA.dll".
There were no problem at all - no interception of any MIDI Message, no crash, etc -, they had been worked without any problem for hours. So I am not really sure, what and where are the root of the problems above: maybe in SAVIHost or VSTHost - or maybe in Dexed.
I wish ask some help, how I shall continue to determine, which component - ie. savihost/svthost or Dexed - is failed and resulted the problem?
Thank you very much for you kind efforts in advance!
I'm considering using Matlab Compiler to distribute software for a price. I'm investigating (very) simple methods to discourage re-distribution without annoying users. Any recommendations?
One thought is to email a user a license key and have them input this during the installation process to be verified on a license server. If the key matches what is on the server, the installation proceeds as usual, otherwise, a warning message is shown to inform the user to purchase another license. However, this method requires a specified function to run only during the installation process, and not thereafter (so as not to annoy the user). Is this possible using Matlab Compiler or otherwise?
I suppose I could create a file on the user's disk that the program looks for when it starts (if it exists, then it is not being run for the first time), but if the user copies the whole directory, that file would get copied too.
In order to create an effective licensing system, you have to link it to one or more properties of a user machine (MAC address, OS ID, hard disk serial numbers, CPU serial numbers, etc...).
If you don't to this, you are just going to release licenses that can be transferred from one user to another. If one user decides to spread his license file worldwide, you are doomed because everyone could potentially take that license file and use it to unlock your application.
But if you link your license files to one or more properties of a user machine, as mentioned above, you must be able to obtain these properties either:
before the user decides to buy your application;
when the user activates his license.
First Scenario
You release your software as a trial. When it is started for the first time, you set an expiration date in the registry or in a file well hidden somewhere. You check against the expiration date when the application starts and, once it is reached, you throw an error and you don't let the used play with your application anymore.
Within the application, you create a Register Now button somewhere. When it is clicked, the application retrieves the machine properties and passes them to the web page / form that will be opened to let the user perform the payment. That page will be in charge to validate the machine properties, receive the payment and, finally, deliver a valid license code based on these properties.
Within the application, you must implement the same logics that allowed your form to create the license code, because you will need to use them in order to validate the code itself every time your application starts. A pseudo-code example:
mp1 = GetMachineProperty1();
mp2 = GetMachineProperty2();
mp3 = GetMachineProperty3();
lc = GetLicenseCode();
if (~strcmp(sha1([mp1 mp2 mp3]),lc))
errordlg('Invalid license code!');
return;
end
This is the simplest path. But keep in mind that if one or more properties of the user machine change (because he changes a device or reinstalls his OS), his license will be invalidated and you will have to provide a customer assistance service that takes care of this kind of situations.
Second Scenario
This one is much harder. You will not be able to know the user's machine properties in advance. So your licensing system will work on a two-steps basis. You release a unique code (called LID for example) when the used purchases your application. Then, once the user inserts that it in your application, your application must send it back together with the machine properties. The final key (called LKey for example) is then computed and sent back to the user.
mp1 = GetMachineProperty1();
mp2 = GetMachineProperty2();
mp3 = GetMachineProperty3();
lkey = GetLicenseKey();
if (~strcmp(sha1([mp1 mp2 mp3]),lkey))
errordlg('Invalid license code!');
return;
end
Machine Properties
The first solution has been provided to you through a comment: the MachineGuid value located in the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography. It's pretty solid. But it will only work on Windows machines. Use winqueryreg to access the registry.
Another good alternative is the Window Domain Controller Security ID, which is another machine-specific unique identifier. You can retrieve it using Java code within Matlab:
wdc_sid = com.sun.security.auth.module.NTSystem.getDomainSID();
or through the Windows registry key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\GroupMembership. The registry approach should be the one to use if you want to maintain a certain backward compatibility with old Matlab releases. Unfortunately, the Window Domain Controller Security ID is another identifier that is available only on machines that run under Windows.
If you want to adapt your licensing system to every possible OS and environment, you have to use a more generic approach, based on universally accessible hardware properties: MAC adresses, hard disk serials and such things. As far as I know, the most reliable property is the MAC address, because its uniqueness, althrough not granted, is almost certain and it's very unfrequent to change a network adapter (there are more chances to break an hard disk actually). Retrieve the MAC adresses of the machine network adapters using Java code as follows:
mac_addrs = '';
net_int = java.net.NetworkInterface.getNetworkInterfaces();
while (net_int.hasMoreElements)
mac_addr = net_int.nextElement.getHardwareAddress();
if (~isempty(mac_addr))
mac_addrs = [mac_addrs, '-', sprintf('%.2X',typecast(mac_addr,'uint8'))];
end
end
mac_addrs = mac_addrs(2:end);
The above computation produces a character array that represents the result of the concatenation of all the MAC addresses found on the machine. Again, for compatibility reasons, this may not work on old Matlab releases, so you have to use a much more complex approach, described here.
[EDIT]
This approach to retrieve the MAC address based on the underlying OS could be easier:
switch computer('arch')
case {'maci','maci64'}
[~,a]=system('ifconfig');
c=strfind(a,'en0');if ~isempty(c),a=a(c:end);end
c=strfind(a,'en1');if ~isempty(c),a=a(1:c-1);end
% find the mac address
b=strfind(a,'ether');
mac_add=a(1,b(1)+6:b(1)+22);
case {'win32','win64'}
[~,a]=system('getmac');b=strfind(a,'=');
mac_add=a(b(end)+1:b(end)+19);
case {'glnx86','glnxa64'}
[~,a]=system('ifconfig');b=strfind(a,'Ether');
mac_add=a(1,b(1)+17:b(1)+33);
otherwise,mac_add=[];
end
I found it in the comments of this article.
I have Wago 750-880 with different sensors. Someone wrote already a program to control it in Codesys. I would like to return (I have a Java background :D) - to write some variables to output in the driver, e.g. holding registers. I would like to to read later those variables (parameters) on a SSI page like that
<!--#READPI ADR=QX4.5&FORMAT=%X-->
I don't have any PLC experience :(
How can I write to the Holding Register?
Thanks a lot in advance
My interpretation of the question is that you'd like the information to be reflected on a web interface or screen?
If so, in Wago's environment there is a VISU facility that you can enable to display whatever you'd like, and access it via a web browser over the internet.
This may help: Supplement to the User Manual for PLC Programming with CoDeSys 2.3
create variables for your I/O and using the Modbus library to access your %MW??? variables.
First %MW0 is at address 12288 and so on
ex: Input1 AT %MW10 ; //12288 + 10 = 12298
//MAP TO ACTUAL IP1 unit channel 1
Input1.0 = IP1.0
I have a Verilog code simulated and synthesized on ISE design toolkit. I've got an FPGA spartan 6 device which is to be used for the implementation. But there is a problem with the device (probably a power issue) which makes the device unavailable in any of the COM ports when I connected it to my PC. So I want to check whether my Matlab code which I made for serial communication through the device does the desired job. So I need a method to test serial communication via any of the COM ports without connecting a serial com device to the PC. Is there any such method that I can Tx Rx serial data from Matlab to COM ports? Any software or any other method would be highly appreciated :)
I found a way to test Matlab serial communication using virtual serial ports.
Download "Freeware Virtual COM Ports Emulator" from: http://freevirtualserialports.com/
I installed it in Windows 10, and it's working (as trial).
Add a pair of two serial ports:
Execute the following Matlab code sample to verify it's working:
s3 = serial('COM3','BaudRate',115200);
s4 = serial('COM4','BaudRate',115200);
fopen(s3);
fopen(s4);
fwrite(s3, uint8([1, 2, 3, 4, 5]));
%fprintf(s3, '12345');
pause(0.1);
RxBuf = fread(s4, 5)
fclose(s3);
delete(s3);
clear s3
fclose(s4);
delete(s4);
clear s4
The output is:
RxBuf =
1
2
3
4
5
Bypassing the problem "it only stays for a single test session".
There is a problem when creating a pair of virtual ports using the software, it only stays for a single test session.
I guess it's a problem with the COM port emulation software.
The following solution, is not a good practice (and not a true solution).
Declare the serial object as global, keeping the object persistent.
Create the serial object only if it's not created.
Don't delete and don't clear the serial object.
See the following code sample:
global s3 s4
if isempty(s3)
s3 = serial('COM3','BaudRate',115200);
end
if isempty(s4)
s4 = serial('COM4','BaudRate',115200);
end
fopen(s3);
fopen(s4);
fwrite(s3, uint8([1, 2, 3, 4, 5]));
pause(0.1);
RxBuf = fread(s4, 5)
fclose(s3);
%delete(s3);
%clear s3
fclose(s4);
%delete(s4);
%clear s4
You can also look for a better virtual COM port software.
As Rotem suggested, if you need to communicate via serial line between 2 program of your PC you need a virtual COM port emulator.
It seems you are running on Windows OS so I would recommend a completely free emulator (not a trial one). For Windows I use com0com Null-modem emulator (from SourceForge).
In the example below I will show how to communicate with "another" device so Matlab will not handle both side of the communication. The other device will be simulated by a simple terminal. For windows I use RealTerm: Serial/TCP Terminal (also from SourceForge).
Setup:
Execute the setup of both program with all default options. by default com0com will create a virtual pair COM3/COM4 but if these port already exist on your system the program may assign other numbers. Check the numbers before you run the example. (it will also create a CNCA0/CNCB0 pair but you can ignore this one for now).
For RealTerm, once installed (don't forget to activate the server registration at the end of the setup, it should be ticked by default though), it will look like below. Keep all default options, just set the port number and the baud rate if they need to be changed.
Test MATLAB -> Terminal
You are ready to send Ascii characters or binary values from MATLAB to your device. The animation below shows you an example of both option:
you can click on the picture to see it full size. It is running in loop so you may want to wait until it restart from the beginning.
Test Terminal -> MATLAB
Below animation shows you how to test the communication in the other way:
Don't forget to tick [CR] [LF] on RealTerm when you send Ascii characters and want to use the '%s' format specifier on MATLAB, as it needs these characters to detect the end of the string.
Note:
If you have another terminal program that you are more used too, it
will work the same.
If the RealTerm option does not suit you, or if you want to handle
both sides of communication from Matlab, then you can use the code
provided by Rotem in his first answer. Just install com0com but
ignore all the RealTerm part.
While connecting my Com-port using matlab, many a times(4 out of 5) I get an error
??? Error using ==> serial.fopen at 72
Port: COM21 is not available. Available ports: COM3,
COM10, COM17, COM18.
However , sometimes it gets connected and responds as expected.
Can anyone tell me whats the problem with this?
By the way , I am using this snippet to connect my microcontroller to PC through USB
s = serial('COM21'); // code to initialize the req COM i.e. COM21 for me
fopen(s);
I ran into this issue before. It turns out MATLAB doesn't really handle plug-and-play very well, as evidenced by this thread:
http://www.mathworks.com/matlabcentral/newsreader/view_thread/311133
Long story short: if you want MATLAB to detect a hardware change, you need to restart it. MATLAB seems to only look for devices when it starts up.