Recent

Author Topic: How to run script on Lazarus  (Read 2109 times)

microguy

  • New Member
  • *
  • Posts: 49
How to run script on Lazarus
« on: April 24, 2021, 09:32:08 am »
I am running Lazarus with Arduino. I am control LEDs and Servos with 40 buttons on Lazarus. They are working just fine. Now I want to know if there is a way we can use the script or something that we can tell which buttons to turn on or off LED or Servos. I am doing a lot of lights and servos for animations. I would like to have several scripts that I can select to run which it will tell which buttons to turn on or off and servos to move right or left or up or down.  Is there a sample where I can add script or something to command which buttons to turn on or off LEDs etc..

dseligo

  • Hero Member
  • *****
  • Posts: 651
Re: How to run script on Lazarus
« Reply #1 on: April 24, 2021, 12:00:13 pm »
Do you program Arduino controller in Arduino app and connect to it through serial connection?
Or do you program Arduino controller with Lazarus and cross compile it to AVR?

I'll assume first one is the case. Lets assume you have ButtonA and ButtonB. When you press ButtonA, Lazarus sends command to Arduino and turn on LED01. When you press ButtonB, Lazarus sends command to Arduino and move Servo01.
And now you would like to configure that e.g. ButtonA send command to Arduino and move Servo01.
Could you show details how this look like?

I would suggest you different ini files or SQlite database where you would store different configurations and according to them, map button press to action.

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 913
  • Professional amateur ;-P
Re: How to run script on Lazarus
« Reply #2 on: April 24, 2021, 12:51:46 pm »
Hey microguy,

Let me see if I get this right.

You want a way to customize the actions performed by the Arduino when you press a button.
And, at the moment, what you have is a set of buttons that are connected to actions and all is hard coded in the app.

The way you solve this is not easy. Not easy to explain AND not easy to implement.

But here it goes...

First of all you need to create the complete set of procedures with all the SINGLE actions that you want to script.

So something like:
Code: Pascal  [Select][+][-]
  1. procedure LED(const Number; const On: Boolean = True);
  2.  
  3. procedure Servo(const Number; const Position: Integer);
  4.  

And after that you need to create your OWN interpreter of a simple scripting language.

On some kind of UI you setup a script editor for each button.
For each button, you store a script and when the button is pressed you run that script.

A script would be something like this:
Code: Text  [Select][+][-]
  1. LED0 ON
  2. WAIT 3
  3. LED1 OFF
  4. SERVO1 1000
  5. SERVO0 250

Now when you're parsing your script and encounter LED0 ON you call LED(0, True)
When you encounter SERVO0 1000 you call SERVO(0, 1000)
When you encounter WAIT 3 you call Sleep(3000)

When you get all this implemented and you feel it's solid you can then try to implement cycles.
After a while you'll miss them ;)

Am I making any sense?

Cheers,
Gus
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.10 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.10 64b Dark Theme
http://github.com/gcarreno

Gustavo 'Gus' Carreno

  • Hero Member
  • *****
  • Posts: 913
  • Professional amateur ;-P
Re: How to run script on Lazarus
« Reply #3 on: April 24, 2021, 12:55:52 pm »
Hey microguy,

One last thing.

My suggestion of doing your own little scripting language comes from the fact that it would be overkill to embed any full blown scripting engine for such a simple usage.

But if you feel curious, there are integrations with Lua, just Google "Lua for Pascal OR Lazarus" and you'll get some good hits.

And there's the Pascal Script that is hosted on GitHub: https://github.com/remobjects/pascalscript.

I'm sure that other people will suggest more.

Cheers,
Gus
« Last Edit: April 24, 2021, 01:01:15 pm by Gustavo 'Gus' Carreno »
Lazarus 2.3.0(trunk) FPC 3.3.1(trunk) Ubuntu 21.10 64b Dark Theme
Lazarus 2.0.12(stable) FPC 3.2.2(stable) Ubuntu 21.10 64b Dark Theme
http://github.com/gcarreno

microguy

  • New Member
  • *
  • Posts: 49
Re: How to run script on Lazarus
« Reply #4 on: April 25, 2021, 06:59:27 am »
dseligo,

