How to continuously read from the serial port in Matlab? - multithreading

This is my code:
serialPort = 'COM3';
s = serial(serialPort,'BaudRate',9600);
if (s.Status == 'closed')
s.BytesAvailableFcnMode = 'byte';
s.BytesAvailableFcnCount = 200;
s.BytesAvailableFcn = #Serial_OnDataReceived;
fopen(s);
end
This is the CallBack function
function Serial_OnDataReceived(obj,event)
global s;
global i;
global endCheck;
global yVals;
global xVals;
if (s.Status == 'open')
while s.BytesAvailable > 0 && endCheck ~= '1',
data = str2num(fgetl(s));
dlmwrite ('SensorsReading.csv', data, '-append');
yVals = circshift(yVals,-1);
yVals(end) = data(3);
xVals = circshift(xVals,-1);
i = i + 0.0125;
xVals(end) = i;
end
figure(1);
plot(xVals,yVals);
end
end
Right after the FOPEN function, I get this Warning:
The BytesAvailableFcn is being disabled. To enable the callback property
either connect to the hardware with FOPEN or set the BytesAvailableFcn property.
Does the logic that happens in the callback function Serial_OnDataReceived run on a different thread?
Is there a way to pass parameters to the function? I want to modify an array in the main script from the callback function, which is in a different file. What's the best way to do so?
I am also trying to plot the values when they're updated to show some kind of dynamic animation.

