Using ShellExecute in Amibroker once on last candle - amibroker

I am new to AFL programming. what I am trying to do is to launch a console program in my computer using ShellExecute in amibroker AFL to launch my console program with parameters, which in turn contains code expensive logic to place order to my stock broker server.
I first using If condition like
if (Buy[Barcount-1]==1)
{
ShellExecute("Path/To/Programm.exe","Parameters");
}
I am using One Minute Candle. this code executes when the latest candle generates a Buy signal, but it keeps executing ShellExecute as long as the last candle has a buy signal.
is there a way to limit amibroker to limit ShellExecute cmd once per candle.
Thank you so much in advance.

I would try something like this so it would only trigger when there is a transition to the first buy signal.
if (BarCount > 1 && Buy[Barcount-2]==0 && Buy[Barcount-1]==1)
{
ShellExecute("Path/To/Programm.exe","Parameters");
}

Related

CANOPEN SYNC timeout after enable Operation

I am a newbie in CANOPEN. I wrote a program that read actual position via PDO1 (default is statusword + actual position).
void canopen_init() {
// code1 setup PDO mapping
nmtPreOperation();
disablePDO(PDO_TX1_CONFIG_COMM);
setTransmissionTypePDO(PDO_TX1_CONFIG_COMM, 1);
setInhibitTimePDO(PDO_TX1_CONFIG_COMM, 0);
setEventTimePDO(PDO_TX1_CONFIG_COMM, 0);
enablePDO(PDO_TX1_CONFIG_COMM);
setCyclePeriod(1000);
setSyncWindow(100);
//code 2: enable OPeration
readyToSwitchOn();
switchOn();
enableOperation();
motionStart();
// code 3
nmtActiveNode();
}
int main (void) {
canopen_init();
while {
delay_ms(1);
send_sync();
}
}
If I remove "code 2" (the servo is in Switch_on_disable status), i can read position each time sync send. But if i use "code 2", the driver has error "sync frame timeout". I dont know driver has problem or my code has problem. Does my code has problem? thank you!
I don't know what protocol stack this is or how it works, but these:
setCyclePeriod(1000);
setSyncWindow(100);
likely correspond to these OD entries :
Object 1006h: Communication cycle period (CiA 301 7.5.2.6)
Object 1007h: Synchronous window length (CiA 301 7.5.2.7)
They set the SYNC interval and time window for synchronous PDOs respectively. The latter is described by the standard as:
If the synchronous window length expires all synchronous TPDOs may be discarded and an EMCY message may be transmitted; all synchronous RPDOs may be discarded until the next SYNC message is received. Synchronous RPDO processing is resumed with the next SYNC message.
Now if you set this sync time window to 100us but have a sloppy busy-wait delay delay_ms(1), then that doesn't add up. If you write zero to Object 1007h, you disable the sync window feature. I suppose setSyncWindow(0); might do that. You can try to do that to see if that's the issue. If so, you have to drop your busy-wait in favour for proper hardware timers, one for the SYNC period and one for PDO timeout (if you must use that feature).
Problem fixed. Due to much EMI from servo, that make my controller didn't work properly. After isolating, it worked very well :)!

Prometheus gauge with custom collector - go

