How can I count pulse inputs with some interval time? - raspberry-pi

I'm develop a pulse counter(coin counter) in raspberry pi with windows 10 iot core, and i need to count pulses that have a interval time of 25 miliseconds like this:
0,05€ - 1 pulse
0,10€ - 2 pulses
0,20€ - 4 pulses
0,50€ - 10 pulses
1€ - 20 pulses
2€ - 40 pulses
like this image: pulses
I need to print the number of pulses(to have the value inserted) when the interval time is diferent of 25 miliseconds.
I have this code:
public MainPage()
{
this.InitializeComponent();
InitGPIO();
}
private void InitGPIO()
{
var gpio = GpioController.GetDefault();
if (gpio == null)
{
GpioStatus.Text = "There is no GPIO controller on this device.";
}
coinPin = gpio.OpenPin(coin_Pin);
if (coinPin.IsDriveModeSupported(GpioPinDriveMode.InputPullUp))
{
coinPin.SetDriveMode(GpioPinDriveMode.InputPullUp);
} else
{
coinPin.SetDriveMode(GpioPinDriveMode.Input);
}
coinPin.DebounceTimeout = TimeSpan.FromMilliseconds(25);
coinPin.ValueChanged += coinPin_ValueChanged;
GpioStatus.Text = "GPIO pins initialized correctly.";
}
private void coinPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
{
if (e.Edge == GpioPinEdge.FallingEdge)
{
counter++;
}
var task = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
if (e.Edge == GpioPinEdge.FallingEdge)
{
//counter++;
var time = PulseIn(coinPin, e.Edge);
value = (counter * 5);
value100 = value / 100;
//money.Text = "Eur: " + (decimal)value100 + " €";
if (time != 25)
{
money.Text = "Eur: " + (decimal)value100 + " €";
GpioStatus.Text = "" + time;
} else
{
GpioStatus.IsEnabled = false;
}
//GpioStatus.Text = "" + time + "";
} else
{
///GpioStatus.Text = "" + coinPin.DebounceTimeout;
}
});
}
private double PulseIn(GpioPin pin, GpioPinEdge edge)
{
var sw = new Stopwatch();
while (edge.Equals(GpioPinEdge.RisingEdge))
{
//sw.Start();
}
sw.Start();
if (!edge.Equals(GpioPinEdge.RisingEdge))
{
//sw.Stop();
}
sw.Stop();
return sw.Elapsed.TotalMilliseconds;
}
private const int coin_Pin = 24;
private int counter = 0;
private double value = 0;
private double value100 = 0;
private GpioPin coinPin;
Can you help me please?
Thank you very much.

From your code,
sw.Start();
if (!edge.Equals(GpioPinEdge.RisingEdge))
{
//sw.Stop();
}
sw.Stop();
it actually measures the execute time of the if statement that between sw.Start() and sw.Stop(). This does not make sense. Record the watch.Elapsed.TotalMilliseconds when the falling edge arrived and restart the stopwatch to measure the pulse interval time. To do this, I add the following two code lines under counter++, remove var time = PulseIn(coinPin, e.Edge) and use timeinterval in GpioStatus.Text = "" + timeinterval instead.
timeinterval = watch.Elapsed.TotalMilliseconds;
watch.Restart();
The following is complete code piece:
private Stopwatch watch = new Stopwatch();
private void coinPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
{
double timeinterval = 0;
if (e.Edge == GpioPinEdge.FallingEdge)
{
counter++;
timeinterval = watch.Elapsed.TotalMilliseconds;
watch.Restart();
}
var task = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
if (e.Edge == GpioPinEdge.FallingEdge)
{
//var time = PulseIn(coinPin, e.Edge);
value = (counter * 5);
value100 = value / 100;
if (timeinterval != 25)
{
money.Text = "Eur: " + (decimal)value100 + " €";
GpioStatus.Text = "" + timeinterval;
}
//...
}
});
}
You can try above code piece to see if it meets your accuracy requirement.
Note: It is not suitable to measure hardware pulse interval in software level because the software jitter is always unpredictable.

Related

