Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
blocks:advanced_scripting:example1 [2019-02-12 21:21]
admin
blocks:advanced_scripting:example1 [2019-03-06 15:51] (current)
admin Foxed typo in initComms
Line 1: Line 1:
 ====== User Script Case Study ====== ====== User Script Case Study ======
  
-Here's a rather interesting case study that shows how a user script can be utilized as a bridge between a position tracking sensor and the scroll position of a scroll block. The project involves a 5 meter long wall with a printed "wallpaper". In front of this wall hangs a vertically oriented display. This display run on a track, allowing it to be moved back and forth along the wall. The display shows the section of the wall it's placed in front of, and allows a visitor to interact with the content at that position. +Here's a rather interesting case study that shows how a user script can be utilized as a bridge between a position tracking sensor and the scroll position of a scroll block. The project involves a 5 meter long wall with a printed "wallpaper". In front of this wall hangs a vertically oriented display. This display runs on a track, allowing it to slide along the wall. The content of the display scrolls to shows the section of the wall it's placed in front of, allowing a visitor to interact with the content at that position. 
  
 {{ :blocks:advanced_scripting:leuzesensorwall.jpg?nolink |}} {{ :blocks:advanced_scripting:leuzesensorwall.jpg?nolink |}}
  
-To interact with another part of the wall, the visitor can push the screen to the desired position. Hence, the screen act as an interactive window or looking glass onto the static image behind it. The position tracker reads a barcode along the track, sending the position readout to Blocks. Blocks translates this to a scroll position, applying the result to the Display Spot connected to the display.+To interact with another part of the wall, the visitor can push the screen to the desired position. Hence, the screen acts as an interactive window or looking glass for the static image behind it. The position tracker reads a barcode along the track, sending the position readout to Blocks. Blocks translates this to a scroll position, applying the result to the Display Spot connected to the display. By scrolling the content in the opposite direction of the display's movement, the image appears stationary in relation to the wall.
  