It is the first one. I program the Arduino controller in Arduino app and connect to Lit through serial connection. When I press Button for LED01, Lazarus sends command to Arduino and turn on on LED01 same as botton for servo01, Lazarus sends command to Arduino and Servo01 move.

What I am trying to figure out how to record all the buttons in order. While I am on Lazaurus with Arduino. I was be able to do manual but I was hope to some kind of automatic or record to run it. I was not sure how to do this. I thought we could run script or maybe it is wrong word. Something that we can click name of list which we can create a small sub program that tell all the buttons and which one comes first like buttons10 to move sevos then button14 turn on LED14 and wait for next button16 servo16 finish moved then button14 LED goes off etc. 

I hope you understand what I am looking for. My english is not that great.

dseligo

  • Hero Member
  • *****
  • Posts: 651
Re: How to run script on Lazarus
« Reply #5 on: April 25, 2021, 10:12:35 am »
Did you look at Gus' proposal? It looks very good to me.
If you don't want your 'script' to be external, you could write it in array in your program.

Please post some code, button's onclick methods and related functions. It will be easier to us to offer you solution.

Does Arduino also sends data back to your program? How does this look like?

microguy

  • New Member
  • *
  • Posts: 49
Re: How to run script on Lazarus
« Reply #6 on: April 26, 2021, 03:01:15 am »
Yeah I read Gus' comment about Lau.  I am trying to understand how does it works or how to use it. I am lost and don't know where to start.

I was thinking to put the numbers on each buttons.  Have some kind of list or table that we can put the number (which buttons) to run first and how long.. then next step... 

Right now just send the code to Arduino. I haven't add the code to have Arduino send the data back to Lazarus yet.  I might do that for Sensors.

Here is my code below.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   ser := TBlockSerial.Create;
  4.   Sleep(25); //250
  5.   ser.Connect('COM5'); // write here Arduino COM port number
  6.   Sleep(25);  //250
  7.   ser.Config(9600, 8, 'N', SB1, False, False);
  8.   ser.RTS := false; // comment this if needed
  9.   ser.DTR := false; // comment this if needed
  10. end;
  11.  
  12. procedure TForm1.Button1Click(Sender: TObject);
  13. begin
  14.   //LED01
  15.   Ser.SendString('off1');
  16.   Shape1.brush.Color:=clRed;
  17. end;
  18.  
  19. procedure TForm1.Button2Click(Sender: TObject);
  20. begin
  21.   Ser.SendString('on1');
  22.   Shape1.brush.Color:=clGreen;
  23. end;    
  24.  
  25. procedure TForm1.Button9Click(Sender: TObject);
  26. begin
  27.   //LED 05
  28.   Ser.SendString('off5');
  29.   Shape5.brush.Color:=clRed;
  30. end;
  31.  
  32. procedure TForm1.Button10Click(Sender: TObject);
  33. begin
  34.   //LED 05
  35.   Ser.SendString('on5');
  36.   Shape5.brush.Color:=clGreen;
  37. end;
  38.  
  39. procedure TForm1.Button11Click(Sender: TObject);
  40. begin
  41.   //LED 06
  42.   Ser.SendString('off6');
  43.   Shape6.brush.Color:=clRed;
  44. end;
  45.  
  46. procedure TForm1.Button12Click(Sender: TObject);
  47. begin
  48.   //LED 06
  49.   Ser.SendString('on6');
  50.   Shape6.brush.Color:=clGreen;
  51. end;
  52.  
  53. procedure TForm1.Button13Click(Sender: TObject);
  54. begin
  55.   //SW1 Close   turnout 1
  56.   Ser.SendString('sw1close');
  57. end;
  58.  
  59. procedure TForm1.Button14Click(Sender: TObject);
  60. begin
  61.   //SW1 throw   turnout 1
  62.   Ser.SendString('sw1throw');
  63. end;
  64.  
  65. procedure TForm1.Button15Click(Sender: TObject);
  66. begin
  67.   //sw2 Close   turnout 2
  68.   Ser.SendString('sw2close');
  69. end;
  70.  
  71. procedure TForm1.Button16Click(Sender: TObject);
  72. begin
  73.   //SW2 throw    turnout 2
  74.   Ser.SendString('sw2throw');
  75. end;
  76.  
  77.  