How to change the audio sample rate in Unity?

The default audio sample rate is 48000. Is it possible to change it to other values like 44100?
I log the value of AudioSettings.outputSampleRate and it shows 48000. But it doesn't seem possible to change that value.
Here is the code to change sample rate of Unity's AudioClip:
Most simple, but very rough
Averaging approach, but channels are get mixed
Averaging approach for each channel (best quality)
public static AudioClip SetSampleRateSimple(AudioClip clip, int frequency)
{
if (clip.frequency == frequency) return clip;
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
var samplesLength = (int)(frequency * clip.length) * clip.channels;
var samplesNew = new float[samplesLength];
var clipNew = AudioClip.Create(clip.name + "_" + frequency, samplesLength, clip.channels, frequency, false);
for (var i = 0; i < samplesLength; i++)
{
var index = (int) ((float) i * samples.Length / samplesLength);
samplesNew[i] = samples[index];
}
clipNew.SetData(samplesNew, 0);
return clipNew;
}
public static AudioClip SetSampleRateAverage(AudioClip clip, int frequency)
{
if (clip.frequency == frequency) return clip;
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
var samplesNewLength = (int) (frequency * clip.length) * clip.channels;
var samplesNew = new float[samplesNewLength];
var clipNew = AudioClip.Create(clip.name + "_" + frequency, samplesNewLength, clip.channels, frequency, false);
var index = 0;
var sum = 0f;
var count = 0;
for (var i = 0; i < samples.Length; i++)
{
var index_ = (int)((float)i / samples.Length * samplesNewLength);
if (index_ == index)
{
sum += samples[i];
count++;
}
else
{
samplesNew[index] = sum / count;
index = index_;
sum = samples[i];
count = 1;
}
}
clipNew.SetData(samplesNew, 0);
return clipNew;
}
public static AudioClip SetSampleRate(AudioClip clip, int frequency)
{
if (clip.frequency == frequency) return clip;
if (clip.channels != 1 && clip.channels != 2) return clip;
var samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
var samplesNewLength = (int) (frequency * clip.length) * clip.channels;
var clipNew = AudioClip.Create(clip.name + "_" + frequency, samplesNewLength, clip.channels, frequency, false);
var channelsOriginal = new List<float[]>();
var channelsNew = new List<float[]>();
if (clip.channels == 1)
{
channelsOriginal.Add(samples);
channelsNew.Add(new float[(int) (frequency * clip.length)]);
}
else
{
channelsOriginal.Add(new float[clip.samples]);
channelsOriginal.Add(new float[clip.samples]);
channelsNew.Add(new float[(int) (frequency * clip.length)]);
channelsNew.Add(new float[(int) (frequency * clip.length)]);
for (var i = 0; i < samples.Length; i++)
{
channelsOriginal[i % 2][i / 2] = samples[i];
}
}
for (var c = 0; c < clip.channels; c++)
{
var index = 0;
var sum = 0f;
var count = 0;
var channelSamples = channelsOriginal[c];
for (var i = 0; i < channelSamples.Length; i++)
{
var index_ = (int) ((float) i / channelSamples.Length * channelsNew[c].Length);
if (index_ == index)
{
sum += channelSamples[i];
count++;
}
else
{
channelsNew[c][index] = sum / count;
index = index_;
sum = channelSamples[i];
count = 1;
}
}
}
float[] samplesNew;
if (clip.channels == 1)
{
samplesNew = channelsNew[0];
}
else
{
samplesNew = new float[channelsNew[0].Length + channelsNew[1].Length];
for (var i = 0; i < samplesNew.Length; i++)
{
samplesNew[i] = channelsNew[i % 2][i / 2];
}
}
clipNew.SetData(samplesNew, 0);
return clipNew;
}

Chrome Developer Tools - Performance profiling

