I made an EA and found that it was doing nothing. I put OnTick() into OnInit() and it called it once but only once each time I compiled.
So I made a brand new EA using the MQL wizard and created a variable int Cycle = 1;
Then in OnTick() I put only this:
Print("This is Cycle#", Cycle); Cycle++;
I expected it to print thousands of cycles till I stopped it but nothing happens!
Related
The following C program that uses the Lua API lua_next function to try and begin iterating LUA_ENVIRONINDEX table crashes in call to lua_next...
#include <lua5.1/lua.hpp>
int main() {
lua_State* L = luaL_newstate();
lua_pushnil(L);
lua_next(L, LUA_ENVIRONINDEX);
}
Any idea why?
The manual says that LUA_ENVIRONINDEX "gives the environment of the running C function". In your code, there is no "running C function" in the sense of Lua: main was not called from Lua.
Take lua.c. If you put your code in main, then there is a crash, as you have found out. If you put your code in pmain, which is called from Lua, then there is no crash.
I'm trying to write some code for the the ESP8266-12E that detects initial program load of a new version of the code. For this simplified version of my code (that still exhibits the behavior I'm seeing) there is no code in the loop() section.
I place my current version of the code in a const String pgmVersion. The code reads the EEPROM (actually flash for the ESP8266) and compares it to the current version of the code (pgmVersion). If they are different, then I know that I have a new version of the code. This is then followed by a write to EEPROM to save the current version pgmVersion so that the next time I boot this version will be the old version.
When I run the code with only the for loop for the eeprom read, I can see that the saved version is different than the current version (and can also see when they are the same). This seems to work properly.
However, when I run the full code that includes the write to eeprom, the read for loop always indicates that the saved version matches the current version and does not execute the eeprom write for loop. This happens consistently even when I run with a new value for the current version. This is simply baffling to me. I can remove power and then power up again and the new version data has been saved to eeprom so it seems that it is really being written.
Can anyone see what is wrong with my code or explain why the eeprom seems to be written without going through my eeprom write for loop? I've read lots of posts and online documentation and still can't figure this out.
Jim
#include <EEPROM.h>
const String pgmVersion = "00.04";
void setup() {
Serial.begin(115200);
EEPROM.begin(6);
delay(500);
char eepData;
char pgmData;
bool pgmMatch = true;
for (unsigned int i = 0; i < pgmVersion.length(); i++)
{
eepData = char(EEPROM.read(i));
pgmData = pgmVersion.charAt(i);
Serial.print("eepData = ");
Serial.println(eepData);
Serial.print("pgmVersion[i] = ");
Serial.println(pgmData);
if (eepData == pgmData)
{
Serial.println("eepData matches pgmData at index " + String(i));
} else
{
Serial.println("eepData does NOT match pgmData at index " + String(i));
pgmMatch = false;
}
}
if (!pgmMatch)
{
Serial.println("Writing EEPROM");
for (unsigned int i = 0; i < pgmVersion.length(); i++)
{
pgmData = pgmVersion.charAt(i);
EEPROM.write(i,pgmData);
delay(10);
}
if (EEPROM.commit())
{
Serial.println("EEPROM successfully committed");
} else
{
Serial.println("ERROR! EEPROM commit failed");
}
}
}
void loop() {
// put your main code here, to run repeatedly:
}
Ok, I've found out what's going on. The above code fails to work correctly as described in the original post when running under VS Code with PlatformIO. But works as it should when running under the Arduino IDE. (I did not originally post the #include <arduino.h> that is needed in that environment - my mistake!).
When running the code with the write loop included, it looks like the eeprom write gets executed before the write loop itself as when the saved pgm data and new pgm data are known to be different the comparison code says they are the same.
I tried just commenting out the line with the eeprom write for a case when the saved pgm data and new pgm data are known to be different. This resulted in the write loop being entered as it should (meaning it the code detected the saved and new pgm data were not the same).
So it looks like the VS Code version with PlatformIO reorders the code by hoisting the eeprom write somewhere or something with that effect. If that is actually the case, what is needed is a fix to some piece of platform code or some sort of barrier instruction to prevent this from happening. This is unfortunate as I do appreciate the extra function available in the VS Code / PlatformIO environment.
In short, while the code seems to work fine, I'm curious of whether less hacky approaches (than the ones I came up so far) with exist.
Suppose you create a coroutine via lua_newthread, and later suspend it from a cclocure via lua_yield. Your program takes a lap around non-Lua code, and it is now time to resume the coroutine via lua_resume, but - suppose the arguments that Lua code provided are extremely illegal, and we should give it an error to indicate that.
As you might know, you can't call lua_error (or luaL_error) on a state unless it's currently running. So the state must resume but immediately get hit by an error.
In 5.3 you would use lua_yieldk, provide a continuation function, and call lua_error or luaL_error in there. Et voilĂ .
But, alas - LuaJIT does not implement lua_yieldk, so what options are we left to?
A single-use hook
Suppose the error message is stored in a char error_text[256]. We could then bind a per-instruction hook immediately before resuming,
lua_sethook(L, throw_error, LUA_MASKCOUNT, 1);
int result = lua_resume(L, NULL, ret_count);
and then unbind the hook and throw an error in there
void throw_error(lua_State *L, lua_Debug *ar) {
lua_sethook(L, throw_error, 0, 0);
if (error_text == nullptr) return; // trust no one, especially yourself
luaL_error(L, "%s", error_text);
}
Should string cleanup be required, you would of course prefer to concatenate error_text to luaL_where(L, 1) yourself before calling _error, as both lua_error and luaL_error do a long jump and thus will be the last thing your function does.
A Lua-side wrapper
Suppose you decide to pull a somewhat node.js-like on this and have your C code resume with an error, result pair so that you could have a wrapper function like so
function some(arg)
local e, r = some_native(arg)
if (e) then
error(e)
else
return r
end
end
Or maybe refactor your API entirely so that errors are also handled using the same pattern, but that's a story for another day.
Option 1 seems less hacky of two.
Option 2 seems less likely to cause any trouble.
I can't help the feeling that there's a much better way of doing this that I'm overlooking (after all, lua_yieldk is a relatively recent addition).
I am wondering how to continue using stdin in D after the program has read an unsuitable value. (for example, letters when it was expecting an int)
I wrote this to test it:
import std.stdio;
void main()
{
int a;
for(;;){
try{
stdin.readf(" %s", a);
break;
}catch(Exception e){
writeln(e);
writeln("Please enter a number.");
}
}
writeln(a);
}
After entering incorrect values such as 'b', the program would print out the message indefinitly. I also examined the exception which indicated that it was trying to read the same characters again, so I made a version like this:
import std.stdio;
void main()
{
int a;
for(;;){
try{
stdin.readf(" %s", a);
break;
}catch(Exception e){
writeln(e);
writeln("Please enter a number.");
char c;
readf("%c", c);
}
}
writeln(a);
}
Which still threw an exception when trying to read a, but not c. I also tried using stdin.clearerr(), which had no effect. Does anyone know how to solve this? Thanks.
My recommendation: don't use readf. It is so bad. Everyone goes to it at first since it is in the stdlib (and has been since 1979 lol, well scanf has... and imo i think scanf is better than readf! but i digress), and almost everyone has trouble with it. It is really picky about formats and whitespace consumption when it goes right, and when it goes wrong, it gives crappy error messages and leaves the input stream in an indeterminate state. And, on top of that, is still really limited in what data types it can actually read in and is horribly user-unfriendly, not even allowing things like working backspacing on most systems!
Slightly less bad than readf is to use readln then strip and to!int it once you check the line and give errors. Something like this:
import std.stdio;
import std.string; // for strip, cuts off whitespace
import std.algorithm.searching; // for all
import std.ascii; // for isAscii
import std.conv; // for to, does string to other type conversions
int readInt() {
for(;;) {
string line = stdin.readln();
line = line.strip();
if(all!isDigit(line))
return to!int(line);
else
writeln("Please enter a number");
}
assert(0);
}
void main()
{
int a = readInt();
writeln(a);
}
I know that's a lot of import spam (and for a bunch of individual trivial functions too), and readln still sucks for the end user, but this little function is going to be so much nicer on your users and on yourself than trying to use readf. It will consistently consume one line at a time and give a nice message. Moreover, the same pattern can be extended to any other type of validation you need, and the call to readln can be replaced by a call to a more user-friendly function that allows editing and history and stuff later if you decide to go down that route.
If you must use readf anyway though, easiest way to make things sane again in your catch block is still to just call readln and discard its result. So then it just skips the whole line containing the error, allowing your user to start fresh. That'd also drop if they were doing "1 2" and wanted two ints to be read at once... but meh, I'd rather start them fresh anyway than try to pick up an errored line half way through.
I have a small dart script which I intend to use in the following way:
CanvasElement canvas;
void main() {
canvas = querySelector('#canvas');
querySelector('#start-button').onClick.listen((_) => work());
}
void work() {
var state; // some state of the computation
for (int i = 0; i < /*big number*/; i++) {
// do some long computation
render(state); // display intermediate result visualisation on canvas
}
}
void render(var state) {
canvas.context2D.... // draw on canvas based on state
}
that is listen for click on a button and on that click execute some long computation and from that computation display some intermediate results on the canvas live as the computation progresses.
However, this does not work - the canvas is updated only once after the whole computation completes.
Why is that? How should I arrange my code to work in a live, responsive way?
One of solutions would be to put parts of your long computation into dart's event loop, i.e. queuing computation by waiting for a future it immediately return.
Please, see sample on DartPad.
But if you have lots of heavy computations, I think it would be better to start a new isolate and communicate with it about it's state.
Update
Here is almost, not exactly the same, work function, rewritten without using await, maybe it would be a bit clearer how it works:
for (int i = 0; i < 200; i++) {
new Future(()=>compute(i)).then((double result)=>render(i+result*50));
}
Here, we are actually creating 200 futures, queuing them into event loop (Future constructor does that), and registering a personal callback for each one.