dseligo

  • Hero Member
  • *****
  • Posts: 651
Re: How to run script on Lazarus
« Reply #7 on: April 26, 2021, 11:09:09 am »
Make method which executes command:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.ExecuteCommand(sCommand:String);
  2. var s:String;
  3.     i:Longint;
  4. begin
  5.   // Memo1.Append(sCommand); // you can uncomment this to test your scripts
  6.   If Pos('sleep',LowerCase(Trim(sCommand)))=1 then
  7.   begin
  8.     s:=Copy(sCommand,6,Length(sCommand));
  9.     i:=StrToIntDef(s,0);
  10.     ShapeSleep.Visible:=True; // make some shape to indicate that program is waiting
  11.     Application.ProcessMessages;
  12.     Sleep(i);
  13.     ShapeSleep.Visible:=False;
  14.   end
  15.   else
  16.   begin
  17.     case sCommand of
  18.     'off1':Shape1.brush.Color:=clRed;
  19.     'on1' :Shape1.brush.Color:=clGreen;
  20.     'off5':Shape5.brush.Color:=clRed;
  21.     'on5' :Shape5.brush.Color:=clGreen;
  22.     'off6':Shape6.brush.Color:=clRed;
  23.     'on6' :Shape6.brush.Color:=clGreen;
  24.     'sw1close':;
  25.     'sw1throw':;
  26.     'sw2close':;
  27.     'sw2throw':;
  28.     otherwise
  29.       // unknown command
  30.     end;
  31.     Ser.SendString(sCommand);
  32.   end;
  33.   Application.ProcessMessages;
  34. end;

Now you can use this function to execute some script which you code in an array, e.g.:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.ExecuteArrayScript(iRepeatCount:Integer);
  2. const script1:array of string =
  3.         ('on1','off5','off6','sleep 3000','off1','on6','on5','sleep2000','off6','off5','sleep2000');
  4. var iRepeat,iCommand:Integer;
  5. begin
  6.   iRepeat:=1;
  7.   repeat
  8.     For iCommand:=0 to High(script1) do
  9.       ExecuteCommand(script1[iCommand]);
  10.     inc(iRepeat);
  11.   until iRepeat>iRepeatCount;
  12. end;

You can call this with:
Code: Pascal  [Select][+][-]
  1. ExecuteArrayScript(3);

Or you can execute script from file with this:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.ExecuteFileScript(sScriptName:String; iRepeatCount:Integer);
  2. var f:TextFile;
  3.     s:String;
  4.     iRepeat:Integer;
  5. begin
  6.   If not FileExists(sScriptName) then
  7.   begin
  8.     MessageDlg('Script "'+sScriptName+'" doesn''t exists.',mtError,[mbOK],0);
  9.     Exit;
  10.   end;
  11.  
  12.   AssignFile(f,sScriptName);
  13.   try
  14.     iRepeat:=1;
  15.     repeat
  16.       Reset(f);
  17.       While not Eof(f) do
  18.       begin
  19.         ReadLn(f,s);
  20.         ExecuteCommand(s);
  21.       end;
  22.       inc(iRepeat);
  23.     until iRepeat>iRepeatCount;
  24.   finally
  25.     CloseFile(f);
  26.   end;
  27. end;

You can call this like this:
Code: Pascal  [Select][+][-]
  1. ExecuteFileScript('test.script', 3);

Example of file 'test.script':
Code: Text  [Select][+][-]
  1. on1
  2. off5
  3. off6
  4. sleep 3000
  5. off1
  6. on6
  7. on5
  8. sleep2000
  9. off6
  10. off5
  11. sleep2000

You can also change your button's OnClick events, e.g. Button1Click to ExecuteCommand('off1');
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   //LED01
  4.   ExecuteCommand('off1');
  5. end;
« Last Edit: April 26, 2021, 11:12:08 am by dseligo »

 

TinyPortal © 2005-2018