i have problem on "reseting" the values for gauges because "life stops" as soon http servervice is started or when i start looping my "runJob" then is server not started..
the way how i am trying to establish this:
i load all the Job-s from YAML array.
i generate gauges from that, then i run loop to get some values for them.
Then i register them.
And after that i start http service for prometheus.
All works perfect, until next cycle - next cycle is just not starting.
I tryed to move functions inside functions etc..
so thats my main function:
//gets poll time from yaml (60s)
timerCh := time.Tick(time.Duration(appConf.PollTimeSec) * time.Second)
//loop after given time
for range timerCh {
runJobs()
}
//start new muxServer
server := http.NewServeMux()
log.Println("DEBUG: Starting server")
server.Handle(appConf.HostPath, promhttp.Handler())
http.ListenAndServe(":"+appConf.ListenerPort, server)
and my runJobs function basicly gets Http response codes
and ads them to prometheus gauge values.
-- everything is OK with that and it works very well on starting, but after i try to start it wheet sleep (as shown in main go) it just gets stuck -
Server is up and values do not change.
So i have (my optinion) two possible ways of fixing it:
My "runJobs" is infinitive loop what runs after every minute
thats why is server not started.
But when i add there a if statement that on first run(cycle) should server be started, then it still gets stuck when server gets started (next loop cycle just woun't get started)
And the other part, when i start the server first, then it never gets to the part where it starts runJobs()
Prefered outcome should be that:
server is started with first values, and after every minute it runs "runJobs" again.
The way it is written, your program will not go beyond that for loop. Try this instead:
go func() {
//loop after given time
for range timerCh {
runJobs()
}
}()
This runs the for loop in its own goroutine, and runJobs executes every so often.

Display progress in a long loop in Unity3d

I'm building a space game, populated by thousands of star systems. Right now, there is a function that generates these thousands of systems. It takes about 5-10 seconds to generate, and I would like to have a simple progress bar updating the user in the progress.
After some searching I've decided to use a coroutine, however there is a little problem: when I call the function to generate star systems, the code that called the function keeps on going, reporting zero stars (because they haven't been generated yet).
I have a feeling coroutines are not an answer for me. Basically, I am simply looking for a way to simulate Application.DoEvents to update the GUI.
Here is a sample of my code:
// Start generating thousands of systems
StartCoroutine(GalacticMap.GenerateRandomGalaxy());
// after the universe is generated...
Game.myGalaxy.StarSystems = GalacticMap.myGalaxy.StarSystems;
// report back the number of systems
print(String.Format("Generated {0} systems", Game.myGalaxy.StarSystems.Count));
In the GalacticMap.GenerateRandomGalaxy() I am yielding back like this yield return new WaitForSeconds(0.1f); however, the effect is not what I am looking for: execution goes right through to print statement while the generation is still on going.
So how do I do this?
EDIT 1:
I've cooked up a sample code to illustrate my issue.
The caller code:
Debug.Log ("Start generating");
StartCoroutine(GenerateMeGalaxy());
Debug.Log ("Finish generating");
The code I call:
public static IEnumerator GenerateMeGalaxy ()
{
Debug.Log ("GenerateMeGalaxy start");
int numberOfStars = 1000;
for (int i=0;i<=numberOfStars;i++)
{
// generate galaxy
// display progress bar on screen
Debug.Monitor(String.Format("{0}% completed", ((i*100)/numberOfStars)),2);
yield return new WaitForSeconds(0.001f);
}
Debug.Log ("GenerateMeGalaxy end");
}
In the code above, Debug.Log displays string on the screen, on a new line so you can read previous logged strings of whatever. This is to debug code execution. Debug.Monitor has a fixed location on the screen and will overwrite previous string. This is where I display progress percentage. What I see after running this code is:
Start generating
GenerateMeGalaxy start
Finish generating
GenerateMeGalaxy end
What I want to see is:
Start generating
GenerateMeGalaxy start
GenerateMeGalaxy end
Finish generating
... and also the progress update is happening in between:
GenerateMeGalaxy start
Finish generating
I think you are misunderstanding how Unity coroutines work. What the yield return new WaitForSeconds(0.1f) is essentially saying is "go do other stuff and come back to me after 0.1 second". So naturally Unity will go ahead and do other stuff, including the print statement.
What you want is something along the lines of the following pattern:
IEnumerator GenerateRandomGalaxy()
{
int numSystems = 5000; // however many systems you want to generate
foreach(int i = 0; i < numSystems; i++)
{
// insert code here that generates system i
// insert code here that updates the progress bar
yield return null;
}
// put logic that prints out final number of systems generated here
}
What this does is generate a system, update the status bar, and then -- with the yield return null statement -- tell Unity to take over (so that it do other stuff, including rendering the updated progress bar) and come back and continue the loop as soon as possible.
Finally, the print statement only happens after the loop is finished, as you intend.

winforms: Reading from serialport and plotting real time data. Many errors/bugs

