Using JavaScript for Robots!

Why use JavaScript?

After a night talking about high-level vs. low-level languages with an old roommate, I was recently convinced to give JavaScript a chance with robotics. I was initially resistant but my friend went on to explain the event-driven/multitasking nature of this high-level interpreted language. He showed me its simplicity, gave me examples of programming dynamically and the use of closures. I did a little research and found that it is actually quite interesting, refreshingly simple and powerful. Because of that, if I could figure out how to make this a reality, JavaScript could be an option to get people interfacing with robots who would otherwise quickly get lost in (or bored of) the tedium of C programming. Rather than scare them off why not get them using motors and sensor very quickly? Correction: very VERY quickly.

As it turns out it already was a reality, later the next day my old roommate posted this video of Rick Waldron at a NodeJS conference on my Facebook page: 

Between my buddy and this video, I was chomping at the bit to try this and rueing the moment I had decided to leave my machine at the office for a night. So, I spent the evening researching JavaScript for embedded systems on a teeny Android tablet, where I came across Gordon Williams' Espruino project. Espruino is a JavaScript interpreter for the Discovery board.

The next morning I had JavaScript up and rolling on the Discovery board and LEDs blinking away. Soon after, I was multitasking with more LEDs using PWM (on an external breadboard), an IR sensor for distance sensing, AND controlling a servo motor. They were each running in the their own task and I hadn't had to *compile* a single thing. For those of you who spend plenty of time writing, debugging, and compiling C - it can get a little old - especially when you are just trying to see how a new hardware component works. It's worse when you are just making minor adjustments to calculations or flow control. 

This time I was writing and changing code "live" in a serial terminal. Each line of code executing as I hit enter rather than executing after I compiled and re-flashed the board. It was the first time I had written JavaScript and I was I more than impressed with how quickly I was able to be productive. When you are hungry to just get your hardware working, this is like being handed a juicy steak and magical fairy dust. I literally laughed out loud then finished that laugh with a "YES!" in the middle of a crowded cafe.

So, here is your How-to.  Bare in mind most of this information is also nicely laid out for you on Gordon's page but I will walk you though my own usage.

What You'll Need

Toolchain or OpenOCD/STLink

See my STM32F4 (07VG) Discovery Toolchain for OSX tutorial if you want the full toolchain - if you are using Linux or Windows there are still plenty of links on that tutorial page to get you started. Gordon's site mentions only OpenOCD or STLink but I had already put in the effort for the entire toolchain so I have not tried just STLink for this. As Gordon explains:

"You don't need a toolchain at all to be able to flash Espruino (just OpenOCD/STLink or on windows, ST's flasher utility). It can take a while to get [a toolchain] working on some systems so it's worth skipping the install if you can."

Espruino 

Download this, start up OpenOCD and flash the espruino_1v27_stm32f4discovery.bin file to the board as you would a C file in my Toolchain tutorial. 

Note: the version number may be different (1v28 as of March 14th 2013).

A serial console. 

I use Screen, sometimes Minicom and even the python Miniterm lately. 

Registration (if you want to save your code so it will run after a power cycle)

The developer is asking a reasonable fee of $5 for the ability to save your code. If you want to just test this interpreter out, you can do so but you will have to re-program your board after each power cycle. See the Espruino Registration page for details and instructions. It's worth the $5. 

Start Writing Code!

Once your board is powered, flashed with Espruino and both USB cables plugged, start your serial console with a baud rate of 9600. If you are unsure of the name of your USB device or how to start Screen, see the "Setting Up Your Devices"  and "Serial Consoles" sections of my How-to 4. UART Serial Communication.

Toggle an On-Board LED

Copy and paste the following code into the serial console and hit enter: 

var tog1 = true

function toggle1() {

    tog1 = !tog1;

    digitalWrite(LED1, tog1);

}

green = setInterval(toggle1, 150)

You should see the green LED on the Discovery board start to blink. It's that simple. 

To stop the green LED from blinking, use:

clearInterval(green)

You can repeat this for the red, orange and blue easily. See my example code based on Gordon's tutorials attached here. I also include code for dimming four externally wired LEDs, and a small servo. I left out the IRSensor code because we were using custom sensors for this which are not available on the market, but its a simple read of the sensor's output using the analogRead() function.

Servo w/ Potentiometer

You can control a servo using a potentiometer with the following:

(I am using the Burton 3386T wired on a breadboard and connected to the Discovery's pin A1 with the servo connected to pin A2)

var potpin = A1

var servo_pin = A2

function servo_test() {

    digitalPulse(servo_pin, 1, 0.5+analogRead(potpin)*0.5);

}

testing_servo = setInterval(servo_test, 50)

Disable the servo with:

clearInterval(testing_servo)

Reading Potentiometer Values

If you want to just read the values coming from the potentiometer on pin A1 as you turn the knob:

var potpin = A1

function read_pot() {

    print(analogRead(potpin));

}

read_interval = setInterval(read_pot, 50)

and clear/stop the read with:

clearInterval(read_interval)

Dial-a-Direction with a Stepper 

You can see the stepper controlled by the Burton potentiometer in this video. In the background, there are two green and two red LEDs tied to Coils A and B of the motor - wired to the Easy Driver on those pins respectively. These allow you to see the coils firing. They turned out invaluable for trouble shooting in a case where a driver I had been using wasn't firing on one of Coil A's pins. I could have wasted hours trying to figure out why my code was not working if I had not had this visual feedback. 

Using the same potentiometer, you can "dial a direction" using a cheap stepper motor. This motor - a 12V bipolar stepper with a 7.5° step resolution - is around $7 at the RobotShop. I am using the SparkFun Easy Driver, powering a breadboard with 5v and the motor with 12V (connected to the M+ pin on the Easy Driver.) 

This is the code that allows me to use the potentiometer (wired the same as above on pin A1 of the Discovery Board) to change the motor's direction:

          var direction = A3;

     var steppin = A4;

function step_test() {

     digitalWrite(direction, digitalRead(potpin));

    var i = 8;

    if(i > 0){

        digitalWrite(steppin, 1);

        digitalWrite(steppin, 0);

        i--;

    }   

};

stepInterval = setInterval(step_test, 100)

As the potentiometer's value changes from 0 to 1 and vice versa, the stepper's direction will change. I have MS1 and MS2 pulled low on the Easy Driver (full-step mode.)

Clear the interval with:

        clearInterval(stepInterval)

Save()

When you are happy with your code and decide you like the interpreter, register your device and use save() to retain your program. The next time you power your board it will run the code normally.

Now imagine where you can take this....Steppers, LCDs, sensors, a Waldron Cat-Annoy-a-Tron, Micromouse.... 

REFERENCES

See the Espruino page for the documentation, more tutorials, a video of writing code within the serial console, etc. 

See the Easy Driver tutorial here for more information.