In the below image (from chrome performance profiling tab for a API call), what is resource loading which costs 719 ms ?
If I visit the network tab, for the same API call, I see only 10.05 seconds.
What is resource loading mean here ? Is there any specific activity the browser does after receiving the data ?
As #wOxxOM stated, buildNetworkRequestDetails is being called from Source Code
From the statement by #Sanju singh :
that statement doesn't tell anything, why it is taking that much time to make the resource available?
I think its necessary to break down exactly what is happening..
Summary:
Activity Browser and Network Activity are using different algorithms for calculating completion. Network Activity is calculating the response times from the request and Activity Browser is calculating the response time + time it took to add it into the WebInspector tracer.
Looking at
/**
* #param {!TimelineModel.TimelineModel.NetworkRequest} request
* #param {!TimelineModel.TimelineModel.TimelineModelImpl} model
* #param {!Components.Linkifier.Linkifier} linkifier
* #return {!Promise<!DocumentFragment>}
*/
static async buildNetworkRequestDetails(request, model, linkifier) {
const target = model.targetByEvent(request.children[0]);
const contentHelper = new TimelineDetailsContentHelper(target, linkifier);
const category = TimelineUIUtils.networkRequestCategory(request);
const color = TimelineUIUtils.networkCategoryColor(category);
contentHelper.addSection(ls`Network request`, color);
if (request.url) {
contentHelper.appendElementRow(ls`URL`, Components.Linkifier.Linkifier.linkifyURL(request.url));
}
// The time from queueing the request until resource processing is finished.
const fullDuration = request.endTime - (request.getStartTime() || -Infinity);
if (isFinite(fullDuration)) {
let textRow = Number.millisToString(fullDuration, true);
// The time from queueing the request until the download is finished. This
// corresponds to the total time reported for the request in the network tab.
const networkDuration = request.finishTime - request.getStartTime();
// The time it takes to make the resource available to the renderer process.
const processingDuration = request.endTime - request.finishTime;
if (isFinite(networkDuration) && isFinite(processingDuration)) {
const networkDurationStr = Number.millisToString(networkDuration, true);
const processingDurationStr = Number.millisToString(processingDuration, true);
const cacheOrNetworkLabel = request.cached() ? ls`load from cache` : ls`network transfer`;
textRow += ls` (${networkDurationStr} ${cacheOrNetworkLabel} + ${processingDurationStr} resource loading)`;
}
contentHelper.appendTextRow(ls`Duration`, textRow);
}
if (request.requestMethod) {
contentHelper.appendTextRow(ls`Request Method`, request.requestMethod);
}
if (typeof request.priority === 'string') {
const priority = PerfUI.NetworkPriorities.uiLabelForNetworkPriority(
/** #type {!Protocol.Network.ResourcePriority} */ (request.priority));
contentHelper.appendTextRow(ls`Priority`, priority);
}
if (request.mimeType) {
contentHelper.appendTextRow(ls`Mime Type`, request.mimeType);
}
let lengthText = '';
if (request.memoryCached()) {
lengthText += ls` (from memory cache)`;
} else if (request.cached()) {
lengthText += ls` (from cache)`;
} else if (request.timing && request.timing.pushStart) {
lengthText += ls` (from push)`;
}
if (request.fromServiceWorker) {
lengthText += ls` (from service worker)`;
}
if (request.encodedDataLength || !lengthText) {
lengthText = `${Number.bytesToString(request.encodedDataLength)}${lengthText}`;
}
contentHelper.appendTextRow(ls`Encoded Data`, lengthText);
if (request.decodedBodyLength) {
contentHelper.appendTextRow(ls`Decoded Body`, Number.bytesToString(request.decodedBodyLength));
}
const title = ls`Initiator`;
const sendRequest = request.children[0];
const topFrame = TimelineModel.TimelineModel.TimelineData.forEvent(sendRequest).topFrame();
if (topFrame) {
const link = linkifier.maybeLinkifyConsoleCallFrame(target, topFrame, {tabStop: true});
if (link) {
contentHelper.appendElementRow(title, link);
}
} else {
const initiator = TimelineModel.TimelineModel.TimelineData.forEvent(sendRequest).initiator();
if (initiator) {
const initiatorURL = TimelineModel.TimelineModel.TimelineData.forEvent(initiator).url;
if (initiatorURL) {
const link = linkifier.maybeLinkifyScriptLocation(target, null, initiatorURL, 0, {tabStop: true});
if (link) {
contentHelper.appendElementRow(title, link);
}
}
}
}
if (!request.previewElement && request.url && target) {
request.previewElement = await Components.ImagePreview.ImagePreview.build(
target, request.url, false,
{imageAltText: Components.ImagePreview.ImagePreview.defaultAltTextForImageURL(request.url)});
}
if (request.previewElement) {
contentHelper.appendElementRow(ls`Preview`, request.previewElement);
}
return contentHelper.fragment;
}
We can easily see that the request parameter is of type
`TimelineModel.TimelineModel.NetworkRequest`
NetWorkRequest has the following code:
_didStopRecordingTraceEvents: function()
{
var metadataEvents = this._processMetadataEvents();
this._injectCpuProfileEvents(metadataEvents);
this._tracingModel.tracingComplete();
this._resetProcessingState();
var startTime = 0;
for (var i = 0, length = metadataEvents.page.length; i < length; i++) {
var metaEvent = metadataEvents.page[i];
var process = metaEvent.thread.process();
var endTime = i + 1 < length ? metadataEvents.page[i + 1].startTime : Infinity;
this._currentPage = metaEvent.args["data"] && metaEvent.args["data"]["page"];
for (var thread of process.sortedThreads()) {
if (thread.name() === WebInspector.TimelineModel.WorkerThreadName && !metadataEvents.workers.some(function(e) { return e.args["data"]["workerThreadId"] === thread.id(); }))
continue;
this._processThreadEvents(startTime, endTime, metaEvent.thread, thread);
}
startTime = endTime;
}
this._inspectedTargetEvents.sort(WebInspector.TracingModel.Event.compareStartTime);
this._cpuProfiles = null;
this._buildTimelineRecords();
this._buildGPUTasks();
this._insertFirstPaintEvent();
this._resetProcessingState();
this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordingStopped);
},
We can see that endTime is being calculated from:
metaEvent.thread.process()
We can see that metaEvent.page is being set by:
_processMetadataEvents: function()
{
var metadataEvents = this._tracingModel.devToolsMetadataEvents();
var pageDevToolsMetadataEvents = [];
var workersDevToolsMetadataEvents = [];
for (var event of metadataEvents) {
if (event.name === WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage)
pageDevToolsMetadataEvents.push(event);
else if (event.name === WebInspector.TimelineModel.DevToolsMetadataEvent.TracingSessionIdForWorker)
workersDevToolsMetadataEvents.push(event);
}
if (!pageDevToolsMetadataEvents.length) {
// The trace is probably coming not from DevTools. Make a mock Metadata event.
var pageMetaEvent = this._loadedFromFile ? this._makeMockPageMetadataEvent() : null;
if (!pageMetaEvent) {
console.error(WebInspector.TimelineModel.DevToolsMetadataEvent.TracingStartedInPage + " event not found.");
return {page: [], workers: []};
}
pageDevToolsMetadataEvents.push(pageMetaEvent);
}
var sessionId = pageDevToolsMetadataEvents[0].args["sessionId"] || pageDevToolsMetadataEvents[0].args["data"]["sessionId"];
this._sessionId = sessionId;
var mismatchingIds = new Set();
/**
* #param {!WebInspector.TracingModel.Event} event
* #return {boolean}
*/
function checkSessionId(event)
{
var args = event.args;
// FIXME: put sessionId into args["data"] for TracingStartedInPage event.
if (args["data"])
args = args["data"];
var id = args["sessionId"];
if (id === sessionId)
return true;
mismatchingIds.add(id);
return false;
}
var result = {
page: pageDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime),
workers: workersDevToolsMetadataEvents.filter(checkSessionId).sort(WebInspector.TracingModel.Event.compareStartTime)
};
if (mismatchingIds.size)
WebInspector.console.error("Timeline recording was started in more than one page simultaneously. Session id mismatch: " + this._sessionId + " and " + mismatchingIds.valuesArray() + ".");
return result;
}

