The escape sequence ‘//$’ causes the current line to be ignored by the JavaScript interpreter, but the remainder of the line is passed unaltered to the C++ compiler. Suppose for example, you need to include a servo library in your C++ application. This may be achieved by adding the line ‘//$#include <servo.h>’ at the start of your sketch. JavaScript will treat the line as a single line comment, but the JavaScript to C++ code conversion recognises these three characters as an escape sequence and removes them. The same technique may be used to hide any subsequent lines of code which would otherwise generate errors in the JavaScript-based simulator.
Of course, this approach is not a magic bullet, as the fact that these lines are hidden as comments to JavaScript, means that it also can’t simulate them!
The following JavaScript example, which is available from the Extras pull-down menu, reads the position of a potentiometer, which in turn controls the angular position of a hobby servo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Potentiometer and Servo //$#include <Servo.h> // Load servo library //$Servo myServo; // Create servo object function setup() { //$ myServo.attach(Y0); // Attach servo to pin Y0 } function loop() { ain(AD0); // Read potentiometer connected to Analogue input AD0 //$scanValue = map(scanValue, 0, 1023, 0, 180); // Scale ADC value to use with servo (0 – 180 degrees) //$myServo.write(scanValue); // Write to servo // delay(2); // Optional 2-40 ms delay } |
Listing 1. Potentiometer and Servo (Source: Extras > PotentiometerServo).
Notice that the value read from analogue input AD0 is stored in the global scanValue variable and is in the range 0-1023, based on the 10-bit ADC resolution. This then needs to be converted to an angular position, in the range 0-180 degrees, which is achieved by the Arduino map command.
Behind the scenes a hobby servo is driven by a repeating pulse waveform, and quite small differences in the pulse width are used to control the angular position of the servo. These devices are often used in remote control applications, hence they are alternatively known as RC servos. A typical servo pulse repeats every 20 ms (hence 50 times per second) with the pulse width varying between 1-2 ms. The internal electronics in the servo reads the pulse width and drives the output shaft to the required position via a step-down gearbox, with potentiometer-based position measurement.
A potential issue when dealing with connected hardware, such as a servo in this case, is the high operating speed of the microcontroller, compared with the connected device. The speed of the scan loop is several orders of magnitude faster than than the 20 ms refresh rate of the servo electronics. In addition, the 20 ms refresh rate of the servo pulse is much faster than the physical rotation rate of the output shaft of the servo, due to the use of a step down gearbox.
The final delay in the above example, although commented out by default, gives the option of slowing down the scan loop to suit the servo, or any hardware connected to the servo. (A better alternative might be to use a regular and generated ‘event’ to drive the updating process for any connected devices, which would then allow the scan loop to run at full speed.)
Escape sequences are ideal where specialist hardware needs to be connected, particularly if additional commands or libraries are required. This has already been seen with the hobby servo. A second example would be an I2C-based LCD display, as shown below.
The following JavaScript example, which is also available from the Extras pull-down menu, implements an up/down counter, with the running count sent to an LCD display for debugging purposes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
// Up-Down Counter with LCD Output // – counts 5 pulses on Input X0 with switch debounce // The following 6 lines are required for Grove LCD display //$#include <Wire.h> //$#include “rgb_lcd.h” //$rgb_lcd lcd; //$const int colorR = 255; //$const int colorG = 0; //$const int colorB = 0; /* Connections: Count up input – switch connected to input X0 Count down input – switch connected to input X1 Clear input – switch connected to input X2 Preset input – switch connected to input X3 Lower Q output – LED connected to output Y0 Upper Q output – LED connected to output Y1 */ ctr = new Counter(10); // Counts up or down in range 0-10, starting at zero TIMER0 = new Timer(); TIMER1 = new Timer(); function setup() { // The following 4 lines initialise the Grove LCD //$ lcd.begin(16, 2); //$ lcd.setRGB(colorR, colorG, colorB); //$ lcd.print(“Up/Down Counter”); // Display message on LCD. //$ delay(1000); } function loop() { din(X0); // Read digital input X0 timerOn(TIMER0, 10); // 10 ms switch debounce delay ctr.countUp(); // Count up din(X1); // Read digital input X1 timerOn(TIMER1, 10); // 10 ms switch debounce delay ctr.countDown(); // Count down din(X2); // Read digital input X1 ctr.clear(); // Clear counter (counter at lower limit) din(X3); // Read digital input X2 ctr.preset(); // Preset counter (counter at upper limit) ctr.lowerQ(); // Display Count Down output on Y0 dout(Y0); ctr.upperQ(); // Display Count Up output on Y1 dout(Y1); //$lcd.setCursor(0, 1); //$lcd.print(“Count: “); //$lcd.print(ctr.value()); //$lcd.print(” “); } |
Listing 2. Up-Down Counter with LCD Output (Source: Extras > CountUpDownLCD).
It would also be possible to insert debugging commands by using console.log commands in JavaScript. These are automatically converted to the equivalent Serial.println commands when code is translated for use with the Arduino.
There are many more applications for LCD displays than just printing debugging messages, of course!