Your Arduino C program can interact with Bitlash using the functions documented here. Of course, in the tiny and open world of Arduino most everything is visible globally. So feel free to dive in and call what you need. The entry points documented here are intended to be reasonably well hardened for third party use.
You must call this first, normally from setup(), to initialize Bitlash and set the serial port baud rate.
You must call runBitlash() from your loop() function to make Bitlash go. The more frequently you call runBitlash(), the more smoothly foreground and background activity will run. If you don't call runBitlash(), nothing will happen.
This is the minimum possible integration, and in fact it is the bones of the code that you will see at the bottom of bitlashdemo.pde:
void setup(void) { initBitlash(57600); } void loop(void) { runBitlash(); // YourOtherCodeHere(); }
A simple way to control Bitlash is to use the doCommand() function to execute commands from your code. Your code can call doCommand() to make Bitlash “do stuff” – anything you can type, actually, up to the buffer size limit. Here's a dumb example that leads up to our next big case study: this code spends a lot of energy looking for the precise millisecond to beep at the top of the hour:
void setup(void) {
initBitlash(57600);
}
void loop(void) {
runBitlash();
// beep at the top of the elapsed hour
if (millis() % (60*60*1000) == 0) doCommand("beep(11,440,1000)")
}
Lots of ways to do this better (read on for one example), but the takeaway point is that your C code can drive Bitlash.
Bitlash has 26 variables named a through z. These are 32-bit signed integer values. Your code can read and write these values using a few simple functions. This allows your C code to control code running in Bitlash, and vice versa.
You refer to a variable using an integer index in the range [0..25] corresponding to ['a'..'z']. For example, here is how your code could use the getValue command to read out the value of the bitlash variable 't' and put it into the signed long C variable named 'temperature':
void loop(void) {
...
long temperature = getValue('t'-'a');
...
Here are the three API functions for Bitlash variable manipulation. Examples of their use are shown below in the clock application.
Assigns the (signed long 32-bit integer) value to the indicated Bitlash variable.
assignVar(0,42); // a=42
// note this stylish notation to calculate the var index:
assignVar('i'-'a', 33); // i=33
Returns the value of the given Bitlash variable.
long temperature = getValue('t'-'a');
Increments the designated Bitlash variable.
incVar('i'-'a'); // i++
You can open and play with this example code from the Arduino IDE via File / Examples / bitlash / bitlashclock.
Here is an example with some meat on it to show a reasonably complex Bitlash-C integration. The application is a clock, of sorts: the time is stored in Bitlash variables (h for hour, m for minute, and so on) and updated by a C routine based on the passage of millis().
The C routine, called runClock(), also triggers Bitlash macros named onsecond, onminute, onhour, and onday as the appropriate time intervals roll over.
Upload this to your Arduino and you have an easily configurable clock that can Do Bitlash Stuff at appointed times… just add macros.
time.cpp -- Bitlash API Integration :: Wall Clock Example Copyright 2008 by Bill Roy. This is a sample Bitlash API integration. It implements clock based on the Arduino millis() timer. INSTALL Paste bitlash.cpp and this file time.cpp into an Arduino sketch window. Modify loop() to look like this: void loop(void) { runClock(); // <-- add this line runBitlash(); } Upload and play. CLOCK REGISTERS The time of the clock is automagically maintained in Bitlash variables: h: the hour m: the minute s: the second d: the day e: the epoch (the value of millis() when d:h:m:s was the time) Think of these as your time registers. To set the time, set the variables at the Bitlash prompt: > h=12;m=30;s=12 A note on 'd': the days variable simply counts the number of days since startup. Implementing better day rollover including end-of-month handling with correction for leap years is left as an exercise for the reader. Same with leap seconds. And time zones. And daylight savings time. CLOCK UPDATE The automagic time update happens in the runClock() function, which the sketch calls runClock() in loop(), along with runBitlash(). The runClock() function updates the Bitlash clock variables so that your Bitlash script can use them at any time: > print "Time: ", h,":",m,":",s CLOCK MACROS: The script also demonstrates running commands through the API by automatically looking for and running these Bitlash macros, if they are present, on the specified time events: onsecond runs each second onminute runs each minute at seconds rollover onhour runs each hour at minutes rollover onday runs each day at hour rollover For example, this will chime the hour on a piezo buzzer at pin 11: > checknoon := "if i==0: i=12" > onhour := "i=h; checknoon; while i--: beep 11,440,200; delay(1000)" Additional event types like onalarm and onleapsecond are left to the reader. ;) LICENSE Bitlash lives at: http://bitlash.net The author can be reached at: bill@bitlash.net Copyright (C) 2008 Bill Roy This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *****/ // variable indexes for epoch, hour, minute, second, and day #define v_epoch ('e'-'a') #define v_hour ('h'-'a') #define v_minute ('m'-'a') #define v_second ('s'-'a') #define v_day ('d'-'a') // runClock -- update the clock variables // // call this frequently in loop() // void runClock() { unsigned long now = millis(); unsigned long dt = now - getVar(v_epoch); if (dt < 1000) return; // nothing to see while (dt >= 1000) { // tally the full seconds dt -= 1000; incVar(v_second); if (getValue("onsecond") >= 0) doCommand("onsecond"); while (getVar(v_second) >= 60) { assignVar(v_second, getVar(v_second) - 60); incVar(v_minute); if (getValue("onminute") >= 0) doCommand("onminute"); while (getVar(v_minute) >= 60) { assignVar(v_minute, getVar(v_minute) - 60); incVar(v_hour); if (getValue("onhour") >= 0) doCommand("onhour"); while (getVar(v_hour) >= 24) { incVar(v_day); if (getValue("onday") >= 0) doCommand("onday"); assignVar(v_hour, getVar(v_hour) - 24); } } } } assignVar(v_epoch, now - dt); // put back remainder }