I am not sure about what is generating the warning, but to answer your other question (how to pass parameter to the callback and how to update the plot), a better way to go would be to prepare your plot outside of the callback, then pass the handle to the callback for update only.
nPointsInFigure = 10 ; %// number of "sliding points" in your figure
step = 0.0125 ; %// X points spacing
xVals = linspace(-(nPointsInFigure-1)*step,0,nPointsInFigure) ; %// prepare empty data for the plot
yVals = NaN(nPointsInFigure,1) ;
figure(1) ;
hp = plot( xVals , yVals ) ; %// Generate the plot (with empty data) it will be passed to the callback.
serialPort = 'COM3';
s = serial(serialPort,'BaudRate',9600);
if (s.Status == 'closed')
s.BytesAvailableFcnMode = 'byte';
s.BytesAvailableFcnCount = 200;
s.BytesAvailableFcn = {#Serial_OnDataReceived,hp,step} ; %// note how the parameters are passed to the callback
fopen(s);
end
Your callback will become:
function Serial_OnDataReceived(obj,event,hp,step)
global endCheck; %// I don't know how you use that so I could not get rid of it.
xVals = get(hp,'XData') ; %// retrieve the X values from the plot
yVals = get(hp,'YData') ; %// retrieve the Y values from the plot
while obj.BytesAvailable > 0 && endCheck ~= '1',
data = str2num(fgetl(s));
dlmwrite ('SensorsReading.csv', data, '-append');
yVals = circshift(yVals,-1);
yVals(end) = data(3);
xVals = circshift(xVals,-1);
xVals(end) = xVals(end-1) + step ;
end
set( hp , 'XData',xVals , 'YData',yVals ) ; %// update the plot with the new values
Also note: (1) You don't need to check for the state open/close of the serial port within the callback function. If the event was triggered it means the port was open. (2) you don't need to declare s as global, the obj parameter is actually the serial object itself.

If the suggestion from Hoki does not work, try using a timer.
% The following line is useful for debugging
mytimerCallback = #(~, ~) disp('Caught error For Tenzo Timer');
if isempty(timerXbee)
timerXbee = timer('ExecutionMode','FixedRate','Period',0.1,...
'TimerFcn',{#storeDataFromSerial},'ErrorFcn', mytimerCallback);
try
start(timerXbee);
catch
disp('Timer Xbee');
disp '******** InstrumentSubscription ERROR *********'
disp (exception.message);
disp '***********************************************'
end
end
% If you are using a polling approach, request data
sendRequest(cmd);
connectionRequested = true;
Then implement the timer function that will be called every period
function storeDataFromSerial(~,~,~)
while (get(xbee, 'BytesAvailable')~=0)
serialProtocol();
end
end
When you want to disconnect the device and close the communication don't forget to stop the timer with
stop(timerXbee)

Related

(Godot Engine) Replicating Line2D's joint functionality on the first + last points

I have created the following method to outline an 2D polygon using an Line2D node (in favor of _drawing because of texturing and round jointing capabilities of the Line2D node):
func Set_Polygon_Outline(_polygon_node: Node2D, _width: int = 5, _color: Color = Color.black, _texture: Texture = null) -> void:
if _polygon_node is Polygon2D:
var _polygon: PoolVector2Array = (_polygon_node as Polygon2D).polygon
if _polygon.size() >= 3:
# Line2D node setup
var _line_node: Line2D = null
var _line_name: String = str(_polygon_node.name, "_Line")
if not _polygon_node.has_node(_line_name):
_line_node = Line2D.new() ; _line_node.name = _line_name ; _polygon_node.add_child(_line_node)
else: _line_node = _polygon_node.get_node(_line_name) as Line2D
# Line2D properties setup
if _line_node != null:
_line_node.width = _width ; _line_node.default_color = _color ; _line_node.joint_mode = Line2D.LINE_JOINT_ROUND
if _texture != null:
_line_node.texture = _texture ; _line_node.texture_mode = Line2D.LINE_TEXTURE_STRETCH
var _points: PoolVector2Array = _polygon ; _points.append(_polygon[0]) ; _line_node.points = _points
How would it be possible to replicate the round point jointing on point 0 in the same way as the other points?
The result meets expectations except on the closing points (from 4 to 0)
One approach I have tried is appending an additional point (point 1) to the _points Array. While the un-textured one looks as desired, the textured variant is slightly off on the additional line because of the two superimposing textures with alpha values making it look "bolder".
Another (very unorthodox approach) is creating two polygons: one black and one with an blur shader, using the following method:
func Set_Polygon_Shadow(_polygon_node: Node2D, _size: float = 10.0, _color: Color = Color.black) -> void:
if _polygon_node is Polygon2D:
var _polygon: PoolVector2Array = (_polygon_node as Polygon2D).polygon
if _polygon.size() >= 3:
# Shadow Polygon node setup
var _shadow_name: String = str(_polygon_node.name, "_Shadow")
if not _polygon_node.has_node(_shadow_name):
var _shadow_node: Polygon2D = Polygon2D.new()
_shadow_node.polygon = Geometry.offset_polygon_2d(_polygon, _size).front() ; _shadow_node.color = _color
_shadow_node.show_behind_parent = true ; _polygon_node.add_child(_shadow_node)
# Blur Polygon node setup
var _blur_node: Polygon2D = Polygon2D.new()
_blur_node.polygon = Geometry.offset_polygon_2d(_polygon, _size * 2.0).front()
_blur_node.material = ShaderMaterial.new()
_blur_node.material.shader = preload("res://shaders/Shader_Blur.shader")
_blur_node.material.set_shader_param("Strength", 2.0)
_blur_node.show_behind_parent = true ; _polygon_node.add_child(_blur_node)
The shader code:
shader_type canvas_item;
uniform float Strength : hint_range(0.0, 5.0);
void fragment() {COLOR = textureLod(SCREEN_TEXTURE, SCREEN_UV, Strength);}
The result looks good but I can't possibly imagine using this approach on a large number of polygons.
Thank you kindly,
Mike.
If using a Line2D is a viable solution, except for fixing the loop, then let us fix the loop.
For a Line2D to loop seamless, even with transparency, it must close in a straight segment (not a corner). And have no end caps.
Thus, I suggest to move the first point, half way between its original position and the second point. Then you add at the end the original position of the first point, following by a copy of its moved position...
Like this:
# Let o be a copy of the original first point
var o = _points[0]
# Let m be the middle of the straight segment between the first and second points
var m = o + (_points[1] - o) * 0.5
_points[0] = m # The line now starts in m, we are moving the first point forth
_points.append(o) # Since we moved the first point forth, add its original position back
_points.append(m) # Add m at the end, so it loops, in the middle of a straight segment
That should result in a Line2D that loops seamlessly.

Making and using an object-style Module in Lua

I've been trying to take a module in Lua and use it to imitate an object. i.e. I made a deck of cards:
local Card = require("Card")
local function firstCard()
Card.newDeck()
Card.drawCard()
return Card.getCard()
end
local function secondCard()
Card.newDeck()
Card.drawCard()
return Card.getCard()
end
first = firstCard()
second = secondCard()
print(first)
print(second)
I set first = firstCard() and second = secondCard() but when I print the two variables second occasionally results as nil. I'm honestly lost. Here's the actual module itself.
local Card = {}
local deck
local value
local number, suit
local index = 0
local getCard
local getValue
function Card.newDeck()
deck = {}
value = {}
for x = 1, 13 do
if x == 1 then
number = "Ace"
elseif x == 11 then
number = "Jack"
elseif x == 12 then
number = "Queen"
elseif x == 13 then
number = "King"
else
number = x
end
for x1 = 1, 4 do
if x1 == 1 then
suit = "Clubs"
elseif x1 == 2 then
suit = "Diamonds"
elseif x1 == 3 then
suit = "Hearts"
else
suit = "Spades"
end
index = index + 1
deck[index] = number.." of "..suit
value[index] = x
end
end
end
function Card.drawCard()
index = math.random(52)
getCard = deck[index]
getValue = value[index]
end
function Card.getCard()
return getCard
end
function Card.getValue()
return getValue
end
function Card.getIndex()
return index
end
return Card
I have limited knowledge of Lua when it comes to Object-Oriented programming and to be honest, I typically only use it for calculations or small games to keep me occupied I'm class- I'm only 16. I'm more used to Java, even though I started using Lua well before I picked up Java. I just want to know if and how I can make this work. For the most part it works, just those occasional nil values.
The problem is that you have declared the index variable local at the top level of your module. That means that the random value of index that you have calculated in your first drawCard() is reused in your second call to newDeck(). You can add print(index) at the start of newDeck() to see what I mean.
There are several ways to solve the problem. One would be to add index = 0 at the top of newDeck(). A better one would be to declare your variables with smaller scoping, i.e. make index local to each function that uses it.
Try to use this instead, seems to work fine, it should print "ERROR NO VALUE" if there is some issue with the index, if that occurs (it shouldn't though), just print the index (in the generateCard() function).
This is the test
local Card = require("Card");
local function firstCard()
Card.newDeck()
return Card.generateCard(); -- two parameters, deck and value
end
local function secondCard()
Card.newDeck()
return Card.generateCard();
end
first = firstCard()
second = secondCard()
print(first)
print(second)
This is the module
local Card = {deck={};value={};};
function Card.newDeck()
local self = Card
local deck = self.deck;
local value = self.value;
local cards = {[1]="Ace",[11]="Jack",[12]="Queen",[13]="King"};
local types = {[1]="Clubs",[2]="Diamonds",[3]="Hearts",[4]="Spades"};
for x = 1, 13 do
for i = 1, 4 do
local _card,_type=(cards[x] or x),types[i];
deck[#deck+1] = _card.." of ".._type
value[#deck+1] = x
end
end
end
function Card.generateCard()
local self = Card;
if(not math.round) then
math.round = function(value) local mi,ma=math.floor(value),math.ceil(value)return(mi+0.5>value and mi or ma)end;
end
local index = math.round(math.random(1000, 52000)/1000);
return (self.deck[index] or "NO VALUE FOR CARD"),(self.value[index] or "NO DECK FOR CARD");
end
return Card

when a spawn object moves across the screen, I want it to despawn once it gets to a certain x value?

I have random spawned objects that automatically moves across the screen. I want it so that when the objects reach a certain x position it despawns itself.
local mRandom = math.random
local objects = {"Vehicle11" ,"Vehicle21","Vehicle31","Vehicle41"}
local objectTag = 0
local object = {}
local function spawncarright()
local rightcar = {408,312}
objectTag = objectTag + 1
local objIdx = mRandom(#objects)
local objName = objects[objIdx]
object[objectTag] = display.newImage(objName..".png") -- see the difference here
object[objectTag].x = 32
object[objectTag].y = rightcar[math.random(1,2)]
object[objectTag].name = objectTag
transition.to(object[objectTag], {time = 3500, x = 348})
end
timer.performWithDelay(2000,spawncarright,0)
so once reaches object[objectTag].x = 348 the object despawn
Try this:
local function deSpawn()
for i=1,objectTag do
if(object[i]~=nil and object[i].x~=nil and object[i].x>=348)then
-- If you want to remove the object, then use the following 2 lines --
object[i]:removeSelf()
print("Removed object["..i.."]")
--or else if you want to reposition the object, then uncomment the following --
--[[
spawncarright()
--]]
end
end
end
Runtime:addEventListener("enterFrame",deSpawn)
Keep coding................... :)
You should do it within the transition.to call:
object[objectTag].deleteSelf = function(self)
object[self.name] = nil -- Remove reference to object in table
display.remove(self)
self = nil
end
local localObj = object[objectTag] -- Do this so the object doesn't change with the objectTag does; if objectTag is incremented, then when the transition ends, it won't be pointing to the same object when we call the function
transition.to(localObj, {time = 3500, x = 348, onComplete = function() localObj:deleteSelf() end})

Compatible SQL function for Excel FDist

Does anyone know that is there a compatible function in SQL for Excel FDIST and FINV? If there is no, anyone has any idea how to build that? May be in C#?
Thanks. Your help is greatly appreciated.
I have managed to resolve my problems by using a library from .Net Framework 4.0 and above (System.Windows.Forms.DataVisualization.Charting.StatisticFormula).
I am able to develop a function in C# using the above library for my calculation process. This is a powerful library where you can find mostly common use statistical formula in there (e.g. mean, median, t distribution, f distribution, and inverse of them.)
Below are the code snippet from me:
using System.Windows.Forms.DataVisualization.Charting;
private Chart ch = new Chart(); // You will need to declare an object of Chart type, as Statistic Formula class does not have a public constructor
double fDist = ch.DataManipulator.Statistics.FDistribution(fRatioVariance, degreeFreedom1, degreeFreedom2);
Hope this will help others. Thanks.
Though its too late but below are some statistical function implementation in SQL Server itself.
To get FDist function (equivalent to Excel - FDist), we will be needing Complete and Incomplete beta function as well as gamma function:
--GAMMA Function
CREATE FUNCTION [dbo].[udf_Gamma]
(
#x Float=NULL
)
RETURNS Float
AS
BEGIN
Declare #f Float = 10E99;
Declare #g Float = 1;
if ( #x > 0 )
Begin
while (#x < 3)
Begin
SET #g = #g * #x;
SET #x = #x + 1;
End
SET #f = (1 - (2/(7*power(#x,2))) * (1 - 2/(3*power(#x,2))))/(30*power(#x,2));
SET #f = (1-#f)/(12*#x) + #x*(log(#x)-1);
SET #f = (exp(#f)/#g)*power(2*PI()/#x,0.5);
End
else
Begin
SET #f = 10E99
End
return #f;
END
--BETA Complete Function
CREATE FUNCTION [dbo].[udf_BetaC]
(
#x Float=NULL
,#a Float=NULL
,#b Float=NULL
)
RETURNS Float
AS
BEGIN
--double betacf(double a,double b,double x){
Declare #maxIterations int = 50, #m int =1
Declare #eps Float = 3E-5
Declare #am Float = 1;
Declare #bm Float = 1;
Declare #az Float = 1;
Declare #qab Float = #a+#b;
Declare #qap Float = #a+1;
Declare #qam Float = #a-1;
Declare #bz Float = 1 - #qab*#x/#qap;
Declare #aold Float = 0;
Declare #em Float, #tem Float, #d Float, #ap Float, #bp Float, #app Float, #bpp Float;
while((#m<#maxIterations) AND (abs(#az-#aold)>=#eps*abs(#az)))
Begin
SET #em = #m;
SET #tem = #em+#em;
SET #d = #em*(#b-#m)*#x/((#qam + #tem)*(#a+#tem));
SET #ap = #az+#d*#am;
SET #bp = #bz+#d*#bm;
SET #d = -(#a+#em)*(#qab+#em)*#x/((#a+#tem)*(#qap+#tem));
SET #app = #ap+#d*#az;
SET #bpp = #bp+#d*#bz;
SET #aold = #az;
SET #am = #ap/#bpp;
SET #bm = #bp/#bpp;
SET #az = #app/#bpp;
SET #bz = 1;
SET #m = #m + 1;
End
return #az
END
--BETA INCOMPLETE Function
CREATE FUNCTION [dbo].[udf_BetaI]
(
#x Float=null
,#a Float=null
,#b Float=null
)
RETURNS Float
AS
BEGIN
Declare #bt Float=0.0
Declare #beta Float=0.0
if( #x=0 OR #x=1 )
Begin
SET #bt = 0
End
else if((#x>0) AND (#x<1))
Begin
SET #bt = (Select dbo.UDF_Gamma(#a+#b)* power(#x,#a)* power(1-#x,#b)/(dbo.UDF_Gamma(#a)*dbo.UDF_Gamma(#b)) )
End
if(#x<(#a+1)/(#a+#b+2))
Begin
SET #beta = (Select #bt*dbo.udf_betaC(#x,#a,#b)/#a)
End
else
Begin
SET #beta = (Select 1-#bt*dbo.udf_betaC(1-#x,#b,#a)/#b)
End
Return #beta
END
--FDist Function
CREATE FUNCTION [dbo].[udf_FDist]
(
#x Float=NULL
,#df1 Float=NULL
,#df2 Float=NULL
)
RETURNS Float
AS
BEGIN
Declare #x1 Float=(#x*#df1)/((#x*#df1)+#df2)
return (select 1 - dbo.udf_BetaI(#x1,(#df1/2),(#df2/2)))
END
Check in Excel =FDIST(0.5,1,1)=0.608173448
and in SQL editor = SELECT udf_FDIST(0.5,1,1)=0.608173457369209
Regards,
Avi
FDIST an FINV Don't exists IN Sql Server.
You can write a SQL Sever function to implement two excel feature.
Show here to create function
in MS SQL Server there is standard_deviation
and some more statistical functions including variance.
There is also a million workarounds, for example: http://oreilly.com/catalog/transqlcook/chapter/ch08.html
,you need to dig deep into the math for these, though.

Updating a string inside a callback

The following code is a graphic rendering of the Earth globe spinning eastward. I have two push buttons, Spin and Stop. Both share the same callback function, hAnimaCallback. In particular, this latter does not work. I pretend to use the strings (names) of the push buttons to create a switch that stops the movement. However, I can not get to change the string name inside the while loop and I do not understand why my method is wrong.
function example
fh = figure('Menu','none','Toolbar','none','Units','characters');
T = 0:pi/100:2*pi;
Y = zeros(numel(T),3);
Y(:,1) = 7000*cos(T);
Y(:,2) = 7000*sin(T);
hPanAni = uipanel('parent',fh,'Units','characters','Position',...
[22.6 10.4 53 23],'title','Controls','FontSize',11,...
'FontAngle','italic','FontWeight','bold');
hIniAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.64 0.5 0.12],'String','Spin',...
'FontSize',10,'Callback',#hAnimaCallback);
hFinAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.26 0.5 0.12],'String','Stop',...
'FontSize',10,'Callback',#hAnimaCallback);
hPantSim = uipanel('Parent',fh,'Units','characters',...
'Position',[107.87 8 157.447 42],'BorderType','none','title',...
'Screen','FontSize',11,'FontAngle','italic',...
'FontWeight','bold');
hPantSimInt = uipanel('Parent',hPantSim,'Units','normalized','Position',...
[0 0 1 1],'BorderType','line','BackgroundColor','black');
ah4 = axes('Parent',hPantSimInt,'Units','normalized','Position',...
[0 0 1 1],'Color','none','Visible','off','DataAspectRatio',...
[1 1 1],'NextPlot','add');
rotate3d(ah4);
hgrot = hgtransform('Parent',ah4);
Resf = 6378;
maptext = imread('tierra.jpg');
[X, map] = rgb2ind(maptext,128);
[x,y,z] = sphere(50);
x = Resf*x;
y = Resf*y;
z = Resf*z;
props.FaceColor= 'texture';
props.EdgeColor = 'none';
props.Parent = hgrot;
props.Cdata = flipud(X); % it is necesary to do this for getting the
% appropiate image on the sphere
hsurf = surface(x,y,z,props);
colormap(map);
axis equal;
view([71 14]);
set(gcf,'Renderer','opengl')
drawnow;
line('parent',ah4,'XData',Y(:,1),'YData',Y(:,2),'ZData',...
Y(:,3),'Color','red','LineWidth',2);
line('parent',ah4,'XData',Y(end,1),'YData',Y(end,2),...
'ZData',Y(end,3),'Marker','o','MarkerSize',6,'MarkerFaceColor','b');
axis square equal vis3d;
view(3);
handles.XLim = get(ah4,'XLim');
handles.YLim = get(ah4,'YLim');
handles.ZLim = get(ah4,'ZLim');
xmin = handles.XLim(1);
ymin = handles.YLim(1);
zmin = handles.ZLim(1);
xmax = handles.XLim(2);
ymax = handles.YLim(2);
zmax = handles.ZLim(2);
set(ah4, 'XLim', [xmin xmax],'YLim', [ymin ymax],'Zlim',[zmin zmax]);
az = 0;
function hAnimaCallback(hObject,evt)
while (ishandle(fh))
state = get(hObject,'String'), % state should change between the states of
% Spin and Stop but this does not occur
if (strcmp(state,'Stop'))
break;
else
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
drawnow;
end
end
end
end
It seems like you are running into some kind of race condition because of the repeated drawnow calls in the while loop. The state changes to Stop, when you press the Stop button, but it is to quick to notice. Basically, the while loop is running as fast as MATLAB can run. Instead of drawnow using a pause(0.1) command seems to work (with a little bit code logic changes):
az = 0;
spin = false;
function hAnimaCallback(hObject,~)
state = get(hObject,'String')
if strcmp(state, 'Spin')
spin = true;
else
spin = false;
end
while (spin)
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
pause(0.1);
end
end

Resources