Making a DragDrop class on as3

I'm making a DragDrop class on as3. I'm trying to make movable movie clips "stick" to a target MovieClip. I've got the basic drag drop and positioning/sticking to work but when I try to create an "easing" effect using Enter Frame, somehow the movie clips move to 0 x and y position.
Here's the code that's working (without EnterFrame Event).
package {
public class DragDrop {
public var clip:MovieClip;
public var targ:MovieClip;
public var myHomeX:Number;
public var myHomeY:Number;
public var myFinalX:Number;
public var myFinalY:Number;
public function selectClip(clipV:MovieClip,targV:MovieClip):void {
clip = clipV;
targ = targV;
var myHomeX = clip.x;
var myHomeY = clip.y;
var myFinalX = targ.x;
var myFinalY = targ.y;
clip.addEventListener(MouseEvent.MOUSE_DOWN,startDragging);
clip.addEventListener(MouseEvent.MOUSE_UP,stopDragging);
clip.addEventListener(MouseEvent.ROLL_OVER,rollOver);
clip.addEventListener(MouseEvent.ROLL_OUT,rollOut);
function startDragging(e:MouseEvent):void {
clip.startDrag();
clip.beingDragged = true;
clip.parent.setChildIndex(clip,clip.parent.numChildren - 1);
}
function stopDragging(e:MouseEvent):void {
clip.stopDrag();
clip.beingDragged = false;
var onTarget:MovieClip;
if (clip.dropTarget != null)
{
onTarget = e.target.dropTarget.parent;
}
else
{
onTarget = null;
}
if ((onTarget == targ))
{
clip.onTarget = true;
targ.gotoAndStop(2);
clip.x = myFinalX;
clip.y = myFinalY;
}
else
{
clip.onTarget = false;
targ.gotoAndStop(1);
clip.x = myHomeX;
clip.y = myHomeY;
}
}
function rollOver(e:MouseEvent) {
clipGlow.restart();
}
function rollOut(e:MouseEvent) {
clipGlow.reverse();
}
}
}
}
Here's the code that's not working (with EnterFrame Event).
package {
public class DragDrop {
public var clip:MovieClip;
public var targ:MovieClip;
public var clip:MovieClip;
public var targ:MovieClip;
public var myHomeX:Number;
public var myHomeY:Number;
public var myFinalX:Number;
public var myFinalY:Number;
public function selectClip(clipV:MovieClip,targV:MovieClip):void {
clip = clipV;
targ = targV;
var myHomeX = clip.x;
var myHomeY = clip.y;
var myFinalX = targ.x;
var myFinalY = targ.y;
clip.addEventListener(MouseEvent.MOUSE_DOWN,startDragging);
clip.addEventListener(MouseEvent.MOUSE_UP,stopDragging);
clip.addEventListener(MouseEvent.ROLL_OVER,rollOver);
clip.addEventListener(MouseEvent.ROLL_OUT,rollOut);
clip.addEventListener(Event.ENTER_FRAME,slide);
function startDragging(e:MouseEvent):void {
clip.startDrag();
clip.beingDragged = true;
clip.parent.setChildIndex(clip,clip.parent.numChildren - 1);
}
function stopDragging(e:MouseEvent):void {
clip.stopDrag();
clip.beingDragged = false;
var onTarget:MovieClip;
if (clip.dropTarget != null)
{
onTarget = e.target.dropTarget.parent;
}
else
{
onTarget = null;
}
if ((onTarget == targ))
{
clip.onTarget = true;
targ.gotoAndStop(2);
}
else
{
clip.onTarget = false;
targ.gotoAndStop(1);
}
}
function rollOver(e:MouseEvent) {
clipGlow.restart();
}
function rollOut(e:MouseEvent) {
clipGlow.reverse();
}
function slide(e:Event):void {
if (! clip.beingDragged && ! clip.onTarget)
{
clip.x -= clip.x - clip.myHomeX / 5;
clip.y -= clip.y - clip.myHomeY / 5;
clip.scaleX += (1 - clip.scaleX) / 5;
clip.scaleY += (1 - clip.scaleY) / 5;
}
else if (! clip.beingDragged && clip.onTarget)
{
clip.x -= clip.x - clip.myFinalX / 5;
clip.y -= clip.y - clip.myFinalY / 5;
clip.scaleX += (1.5 - clip.scaleX) / 5;
clip.scaleY += (1.5 - clip.scaleY) / 5;
}
}
}
}
}
Thanks in advance for any help. :)
If you do this:
var myHomeX = clip.x;
var myHomeY = clip.y;
var myFinalX = targ.x;
var myFinalY = targ.y;
Then maybe clip.myHomeX should be myHomeX only etc?
function slide(e:Event):void {
if (! clip.beingDragged && ! clip.onTarget)
{
clip.x -= clip.x -myHomeX / 5;
clip.y -= clip.y -myHomeY / 5;
clip.scaleX += (1 - clip.scaleX) / 5;
clip.scaleY += (1 - clip.scaleY) / 5;
}
else if (! clip.beingDragged && clip.onTarget)
{
clip.x -= clip.x -myFinalX / 5;
clip.y -= clip.y -myFinalY / 5;
clip.scaleX += (1.5 - clip.scaleX) / 5;
clip.scaleY += (1.5 - clip.scaleY) / 5;
}
}

