How to set general purpose timer to counter mode on STM32F411E? - stm32f4discovery

I need a timer to increment with rising edge on the GPIO pin. I can't find any code example doing just that.
I have a digital Hall sensor which sense a magnet approaching the sensor and I want to count how many times the magnet came around the sensor. The sensor gives positive pulse when magnet goes around. I want to use this pulse to increment counter value.
I know how to set the timer into basic up-counting mode (with internal clock).
TIM_TimeBaseInitTypeDef TIM_BaseStruct;
/* Configure TIMER4*/
TIM_BaseStruct.TIM_Prescaler = 40000;
TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_BaseStruct.TIM_Period = 500;
TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
TIM_Cmd(TIM4, ENABLE);
And this works, but I need to switch the clock to external signal. How do I do that?
EDIT
After rewriting code from Guillaume Michel's answer with the use of functions defined in library I'm using (I do not use HAL library), I came up with a code
TIM_TimeBaseInitTypeDef timer4;
timer4.TIM_Prescaler=0;
timer4.TIM_CounterMode=TIM_CounterMode_Up;
timer4.TIM_Period=5;
timer4.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM4,&timer4);
TIM_ETRClockMode2Config(TIM4,TIM_ExtTRGPSC_DIV2,TIM_ExtTRGPolarity_NonInverted, 0);
TIM_SelectSlaveMode(TIM4,TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Disable);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_PinAFConfig(GPIOD,GPIO_Pin_13,GPIO_AF_TIM4);
GPIO_Init(GPIOD, &GPIO_InitStructure);
This is compilable, yet non-working code. I set the timer period to 5 and I set interrupt to toggle LED every time timer counts all the way up, but LED never lights on no matter how many times i run magnet around sensor. Is there some visible mistake? What can I do to make it work?

You could try to connect the hall sensor output on a GPIO of you STM32F411 and set this GPIO as clock of the timer. This could look like:
TIM_HandleTypeDef htim4;
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim4.Instance = TIM4;
htim4.Init.Prescaler = 0;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 65535;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim4);
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
sClockSourceConfig.ClockFilter = 0;
HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig);
The GPIO is set up like this:
//Set PE0 as TIM4_ETR
__HAL_RCC_GPIOE_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

Related

Error: On Activation: Select: Type: Nothing expected, Array,String,Config entry when running specified code in Arma 3