-The barcode reader is a rather small device, mounted behind one of the brackets used to attach the display on the track. There are many types of position sensors that work in similar ways. This one – a [[https://leuze.com/en/deutschland/produkte/messende_sensoren/optische_abstandssensoren/odsl_6/selector.php|Leuze ODSL 8]] – reads the position with millimeter accuracy from a barcode strip taped to the track.+The barcode reader is a rather small device, mounted behind one of the brackets used to attach the display to the track. There are many types of position sensors operating in various ways. This one – a [[https://leuze.com/en/deutschland/produkte/messende_sensoren/optische_abstandssensoren/odsl_6/selector.php|Leuze ODSL 8]] – reads the position with millimeter accuracy from a barcode strip affixed to the track.
  
 {{:blocks:advanced_scripting:leuze-odsl-8.jpg?nolink |}}  {{:blocks:advanced_scripting:leuze-odsl-8.jpg?nolink |}} 
Line 13: Line 13:
  
  
-The sensor uses a laser to read the barcode strip, streaming the resulting data over a serial (RS-232connection, which in its turn connects to Blocks through a [[blocks:drivers:serial|MOXA nPort serial-to-ethernet adapter]]. The MOXA nPort is added to Blocks under Manage as a Network TCP device. To save some time in getting the complete solution working, no driver was written for this device. Instead, the code that received data from the sensor was rolled into the user script. Another option could have been to write a driver that published a property corresponding to the most recent position readout. That would have simplified the user script at the expense of writing //both// a driver and a user script.+The sensor uses a laser to read the barcode strip, streaming the resulting data over a serial RS-232 connection, which in its turn connects to Blocks through a [[blocks:drivers:serial|MOXA nPort serial-to-ethernet adapter]]. The MOXA nPort is added to Blocks under //Manage// as a //Network TCP// device. 
 + 
 +To save some time in getting the complete solution working, no driver was written for this device. Instead, the code that received data from the sensor was rolled into the user script. Another option could have been to write a driver that published a property corresponding to the most recent position readout. That would have simplified the user script at the expense of writing //both// a driver and a user script.
  
 Here's the complete script used to read the position data, scale it as appropriate and apply the result to the scroll position of the display spot.  Here's the complete script used to read the position data, scale it as appropriate and apply the result to the scroll position of the display spot. 
Line 60: Line 62:
   }   }
  
-  /** Hook up event handler to receive data form reader. Get comms going.+  /** What needs to be one when we connect (or re-connect) to the reader device.
   */   */
   doWhenConnected() {   doWhenConnected() {
Line 71: Line 73:
   */   */
   initComms() {   initComms() {
-    if (this.networkPort.connected) {}+    if (this.networkPort.connected) {
       this.networkPort.sendText('\x02M+', '\r\n');       this.networkPort.sendText('\x02M+', '\r\n');
       this.networkPort.sendText('\x02MMT0100', '\r\n');       this.networkPort.sendText('\x02MMT0100', '\r\n');
Line 124: Line 126:
   * The script must be saved in a file named LeuzeScript.ts in the script/user directory of the Blocks root.    * The script must be saved in a file named LeuzeScript.ts in the script/user directory of the Blocks root. 
   * It compiles to a file named LeuzeScript.js, in that same directory. This is handled automatically by the [[blocks:drivers:tools|editor]] used to create and edit scripts.   * It compiles to a file named LeuzeScript.js, in that same directory. This is handled automatically by the [[blocks:drivers:tools|editor]] used to create and edit scripts.
 +  * The script doesn't expose any externally visible properties or functions, as all it's intended to do is handled internally.
   * The class name must match the filename (minus the .ts/.js file extension).   * The class name must match the filename (minus the .ts/.js file extension).
-  * Several console.log calls were added during the development to inspect the behavior along the way. Those were commented out once the script was working properly.  +  * Several //console.log// calls were added during the development to inspect the behavior along the way. Those were commented out once the script was working properly.  
-  * It must have a constructor that takes a single ScriptEnv parameter and calls super with this parameter.+  * The script must have a constructor that takes a single ScriptEnv parameter and calls super with this parameter.
   * It uses the imported Network system object to obtain a reference to the network device named 'Leuze over Moxa', which has been added with that name under //Manage, Network TCP/UDP// in Blocks, with its IP address and port number set to the ones assigned to the MOXA interface.   * It uses the imported Network system object to obtain a reference to the network device named 'Leuze over Moxa', which has been added with that name under //Manage, Network TCP/UDP// in Blocks, with its IP address and port number set to the ones assigned to the MOXA interface.
-  * It subscribes to the textReceived event in order to read the position information from the sensor.+  * It subscribes to the //textReceived// event in order to read the position information from the sensor.
   * When data is received, the payload in //message.text// is passed to the //dataReceived// function. This is done using an [[https://basarat.gitbooks.io/typescript/docs/arrow-functions.html|arrow function]], also known as a lambda function.   * When data is received, the payload in //message.text// is passed to the //dataReceived// function. This is done using an [[https://basarat.gitbooks.io/typescript/docs/arrow-functions.html|arrow function]], also known as a lambda function.
   * The sensor needs to be told to start streaming data. This is done by the //initComms// function.   * The sensor needs to be told to start streaming data. This is done by the //initComms// function.
Line 136: Line 139:
 ==== Transforming the sensor data to a scroll position ==== ==== Transforming the sensor data to a scroll position ====
  
-The part that binds the data received from the sensor to the scroll position of the spot is all found in the dataReceived function. It accepts the raw sensor data, which is a string that begins with an ASCII STX character, followed by a number of digits indicating the scroll position. The STX character is of no interest, so it is skipped over. The remainder is parsed to a number. Occasionally, the sensor may send other data rather than a numeric position. Hence, we need to verify that the type of the resulting data is indeed a number. We also compare the numeric value to the previous value received, and ignore any repetitions.+The code that binds the data received from the sensor to the scroll position of the spot is found in the //dataReceived// function. It accepts the raw sensor data, which is a string that begins with an ASCII STX character, followed by a number of digits indicating the scroll position. The STX character is of no interest, so it is skipped over. The remainder is parsed to a number. Occasionally, the sensor may send other data rather than a numeric position. Hence, we need to verify that the type of the resulting data is indeed a number. We also compare the numeric value to the previous value received, and ignore any repetitions.
  
 Finally, the readout from the sensor is scaled to a normalized value (0...1), the Display Spot is obtained from the Spot system object, and scrolled to desired position. Finally, the readout from the sensor is scaled to a normalized value (0...1), the Display Spot is obtained from the Spot system object, and scrolled to desired position.