Score isn't showing in guiText

I have guiTexts called scoreLevel1, scoreLevel2 where i want to show the score from the right levels but it isn't showing any text or scores... There are no build errors. How do I make it show up as expected?
var Score : int;
function Update () {
Score -= 1 * Time.deltaTime;
guiText.text = "Score: "+Score;
TimerOfDeath();
}
HighScores.js:
//run at start if score doesn't exist yet to initialise playerPref
function Start(){
if(!PlayerPrefs.HasKey(Application.loadedLevelName+"HighScore"))
PlayerPrefs.SetFloat(Application.loadedLevelName+"HighScore", 0);
}
//run when level is completed
function OnTriggerEnter(other : Collider){
if(other.tag == "Player"){
Score = gameObject.Find("ScoreCount").GetComponent("ScoringPts").Update("Score");
if(Score > PlayerPrefs.GetFloat(Application.loadedLevelName+"HighScore"))
{
PlayerPrefs.SetFloat(Application.loadedLevelName+"HighScore", Score);
}
}
}
GetHighScores.js:
#pragma strict
function Start () {
var hscount = 1;
var iterations = 1;
var maxIterations = 5;
var findtext = gameObject.Find("scoreLevel"+(hscount));
while(hscount < 5 && iterations < maxIterations){
if(!PlayerPrefs.HasKey("Level"+(hscount)+"HighScore")){
findtext.guiText.text = "Level"+(hscount)+ ": " + PlayerPrefs.GetFloat("Level"+(hscount)+"HighScore");
hscount++;
}
iterations++;
}
}