I'm trying to acquire data from an MCU, save them to a file and plot them. The code functions properly for some time, then just hangs randomly (sometimes after 1 sec, sometimes after 1 minute ...!). Also the serialport timeouts are not respected, i.e. I'm not receiving any timeout exceptions. I'm using an FTDI232RL chip. The only time I get a timeout exception is when I unplug it while the program is running.
Code:
private: System::Void START_Click(System::Object^ sender, System::EventArgs^ e) {
seconds=0;
minutes=0;
hours=0;
days=0;
t=0;
if((this->comboBox4->Text == String::Empty)||(this->textBox2->Text == String::Empty)||(this->textBox3->Text == String::Empty)){
this->textBox1->Text="please select port, save file directory and logging interval";
timer1->Enabled=false;
}
else{ // start assigning
w=Convert::ToDouble(this->textBox3->Text);
double q=fmod(w*1000,10);
if(q!=0){
MessageBox::Show("The logging interval must be a multiple of 0.01s");
}
else{
period=static_cast<int>(w*1000);
this->interval->Interval = period;
try{ // first make sure port isn't busy/open
if(!this->serialPort1->IsOpen){
// select the port whose name is in comboBox4 (select port)
this->serialPort1->PortName=this->comboBox4->Text;
//open the port
this->serialPort1->Open();
this->serialPort1->ReadTimeout = period+1;
this->serialPort1->WriteTimeout = period+1;
String^ name_ = this->serialPort1->PortName;
START=gcnew String("S");
this->textBox1->Text="Logging started";
timer1->Enabled=true;
interval->Enabled=true;
myStream=new ofstream(directory,ios::out);
*myStream<<"time(ms);ADC1;ADC2;ADC3;ADC4;ADC5;ADC6;ADC7;ADC8;";
*myStream<<endl;
chart1->Series["ADC1"]->Points->Clear();
chart1->Series["ADC2"]->Points->Clear();
chart1->Series["ADC3"]->Points->Clear();
chart1->Series["ADC4"]->Points->Clear();
chart1->Series["ADC5"]->Points->Clear();
chart1->Series["ADC6"]->Points->Clear();
chart1->Series["ADC7"]->Points->Clear();
chart1->Series["ADC8"]->Points->Clear();
backgroundWorker1->RunWorkerAsync();
}
else
{
this->textBox1->Text="Warning: port is busy or isn't open";
timer1->Enabled=false;
interval->Enabled=false;
}
}
catch(UnauthorizedAccessException^)
{
this->textBox1->Text="Unauthorized access";
timer1->Enabled=false;
interval->Enabled=false;
}
}
}
}
private: System::Void backgroundWorker1_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
while(!backgroundWorker1->CancellationPending){
if(backgroundWorker1->CancellationPending){
e->Cancel=true;
return;
}
t+=period;
if(t<10*period){
this->chart1->ChartAreas["ChartArea1"]->AxisX->Minimum=0;
this->chart1->ChartAreas["ChartArea1"]->AxisX->Maximum=t+10*period;
}
else {
this->chart1->ChartAreas["ChartArea1"]->AxisX->Minimum=t-10*period;
this->chart1->ChartAreas["ChartArea1"]->AxisX->Maximum=t+10*period;
}
*myStream<<t<<";";
for (int n=0;n<8;n++){
adc_array[n]= this->serialPort1->ReadByte();
}
Array::Copy(adc_array,ADC,8);
for(int f=0; f<8; f++){
*myStream<<ADC[f]<<";";
}
*myStream<<endl;
backgroundWorker1->ReportProgress(t);
}
}
private: System::Void backgroundWorker1_ProgressChanged(System::Object^ sender, System::ComponentModel::ProgressChangedEventArgs^ e) {
chart1->Series["ADC1"]->Points->AddXY(t,ADC[0]);
chart1->Series["ADC2"]->Points->AddXY(t,ADC[1]);
chart1->Series["ADC3"]->Points->AddXY(t,ADC[2]);
chart1->Series["ADC4"]->Points->AddXY(t,ADC[3]);
chart1->Series["ADC5"]->Points->AddXY(t,ADC[4]);
chart1->Series["ADC6"]->Points->AddXY(t,ADC[5]);
chart1->Series["ADC7"]->Points->AddXY(t,ADC[6]);
chart1->Series["ADC8"]->Points->AddXY(t,ADC[7]);
}
the user is allowed to define intervals in seconds for data acquisition (in the code this interval is w after conversion to double). In this case, the program sends a pulse to the MCU requesting a new data transmission. So far, I have been testing this for 1 second intervals (note, during each interval the MCU sends 8 frames, each representing an ADC). However, I need to get this to run for 10ms intervals at some point. Will this be possible? Any idea on how to solve the few problems I mentioned at the beginning?
Thanks in advance
UPDATE
Just to give you an idea of what's happening:
I commented the charting part and ran the program for about 5 minutes, with a reading interval of 1s. So I expected to get around 5x60=300 values in the output file, but I only got 39 (i.e. starting from 1s till 39s). The program was still running, but the data were not getting stored anymore.
Testing was done in release mode and not debug mode. In debug mode, setting a break point under serialport->readbyte(), does not reproduce the problem. My guess is it's a timing issue between program and MCU.
You are making several standard mistakes. First off, do NOT unplug the cable when the port is opened. Many USB emulators don't know how to deal with that, the FTDI driver is particularly notorious about that. They just make the port disappear while it is in use, this invariably gives code that uses the port a severe heart attack. An uncatchable exception is common.
Secondly, you are accessing properties of a class that is not thread-safe in a worker thread. The Chart control was made to be used only in a UI thread, accessing the ChartAreas property in a worker is going to buy you a lot of misery. Getting an InvalidOperationException is pretty typical when you violate threading requirements, it is however not consistently implemented. Nastiness includes random AccessViolationExceptions, corrupted data and deadlock.
Third, you are setting completely unrealistic goals. Pursuing an update every 10 milliseconds is pointless, the human eye cannot perceive that. Anything past 50 milliseconds just turns into a blur. Something that is taken advantage of when you watch a movie in the cinema, it displays at 24 frames per second. The failure mode for that is unpleasant as well, you'll eventually reach a point where you are pummeling the UI thread (or the Chart control) with more updates than it can process. The side effect is that the UI stops painting itself, it is too busy trying to keep up with the deluge of invoke requests. And the amount of memory your program consumes keeps building, the update queue grows without bounds. That does eventually end with an OOM exception, it takes a while to consume 2 jiggabytes however. You will need to prevent this from happening, you need to throttle the rate at which you invoke. A simple thread-safe counter can take care of that.
Forth, you are accessing the data you gather in more than one thread without taking care of thread-safety. The ADC array content is being changed by the worker while the UI thread is reading it. Various amounts of misery from that, bad data at a minimum. A simply workaround is to pass a copy of the data to the ReportProgress method. In general, address these kind of threading problems by using pull instead of push. Get rid of the fire-hose problem by having the UI thread pace the requests instead of trying to have the UI thread keep up.

Wait for WPF app to load after starting with Process.Start()

I have a WinForms app that starts a wpf process running using Process.Start. I would like to know when the WPF process is finished loading and I can access the process.MainWindowHandle property (its 0 before its completly loaded).
I tried polling but the handle is always 0. However, if I debug and wait (after Process.Start) for the WPF app to load - I then will get the correct handle.
Does not work:
int maxCount=100000;
int count=0;
do
{
wpfProcess.WaitForInputIdle();
_hWnd = net4ReconProcess.MainWindowHandle;
count++;
} while (_hWnd.ToInt32() == 0 || count > maxCount);
Add process.Refresh(); to the while loop.
Using a while loop for WaitForInputIdle is a non-sense because this call blocks the current thread until the other process has finished its initialization. After that, it always returns immediately. Please read the post WaitForInputIdle should really be called WaitForProcessStartupComplete – The Old New Thing
As raymond says it, it should really be called WaitForProcessStartupComplete.
You should use this code:
if (!wpfProcess.WaitForInputIdle(10000)) // 10 s timout
throw new ApplicationException("Process takes too much time to start");
_hWnd = net4ReconProcess.MainWindowHandle;

Resources