So, my issue is whenever I run this code block within a trigger with condition any player,
private _all_freedom_units = ["B_FRD_Freedomer_Patrolman_01","B_FRD_Freedomer_Sniper_01", "B_FRD_Freedomer_Exo_1", "B_FRD_Freedomer_Warrior_01", "B_FRD_Freedomer_SEVA_01", "B_FRD_Freedomer_Gaurdian_01", "B_FRD_Freedomer_Seva_II_01"];
private _final_pos = [0,0,0];
private _position_player = [0, 0, 0];
_direction = getDir player;
if (_direction > 0 and _direction < 90) then {cardinal_direction = "North";};
if (_direction > 90 and _direction < 180) then {cardinal_direction = "South";};
if (_direction > 180 and _direction < 250) then{cardinal_direction = "South";};
if (_direction > 250 and _direction < 359) then{cardinal_direction = "North";};
_position_player = getPos player;
_position_player_x = _position_player select 0;
_position_player_y = _position_player select 1;
if (cardinal_direction == "North") then{
_random_x = [250, 500] call BIS_fnc_randomInt;
_random_y = [250, 500] call BIS_fnc_randomInt;
_final_pos set [0 , _position_player_x + 200 + _random_x];
_final_pos set [1 , _position_player_y + 200 + _random_y];
};
if (cardinal_direction == "South") then{
_random_x = [-250, -500] call BIS_fnc_randomInt;
_random_y = [-250, -500] call BIS_fnc_randomInt;
_final_pos set [0 , _position_player_x + _random_x];
_final_pos set [1 , _position_player_y + _random_y];
};
_position = _final_pos;
_group_freedom_patrol = createGroup [west, true];
hint str _final_pos select 0;
_random_number = floor random 5;
The editor returns with,
On Activation: Select: Type Nothing, expected Array,String,Config entry
I have a suspicion from similar reports that it's centered around these statements
_position_player = getPos player;
_position_player_x = _position_player select 0;
_position_player_y = _position_player select 1;
Because of the "select" aspect of the error code, but I just started Arma 3 scripting
A similar post recommended dealing with the Condition portion of the Trigger, but the fixes their didn't work. I'm not quite sure what the issue is at this point, as I'm new to Arma 3 scripted.
The big issue here is I'm 90% sure it's an issue with syntax, because if it was logic the trigger would allow me to use the code in the first place. In this case, the built in checks are barring me from running the code, and syntax errors are harder than logic for me.
The code is intended to run properly, grab the first player who enters the trigger, and using the position data and angle it should (this part of the code isn't included as I'm testing in chunks and this chunk isn't working) spawn units in front of the player, min 250 out, heading towards them,
But as I explained previously, the Arma 3 debugger is yelling at me before I can even test the code.
Take this with a grain of salt, I haven't scripted for Arma 3 for quite the time.
I think if the errors comes up in the editor, then it may be because the player may not be defined (makes sense in the editor). You should check that. Either way - to make it multiplayer compatible - you should use the the "thisList" variable to access the list of the objects which are in the trigger area. If this only triggers for players, then you can use "thisList select 0".
See the passed variables for On Activation in the documentation

uiresume (gcbf) worked in the function, but failed when the function being called

I want to let the user select multiple ROI's on a picture. I used a while loop. I paused and let the user select an ROI. After that the while loop would continue unless the user clicked another button on the toolbar to terminate the while loop. The code worked on single pictures. I made the code a function. When I looped and called the function in another script, it failed to proceed. I pressed Ctrl + C and it showed that "Operation terminated by user during uiwait". Apparently the uiresume didn't work.
Please let me know where the problems are. Thanks! My code:
% Below was basically a copy of the example given in R2014a.
% It created an interactive toolbar with 2 pushbuttons.
fh = figure('ToolBar', 'none'); hold on;
h_im = imshow(rgb2gray (I));
tbh = uitoolbar(fh);
[X_OK, map_OK] = imread(fullfile(matlabroot,...
'toolbox','matlab','icons','greenarrowicon.gif'));
[X_rect, map_rect] = imread(fullfile(matlabroot,...
'toolbox','matlab','icons','tool_rectangle.gif'));
% Convert indexed image and colormap to truecolor
icon_OK = ind2rgb(X_OK, map_OK);
icon_rect = ind2rgb(X_rect, map_rect);
% Create 2 uipushtools in the toolbar
% I introduced 2 variables, leave and draw, to facilitate the control of the
% later while-loop.
pth_OK = uipushtool(tbh, 'CData',icon_OK,...
'TooltipString','Toolbar push button',...
'ClickedCallback',...
'leave = 1; uiresume (gcbf)');
pth_rect = uipushtool(tbh, 'CData',icon_rect, 'Separator','on',...
'TooltipString','Toolbar push button',...
'ClickedCallback',...
'draw = 1; uiresume (gcbf)');
% The loop for ROI selection.
ii = 1;
% Maximum the use can select 30 ROI's.
while ii < 31;
draw = 0;
uiwait;
if leave == 1;
% If the user pressed "OK" button, leave will be 1.
break;
end;
if draw == 1;
% If the user pressed the "rect" button, draw will be 1.
h = imrect;
wait (h);
gui_Mask = createMask(h, h_im);
greyImg (~gui_Mask) = 255;
ii = ii + 1;
continue;
end;
end;
I saw someone used set/waitfor instead.
I tried to change to set/waitfor. Now it works both in the function and when the function being called.
But I still want to know why uiresume didn't work.

Use of particle effect

I am using particle effect my game using libgdx. But effect is showing for small time and after that it disappear.But I want to show my effect for long time or in my control.
My code is given below in my game play screen class...
ParticleEffectPool waterEffectPool;
Array<PooledEffect> effects = new Array<PooledEffect>();
ParticleEffect waterEffect;
...
...
waterEffect = new ParticleEffect();
waterEffect.load(Gdx.files.internal("data/runonwater"), Gdx.files.internal("data"));
waterEffectPool = new ParticleEffectPool(waterEffect, 1, 5);
//for(int i = 0; i <= waterEffectPool.max; i++){
PooledEffect effect = waterEffectPool.obtain();
effect.setPosition(150, 130);
effects.add(effect);
and in render method I use it to render
for(int i = effects.size - 1; i >= 0; i--){
PooledEffect effect = effects.get(i);
effect.draw(spriteBatch, deltaTime);
if(effect.isComplete()){
effect.free();
effects.removeIndex(i);
}
}
I have already answered the question in the comments section above but still writing it here so as it can be accepted (as suggested by P.T.)
If you are using particle editor then there is an option weather to set this effect continuous or not. Set continuous as true and problem will be solved .
#P.T. yups you r right. Will remember it from now on :)

AS3 class instances names

I really wonder. I made a MovieClip class Apple, I wrote a function that creates a new instance with a name "apple". Each time a new instance is pushed into an Array "apples". I call the function 5 times and I get 5 apples. I can manipulate them by calling them i.e. apples[0]. And when I trace my array I see 5 [object Apple] things. So maybe I don't really understand the structure of AS3 objects but shouldn't each object have a name?
When I set apple.name and get an array with 5 different names, I can't manipulate objects by names like apple1.x = 10. How does computer know which apple is where if each has own coordinates? Is the only way to call them: apples[0]-apples[4]? And if I create a code that should be same for all apples, how should I address the function, to "this"? Cause when I write class code I don't have any names yet...
For example, if I want to make Apple class a picture(MovieClip) that can be dragged, create any number of apples, up to a million, I can't possibly add apples[0].addEventListener, apples[1].addEventListener ... apples[1000000].addEventListener to the code. How do I make it global?
I'm asking cause when I'm directly coding for a specific instance, it has a name and I know exactly what am I addressing. And working with a class and making many objects I kinda don't... Sorry, I'm green
You don't need names to be able to access and manipulate your instances.
You can do something like this:
var apples:Array = new Array();
for (var i:int = 0; i < 100; i++)
{
var apple:Apple = new Apple();
apples.push(apple);
apple.x = Math.random() * 500;
apple.y = Math.random() * 500;
addChild(apple);
apple.addEventListener(MouseEvent.CLICK, onAppleClick);
}
function onAppleClick(e:MouseEvent):void
{
var ind:int = apples.indexOf(e.currentTarget);
var apple:Apple = apples[ind];
trace(ind);
apples[ind].visible = false;
//or
//apple.visible = false;
}
The same problem, huh? :)
For example Apple extends Sprite and inherits property name.
It's public, this means that you can change its name.
var apple:Apple = new Apple() ;
apple.name = "MegaApple" ;
Also, if you add the apple to stage, you can get him via name.
stage.addChild(apple) ;
get apple back:
var oldApple:Apple = stage.getChildByName("MegaApple") ;
But that never means, that you can use apple like that:
MegaApple.move() - because name of apple is supposed to be a property of apple, not a name of a variable.
Of course, you can create a lot of apples manually:
var apple1 = new Apple() ;
var apple2 = new Apple() ;
var apple3 = new Apple() ;
But if they all behave the same way, there is no point in doing. That's why you store them into array.
Hope you understand what I mean.