Stochastic universal sampling

I need a sus implementation in c# for finding candidate individuals in a population this is what i have so far but im not sure if it is correct.
public void sus(IEnumerable<TimeTable>population)
{
var ag = population.Sum(i => normalize((double) i.Fitness, true));
var mark = rnMutate.NextDouble();
var index = 0;
foreach (var candidate in population)
{
var cu = population.Sum(i => normalize((double)i.Fitness, false)) / ag * 5;
while (cu > mark + index)
{
Survivors.Add(candidate);
index++;
}
}
}
public double normalize(double fitness, bool natural)
{
if (natural)
return fitness;
return fitness == (double)FitnessLBound ? double.PositiveInfinity : 1 / fitness;
}
private IEnumerable<TimeTable> StochasticSample(IEnumerable<TimeTable> population, int size)
{
var t = population.Sum(it => it.Fitness);
var temp = new List<TimeTable>();
var ptr = rnMutate.NextDouble();
var sum = 0M;
for (int i = 0; i < size; i++)
{
for (sum += ExpValue(i, t); sum > (decimal) ptr; ptr++)
{
temp.Add(population.ElementAt(i));
--size;
}
}
return temp;
}
private decimal ExpValue(decimal fitness, decimal sum)
{
return decimal.Divide(fitness, sum);
}