Tips for function inside while loop and i=i+1, Matlab

I have a problem with a function in matlab. This specific function is for filtering light signals. As you can see below I added the coding I’ve used in the function and in the while loop itself. The code is written for a NXT Lego robot.
Is there any tip how to get the count variable ( i = i + 1 ) to work in the function, so we can plot Light(i)? Because we’re getting a bunch of error messages when we try different codes to make it work.
function [light] = filter_func( i)
lightI(i) = GetLight(SENSOR_3);
if i==1
light(i)=lightI(i)
elseif i==2
light(i) = 0.55*lightI(i) + 0.45*lightI(i-1)
else
light(i) = 0.4*lightI(i) + 0.3*lightI(i-1) + 0.3*lightI(i-2);
end
end
i=1
while true
lightI(i) = GetLight(SENSOR_3); % Get’s a lightvalue between 0 and 1024.
if i>2
light =filter_func(i)
light=round(light);
else
light(i) = GetLight(SENSOR_3);;
end
i=1+i
plot(light(end-90:end), 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
end
You probably mainly get errors because you are not allowed to mix script and functions like this in MATLAB (like you are in Python).
Your filter function is only used when i>2 so why are you doing the first 2 tests? It seems like you want lightI as a global variable, but that is not what you have done. The lightI inside the function is not the same as the one in the while loop.
Since your while loop runs forever, maybe you don't need to worry about updating the plot the first two times. In that case you can do this:
filter = [0.4 0.3 0.3]';
latest_filtered_light = nan(90,1);
lightI = [];
p = plot(latest_filtered_light, 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
while True
lightI(end+1,1) = rand*1024; % Get’s a lightvalue between 0 and 1024.
if i>=3
new_val = lightI(end-2:end,1)'*filter;
latest_filtered_light = [latest_filtered_light(2:end);...
new_val];
set(p, 'ydata', latest_filtered_light)
drawnow
end
end
I think it is an important point to not call plot every time - at least if you are the least concerned about performance.